aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage/usb.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2011-06-07 11:35:52 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-07 12:05:42 -0400
commit21c13a4f7bc185552c4b402b792c3bbb9aa69df0 (patch)
tree053350f3dd7186759ced487ce470841c3bfb1030 /drivers/usb/storage/usb.c
parent3af51ac9c0889a188aaa3defe5134ef97c80d7c5 (diff)
usb-storage: redo incorrect reads
Some USB mass-storage devices have bugs that cause them not to handle the first READ(10) command they receive correctly. The Corsair Padlock v2 returns completely bogus data for its first read (possibly it returns the data in encrypted form even though the device is supposed to be unlocked). The Feiya SD/SDHC card reader fails to complete the first READ(10) command after it is plugged in or after a new card is inserted, returning a status code that indicates it thinks the command was invalid, which prevents the kernel from retrying the read. Since the first read of a new device or a new medium is for the partition sector, the kernel is unable to retrieve the device's partition table. Users have to manually issue an "hdparm -z" or "blockdev --rereadpt" command before they can access the device. This patch (as1470) works around the problem. It adds a new quirk flag, US_FL_INVALID_READ10, indicating that the first READ(10) should always be retried immediately, as should any failing READ(10) commands (provided the preceding READ(10) command succeeded, to avoid getting stuck in a loop). The patch also adds appropriate unusual_devs entries containing the new flag. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Tested-by: Sven Geggus <sven-usbst@geggus.net> Tested-by: Paul Hartman <paul.hartman+linux@gmail.com> CC: Matthew Dharm <mdharm-usb@one-eyed-alien.net> CC: <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/storage/usb.c')
-rw-r--r--drivers/usb/storage/usb.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 5ee7ac42e08f..0ca095820f3e 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -440,7 +440,8 @@ static void adjust_quirks(struct us_data *us)
440 US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 | 440 US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 |
441 US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE | 441 US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE |
442 US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT | 442 US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT |
443 US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16); 443 US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 |
444 US_FL_INITIAL_READ10);
444 445
445 p = quirks; 446 p = quirks;
446 while (*p) { 447 while (*p) {
@@ -490,6 +491,9 @@ static void adjust_quirks(struct us_data *us)
490 case 'm': 491 case 'm':
491 f |= US_FL_MAX_SECTORS_64; 492 f |= US_FL_MAX_SECTORS_64;
492 break; 493 break;
494 case 'n':
495 f |= US_FL_INITIAL_READ10;
496 break;
493 case 'o': 497 case 'o':
494 f |= US_FL_CAPACITY_OK; 498 f |= US_FL_CAPACITY_OK;
495 break; 499 break;
@@ -953,6 +957,13 @@ int usb_stor_probe2(struct us_data *us)
953 if (result) 957 if (result)
954 goto BadDevice; 958 goto BadDevice;
955 959
960 /*
961 * If the device returns invalid data for the first READ(10)
962 * command, indicate the command should be retried.
963 */
964 if (us->fflags & US_FL_INITIAL_READ10)
965 set_bit(US_FLIDX_REDO_READ10, &us->dflags);
966
956 /* Acquire all the other resources and add the host */ 967 /* Acquire all the other resources and add the host */
957 result = usb_stor_acquire_resources(us); 968 result = usb_stor_acquire_resources(us);
958 if (result) 969 if (result)