Skip to contentSkip to conversation

cdrom sane fallback vs 2.4.20-pre1

PATCH In review Erik Andersen 4 participants 5 messages Aug 11, 2002 – Aug 16, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 cdrom sane fallback vs 2.4.20-pre1

Here is an update to cdrom.c. SCSI-II devices are not required
to support the READ_CD packet command. Currently, the cdrom driver assumes that _all_ READ_CD packet command failures are due to READ_CD being unsupported. Obviously, there are a million other reasons for a READ_CD packet command to fail. Here at my house, the most common reason for READ_CD failures is that my kids have, once again, scratched up my CDs resulting in bad sectors. So the drive hits an uncorrectable error and thinks that READ_CD is unsupported, and then trys again using READ_10 (which takes another a few seconds to fail and, of course, again returns an L-EC Uncorrectable Error).

This patch teaches cdrom.c to only fall back to READ_10 when the drive reports that we sent it an invalid command...

-Erik

--
Erik B. Andersen http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--

cdrom/cdrom.c renamed from cdrom/cdrom.c~ +4 -1
@@ -1916,6 +1916,7 @@
 {		
 	struct cdrom_device_ops *cdo = cdi->ops;
 	struct cdrom_generic_command cgc;
+	struct request_sense sense;
 	kdev_t dev = cdi->dev;
 	char buffer[32];
 	int ret = 0;
@@ -1951,9 +1952,11 @@
 		cgc.buffer = (char *) kmalloc(blocksize, GFP_KERNEL);
 		if (cgc.buffer == NULL)
 			return -ENOMEM;
+		memset(&sense, 0, sizeof(sense));
+		cgc.sense = &sense;
 		cgc.data_direction = CGC_DATA_READ;
 		ret = cdrom_read_block(cdi, &cgc, lba, 1, format, blocksize);
-		if (ret) {
+		if (ret && sense.sense_key==0x05 && sense.asc==0x20 && sense.ascq==0x00) {
 			/*
 			 * SCSI-II devices are not required to support
 			 * READ_CD, so let's try switching block size
#1 lore raw
Quoted 11 lines · Erik Andersen
cdrom/cdrom.c renamed from cdrom/cdrom.c~ +1 -0
@@ -1916,6 +1916,7 @@
 {
 	struct cdrom_device_ops *cdo = cdi->ops;
 	struct cdrom_generic_command cgc;
+	struct request_sense sense;
 	kdev_t dev = cdi->dev;
 	char buffer[32];
 	int ret = 0;

cdrom/cdrom.c line 1959

Quoted 9 lines
cdrom/cdrom.c renamed from cdrom/cdrom.c~ +3 -1
@@ -1951,9 +1952,11 @@
 		cgc.buffer = (char *) kmalloc(blocksize, GFP_KERNEL);
 		if (cgc.buffer == NULL)
 			return -ENOMEM;
+		memset(&sense, 0, sizeof(sense));
+		cgc.sense = &sense;
 		cgc.data_direction = CGC_DATA_READ;
 		ret = cdrom_read_block(cdi, &cgc, lba, 1, format, blocksize);
-		if (ret) {
+		if (ret && sense.sense_key==0x05 && sense.asc==0x20 && sense.ascq==0x00) {

Do you really need to hardcode this values ?

#2 lore raw
Quoted 18 lines · Marcelo Tosatti
Quoted 14 lines · Erik Andersen
cdrom/cdrom.c renamed from cdrom/cdrom.c~ +1 -0
@@ -1916,6 +1916,7 @@
 {
 	struct cdrom_device_ops *cdo = cdi->ops;
 	struct cdrom_generic_command cgc;
+	struct request_sense sense;
 	kdev_t dev = cdi->dev;
 	char buffer[32];
 	int ret = 0;
@@ -1951,9 +1952,11 @@
 		cgc.buffer = (char *) kmalloc(blocksize, GFP_KERNEL);
 		if (cgc.buffer == NULL)
 			return -ENOMEM;
Quoted 8 lines

cdrom/cdrom.c line 1959

Quoted 6 lines
cdrom/cdrom.c renamed from cdrom/cdrom.c~ +3 -1
+		memset(&sense, 0, sizeof(sense));
+		cgc.sense = &sense;
 		cgc.data_direction = CGC_DATA_READ;
 		ret = cdrom_read_block(cdi, &cgc, lba, 1, format, blocksize);
-		if (ret) {
+		if (ret && sense.sense_key==0x05 && sense.asc==0x20 && sense.ascq==0x00) {

Do you really need to hardcode this values ?

This allows it to falls back to READ_10 only when the drive reports "Hey! You gave me an invalid command!" which is the one and only case when a fall back to READ_10 is appropriate. I am not aware of any other reason for which a fallback to READ_10 is useful.

-Erik

--
Erik B. Andersen http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--

#3 lore raw
Quoted 27 lines · Erik Andersen
Quoted 17 lines · Marcelo Tosatti
Quoted 13 lines · Erik Andersen

+++ drivers/cdrom/cdrom.c Sun Aug 11 15:37:24 2002

cdrom/cdrom.c renamed from cdrom/cdrom.c~ +1 -0
@@ -1916,6 +1916,7 @@
 {
 	struct cdrom_device_ops *cdo = cdi->ops;
 	struct cdrom_generic_command cgc;
+	struct request_sense sense;
 	kdev_t dev = cdi->dev;
 	char buffer[32];
 	int ret = 0;
@@ -1951,9 +1952,11 @@
 		cgc.buffer = (char *) kmalloc(blocksize, GFP_KERNEL);
 		if (cgc.buffer == NULL)
 			return -ENOMEM;
Quoted 8 lines

cdrom/cdrom.c line 1959

Quoted 6 lines
cdrom/cdrom.c renamed from cdrom/cdrom.c~ +3 -1
+		memset(&sense, 0, sizeof(sense));
+		cgc.sense = &sense;
 		cgc.data_direction = CGC_DATA_READ;
 		ret = cdrom_read_block(cdi, &cgc, lba, 1, format, blocksize);
-		if (ret) {
+		if (ret && sense.sense_key==0x05 && sense.asc==0x20 && sense.ascq==0x00) {

Do you really need to hardcode this values ?

Quoted 5 lines

This allows it to falls back to READ_10 only when the drive reports "Hey! You gave me an invalid command!" which is the one and only case when a fall back to READ_10 is appropriate. I am not aware of any other reason for which a fallback to READ_10 is useful.

A comment to that effect would be useful. Not so much the interpretation of the numbers (which are easy enough to look up) but the rationale.

Signature · 1 line
 "Love the dolphins," she advised him. "Write by W.A.S.T.E.." 
#4 lore raw
In reply to Marcelo Tosatti
Quoted 18 lines · Marcelo Tosatti
Quoted 14 lines · Erik Andersen
cdrom/cdrom.c renamed from cdrom/cdrom.c~ +1 -0
@@ -1916,6 +1916,7 @@
 {
 	struct cdrom_device_ops *cdo = cdi->ops;
 	struct cdrom_generic_command cgc;
+	struct request_sense sense;
 	kdev_t dev = cdi->dev;
 	char buffer[32];
 	int ret = 0;
@@ -1951,9 +1952,11 @@
 		cgc.buffer = (char *) kmalloc(blocksize, GFP_KERNEL);
 		if (cgc.buffer == NULL)
 			return -ENOMEM;
Quoted 8 lines

cdrom/cdrom.c line 1959

Quoted 6 lines
cdrom/cdrom.c renamed from cdrom/cdrom.c~ +3 -1
+		memset(&sense, 0, sizeof(sense));
+		cgc.sense = &sense;
 		cgc.data_direction = CGC_DATA_READ;
 		ret = cdrom_read_block(cdi, &cgc, lba, 1, format, blocksize);
-		if (ret) {
+		if (ret && sense.sense_key==0x05 && sense.asc==0x20 && sense.ascq==0x00) {

Do you really need to hardcode this values ?

the values above are well known to anyone familiar with atapi and/or scsi, so it's not a worry. the patch looks good to me, I can recommend it for inclusion.

Signature · 1 line
Jens Axboe