aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Lunz <lunz@falooley.org>2006-10-03 04:14:26 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-03 11:04:08 -0400
commit8c2c0118b86183bf4826db990cae5c8a8d6c6746 (patch)
tree71f7e806eccec4ef2d41fc6490395cc01bcb8123
parent3f63c5e88a5ce45b423f3712293f1664115b09c0 (diff)
[PATCH] ide: reprogram disk pio timings on resume
Add a step to the IDE PM state machine that reprograms disk PIO timings as the first step on resume. This prevents ide deadlock on resume-from-ram on my nforce3-based laptop. An earlier implementation was written entirely within the amd74xx ide driver, but Alan helpfully pointed out that this is the correct thing to do globally. Still, I'm only calling hwif->tuneproc() for disks, based on two things: - The existing state machine is already passed over for non-disk drives - Previous testing on my laptop shows that the hangs are related only to the disk - suspend/resume from a livecd showed that there's no need for this on the cdrom. Signed-off-by: Jason Lunz <lunz@falooley.org> Cc: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl> Cc: "Rafael J. Wysocki" <rjw@sisk.pl> Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com> Cc: Pavel Machek <pavel@ucw.cz> Cc: Brad Campbell <brad@wasp.net.au> Cc: David Brownell <david-b@pacbell.net> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/ide/ide-io.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 8d26619ba16b..ba6039b55b41 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -134,7 +134,8 @@ enum {
134 ide_pm_flush_cache = ide_pm_state_start_suspend, 134 ide_pm_flush_cache = ide_pm_state_start_suspend,
135 idedisk_pm_standby, 135 idedisk_pm_standby,
136 136
137 idedisk_pm_idle = ide_pm_state_start_resume, 137 idedisk_pm_restore_pio = ide_pm_state_start_resume,
138 idedisk_pm_idle,
138 ide_pm_restore_dma, 139 ide_pm_restore_dma,
139}; 140};
140 141
@@ -155,7 +156,10 @@ static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 s
155 case idedisk_pm_standby: /* Suspend step 2 (standby) complete */ 156 case idedisk_pm_standby: /* Suspend step 2 (standby) complete */
156 pm->pm_step = ide_pm_state_completed; 157 pm->pm_step = ide_pm_state_completed;
157 break; 158 break;
158 case idedisk_pm_idle: /* Resume step 1 (idle) complete */ 159 case idedisk_pm_restore_pio: /* Resume step 1 complete */
160 pm->pm_step = idedisk_pm_idle;
161 break;
162 case idedisk_pm_idle: /* Resume step 2 (idle) complete */
159 pm->pm_step = ide_pm_restore_dma; 163 pm->pm_step = ide_pm_restore_dma;
160 break; 164 break;
161 } 165 }
@@ -169,8 +173,11 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
169 memset(args, 0, sizeof(*args)); 173 memset(args, 0, sizeof(*args));
170 174
171 if (drive->media != ide_disk) { 175 if (drive->media != ide_disk) {
172 /* skip idedisk_pm_idle for ATAPI devices */ 176 /*
173 if (pm->pm_step == idedisk_pm_idle) 177 * skip idedisk_pm_restore_pio and idedisk_pm_idle for ATAPI
178 * devices
179 */
180 if (pm->pm_step == idedisk_pm_restore_pio)
174 pm->pm_step = ide_pm_restore_dma; 181 pm->pm_step = ide_pm_restore_dma;
175 } 182 }
176 183
@@ -197,13 +204,19 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
197 args->handler = &task_no_data_intr; 204 args->handler = &task_no_data_intr;
198 return do_rw_taskfile(drive, args); 205 return do_rw_taskfile(drive, args);
199 206
200 case idedisk_pm_idle: /* Resume step 1 (idle) */ 207 case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */
208 if (drive->hwif->tuneproc != NULL)
209 drive->hwif->tuneproc(drive, 255);
210 ide_complete_power_step(drive, rq, 0, 0);
211 return ide_stopped;
212
213 case idedisk_pm_idle: /* Resume step 2 (idle) */
201 args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE; 214 args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE;
202 args->command_type = IDE_DRIVE_TASK_NO_DATA; 215 args->command_type = IDE_DRIVE_TASK_NO_DATA;
203 args->handler = task_no_data_intr; 216 args->handler = task_no_data_intr;
204 return do_rw_taskfile(drive, args); 217 return do_rw_taskfile(drive, args);
205 218
206 case ide_pm_restore_dma: /* Resume step 2 (restore DMA) */ 219 case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */
207 /* 220 /*
208 * Right now, all we do is call hwif->ide_dma_check(drive), 221 * Right now, all we do is call hwif->ide_dma_check(drive),
209 * we could be smarter and check for current xfer_speed 222 * we could be smarter and check for current xfer_speed