diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 777dc8a32df8d077fc9bdca101a071d3c7f97294..3f886e298f62bf6e32c870fc4df568769aeb5db2 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2663,6 +2663,8 @@ and is between 256 and 4096 characters. It is defined in the file to a common usb-storage quirk flag as follows: a = SANE_SENSE (collect more than 18 bytes of sense data); + b = BAD_SENSE (don't collect more than 18 + bytes of sense data); c = FIX_CAPACITY (decrease the reported device capacity by one sector); h = CAPACITY_HEURISTICS (decrease the diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 589f6b4404f0b1550718c66353ec4c807c0a46ac..cc313d16d727d0dc827627835d380249f638ab9c 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) * to wait for at least one CHECK_CONDITION to determine * SANE_SENSE support */ - if ((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) && + if (unlikely((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) && result == USB_STOR_TRANSPORT_GOOD && !(us->fflags & US_FL_SANE_SENSE) && - !(srb->cmnd[2] & 0x20)) { + !(us->fflags & US_FL_BAD_SENSE) && + !(srb->cmnd[2] & 0x20))) { US_DEBUGP("-- SAT supported, increasing auto-sense\n"); us->fflags |= US_FL_SANE_SENSE; } @@ -718,6 +719,12 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) { US_DEBUGP("-- auto-sense aborted\n"); srb->result = DID_ABORT << 16; + + /* If SANE_SENSE caused this problem, disable it */ + if (sense_size != US_SENSE_SIZE) { + us->fflags &= ~US_FL_SANE_SENSE; + us->fflags |= US_FL_BAD_SENSE; + } goto Handle_Errors; } @@ -727,10 +734,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) * (small) sense request. This fixes some USB GSM modems */ if (temp_result == USB_STOR_TRANSPORT_FAILED && - (us->fflags & US_FL_SANE_SENSE) && - sense_size != US_SENSE_SIZE) { + sense_size != US_SENSE_SIZE) { US_DEBUGP("-- auto-sense failure, retry small sense\n"); sense_size = US_SENSE_SIZE; + us->fflags &= ~US_FL_SANE_SENSE; + us->fflags |= US_FL_BAD_SENSE; goto Retry_Sense; } @@ -754,6 +762,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) */ if (srb->sense_buffer[7] > (US_SENSE_SIZE - 8) && !(us->fflags & US_FL_SANE_SENSE) && + !(us->fflags & US_FL_BAD_SENSE) && (srb->sense_buffer[0] & 0x7C) == 0x70) { US_DEBUGP("-- SANE_SENSE support enabled\n"); us->fflags |= US_FL_SANE_SENSE; diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d4f034ebaa8a44080af462b8876ecbc632c62cee..64a0a2c27e12b4478734ae9683fead5750abfe67 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, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* Reported by Daniel Kukula <daniel.kuku@gmail.com> */ +UNUSUAL_DEV( 0x067b, 0x1063, 0x0100, 0x0100, + "Prolific Technology, Inc.", + "Prolific Storage Gadget", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_BAD_SENSE ), + /* Reported by Rogerio Brito <rbrito@ime.usp.br> */ UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001, "Prolific Technology, Inc.", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 1599d86154c471395f199a090c1bace80532e667..f5c0264caa3317a1b681d085d09d64af6050ddc1 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) case 'a': f |= US_FL_SANE_SENSE; break; + case 'b': + f |= US_FL_BAD_SENSE; + break; case 'c': f |= US_FL_FIX_CAPACITY; break; diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h index 3d15fb9bc116fbba8f03612b9af2fae6b34ba8bf..a4b947e470a59b9a191e55edab3a0fdd24a2a469 100644 --- a/include/linux/usb_usual.h +++ b/include/linux/usb_usual.h @@ -56,7 +56,9 @@ US_FLAG(SANE_SENSE, 0x00008000) \ /* Sane Sense (> 18 bytes) */ \ US_FLAG(CAPACITY_OK, 0x00010000) \ - /* READ CAPACITY response is correct */ + /* READ CAPACITY response is correct */ \ + US_FLAG(BAD_SENSE, 0x00020000) \ + /* Bad Sense (never more than 18 bytes) */ #define US_FLAG(name, value) US_FL_##name = value , enum { US_DO_ALL_FLAGS };