diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-12-29 14:27:37 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-12-29 14:27:37 -0500 |
commit | e2984c628c924442132304ae662da433f41c05c9 (patch) | |
tree | c7ed2d995fbd96fc9e4cdd12c395640bd2e6fab5 /drivers/ide/ide-io.c | |
parent | 1d35364acbd5ab7d67bb39cfc5dd3ed0fbefb4b8 (diff) |
ide: move Power Management support to ide-pm.c
There should be no functional changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r-- | drivers/ide/ide-io.c | 159 |
1 files changed, 0 insertions, 159 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 26d3f3cacc8a..ecacc008fdaf 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -120,98 +120,6 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) | |||
120 | } | 120 | } |
121 | EXPORT_SYMBOL(ide_end_request); | 121 | EXPORT_SYMBOL(ide_end_request); |
122 | 122 | ||
123 | static void ide_complete_power_step(ide_drive_t *drive, struct request *rq) | ||
124 | { | ||
125 | struct request_pm_state *pm = rq->data; | ||
126 | |||
127 | #ifdef DEBUG_PM | ||
128 | printk(KERN_INFO "%s: complete_power_step(step: %d)\n", | ||
129 | drive->name, pm->pm_step); | ||
130 | #endif | ||
131 | if (drive->media != ide_disk) | ||
132 | return; | ||
133 | |||
134 | switch (pm->pm_step) { | ||
135 | case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ | ||
136 | if (pm->pm_state == PM_EVENT_FREEZE) | ||
137 | pm->pm_step = IDE_PM_COMPLETED; | ||
138 | else | ||
139 | pm->pm_step = IDE_PM_STANDBY; | ||
140 | break; | ||
141 | case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ | ||
142 | pm->pm_step = IDE_PM_COMPLETED; | ||
143 | break; | ||
144 | case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ | ||
145 | pm->pm_step = IDE_PM_IDLE; | ||
146 | break; | ||
147 | case IDE_PM_IDLE: /* Resume step 2 (idle)*/ | ||
148 | pm->pm_step = IDE_PM_RESTORE_DMA; | ||
149 | break; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) | ||
154 | { | ||
155 | struct request_pm_state *pm = rq->data; | ||
156 | ide_task_t *args = rq->special; | ||
157 | |||
158 | memset(args, 0, sizeof(*args)); | ||
159 | |||
160 | switch (pm->pm_step) { | ||
161 | case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ | ||
162 | if (drive->media != ide_disk) | ||
163 | break; | ||
164 | /* Not supported? Switch to next step now. */ | ||
165 | if (ata_id_flush_enabled(drive->id) == 0 || | ||
166 | (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) { | ||
167 | ide_complete_power_step(drive, rq); | ||
168 | return ide_stopped; | ||
169 | } | ||
170 | if (ata_id_flush_ext_enabled(drive->id)) | ||
171 | args->tf.command = ATA_CMD_FLUSH_EXT; | ||
172 | else | ||
173 | args->tf.command = ATA_CMD_FLUSH; | ||
174 | goto out_do_tf; | ||
175 | case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ | ||
176 | args->tf.command = ATA_CMD_STANDBYNOW1; | ||
177 | goto out_do_tf; | ||
178 | case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ | ||
179 | ide_set_max_pio(drive); | ||
180 | /* | ||
181 | * skip IDE_PM_IDLE for ATAPI devices | ||
182 | */ | ||
183 | if (drive->media != ide_disk) | ||
184 | pm->pm_step = IDE_PM_RESTORE_DMA; | ||
185 | else | ||
186 | ide_complete_power_step(drive, rq); | ||
187 | return ide_stopped; | ||
188 | case IDE_PM_IDLE: /* Resume step 2 (idle) */ | ||
189 | args->tf.command = ATA_CMD_IDLEIMMEDIATE; | ||
190 | goto out_do_tf; | ||
191 | case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */ | ||
192 | /* | ||
193 | * Right now, all we do is call ide_set_dma(drive), | ||
194 | * we could be smarter and check for current xfer_speed | ||
195 | * in struct drive etc... | ||
196 | */ | ||
197 | if (drive->hwif->dma_ops == NULL) | ||
198 | break; | ||
199 | /* | ||
200 | * TODO: respect IDE_DFLAG_USING_DMA | ||
201 | */ | ||
202 | ide_set_dma(drive); | ||
203 | break; | ||
204 | } | ||
205 | |||
206 | pm->pm_step = IDE_PM_COMPLETED; | ||
207 | return ide_stopped; | ||
208 | |||
209 | out_do_tf: | ||
210 | args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | ||
211 | args->data_phase = TASKFILE_NO_DATA; | ||
212 | return do_rw_taskfile(drive, args); | ||
213 | } | ||
214 | |||
215 | /** | 123 | /** |
216 | * ide_end_dequeued_request - complete an IDE I/O | 124 | * ide_end_dequeued_request - complete an IDE I/O |
217 | * @drive: IDE device for the I/O | 125 | * @drive: IDE device for the I/O |
@@ -236,39 +144,6 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, | |||
236 | } | 144 | } |
237 | EXPORT_SYMBOL_GPL(ide_end_dequeued_request); | 145 | EXPORT_SYMBOL_GPL(ide_end_dequeued_request); |
238 | 146 | ||
239 | |||
240 | /** | ||
241 | * ide_complete_pm_request - end the current Power Management request | ||
242 | * @drive: target drive | ||
243 | * @rq: request | ||
244 | * | ||
245 | * This function cleans up the current PM request and stops the queue | ||
246 | * if necessary. | ||
247 | */ | ||
248 | static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) | ||
249 | { | ||
250 | struct request_queue *q = drive->queue; | ||
251 | unsigned long flags; | ||
252 | |||
253 | #ifdef DEBUG_PM | ||
254 | printk("%s: completing PM request, %s\n", drive->name, | ||
255 | blk_pm_suspend_request(rq) ? "suspend" : "resume"); | ||
256 | #endif | ||
257 | spin_lock_irqsave(q->queue_lock, flags); | ||
258 | if (blk_pm_suspend_request(rq)) { | ||
259 | blk_stop_queue(q); | ||
260 | } else { | ||
261 | drive->dev_flags &= ~IDE_DFLAG_BLOCKED; | ||
262 | blk_start_queue(q); | ||
263 | } | ||
264 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
265 | |||
266 | drive->hwif->hwgroup->rq = NULL; | ||
267 | |||
268 | if (blk_end_request(rq, 0, 0)) | ||
269 | BUG(); | ||
270 | } | ||
271 | |||
272 | /** | 147 | /** |
273 | * ide_end_drive_cmd - end an explicit drive command | 148 | * ide_end_drive_cmd - end an explicit drive command |
274 | * @drive: command | 149 | * @drive: command |
@@ -697,40 +572,6 @@ static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) | |||
697 | } | 572 | } |
698 | } | 573 | } |
699 | 574 | ||
700 | static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) | ||
701 | { | ||
702 | struct request_pm_state *pm = rq->data; | ||
703 | |||
704 | if (blk_pm_suspend_request(rq) && | ||
705 | pm->pm_step == IDE_PM_START_SUSPEND) | ||
706 | /* Mark drive blocked when starting the suspend sequence. */ | ||
707 | drive->dev_flags |= IDE_DFLAG_BLOCKED; | ||
708 | else if (blk_pm_resume_request(rq) && | ||
709 | pm->pm_step == IDE_PM_START_RESUME) { | ||
710 | /* | ||
711 | * The first thing we do on wakeup is to wait for BSY bit to | ||
712 | * go away (with a looong timeout) as a drive on this hwif may | ||
713 | * just be POSTing itself. | ||
714 | * We do that before even selecting as the "other" device on | ||
715 | * the bus may be broken enough to walk on our toes at this | ||
716 | * point. | ||
717 | */ | ||
718 | ide_hwif_t *hwif = drive->hwif; | ||
719 | int rc; | ||
720 | #ifdef DEBUG_PM | ||
721 | printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name); | ||
722 | #endif | ||
723 | rc = ide_wait_not_busy(hwif, 35000); | ||
724 | if (rc) | ||
725 | printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); | ||
726 | SELECT_DRIVE(drive); | ||
727 | hwif->tp_ops->set_irq(hwif, 1); | ||
728 | rc = ide_wait_not_busy(hwif, 100000); | ||
729 | if (rc) | ||
730 | printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); | ||
731 | } | ||
732 | } | ||
733 | |||
734 | /** | 575 | /** |
735 | * start_request - start of I/O and command issuing for IDE | 576 | * start_request - start of I/O and command issuing for IDE |
736 | * | 577 | * |