summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/storage/transport.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index e20dc525d17..3a4fb023af7 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -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;
+ }
}
}