Skip to content

Commit

Permalink
ide: move Power Management support to ide-pm.c
Browse files Browse the repository at this point in the history
There should be no functional changes caused by this patch.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
  • Loading branch information
bzolnier committed Dec 29, 2008
1 parent 1d35364 commit e2984c6
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 234 deletions.
2 changes: 1 addition & 1 deletion drivers/ide/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
EXTRA_CFLAGS += -Idrivers/ide

ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
ide-taskfile.o ide-park.o ide-pio-blacklist.o
ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o

# core IDE code
ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o
Expand Down
159 changes: 0 additions & 159 deletions drivers/ide/ide-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,98 +120,6 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
}
EXPORT_SYMBOL(ide_end_request);

static void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
{
struct request_pm_state *pm = rq->data;

#ifdef DEBUG_PM
printk(KERN_INFO "%s: complete_power_step(step: %d)\n",
drive->name, pm->pm_step);
#endif
if (drive->media != ide_disk)
return;

switch (pm->pm_step) {
case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */
if (pm->pm_state == PM_EVENT_FREEZE)
pm->pm_step = IDE_PM_COMPLETED;
else
pm->pm_step = IDE_PM_STANDBY;
break;
case IDE_PM_STANDBY: /* Suspend step 2 (standby) */
pm->pm_step = IDE_PM_COMPLETED;
break;
case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */
pm->pm_step = IDE_PM_IDLE;
break;
case IDE_PM_IDLE: /* Resume step 2 (idle)*/
pm->pm_step = IDE_PM_RESTORE_DMA;
break;
}
}

static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
{
struct request_pm_state *pm = rq->data;
ide_task_t *args = rq->special;

memset(args, 0, sizeof(*args));

switch (pm->pm_step) {
case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */
if (drive->media != ide_disk)
break;
/* Not supported? Switch to next step now. */
if (ata_id_flush_enabled(drive->id) == 0 ||
(drive->dev_flags & IDE_DFLAG_WCACHE) == 0) {
ide_complete_power_step(drive, rq);
return ide_stopped;
}
if (ata_id_flush_ext_enabled(drive->id))
args->tf.command = ATA_CMD_FLUSH_EXT;
else
args->tf.command = ATA_CMD_FLUSH;
goto out_do_tf;
case IDE_PM_STANDBY: /* Suspend step 2 (standby) */
args->tf.command = ATA_CMD_STANDBYNOW1;
goto out_do_tf;
case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */
ide_set_max_pio(drive);
/*
* skip IDE_PM_IDLE for ATAPI devices
*/
if (drive->media != ide_disk)
pm->pm_step = IDE_PM_RESTORE_DMA;
else
ide_complete_power_step(drive, rq);
return ide_stopped;
case IDE_PM_IDLE: /* Resume step 2 (idle) */
args->tf.command = ATA_CMD_IDLEIMMEDIATE;
goto out_do_tf;
case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */
/*
* Right now, all we do is call ide_set_dma(drive),
* we could be smarter and check for current xfer_speed
* in struct drive etc...
*/
if (drive->hwif->dma_ops == NULL)
break;
/*
* TODO: respect IDE_DFLAG_USING_DMA
*/
ide_set_dma(drive);
break;
}

pm->pm_step = IDE_PM_COMPLETED;
return ide_stopped;

out_do_tf:
args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
args->data_phase = TASKFILE_NO_DATA;
return do_rw_taskfile(drive, args);
}

/**
* ide_end_dequeued_request - complete an IDE I/O
* @drive: IDE device for the I/O
Expand All @@ -236,39 +144,6 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
}
EXPORT_SYMBOL_GPL(ide_end_dequeued_request);


/**
* ide_complete_pm_request - end the current Power Management request
* @drive: target drive
* @rq: request
*
* This function cleans up the current PM request and stops the queue
* if necessary.
*/
static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
{
struct request_queue *q = drive->queue;
unsigned long flags;

#ifdef DEBUG_PM
printk("%s: completing PM request, %s\n", drive->name,
blk_pm_suspend_request(rq) ? "suspend" : "resume");
#endif
spin_lock_irqsave(q->queue_lock, flags);
if (blk_pm_suspend_request(rq)) {
blk_stop_queue(q);
} else {
drive->dev_flags &= ~IDE_DFLAG_BLOCKED;
blk_start_queue(q);
}
spin_unlock_irqrestore(q->queue_lock, flags);

drive->hwif->hwgroup->rq = NULL;

if (blk_end_request(rq, 0, 0))
BUG();
}

/**
* ide_end_drive_cmd - end an explicit drive command
* @drive: command
Expand Down Expand Up @@ -697,40 +572,6 @@ static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
}
}

static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
{
struct request_pm_state *pm = rq->data;

if (blk_pm_suspend_request(rq) &&
pm->pm_step == IDE_PM_START_SUSPEND)
/* Mark drive blocked when starting the suspend sequence. */
drive->dev_flags |= IDE_DFLAG_BLOCKED;
else if (blk_pm_resume_request(rq) &&
pm->pm_step == IDE_PM_START_RESUME) {
/*
* The first thing we do on wakeup is to wait for BSY bit to
* go away (with a looong timeout) as a drive on this hwif may
* just be POSTing itself.
* We do that before even selecting as the "other" device on
* the bus may be broken enough to walk on our toes at this
* point.
*/
ide_hwif_t *hwif = drive->hwif;
int rc;
#ifdef DEBUG_PM
printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name);
#endif
rc = ide_wait_not_busy(hwif, 35000);
if (rc)
printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
SELECT_DRIVE(drive);
hwif->tp_ops->set_irq(hwif, 1);
rc = ide_wait_not_busy(hwif, 100000);
if (rc)
printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
}
}

/**
* start_request - start of I/O and command issuing for IDE
*
Expand Down
Loading

0 comments on commit e2984c6

Please sign in to comment.