Commit a0bb108112a872c0b0c4b3ef4974f95fb75b155d

Authored by Alan Stern
Committed by Greg Kroah-Hartman
1 parent 8e4ceb38eb

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>

Showing 5 changed files with 28 additions and 5 deletions Side-by-side Diff

Documentation/kernel-parameters.txt
... ... @@ -2663,6 +2663,8 @@
2663 2663 to a common usb-storage quirk flag as follows:
2664 2664 a = SANE_SENSE (collect more than 18 bytes
2665 2665 of sense data);
  2666 + b = BAD_SENSE (don't collect more than 18
  2667 + bytes of sense data);
2666 2668 c = FIX_CAPACITY (decrease the reported
2667 2669 device capacity by one sector);
2668 2670 h = CAPACITY_HEURISTICS (decrease the
drivers/usb/storage/transport.c
... ... @@ -666,10 +666,11 @@
666 666 * to wait for at least one CHECK_CONDITION to determine
667 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 670 result == USB_STOR_TRANSPORT_GOOD &&
671 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 674 US_DEBUGP("-- SAT supported, increasing auto-sense\n");
674 675 us->fflags |= US_FL_SANE_SENSE;
675 676 }
... ... @@ -718,6 +719,12 @@
718 719 if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
719 720 US_DEBUGP("-- auto-sense aborted\n");
720 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 728 goto Handle_Errors;
722 729 }
723 730  
724 731  
... ... @@ -727,10 +734,11 @@
727 734 * (small) sense request. This fixes some USB GSM modems
728 735 */
729 736 if (temp_result == USB_STOR_TRANSPORT_FAILED &&
730   - (us->fflags & US_FL_SANE_SENSE) &&
731   - sense_size != US_SENSE_SIZE) {
  737 + sense_size != US_SENSE_SIZE) {
732 738 US_DEBUGP("-- auto-sense failure, retry small sense\n");
733 739 sense_size = US_SENSE_SIZE;
  740 + us->fflags &= ~US_FL_SANE_SENSE;
  741 + us->fflags |= US_FL_BAD_SENSE;
734 742 goto Retry_Sense;
735 743 }
736 744  
... ... @@ -754,6 +762,7 @@
754 762 */
755 763 if (srb->sense_buffer[7] > (US_SENSE_SIZE - 8) &&
756 764 !(us->fflags & US_FL_SANE_SENSE) &&
  765 + !(us->fflags & US_FL_BAD_SENSE) &&
757 766 (srb->sense_buffer[0] & 0x7C) == 0x70) {
758 767 US_DEBUGP("-- SANE_SENSE support enabled\n");
759 768 us->fflags |= US_FL_SANE_SENSE;
drivers/usb/storage/unusual_devs.h
... ... @@ -818,6 +818,13 @@
818 818 US_SC_DEVICE, US_PR_DEVICE, NULL,
819 819 US_FL_FIX_CAPACITY ),
820 820  
  821 +/* Reported by Daniel Kukula <daniel.kuku@gmail.com> */
  822 +UNUSUAL_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 828 /* Reported by Rogerio Brito <rbrito@ime.usp.br> */
822 829 UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001,
823 830 "Prolific Technology, Inc.",
drivers/usb/storage/usb.c
... ... @@ -463,6 +463,9 @@
463 463 case 'a':
464 464 f |= US_FL_SANE_SENSE;
465 465 break;
  466 + case 'b':
  467 + f |= US_FL_BAD_SENSE;
  468 + break;
466 469 case 'c':
467 470 f |= US_FL_FIX_CAPACITY;
468 471 break;
include/linux/usb_usual.h
... ... @@ -56,7 +56,9 @@
56 56 US_FLAG(SANE_SENSE, 0x00008000) \
57 57 /* Sane Sense (> 18 bytes) */ \
58 58 US_FLAG(CAPACITY_OK, 0x00010000) \
59   - /* READ CAPACITY response is correct */
  59 + /* READ CAPACITY response is correct */ \
  60 + US_FLAG(BAD_SENSE, 0x00020000) \
  61 + /* Bad Sense (never more than 18 bytes) */
60 62  
61 63 #define US_FLAG(name, value) US_FL_##name = value ,
62 64 enum { US_DO_ALL_FLAGS };