diff options
author | Hans de Goede <hdegoede@redhat.com> | 2014-09-15 10:04:12 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-09-24 00:40:48 -0400 |
commit | 593078525c8b234a35a36ff551b8716464e86481 (patch) | |
tree | 3f28834cbca55ae39470f553077eb220211a61ad /drivers/usb | |
parent | ab945eff8396bc3329cc97274320e8d2c6585077 (diff) |
uas: Add a quirk for rejecting ATA_12 and ATA_16 commands
And set this quirk for the Seagate Expansion Desk (0bc2:2312), as that one
seems to hang upon receiving an ATA_12 or ATA_16 command.
https://bugzilla.kernel.org/show_bug.cgi?id=79511
https://bbs.archlinux.org/viewtopic.php?id=183190
While at it also add missing documentation for the u value for usb-storage
quirks.
Cc: stable@vger.kernel.org # 3.16, 3.17
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
--
Changes in v2: Add documentation for new t and u usb-storage.quirks flags
Changes in v3: Fix typo in documentation
Changes in v4: Also apply the quirk to (0bc2:3312)
Changes in v5: Rebased on 3.17-rc5, drop u documentation, already upstream
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/storage/uas.c | 13 | ||||
-rw-r--r-- | drivers/usb/storage/unusual_uas.h | 23 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 6 |
3 files changed, 31 insertions, 11 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 05b2d8e077d9..8c7d4a239f4c 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <scsi/scsi_tcq.h> | 28 | #include <scsi/scsi_tcq.h> |
29 | 29 | ||
30 | #include "uas-detect.h" | 30 | #include "uas-detect.h" |
31 | #include "scsiglue.h" | ||
31 | 32 | ||
32 | /* | 33 | /* |
33 | * The r00-r01c specs define this version of the SENSE IU data structure. | 34 | * The r00-r01c specs define this version of the SENSE IU data structure. |
@@ -49,6 +50,7 @@ struct uas_dev_info { | |||
49 | struct usb_anchor cmd_urbs; | 50 | struct usb_anchor cmd_urbs; |
50 | struct usb_anchor sense_urbs; | 51 | struct usb_anchor sense_urbs; |
51 | struct usb_anchor data_urbs; | 52 | struct usb_anchor data_urbs; |
53 | unsigned long flags; | ||
52 | int qdepth, resetting; | 54 | int qdepth, resetting; |
53 | struct response_iu response; | 55 | struct response_iu response; |
54 | unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; | 56 | unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; |
@@ -714,6 +716,15 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
714 | 716 | ||
715 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); | 717 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); |
716 | 718 | ||
719 | if ((devinfo->flags & US_FL_NO_ATA_1X) && | ||
720 | (cmnd->cmnd[0] == ATA_12 || cmnd->cmnd[0] == ATA_16)) { | ||
721 | memcpy(cmnd->sense_buffer, usb_stor_sense_invalidCDB, | ||
722 | sizeof(usb_stor_sense_invalidCDB)); | ||
723 | cmnd->result = SAM_STAT_CHECK_CONDITION; | ||
724 | cmnd->scsi_done(cmnd); | ||
725 | return 0; | ||
726 | } | ||
727 | |||
717 | spin_lock_irqsave(&devinfo->lock, flags); | 728 | spin_lock_irqsave(&devinfo->lock, flags); |
718 | 729 | ||
719 | if (devinfo->resetting) { | 730 | if (devinfo->resetting) { |
@@ -1080,6 +1091,8 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1080 | devinfo->resetting = 0; | 1091 | devinfo->resetting = 0; |
1081 | devinfo->running_task = 0; | 1092 | devinfo->running_task = 0; |
1082 | devinfo->shutdown = 0; | 1093 | devinfo->shutdown = 0; |
1094 | devinfo->flags = id->driver_info; | ||
1095 | usb_stor_adjust_quirks(udev, &devinfo->flags); | ||
1083 | init_usb_anchor(&devinfo->cmd_urbs); | 1096 | init_usb_anchor(&devinfo->cmd_urbs); |
1084 | init_usb_anchor(&devinfo->sense_urbs); | 1097 | init_usb_anchor(&devinfo->sense_urbs); |
1085 | init_usb_anchor(&devinfo->data_urbs); | 1098 | init_usb_anchor(&devinfo->data_urbs); |
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 7244444df8ee..3ff2dd4c78ca 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h | |||
@@ -40,13 +40,16 @@ | |||
40 | * and don't forget to CC: the USB development list <linux-usb@vger.kernel.org> | 40 | * and don't forget to CC: the USB development list <linux-usb@vger.kernel.org> |
41 | */ | 41 | */ |
42 | 42 | ||
43 | /* | 43 | /* https://bugzilla.kernel.org/show_bug.cgi?id=79511 */ |
44 | * This is an example entry for the US_FL_IGNORE_UAS flag. Once we have an | 44 | UNUSUAL_DEV(0x0bc2, 0x2312, 0x0000, 0x9999, |
45 | * actual entry using US_FL_IGNORE_UAS this entry should be removed. | 45 | "Seagate", |
46 | * | 46 | "Expansion Desk", |
47 | * UNUSUAL_DEV( 0xabcd, 0x1234, 0x0100, 0x0100, | 47 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
48 | * "Example", | 48 | US_FL_NO_ATA_1X), |
49 | * "Storage with broken UAS", | 49 | |
50 | * USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 50 | /* https://bbs.archlinux.org/viewtopic.php?id=183190 */ |
51 | * US_FL_IGNORE_UAS), | 51 | UNUSUAL_DEV(0x0bc2, 0x3312, 0x0000, 0x9999, |
52 | */ | 52 | "Seagate", |
53 | "Expansion Desk", | ||
54 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
55 | US_FL_NO_ATA_1X), | ||
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index cedb29252a92..b9d1b9357287 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -478,7 +478,8 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags) | |||
478 | US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE | | 478 | US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE | |
479 | US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT | | 479 | US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT | |
480 | US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 | | 480 | US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 | |
481 | US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE); | 481 | US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE | |
482 | US_FL_NO_ATA_1X); | ||
482 | 483 | ||
483 | p = quirks; | 484 | p = quirks; |
484 | while (*p) { | 485 | while (*p) { |
@@ -543,6 +544,9 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags) | |||
543 | case 's': | 544 | case 's': |
544 | f |= US_FL_SINGLE_LUN; | 545 | f |= US_FL_SINGLE_LUN; |
545 | break; | 546 | break; |
547 | case 't': | ||
548 | f |= US_FL_NO_ATA_1X; | ||
549 | break; | ||
546 | case 'u': | 550 | case 'u': |
547 | f |= US_FL_IGNORE_UAS; | 551 | f |= US_FL_IGNORE_UAS; |
548 | break; | 552 | break; |