aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-09-15 10:04:12 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-09-24 00:40:48 -0400
commit593078525c8b234a35a36ff551b8716464e86481 (patch)
tree3f28834cbca55ae39470f553077eb220211a61ad /drivers/usb
parentab945eff8396bc3329cc97274320e8d2c6585077 (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.c13
-rw-r--r--drivers/usb/storage/unusual_uas.h23
-rw-r--r--drivers/usb/storage/usb.c6
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 44UNUSUAL_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), 51UNUSUAL_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;