Print this page
*** NO COMMENTS ***
        
@@ -129,12 +129,10 @@
 
 static void pppt_task_sent_status(pppt_task_t *ptask);
 
 static pppt_status_t pppt_task_try_abort(pppt_task_t *ptask);
 
-static pppt_status_t pppt_task_hold(pppt_task_t *ptask);
-
 static void pppt_task_rele(pppt_task_t *ptask);
 
 static void pppt_task_update_state(pppt_task_t *ptask,
     pppt_task_state_t new_state);
 
@@ -799,11 +797,11 @@
 pppt_lport_task_free(scsi_task_t *task)
 {
         pppt_task_t *ptask = task->task_port_private;
         pppt_sess_t *ps = ptask->pt_sess;
 
-        pppt_task_free(ptask);
+        pppt_task_rele(ptask);
         pppt_sess_rele(ps);
 }
 
 /*ARGSUSED*/
 stmf_status_t
@@ -1207,11 +1205,11 @@
             sizeof (stmf_data_buf_t), KM_NOSLEEP);
         if (ptask != NULL) {
                 ptask->pt_state = PTS_INIT;
                 ptask->pt_read_buf = NULL;
                 ptask->pt_read_xfer_msgid = 0;
-                cv_init(&ptask->pt_cv, NULL, CV_DRIVER, NULL);
+                ptask->pt_refcnt = 0;
                 mutex_init(&ptask->pt_mutex, NULL, MUTEX_DRIVER, NULL);
                 immed_pbuf = (pppt_buf_t *)(ptask + 1);
                 bzero(immed_pbuf, sizeof (*immed_pbuf));
                 immed_pbuf->pbuf_is_immed = B_TRUE;
                 immed_pbuf->pbuf_stmf_buf = (stmf_data_buf_t *)(immed_pbuf + 1);
@@ -1230,12 +1228,12 @@
 
 void
 pppt_task_free(pppt_task_t *ptask)
 {
         mutex_enter(&ptask->pt_mutex);
+        ASSERT(ptask->pt_refcnt == 0);
         mutex_destroy(&ptask->pt_mutex);
-        cv_destroy(&ptask->pt_cv);
         kmem_free(ptask, sizeof (pppt_task_t) + sizeof (pppt_buf_t) +
             sizeof (stmf_data_buf_t));
 }
 
 pppt_status_t
@@ -1247,10 +1245,12 @@
 
         mutex_enter(&ptask->pt_sess->ps_mutex);
         mutex_enter(&ptask->pt_mutex);
         if (avl_find(&ptask->pt_sess->ps_task_list, ptask, &where) == NULL) {
                 pppt_task_update_state(ptask, PTS_ACTIVE);
+                /* Manually increment refcnt, sincd we hold the mutex... */
+                ptask->pt_refcnt++;
                 avl_insert(&ptask->pt_sess->ps_task_list, ptask, where);
                 mutex_exit(&ptask->pt_mutex);
                 mutex_exit(&ptask->pt_sess->ps_mutex);
                 return (PPPT_STATUS_SUCCESS);
         }
@@ -1287,10 +1287,12 @@
 
         if (remove) {
                 mutex_enter(&ptask->pt_sess->ps_mutex);
                 avl_remove(&ptask->pt_sess->ps_task_list, ptask);
                 mutex_exit(&ptask->pt_sess->ps_mutex);
+                /* Out of the AVL tree, so drop a reference. */
+                pppt_task_rele(ptask);
         }
 
         return (pppt_status);
 }
 
@@ -1399,16 +1401,18 @@
 
         if (remove) {
                 mutex_enter(&ptask->pt_sess->ps_mutex);
                 avl_remove(&ptask->pt_sess->ps_task_list, ptask);
                 mutex_exit(&ptask->pt_sess->ps_mutex);
+                /* Out of the AVL tree, so drop a reference. */
+                pppt_task_rele(ptask);
         }
 
         return (pppt_status);
 }
 
-static pppt_status_t
+pppt_status_t
 pppt_task_hold(pppt_task_t *ptask)
 {
         pppt_status_t   pppt_status = PPPT_STATUS_SUCCESS;
 
         mutex_enter(&ptask->pt_mutex);
@@ -1423,14 +1427,18 @@
 }
 
 static void
 pppt_task_rele(pppt_task_t *ptask)
 {
+        boolean_t freeit;
+
         mutex_enter(&ptask->pt_mutex);
         ptask->pt_refcnt--;
-        cv_signal(&ptask->pt_cv);
+        freeit = (ptask->pt_refcnt == 0);
         mutex_exit(&ptask->pt_mutex);
+        if (freeit)
+                pppt_task_free(ptask);
 }
 
 static void
 pppt_task_update_state(pppt_task_t *ptask,
     pppt_task_state_t new_state)
@@ -1438,7 +1446,6 @@
         PPPT_LOG(CE_NOTE, "task %p %d -> %d", (void *)ptask,
             ptask->pt_state, new_state);
 
         ASSERT(mutex_owned(&ptask->pt_mutex));
         ptask->pt_state = new_state;
-        cv_signal(&ptask->pt_cv);
 }