void ghd_waitq_shuffle_up(ccc_t *cccp, gdev_t *gdevp) { gcmd_t *gcmdp; ASSERT(mutex_owned(&cccp->ccc_waitq_mutex)); GDBG_WAITQ(("ghd_waitq_shuffle_up: cccp 0x%p gdevp 0x%p N %ld " "max %ld\n", cccp, gdevp, GDEV_NACTIVE(gdevp), GDEV_MAXACTIVE(gdevp))); for (;;) { /* * Now check the device wait queue throttle to see if I can * shuffle up a request to the HBA wait queue. */ if (GDEV_NACTIVE(gdevp) >= GDEV_MAXACTIVE(gdevp)) { GDBG_WAITQ(("ghd_waitq_shuffle_up: N>MAX gdevp 0x%p\n", gdevp)); return; } /* * single thread requests while multiple instances * because the different target drives might have * conflicting maxactive throttles. */ if (gdevp->gd_ninstances > 1 && GDEV_NACTIVE(gdevp) > 0) { GDBG_WAITQ(("ghd_waitq_shuffle_up: multi gdevp 0x%p\n", gdevp)); return; } /* * promote the topmost request from the device queue to * the HBA queue. */ if ((gcmdp = L2_remove_head(&GDEV_QHEAD(gdevp))) == NULL) { /* the device is empty so we're done */ GDBG_WAITQ(("ghd_waitq_shuffle_up: MT gdevp 0x%p\n", gdevp)); return; } L2_add(&GHBA_QHEAD(cccp), &gcmdp->cmd_q, gcmdp); GDEV_NACTIVE(gdevp)++; gcmdp->cmd_waitq_level++; GDBG_WAITQ(("ghd_waitq_shuffle_up: gdevp 0x%p gcmdp 0x%p\n", gdevp, gcmdp)); } }
/*ARGSUSED*/ void ghd_target_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, ccc_t *cccp, gtgt_t *gtgtp) { _NOTE(ARGUNUSED(hba_dip,tgt_dip)) gdev_t *gdevp = gtgtp->gt_gdevp; GDBG_WAITQ(("ghd_target_free(%d,%d) gdevp-0x%p gtgtp 0x%p\n", gtgtp->gt_target, gtgtp->gt_lun, (void *)gdevp, (void *)gtgtp)); /* * grab both mutexes so the queue structures * stay stable while deleting this instance */ mutex_enter(&cccp->ccc_hba_mutex); mutex_enter(&cccp->ccc_waitq_mutex); ASSERT(gdevp->gd_ninstances > 0); /* * remove this per-instance structure from the device list and * free the memory */ GTGT_DEATTACH(gtgtp, gdevp); kmem_free((caddr_t)gtgtp, gtgtp->gt_size); if (gdevp->gd_ninstances == 1) { GDBG_WAITQ(("ghd_target_free: N=1 gdevp 0x%p\n", (void *)gdevp)); /* * If there's now just one instance left attached to this * device then reset the queue's max active value * from that instance's saved value. */ gtgtp = GDEVP2GTGTP(gdevp); GDEV_MAXACTIVE(gdevp) = gtgtp->gt_maxactive; } else if (gdevp->gd_ninstances == 0) { /* else no instances left */ GDBG_WAITQ(("ghd_target_free: N=0 gdevp 0x%p\n", (void *)gdevp)); /* detach this per-dev-structure from the HBA's dev list */ GDEV_QDETACH(gdevp, cccp); kmem_free(gdevp, sizeof (*gdevp)); } #if defined(GHD_DEBUG) || defined(__lint) else { /* leave maxactive set to 1 */ GDBG_WAITQ(("ghd_target_free: N>1 gdevp 0x%p\n", (void *)gdevp)); } #endif ghd_waitq_process_and_mutex_exit(cccp); }