aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-10-06 14:07:57 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-10-09 16:52:08 -0400
commitf1a0743bc0e7a30c032b1eb78f6a2b0f805b4597 (patch)
treef2b86a85b8a0a1c32d362f1e436b9ab32edfa114 /drivers
parenta5f6005d7b1821d2085d9749b56500a8f2610924 (diff)
USB: storage: When a device returns no sense data, call it a Hardware Error
This patch (as1294) fixes a problem that has plagued users for several kernel releases. Some USB mass-storage devices don't return any sense data when they encounter certain kinds of errors. The SCSI layer interprets this to mean that the operation should be retried, and the same thing happens -- over and over again with no limit. In some circumstances (such as when a bus reset occurs) that is the right thing to do, but not here. The patch checks for this condition (a transport failure with no sense data) and changes the result code to DID_ERROR and the sense code to Hardware Error. This does get only a limited number of retries, and so the command will fail relatively quickly instead of getting stuck in an infinite loop. This fixes a large part of Bugzilla #14118. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Tested-by: Mantas Mikulenas <grawity@gmail.com> CC: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-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 e20dc525d177..3a4fb023af72 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)
768 /* set the result so the higher layers expect this data */ 768 /* set the result so the higher layers expect this data */
769 srb->result = SAM_STAT_CHECK_CONDITION; 769 srb->result = SAM_STAT_CHECK_CONDITION;
770 770
771 /* If things are really okay, then let's show that. Zero 771 /* We often get empty sense data. This could indicate that
772 * out the sense buffer so the higher layers won't realize 772 * everything worked or that there was an unspecified
773 * we did an unsolicited auto-sense. */ 773 * problem. We have to decide which.
774 if (result == USB_STOR_TRANSPORT_GOOD && 774 */
775 /* Filemark 0, ignore EOM, ILI 0, no sense */ 775 if ( /* Filemark 0, ignore EOM, ILI 0, no sense */
776 (srb->sense_buffer[2] & 0xaf) == 0 && 776 (srb->sense_buffer[2] & 0xaf) == 0 &&
777 /* No ASC or ASCQ */ 777 /* No ASC or ASCQ */
778 srb->sense_buffer[12] == 0 && 778 srb->sense_buffer[12] == 0 &&
779 srb->sense_buffer[13] == 0) { 779 srb->sense_buffer[13] == 0) {
780 srb->result = SAM_STAT_GOOD; 780
781 srb->sense_buffer[0] = 0x0; 781 /* If things are really okay, then let's show that.
782 * Zero out the sense buffer so the higher layers
783 * won't realize we did an unsolicited auto-sense.
784 */
785 if (result == USB_STOR_TRANSPORT_GOOD) {
786 srb->result = SAM_STAT_GOOD;
787 srb->sense_buffer[0] = 0x0;
788
789 /* If there was a problem, report an unspecified
790 * hardware error to prevent the higher layers from
791 * entering an infinite retry loop.
792 */
793 } else {
794 srb->result = DID_ERROR << 16;
795 srb->sense_buffer[2] = HARDWARE_ERROR;
796 }
782 } 797 }
783 } 798 }
784 799