Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb-storage: add quirk for mandatory READ_CAPACITY_16

Some USB drive enclosures do not correctly report an
overflow condition if they hold a drive with a capacity
over 2TB and are confronted with a READ_CAPACITY_10.
They answer with their capacity modulo 2TB.
The generic layer cannot cope with that. It must be told
to use READ_CAPACITY_16 from the beginning.

Signed-off-by: Oliver Neukum <oneukum@suse.de>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Oliver Neukum and committed by
Greg Kroah-Hartman
32c37fc3 fd8573f5

+14 -2
+4 -1
drivers/usb/storage/scsiglue.c
··· 211 211 /* 212 212 * Many devices do not respond properly to READ_CAPACITY_16. 213 213 * Tell the SCSI layer to try READ_CAPACITY_10 first. 214 + * However some USB 3.0 drive enclosures return capacity 215 + * modulo 2TB. Those must use READ_CAPACITY_16 214 216 */ 215 - sdev->try_rc_10_first = 1; 217 + if (!(us->fflags & US_FL_NEEDS_CAP16)) 218 + sdev->try_rc_10_first = 1; 216 219 217 220 /* assume SPC3 or latter devices support sense size > 18 */ 218 221 if (sdev->scsi_level > SCSI_SPC_2)
+7
drivers/usb/storage/unusual_devs.h
··· 1925 1925 USB_SC_DEVICE, USB_PR_DEVICE, NULL, 1926 1926 US_FL_IGNORE_RESIDUE ), 1927 1927 1928 + /* Reported by Oliver Neukum <oneukum@suse.com> */ 1929 + UNUSUAL_DEV( 0x174c, 0x55aa, 0x0100, 0x0100, 1930 + "ASMedia", 1931 + "AS2105", 1932 + USB_SC_DEVICE, USB_PR_DEVICE, NULL, 1933 + US_FL_NEEDS_CAP16), 1934 + 1928 1935 /* Reported by Jesse Feddema <jdfeddema@gmail.com> */ 1929 1936 UNUSUAL_DEV( 0x177f, 0x0400, 0x0000, 0x0000, 1930 1937 "Yarvik",
+3 -1
include/linux/usb_usual.h
··· 66 66 US_FLAG(INITIAL_READ10, 0x00100000) \ 67 67 /* Initial READ(10) (and others) must be retried */ \ 68 68 US_FLAG(WRITE_CACHE, 0x00200000) \ 69 - /* Write Cache status is not available */ 69 + /* Write Cache status is not available */ \ 70 + US_FLAG(NEEDS_CAP16, 0x00400000) 71 + /* cannot handle READ_CAPACITY_10 */ 70 72 71 73 #define US_FLAG(name, value) US_FL_##name = value , 72 74 enum { US_DO_ALL_FLAGS };