aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-12-07 16:39:16 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:55:26 -0500
commita0bb108112a872c0b0c4b3ef4974f95fb75b155d (patch)
tree86f7327949289b70960f57b07b99054e240a91e4 /drivers/usb
parent8e4ceb38eb5bbaef22fc00abe9bc11e26bea2ab5 (diff)
USB: usb-storage: add BAD_SENSE flag
This patch (as1311) fixes a problem in usb-storage: Some devices are pretty broken when it comes to reporting sense data. The information they send back indicates that they have more than 18 bytes of sense data available, but when the system asks for more than 18 they fail or hang. The symptom is that probing fails with multiple resets. The patch adds a new BAD_SENSE flag to indicate that usb-storage should never ask for more than 18 bytes of sense data. The flag can be set in an unusual_devs entry or via the "quirks=" module parameter, and it is set automatically whenever a REQUEST SENSE command for more than 18 bytes fails or times out. An unusual_devs entry is added for the Agfa photo frame, which uses a Prolific chip having this bug. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Tested-by: Daniel Kukula <daniel.kuku@gmail.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/storage/transport.c17
-rw-r--r--drivers/usb/storage/unusual_devs.h7
-rw-r--r--drivers/usb/storage/usb.c3
3 files changed, 23 insertions, 4 deletions
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 589f6b4404f0..cc313d16d727 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -666,10 +666,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 666 * to wait for at least one CHECK_CONDITION to determine
667 * SANE_SENSE support 667 * SANE_SENSE support
668 */ 668 */
669 if ((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) && 669 if (unlikely((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) &&
670 result == USB_STOR_TRANSPORT_GOOD && 670 result == USB_STOR_TRANSPORT_GOOD &&
671 !(us->fflags & US_FL_SANE_SENSE) && 671 !(us->fflags & US_FL_SANE_SENSE) &&
672 !(srb->cmnd[2] & 0x20)) { 672 !(us->fflags & US_FL_BAD_SENSE) &&
673 !(srb->cmnd[2] & 0x20))) {
673 US_DEBUGP("-- SAT supported, increasing auto-sense\n"); 674 US_DEBUGP("-- SAT supported, increasing auto-sense\n");
674 us->fflags |= US_FL_SANE_SENSE; 675 us->fflags |= US_FL_SANE_SENSE;
675 } 676 }
@@ -718,6 +719,12 @@ Retry_Sense:
718 if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) { 719 if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
719 US_DEBUGP("-- auto-sense aborted\n"); 720 US_DEBUGP("-- auto-sense aborted\n");
720 srb->result = DID_ABORT << 16; 721 srb->result = DID_ABORT << 16;
722
723 /* If SANE_SENSE caused this problem, disable it */
724 if (sense_size != US_SENSE_SIZE) {
725 us->fflags &= ~US_FL_SANE_SENSE;
726 us->fflags |= US_FL_BAD_SENSE;
727 }
721 goto Handle_Errors; 728 goto Handle_Errors;
722 } 729 }
723 730
@@ -727,10 +734,11 @@ Retry_Sense:
727 * (small) sense request. This fixes some USB GSM modems 734 * (small) sense request. This fixes some USB GSM modems
728 */ 735 */
729 if (temp_result == USB_STOR_TRANSPORT_FAILED && 736 if (temp_result == USB_STOR_TRANSPORT_FAILED &&
730 (us->fflags & US_FL_SANE_SENSE) && 737 sense_size != US_SENSE_SIZE) {
731 sense_size != US_SENSE_SIZE) {
732 US_DEBUGP("-- auto-sense failure, retry small sense\n"); 738 US_DEBUGP("-- auto-sense failure, retry small sense\n");
733 sense_size = US_SENSE_SIZE; 739 sense_size = US_SENSE_SIZE;
740 us->fflags &= ~US_FL_SANE_SENSE;
741 us->fflags |= US_FL_BAD_SENSE;
734 goto Retry_Sense; 742 goto Retry_Sense;
735 } 743 }
736 744
@@ -754,6 +762,7 @@ Retry_Sense:
754 */ 762 */
755 if (srb->sense_buffer[7] > (US_SENSE_SIZE - 8) && 763 if (srb->sense_buffer[7] > (US_SENSE_SIZE - 8) &&
756 !(us->fflags & US_FL_SANE_SENSE) && 764 !(us->fflags & US_FL_SANE_SENSE) &&
765 !(us->fflags & US_FL_BAD_SENSE) &&
757 (srb->sense_buffer[0] & 0x7C) == 0x70) { 766 (srb->sense_buffer[0] & 0x7C) == 0x70) {
758 US_DEBUGP("-- SANE_SENSE support enabled\n"); 767 US_DEBUGP("-- SANE_SENSE support enabled\n");
759 us->fflags |= US_FL_SANE_SENSE; 768 us->fflags |= US_FL_SANE_SENSE;
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index d4f034ebaa8a..64a0a2c27e12 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -818,6 +818,13 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001,
818 US_SC_DEVICE, US_PR_DEVICE, NULL, 818 US_SC_DEVICE, US_PR_DEVICE, NULL,
819 US_FL_FIX_CAPACITY ), 819 US_FL_FIX_CAPACITY ),
820 820
821/* Reported by Daniel Kukula <daniel.kuku@gmail.com> */
822UNUSUAL_DEV( 0x067b, 0x1063, 0x0100, 0x0100,
823 "Prolific Technology, Inc.",
824 "Prolific Storage Gadget",
825 US_SC_DEVICE, US_PR_DEVICE, NULL,
826 US_FL_BAD_SENSE ),
827
821/* Reported by Rogerio Brito <rbrito@ime.usp.br> */ 828/* Reported by Rogerio Brito <rbrito@ime.usp.br> */
822UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001, 829UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001,
823 "Prolific Technology, Inc.", 830 "Prolific Technology, Inc.",
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 1599d86154c4..f5c0264caa33 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -463,6 +463,9 @@ static void adjust_quirks(struct us_data *us)
463 case 'a': 463 case 'a':
464 f |= US_FL_SANE_SENSE; 464 f |= US_FL_SANE_SENSE;
465 break; 465 break;
466 case 'b':
467 f |= US_FL_BAD_SENSE;
468 break;
466 case 'c': 469 case 'c':
467 f |= US_FL_FIX_CAPACITY; 470 f |= US_FL_FIX_CAPACITY;
468 break; 471 break;