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);
}