6197 return (DDI_FAILURE);
6198 }
6199
6200
6201 un->un_save_state = un->un_last_state;
6202 New_state(un, SD_STATE_SUSPENDED);
6203
6204 /*
6205 * Wait for all commands that are in transport or queued to a timer
6206 * for retry to complete.
6207 *
6208 * While waiting, no new commands will be accepted or sent because of
6209 * the new state we set above.
6210 *
6211 * Wait till current operation has completed. If we are in the resource
6212 * wait state (with an intr outstanding) then we need to wait till the
6213 * intr completes and starts the next cmd. We want to wait for
6214 * SD_WAIT_CMDS_COMPLETE seconds before failing the DDI_SUSPEND.
6215 */
6216 wait_cmds_complete = ddi_get_lbolt() +
6217 (sd_wait_cmds_complete * drv_usectohz(1000000));
6218
6219 while (un->un_ncmds_in_transport != 0) {
6220 /*
6221 * Fail if commands do not finish in the specified time.
6222 */
6223 if (cv_timedwait(&un->un_disk_busy_cv, SD_MUTEX(un),
6224 wait_cmds_complete) == -1) {
6225 /*
6226 * Undo the state changes made above. Everything
6227 * must go back to it's original value.
6228 */
6229 Restore_state(un);
6230 un->un_last_state = un->un_save_state;
6231 /* Wake up any threads that might be waiting. */
6232 cv_broadcast(&un->un_suspend_cv);
6233 mutex_exit(SD_MUTEX(un));
6234 SD_ERROR(SD_LOG_IO_PM, un,
6235 "sd_ddi_suspend: failed due to outstanding cmds\n");
6236 SD_TRACE(SD_LOG_IO_PM, un, "sd_ddi_suspend: exiting\n");
6237 return (DDI_FAILURE);
6830 * can be effective again.
6831 *
6832 * To effect this behavior, call pm_busy_component to
6833 * indicate to the framework this device is busy.
6834 * By not adjusting un_pm_count the rest of PM in
6835 * the driver will function normally, and independent
6836 * of this but because the framework is told the device
6837 * is busy it won't attempt powering down until it gets
6838 * a matching idle. The timeout handler sends this.
6839 * Note: sd_pm_entry can't be called here to do this
6840 * because sdpower may have been called as a result
6841 * of a call to pm_raise_power from within sd_pm_entry.
6842 *
6843 * If a timeout handler is already active then
6844 * don't install another.
6845 */
6846 mutex_enter(&un->un_pm_mutex);
6847 if (un->un_pm_timeid == NULL) {
6848 un->un_pm_timeid =
6849 timeout(sd_pm_timeout_handler,
6850 un, intvlp * drv_usectohz(1000000));
6851 mutex_exit(&un->un_pm_mutex);
6852 (void) pm_busy_component(SD_DEVINFO(un), 0);
6853 } else {
6854 mutex_exit(&un->un_pm_mutex);
6855 }
6856 if (got_semaphore_here != 0) {
6857 sema_v(&un->un_semoclose);
6858 }
6859 /*
6860 * On exit put the state back to it's original value
6861 * and broadcast to anyone waiting for the power
6862 * change completion.
6863 */
6864 mutex_enter(SD_MUTEX(un));
6865 un->un_state = state_before_pm;
6866 cv_broadcast(&un->un_suspend_cv);
6867 mutex_exit(SD_MUTEX(un));
6868
6869 SD_TRACE(SD_LOG_IO_PM, un, "sdpower: exit, "
6870 "trans check Failed, not ok to power cycle.\n");
|
6197 return (DDI_FAILURE);
6198 }
6199
6200
6201 un->un_save_state = un->un_last_state;
6202 New_state(un, SD_STATE_SUSPENDED);
6203
6204 /*
6205 * Wait for all commands that are in transport or queued to a timer
6206 * for retry to complete.
6207 *
6208 * While waiting, no new commands will be accepted or sent because of
6209 * the new state we set above.
6210 *
6211 * Wait till current operation has completed. If we are in the resource
6212 * wait state (with an intr outstanding) then we need to wait till the
6213 * intr completes and starts the next cmd. We want to wait for
6214 * SD_WAIT_CMDS_COMPLETE seconds before failing the DDI_SUSPEND.
6215 */
6216 wait_cmds_complete = ddi_get_lbolt() +
6217 drv_sectohz(sd_wait_cmds_complete);
6218
6219 while (un->un_ncmds_in_transport != 0) {
6220 /*
6221 * Fail if commands do not finish in the specified time.
6222 */
6223 if (cv_timedwait(&un->un_disk_busy_cv, SD_MUTEX(un),
6224 wait_cmds_complete) == -1) {
6225 /*
6226 * Undo the state changes made above. Everything
6227 * must go back to it's original value.
6228 */
6229 Restore_state(un);
6230 un->un_last_state = un->un_save_state;
6231 /* Wake up any threads that might be waiting. */
6232 cv_broadcast(&un->un_suspend_cv);
6233 mutex_exit(SD_MUTEX(un));
6234 SD_ERROR(SD_LOG_IO_PM, un,
6235 "sd_ddi_suspend: failed due to outstanding cmds\n");
6236 SD_TRACE(SD_LOG_IO_PM, un, "sd_ddi_suspend: exiting\n");
6237 return (DDI_FAILURE);
6830 * can be effective again.
6831 *
6832 * To effect this behavior, call pm_busy_component to
6833 * indicate to the framework this device is busy.
6834 * By not adjusting un_pm_count the rest of PM in
6835 * the driver will function normally, and independent
6836 * of this but because the framework is told the device
6837 * is busy it won't attempt powering down until it gets
6838 * a matching idle. The timeout handler sends this.
6839 * Note: sd_pm_entry can't be called here to do this
6840 * because sdpower may have been called as a result
6841 * of a call to pm_raise_power from within sd_pm_entry.
6842 *
6843 * If a timeout handler is already active then
6844 * don't install another.
6845 */
6846 mutex_enter(&un->un_pm_mutex);
6847 if (un->un_pm_timeid == NULL) {
6848 un->un_pm_timeid =
6849 timeout(sd_pm_timeout_handler,
6850 un, drv_sectohz(intvlp));
6851 mutex_exit(&un->un_pm_mutex);
6852 (void) pm_busy_component(SD_DEVINFO(un), 0);
6853 } else {
6854 mutex_exit(&un->un_pm_mutex);
6855 }
6856 if (got_semaphore_here != 0) {
6857 sema_v(&un->un_semoclose);
6858 }
6859 /*
6860 * On exit put the state back to it's original value
6861 * and broadcast to anyone waiting for the power
6862 * change completion.
6863 */
6864 mutex_enter(SD_MUTEX(un));
6865 un->un_state = state_before_pm;
6866 cv_broadcast(&un->un_suspend_cv);
6867 mutex_exit(SD_MUTEX(un));
6868
6869 SD_TRACE(SD_LOG_IO_PM, un, "sdpower: exit, "
6870 "trans check Failed, not ok to power cycle.\n");
|