5691 * Probe nodes are bound to nulldriver. The list is sorted by
5692 * expiration time.
5693 *
5694 * NOTE: If we drove a probe node to DS_ATTACHED, we could use ndi_hold_devi()
5695 * to prevent demotion (instead of sd_uninit_prevent).
5696 */
5697 static void
5698 scsi_hba_barrier_add(dev_info_t *probe, int seconds)
5699 {
5700 struct scsi_hba_barrier *nb;
5701 struct scsi_hba_barrier *b;
5702 struct scsi_hba_barrier **bp;
5703 clock_t endtime;
5704
5705 ASSERT(scsi_hba_devi_is_barrier(probe));
5706
5707 /* HBA is no longer responsible for nodes on the barrier list. */
5708 scsi_hba_barrier_tran_tgt_free(probe);
5709 nb = kmem_alloc(sizeof (struct scsi_hba_barrier), KM_SLEEP);
5710 mutex_enter(&scsi_hba_barrier_mutex);
5711 endtime = ddi_get_lbolt() + drv_usectohz(seconds * MICROSEC);
5712 for (bp = &scsi_hba_barrier_list; (b = *bp) != NULL;
5713 bp = &b->barrier_next)
5714 if (b->barrier_endtime > endtime)
5715 break;
5716 nb->barrier_next = *bp;
5717 nb->barrier_endtime = endtime;
5718 nb->barrier_probe = probe;
5719 *bp = nb;
5720 if (bp == &scsi_hba_barrier_list)
5721 (void) cv_signal(&scsi_hba_barrier_cv);
5722 mutex_exit(&scsi_hba_barrier_mutex);
5723 }
5724
5725 /*
5726 * Attempt to remove devinfo node node, return 1 if removed. We
5727 * don't try to remove barrier nodes that have sd_uninit_prevent set
5728 * (even though they should fail device_uninitchild).
5729 */
5730 static int
5731 scsi_hba_remove_node(dev_info_t *child)
6194 * removing the probe node will cause cv_wait to return
6195 * (scsi_hba_devi_exit does the cv_broadcast).
6196 */
6197 if (wait_msg) {
6198 wait_msg--;
6199 SCSI_HBA_LOG((_LOG(2), NULL, probe,
6200 "exists, probe already in progress: %s", wait_msg ?
6201 "waiting..." : "last msg, but still waiting..."));
6202 }
6203
6204 /*
6205 * NOTE: we could avoid rare case of one second delay by
6206 * implementing scsi_hba_devi_exit_and_wait based on
6207 * ndi/mdi_devi_exit_and_wait (and consider switching devcfg.c
6208 * code to use these ndi/mdi interfaces too).
6209 */
6210 scsi_hba_devi_exit(self, *circp);
6211 mutex_enter(&DEVI(self)->devi_lock);
6212 (void) cv_timedwait(&DEVI(self)->devi_cv,
6213 &DEVI(self)->devi_lock,
6214 ddi_get_lbolt() + drv_usectohz(MICROSEC));
6215 mutex_exit(&DEVI(self)->devi_lock);
6216 scsi_hba_devi_enter(self, circp);
6217 }
6218 ASSERT(probe == NULL);
6219
6220 /*
6221 * Search to see if we are requesting a SID node that already exists.
6222 * We hold the HBA (self) and there is not another probe in progress at
6223 * the same @addr. scsi_findchild() does not hold the returned
6224 * devinfo node but this is OK since we hold the HBA (self).
6225 */
6226 if (name) {
6227 (void) scsi_findchild(self, name, addr, 1, &dsearch, NULL, &pi);
6228 if (dsearch && scsi_hba_dev_is_sid(dsearch)) {
6229 SCSI_HBA_LOG((_LOG(4), NULL, dsearch,
6230 "%s@%s probe devinfo fastpath",
6231 name ? name : "", addr));
6232 child = dsearch;
6233 goto done;
6234 }
|
5691 * Probe nodes are bound to nulldriver. The list is sorted by
5692 * expiration time.
5693 *
5694 * NOTE: If we drove a probe node to DS_ATTACHED, we could use ndi_hold_devi()
5695 * to prevent demotion (instead of sd_uninit_prevent).
5696 */
5697 static void
5698 scsi_hba_barrier_add(dev_info_t *probe, int seconds)
5699 {
5700 struct scsi_hba_barrier *nb;
5701 struct scsi_hba_barrier *b;
5702 struct scsi_hba_barrier **bp;
5703 clock_t endtime;
5704
5705 ASSERT(scsi_hba_devi_is_barrier(probe));
5706
5707 /* HBA is no longer responsible for nodes on the barrier list. */
5708 scsi_hba_barrier_tran_tgt_free(probe);
5709 nb = kmem_alloc(sizeof (struct scsi_hba_barrier), KM_SLEEP);
5710 mutex_enter(&scsi_hba_barrier_mutex);
5711 endtime = ddi_get_lbolt() + drv_sectohz(seconds);
5712 for (bp = &scsi_hba_barrier_list; (b = *bp) != NULL;
5713 bp = &b->barrier_next)
5714 if (b->barrier_endtime > endtime)
5715 break;
5716 nb->barrier_next = *bp;
5717 nb->barrier_endtime = endtime;
5718 nb->barrier_probe = probe;
5719 *bp = nb;
5720 if (bp == &scsi_hba_barrier_list)
5721 (void) cv_signal(&scsi_hba_barrier_cv);
5722 mutex_exit(&scsi_hba_barrier_mutex);
5723 }
5724
5725 /*
5726 * Attempt to remove devinfo node node, return 1 if removed. We
5727 * don't try to remove barrier nodes that have sd_uninit_prevent set
5728 * (even though they should fail device_uninitchild).
5729 */
5730 static int
5731 scsi_hba_remove_node(dev_info_t *child)
6194 * removing the probe node will cause cv_wait to return
6195 * (scsi_hba_devi_exit does the cv_broadcast).
6196 */
6197 if (wait_msg) {
6198 wait_msg--;
6199 SCSI_HBA_LOG((_LOG(2), NULL, probe,
6200 "exists, probe already in progress: %s", wait_msg ?
6201 "waiting..." : "last msg, but still waiting..."));
6202 }
6203
6204 /*
6205 * NOTE: we could avoid rare case of one second delay by
6206 * implementing scsi_hba_devi_exit_and_wait based on
6207 * ndi/mdi_devi_exit_and_wait (and consider switching devcfg.c
6208 * code to use these ndi/mdi interfaces too).
6209 */
6210 scsi_hba_devi_exit(self, *circp);
6211 mutex_enter(&DEVI(self)->devi_lock);
6212 (void) cv_timedwait(&DEVI(self)->devi_cv,
6213 &DEVI(self)->devi_lock,
6214 ddi_get_lbolt() + drv_sectohz(1));
6215 mutex_exit(&DEVI(self)->devi_lock);
6216 scsi_hba_devi_enter(self, circp);
6217 }
6218 ASSERT(probe == NULL);
6219
6220 /*
6221 * Search to see if we are requesting a SID node that already exists.
6222 * We hold the HBA (self) and there is not another probe in progress at
6223 * the same @addr. scsi_findchild() does not hold the returned
6224 * devinfo node but this is OK since we hold the HBA (self).
6225 */
6226 if (name) {
6227 (void) scsi_findchild(self, name, addr, 1, &dsearch, NULL, &pi);
6228 if (dsearch && scsi_hba_dev_is_sid(dsearch)) {
6229 SCSI_HBA_LOG((_LOG(4), NULL, dsearch,
6230 "%s@%s probe devinfo fastpath",
6231 name ? name : "", addr));
6232 child = dsearch;
6233 goto done;
6234 }
|