summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Butler <jesse.butler@oracle.com>2010-05-27 15:10:17 -0600
committerJesse Butler <jesse.butler@oracle.com>2010-05-27 15:10:17 -0600
commit39cd77a06f56f308333bd7b2d8aae1b1467be113 (patch)
treea2240effb89cde5d0331a9eda45b3dd01ffb4359
parentb8a1bc93abd7f91503ab2661db0af6e85108b50b (diff)
downloadillumos-gate-39cd77a06f56f308333bd7b2d8aae1b1467be113.tar.gz
6955322 Anago: i/o from FC client failed on LCC pull; appliance kit failed
6952400 assertion failed: phyp->ref_count != 0 pmcs_subr.c, line: 7815
-rw-r--r--usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c20
-rw-r--r--usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c31
-rw-r--r--usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_def.h1
3 files changed, 47 insertions, 5 deletions
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 a4b76f6308..0b85e33cb9 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
@@ -2211,7 +2211,15 @@ out:
pwrk->phy = NULL;
}
- pmcs_pwork(pwp, pwrk);
+ /*
+ * We may arrive here due to a command timing out, which in turn
+ * could be addressed in a different context. So, free the work
+ * back, but only after confirming it's not already been freed
+ * elsewhere.
+ */
+ if (!PMCS_COMMAND_DONE(pwrk)) {
+ pmcs_pwork(pwp, pwrk);
+ }
/*
* If the device is gone, we only put this command on the completion
@@ -2697,7 +2705,15 @@ out:
pwrk->phy = NULL;
}
- pmcs_pwork(pwp, pwrk);
+ /*
+ * We may arrive here due to a command timing out, which in turn
+ * could be addressed in a different context. So, free the work
+ * back, but only after confirming it's not already been freed
+ * elsewhere.
+ */
+ if (!PMCS_COMMAND_DONE(pwrk)) {
+ pmcs_pwork(pwp, pwrk);
+ }
if (xp->dev_gone) {
mutex_exit(&xp->statlock);
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 4aefcdb013..ae92755483 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
@@ -4906,6 +4906,7 @@ pmcs_abort(pmcs_hw_t *pwp, pmcs_phy_t *pptr, uint32_t tag, int all_cmds,
msg[3] = 0;
msg[4] = LE_32(1);
pwrk->ptr = NULL;
+ pwrk->abt_htag = PMCS_ABT_HTAG_ALL;
pptr->abort_all_start = gethrtime();
} else {
msg[3] = LE_32(tag);
@@ -4955,9 +4956,14 @@ pmcs_abort(pmcs_hw_t *pwp, pmcs_phy_t *pptr, uint32_t tag, int all_cmds,
}
if (result) {
- pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt,
- "%s: Abort (htag 0x%08x) request timed out",
- __func__, abt_htag);
+ if (all_cmds) {
+ pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt,
+ "%s: Abort all request timed out", __func__);
+ } else {
+ pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt,
+ "%s: Abort (htag 0x%08x) request timed out",
+ __func__, abt_htag);
+ }
if (tgt != NULL) {
mutex_enter(&tgt->statlock);
if ((tgt->dev_state != PMCS_DEVICE_STATE_IN_RECOVERY) &&
@@ -7103,6 +7109,8 @@ void
pmcs_complete_work_impl(pmcs_hw_t *pwp, pmcwork_t *pwrk, uint32_t *iomb,
size_t amt)
{
+ pmcs_phy_t *pptr;
+
switch (PMCS_TAG_TYPE(pwrk->htag)) {
case PMCS_TAG_TYPE_CBACK:
{
@@ -7121,6 +7129,23 @@ pmcs_complete_work_impl(pmcs_hw_t *pwp, pmcwork_t *pwrk, uint32_t *iomb,
#ifdef DEBUG
pmcs_check_iomb_status(pwp, iomb);
#endif
+ /*
+ * If this was an abort all cmd, clear the phy's
+ * 'abort_all_start' time and signal the abort_all_cv.
+ */
+ if (pwrk->abt_htag == PMCS_ABT_HTAG_ALL) {
+ pptr = pwrk->phy;
+ if (pptr != NULL) {
+ mutex_exit(&pwrk->lock);
+ mutex_enter(&pptr->phy_lock);
+ if (pptr->abort_all_start) {
+ pptr->abort_all_start = 0;
+ cv_signal(&pptr->abort_all_cv);
+ }
+ mutex_exit(&pptr->phy_lock);
+ mutex_enter(&pwrk->lock);
+ }
+ }
pmcs_pwork(pwp, pwrk);
break;
default:
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 bc57ad2e3b..ef17eebc1c 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
@@ -248,6 +248,7 @@ struct pmcwork {
pmcs_work_state_t last_state;
hrtime_t finish;
};
+#define PMCS_ABT_HTAG_ALL 0xffffffff
#define PMCS_REC_EVENT 0xffffffff /* event recovery */