[PATCH] scsi_scan fix (for usb)

2001-06-06 Thread Andries . Brouwer

Recently I reported for 2.4.3 and 2.4.5 a failure to detect
a USB CF card reader caused by the occurrence of a Unit Attention
at boot time. An ugly solution is to remove this "error" in
usb/storage/transport.c, but since this is perfectly normal
SCSI behaviour, and can in principle occur with all kinds of
hosts and drivers, it is probably better to test for Unit Attention
is scan_scsis. (In the good old days we did TEST UNIT READY there,
but not anymore.)
No doubt the actual test will have to become more complicated,
but I just wrote the minimum required to make my hardware work.

The things other than in scsi_scan.c are just minor polishing.
For example, sd.c printed an "extended sense code" that was in
reality the sense key. I started adding ASC and ASCQ, but we
already have a function for that in constants.c.

Andries

diff -u --recursive --new-file ../linux-2.4.5/linux/drivers/scsi/constants.c 
./linux/drivers/scsi/constants.c
--- ../linux-2.4.5/linux/drivers/scsi/constants.c   Mon Jan 15 22:08:15 2001
+++ ./linux/drivers/scsi/constants.cThu Jun  7 00:36:41 2001
@@ -689,7 +689,7 @@
  kdev_t dev)
 {
 int i, s;
-int sense_class, valid, code;
+int sense_class, valid, code, info;
 const char * error = NULL;
 
 sense_class = (sense_buffer[0] >> 4) & 0x07;
@@ -701,11 +701,14 @@
if(s > SCSI_SENSE_BUFFERSIZE)
   s = SCSI_SENSE_BUFFERSIZE;

-   if (!valid)
-   printk("[valid=0] ");
-   printk("Info fld=0x%x, ", (int)((sense_buffer[3] << 24) |
-  (sense_buffer[4] << 16) | (sense_buffer[5] << 8) |
-  sense_buffer[6]));
+   info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) |
+   (sense_buffer[5] << 8) | sense_buffer[6]);
+   if (info || !valid) {
+   printk("Info fld=0x%x", info);
+   if (!valid) /* info data not according to standard */
+   printk(" (nonstd)");
+   printk(", ");
+   }
if (sense_buffer[2] & 0x80)
printk( "FMK ");/* current command has read a filemark */
if (sense_buffer[2] & 0x40)
diff -u --recursive --new-file ../linux-2.4.5/linux/drivers/scsi/scsi_scan.c 
./linux/drivers/scsi/scsi_scan.c
--- ../linux-2.4.5/linux/drivers/scsi/scsi_scan.c   Sun Apr  8 19:10:01 2001
+++ ./linux/drivers/scsi/scsi_scan.cThu Jun  7 00:10:27 2001
@@ -328,8 +328,8 @@
}
 
/*
-* We need to increment the counter for this one device so we can track when
-* things are quiet.
+* We need to increment the counter for this one device so we can track
+* when things are quiet.
 */
