-/*
- * Power Management state machine. This one is rather trivial for now,
- * we should probably add more, like switching back to PIO on suspend
- * to help some BIOSes, re-do the door locking on resume, etc...
- */
-
-enum {
- idedisk_pm_flush_cache = ide_pm_state_start_suspend,
- idedisk_pm_standby,
-
- idedisk_pm_idle = ide_pm_state_start_resume,
- idedisk_pm_restore_dma,
-};
-
-static void idedisk_complete_power_step (ide_drive_t *drive, struct request *rq, u8 stat, u8 error)
-{
- switch (rq->pm->pm_step) {
- case idedisk_pm_flush_cache: /* Suspend step 1 (flush cache) complete */
- if (rq->pm->pm_state == 4)
- rq->pm->pm_step = ide_pm_state_completed;
- else
- rq->pm->pm_step = idedisk_pm_standby;
- break;
- case idedisk_pm_standby: /* Suspend step 2 (standby) complete */
- rq->pm->pm_step = ide_pm_state_completed;
- break;
- case idedisk_pm_idle: /* Resume step 1 (idle) complete */
- rq->pm->pm_step = idedisk_pm_restore_dma;
- break;
- }
-}
-
-static ide_startstop_t idedisk_start_power_step (ide_drive_t *drive, struct request *rq)
-{
- ide_task_t *args = rq->special;
-
- memset(args, 0, sizeof(*args));
-
- switch (rq->pm->pm_step) {
- case idedisk_pm_flush_cache: /* Suspend step 1 (flush cache) */
- /* Not supported? Switch to next step now. */
- if (!drive->wcache || !ide_id_has_flush_cache(drive->id)) {
- idedisk_complete_power_step(drive, rq, 0, 0);
- return ide_stopped;
- }
- if (ide_id_has_flush_cache_ext(drive->id))
- args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT;
- else
- args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE;
- args->command_type = IDE_DRIVE_TASK_NO_DATA;
- args->handler = &task_no_data_intr;
- return do_rw_taskfile(drive, args);
-
- case idedisk_pm_standby: /* Suspend step 2 (standby) */
- args->tfRegister[IDE_COMMAND_OFFSET] = WIN_STANDBYNOW1;
- args->command_type = IDE_DRIVE_TASK_NO_DATA;
- args->handler = &task_no_data_intr;
- return do_rw_taskfile(drive, args);
-
- case idedisk_pm_idle: /* Resume step 1 (idle) */
- args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE;
- args->command_type = IDE_DRIVE_TASK_NO_DATA;
- args->handler = task_no_data_intr;
- return do_rw_taskfile(drive, args);
-
- case idedisk_pm_restore_dma: /* Resume step 2 (restore DMA) */
- /*
- * Right now, all we do is call hwif->ide_dma_check(drive),
- * we could be smarter and check for current xfer_speed
- * in struct drive etc...
- * Also, this step could be implemented as a generic helper
- * as most subdrivers will use it
- */
- if ((drive->id->capability & 1) == 0)
- break;
- if (HWIF(drive)->ide_dma_check == NULL)
- break;
- HWIF(drive)->ide_dma_check(drive);
- break;
- }
- rq->pm->pm_step = ide_pm_state_completed;
- return ide_stopped;
-}
-