Print this page
First pass at 4310

@@ -1061,10 +1061,11 @@
         char                    config_setup = 0;
         char                    hba_attach_setup = 0;
         char                    smp_attach_setup = 0;
         char                    mutex_init_done = 0;
         char                    event_taskq_create = 0;
+        char                    reset_taskq_create = 0;
         char                    dr_taskq_create = 0;
         char                    doneq_thread_create = 0;
         char                    added_watchdog = 0;
         scsi_hba_tran_t         *hba_tran;
         uint_t                  mem_bar = MEM_SPACE;

@@ -1267,10 +1268,22 @@
                     "failed");
                 goto fail;
         }
         dr_taskq_create++;
 
+        /*
+         * A taskq is created for dealing with reset events
+         */
+        if ((mpt->m_reset_taskq = ddi_taskq_create(dip,
+            "mptsas_reset_taskq",
+            1, TASKQ_DEFAULTPRI, 0)) == NULL) {
+                mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for reset "
+                    "failed");
+                goto fail;
+        }
+        reset_taskq_create++;
+
         mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
             0, "mptsas_doneq_thread_threshold_prop", 10);
         mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
             0, "mptsas_doneq_length_threshold_prop", 8);
         mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip,

@@ -1591,10 +1604,13 @@
                         ddi_taskq_destroy(mpt->m_event_taskq);
                 }
                 if (dr_taskq_create) {
                         ddi_taskq_destroy(mpt->m_dr_taskq);
                 }
+                if (reset_taskq_create) {
+                        ddi_taskq_destroy(mpt->m_reset_taskq);
+                }
                 if (mutex_init_done) {
                         mutex_destroy(&mpt->m_tx_waitq_mutex);
                         mutex_destroy(&mpt->m_passthru_mutex);
                         mutex_destroy(&mpt->m_mutex);
                         for (i = 0; i < MPTSAS_MAX_PHYS; i++) {

@@ -1723,10 +1739,11 @@
         mptsas_raid_action_system_shutdown(mpt);
 
         mutex_exit(&mpt->m_mutex);
 
         /* drain the taskq */
+        ddi_taskq_wait(mpt->m_reset_taskq);
         ddi_taskq_wait(mpt->m_event_taskq);
         ddi_taskq_wait(mpt->m_dr_taskq);
 
         return (DDI_SUCCESS);
 }

@@ -1898,10 +1915,11 @@
         mptsas_raid_action_system_shutdown(mpt);
         mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
         (void) mptsas_ioc_reset(mpt, FALSE);
         mutex_exit(&mpt->m_mutex);
         mptsas_rem_intrs(mpt);
+        ddi_taskq_destroy(mpt->m_reset_taskq);
         ddi_taskq_destroy(mpt->m_event_taskq);
         ddi_taskq_destroy(mpt->m_dr_taskq);
 
         if (mpt->m_doneq_thread_n) {
                 mutex_enter(&mpt->m_doneq_mutex);

@@ -12735,10 +12753,16 @@
 
 out:
         return (status);
 }
 
+/* Dirty wrapper for taskq */
+void
+mptsas_handle_restart_ioc(void *mpt) {
+    mptsas_restart_ioc((mptsas_t *) mpt);
+}
+
 int
 mptsas_restart_ioc(mptsas_t *mpt)
 {
         int             rval = DDI_SUCCESS;
         mptsas_target_t *ptgt = NULL;