if (hardcoded == 1) {
Scsi_Device *oldSDpnt = SDpnt;
@@ -485,8 +485,8 @@
SDpnt->type = -1;
 
/*
-* Assume that the device will have handshaking problems, and then fix this
-* field later if it turns out it doesn't
+* Assume that the device will have handshaking problems, and then fix
+* this field later if it turns out it doesn't
 */
SDpnt->borken = 1;
SDpnt->was_reset = 0;
@@ -524,9 +524,21 @@
SCSI_LOG_SCAN_BUS(3, printk("scsi: INQUIRY %s with code 0x%x\n",
SRpnt->sr_result ? "failed" : "successful", SRpnt->sr_result));
 
+   /*
+* Now that we don't do TEST_UNIT_READY anymore, we must be prepared
+* for media change conditions here, so cannot require zero result.
+*/
if (SRpnt->sr_result) {
-   scsi_release_request(SRpnt);
-   return 0;   /* assume no peripheral if any sort of error */
+   if ((driver_byte(SRpnt->sr_result) & DRIVER_SENSE) != 0 &&
+   (SRpnt->sr_sense_buffer[2] & 0xf) == UNIT_ATTENTION &&
+   SRpnt->sr_sense_buffer[12] == 0x28 &&
+   SRpnt->sr_sense_buffer[13] == 0) {
+   /* not-ready to ready transition - good */
+   } else {
+   /* assume no peripheral if any other sort of error */
+   scsi_release_request(SRpnt);
+   return 0;
+   }
}
 
/*
diff -u --recursive --new-file ../linux-2.4.5/linux/drivers/scsi/sd.c 
./linux/drivers/scsi/sd.c
--- ../linux-2.4.5/linux/drivers/scsi/sd.c  Fri May 25 18:54:50 2001
+++ ./linux/drivers/scsi/sd.c   Wed Jun  6 23:58:46 2001
@@ -861,8 +861,7 @@
   driver_byte(the_result)
);
if (driver_byte(the_result) & DRIVER_SENSE)
-   printk("%s : extended sense code = %1x \n",
-  nbuff, SRpnt->sr_sense_buffer[2] & 0xf);
+   print_req_sense("sd", SRpnt);
else
printk("%s : sense not available. \n", nbuff);
 
diff -u --recursive --new-file ../linux-2.4.5/linux/drivers/usb/storage/debug.c 

[PATCH] scsi_scan fix (for usb)

2001-06-06 Thread Andries . Brouwer

Recently I reported for 2.4.3 and 2.4.5 a failure to detect
a USB CF card reader caused by the occurrence of a Unit Attention
at boot time. An ugly solution is to remove this error in
usb/storage/transport.c, but since this is perfectly normal
SCSI behaviour, and can in principle occur with all kinds of
hosts and drivers, it is probably better to test for Unit Attention
is scan_scsis. (In the good old days we did TEST UNIT READY there,
but not anymore.)
No doubt the actual test will have to become more complicated,
but I just wrote the minimum required to make my hardware work.

The things other than in scsi_scan.c are just minor polishing.
For example, sd.c printed an extended sense code that was in
reality the sense key. I started adding ASC and ASCQ, but we
already have a function for that in constants.c.

Andries

diff -u --recursive --new-file ../linux-2.4.5/linux/drivers/scsi/constants.c 
./linux/drivers/scsi/constants.c
--- ../linux-2.4.5/linux/drivers/scsi/constants.c   Mon Jan 15 22:08:15 2001
+++ ./linux/drivers/scsi/constants.cThu Jun  7 00:36:41 2001
@@ -689,7 +689,7 @@
  kdev_t dev)
 {
 int i, s;
-int sense_class, valid, code;
+int sense_class, valid, code, info;
 const char * error = NULL;
 
 sense_class = (sense_buffer[0]  4)  0x07;
@@ -701,11 +701,14 @@
if(s  SCSI_SENSE_BUFFERSIZE)
   s = SCSI_SENSE_BUFFERSIZE;

-   if (!valid)
-   printk([valid=0] );
-   printk(Info fld=0x%x, , (int)((sense_buffer[3]  24) |
-  (sense_buffer[4]  16) | (sense_buffer[5]  8) |
-  sense_buffer[6]));
+   info = ((sense_buffer[3]  24) | (sense_buffer[4]  16) |
+   (sense_buffer[5]  8) | sense_buffer[6]);
+   if (info || !valid) {
+   printk(Info fld=0x%x, info);
+   if (!valid) /* info data not according to standard */
+   printk( (nonstd));
+   printk(, );
+   }
if (sense_buffer[2]  0x80)
printk( FMK );/* current command has read a filemark */
if (sense_buffer[2]  0x40)
diff -u --recursive --new-file ../linux-2.4.5/linux/drivers/scsi/scsi_scan.c 
./linux/drivers/scsi/scsi_scan.c
--- ../linux-2.4.5/linux/drivers/scsi/scsi_scan.c   Sun Apr  8 19:10:01 2001
+++ ./linux/drivers/scsi/scsi_scan.cThu Jun  7 00:10:27 2001
@@ -328,8 +328,8 @@
}
 
/*
-* We need to increment the counter for this one device so we can track when
-* things are quiet.
+* We need to increment the counter for this one device so we can track
+* when things are quiet.
 */
if (hardcoded == 1) {
Scsi_Device *oldSDpnt = SDpnt;
@@ -485,8 +485,8 @@
SDpnt-type = -1;
 
/*
-* Assume that the device will have handshaking problems, and then fix this
-* field later if it turns out it doesn't
+* Assume that the device will have handshaking problems, and then fix
+* this field later if it turns out it doesn't
 */
SDpnt-borken = 1;
SDpnt-was_reset = 0;
@@ -524,9 +524,21 @@
SCSI_LOG_SCAN_BUS(3, printk(scsi: INQUIRY %s with code 0x%x\n,
SRpnt-sr_result ? failed : successful, SRpnt-sr_result));
 
+   /*
+* Now that we don't do TEST_UNIT_READY anymore, we must be prepared
+* for media change conditions here, so cannot require zero result.
+*/
if (SRpnt-sr_result) {
-   scsi_release_request(SRpnt);
-   return 0;   /* assume no peripheral if any sort of error */
+   if ((driver_byte(SRpnt-sr_result)  DRIVER_SENSE) != 0 
+   (SRpnt-sr_sense_buffer[2]  0xf) == UNIT_ATTENTION 
+   SRpnt-sr_sense_buffer[12] == 0x28 
+   SRpnt-sr_sense_buffer[13] == 0) {
+   /* not-ready to ready transition - good */
+   } else {
+   /* assume no peripheral if any other sort of error */
+   scsi_release_request(SRpnt);
+   return 0;
+   }
}
 
/*
diff -u --recursive --new-file ../linux-2.4.5/linux/drivers/scsi/sd.c 
./linux/drivers/scsi/sd.c
--- ../linux-2.4.5/linux/drivers/scsi/sd.c  Fri May 25 18:54:50 2001
+++ ./linux/drivers/scsi/sd.c   Wed Jun  6 23:58:46 2001
@@ -861,8 +861,7 @@
   driver_byte(the_result)
);
if (driver_byte(the_result)  DRIVER_SENSE)
-   printk(%s : extended sense code = %1x \n,
-  nbuff, SRpnt-sr_sense_buffer[2]  0xf);
+   print_req_sense(sd, SRpnt);
else
printk(%s : sense not available. \n, nbuff);
 
diff -u --recursive --new-file ../linux-2.4.5/linux/drivers/usb/storage/debug.c 
./linux/drivers/usb/storage/debug.c
---