aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-io.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2006-06-25 08:47:44 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 13:01:06 -0400
commitdbe217af3be08346f4b1abb885c2d9ec29c98fac (patch)
tree493ee2547ba3095d7aa468d6ddffc1a82f18ce56 /drivers/ide/ide-io.c
parent8e3a67a99231f9f3f476bc3449e93c9a6a17f2e0 (diff)
[PATCH] IDE CD end-of media error fix
This is a patch from Alan that fixes a real ide-cd.c regression causing bogus "Media Check" failures for perfectly valid Fedora install ISOs, on certain CD-ROM drives. This is a forward port to 2.6.16 (from RHEL) of the minimal changes for the end of media problem. It may not be sufficient for some controllers (promise notably) and it does not touch the locking so the error path locking is as horked as in mainstream. From: Ingo Molnar <mingo@elte.hu> I have ported the patch to 2.6.17-rc4 and tested it by provoking end-of-media IO errors with an unaligned ISO image. Unlike the vanilla kernel, the patched kernel interpreted the error condition correctly with 512 byte granularity: hdc: command error: status=0x51 { DriveReady SeekComplete Error } hdc: command error: error=0x54 { AbortedCommand LastFailedSense=0x05 } ide: failed opcode was: unknown ATAPI device hdc: Error: Illegal request -- (Sense key=0x05) Illegal mode for this track or incompatible medium -- (asc=0x64, ascq=0x00) The failed "Read 10" packet command was: "28 00 00 04 fb 78 00 00 06 00 00 00 00 00 00 00 " end_request: I/O error, dev hdc, sector 1306080 Buffer I/O error on device hdc, logical block 163260 Buffer I/O error on device hdc, logical block 163261 Buffer I/O error on device hdc, logical block 163262 the unpatched kernel produces an incorrect error dump: hdc: command error: status=0x51 { DriveReady SeekComplete Error } hdc: command error: error=0x54 { AbortedCommand LastFailedSense=0x05 } ide: failed opcode was: unknown end_request: I/O error, dev hdc, sector 1306080 Buffer I/O error on device hdc, logical block 163260 hdc: command error: status=0x51 { DriveReady SeekComplete Error } hdc: command error: error=0x54 { AbortedCommand LastFailedSense=0x05 } ide: failed opcode was: unknown end_request: I/O error, dev hdc, sector 1306088 Buffer I/O error on device hdc, logical block 163261 hdc: command error: status=0x51 { DriveReady SeekComplete Error } hdc: command error: error=0x54 { AbortedCommand LastFailedSense=0x05 } ide: failed opcode was: unknown end_request: I/O error, dev hdc, sector 1306096 Buffer I/O error on device hdc, logical block 163262 I do not have the right type of CD-ROM drive to reproduce the end-of-media data corruption bug myself, but this same patch in RHEL solved it. Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl> Cc: Jens Axboe <axboe@suse.de> Cc: Matt Mackall <mpm@selenic.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r--drivers/ide/ide-io.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 4f2f138de2c..622a55c72f0 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -223,6 +223,63 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
223} 223}
224 224
225/** 225/**
226 * ide_end_dequeued_request - complete an IDE I/O
227 * @drive: IDE device for the I/O
228 * @uptodate:
229 * @nr_sectors: number of sectors completed
230 *
231 * Complete an I/O that is no longer on the request queue. This
232 * typically occurs when we pull the request and issue a REQUEST_SENSE.
233 * We must still finish the old request but we must not tamper with the
234 * queue in the meantime.
235 *
236 * NOTE: This path does not handle barrier, but barrier is not supported
237 * on ide-cd anyway.
238 */
239
240int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
241 int uptodate, int nr_sectors)
242{
243 unsigned long flags;
244 int ret = 1;
245
246 spin_lock_irqsave(&ide_lock, flags);
247
248 BUG_ON(!(rq->flags & REQ_STARTED));
249
250 /*
251 * if failfast is set on a request, override number of sectors and
252 * complete the whole request right now
253 */
254 if (blk_noretry_request(rq) && end_io_error(uptodate))
255 nr_sectors = rq->hard_nr_sectors;
256
257 if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors)
258 rq->errors = -EIO;
259
260 /*
261 * decide whether to reenable DMA -- 3 is a random magic for now,
262 * if we DMA timeout more than 3 times, just stay in PIO
263 */
264 if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
265 drive->state = 0;
266 HWGROUP(drive)->hwif->ide_dma_on(drive);
267 }
268
269 if (!end_that_request_first(rq, uptodate, nr_sectors)) {
270 add_disk_randomness(rq->rq_disk);
271 if (blk_rq_tagged(rq))
272 blk_queue_end_tag(drive->queue, rq);
273 end_that_request_last(rq, uptodate);
274 ret = 0;
275 }
276 spin_unlock_irqrestore(&ide_lock, flags);
277 return ret;
278}
279EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
280
281
282/**
226 * ide_complete_pm_request - end the current Power Management request 283 * ide_complete_pm_request - end the current Power Management request
227 * @drive: target drive 284 * @drive: target drive
228 * @rq: request 285 * @rq: request