Print this page
XXXX don't fail device detach when it's physically removed
@@ -8549,30 +8549,35 @@
int i;
int tgt;
dev_t dev;
dev_info_t *pdip = ddi_get_parent(devi);
int instance = ddi_get_instance(devi);
+ int devigone = DEVI(devi)->devi_gone;
mutex_enter(&sd_detach_mutex);
/*
* Fail the detach for any of the following:
* - Unable to get the sd_lun struct for the instance
- * - A layered driver has an outstanding open on the instance
* - Another thread is already detaching this instance
* - Another thread is currently performing an open
+ *
+ * Additionaly, if "device gone" flag is not set:
+ * - There are outstanding commands in driver
+ * - There are outstanding commands in transport
*/
devp = ddi_get_driver_private(devi);
- if ((devp == NULL) ||
- ((un = (struct sd_lun *)devp->sd_private) == NULL) ||
- (un->un_ncmds_in_driver != 0) || (un->un_layer_count != 0) ||
- (un->un_detach_count != 0) || (un->un_opens_in_progress != 0)) {
+ if (devp == NULL || (un = (struct sd_lun *)devp->sd_private) == NULL ||
+ un->un_detach_count != 0 || un->un_opens_in_progress != 0 ||
+ (!devigone && (un->un_ncmds_in_driver != 0 ||
+ un->un_ncmds_in_transport != 0 ||
+ un->un_state == SD_STATE_RWAIT))) {
mutex_exit(&sd_detach_mutex);
return (DDI_FAILURE);
}
- SD_TRACE(SD_LOG_ATTACH_DETACH, un, "sd_unit_detach: entry 0x%p\n", un);
+ SD_TRACE(SD_LOG_ATTACH_DETACH, un, "%s: entry 0x%p\n", __func__, un);
/*
* Mark this instance as currently in a detach, to inhibit any
* opens from a layered driver.
*/
@@ -8582,14 +8587,10 @@
tgt = ddi_prop_get_int(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
SCSI_ADDR_PROP_TARGET, -1);
dev = sd_make_device(SD_DEVINFO(un));
-#ifndef lint
- _NOTE(COMPETING_THREADS_NOW);
-#endif
-
mutex_enter(SD_MUTEX(un));
/*
* Fail the detach if there are any outstanding layered
* opens on this device.
@@ -8599,37 +8600,23 @@
goto err_notclosed;
}
}
/*
- * Verify there are NO outstanding commands issued to this device.
- * ie, un_ncmds_in_transport == 0.
- * It's possible to have outstanding commands through the physio
- * code path, even though everything's closed.
- */
- if ((un->un_ncmds_in_transport != 0) || (un->un_retry_timeid != NULL) ||
- (un->un_direct_priority_timeid != NULL) ||
- (un->un_state == SD_STATE_RWAIT)) {
- mutex_exit(SD_MUTEX(un));
- SD_ERROR(SD_LOG_ATTACH_DETACH, un,
- "sd_dr_detach: Detach failure due to outstanding cmds\n");
- goto err_stillbusy;
- }
-
- /*
* If we have the device reserved, release the reservation.
*/
- if ((un->un_resvd_status & SD_RESERVE) &&
+ if (!devigone &&
+ (un->un_resvd_status & SD_RESERVE) &&
!(un->un_resvd_status & SD_LOST_RESERVE)) {
mutex_exit(SD_MUTEX(un));
/*
* Note: sd_reserve_release sends a command to the device
* via the sd_ioctlcmd() path, and can sleep.
*/
if (sd_reserve_release(dev, SD_RELEASE) != 0) {
SD_ERROR(SD_LOG_ATTACH_DETACH, un,
- "sd_dr_detach: Cannot release reservation \n");
+ "%s: cannot release reservation\n", __func__);
}
} else {
mutex_exit(SD_MUTEX(un));
}
@@ -8682,10 +8669,17 @@
/* Remove any pending reservation reclaim requests for this device */
sd_rmv_resv_reclaim_req(dev);
mutex_enter(SD_MUTEX(un));
+ if (un->un_retry_timeid != NULL) {
+ timeout_id_t temp_id = un->un_retry_timeid;
+ un->un_retry_timeid = NULL;
+ mutex_exit(SD_MUTEX(un));
+ (void) untimeout(temp_id);
+ mutex_enter(SD_MUTEX(un));
+ }
/* Cancel any pending callbacks for SD_PATH_DIRECT_PRIORITY cmd. */
if (un->un_direct_priority_timeid != NULL) {
timeout_id_t temp_id = un->un_direct_priority_timeid;
un->un_direct_priority_timeid = NULL;
@@ -8699,11 +8693,11 @@
mutex_exit(SD_MUTEX(un));
_NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_mhd_token));
if (scsi_watch_request_terminate(un->un_mhd_token,
SCSI_WATCH_TERMINATE_NOWAIT)) {
SD_ERROR(SD_LOG_ATTACH_DETACH, un,
- "sd_dr_detach: Cannot cancel mhd watch request\n");
+ "%s: cannot cancel mhd watch request\n", __func__);
/*
* Note: We are returning here after having removed
* some driver timeouts above. This is consistent with
* the legacy implementation but perhaps the watch
* terminate call should be made with the wait flag set.
@@ -8718,11 +8712,11 @@
mutex_exit(SD_MUTEX(un));
_NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_swr_token));
if (scsi_watch_request_terminate(un->un_swr_token,
SCSI_WATCH_TERMINATE_NOWAIT)) {
SD_ERROR(SD_LOG_ATTACH_DETACH, un,
- "sd_dr_detach: Cannot cancel swr watch request\n");
+ "%s: cannot cancel swr watch request\n", __func__);
/*
* Note: We are returning here after having removed
* some driver timeouts above. This is consistent with
* the legacy implementation but perhaps the watch
* terminate call should be made with the wait flag set.
@@ -8731,17 +8725,16 @@
}
mutex_enter(SD_MUTEX(un));
un->un_swr_token = NULL;
}
- mutex_exit(SD_MUTEX(un));
-
/*
* Clear any scsi_reset_notifies. We clear the reset notifies
* if we have not registered one.
* Note: The sd_mhd_reset_notify_cb() fn tries to acquire SD_MUTEX!
*/
+ mutex_exit(SD_MUTEX(un));
(void) scsi_reset_notify(SD_ADDRESS(un), SCSI_RESET_CANCEL,
sd_mhd_reset_notify_cb, (caddr_t)un);
/*
* protect the timeout pointers from getting nulled by
@@ -8789,13 +8782,13 @@
mutex_exit(&un->un_pm_mutex);
if ((un->un_f_pm_is_enabled == TRUE) &&
(pm_lower_power(SD_DEVINFO(un), 0, SD_PM_STATE_STOPPED(un))
!= DDI_SUCCESS)) {
SD_ERROR(SD_LOG_ATTACH_DETACH, un,
- "sd_dr_detach: Lower power request failed, ignoring.\n");
+ "%s: lower power request failed, ignoring\n",
+ __func__);
/*
- * Fix for bug: 4297749, item # 13
* The above test now includes a check to see if PM is
* supported by this device before call
* pm_lower_power().
* Note, the following is not dead code. The call to
* pm_lower_power above will generate a call back into
@@ -8854,11 +8847,11 @@
* substantial cleanup above. This is consistent
* with the legacy implementation but this may not
* be the right thing to do.
*/
SD_ERROR(SD_LOG_ATTACH_DETACH, un,
- "sd_dr_detach: Cannot cancel insert event\n");
+ "%s: cannot cancel insert event\n", __func__);
goto err_remove_event;
}
un->un_insert_event = NULL;
if ((un->un_remove_event != NULL) &&
@@ -8869,11 +8862,11 @@
* substantial cleanup above. This is consistent
* with the legacy implementation but this may not
* be the right thing to do.
*/
SD_ERROR(SD_LOG_ATTACH_DETACH, un,
- "sd_dr_detach: Cannot cancel remove event\n");
+ "%s: cannot cancel remove event\n", __func__);
goto err_remove_event;
}
un->un_remove_event = NULL;
}
@@ -9012,11 +9005,11 @@
err_remove_event:
mutex_enter(&sd_detach_mutex);
un->un_detach_count--;
mutex_exit(&sd_detach_mutex);
- SD_TRACE(SD_LOG_ATTACH_DETACH, un, "sd_unit_detach: exit failure\n");
+ SD_TRACE(SD_LOG_ATTACH_DETACH, un, "%s: exit failure\n", __func__);
return (DDI_FAILURE);
}
/*