Fix cdrom error handling in 2.4
PATCH 1/1 Fix cdrom error handling in 2.4
In both 2.4 and in 2.6, error handling for bad cdrom media is wrong. And it is my fault I'm afraid, since I botched an earlier fix for the problem by putting the fix in the wrong spot.
My kids have a "Jumpstart Toddlers" cd they have long since completely killed, which makes a great test disc. Without this fix, the best time projection I can get for completing a dd type sector copy is about 2 years... Most of that is spent thrashing about in kernel space trying to re-read sectors we already know are not correctable.... After the fix, I was able to rip a copy the CD (or rather muddle through it getting lots of EIO errors) in about 15 minutes.
Attached is the fix for 2.4.x, which just moves the MEDIUM_ERROR handler a bit earlier. I have also included a minor error path cleanup from the 2.6.x driver,
-Erik
--
Erik B. Andersen http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--
drivers/ide/ide-cd.c renamed from drivers/ide/ide-cd.c.orig +14 -9
@@ -765,6 +765,8 @@if ((stat &ERR_STAT ) !=0 )cdrom_queue_request_sense (drive, wait, pc->sense, pc); }else if (blk_fs_request (rq)) { +int do_end_request =0 ; +/* Handle errors from READ and WRITE requests. */ if (sense_key ==NOT_READY ) {
@@ -773,7 +775,7 @@/* Fail the request. */ printk ("%s: tray open\n" , drive->name); -cdrom_end_request (drive,0 ); + do_end_request =1 ; }else if (sense_key ==UNIT_ATTENTION ) {/* Media change. */ cdrom_saw_media_change (drive);
@@ -782,28 +784,31 @@But be sure to give up if we've retried too many times. */ if (++rq->errors >ERROR_MAX ) -cdrom_end_request (drive,0 ); + do_end_request =1 ; }else if (sense_key ==ILLEGAL_REQUEST || sense_key ==DATA_PROTECT ) {/* No point in retrying after an illegal request or data protect error.*/ ide_dump_status (drive,"command error" , stat); -cdrom_end_request (drive,0 ); + do_end_request =1 ; + }else if (sense_key ==MEDIUM_ERROR ) { +/* No point in re-trying a zillion times on a bad +* sector... If we got here the error is not correctable */ +ide_dump_status (drive,"media error (bad sector)" , stat); + do_end_request =1 ; }else if ((err & ~ABRT_ERR ) !=0 ) {/* Go to the default handler for other errors. */ *startstop =DRIVER (drive)->error (drive,"cdrom_decode_status" , stat);return 1 ; - }else if (sense_key ==MEDIUM_ERROR ) { -/* No point in re-trying a zillion times on a bad -* sector... If we got here the error is not correctable */ -ide_dump_status (drive,"media error (bad sector)" , stat); -cdrom_end_request (drive,0 ); }else if ((++rq->errors >ERROR_MAX )) {/* We've racked up too many retries. Abort. */ -cdrom_end_request (drive,0 ); + do_end_request =1 ; } +if (do_end_request) +cdrom_end_request (drive,0 ); +/* If we got a CHECK_CONDITION status, queue a request sense command. */ if ((stat &ERR_STAT ) !=0 )