[PATCH] ide: Workaround PM problem

The logic in ide_do_request() doesn't guarantee that both drives will be
serviced after a call. It may "forget" to service one in some
circumstances, including when one of the drive is suspended (it will
eventually fail to service the slave when the master is suspended for
example). This prevents the wakeup requests that gets queued on wakeup
from sleep from beeing serviced in some cases when 2 drives are sharing
an IDE bus.

The problem is deep enough in the way this code works (and there are
probably a few other problematic but rare corner cases) and fixing it
would require some major rethinking of the way IDE decides which channel
to service. This is not 2.6.14 material. However, in the meantime,
Bart has accepted this simple workaround that will fix the crash on
wakeup from sleep since this specific corner case is actually hitting
users to get into 2.6.14.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Benjamin Herrenschmidt and committed by Linus Torvalds 867f8b4e 1cc956e1

+8
+8
drivers/ide/ide-io.c
··· 1101 1101 ide_hwif_t *hwif; 1102 1102 struct request *rq; 1103 1103 ide_startstop_t startstop; 1104 + int loops = 0; 1104 1105 1105 1106 /* for atari only: POSSIBLY BROKEN HERE(?) */ 1106 1107 ide_get_lock(ide_intr, hwgroup); ··· 1154 1153 /* no more work for this hwgroup (for now) */ 1155 1154 return; 1156 1155 } 1156 + again: 1157 1157 hwif = HWIF(drive); 1158 1158 if (hwgroup->hwif->sharing_irq && 1159 1159 hwif != hwgroup->hwif && ··· 1194 1192 * though. I hope that doesn't happen too much, hopefully not 1195 1193 * unless the subdriver triggers such a thing in its own PM 1196 1194 * state machine. 1195 + * 1196 + * We count how many times we loop here to make sure we service 1197 + * all drives in the hwgroup without looping for ever 1197 1198 */ 1198 1199 if (drive->blocked && !blk_pm_request(rq) && !(rq->flags & REQ_PREEMPT)) { 1200 + drive = drive->next ? drive->next : hwgroup->drive; 1201 + if (loops++ < 4 && !blk_queue_plugged(drive->queue)) 1202 + goto again; 1199 1203 /* We clear busy, there should be no pending ATA command at this point. */ 1200 1204 hwgroup->busy = 0; 1201 1205 break;