summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrikanth Suravajhala <srikanth.suravajhala@oracle.com>2010-04-26 18:00:24 -0400
committerSrikanth Suravajhala <srikanth.suravajhala@oracle.com>2010-04-26 18:00:24 -0400
commit978d7443a924cda8208d6a10e72be89383bc7bec (patch)
treeff805c3a4d727c2b87036de000e0a116adce81c9
parent5f1fdc187ec74acfbc49a47e07b89d7f64519f7b (diff)
downloadillumos-gate-978d7443a924cda8208d6a10e72be89383bc7bec.tar.gz
6940745 work structures without a pmcs_cmd_t need to be cleaned up after hot reset
6945802 potential null dereference in pmcs_create_one_phy_stats()
-rw-r--r--usr/src/cmd/mdb/common/modules/pmcs/pmcs.c2
-rw-r--r--usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_attach.c5
-rw-r--r--usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_intr.c30
-rw-r--r--usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c2
-rw-r--r--usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c122
-rw-r--r--usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_def.h6
-rw-r--r--usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h8
-rw-r--r--usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h8
8 files changed, 77 insertions, 106 deletions
diff --git a/usr/src/cmd/mdb/common/modules/pmcs/pmcs.c b/usr/src/cmd/mdb/common/modules/pmcs/pmcs.c
index 7379c0e470..24785a7445 100644
--- a/usr/src/cmd/mdb/common/modules/pmcs/pmcs.c
+++ b/usr/src/cmd/mdb/common/modules/pmcs/pmcs.c
@@ -1454,7 +1454,7 @@ inbound_iomb_opcode(uint32_t opcode)
case PMCIN_SAS_DIAG_EXECUTE:
return ("SAS_DIAG_EXECUTE");
break;
- case PMCIN_SAW_HW_EVENT_ACK:
+ case PMCIN_SAS_HW_EVENT_ACK:
return ("SAS_HW_EVENT_ACK");
break;
case PMCIN_GET_TIME_STAMP:
diff --git a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_attach.c b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_attach.c
index 12f3aa4a9c..dadba60f7a 100644
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_attach.c
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_attach.c
@@ -918,7 +918,7 @@ pmcs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
}
pwp->work = kmem_zalloc(pwp->max_cmd * sizeof (pmcwork_t), KM_SLEEP);
- for (i = 0; i < pwp->max_cmd - 1; i++) {
+ for (i = 0; i < pwp->max_cmd; i++) {
pmcwork_t *pwrk = &pwp->work[i];
mutex_init(&pwrk->lock, NULL, MUTEX_DRIVER,
DDI_INTR_PRI(pwp->intr_pri));
@@ -1600,7 +1600,7 @@ pmcs_unattach(pmcs_hw_t *pwp)
*/
if (pwp->work && pwp->max_cmd) {
- for (i = 0; i < pwp->max_cmd - 1; i++) {
+ for (i = 0; i < pwp->max_cmd; i++) {
pmcwork_t *pwrk = &pwp->work[i];
mutex_destroy(&pwrk->lock);
cv_destroy(&pwrk->sleep_cv);
@@ -3054,6 +3054,7 @@ pmcs_create_one_phy_stats(pmcs_iport_t *iport, pmcs_phy_t *phyp)
pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, NULL,
"%s: Failed to create %s kstats for PHY(0x%p) at %s",
__func__, ks_name, (void *)phyp, phyp->path);
+ return;
}
ps = (sas_phy_stats_t *)phyp->phy_stats->ks_data;
diff --git a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_intr.c b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_intr.c
index 90320505f8..ecb51a9fbf 100644
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_intr.c
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_intr.c
@@ -166,7 +166,7 @@ pmcs_process_io_completion(pmcs_hw_t *pwp, pmcs_iocomp_cb_t *ioccb, size_t amt)
uint32_t tag_type;
uint32_t htag = LE_32(((uint32_t *)((void *)ioccb->iomb))[1]);
- pwrk = pmcs_tag2wp(pwp, htag);
+ pwrk = pmcs_tag2wp(pwp, htag, B_FALSE);
if (pwrk == NULL) {
pmcs_work_not_found(pwp, htag, (void *)&ioccb->iomb);
kmem_cache_free(pwp->iocomp_cb_cache, ioccb);
@@ -237,7 +237,7 @@ pmcs_process_completion(pmcs_hw_t *pwp, void *iomb, size_t amt)
pmcwork_t *pwrk;
uint32_t htag = LE_32(((uint32_t *)iomb)[1]);
- pwrk = pmcs_tag2wp(pwp, htag);
+ pwrk = pmcs_tag2wp(pwp, htag, B_FALSE);
if (pwrk == NULL) {
pmcs_work_not_found(pwp, htag, iomb);
return;
@@ -1061,7 +1061,7 @@ pmcs_process_echo_completion(pmcs_hw_t *pwp, void *iomb, size_t amt)
echo_test_t fred;
pmcwork_t *pwrk;
uint32_t *msg = iomb, htag = LE_32(msg[1]);
- pwrk = pmcs_tag2wp(pwp, htag);
+ pwrk = pmcs_tag2wp(pwp, htag, B_FALSE);
if (pwrk) {
(void) memcpy(&fred, &((uint32_t *)iomb)[2], sizeof (fred));
fred.ptr[0]++;
@@ -1087,7 +1087,7 @@ pmcs_process_ssp_event(pmcs_hw_t *pwp, void *iomb, size_t amt)
status = LE_32(w[2]);
- pwrk = pmcs_tag2wp(pwp, htag);
+ pwrk = pmcs_tag2wp(pwp, htag, B_FALSE);
if (pwrk == NULL) {
path = "????";
} else {
@@ -1150,25 +1150,12 @@ pmcs_process_sata_event(pmcs_hw_t *pwp, void *iomb, size_t amt)
*/
path = NULL;
if (htag) {
- pwrk = pmcs_tag2wp(pwp, htag);
+ pwrk = pmcs_tag2wp(pwp, htag, B_TRUE);
if (pwrk) {
- pmcs_lock_phy(pwrk->phy);
pptr = pwrk->phy;
path = pptr->path;
}
}
- if (path == NULL) {
- mutex_enter(&pwp->lock);
- pptr = pmcs_find_phy_by_devid(pwp, LE_32(w[4]));
- /* This PHY is now locked */
- mutex_exit(&pwp->lock);
- if (pptr) {
- path = pptr->path;
- } else {
- path = "????";
- }
- }
-
if (status != PMCOUT_STATUS_XFER_CMD_FRAME_ISSUED) {
char buf[20];
const char *emsg = pmcs_status_str(status);
@@ -1209,7 +1196,7 @@ pmcs_process_sata_event(pmcs_hw_t *pwp, void *iomb, size_t amt)
}
if (pptr) {
- pmcs_unlock_phy(pptr);
+ mutex_exit(&pptr->phy_lock);
}
}
@@ -1223,7 +1210,7 @@ pmcs_process_abort_completion(pmcs_hw_t *pwp, void *iomb, size_t amt)
uint32_t scp = LE_32(((uint32_t *)iomb)[3]) & 0x1;
char *path;
- pwrk = pmcs_tag2wp(pwp, htag);
+ pwrk = pmcs_tag2wp(pwp, htag, B_TRUE);
if (pwrk == NULL) {
pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
"%s: cannot find work structure for ABORT", __func__);
@@ -1236,7 +1223,6 @@ pmcs_process_abort_completion(pmcs_hw_t *pwp, void *iomb, size_t amt)
* Don't use pmcs_lock_phy here since it could potentially lock
* other PHYs beneath, which is unnecessary in this context.
*/
- mutex_enter(&pptr->phy_lock);
pptr->abort_pending = 0;
pptr->abort_sent = 0;
@@ -1327,7 +1313,7 @@ pmcs_process_general_event(pmcs_hw_t *pwp, uint32_t *iomb)
iomb[PMCS_MSG_SIZE - 1] = 0;
htag = LE_32(iomb[1]);
pmcs_print_entry(pwp, PMCS_PRT_DEBUG, local, iomb);
- pwrk = pmcs_tag2wp(pwp, htag);
+ pwrk = pmcs_tag2wp(pwp, htag, B_FALSE);
if (pwrk) {
pmcs_complete_work(pwp, pwrk, iomb, PMCS_QENTRY_SIZE);
}
diff --git a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c
index 8f536bd99f..d6b6c0fa04 100644
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c
@@ -668,7 +668,7 @@ pmcs_scsa_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
/*
* See if we have a real work structure associated with this cmd.
*/
- pwrk = pmcs_tag2wp(pwp, sp->cmd_tag);
+ pwrk = pmcs_tag2wp(pwp, sp->cmd_tag, B_FALSE);
if (pwrk && pwrk->arg == sp) {
tag = pwrk->htag;
pptr = pwrk->phy;
diff --git a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c
index 6057082bde..fb7898ecaf 100644
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c
@@ -2324,7 +2324,8 @@ pmcs_phymap_activate(void *arg, char *ua, void **privp)
pmcs_iport_t *iport = NULL;
mutex_enter(&pwp->lock);
- if ((pwp->state == STATE_UNPROBING) || (pwp->state == STATE_DEAD)) {
+ if ((pwp->state == STATE_UNPROBING) || (pwp->state == STATE_DEAD) ||
+ (pwp->state == STATE_IN_RESET)) {
mutex_exit(&pwp->lock);
return;
}
@@ -4163,6 +4164,7 @@ again:
(void) memset(pwp->scratch, 0x77, PMCS_SCRATCH_SIZE);
pwrk->arg = pwp->scratch;
pwrk->dtype = pptr->dtype;
+ pwrk->htag |= PMCS_TAG_NONIO_CMD;
mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]);
ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER);
if (ptr == NULL) {
@@ -4399,6 +4401,7 @@ pmcs_expander_content_discover(pmcs_hw_t *pwp, pmcs_phy_t *expander,
(void) memset(pwp->scratch, 0x77, PMCS_SCRATCH_SIZE);
pwrk->arg = pwp->scratch;
pwrk->dtype = expander->dtype;
+ pwrk->htag |= PMCS_TAG_NONIO_CMD;
msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, PMCIN_SMP_REQUEST));
msg[1] = LE_32(pwrk->htag);
msg[2] = LE_32(expander->device_id);
@@ -4806,9 +4809,10 @@ pmcs_pwork(pmcs_hw_t *pwp, pmcwork_t *p)
* Find a work structure based upon a tag and make sure that the tag
* serial number matches the work structure we've found.
* If a structure is found, its lock is held upon return.
+ * If lock_phy is B_TRUE, then lock the phy also when returning the work struct
*/
pmcwork_t *
-pmcs_tag2wp(pmcs_hw_t *pwp, uint32_t htag)
+pmcs_tag2wp(pmcs_hw_t *pwp, uint32_t htag, boolean_t lock_phy)
{
pmcwork_t *p;
uint32_t idx = PMCS_TAG_INDEX(htag);
@@ -4817,6 +4821,11 @@ pmcs_tag2wp(pmcs_hw_t *pwp, uint32_t htag)
mutex_enter(&p->lock);
if (p->htag == htag) {
+ if (lock_phy) {
+ mutex_exit(&p->lock);
+ mutex_enter(&p->phy->phy_lock);
+ mutex_enter(&p->lock);
+ }
return (p);
}
mutex_exit(&p->lock);
@@ -4872,6 +4881,7 @@ pmcs_abort(pmcs_hw_t *pwp, pmcs_phy_t *pptr, uint32_t tag, int all_cmds,
}
pwrk->dtype = pptr->dtype;
+ pwrk->htag |= PMCS_TAG_NONIO_CMD;
if (wait) {
pwrk->arg = msg;
}
@@ -5039,6 +5049,7 @@ pmcs_ssp_tmf(pmcs_hw_t *pwp, pmcs_phy_t *pptr, uint8_t tmf, uint32_t tag,
* NB: so as to not get entangled in normal I/O
* NB: processing.
*/
+ pwrk->htag |= PMCS_TAG_NONIO_CMD;
msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL,
PMCIN_SSP_INI_TM_START));
msg[1] = LE_32(pwrk->htag);
@@ -5254,6 +5265,7 @@ pmcs_sata_abort_ncq(pmcs_hw_t *pwp, pmcs_phy_t *pptr)
if (pwrk == NULL) {
return (ENOMEM);
}
+ pwrk->htag |= PMCS_TAG_NONIO_CMD;
msg[0] = LE_32(PMCS_IOMB_IN_SAS(PMCS_OQ_IODONE,
PMCIN_SATA_HOST_IO_START));
msg[1] = LE_32(pwrk->htag);
@@ -5677,69 +5689,6 @@ pmcs_phy_name(pmcs_hw_t *pwp, pmcs_phy_t *pptr, char *obuf, size_t olen)
}
/*
- * Implementation for pmcs_find_phy_by_devid.
- * If the PHY is found, it is returned locked.
- */
-static pmcs_phy_t *
-pmcs_find_phy_by_devid_impl(pmcs_phy_t *phyp, uint32_t device_id)
-{
- pmcs_phy_t *match, *cphyp, *nphyp;
-
- ASSERT(!mutex_owned(&phyp->phy_lock));
-
- while (phyp) {
- pmcs_lock_phy(phyp);
-
- if ((phyp->valid_device_id) && (phyp->device_id == device_id)) {
- return (phyp);
- }
- if (phyp->children) {
- cphyp = phyp->children;
- pmcs_unlock_phy(phyp);
- match = pmcs_find_phy_by_devid_impl(cphyp, device_id);
- if (match) {
- ASSERT(mutex_owned(&match->phy_lock));
- return (match);
- }
- pmcs_lock_phy(phyp);
- }
-
- if (IS_ROOT_PHY(phyp)) {
- pmcs_unlock_phy(phyp);
- phyp = NULL;
- } else {
- nphyp = phyp->sibling;
- pmcs_unlock_phy(phyp);
- phyp = nphyp;
- }
- }
-
- return (NULL);
-}
-
-/*
- * If the PHY is found, it is returned locked
- */
-pmcs_phy_t *
-pmcs_find_phy_by_devid(pmcs_hw_t *pwp, uint32_t device_id)
-{
- pmcs_phy_t *phyp, *match = NULL;
-
- phyp = pwp->root_phys;
-
- while (phyp) {
- match = pmcs_find_phy_by_devid_impl(phyp, device_id);
- if (match) {
- ASSERT(mutex_owned(&match->phy_lock));
- return (match);
- }
- phyp = phyp->sibling;
- }
-
- return (NULL);
-}
-
-/*
* This function is called as a sanity check to ensure that a newly registered
* PHY doesn't have a device_id that exists with another registered PHY.
*/
@@ -6019,6 +5968,7 @@ pmcs_spinup_release(pmcs_hw_t *pwp, pmcs_phy_t *phyp)
phyp->spinup_hold = 0;
bzero(msg, PMCS_QENTRY_SIZE);
+ pwrk->htag |= PMCS_TAG_NONIO_CMD;
msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL,
PMCIN_LOCAL_PHY_CONTROL));
msg[1] = LE_32(pwrk->htag);
@@ -6247,7 +6197,7 @@ pmcs_ack_events(pmcs_hw_t *pwp)
}
msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL,
- PMCIN_SAW_HW_EVENT_ACK));
+ PMCIN_SAS_HW_EVENT_ACK));
msg[1] = LE_32(pwrk->htag);
msg[2] = LE_32(pptr->hw_event_ack);
@@ -7100,7 +7050,7 @@ pmcs_flush_target_queues(pmcs_hw_t *pwp, pmcs_xscsi_t *tgt, uint8_t queues)
sp = STAILQ_FIRST(&tgt->aq);
while (sp) {
sp_next = STAILQ_NEXT(sp, cmd_next);
- pwrk = pmcs_tag2wp(pwp, sp->cmd_tag);
+ pwrk = pmcs_tag2wp(pwp, sp->cmd_tag, B_FALSE);
/*
* If we don't find a work structure, it's because
@@ -7154,6 +7104,39 @@ pmcs_flush_target_queues(pmcs_hw_t *pwp, pmcs_xscsi_t *tgt, uint8_t queues)
mutex_exit(&pwp->cq_lock);
}
}
+
+ if (queues == PMCS_TGT_ALL_QUEUES) {
+ mutex_exit(&tgt->statlock);
+ (void) pmcs_flush_nonio_cmds(pwp);
+ mutex_enter(&tgt->statlock);
+ }
+}
+
+/*
+ * Clean up work structures with no associated pmcs_cmd_t struct
+ */
+void
+pmcs_flush_nonio_cmds(pmcs_hw_t *pwp)
+{
+ int i;
+ pmcwork_t *p;
+
+ for (i = 0; i < pwp->max_cmd; i++) {
+ p = &pwp->work[i];
+ mutex_enter(&p->lock);
+ if (p->htag & PMCS_TAG_NONIO_CMD) {
+ if (!PMCS_COMMAND_ACTIVE(p) || PMCS_COMMAND_DONE(p)) {
+ mutex_exit(&p->lock);
+ continue;
+ }
+ pmcs_prt(pwp, PMCS_PRT_DEBUG, p->phy, p->xp,
+ "%s: Completing non-io cmd with HTAG 0x%x",
+ __func__, p->htag);
+ pmcs_complete_work_impl(pwp, p, NULL, 0);
+ } else {
+ mutex_exit(&p->lock);
+ }
+ }
}
void
@@ -7545,13 +7528,15 @@ pmcs_free_all_phys(pmcs_hw_t *pwp, pmcs_phy_t *phyp)
tphyp = nphyp;
}
+ mutex_enter(&pwp->dead_phylist_lock);
tphyp = pwp->dead_phys;
while (tphyp) {
- nphyp = tphyp->sibling;
+ nphyp = tphyp->dead_next;
kmem_cache_free(pwp->phy_cache, tphyp);
tphyp = nphyp;
}
pwp->dead_phys = NULL;
+ mutex_exit(&pwp->dead_phylist_lock);
}
/*
@@ -7921,6 +7906,7 @@ pmcs_add_phy_to_iport(pmcs_iport_t *iport, pmcs_phy_t *phyp)
ASSERT(mutex_owned(&iport->lock));
ASSERT(phyp);
ASSERT(!list_link_active(&phyp->list_node));
+
iport->nphy++;
list_insert_tail(&iport->phys, phyp);
pmcs_smhba_add_iport_prop(iport, DATA_TYPE_INT32, PMCS_NUM_PHYS,
diff --git a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_def.h b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_def.h
index 18132eaa85..7b25fccd2a 100644
--- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_def.h
+++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_def.h
@@ -316,7 +316,8 @@ typedef struct {
* bits what
* ------------------------
* 31 done bit
- * 30..28 tag type
+ * 30 non-io cmd bit
+ * 29..28 tag type
* 27..12 rolling serial number
* 11..0 index into work area to get pmcwork structure
*
@@ -346,7 +347,8 @@ typedef struct {
#define PMCS_TAG_TYPE_SHIFT 28
#define PMCS_TAG_SERNO_SHIFT 12
#define PMCS_TAG_INDEX_SHIFT 0
-#define PMCS_TAG_TYPE_MASK 0x70000000
+#define PMCS_TAG_TYPE_MASK 0x30000000
+#define PMCS_TAG_NONIO_CMD 0x40000000
#define PMCS_TAG_DONE 0x80000000
#define PMCS_TAG_SERNO_MASK 0x0ffff000
#define PMCS_TAG_INDEX_MASK 0x00000fff
diff --git a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h
index 0ab8c09c49..c8860b6376 100644
--- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h
+++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h
@@ -18,9 +18,9 @@
*
* CDDL HEADER END
*
- *
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
* PMC 8x6G IOMB Definitions
@@ -116,7 +116,7 @@ extern "C" {
#define PMCIN_GPIO 0x22
#define PMCIN_SAS_DIAG_MODE_START_END 0x23
#define PMCIN_SAS_DIAG_EXECUTE 0x24
-#define PMCIN_SAW_HW_EVENT_ACK 0x25
+#define PMCIN_SAS_HW_EVENT_ACK 0x25
#define PMCIN_GET_TIME_STAMP 0x26
#define PMCIN_PORT_CONTROL 0x27
#define PMCIN_GET_NVMD_DATA 0x28
diff --git a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h
index 348439d222..6aeeaaf355 100644
--- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h
+++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_proto.h
@@ -76,7 +76,7 @@ pmcwork_t *pmcs_gwork(pmcs_hw_t *, uint32_t, pmcs_phy_t *);
void pmcs_pwork(pmcs_hw_t *, struct pmcwork *);
/* given a tag, find a work structure */
-pmcwork_t *pmcs_tag2wp(pmcs_hw_t *, uint32_t);
+pmcwork_t *pmcs_tag2wp(pmcs_hw_t *, uint32_t, boolean_t);
/*
* Abort function
@@ -148,11 +148,6 @@ void pmcs_report_fwversion(pmcs_hw_t *);
void pmcs_phy_name(pmcs_hw_t *, pmcs_phy_t *, char *, size_t);
/*
- * Find a PHY by device_id
- */
-pmcs_phy_t *pmcs_find_phy_by_devid(pmcs_hw_t *, uint32_t);
-
-/*
* Find a PHY by wwn
*/
pmcs_phy_t *pmcs_find_phy_by_wwn(pmcs_hw_t *, uint64_t);
@@ -302,6 +297,7 @@ boolean_t pmcs_set_nvmd(pmcs_hw_t *pwp, pmcs_nvmd_type_t nvmd_type,
void pmcs_complete_work_impl(pmcs_hw_t *pwp, pmcwork_t *pwrk, uint32_t *iomb,
size_t amt);
void pmcs_flush_target_queues(pmcs_hw_t *, pmcs_xscsi_t *, uint8_t);
+void pmcs_flush_nonio_cmds(pmcs_hw_t *);
boolean_t pmcs_iport_has_targets(pmcs_hw_t *, pmcs_iport_t *);
void pmcs_free_dma_chunklist(pmcs_hw_t *);
void pmcs_dev_state_recovery(pmcs_hw_t *, pmcs_phy_t *);