USB: storage: When a device returns no sense data, call it a Hardware Error
[safe/jmp/linux-2.6] / drivers / usb / storage / transport.c
index e20dc52..3a4fb02 100644 (file)
@@ -768,17 +768,32 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                /* set the result so the higher layers expect this data */
                srb->result = SAM_STAT_CHECK_CONDITION;
 
-               /* If things are really okay, then let's show that.  Zero
-                * out the sense buffer so the higher layers won't realize
-                * we did an unsolicited auto-sense. */
-               if (result == USB_STOR_TRANSPORT_GOOD &&
-                       /* Filemark 0, ignore EOM, ILI 0, no sense */
+               /* We often get empty sense data.  This could indicate that
+                * everything worked or that there was an unspecified
+                * problem.  We have to decide which.
+                */
+               if (    /* Filemark 0, ignore EOM, ILI 0, no sense */
                                (srb->sense_buffer[2] & 0xaf) == 0 &&
                        /* No ASC or ASCQ */
                                srb->sense_buffer[12] == 0 &&
                                srb->sense_buffer[13] == 0) {
-                       srb->result = SAM_STAT_GOOD;
-                       srb->sense_buffer[0] = 0x0;
+
+                       /* If things are really okay, then let's show that.
+                        * Zero out the sense buffer so the higher layers
+                        * won't realize we did an unsolicited auto-sense.
+                        */
+                       if (result == USB_STOR_TRANSPORT_GOOD) {
+                               srb->result = SAM_STAT_GOOD;
+                               srb->sense_buffer[0] = 0x0;
+
+                       /* If there was a problem, report an unspecified
+                        * hardware error to prevent the higher layers from
+                        * entering an infinite retry loop.
+                        */
+                       } else {
+                               srb->result = DID_ERROR << 16;
+                               srb->sense_buffer[2] = HARDWARE_ERROR;
+                       }
                }
        }