summaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r--drivers/usb/storage/ene_ub6250.c4
-rw-r--r--drivers/usb/storage/isd200.c1
-rw-r--r--drivers/usb/storage/transport.c29
-rw-r--r--drivers/usb/storage/unusual_devs.h19
-rw-r--r--drivers/usb/storage/unusual_realtek.h10
-rw-r--r--drivers/usb/storage/usb.c20
-rw-r--r--drivers/usb/storage/usb.h2
7 files changed, 76 insertions, 9 deletions
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c
index 0e5aafda4537..31645afff5fc 100644
--- a/drivers/usb/storage/ene_ub6250.c
+++ b/drivers/usb/storage/ene_ub6250.c
@@ -715,8 +715,8 @@ static int ene_ub6250_probe(struct usb_interface *intf,
if (!(misc_reg03 & 0x01)) {
result = -ENODEV;
- printk(KERN_NOTICE "ums_eneub6250: The driver only supports SD\
- card. To use SM/MS card, please build driver/stagging/keucr\n");
+ printk(KERN_NOTICE "ums_eneub6250: The driver only supports SD card. "
+ "To use SM/MS card, please build driver/staging/keucr\n");
usb_stor_disconnect(intf);
}
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 09e52ba47ddf..ffc4193e9505 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -499,7 +499,6 @@ static int isd200_action( struct us_data *us, int action,
memset(&ata, 0, sizeof(ata));
srb->cmnd = info->cmnd;
srb->device = &srb_dev;
- ++srb->serial_number;
ata.generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
ata.generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 00418995d8e9..e8ae21b2d387 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -819,6 +819,35 @@ Retry_Sense:
}
}
+ /*
+ * Some devices don't work or return incorrect data the first
+ * time they get a READ(10) command, or for the first READ(10)
+ * after a media change. If the INITIAL_READ10 flag is set,
+ * keep track of whether READ(10) commands succeed. If the
+ * previous one succeeded and this one failed, set the REDO_READ10
+ * flag to force a retry.
+ */
+ if (unlikely((us->fflags & US_FL_INITIAL_READ10) &&
+ srb->cmnd[0] == READ_10)) {
+ if (srb->result == SAM_STAT_GOOD) {
+ set_bit(US_FLIDX_READ10_WORKED, &us->dflags);
+ } else if (test_bit(US_FLIDX_READ10_WORKED, &us->dflags)) {
+ clear_bit(US_FLIDX_READ10_WORKED, &us->dflags);
+ set_bit(US_FLIDX_REDO_READ10, &us->dflags);
+ }
+
+ /*
+ * Next, if the REDO_READ10 flag is set, return a result
+ * code that will cause the SCSI core to retry the READ(10)
+ * command immediately.
+ */
+ if (test_bit(US_FLIDX_REDO_READ10, &us->dflags)) {
+ clear_bit(US_FLIDX_REDO_READ10, &us->dflags);
+ srb->result = DID_IMM_RETRY << 16;
+ srb->sense_buffer[0] = 0;
+ }
+ }
+
/* Did we transfer less than the minimum amount required? */
if ((srb->result == SAM_STAT_GOOD || srb->sense_buffer[2] == 0) &&
scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow)
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index c1602b8c5594..ccff3483eebc 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1114,6 +1114,16 @@ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
+/* Reported by Paul Hartman <paul.hartman+linux@gmail.com>
+ * This card reader returns "Illegal Request, Logical Block Address
+ * Out of Range" for the first READ(10) after a new card is inserted.
+ */
+UNUSUAL_DEV( 0x090c, 0x6000, 0x0100, 0x0100,
+ "Feiya",
+ "SD/SDHC Card Reader",
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+ US_FL_INITIAL_READ10 ),
+
/* This Pentax still camera is not conformant
* to the USB storage specification: -
* - It does not like the INQUIRY command. So we must handle this command
@@ -1888,6 +1898,15 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_NO_READ_DISC_INFO ),
+/* Reported by Sven Geggus <sven-usbst@geggus.net>
+ * This encrypted pen drive returns bogus data for the initial READ(10).
+ */
+UNUSUAL_DEV( 0x1b1c, 0x1ab5, 0x0200, 0x0200,
+ "Corsair",
+ "Padlock v2",
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+ US_FL_INITIAL_READ10 ),
+
/* Patch by Richard Schütz <r.schtz@t-online.de>
* This external hard drive enclosure uses a JMicron chip which
* needs the US_FL_IGNORE_RESIDUE flag to work properly. */
diff --git a/drivers/usb/storage/unusual_realtek.h b/drivers/usb/storage/unusual_realtek.h
index 3236e0328516..e41f50c95ed4 100644
--- a/drivers/usb/storage/unusual_realtek.h
+++ b/drivers/usb/storage/unusual_realtek.h
@@ -23,19 +23,19 @@
#if defined(CONFIG_USB_STORAGE_REALTEK) || \
defined(CONFIG_USB_STORAGE_REALTEK_MODULE)
-UNUSUAL_DEV(0x0bda, 0x0159, 0x0000, 0x9999,
+UNUSUAL_DEV(0x0bda, 0x0138, 0x0000, 0x9999,
"Realtek",
"USB Card Reader",
- USB_SC_SCSI, USB_PR_BULK, init_realtek_cr, 0),
+ USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0),
UNUSUAL_DEV(0x0bda, 0x0158, 0x0000, 0x9999,
"Realtek",
"USB Card Reader",
- USB_SC_SCSI, USB_PR_BULK, init_realtek_cr, 0),
+ USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0),
-UNUSUAL_DEV(0x0bda, 0x0138, 0x0000, 0x9999,
+UNUSUAL_DEV(0x0bda, 0x0159, 0x0000, 0x9999,
"Realtek",
"USB Card Reader",
- USB_SC_SCSI, USB_PR_BULK, init_realtek_cr, 0),
+ USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0),
#endif /* defined(CONFIG_USB_STORAGE_REALTEK) || ... */
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 4219c197cb08..0ca095820f3e 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -439,7 +439,9 @@ static void adjust_quirks(struct us_data *us)
US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE |
US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 |
US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE |
- US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT);
+ US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT |
+ US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 |
+ US_FL_INITIAL_READ10);
p = quirks;
while (*p) {
@@ -471,6 +473,12 @@ static void adjust_quirks(struct us_data *us)
case 'c':
f |= US_FL_FIX_CAPACITY;
break;
+ case 'd':
+ f |= US_FL_NO_READ_DISC_INFO;
+ break;
+ case 'e':
+ f |= US_FL_NO_READ_CAPACITY_16;
+ break;
case 'h':
f |= US_FL_CAPACITY_HEURISTICS;
break;
@@ -483,6 +491,9 @@ static void adjust_quirks(struct us_data *us)
case 'm':
f |= US_FL_MAX_SECTORS_64;
break;
+ case 'n':
+ f |= US_FL_INITIAL_READ10;
+ break;
case 'o':
f |= US_FL_CAPACITY_OK;
break;
@@ -946,6 +957,13 @@ int usb_stor_probe2(struct us_data *us)
if (result)
goto BadDevice;
+ /*
+ * If the device returns invalid data for the first READ(10)
+ * command, indicate the command should be retried.
+ */
+ if (us->fflags & US_FL_INITIAL_READ10)
+ set_bit(US_FLIDX_REDO_READ10, &us->dflags);
+
/* Acquire all the other resources and add the host */
result = usb_stor_acquire_resources(us);
if (result)
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 89d3bfff98df..7b0f2113632e 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -73,6 +73,8 @@ struct us_unusual_dev {
#define US_FLIDX_RESETTING 4 /* device reset in progress */
#define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */
#define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */
+#define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */
+#define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */
#define USB_STOR_STRING_LEN 32