aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/storage/transport.c')
-rw-r--r--drivers/usb/storage/transport.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 589f6b4404f0..f253edec3bb8 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -44,8 +44,10 @@
44 */ 44 */
45 45
46#include <linux/sched.h> 46#include <linux/sched.h>
47#include <linux/gfp.h>
47#include <linux/errno.h> 48#include <linux/errno.h>
48#include <linux/slab.h> 49
50#include <linux/usb/quirks.h>
49 51
50#include <scsi/scsi.h> 52#include <scsi/scsi.h>
51#include <scsi/scsi_eh.h> 53#include <scsi/scsi_eh.h>
@@ -666,10 +668,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
666 * to wait for at least one CHECK_CONDITION to determine 668 * to wait for at least one CHECK_CONDITION to determine
667 * SANE_SENSE support 669 * SANE_SENSE support
668 */ 670 */
669 if ((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) && 671 if (unlikely((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) &&
670 result == USB_STOR_TRANSPORT_GOOD && 672 result == USB_STOR_TRANSPORT_GOOD &&
671 !(us->fflags & US_FL_SANE_SENSE) && 673 !(us->fflags & US_FL_SANE_SENSE) &&
672 !(srb->cmnd[2] & 0x20)) { 674 !(us->fflags & US_FL_BAD_SENSE) &&
675 !(srb->cmnd[2] & 0x20))) {
673 US_DEBUGP("-- SAT supported, increasing auto-sense\n"); 676 US_DEBUGP("-- SAT supported, increasing auto-sense\n");
674 us->fflags |= US_FL_SANE_SENSE; 677 us->fflags |= US_FL_SANE_SENSE;
675 } 678 }
@@ -718,6 +721,12 @@ Retry_Sense:
718 if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) { 721 if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
719 US_DEBUGP("-- auto-sense aborted\n"); 722 US_DEBUGP("-- auto-sense aborted\n");
720 srb->result = DID_ABORT << 16; 723 srb->result = DID_ABORT << 16;
724
725 /* If SANE_SENSE caused this problem, disable it */
726 if (sense_size != US_SENSE_SIZE) {
727 us->fflags &= ~US_FL_SANE_SENSE;
728 us->fflags |= US_FL_BAD_SENSE;
729 }
721 goto Handle_Errors; 730 goto Handle_Errors;
722 } 731 }
723 732
@@ -727,10 +736,11 @@ Retry_Sense:
727 * (small) sense request. This fixes some USB GSM modems 736 * (small) sense request. This fixes some USB GSM modems
728 */ 737 */
729 if (temp_result == USB_STOR_TRANSPORT_FAILED && 738 if (temp_result == USB_STOR_TRANSPORT_FAILED &&
730 (us->fflags & US_FL_SANE_SENSE) && 739 sense_size != US_SENSE_SIZE) {
731 sense_size != US_SENSE_SIZE) {
732 US_DEBUGP("-- auto-sense failure, retry small sense\n"); 740 US_DEBUGP("-- auto-sense failure, retry small sense\n");
733 sense_size = US_SENSE_SIZE; 741 sense_size = US_SENSE_SIZE;
742 us->fflags &= ~US_FL_SANE_SENSE;
743 us->fflags |= US_FL_BAD_SENSE;
734 goto Retry_Sense; 744 goto Retry_Sense;
735 } 745 }
736 746
@@ -754,6 +764,7 @@ Retry_Sense:
754 */ 764 */
755 if (srb->sense_buffer[7] > (US_SENSE_SIZE - 8) && 765 if (srb->sense_buffer[7] > (US_SENSE_SIZE - 8) &&
756 !(us->fflags & US_FL_SANE_SENSE) && 766 !(us->fflags & US_FL_SANE_SENSE) &&
767 !(us->fflags & US_FL_BAD_SENSE) &&
757 (srb->sense_buffer[0] & 0x7C) == 0x70) { 768 (srb->sense_buffer[0] & 0x7C) == 0x70) {
758 US_DEBUGP("-- SANE_SENSE support enabled\n"); 769 US_DEBUGP("-- SANE_SENSE support enabled\n");
759 us->fflags |= US_FL_SANE_SENSE; 770 us->fflags |= US_FL_SANE_SENSE;
@@ -1288,6 +1299,10 @@ int usb_stor_port_reset(struct us_data *us)
1288{ 1299{
1289 int result; 1300 int result;
1290 1301
1302 /*for these devices we must use the class specific method */
1303 if (us->pusb_dev->quirks & USB_QUIRK_RESET_MORPHS)
1304 return -EPERM;
1305
1291 result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf); 1306 result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
1292 if (result < 0) 1307 if (result < 0)
1293 US_DEBUGP("unable to lock device for reset: %d\n", result); 1308 US_DEBUGP("unable to lock device for reset: %d\n", result);