diff options
Diffstat (limited to 'drivers/usb/storage/transport.c')
-rw-r--r-- | drivers/usb/storage/transport.c | 25 |
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); |