diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/usb/storage | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/usb/storage')
26 files changed, 621 insertions, 767 deletions
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index eab04a6b5fb..fe2d803a634 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -203,7 +203,7 @@ config USB_STORAGE_ENE_UB6250 | |||
203 | 203 | ||
204 | config USB_UAS | 204 | config USB_UAS |
205 | tristate "USB Attached SCSI" | 205 | tristate "USB Attached SCSI" |
206 | depends on USB && SCSI && BROKEN | 206 | depends on USB && SCSI |
207 | help | 207 | help |
208 | The USB Attached SCSI protocol is supported by some USB | 208 | The USB Attached SCSI protocol is supported by some USB |
209 | storage devices. It permits higher performance by supporting | 209 | storage devices. It permits higher performance by supporting |
@@ -213,3 +213,17 @@ config USB_UAS | |||
213 | say 'Y' or 'M' here and the kernel will use the right driver. | 213 | say 'Y' or 'M' here and the kernel will use the right driver. |
214 | 214 | ||
215 | If you compile this driver as a module, it will be named uas. | 215 | If you compile this driver as a module, it will be named uas. |
216 | |||
217 | config USB_LIBUSUAL | ||
218 | bool "The shared table of common (or usual) storage devices" | ||
219 | depends on USB | ||
220 | help | ||
221 | This module contains a table of common (or usual) devices | ||
222 | for usb-storage and ub drivers, and allows to switch binding | ||
223 | of these devices without rebuilding modules. | ||
224 | |||
225 | Typical syntax of /etc/modprobe.conf is: | ||
226 | |||
227 | options libusual bias="ub" | ||
228 | |||
229 | If unsure, say N. | ||
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index 4cd55481b30..82e6416a2d4 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile | |||
@@ -12,9 +12,16 @@ obj-$(CONFIG_USB_STORAGE) += usb-storage.o | |||
12 | 12 | ||
13 | usb-storage-y := scsiglue.o protocol.o transport.o usb.o | 13 | usb-storage-y := scsiglue.o protocol.o transport.o usb.o |
14 | usb-storage-y += initializers.o sierra_ms.o option_ms.o | 14 | usb-storage-y += initializers.o sierra_ms.o option_ms.o |
15 | usb-storage-y += usual-tables.o | 15 | |
16 | usb-storage-$(CONFIG_USB_STORAGE_DEBUG) += debug.o | 16 | usb-storage-$(CONFIG_USB_STORAGE_DEBUG) += debug.o |
17 | 17 | ||
18 | ifeq ($(CONFIG_USB_LIBUSUAL),) | ||
19 | usb-storage-y += usual-tables.o | ||
20 | else | ||
21 | obj-$(CONFIG_USB) += usb-libusual.o | ||
22 | usb-libusual-y := libusual.o usual-tables.o | ||
23 | endif | ||
24 | |||
18 | obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o | 25 | obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o |
19 | obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += ums-cypress.o | 26 | obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += ums-cypress.o |
20 | obj-$(CONFIG_USB_STORAGE_DATAFAB) += ums-datafab.o | 27 | obj-$(CONFIG_USB_STORAGE_DATAFAB) += ums-datafab.o |
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index be5564cc8e0..42d0eaed4a0 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c | |||
@@ -137,9 +137,9 @@ static int init_alauda(struct us_data *us); | |||
137 | vendorName, productName, useProtocol, useTransport, \ | 137 | vendorName, productName, useProtocol, useTransport, \ |
138 | initFunction, flags) \ | 138 | initFunction, flags) \ |
139 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 139 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
140 | .driver_info = (flags) } | 140 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
141 | 141 | ||
142 | static struct usb_device_id alauda_usb_ids[] = { | 142 | struct usb_device_id alauda_usb_ids[] = { |
143 | # include "unusual_alauda.h" | 143 | # include "unusual_alauda.h" |
144 | { } /* Terminating entry */ | 144 | { } /* Terminating entry */ |
145 | }; | 145 | }; |
@@ -1276,7 +1276,17 @@ static struct usb_driver alauda_driver = { | |||
1276 | .post_reset = usb_stor_post_reset, | 1276 | .post_reset = usb_stor_post_reset, |
1277 | .id_table = alauda_usb_ids, | 1277 | .id_table = alauda_usb_ids, |
1278 | .soft_unbind = 1, | 1278 | .soft_unbind = 1, |
1279 | .no_dynamic_id = 1, | ||
1280 | }; | 1279 | }; |
1281 | 1280 | ||
1282 | module_usb_driver(alauda_driver); | 1281 | static int __init alauda_init(void) |
1282 | { | ||
1283 | return usb_register(&alauda_driver); | ||
1284 | } | ||
1285 | |||
1286 | static void __exit alauda_exit(void) | ||
1287 | { | ||
1288 | usb_deregister(&alauda_driver); | ||
1289 | } | ||
1290 | |||
1291 | module_init(alauda_init); | ||
1292 | module_exit(alauda_exit); | ||
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index 070b5c0ebbf..c8447182118 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c | |||
@@ -41,9 +41,9 @@ MODULE_LICENSE("GPL"); | |||
41 | vendorName, productName, useProtocol, useTransport, \ | 41 | vendorName, productName, useProtocol, useTransport, \ |
42 | initFunction, flags) \ | 42 | initFunction, flags) \ |
43 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 43 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
44 | .driver_info = (flags) } | 44 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
45 | 45 | ||
46 | static struct usb_device_id cypress_usb_ids[] = { | 46 | struct usb_device_id cypress_usb_ids[] = { |
47 | # include "unusual_cypress.h" | 47 | # include "unusual_cypress.h" |
48 | { } /* Terminating entry */ | 48 | { } /* Terminating entry */ |
49 | }; | 49 | }; |
@@ -272,7 +272,17 @@ static struct usb_driver cypress_driver = { | |||
272 | .post_reset = usb_stor_post_reset, | 272 | .post_reset = usb_stor_post_reset, |
273 | .id_table = cypress_usb_ids, | 273 | .id_table = cypress_usb_ids, |
274 | .soft_unbind = 1, | 274 | .soft_unbind = 1, |
275 | .no_dynamic_id = 1, | ||
276 | }; | 275 | }; |
277 | 276 | ||
278 | module_usb_driver(cypress_driver); | 277 | static int __init cypress_init(void) |
278 | { | ||
279 | return usb_register(&cypress_driver); | ||
280 | } | ||
281 | |||
282 | static void __exit cypress_exit(void) | ||
283 | { | ||
284 | usb_deregister(&cypress_driver); | ||
285 | } | ||
286 | |||
287 | module_init(cypress_init); | ||
288 | module_exit(cypress_exit); | ||
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 494fee5af41..ded836b02d7 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c | |||
@@ -86,9 +86,9 @@ static int datafab_determine_lun(struct us_data *us, | |||
86 | vendorName, productName, useProtocol, useTransport, \ | 86 | vendorName, productName, useProtocol, useTransport, \ |
87 | initFunction, flags) \ | 87 | initFunction, flags) \ |
88 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 88 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
89 | .driver_info = (flags) } | 89 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
90 | 90 | ||
91 | static struct usb_device_id datafab_usb_ids[] = { | 91 | struct usb_device_id datafab_usb_ids[] = { |
92 | # include "unusual_datafab.h" | 92 | # include "unusual_datafab.h" |
93 | { } /* Terminating entry */ | 93 | { } /* Terminating entry */ |
94 | }; | 94 | }; |
@@ -751,7 +751,17 @@ static struct usb_driver datafab_driver = { | |||
751 | .post_reset = usb_stor_post_reset, | 751 | .post_reset = usb_stor_post_reset, |
752 | .id_table = datafab_usb_ids, | 752 | .id_table = datafab_usb_ids, |
753 | .soft_unbind = 1, | 753 | .soft_unbind = 1, |
754 | .no_dynamic_id = 1, | ||
755 | }; | 754 | }; |
756 | 755 | ||
757 | module_usb_driver(datafab_driver); | 756 | static int __init datafab_init(void) |
757 | { | ||
758 | return usb_register(&datafab_driver); | ||
759 | } | ||
760 | |||
761 | static void __exit datafab_exit(void) | ||
762 | { | ||
763 | usb_deregister(&datafab_driver); | ||
764 | } | ||
765 | |||
766 | module_init(datafab_init); | ||
767 | module_exit(datafab_exit); | ||
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 118b134a1da..4dca3ef0668 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c | |||
@@ -29,21 +29,9 @@ | |||
29 | #include "protocol.h" | 29 | #include "protocol.h" |
30 | #include "debug.h" | 30 | #include "debug.h" |
31 | 31 | ||
32 | #define SD_INIT1_FIRMWARE "ene-ub6250/sd_init1.bin" | ||
33 | #define SD_INIT2_FIRMWARE "ene-ub6250/sd_init2.bin" | ||
34 | #define SD_RW_FIRMWARE "ene-ub6250/sd_rdwr.bin" | ||
35 | #define MS_INIT_FIRMWARE "ene-ub6250/ms_init.bin" | ||
36 | #define MSP_RW_FIRMWARE "ene-ub6250/msp_rdwr.bin" | ||
37 | #define MS_RW_FIRMWARE "ene-ub6250/ms_rdwr.bin" | ||
38 | |||
39 | MODULE_DESCRIPTION("Driver for ENE UB6250 reader"); | 32 | MODULE_DESCRIPTION("Driver for ENE UB6250 reader"); |
40 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL"); |
41 | MODULE_FIRMWARE(SD_INIT1_FIRMWARE); | 34 | |
42 | MODULE_FIRMWARE(SD_INIT2_FIRMWARE); | ||
43 | MODULE_FIRMWARE(SD_RW_FIRMWARE); | ||
44 | MODULE_FIRMWARE(MS_INIT_FIRMWARE); | ||
45 | MODULE_FIRMWARE(MSP_RW_FIRMWARE); | ||
46 | MODULE_FIRMWARE(MS_RW_FIRMWARE); | ||
47 | 35 | ||
48 | /* | 36 | /* |
49 | * The table of devices | 37 | * The table of devices |
@@ -52,9 +40,9 @@ MODULE_FIRMWARE(MS_RW_FIRMWARE); | |||
52 | vendorName, productName, useProtocol, useTransport, \ | 40 | vendorName, productName, useProtocol, useTransport, \ |
53 | initFunction, flags) \ | 41 | initFunction, flags) \ |
54 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 42 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
55 | .driver_info = (flags)} | 43 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
56 | 44 | ||
57 | static struct usb_device_id ene_ub6250_usb_ids[] = { | 45 | struct usb_device_id ene_ub6250_usb_ids[] = { |
58 | # include "unusual_ene_ub6250.h" | 46 | # include "unusual_ene_ub6250.h" |
59 | { } /* Terminating entry */ | 47 | { } /* Terminating entry */ |
60 | }; | 48 | }; |
@@ -619,8 +607,8 @@ static int sd_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb) | |||
619 | 607 | ||
620 | static int sd_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb) | 608 | static int sd_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb) |
621 | { | 609 | { |
622 | u32 bl_num; | 610 | u32 bl_num; |
623 | u32 bl_len; | 611 | u16 bl_len; |
624 | unsigned int offset = 0; | 612 | unsigned int offset = 0; |
625 | unsigned char buf[8]; | 613 | unsigned char buf[8]; |
626 | struct scatterlist *sg = NULL; | 614 | struct scatterlist *sg = NULL; |
@@ -634,7 +622,7 @@ static int sd_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb) | |||
634 | else | 622 | else |
635 | bl_num = (info->HC_C_SIZE + 1) * 1024 - 1; | 623 | bl_num = (info->HC_C_SIZE + 1) * 1024 - 1; |
636 | } else { | 624 | } else { |
637 | bl_len = 1 << (info->SD_READ_BL_LEN); | 625 | bl_len = 1<<(info->SD_READ_BL_LEN); |
638 | bl_num = info->SD_Block_Mult * (info->SD_C_SIZE + 1) | 626 | bl_num = info->SD_Block_Mult * (info->SD_C_SIZE + 1) |
639 | * (1 << (info->SD_C_SIZE_MULT + 2)) - 1; | 627 | * (1 << (info->SD_C_SIZE_MULT + 2)) - 1; |
640 | } | 628 | } |
@@ -686,7 +674,7 @@ static int sd_scsi_read(struct us_data *us, struct scsi_cmnd *srb) | |||
686 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 674 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
687 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 675 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
688 | bcb->DataTransferLength = blenByte; | 676 | bcb->DataTransferLength = blenByte; |
689 | bcb->Flags = US_BULK_FLAG_IN; | 677 | bcb->Flags = 0x80; |
690 | bcb->CDB[0] = 0xF1; | 678 | bcb->CDB[0] = 0xF1; |
691 | bcb->CDB[5] = (unsigned char)(bnByte); | 679 | bcb->CDB[5] = (unsigned char)(bnByte); |
692 | bcb->CDB[4] = (unsigned char)(bnByte>>8); | 680 | bcb->CDB[4] = (unsigned char)(bnByte>>8); |
@@ -789,7 +777,7 @@ static int ms_lib_free_logicalmap(struct us_data *us) | |||
789 | return 0; | 777 | return 0; |
790 | } | 778 | } |
791 | 779 | ||
792 | static int ms_lib_alloc_logicalmap(struct us_data *us) | 780 | int ms_lib_alloc_logicalmap(struct us_data *us) |
793 | { | 781 | { |
794 | u32 i; | 782 | u32 i; |
795 | struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; | 783 | struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; |
@@ -870,7 +858,7 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr, | |||
870 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 858 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
871 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 859 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
872 | bcb->DataTransferLength = 0x200; | 860 | bcb->DataTransferLength = 0x200; |
873 | bcb->Flags = US_BULK_FLAG_IN; | 861 | bcb->Flags = 0x80; |
874 | bcb->CDB[0] = 0xF1; | 862 | bcb->CDB[0] = 0xF1; |
875 | 863 | ||
876 | bcb->CDB[1] = 0x02; /* in init.c ENE_MSInit() is 0x01 */ | 864 | bcb->CDB[1] = 0x02; /* in init.c ENE_MSInit() is 0x01 */ |
@@ -889,7 +877,7 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr, | |||
889 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 877 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
890 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 878 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
891 | bcb->DataTransferLength = 0x4; | 879 | bcb->DataTransferLength = 0x4; |
892 | bcb->Flags = US_BULK_FLAG_IN; | 880 | bcb->Flags = 0x80; |
893 | bcb->CDB[0] = 0xF1; | 881 | bcb->CDB[0] = 0xF1; |
894 | bcb->CDB[1] = 0x03; | 882 | bcb->CDB[1] = 0x03; |
895 | 883 | ||
@@ -1182,7 +1170,7 @@ static int ms_read_eraseblock(struct us_data *us, u32 PhyBlockAddr) | |||
1182 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 1170 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
1183 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 1171 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
1184 | bcb->DataTransferLength = 0x200; | 1172 | bcb->DataTransferLength = 0x200; |
1185 | bcb->Flags = US_BULK_FLAG_IN; | 1173 | bcb->Flags = 0x80; |
1186 | bcb->CDB[0] = 0xF2; | 1174 | bcb->CDB[0] = 0xF2; |
1187 | bcb->CDB[1] = 0x06; | 1175 | bcb->CDB[1] = 0x06; |
1188 | bcb->CDB[4] = (unsigned char)(bn); | 1176 | bcb->CDB[4] = (unsigned char)(bn); |
@@ -1261,7 +1249,7 @@ static int ms_lib_overwrite_extra(struct us_data *us, u32 PhyBlockAddr, | |||
1261 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 1249 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
1262 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 1250 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
1263 | bcb->DataTransferLength = 0x4; | 1251 | bcb->DataTransferLength = 0x4; |
1264 | bcb->Flags = US_BULK_FLAG_IN; | 1252 | bcb->Flags = 0x80; |
1265 | bcb->CDB[0] = 0xF2; | 1253 | bcb->CDB[0] = 0xF2; |
1266 | bcb->CDB[1] = 0x05; | 1254 | bcb->CDB[1] = 0x05; |
1267 | bcb->CDB[5] = (unsigned char)(PageNum); | 1255 | bcb->CDB[5] = (unsigned char)(PageNum); |
@@ -1343,7 +1331,7 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock, | |||
1343 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 1331 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
1344 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 1332 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
1345 | bcb->DataTransferLength = 0x4; | 1333 | bcb->DataTransferLength = 0x4; |
1346 | bcb->Flags = US_BULK_FLAG_IN; | 1334 | bcb->Flags = 0x80; |
1347 | bcb->CDB[0] = 0xF1; | 1335 | bcb->CDB[0] = 0xF1; |
1348 | bcb->CDB[1] = 0x03; | 1336 | bcb->CDB[1] = 0x03; |
1349 | bcb->CDB[5] = (unsigned char)(PageNum); | 1337 | bcb->CDB[5] = (unsigned char)(PageNum); |
@@ -1545,7 +1533,7 @@ static int ms_lib_read_extrablock(struct us_data *us, u32 PhyBlock, | |||
1545 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 1533 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
1546 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 1534 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
1547 | bcb->DataTransferLength = 0x4 * blen; | 1535 | bcb->DataTransferLength = 0x4 * blen; |
1548 | bcb->Flags = US_BULK_FLAG_IN; | 1536 | bcb->Flags = 0x80; |
1549 | bcb->CDB[0] = 0xF1; | 1537 | bcb->CDB[0] = 0xF1; |
1550 | bcb->CDB[1] = 0x03; | 1538 | bcb->CDB[1] = 0x03; |
1551 | bcb->CDB[5] = (unsigned char)(PageNum); | 1539 | bcb->CDB[5] = (unsigned char)(PageNum); |
@@ -1662,7 +1650,7 @@ static int ms_scsi_read(struct us_data *us, struct scsi_cmnd *srb) | |||
1662 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 1650 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
1663 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 1651 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
1664 | bcb->DataTransferLength = blenByte; | 1652 | bcb->DataTransferLength = blenByte; |
1665 | bcb->Flags = US_BULK_FLAG_IN; | 1653 | bcb->Flags = 0x80; |
1666 | bcb->CDB[0] = 0xF1; | 1654 | bcb->CDB[0] = 0xF1; |
1667 | bcb->CDB[1] = 0x02; | 1655 | bcb->CDB[1] = 0x02; |
1668 | bcb->CDB[5] = (unsigned char)(bn); | 1656 | bcb->CDB[5] = (unsigned char)(bn); |
@@ -1706,7 +1694,7 @@ static int ms_scsi_read(struct us_data *us, struct scsi_cmnd *srb) | |||
1706 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 1694 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
1707 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 1695 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
1708 | bcb->DataTransferLength = 0x200 * len; | 1696 | bcb->DataTransferLength = 0x200 * len; |
1709 | bcb->Flags = US_BULK_FLAG_IN; | 1697 | bcb->Flags = 0x80; |
1710 | bcb->CDB[0] = 0xF1; | 1698 | bcb->CDB[0] = 0xF1; |
1711 | bcb->CDB[1] = 0x02; | 1699 | bcb->CDB[1] = 0x02; |
1712 | bcb->CDB[5] = (unsigned char)(blkno); | 1700 | bcb->CDB[5] = (unsigned char)(blkno); |
@@ -1774,9 +1762,10 @@ static int ms_scsi_write(struct us_data *us, struct scsi_cmnd *srb) | |||
1774 | result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1); | 1762 | result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1); |
1775 | } else { | 1763 | } else { |
1776 | void *buf; | 1764 | void *buf; |
1777 | int offset = 0; | 1765 | int offset; |
1778 | u16 PhyBlockAddr; | 1766 | u16 PhyBlockAddr; |
1779 | u8 PageNum; | 1767 | u8 PageNum; |
1768 | u32 result; | ||
1780 | u16 len, oldphy, newphy; | 1769 | u16 len, oldphy, newphy; |
1781 | 1770 | ||
1782 | buf = kmalloc(blenByte, GFP_KERNEL); | 1771 | buf = kmalloc(blenByte, GFP_KERNEL); |
@@ -1839,7 +1828,7 @@ static int ene_get_card_type(struct us_data *us, u16 index, void *buf) | |||
1839 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 1828 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
1840 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 1829 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
1841 | bcb->DataTransferLength = 0x01; | 1830 | bcb->DataTransferLength = 0x01; |
1842 | bcb->Flags = US_BULK_FLAG_IN; | 1831 | bcb->Flags = 0x80; |
1843 | bcb->CDB[0] = 0xED; | 1832 | bcb->CDB[0] = 0xED; |
1844 | bcb->CDB[2] = (unsigned char)(index>>8); | 1833 | bcb->CDB[2] = (unsigned char)(index>>8); |
1845 | bcb->CDB[3] = (unsigned char)index; | 1834 | bcb->CDB[3] = (unsigned char)index; |
@@ -1895,28 +1884,28 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag) | |||
1895 | /* For SD */ | 1884 | /* For SD */ |
1896 | case SD_INIT1_PATTERN: | 1885 | case SD_INIT1_PATTERN: |
1897 | US_DEBUGP("SD_INIT1_PATTERN\n"); | 1886 | US_DEBUGP("SD_INIT1_PATTERN\n"); |
1898 | fw_name = SD_INIT1_FIRMWARE; | 1887 | fw_name = "ene-ub6250/sd_init1.bin"; |
1899 | break; | 1888 | break; |
1900 | case SD_INIT2_PATTERN: | 1889 | case SD_INIT2_PATTERN: |
1901 | US_DEBUGP("SD_INIT2_PATTERN\n"); | 1890 | US_DEBUGP("SD_INIT2_PATTERN\n"); |
1902 | fw_name = SD_INIT2_FIRMWARE; | 1891 | fw_name = "ene-ub6250/sd_init2.bin"; |
1903 | break; | 1892 | break; |
1904 | case SD_RW_PATTERN: | 1893 | case SD_RW_PATTERN: |
1905 | US_DEBUGP("SD_RW_PATTERN\n"); | 1894 | US_DEBUGP("SD_RDWR_PATTERN\n"); |
1906 | fw_name = SD_RW_FIRMWARE; | 1895 | fw_name = "ene-ub6250/sd_rdwr.bin"; |
1907 | break; | 1896 | break; |
1908 | /* For MS */ | 1897 | /* For MS */ |
1909 | case MS_INIT_PATTERN: | 1898 | case MS_INIT_PATTERN: |
1910 | US_DEBUGP("MS_INIT_PATTERN\n"); | 1899 | US_DEBUGP("MS_INIT_PATTERN\n"); |
1911 | fw_name = MS_INIT_FIRMWARE; | 1900 | fw_name = "ene-ub6250/ms_init.bin"; |
1912 | break; | 1901 | break; |
1913 | case MSP_RW_PATTERN: | 1902 | case MSP_RW_PATTERN: |
1914 | US_DEBUGP("MSP_RW_PATTERN\n"); | 1903 | US_DEBUGP("MSP_RW_PATTERN\n"); |
1915 | fw_name = MSP_RW_FIRMWARE; | 1904 | fw_name = "ene-ub6250/msp_rdwr.bin"; |
1916 | break; | 1905 | break; |
1917 | case MS_RW_PATTERN: | 1906 | case MS_RW_PATTERN: |
1918 | US_DEBUGP("MS_RW_PATTERN\n"); | 1907 | US_DEBUGP("MS_RW_PATTERN\n"); |
1919 | fw_name = MS_RW_FIRMWARE; | 1908 | fw_name = "ene-ub6250/ms_rdwr.bin"; |
1920 | break; | 1909 | break; |
1921 | default: | 1910 | default: |
1922 | US_DEBUGP("----------- Unknown PATTERN ----------\n"); | 1911 | US_DEBUGP("----------- Unknown PATTERN ----------\n"); |
@@ -1945,7 +1934,11 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag) | |||
1945 | kfree(buf); | 1934 | kfree(buf); |
1946 | 1935 | ||
1947 | nofw: | 1936 | nofw: |
1948 | release_firmware(sd_fw); | 1937 | if (sd_fw != NULL) { |
1938 | release_firmware(sd_fw); | ||
1939 | sd_fw = NULL; | ||
1940 | } | ||
1941 | |||
1949 | return result; | 1942 | return result; |
1950 | } | 1943 | } |
1951 | 1944 | ||
@@ -2091,7 +2084,7 @@ static int ene_ms_init(struct us_data *us) | |||
2091 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 2084 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
2092 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 2085 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
2093 | bcb->DataTransferLength = 0x200; | 2086 | bcb->DataTransferLength = 0x200; |
2094 | bcb->Flags = US_BULK_FLAG_IN; | 2087 | bcb->Flags = 0x80; |
2095 | bcb->CDB[0] = 0xF1; | 2088 | bcb->CDB[0] = 0xF1; |
2096 | bcb->CDB[1] = 0x01; | 2089 | bcb->CDB[1] = 0x01; |
2097 | 2090 | ||
@@ -2142,7 +2135,7 @@ static int ene_sd_init(struct us_data *us) | |||
2142 | 2135 | ||
2143 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 2136 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
2144 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 2137 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
2145 | bcb->Flags = US_BULK_FLAG_IN; | 2138 | bcb->Flags = 0x80; |
2146 | bcb->CDB[0] = 0xF2; | 2139 | bcb->CDB[0] = 0xF2; |
2147 | 2140 | ||
2148 | result = ene_send_scsi_cmd(us, FDIR_READ, NULL, 0); | 2141 | result = ene_send_scsi_cmd(us, FDIR_READ, NULL, 0); |
@@ -2161,7 +2154,7 @@ static int ene_sd_init(struct us_data *us) | |||
2161 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); | 2154 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
2162 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 2155 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
2163 | bcb->DataTransferLength = 0x200; | 2156 | bcb->DataTransferLength = 0x200; |
2164 | bcb->Flags = US_BULK_FLAG_IN; | 2157 | bcb->Flags = 0x80; |
2165 | bcb->CDB[0] = 0xF1; | 2158 | bcb->CDB[0] = 0xF1; |
2166 | 2159 | ||
2167 | result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0); | 2160 | result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0); |
@@ -2256,7 +2249,7 @@ static int sd_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) | |||
2256 | /* | 2249 | /* |
2257 | * ms_scsi_irp() | 2250 | * ms_scsi_irp() |
2258 | */ | 2251 | */ |
2259 | static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) | 2252 | int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) |
2260 | { | 2253 | { |
2261 | int result; | 2254 | int result; |
2262 | struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra; | 2255 | struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra; |
@@ -2415,7 +2408,17 @@ static struct usb_driver ene_ub6250_driver = { | |||
2415 | .post_reset = usb_stor_post_reset, | 2408 | .post_reset = usb_stor_post_reset, |
2416 | .id_table = ene_ub6250_usb_ids, | 2409 | .id_table = ene_ub6250_usb_ids, |
2417 | .soft_unbind = 1, | 2410 | .soft_unbind = 1, |
2418 | .no_dynamic_id = 1, | ||
2419 | }; | 2411 | }; |
2420 | 2412 | ||
2421 | module_usb_driver(ene_ub6250_driver); | 2413 | static int __init ene_ub6250_init(void) |
2414 | { | ||
2415 | return usb_register(&ene_ub6250_driver); | ||
2416 | } | ||
2417 | |||
2418 | static void __exit ene_ub6250_exit(void) | ||
2419 | { | ||
2420 | usb_deregister(&ene_ub6250_driver); | ||
2421 | } | ||
2422 | |||
2423 | module_init(ene_ub6250_init); | ||
2424 | module_exit(ene_ub6250_exit); | ||
diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index e6df087dca9..6542ca40d50 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c | |||
@@ -117,9 +117,9 @@ static int init_freecom(struct us_data *us); | |||
117 | vendorName, productName, useProtocol, useTransport, \ | 117 | vendorName, productName, useProtocol, useTransport, \ |
118 | initFunction, flags) \ | 118 | initFunction, flags) \ |
119 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 119 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
120 | .driver_info = (flags) } | 120 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
121 | 121 | ||
122 | static struct usb_device_id freecom_usb_ids[] = { | 122 | struct usb_device_id freecom_usb_ids[] = { |
123 | # include "unusual_freecom.h" | 123 | # include "unusual_freecom.h" |
124 | { } /* Terminating entry */ | 124 | { } /* Terminating entry */ |
125 | }; | 125 | }; |
@@ -553,7 +553,17 @@ static struct usb_driver freecom_driver = { | |||
553 | .post_reset = usb_stor_post_reset, | 553 | .post_reset = usb_stor_post_reset, |
554 | .id_table = freecom_usb_ids, | 554 | .id_table = freecom_usb_ids, |
555 | .soft_unbind = 1, | 555 | .soft_unbind = 1, |
556 | .no_dynamic_id = 1, | ||
557 | }; | 556 | }; |
558 | 557 | ||
559 | module_usb_driver(freecom_driver); | 558 | static int __init freecom_init(void) |
559 | { | ||
560 | return usb_register(&freecom_driver); | ||
561 | } | ||
562 | |||
563 | static void __exit freecom_exit(void) | ||
564 | { | ||
565 | usb_deregister(&freecom_driver); | ||
566 | } | ||
567 | |||
568 | module_init(freecom_init); | ||
569 | module_exit(freecom_exit); | ||
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index ecea4787736..ffc4193e950 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c | |||
@@ -61,7 +61,7 @@ | |||
61 | #include "scsiglue.h" | 61 | #include "scsiglue.h" |
62 | 62 | ||
63 | MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC"); | 63 | MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC"); |
64 | MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>"); | 64 | MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>"); |
65 | MODULE_LICENSE("GPL"); | 65 | MODULE_LICENSE("GPL"); |
66 | 66 | ||
67 | static int isd200_Initialization(struct us_data *us); | 67 | static int isd200_Initialization(struct us_data *us); |
@@ -74,15 +74,16 @@ static int isd200_Initialization(struct us_data *us); | |||
74 | vendorName, productName, useProtocol, useTransport, \ | 74 | vendorName, productName, useProtocol, useTransport, \ |
75 | initFunction, flags) \ | 75 | initFunction, flags) \ |
76 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 76 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
77 | .driver_info = (flags) } | 77 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
78 | 78 | ||
79 | static struct usb_device_id isd200_usb_ids[] = { | 79 | struct usb_device_id isd200_usb_ids[] = { |
80 | # include "unusual_isd200.h" | 80 | # include "unusual_isd200.h" |
81 | { } /* Terminating entry */ | 81 | { } /* Terminating entry */ |
82 | }; | 82 | }; |
83 | MODULE_DEVICE_TABLE(usb, isd200_usb_ids); | 83 | MODULE_DEVICE_TABLE(usb, isd200_usb_ids); |
84 | 84 | ||
85 | #undef UNUSUAL_DEV | 85 | #undef UNUSUAL_DEV |
86 | #undef USUAL_DEV | ||
86 | 87 | ||
87 | /* | 88 | /* |
88 | * The flags table | 89 | * The flags table |
@@ -104,6 +105,8 @@ static struct us_unusual_dev isd200_unusual_dev_list[] = { | |||
104 | }; | 105 | }; |
105 | 106 | ||
106 | #undef UNUSUAL_DEV | 107 | #undef UNUSUAL_DEV |
108 | #undef USUAL_DEV | ||
109 | |||
107 | 110 | ||
108 | /* Timeout defines (in Seconds) */ | 111 | /* Timeout defines (in Seconds) */ |
109 | 112 | ||
@@ -1563,7 +1566,17 @@ static struct usb_driver isd200_driver = { | |||
1563 | .post_reset = usb_stor_post_reset, | 1566 | .post_reset = usb_stor_post_reset, |
1564 | .id_table = isd200_usb_ids, | 1567 | .id_table = isd200_usb_ids, |
1565 | .soft_unbind = 1, | 1568 | .soft_unbind = 1, |
1566 | .no_dynamic_id = 1, | ||
1567 | }; | 1569 | }; |
1568 | 1570 | ||
1569 | module_usb_driver(isd200_driver); | 1571 | static int __init isd200_init(void) |
1572 | { | ||
1573 | return usb_register(&isd200_driver); | ||
1574 | } | ||
1575 | |||
1576 | static void __exit isd200_exit(void) | ||
1577 | { | ||
1578 | usb_deregister(&isd200_driver); | ||
1579 | } | ||
1580 | |||
1581 | module_init(isd200_init); | ||
1582 | module_exit(isd200_exit); | ||
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index ddc78780b1a..6168596c5ac 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c | |||
@@ -69,9 +69,9 @@ MODULE_LICENSE("GPL"); | |||
69 | vendorName, productName, useProtocol, useTransport, \ | 69 | vendorName, productName, useProtocol, useTransport, \ |
70 | initFunction, flags) \ | 70 | initFunction, flags) \ |
71 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 71 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
72 | .driver_info = (flags) } | 72 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
73 | 73 | ||
74 | static struct usb_device_id jumpshot_usb_ids[] = { | 74 | struct usb_device_id jumpshot_usb_ids[] = { |
75 | # include "unusual_jumpshot.h" | 75 | # include "unusual_jumpshot.h" |
76 | { } /* Terminating entry */ | 76 | { } /* Terminating entry */ |
77 | }; | 77 | }; |
@@ -677,7 +677,17 @@ static struct usb_driver jumpshot_driver = { | |||
677 | .post_reset = usb_stor_post_reset, | 677 | .post_reset = usb_stor_post_reset, |
678 | .id_table = jumpshot_usb_ids, | 678 | .id_table = jumpshot_usb_ids, |
679 | .soft_unbind = 1, | 679 | .soft_unbind = 1, |
680 | .no_dynamic_id = 1, | ||
681 | }; | 680 | }; |
682 | 681 | ||
683 | module_usb_driver(jumpshot_driver); | 682 | static int __init jumpshot_init(void) |
683 | { | ||
684 | return usb_register(&jumpshot_driver); | ||
685 | } | ||
686 | |||
687 | static void __exit jumpshot_exit(void) | ||
688 | { | ||
689 | usb_deregister(&jumpshot_driver); | ||
690 | } | ||
691 | |||
692 | module_init(jumpshot_init); | ||
693 | module_exit(jumpshot_exit); | ||
diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index f085ffb606c..ba1b7890688 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c | |||
@@ -57,9 +57,9 @@ static int rio_karma_init(struct us_data *us); | |||
57 | vendorName, productName, useProtocol, useTransport, \ | 57 | vendorName, productName, useProtocol, useTransport, \ |
58 | initFunction, flags) \ | 58 | initFunction, flags) \ |
59 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 59 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
60 | .driver_info = (flags) } | 60 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
61 | 61 | ||
62 | static struct usb_device_id karma_usb_ids[] = { | 62 | struct usb_device_id karma_usb_ids[] = { |
63 | # include "unusual_karma.h" | 63 | # include "unusual_karma.h" |
64 | { } /* Terminating entry */ | 64 | { } /* Terminating entry */ |
65 | }; | 65 | }; |
@@ -230,7 +230,17 @@ static struct usb_driver karma_driver = { | |||
230 | .post_reset = usb_stor_post_reset, | 230 | .post_reset = usb_stor_post_reset, |
231 | .id_table = karma_usb_ids, | 231 | .id_table = karma_usb_ids, |
232 | .soft_unbind = 1, | 232 | .soft_unbind = 1, |
233 | .no_dynamic_id = 1, | ||
234 | }; | 233 | }; |
235 | 234 | ||
236 | module_usb_driver(karma_driver); | 235 | static int __init karma_init(void) |
236 | { | ||
237 | return usb_register(&karma_driver); | ||
238 | } | ||
239 | |||
240 | static void __exit karma_exit(void) | ||
241 | { | ||
242 | usb_deregister(&karma_driver); | ||
243 | } | ||
244 | |||
245 | module_init(karma_init); | ||
246 | module_exit(karma_exit); | ||
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index cb79de61f4c..1943be5a291 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -67,9 +67,9 @@ struct usb_onetouch { | |||
67 | vendorName, productName, useProtocol, useTransport, \ | 67 | vendorName, productName, useProtocol, useTransport, \ |
68 | initFunction, flags) \ | 68 | initFunction, flags) \ |
69 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 69 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
70 | .driver_info = (flags) } | 70 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
71 | 71 | ||
72 | static struct usb_device_id onetouch_usb_ids[] = { | 72 | struct usb_device_id onetouch_usb_ids[] = { |
73 | # include "unusual_onetouch.h" | 73 | # include "unusual_onetouch.h" |
74 | { } /* Terminating entry */ | 74 | { } /* Terminating entry */ |
75 | }; | 75 | }; |
@@ -312,7 +312,17 @@ static struct usb_driver onetouch_driver = { | |||
312 | .post_reset = usb_stor_post_reset, | 312 | .post_reset = usb_stor_post_reset, |
313 | .id_table = onetouch_usb_ids, | 313 | .id_table = onetouch_usb_ids, |
314 | .soft_unbind = 1, | 314 | .soft_unbind = 1, |
315 | .no_dynamic_id = 1, | ||
316 | }; | 315 | }; |
317 | 316 | ||
318 | module_usb_driver(onetouch_driver); | 317 | static int __init onetouch_init(void) |
318 | { | ||
319 | return usb_register(&onetouch_driver); | ||
320 | } | ||
321 | |||
322 | static void __exit onetouch_exit(void) | ||
323 | { | ||
324 | usb_deregister(&onetouch_driver); | ||
325 | } | ||
326 | |||
327 | module_init(onetouch_init); | ||
328 | module_exit(onetouch_exit); | ||
diff --git a/drivers/usb/storage/option_ms.c b/drivers/usb/storage/option_ms.c index e0f76bb0591..89460181d12 100644 --- a/drivers/usb/storage/option_ms.c +++ b/drivers/usb/storage/option_ms.c | |||
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | #include <linux/usb.h> | 23 | #include <linux/usb.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/module.h> | ||
26 | 25 | ||
27 | #include "usb.h" | 26 | #include "usb.h" |
28 | #include "transport.h" | 27 | #include "transport.h" |
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index 5dfb4c36a1b..0fded39e3b3 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c | |||
@@ -43,7 +43,6 @@ | |||
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <linux/highmem.h> | 45 | #include <linux/highmem.h> |
46 | #include <linux/export.h> | ||
47 | #include <scsi/scsi.h> | 46 | #include <scsi/scsi.h> |
48 | #include <scsi/scsi_cmnd.h> | 47 | #include <scsi/scsi_cmnd.h> |
49 | 48 | ||
@@ -66,7 +65,7 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) | |||
66 | * NOTE: This only works because a scsi_cmnd struct field contains | 65 | * NOTE: This only works because a scsi_cmnd struct field contains |
67 | * a unsigned char cmnd[16], so we know we have storage available | 66 | * a unsigned char cmnd[16], so we know we have storage available |
68 | */ | 67 | */ |
69 | for (; srb->cmd_len < 12; srb->cmd_len++) | 68 | for (; srb->cmd_len<12; srb->cmd_len++) |
70 | srb->cmnd[srb->cmd_len] = 0; | 69 | srb->cmnd[srb->cmd_len] = 0; |
71 | 70 | ||
72 | /* send the command to the transport layer */ | 71 | /* send the command to the transport layer */ |
@@ -76,14 +75,14 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) | |||
76 | void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us) | 75 | void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us) |
77 | { | 76 | { |
78 | /* fix some commands -- this is a form of mode translation | 77 | /* fix some commands -- this is a form of mode translation |
79 | * UFI devices only accept 12 byte long commands | 78 | * UFI devices only accept 12 byte long commands |
80 | * | 79 | * |
81 | * NOTE: This only works because a scsi_cmnd struct field contains | 80 | * NOTE: This only works because a scsi_cmnd struct field contains |
82 | * a unsigned char cmnd[16], so we know we have storage available | 81 | * a unsigned char cmnd[16], so we know we have storage available |
83 | */ | 82 | */ |
84 | 83 | ||
85 | /* Pad the ATAPI command with zeros */ | 84 | /* Pad the ATAPI command with zeros */ |
86 | for (; srb->cmd_len < 12; srb->cmd_len++) | 85 | for (; srb->cmd_len<12; srb->cmd_len++) |
87 | srb->cmnd[srb->cmd_len] = 0; | 86 | srb->cmnd[srb->cmd_len] = 0; |
88 | 87 | ||
89 | /* set command length to 12 bytes (this affects the transport layer) */ | 88 | /* set command length to 12 bytes (this affects the transport layer) */ |
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 6c3586a4c95..232167ad478 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/kthread.h> | 25 | #include <linux/kthread.h> |
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/version.h> | ||
28 | 29 | ||
29 | #include <scsi/scsi.h> | 30 | #include <scsi/scsi.h> |
30 | #include <scsi/scsi_cmnd.h> | 31 | #include <scsi/scsi_cmnd.h> |
@@ -172,7 +173,7 @@ static int init_realtek_cr(struct us_data *us); | |||
172 | initFunction, flags) \ | 173 | initFunction, flags) \ |
173 | {\ | 174 | {\ |
174 | USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 175 | USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
175 | .driver_info = (flags) \ | 176 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24)\ |
176 | } | 177 | } |
177 | 178 | ||
178 | static const struct usb_device_id realtek_cr_ids[] = { | 179 | static const struct usb_device_id realtek_cr_ids[] = { |
@@ -219,7 +220,7 @@ static int rts51x_bulk_transport(struct us_data *us, u8 lun, | |||
219 | /* set up the command wrapper */ | 220 | /* set up the command wrapper */ |
220 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 221 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
221 | bcb->DataTransferLength = cpu_to_le32(buf_len); | 222 | bcb->DataTransferLength = cpu_to_le32(buf_len); |
222 | bcb->Flags = (dir == DMA_FROM_DEVICE) ? US_BULK_FLAG_IN : 0; | 223 | bcb->Flags = (dir == DMA_FROM_DEVICE) ? 1 << 7 : 0; |
223 | bcb->Tag = ++us->tag; | 224 | bcb->Tag = ++us->tag; |
224 | bcb->Lun = lun; | 225 | bcb->Lun = lun; |
225 | bcb->Length = cmd_len; | 226 | bcb->Length = cmd_len; |
@@ -292,52 +293,6 @@ static int rts51x_bulk_transport(struct us_data *us, u8 lun, | |||
292 | return USB_STOR_TRANSPORT_ERROR; | 293 | return USB_STOR_TRANSPORT_ERROR; |
293 | } | 294 | } |
294 | 295 | ||
295 | static int rts51x_bulk_transport_special(struct us_data *us, u8 lun, | ||
296 | u8 *cmd, int cmd_len, u8 *buf, int buf_len, | ||
297 | enum dma_data_direction dir, int *act_len) | ||
298 | { | ||
299 | struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; | ||
300 | struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; | ||
301 | int result; | ||
302 | unsigned int cswlen; | ||
303 | unsigned int cbwlen = US_BULK_CB_WRAP_LEN; | ||
304 | |||
305 | /* set up the command wrapper */ | ||
306 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | ||
307 | bcb->DataTransferLength = cpu_to_le32(buf_len); | ||
308 | bcb->Flags = (dir == DMA_FROM_DEVICE) ? US_BULK_FLAG_IN : 0; | ||
309 | bcb->Tag = ++us->tag; | ||
310 | bcb->Lun = lun; | ||
311 | bcb->Length = cmd_len; | ||
312 | |||
313 | /* copy the command payload */ | ||
314 | memset(bcb->CDB, 0, sizeof(bcb->CDB)); | ||
315 | memcpy(bcb->CDB, cmd, bcb->Length); | ||
316 | |||
317 | /* send it to out endpoint */ | ||
318 | result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
319 | bcb, cbwlen, NULL); | ||
320 | if (result != USB_STOR_XFER_GOOD) | ||
321 | return USB_STOR_TRANSPORT_ERROR; | ||
322 | |||
323 | /* DATA STAGE */ | ||
324 | /* send/receive data payload, if there is any */ | ||
325 | |||
326 | if (buf && buf_len) { | ||
327 | unsigned int pipe = (dir == DMA_FROM_DEVICE) ? | ||
328 | us->recv_bulk_pipe : us->send_bulk_pipe; | ||
329 | result = usb_stor_bulk_transfer_buf(us, pipe, | ||
330 | buf, buf_len, NULL); | ||
331 | if (result == USB_STOR_XFER_ERROR) | ||
332 | return USB_STOR_TRANSPORT_ERROR; | ||
333 | } | ||
334 | |||
335 | /* get CSW for device status */ | ||
336 | result = usb_bulk_msg(us->pusb_dev, us->recv_bulk_pipe, bcs, | ||
337 | US_BULK_CS_WRAP_LEN, &cswlen, 250); | ||
338 | return result; | ||
339 | } | ||
340 | |||
341 | /* Determine what the maximum LUN supported is */ | 296 | /* Determine what the maximum LUN supported is */ |
342 | static int rts51x_get_max_lun(struct us_data *us) | 297 | static int rts51x_get_max_lun(struct us_data *us) |
343 | { | 298 | { |
@@ -398,9 +353,10 @@ static int rts51x_write_mem(struct us_data *us, u16 addr, u8 *data, u16 len) | |||
398 | u8 cmnd[12] = { 0 }; | 353 | u8 cmnd[12] = { 0 }; |
399 | u8 *buf; | 354 | u8 *buf; |
400 | 355 | ||
401 | buf = kmemdup(data, len, GFP_NOIO); | 356 | buf = kmalloc(len, GFP_NOIO); |
402 | if (buf == NULL) | 357 | if (buf == NULL) |
403 | return USB_STOR_TRANSPORT_ERROR; | 358 | return USB_STOR_TRANSPORT_ERROR; |
359 | memcpy(buf, data, len); | ||
404 | 360 | ||
405 | US_DEBUGP("%s, addr = 0x%x, len = %d\n", __func__, addr, len); | 361 | US_DEBUGP("%s, addr = 0x%x, len = %d\n", __func__, addr, len); |
406 | 362 | ||
@@ -455,7 +411,7 @@ static int rts51x_check_status(struct us_data *us, u8 lun) | |||
455 | u8 buf[16]; | 411 | u8 buf[16]; |
456 | 412 | ||
457 | retval = rts51x_read_status(us, lun, buf, 16, &(chip->status_len)); | 413 | retval = rts51x_read_status(us, lun, buf, 16, &(chip->status_len)); |
458 | if (retval != STATUS_SUCCESS) | 414 | if (retval < 0) |
459 | return -EIO; | 415 | return -EIO; |
460 | 416 | ||
461 | US_DEBUGP("chip->status_len = %d\n", chip->status_len); | 417 | US_DEBUGP("chip->status_len = %d\n", chip->status_len); |
@@ -503,34 +459,6 @@ static int enable_oscillator(struct us_data *us) | |||
503 | return 0; | 459 | return 0; |
504 | } | 460 | } |
505 | 461 | ||
506 | static int __do_config_autodelink(struct us_data *us, u8 *data, u16 len) | ||
507 | { | ||
508 | int retval; | ||
509 | u8 cmnd[12] = {0}; | ||
510 | u8 *buf; | ||
511 | |||
512 | US_DEBUGP("%s, addr = 0xfe47, len = %d\n", __FUNCTION__, len); | ||
513 | |||
514 | buf = kmemdup(data, len, GFP_NOIO); | ||
515 | if (!buf) | ||
516 | return USB_STOR_TRANSPORT_ERROR; | ||
517 | |||
518 | cmnd[0] = 0xF0; | ||
519 | cmnd[1] = 0x0E; | ||
520 | cmnd[2] = 0xfe; | ||
521 | cmnd[3] = 0x47; | ||
522 | cmnd[4] = (u8)(len >> 8); | ||
523 | cmnd[5] = (u8)len; | ||
524 | |||
525 | retval = rts51x_bulk_transport_special(us, 0, cmnd, 12, buf, len, DMA_TO_DEVICE, NULL); | ||
526 | kfree(buf); | ||
527 | if (retval != USB_STOR_TRANSPORT_GOOD) { | ||
528 | return -EIO; | ||
529 | } | ||
530 | |||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | static int do_config_autodelink(struct us_data *us, int enable, int force) | 462 | static int do_config_autodelink(struct us_data *us, int enable, int force) |
535 | { | 463 | { |
536 | int retval; | 464 | int retval; |
@@ -551,8 +479,7 @@ static int do_config_autodelink(struct us_data *us, int enable, int force) | |||
551 | 479 | ||
552 | US_DEBUGP("In %s,set 0xfe47 to 0x%x\n", __func__, value); | 480 | US_DEBUGP("In %s,set 0xfe47 to 0x%x\n", __func__, value); |
553 | 481 | ||
554 | /* retval = rts51x_write_mem(us, 0xFE47, &value, 1); */ | 482 | retval = rts51x_write_mem(us, 0xFE47, &value, 1); |
555 | retval = __do_config_autodelink(us, &value, 1); | ||
556 | if (retval < 0) | 483 | if (retval < 0) |
557 | return -EIO; | 484 | return -EIO; |
558 | 485 | ||
@@ -584,8 +511,7 @@ static int config_autodelink_after_power_on(struct us_data *us) | |||
584 | 511 | ||
585 | SET_BIT(value, 7); | 512 | SET_BIT(value, 7); |
586 | 513 | ||
587 | /* retval = rts51x_write_mem(us, 0xFE47, &value, 1); */ | 514 | retval = rts51x_write_mem(us, 0xFE47, &value, 1); |
588 | retval = __do_config_autodelink(us, &value, 1); | ||
589 | if (retval < 0) | 515 | if (retval < 0) |
590 | return -EIO; | 516 | return -EIO; |
591 | 517 | ||
@@ -606,8 +532,7 @@ static int config_autodelink_after_power_on(struct us_data *us) | |||
606 | CLR_BIT(value, 7); | 532 | CLR_BIT(value, 7); |
607 | } | 533 | } |
608 | 534 | ||
609 | /* retval = rts51x_write_mem(us, 0xFE47, &value, 1); */ | 535 | retval = rts51x_write_mem(us, 0xFE47, &value, 1); |
610 | retval = __do_config_autodelink(us, &value, 1); | ||
611 | if (retval < 0) | 536 | if (retval < 0) |
612 | return -EIO; | 537 | return -EIO; |
613 | 538 | ||
@@ -684,8 +609,7 @@ static int config_autodelink_before_power_down(struct us_data *us) | |||
684 | if (CHECK_ID(chip, 0x0138, 0x3882)) | 609 | if (CHECK_ID(chip, 0x0138, 0x3882)) |
685 | SET_BIT(value, 2); | 610 | SET_BIT(value, 2); |
686 | 611 | ||
687 | /* retval = rts51x_write_mem(us, 0xFE47, &value, 1); */ | 612 | retval = rts51x_write_mem(us, 0xFE47, &value, 1); |
688 | retval = __do_config_autodelink(us, &value, 1); | ||
689 | if (retval < 0) | 613 | if (retval < 0) |
690 | return -EIO; | 614 | return -EIO; |
691 | } | 615 | } |
@@ -795,7 +719,7 @@ static void rts51x_suspend_timer_fn(unsigned long data) | |||
795 | rts51x_set_stat(chip, RTS51X_STAT_SS); | 719 | rts51x_set_stat(chip, RTS51X_STAT_SS); |
796 | /* ignore mass storage interface's children */ | 720 | /* ignore mass storage interface's children */ |
797 | pm_suspend_ignore_children(&us->pusb_intf->dev, true); | 721 | pm_suspend_ignore_children(&us->pusb_intf->dev, true); |
798 | usb_autopm_put_interface_async(us->pusb_intf); | 722 | usb_autopm_put_interface(us->pusb_intf); |
799 | US_DEBUGP("%s: RTS51X_STAT_SS 01," | 723 | US_DEBUGP("%s: RTS51X_STAT_SS 01," |
800 | "intf->pm_usage_cnt:%d, power.usage:%d\n", | 724 | "intf->pm_usage_cnt:%d, power.usage:%d\n", |
801 | __func__, | 725 | __func__, |
@@ -822,7 +746,7 @@ static inline int working_scsi(struct scsi_cmnd *srb) | |||
822 | return 1; | 746 | return 1; |
823 | } | 747 | } |
824 | 748 | ||
825 | static void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) | 749 | void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) |
826 | { | 750 | { |
827 | struct rts51x_chip *chip = (struct rts51x_chip *)(us->extra); | 751 | struct rts51x_chip *chip = (struct rts51x_chip *)(us->extra); |
828 | static int card_first_show = 1; | 752 | static int card_first_show = 1; |
@@ -883,7 +807,7 @@ static void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
883 | } else { | 807 | } else { |
884 | US_DEBUGP("%s: NOT working scsi, not SS\n", __func__); | 808 | US_DEBUGP("%s: NOT working scsi, not SS\n", __func__); |
885 | chip->proto_handler_backup(srb, us); | 809 | chip->proto_handler_backup(srb, us); |
886 | /* Check whether card is plugged in */ | 810 | /* Check wether card is plugged in */ |
887 | if (srb->cmnd[0] == TEST_UNIT_READY) { | 811 | if (srb->cmnd[0] == TEST_UNIT_READY) { |
888 | if (srb->result == SAM_STAT_GOOD) { | 812 | if (srb->result == SAM_STAT_GOOD) { |
889 | SET_LUN_READY(chip, srb->device->lun); | 813 | SET_LUN_READY(chip, srb->device->lun); |
@@ -981,7 +905,7 @@ static void realtek_cr_destructor(void *extra) | |||
981 | } | 905 | } |
982 | 906 | ||
983 | #ifdef CONFIG_PM | 907 | #ifdef CONFIG_PM |
984 | static int realtek_cr_suspend(struct usb_interface *iface, pm_message_t message) | 908 | int realtek_cr_suspend(struct usb_interface *iface, pm_message_t message) |
985 | { | 909 | { |
986 | struct us_data *us = usb_get_intfdata(iface); | 910 | struct us_data *us = usb_get_intfdata(iface); |
987 | 911 | ||
@@ -1106,7 +1030,17 @@ static struct usb_driver realtek_cr_driver = { | |||
1106 | .id_table = realtek_cr_ids, | 1030 | .id_table = realtek_cr_ids, |
1107 | .soft_unbind = 1, | 1031 | .soft_unbind = 1, |
1108 | .supports_autosuspend = 1, | 1032 | .supports_autosuspend = 1, |
1109 | .no_dynamic_id = 1, | ||
1110 | }; | 1033 | }; |
1111 | 1034 | ||
1112 | module_usb_driver(realtek_cr_driver); | 1035 | static int __init realtek_cr_init(void) |
1036 | { | ||
1037 | return usb_register(&realtek_cr_driver); | ||
1038 | } | ||
1039 | |||
1040 | static void __exit realtek_cr_exit(void) | ||
1041 | { | ||
1042 | usb_deregister(&realtek_cr_driver); | ||
1043 | } | ||
1044 | |||
1045 | module_init(realtek_cr_init); | ||
1046 | module_exit(realtek_cr_exit); | ||
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 92f35abee92..13b8bcdf3db 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -78,6 +78,8 @@ static const char* host_info(struct Scsi_Host *host) | |||
78 | 78 | ||
79 | static int slave_alloc (struct scsi_device *sdev) | 79 | static int slave_alloc (struct scsi_device *sdev) |
80 | { | 80 | { |
81 | struct us_data *us = host_to_us(sdev->host); | ||
82 | |||
81 | /* | 83 | /* |
82 | * Set the INQUIRY transfer length to 36. We don't use any of | 84 | * Set the INQUIRY transfer length to 36. We don't use any of |
83 | * the extra data and many devices choke if asked for more or | 85 | * the extra data and many devices choke if asked for more or |
@@ -102,6 +104,18 @@ static int slave_alloc (struct scsi_device *sdev) | |||
102 | */ | 104 | */ |
103 | blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); | 105 | blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); |
104 | 106 | ||
107 | /* | ||
108 | * The UFI spec treates the Peripheral Qualifier bits in an | ||
109 | * INQUIRY result as reserved and requires devices to set them | ||
110 | * to 0. However the SCSI spec requires these bits to be set | ||
111 | * to 3 to indicate when a LUN is not present. | ||
112 | * | ||
113 | * Let the scanning code know if this target merely sets | ||
114 | * Peripheral Device Type to 0x1f to indicate no LUN. | ||
115 | */ | ||
116 | if (us->subclass == USB_SC_UFI) | ||
117 | sdev->sdev_target->pdt_1f_for_no_lun = 1; | ||
118 | |||
105 | return 0; | 119 | return 0; |
106 | } | 120 | } |
107 | 121 | ||
@@ -183,15 +197,6 @@ static int slave_configure(struct scsi_device *sdev) | |||
183 | * page x08, so we will skip it. */ | 197 | * page x08, so we will skip it. */ |
184 | sdev->skip_ms_page_8 = 1; | 198 | sdev->skip_ms_page_8 = 1; |
185 | 199 | ||
186 | /* Some devices don't handle VPD pages correctly */ | ||
187 | sdev->skip_vpd_pages = 1; | ||
188 | |||
189 | /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */ | ||
190 | sdev->no_report_opcodes = 1; | ||
191 | |||
192 | /* Do not attempt to use WRITE SAME */ | ||
193 | sdev->no_write_same = 1; | ||
194 | |||
195 | /* Some disks return the total number of blocks in response | 200 | /* Some disks return the total number of blocks in response |
196 | * to READ CAPACITY rather than the highest block number. | 201 | * to READ CAPACITY rather than the highest block number. |
197 | * If this device makes that mistake, tell the sd driver. */ | 202 | * If this device makes that mistake, tell the sd driver. */ |
@@ -208,16 +213,20 @@ static int slave_configure(struct scsi_device *sdev) | |||
208 | if (us->fflags & US_FL_NO_READ_CAPACITY_16) | 213 | if (us->fflags & US_FL_NO_READ_CAPACITY_16) |
209 | sdev->no_read_capacity_16 = 1; | 214 | sdev->no_read_capacity_16 = 1; |
210 | 215 | ||
211 | /* | ||
212 | * Many devices do not respond properly to READ_CAPACITY_16. | ||
213 | * Tell the SCSI layer to try READ_CAPACITY_10 first. | ||
214 | */ | ||
215 | sdev->try_rc_10_first = 1; | ||
216 | |||
217 | /* assume SPC3 or latter devices support sense size > 18 */ | 216 | /* assume SPC3 or latter devices support sense size > 18 */ |
218 | if (sdev->scsi_level > SCSI_SPC_2) | 217 | if (sdev->scsi_level > SCSI_SPC_2) |
219 | us->fflags |= US_FL_SANE_SENSE; | 218 | us->fflags |= US_FL_SANE_SENSE; |
220 | 219 | ||
220 | /* Some devices report a SCSI revision level above 2 but are | ||
221 | * unable to handle the REPORT LUNS command (for which | ||
222 | * support is mandatory at level 3). Since we already have | ||
223 | * a Get-Max-LUN request, we won't lose much by setting the | ||
224 | * revision level down to 2. The only devices that would be | ||
225 | * affected are those with sparse LUNs. */ | ||
226 | if (sdev->scsi_level > SCSI_2) | ||
227 | sdev->sdev_target->scsi_level = | ||
228 | sdev->scsi_level = SCSI_2; | ||
229 | |||
221 | /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable | 230 | /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable |
222 | * Hardware Error) when any low-level error occurs, | 231 | * Hardware Error) when any low-level error occurs, |
223 | * recoverable or not. Setting this flag tells the SCSI | 232 | * recoverable or not. Setting this flag tells the SCSI |
@@ -242,11 +251,6 @@ static int slave_configure(struct scsi_device *sdev) | |||
242 | US_FL_SCM_MULT_TARG)) && | 251 | US_FL_SCM_MULT_TARG)) && |
243 | us->protocol == USB_PR_BULK) | 252 | us->protocol == USB_PR_BULK) |
244 | us->use_last_sector_hacks = 1; | 253 | us->use_last_sector_hacks = 1; |
245 | |||
246 | /* Check if write cache default on flag is set or not */ | ||
247 | if (us->fflags & US_FL_WRITE_CACHE) | ||
248 | sdev->wce_default_on = 1; | ||
249 | |||
250 | } else { | 254 | } else { |
251 | 255 | ||
252 | /* Non-disk-type devices don't need to blacklist any pages | 256 | /* Non-disk-type devices don't need to blacklist any pages |
@@ -279,33 +283,6 @@ static int slave_configure(struct scsi_device *sdev) | |||
279 | return 0; | 283 | return 0; |
280 | } | 284 | } |
281 | 285 | ||
282 | static int target_alloc(struct scsi_target *starget) | ||
283 | { | ||
284 | struct us_data *us = host_to_us(dev_to_shost(starget->dev.parent)); | ||
285 | |||
286 | /* | ||
287 | * Some USB drives don't support REPORT LUNS, even though they | ||
288 | * report a SCSI revision level above 2. Tell the SCSI layer | ||
289 | * not to issue that command; it will perform a normal sequential | ||
290 | * scan instead. | ||
291 | */ | ||
292 | starget->no_report_luns = 1; | ||
293 | |||
294 | /* | ||
295 | * The UFI spec treats the Peripheral Qualifier bits in an | ||
296 | * INQUIRY result as reserved and requires devices to set them | ||
297 | * to 0. However the SCSI spec requires these bits to be set | ||
298 | * to 3 to indicate when a LUN is not present. | ||
299 | * | ||
300 | * Let the scanning code know if this target merely sets | ||
301 | * Peripheral Device Type to 0x1f to indicate no LUN. | ||
302 | */ | ||
303 | if (us->subclass == USB_SC_UFI) | ||
304 | starget->pdt_1f_for_no_lun = 1; | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | /* queue a command */ | 286 | /* queue a command */ |
310 | /* This is always called with scsi_lock(host) held */ | 287 | /* This is always called with scsi_lock(host) held */ |
311 | static int queuecommand_lck(struct scsi_cmnd *srb, | 288 | static int queuecommand_lck(struct scsi_cmnd *srb, |
@@ -569,7 +546,6 @@ struct scsi_host_template usb_stor_host_template = { | |||
569 | 546 | ||
570 | .slave_alloc = slave_alloc, | 547 | .slave_alloc = slave_alloc, |
571 | .slave_configure = slave_configure, | 548 | .slave_configure = slave_configure, |
572 | .target_alloc = target_alloc, | ||
573 | 549 | ||
574 | /* lots of sg segments can be handled */ | 550 | /* lots of sg segments can be handled */ |
575 | .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, | 551 | .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, |
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 7bd54e0d512..bcb9a709d34 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
@@ -69,9 +69,9 @@ static int usb_stor_sddr09_init(struct us_data *us); | |||
69 | vendorName, productName, useProtocol, useTransport, \ | 69 | vendorName, productName, useProtocol, useTransport, \ |
70 | initFunction, flags) \ | 70 | initFunction, flags) \ |
71 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 71 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
72 | .driver_info = (flags) } | 72 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
73 | 73 | ||
74 | static struct usb_device_id sddr09_usb_ids[] = { | 74 | struct usb_device_id sddr09_usb_ids[] = { |
75 | # include "unusual_sddr09.h" | 75 | # include "unusual_sddr09.h" |
76 | { } /* Terminating entry */ | 76 | { } /* Terminating entry */ |
77 | }; | 77 | }; |
@@ -1787,7 +1787,17 @@ static struct usb_driver sddr09_driver = { | |||
1787 | .post_reset = usb_stor_post_reset, | 1787 | .post_reset = usb_stor_post_reset, |
1788 | .id_table = sddr09_usb_ids, | 1788 | .id_table = sddr09_usb_ids, |
1789 | .soft_unbind = 1, | 1789 | .soft_unbind = 1, |
1790 | .no_dynamic_id = 1, | ||
1791 | }; | 1790 | }; |
1792 | 1791 | ||
1793 | module_usb_driver(sddr09_driver); | 1792 | static int __init sddr09_init(void) |
1793 | { | ||
1794 | return usb_register(&sddr09_driver); | ||
1795 | } | ||
1796 | |||
1797 | static void __exit sddr09_exit(void) | ||
1798 | { | ||
1799 | usb_deregister(&sddr09_driver); | ||
1800 | } | ||
1801 | |||
1802 | module_init(sddr09_init); | ||
1803 | module_exit(sddr09_exit); | ||
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index d278c5a99b7..44dfed7754e 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c | |||
@@ -46,9 +46,9 @@ MODULE_LICENSE("GPL"); | |||
46 | vendorName, productName, useProtocol, useTransport, \ | 46 | vendorName, productName, useProtocol, useTransport, \ |
47 | initFunction, flags) \ | 47 | initFunction, flags) \ |
48 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 48 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
49 | .driver_info = (flags) } | 49 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
50 | 50 | ||
51 | static struct usb_device_id sddr55_usb_ids[] = { | 51 | struct usb_device_id sddr55_usb_ids[] = { |
52 | # include "unusual_sddr55.h" | 52 | # include "unusual_sddr55.h" |
53 | { } /* Terminating entry */ | 53 | { } /* Terminating entry */ |
54 | }; | 54 | }; |
@@ -1006,7 +1006,17 @@ static struct usb_driver sddr55_driver = { | |||
1006 | .post_reset = usb_stor_post_reset, | 1006 | .post_reset = usb_stor_post_reset, |
1007 | .id_table = sddr55_usb_ids, | 1007 | .id_table = sddr55_usb_ids, |
1008 | .soft_unbind = 1, | 1008 | .soft_unbind = 1, |
1009 | .no_dynamic_id = 1, | ||
1010 | }; | 1009 | }; |
1011 | 1010 | ||
1012 | module_usb_driver(sddr55_driver); | 1011 | static int __init sddr55_init(void) |
1012 | { | ||
1013 | return usb_register(&sddr55_driver); | ||
1014 | } | ||
1015 | |||
1016 | static void __exit sddr55_exit(void) | ||
1017 | { | ||
1018 | usb_deregister(&sddr55_driver); | ||
1019 | } | ||
1020 | |||
1021 | module_init(sddr55_init); | ||
1022 | module_exit(sddr55_exit); | ||
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index daf2fc58ae0..0b00091d2ae 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -168,9 +168,9 @@ static int init_usbat_flash(struct us_data *us); | |||
168 | vendorName, productName, useProtocol, useTransport, \ | 168 | vendorName, productName, useProtocol, useTransport, \ |
169 | initFunction, flags) \ | 169 | initFunction, flags) \ |
170 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 170 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
171 | .driver_info = (flags) } | 171 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
172 | 172 | ||
173 | static struct usb_device_id usbat_usb_ids[] = { | 173 | struct usb_device_id usbat_usb_ids[] = { |
174 | # include "unusual_usbat.h" | 174 | # include "unusual_usbat.h" |
175 | { } /* Terminating entry */ | 175 | { } /* Terminating entry */ |
176 | }; | 176 | }; |
@@ -1863,7 +1863,17 @@ static struct usb_driver usbat_driver = { | |||
1863 | .post_reset = usb_stor_post_reset, | 1863 | .post_reset = usb_stor_post_reset, |
1864 | .id_table = usbat_usb_ids, | 1864 | .id_table = usbat_usb_ids, |
1865 | .soft_unbind = 1, | 1865 | .soft_unbind = 1, |
1866 | .no_dynamic_id = 1, | ||
1867 | }; | 1866 | }; |
1868 | 1867 | ||
1869 | module_usb_driver(usbat_driver); | 1868 | static int __init usbat_init(void) |
1869 | { | ||
1870 | return usb_register(&usbat_driver); | ||
1871 | } | ||
1872 | |||
1873 | static void __exit usbat_exit(void) | ||
1874 | { | ||
1875 | usb_deregister(&usbat_driver); | ||
1876 | } | ||
1877 | |||
1878 | module_init(usbat_init); | ||
1879 | module_exit(usbat_exit); | ||
diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c index 17e36952bce..1deca07c826 100644 --- a/drivers/usb/storage/sierra_ms.c +++ b/drivers/usb/storage/sierra_ms.c | |||
@@ -3,7 +3,6 @@ | |||
3 | #include <scsi/scsi_cmnd.h> | 3 | #include <scsi/scsi_cmnd.h> |
4 | #include <scsi/scsi_device.h> | 4 | #include <scsi/scsi_device.h> |
5 | #include <linux/usb.h> | 5 | #include <linux/usb.h> |
6 | #include <linux/module.h> | ||
7 | #include <linux/slab.h> | 6 | #include <linux/slab.h> |
8 | 7 | ||
9 | #include "usb.h" | 8 | #include "usb.h" |
@@ -130,13 +129,14 @@ int sierra_ms_init(struct us_data *us) | |||
130 | struct swoc_info *swocInfo; | 129 | struct swoc_info *swocInfo; |
131 | struct usb_device *udev; | 130 | struct usb_device *udev; |
132 | struct Scsi_Host *sh; | 131 | struct Scsi_Host *sh; |
132 | struct scsi_device *sd; | ||
133 | 133 | ||
134 | retries = 3; | 134 | retries = 3; |
135 | result = 0; | 135 | result = 0; |
136 | udev = us->pusb_dev; | 136 | udev = us->pusb_dev; |
137 | 137 | ||
138 | sh = us_to_host(us); | 138 | sh = us_to_host(us); |
139 | scsi_get_host_dev(sh); | 139 | sd = scsi_get_host_dev(sh); |
140 | 140 | ||
141 | US_DEBUGP("SWIMS: sierra_ms_init called\n"); | 141 | US_DEBUGP("SWIMS: sierra_ms_init called\n"); |
142 | 142 | ||
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index c0543c83923..ff32390d61e 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/sched.h> | 46 | #include <linux/sched.h> |
47 | #include <linux/gfp.h> | 47 | #include <linux/gfp.h> |
48 | #include <linux/errno.h> | 48 | #include <linux/errno.h> |
49 | #include <linux/export.h> | ||
50 | 49 | ||
51 | #include <linux/usb/quirks.h> | 50 | #include <linux/usb/quirks.h> |
52 | 51 | ||
@@ -1071,8 +1070,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1071 | /* set up the command wrapper */ | 1070 | /* set up the command wrapper */ |
1072 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | 1071 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
1073 | bcb->DataTransferLength = cpu_to_le32(transfer_length); | 1072 | bcb->DataTransferLength = cpu_to_le32(transfer_length); |
1074 | bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? | 1073 | bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0; |
1075 | US_BULK_FLAG_IN : 0; | ||
1076 | bcb->Tag = ++us->tag; | 1074 | bcb->Tag = ++us->tag; |
1077 | bcb->Lun = srb->device->lun; | 1075 | bcb->Lun = srb->device->lun; |
1078 | if (us->fflags & US_FL_SCM_MULT_TARG) | 1076 | if (us->fflags & US_FL_SCM_MULT_TARG) |
@@ -1331,7 +1329,7 @@ int usb_stor_port_reset(struct us_data *us) | |||
1331 | int result; | 1329 | int result; |
1332 | 1330 | ||
1333 | /*for these devices we must use the class specific method */ | 1331 | /*for these devices we must use the class specific method */ |
1334 | if (us->pusb_dev->quirks & USB_QUIRK_RESET) | 1332 | if (us->pusb_dev->quirks & USB_QUIRK_RESET_MORPHS) |
1335 | return -EPERM; | 1333 | return -EPERM; |
1336 | 1334 | ||
1337 | result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf); | 1335 | result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf); |
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 9369d752d41..242ff5e791a 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h | |||
@@ -42,6 +42,45 @@ | |||
42 | #include <linux/blkdev.h> | 42 | #include <linux/blkdev.h> |
43 | 43 | ||
44 | /* | 44 | /* |
45 | * Bulk only data structures | ||
46 | */ | ||
47 | |||
48 | /* command block wrapper */ | ||
49 | struct bulk_cb_wrap { | ||
50 | __le32 Signature; /* contains 'USBC' */ | ||
51 | __u32 Tag; /* unique per command id */ | ||
52 | __le32 DataTransferLength; /* size of data */ | ||
53 | __u8 Flags; /* direction in bit 0 */ | ||
54 | __u8 Lun; /* LUN normally 0 */ | ||
55 | __u8 Length; /* of of the CDB */ | ||
56 | __u8 CDB[16]; /* max command */ | ||
57 | }; | ||
58 | |||
59 | #define US_BULK_CB_WRAP_LEN 31 | ||
60 | #define US_BULK_CB_SIGN 0x43425355 /*spells out USBC */ | ||
61 | #define US_BULK_FLAG_IN 1 | ||
62 | #define US_BULK_FLAG_OUT 0 | ||
63 | |||
64 | /* command status wrapper */ | ||
65 | struct bulk_cs_wrap { | ||
66 | __le32 Signature; /* should = 'USBS' */ | ||
67 | __u32 Tag; /* same as original command */ | ||
68 | __le32 Residue; /* amount not transferred */ | ||
69 | __u8 Status; /* see below */ | ||
70 | __u8 Filler[18]; | ||
71 | }; | ||
72 | |||
73 | #define US_BULK_CS_WRAP_LEN 13 | ||
74 | #define US_BULK_CS_SIGN 0x53425355 /* spells out 'USBS' */ | ||
75 | #define US_BULK_STAT_OK 0 | ||
76 | #define US_BULK_STAT_FAIL 1 | ||
77 | #define US_BULK_STAT_PHASE 2 | ||
78 | |||
79 | /* bulk-only class specific requests */ | ||
80 | #define US_BULK_RESET_REQUEST 0xff | ||
81 | #define US_BULK_GET_MAX_LUN 0xfe | ||
82 | |||
83 | /* | ||
45 | * usb_stor_bulk_transfer_xxx() return codes, in order of severity | 84 | * usb_stor_bulk_transfer_xxx() return codes, in order of severity |
46 | */ | 85 | */ |
47 | 86 | ||
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 98b98eef752..23f0dd9c36d 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
@@ -11,11 +11,8 @@ | |||
11 | #include <linux/blkdev.h> | 11 | #include <linux/blkdev.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/module.h> | ||
15 | #include <linux/usb.h> | 14 | #include <linux/usb.h> |
16 | #include <linux/usb/hcd.h> | ||
17 | #include <linux/usb/storage.h> | 15 | #include <linux/usb/storage.h> |
18 | #include <linux/usb/uas.h> | ||
19 | 16 | ||
20 | #include <scsi/scsi.h> | 17 | #include <scsi/scsi.h> |
21 | #include <scsi/scsi_dbg.h> | 18 | #include <scsi/scsi_dbg.h> |
@@ -24,6 +21,49 @@ | |||
24 | #include <scsi/scsi_host.h> | 21 | #include <scsi/scsi_host.h> |
25 | #include <scsi/scsi_tcq.h> | 22 | #include <scsi/scsi_tcq.h> |
26 | 23 | ||
24 | /* Common header for all IUs */ | ||
25 | struct iu { | ||
26 | __u8 iu_id; | ||
27 | __u8 rsvd1; | ||
28 | __be16 tag; | ||
29 | }; | ||
30 | |||
31 | enum { | ||
32 | IU_ID_COMMAND = 0x01, | ||
33 | IU_ID_STATUS = 0x03, | ||
34 | IU_ID_RESPONSE = 0x04, | ||
35 | IU_ID_TASK_MGMT = 0x05, | ||
36 | IU_ID_READ_READY = 0x06, | ||
37 | IU_ID_WRITE_READY = 0x07, | ||
38 | }; | ||
39 | |||
40 | struct command_iu { | ||
41 | __u8 iu_id; | ||
42 | __u8 rsvd1; | ||
43 | __be16 tag; | ||
44 | __u8 prio_attr; | ||
45 | __u8 rsvd5; | ||
46 | __u8 len; | ||
47 | __u8 rsvd7; | ||
48 | struct scsi_lun lun; | ||
49 | __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ | ||
50 | }; | ||
51 | |||
52 | /* | ||
53 | * Also used for the Read Ready and Write Ready IUs since they have the | ||
54 | * same first four bytes | ||
55 | */ | ||
56 | struct sense_iu { | ||
57 | __u8 iu_id; | ||
58 | __u8 rsvd1; | ||
59 | __be16 tag; | ||
60 | __be16 status_qual; | ||
61 | __u8 status; | ||
62 | __u8 rsvd7[7]; | ||
63 | __be16 len; | ||
64 | __u8 sense[SCSI_SENSE_BUFFERSIZE]; | ||
65 | }; | ||
66 | |||
27 | /* | 67 | /* |
28 | * The r00-r01c specs define this version of the SENSE IU data structure. | 68 | * The r00-r01c specs define this version of the SENSE IU data structure. |
29 | * It's still in use by several different firmware releases. | 69 | * It's still in use by several different firmware releases. |
@@ -38,22 +78,29 @@ struct sense_iu_old { | |||
38 | __u8 sense[SCSI_SENSE_BUFFERSIZE]; | 78 | __u8 sense[SCSI_SENSE_BUFFERSIZE]; |
39 | }; | 79 | }; |
40 | 80 | ||
81 | enum { | ||
82 | CMD_PIPE_ID = 1, | ||
83 | STATUS_PIPE_ID = 2, | ||
84 | DATA_IN_PIPE_ID = 3, | ||
85 | DATA_OUT_PIPE_ID = 4, | ||
86 | |||
87 | UAS_SIMPLE_TAG = 0, | ||
88 | UAS_HEAD_TAG = 1, | ||
89 | UAS_ORDERED_TAG = 2, | ||
90 | UAS_ACA = 4, | ||
91 | }; | ||
92 | |||
41 | struct uas_dev_info { | 93 | struct uas_dev_info { |
42 | struct usb_interface *intf; | 94 | struct usb_interface *intf; |
43 | struct usb_device *udev; | 95 | struct usb_device *udev; |
44 | struct usb_anchor cmd_urbs; | 96 | int qdepth; |
45 | struct usb_anchor sense_urbs; | ||
46 | struct usb_anchor data_urbs; | ||
47 | int qdepth, resetting; | ||
48 | struct response_ui response; | ||
49 | unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; | 97 | unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; |
50 | unsigned use_streams:1; | 98 | unsigned use_streams:1; |
51 | unsigned uas_sense_old:1; | 99 | unsigned uas_sense_old:1; |
52 | struct scsi_cmnd *cmnd; | ||
53 | spinlock_t lock; | ||
54 | }; | 100 | }; |
55 | 101 | ||
56 | enum { | 102 | enum { |
103 | ALLOC_STATUS_URB = (1 << 0), | ||
57 | SUBMIT_STATUS_URB = (1 << 1), | 104 | SUBMIT_STATUS_URB = (1 << 1), |
58 | ALLOC_DATA_IN_URB = (1 << 2), | 105 | ALLOC_DATA_IN_URB = (1 << 2), |
59 | SUBMIT_DATA_IN_URB = (1 << 3), | 106 | SUBMIT_DATA_IN_URB = (1 << 3), |
@@ -61,11 +108,6 @@ enum { | |||
61 | SUBMIT_DATA_OUT_URB = (1 << 5), | 108 | SUBMIT_DATA_OUT_URB = (1 << 5), |
62 | ALLOC_CMD_URB = (1 << 6), | 109 | ALLOC_CMD_URB = (1 << 6), |
63 | SUBMIT_CMD_URB = (1 << 7), | 110 | SUBMIT_CMD_URB = (1 << 7), |
64 | COMMAND_INFLIGHT = (1 << 8), | ||
65 | DATA_IN_URB_INFLIGHT = (1 << 9), | ||
66 | DATA_OUT_URB_INFLIGHT = (1 << 10), | ||
67 | COMMAND_COMPLETED = (1 << 11), | ||
68 | COMMAND_ABORTED = (1 << 12), | ||
69 | }; | 111 | }; |
70 | 112 | ||
71 | /* Overrides scsi_pointer */ | 113 | /* Overrides scsi_pointer */ |
@@ -73,6 +115,7 @@ struct uas_cmd_info { | |||
73 | unsigned int state; | 115 | unsigned int state; |
74 | unsigned int stream; | 116 | unsigned int stream; |
75 | struct urb *cmd_urb; | 117 | struct urb *cmd_urb; |
118 | struct urb *status_urb; | ||
76 | struct urb *data_in_urb; | 119 | struct urb *data_in_urb; |
77 | struct urb *data_out_urb; | 120 | struct urb *data_out_urb; |
78 | struct list_head list; | 121 | struct list_head list; |
@@ -81,42 +124,29 @@ struct uas_cmd_info { | |||
81 | /* I hate forward declarations, but I actually have a loop */ | 124 | /* I hate forward declarations, but I actually have a loop */ |
82 | static int uas_submit_urbs(struct scsi_cmnd *cmnd, | 125 | static int uas_submit_urbs(struct scsi_cmnd *cmnd, |
83 | struct uas_dev_info *devinfo, gfp_t gfp); | 126 | struct uas_dev_info *devinfo, gfp_t gfp); |
84 | static void uas_do_work(struct work_struct *work); | ||
85 | 127 | ||
86 | static DECLARE_WORK(uas_work, uas_do_work); | ||
87 | static DEFINE_SPINLOCK(uas_work_lock); | 128 | static DEFINE_SPINLOCK(uas_work_lock); |
88 | static LIST_HEAD(uas_work_list); | 129 | static LIST_HEAD(uas_work_list); |
89 | 130 | ||
90 | static void uas_do_work(struct work_struct *work) | 131 | static void uas_do_work(struct work_struct *work) |
91 | { | 132 | { |
92 | struct uas_cmd_info *cmdinfo; | 133 | struct uas_cmd_info *cmdinfo; |
93 | struct uas_cmd_info *temp; | ||
94 | struct list_head list; | 134 | struct list_head list; |
95 | unsigned long flags; | ||
96 | int err; | ||
97 | 135 | ||
98 | spin_lock_irq(&uas_work_lock); | 136 | spin_lock_irq(&uas_work_lock); |
99 | list_replace_init(&uas_work_list, &list); | 137 | list_replace_init(&uas_work_list, &list); |
100 | spin_unlock_irq(&uas_work_lock); | 138 | spin_unlock_irq(&uas_work_lock); |
101 | 139 | ||
102 | list_for_each_entry_safe(cmdinfo, temp, &list, list) { | 140 | list_for_each_entry(cmdinfo, &list, list) { |
103 | struct scsi_pointer *scp = (void *)cmdinfo; | 141 | struct scsi_pointer *scp = (void *)cmdinfo; |
104 | struct scsi_cmnd *cmnd = container_of(scp, | 142 | struct scsi_cmnd *cmnd = container_of(scp, |
105 | struct scsi_cmnd, SCp); | 143 | struct scsi_cmnd, SCp); |
106 | struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; | 144 | uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO); |
107 | spin_lock_irqsave(&devinfo->lock, flags); | ||
108 | err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); | ||
109 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
110 | if (err) { | ||
111 | list_del(&cmdinfo->list); | ||
112 | spin_lock_irq(&uas_work_lock); | ||
113 | list_add_tail(&cmdinfo->list, &uas_work_list); | ||
114 | spin_unlock_irq(&uas_work_lock); | ||
115 | schedule_work(&uas_work); | ||
116 | } | ||
117 | } | 145 | } |
118 | } | 146 | } |
119 | 147 | ||
148 | static DECLARE_WORK(uas_work, uas_do_work); | ||
149 | |||
120 | static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) | 150 | static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) |
121 | { | 151 | { |
122 | struct sense_iu *sense_iu = urb->transfer_buffer; | 152 | struct sense_iu *sense_iu = urb->transfer_buffer; |
@@ -138,6 +168,10 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) | |||
138 | } | 168 | } |
139 | 169 | ||
140 | cmnd->result = sense_iu->status; | 170 | cmnd->result = sense_iu->status; |
171 | if (sdev->current_cmnd) | ||
172 | sdev->current_cmnd = NULL; | ||
173 | cmnd->scsi_done(cmnd); | ||
174 | usb_free_urb(urb); | ||
141 | } | 175 | } |
142 | 176 | ||
143 | static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) | 177 | static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) |
@@ -161,58 +195,19 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) | |||
161 | } | 195 | } |
162 | 196 | ||
163 | cmnd->result = sense_iu->status; | 197 | cmnd->result = sense_iu->status; |
164 | } | 198 | if (sdev->current_cmnd) |
165 | 199 | sdev->current_cmnd = NULL; | |
166 | static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller) | ||
167 | { | ||
168 | struct uas_cmd_info *ci = (void *)&cmnd->SCp; | ||
169 | |||
170 | scmd_printk(KERN_INFO, cmnd, "%s %p tag %d, inflight:" | ||
171 | "%s%s%s%s%s%s%s%s%s%s%s%s\n", | ||
172 | caller, cmnd, cmnd->request->tag, | ||
173 | (ci->state & SUBMIT_STATUS_URB) ? " s-st" : "", | ||
174 | (ci->state & ALLOC_DATA_IN_URB) ? " a-in" : "", | ||
175 | (ci->state & SUBMIT_DATA_IN_URB) ? " s-in" : "", | ||
176 | (ci->state & ALLOC_DATA_OUT_URB) ? " a-out" : "", | ||
177 | (ci->state & SUBMIT_DATA_OUT_URB) ? " s-out" : "", | ||
178 | (ci->state & ALLOC_CMD_URB) ? " a-cmd" : "", | ||
179 | (ci->state & SUBMIT_CMD_URB) ? " s-cmd" : "", | ||
180 | (ci->state & COMMAND_INFLIGHT) ? " CMD" : "", | ||
181 | (ci->state & DATA_IN_URB_INFLIGHT) ? " IN" : "", | ||
182 | (ci->state & DATA_OUT_URB_INFLIGHT) ? " OUT" : "", | ||
183 | (ci->state & COMMAND_COMPLETED) ? " done" : "", | ||
184 | (ci->state & COMMAND_ABORTED) ? " abort" : ""); | ||
185 | } | ||
186 | |||
187 | static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller) | ||
188 | { | ||
189 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; | ||
190 | struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; | ||
191 | |||
192 | WARN_ON(!spin_is_locked(&devinfo->lock)); | ||
193 | if (cmdinfo->state & (COMMAND_INFLIGHT | | ||
194 | DATA_IN_URB_INFLIGHT | | ||
195 | DATA_OUT_URB_INFLIGHT)) | ||
196 | return -EBUSY; | ||
197 | BUG_ON(cmdinfo->state & COMMAND_COMPLETED); | ||
198 | cmdinfo->state |= COMMAND_COMPLETED; | ||
199 | usb_free_urb(cmdinfo->data_in_urb); | ||
200 | usb_free_urb(cmdinfo->data_out_urb); | ||
201 | if (cmdinfo->state & COMMAND_ABORTED) { | ||
202 | scmd_printk(KERN_INFO, cmnd, "abort completed\n"); | ||
203 | cmnd->result = DID_ABORT << 16; | ||
204 | } | ||
205 | cmnd->scsi_done(cmnd); | 200 | cmnd->scsi_done(cmnd); |
206 | return 0; | 201 | usb_free_urb(urb); |
207 | } | 202 | } |
208 | 203 | ||
209 | static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, | 204 | static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, |
210 | unsigned direction) | 205 | unsigned direction) |
211 | { | 206 | { |
212 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; | 207 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; |
213 | int err; | 208 | int err; |
214 | 209 | ||
215 | cmdinfo->state |= direction | SUBMIT_STATUS_URB; | 210 | cmdinfo->state = direction | SUBMIT_STATUS_URB; |
216 | err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); | 211 | err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); |
217 | if (err) { | 212 | if (err) { |
218 | spin_lock(&uas_work_lock); | 213 | spin_lock(&uas_work_lock); |
@@ -225,11 +220,9 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, | |||
225 | static void uas_stat_cmplt(struct urb *urb) | 220 | static void uas_stat_cmplt(struct urb *urb) |
226 | { | 221 | { |
227 | struct iu *iu = urb->transfer_buffer; | 222 | struct iu *iu = urb->transfer_buffer; |
228 | struct Scsi_Host *shost = urb->context; | 223 | struct scsi_device *sdev = urb->context; |
229 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; | 224 | struct uas_dev_info *devinfo = sdev->hostdata; |
230 | struct scsi_cmnd *cmnd; | 225 | struct scsi_cmnd *cmnd; |
231 | struct uas_cmd_info *cmdinfo; | ||
232 | unsigned long flags; | ||
233 | u16 tag; | 226 | u16 tag; |
234 | 227 | ||
235 | if (urb->status) { | 228 | if (urb->status) { |
@@ -238,55 +231,22 @@ static void uas_stat_cmplt(struct urb *urb) | |||
238 | return; | 231 | return; |
239 | } | 232 | } |
240 | 233 | ||
241 | if (devinfo->resetting) { | ||
242 | usb_free_urb(urb); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | spin_lock_irqsave(&devinfo->lock, flags); | ||
247 | tag = be16_to_cpup(&iu->tag) - 1; | 234 | tag = be16_to_cpup(&iu->tag) - 1; |
248 | if (tag == 0) | 235 | if (sdev->current_cmnd) |
249 | cmnd = devinfo->cmnd; | 236 | cmnd = sdev->current_cmnd; |
250 | else | 237 | else |
251 | cmnd = scsi_host_find_tag(shost, tag - 1); | 238 | cmnd = scsi_find_tag(sdev, tag); |
252 | 239 | if (!cmnd) | |
253 | if (!cmnd) { | ||
254 | if (iu->iu_id == IU_ID_RESPONSE) { | ||
255 | /* store results for uas_eh_task_mgmt() */ | ||
256 | memcpy(&devinfo->response, iu, sizeof(devinfo->response)); | ||
257 | } | ||
258 | usb_free_urb(urb); | ||
259 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
260 | return; | 240 | return; |
261 | } | ||
262 | 241 | ||
263 | cmdinfo = (void *)&cmnd->SCp; | ||
264 | switch (iu->iu_id) { | 242 | switch (iu->iu_id) { |
265 | case IU_ID_STATUS: | 243 | case IU_ID_STATUS: |
266 | if (devinfo->cmnd == cmnd) | ||
267 | devinfo->cmnd = NULL; | ||
268 | |||
269 | if (urb->actual_length < 16) | 244 | if (urb->actual_length < 16) |
270 | devinfo->uas_sense_old = 1; | 245 | devinfo->uas_sense_old = 1; |
271 | if (devinfo->uas_sense_old) | 246 | if (devinfo->uas_sense_old) |
272 | uas_sense_old(urb, cmnd); | 247 | uas_sense_old(urb, cmnd); |
273 | else | 248 | else |
274 | uas_sense(urb, cmnd); | 249 | uas_sense(urb, cmnd); |
275 | if (cmnd->result != 0) { | ||
276 | /* cancel data transfers on error */ | ||
277 | if (cmdinfo->state & DATA_IN_URB_INFLIGHT) { | ||
278 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
279 | usb_unlink_urb(cmdinfo->data_in_urb); | ||
280 | spin_lock_irqsave(&devinfo->lock, flags); | ||
281 | } | ||
282 | if (cmdinfo->state & DATA_OUT_URB_INFLIGHT) { | ||
283 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
284 | usb_unlink_urb(cmdinfo->data_out_urb); | ||
285 | spin_lock_irqsave(&devinfo->lock, flags); | ||
286 | } | ||
287 | } | ||
288 | cmdinfo->state &= ~COMMAND_INFLIGHT; | ||
289 | uas_try_complete(cmnd, __func__); | ||
290 | break; | 250 | break; |
291 | case IU_ID_READ_READY: | 251 | case IU_ID_READ_READY: |
292 | uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB); | 252 | uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB); |
@@ -298,51 +258,27 @@ static void uas_stat_cmplt(struct urb *urb) | |||
298 | scmd_printk(KERN_ERR, cmnd, | 258 | scmd_printk(KERN_ERR, cmnd, |
299 | "Bogus IU (%d) received on status pipe\n", iu->iu_id); | 259 | "Bogus IU (%d) received on status pipe\n", iu->iu_id); |
300 | } | 260 | } |
301 | usb_free_urb(urb); | ||
302 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
303 | } | 261 | } |
304 | 262 | ||
305 | static void uas_data_cmplt(struct urb *urb) | 263 | static void uas_data_cmplt(struct urb *urb) |
306 | { | 264 | { |
307 | struct scsi_cmnd *cmnd = urb->context; | 265 | struct scsi_data_buffer *sdb = urb->context; |
308 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; | 266 | sdb->resid = sdb->length - urb->actual_length; |
309 | struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; | 267 | usb_free_urb(urb); |
310 | struct scsi_data_buffer *sdb = NULL; | ||
311 | unsigned long flags; | ||
312 | |||
313 | spin_lock_irqsave(&devinfo->lock, flags); | ||
314 | if (cmdinfo->data_in_urb == urb) { | ||
315 | sdb = scsi_in(cmnd); | ||
316 | cmdinfo->state &= ~DATA_IN_URB_INFLIGHT; | ||
317 | } else if (cmdinfo->data_out_urb == urb) { | ||
318 | sdb = scsi_out(cmnd); | ||
319 | cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT; | ||
320 | } | ||
321 | BUG_ON(sdb == NULL); | ||
322 | if (urb->status) { | ||
323 | /* error: no data transfered */ | ||
324 | sdb->resid = sdb->length; | ||
325 | } else { | ||
326 | sdb->resid = sdb->length - urb->actual_length; | ||
327 | } | ||
328 | uas_try_complete(cmnd, __func__); | ||
329 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
330 | } | 268 | } |
331 | 269 | ||
332 | static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, | 270 | static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, |
333 | unsigned int pipe, u16 stream_id, | 271 | unsigned int pipe, u16 stream_id, |
334 | struct scsi_cmnd *cmnd, | 272 | struct scsi_data_buffer *sdb, |
335 | enum dma_data_direction dir) | 273 | enum dma_data_direction dir) |
336 | { | 274 | { |
337 | struct usb_device *udev = devinfo->udev; | 275 | struct usb_device *udev = devinfo->udev; |
338 | struct urb *urb = usb_alloc_urb(0, gfp); | 276 | struct urb *urb = usb_alloc_urb(0, gfp); |
339 | struct scsi_data_buffer *sdb = (dir == DMA_FROM_DEVICE) | ||
340 | ? scsi_in(cmnd) : scsi_out(cmnd); | ||
341 | 277 | ||
342 | if (!urb) | 278 | if (!urb) |
343 | goto out; | 279 | goto out; |
344 | usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, | 280 | usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, uas_data_cmplt, |
345 | uas_data_cmplt, cmnd); | 281 | sdb); |
346 | if (devinfo->use_streams) | 282 | if (devinfo->use_streams) |
347 | urb->stream_id = stream_id; | 283 | urb->stream_id = stream_id; |
348 | urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0; | 284 | urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0; |
@@ -352,7 +288,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
352 | } | 288 | } |
353 | 289 | ||
354 | static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, | 290 | static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, |
355 | struct Scsi_Host *shost, u16 stream_id) | 291 | struct scsi_cmnd *cmnd, u16 stream_id) |
356 | { | 292 | { |
357 | struct usb_device *udev = devinfo->udev; | 293 | struct usb_device *udev = devinfo->udev; |
358 | struct urb *urb = usb_alloc_urb(0, gfp); | 294 | struct urb *urb = usb_alloc_urb(0, gfp); |
@@ -366,7 +302,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
366 | goto free; | 302 | goto free; |
367 | 303 | ||
368 | usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), | 304 | usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), |
369 | uas_stat_cmplt, shost); | 305 | uas_stat_cmplt, cmnd->device); |
370 | urb->stream_id = stream_id; | 306 | urb->stream_id = stream_id; |
371 | urb->transfer_flags |= URB_FREE_BUFFER; | 307 | urb->transfer_flags |= URB_FREE_BUFFER; |
372 | out: | 308 | out: |
@@ -397,10 +333,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
397 | goto free; | 333 | goto free; |
398 | 334 | ||
399 | iu->iu_id = IU_ID_COMMAND; | 335 | iu->iu_id = IU_ID_COMMAND; |
400 | if (blk_rq_tagged(cmnd->request)) | 336 | iu->tag = cpu_to_be16(stream_id); |
401 | iu->tag = cpu_to_be16(cmnd->request->tag + 2); | ||
402 | else | ||
403 | iu->tag = cpu_to_be16(1); | ||
404 | iu->prio_attr = UAS_SIMPLE_TAG; | 337 | iu->prio_attr = UAS_SIMPLE_TAG; |
405 | iu->len = len; | 338 | iu->len = len; |
406 | int_to_scsilun(sdev->lun, &iu->lun); | 339 | int_to_scsilun(sdev->lun, &iu->lun); |
@@ -416,89 +349,30 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
416 | return NULL; | 349 | return NULL; |
417 | } | 350 | } |
418 | 351 | ||
419 | static int uas_submit_task_urb(struct scsi_cmnd *cmnd, gfp_t gfp, | ||
420 | u8 function, u16 stream_id) | ||
421 | { | ||
422 | struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; | ||
423 | struct usb_device *udev = devinfo->udev; | ||
424 | struct urb *urb = usb_alloc_urb(0, gfp); | ||
425 | struct task_mgmt_iu *iu; | ||
426 | int err = -ENOMEM; | ||
427 | |||
428 | if (!urb) | ||
429 | goto err; | ||
430 | |||
431 | iu = kzalloc(sizeof(*iu), gfp); | ||
432 | if (!iu) | ||
433 | goto err; | ||
434 | |||
435 | iu->iu_id = IU_ID_TASK_MGMT; | ||
436 | iu->tag = cpu_to_be16(stream_id); | ||
437 | int_to_scsilun(cmnd->device->lun, &iu->lun); | ||
438 | |||
439 | iu->function = function; | ||
440 | switch (function) { | ||
441 | case TMF_ABORT_TASK: | ||
442 | if (blk_rq_tagged(cmnd->request)) | ||
443 | iu->task_tag = cpu_to_be16(cmnd->request->tag + 2); | ||
444 | else | ||
445 | iu->task_tag = cpu_to_be16(1); | ||
446 | break; | ||
447 | } | ||
448 | |||
449 | usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu), | ||
450 | usb_free_urb, NULL); | ||
451 | urb->transfer_flags |= URB_FREE_BUFFER; | ||
452 | |||
453 | err = usb_submit_urb(urb, gfp); | ||
454 | if (err) | ||
455 | goto err; | ||
456 | usb_anchor_urb(urb, &devinfo->cmd_urbs); | ||
457 | |||
458 | return 0; | ||
459 | |||
460 | err: | ||
461 | usb_free_urb(urb); | ||
462 | return err; | ||
463 | } | ||
464 | |||
465 | /* | 352 | /* |
466 | * Why should I request the Status IU before sending the Command IU? Spec | 353 | * Why should I request the Status IU before sending the Command IU? Spec |
467 | * says to, but also says the device may receive them in any order. Seems | 354 | * says to, but also says the device may receive them in any order. Seems |
468 | * daft to me. | 355 | * daft to me. |
469 | */ | 356 | */ |
470 | 357 | ||
471 | static int uas_submit_sense_urb(struct Scsi_Host *shost, | ||
472 | gfp_t gfp, unsigned int stream) | ||
473 | { | ||
474 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; | ||
475 | struct urb *urb; | ||
476 | |||
477 | urb = uas_alloc_sense_urb(devinfo, gfp, shost, stream); | ||
478 | if (!urb) | ||
479 | return SCSI_MLQUEUE_DEVICE_BUSY; | ||
480 | if (usb_submit_urb(urb, gfp)) { | ||
481 | shost_printk(KERN_INFO, shost, | ||
482 | "sense urb submission failure\n"); | ||
483 | usb_free_urb(urb); | ||
484 | return SCSI_MLQUEUE_DEVICE_BUSY; | ||
485 | } | ||
486 | usb_anchor_urb(urb, &devinfo->sense_urbs); | ||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | static int uas_submit_urbs(struct scsi_cmnd *cmnd, | 358 | static int uas_submit_urbs(struct scsi_cmnd *cmnd, |
491 | struct uas_dev_info *devinfo, gfp_t gfp) | 359 | struct uas_dev_info *devinfo, gfp_t gfp) |
492 | { | 360 | { |
493 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; | 361 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; |
494 | int err; | ||
495 | 362 | ||
496 | WARN_ON(!spin_is_locked(&devinfo->lock)); | 363 | if (cmdinfo->state & ALLOC_STATUS_URB) { |
364 | cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd, | ||
365 | cmdinfo->stream); | ||
366 | if (!cmdinfo->status_urb) | ||
367 | return SCSI_MLQUEUE_DEVICE_BUSY; | ||
368 | cmdinfo->state &= ~ALLOC_STATUS_URB; | ||
369 | } | ||
370 | |||
497 | if (cmdinfo->state & SUBMIT_STATUS_URB) { | 371 | if (cmdinfo->state & SUBMIT_STATUS_URB) { |
498 | err = uas_submit_sense_urb(cmnd->device->host, gfp, | 372 | if (usb_submit_urb(cmdinfo->status_urb, gfp)) { |
499 | cmdinfo->stream); | 373 | scmd_printk(KERN_INFO, cmnd, |
500 | if (err) { | 374 | "sense urb submission failure\n"); |
501 | return err; | 375 | return SCSI_MLQUEUE_DEVICE_BUSY; |
502 | } | 376 | } |
503 | cmdinfo->state &= ~SUBMIT_STATUS_URB; | 377 | cmdinfo->state &= ~SUBMIT_STATUS_URB; |
504 | } | 378 | } |
@@ -506,7 +380,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, | |||
506 | if (cmdinfo->state & ALLOC_DATA_IN_URB) { | 380 | if (cmdinfo->state & ALLOC_DATA_IN_URB) { |
507 | cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp, | 381 | cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp, |
508 | devinfo->data_in_pipe, cmdinfo->stream, | 382 | devinfo->data_in_pipe, cmdinfo->stream, |
509 | cmnd, DMA_FROM_DEVICE); | 383 | scsi_in(cmnd), DMA_FROM_DEVICE); |
510 | if (!cmdinfo->data_in_urb) | 384 | if (!cmdinfo->data_in_urb) |
511 | return SCSI_MLQUEUE_DEVICE_BUSY; | 385 | return SCSI_MLQUEUE_DEVICE_BUSY; |
512 | cmdinfo->state &= ~ALLOC_DATA_IN_URB; | 386 | cmdinfo->state &= ~ALLOC_DATA_IN_URB; |
@@ -519,14 +393,12 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, | |||
519 | return SCSI_MLQUEUE_DEVICE_BUSY; | 393 | return SCSI_MLQUEUE_DEVICE_BUSY; |
520 | } | 394 | } |
521 | cmdinfo->state &= ~SUBMIT_DATA_IN_URB; | 395 | cmdinfo->state &= ~SUBMIT_DATA_IN_URB; |
522 | cmdinfo->state |= DATA_IN_URB_INFLIGHT; | ||
523 | usb_anchor_urb(cmdinfo->data_in_urb, &devinfo->data_urbs); | ||
524 | } | 396 | } |
525 | 397 | ||
526 | if (cmdinfo->state & ALLOC_DATA_OUT_URB) { | 398 | if (cmdinfo->state & ALLOC_DATA_OUT_URB) { |
527 | cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp, | 399 | cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp, |
528 | devinfo->data_out_pipe, cmdinfo->stream, | 400 | devinfo->data_out_pipe, cmdinfo->stream, |
529 | cmnd, DMA_TO_DEVICE); | 401 | scsi_out(cmnd), DMA_TO_DEVICE); |
530 | if (!cmdinfo->data_out_urb) | 402 | if (!cmdinfo->data_out_urb) |
531 | return SCSI_MLQUEUE_DEVICE_BUSY; | 403 | return SCSI_MLQUEUE_DEVICE_BUSY; |
532 | cmdinfo->state &= ~ALLOC_DATA_OUT_URB; | 404 | cmdinfo->state &= ~ALLOC_DATA_OUT_URB; |
@@ -539,30 +411,23 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, | |||
539 | return SCSI_MLQUEUE_DEVICE_BUSY; | 411 | return SCSI_MLQUEUE_DEVICE_BUSY; |
540 | } | 412 | } |
541 | cmdinfo->state &= ~SUBMIT_DATA_OUT_URB; | 413 | cmdinfo->state &= ~SUBMIT_DATA_OUT_URB; |
542 | cmdinfo->state |= DATA_OUT_URB_INFLIGHT; | ||
543 | usb_anchor_urb(cmdinfo->data_out_urb, &devinfo->data_urbs); | ||
544 | } | 414 | } |
545 | 415 | ||
546 | if (cmdinfo->state & ALLOC_CMD_URB) { | 416 | if (cmdinfo->state & ALLOC_CMD_URB) { |
547 | cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd, | 417 | cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd, |
548 | cmdinfo->stream); | 418 | cmdinfo->stream); |
549 | if (!cmdinfo->cmd_urb) | 419 | if (!cmdinfo->cmd_urb) |
550 | return SCSI_MLQUEUE_DEVICE_BUSY; | 420 | return SCSI_MLQUEUE_DEVICE_BUSY; |
551 | cmdinfo->state &= ~ALLOC_CMD_URB; | 421 | cmdinfo->state &= ~ALLOC_CMD_URB; |
552 | } | 422 | } |
553 | 423 | ||
554 | if (cmdinfo->state & SUBMIT_CMD_URB) { | 424 | if (cmdinfo->state & SUBMIT_CMD_URB) { |
555 | usb_get_urb(cmdinfo->cmd_urb); | ||
556 | if (usb_submit_urb(cmdinfo->cmd_urb, gfp)) { | 425 | if (usb_submit_urb(cmdinfo->cmd_urb, gfp)) { |
557 | scmd_printk(KERN_INFO, cmnd, | 426 | scmd_printk(KERN_INFO, cmnd, |
558 | "cmd urb submission failure\n"); | 427 | "cmd urb submission failure\n"); |
559 | return SCSI_MLQUEUE_DEVICE_BUSY; | 428 | return SCSI_MLQUEUE_DEVICE_BUSY; |
560 | } | 429 | } |
561 | usb_anchor_urb(cmdinfo->cmd_urb, &devinfo->cmd_urbs); | ||
562 | usb_put_urb(cmdinfo->cmd_urb); | ||
563 | cmdinfo->cmd_urb = NULL; | ||
564 | cmdinfo->state &= ~SUBMIT_CMD_URB; | 430 | cmdinfo->state &= ~SUBMIT_CMD_URB; |
565 | cmdinfo->state |= COMMAND_INFLIGHT; | ||
566 | } | 431 | } |
567 | 432 | ||
568 | return 0; | 433 | return 0; |
@@ -574,27 +439,23 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
574 | struct scsi_device *sdev = cmnd->device; | 439 | struct scsi_device *sdev = cmnd->device; |
575 | struct uas_dev_info *devinfo = sdev->hostdata; | 440 | struct uas_dev_info *devinfo = sdev->hostdata; |
576 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; | 441 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; |
577 | unsigned long flags; | ||
578 | int err; | 442 | int err; |
579 | 443 | ||
580 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); | 444 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); |
581 | 445 | ||
582 | spin_lock_irqsave(&devinfo->lock, flags); | 446 | if (!cmdinfo->status_urb && sdev->current_cmnd) |
583 | if (devinfo->cmnd) { | ||
584 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
585 | return SCSI_MLQUEUE_DEVICE_BUSY; | 447 | return SCSI_MLQUEUE_DEVICE_BUSY; |
586 | } | ||
587 | 448 | ||
588 | if (blk_rq_tagged(cmnd->request)) { | 449 | if (blk_rq_tagged(cmnd->request)) { |
589 | cmdinfo->stream = cmnd->request->tag + 2; | 450 | cmdinfo->stream = cmnd->request->tag + 1; |
590 | } else { | 451 | } else { |
591 | devinfo->cmnd = cmnd; | 452 | sdev->current_cmnd = cmnd; |
592 | cmdinfo->stream = 1; | 453 | cmdinfo->stream = 1; |
593 | } | 454 | } |
594 | 455 | ||
595 | cmnd->scsi_done = done; | 456 | cmnd->scsi_done = done; |
596 | 457 | ||
597 | cmdinfo->state = SUBMIT_STATUS_URB | | 458 | cmdinfo->state = ALLOC_STATUS_URB | SUBMIT_STATUS_URB | |
598 | ALLOC_CMD_URB | SUBMIT_CMD_URB; | 459 | ALLOC_CMD_URB | SUBMIT_CMD_URB; |
599 | 460 | ||
600 | switch (cmnd->sc_data_direction) { | 461 | switch (cmnd->sc_data_direction) { |
@@ -618,7 +479,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
618 | if (err) { | 479 | if (err) { |
619 | /* If we did nothing, give up now */ | 480 | /* If we did nothing, give up now */ |
620 | if (cmdinfo->state & SUBMIT_STATUS_URB) { | 481 | if (cmdinfo->state & SUBMIT_STATUS_URB) { |
621 | spin_unlock_irqrestore(&devinfo->lock, flags); | 482 | usb_free_urb(cmdinfo->status_urb); |
622 | return SCSI_MLQUEUE_DEVICE_BUSY; | 483 | return SCSI_MLQUEUE_DEVICE_BUSY; |
623 | } | 484 | } |
624 | spin_lock(&uas_work_lock); | 485 | spin_lock(&uas_work_lock); |
@@ -627,78 +488,41 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
627 | schedule_work(&uas_work); | 488 | schedule_work(&uas_work); |
628 | } | 489 | } |
629 | 490 | ||
630 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
631 | return 0; | 491 | return 0; |
632 | } | 492 | } |
633 | 493 | ||
634 | static DEF_SCSI_QCMD(uas_queuecommand) | 494 | static DEF_SCSI_QCMD(uas_queuecommand) |
635 | 495 | ||
636 | static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd, | 496 | static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) |
637 | const char *fname, u8 function) | ||
638 | { | 497 | { |
639 | struct Scsi_Host *shost = cmnd->device->host; | 498 | struct scsi_device *sdev = cmnd->device; |
640 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; | 499 | sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__, |
641 | u16 tag = devinfo->qdepth - 1; | 500 | cmnd->request->tag); |
642 | unsigned long flags; | ||
643 | |||
644 | spin_lock_irqsave(&devinfo->lock, flags); | ||
645 | memset(&devinfo->response, 0, sizeof(devinfo->response)); | ||
646 | if (uas_submit_sense_urb(shost, GFP_ATOMIC, tag)) { | ||
647 | shost_printk(KERN_INFO, shost, | ||
648 | "%s: %s: submit sense urb failed\n", | ||
649 | __func__, fname); | ||
650 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
651 | return FAILED; | ||
652 | } | ||
653 | if (uas_submit_task_urb(cmnd, GFP_ATOMIC, function, tag)) { | ||
654 | shost_printk(KERN_INFO, shost, | ||
655 | "%s: %s: submit task mgmt urb failed\n", | ||
656 | __func__, fname); | ||
657 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
658 | return FAILED; | ||
659 | } | ||
660 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
661 | 501 | ||
662 | if (usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 3000) == 0) { | 502 | /* XXX: Send ABORT TASK Task Management command */ |
663 | shost_printk(KERN_INFO, shost, | 503 | return FAILED; |
664 | "%s: %s timed out\n", __func__, fname); | ||
665 | return FAILED; | ||
666 | } | ||
667 | if (be16_to_cpu(devinfo->response.tag) != tag) { | ||
668 | shost_printk(KERN_INFO, shost, | ||
669 | "%s: %s failed (wrong tag %d/%d)\n", __func__, | ||
670 | fname, be16_to_cpu(devinfo->response.tag), tag); | ||
671 | return FAILED; | ||
672 | } | ||
673 | if (devinfo->response.response_code != RC_TMF_COMPLETE) { | ||
674 | shost_printk(KERN_INFO, shost, | ||
675 | "%s: %s failed (rc 0x%x)\n", __func__, | ||
676 | fname, devinfo->response.response_code); | ||
677 | return FAILED; | ||
678 | } | ||
679 | return SUCCESS; | ||
680 | } | 504 | } |
681 | 505 | ||
682 | static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) | 506 | static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd) |
683 | { | 507 | { |
684 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; | 508 | struct scsi_device *sdev = cmnd->device; |
685 | struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; | 509 | sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__, |
686 | unsigned long flags; | 510 | cmnd->request->tag); |
687 | int ret; | 511 | |
688 | 512 | /* XXX: Send LOGICAL UNIT RESET Task Management command */ | |
689 | uas_log_cmd_state(cmnd, __func__); | 513 | return FAILED; |
690 | spin_lock_irqsave(&devinfo->lock, flags); | ||
691 | cmdinfo->state |= COMMAND_ABORTED; | ||
692 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
693 | ret = uas_eh_task_mgmt(cmnd, "ABORT TASK", TMF_ABORT_TASK); | ||
694 | return ret; | ||
695 | } | 514 | } |
696 | 515 | ||
697 | static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd) | 516 | static int uas_eh_target_reset_handler(struct scsi_cmnd *cmnd) |
698 | { | 517 | { |
699 | sdev_printk(KERN_INFO, cmnd->device, "%s\n", __func__); | 518 | struct scsi_device *sdev = cmnd->device; |
700 | return uas_eh_task_mgmt(cmnd, "LOGICAL UNIT RESET", | 519 | sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__, |
701 | TMF_LOGICAL_UNIT_RESET); | 520 | cmnd->request->tag); |
521 | |||
522 | /* XXX: Can we reset just the one USB interface? | ||
523 | * Would calling usb_set_interface() have the right effect? | ||
524 | */ | ||
525 | return FAILED; | ||
702 | } | 526 | } |
703 | 527 | ||
704 | static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) | 528 | static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) |
@@ -706,22 +530,14 @@ static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
706 | struct scsi_device *sdev = cmnd->device; | 530 | struct scsi_device *sdev = cmnd->device; |
707 | struct uas_dev_info *devinfo = sdev->hostdata; | 531 | struct uas_dev_info *devinfo = sdev->hostdata; |
708 | struct usb_device *udev = devinfo->udev; | 532 | struct usb_device *udev = devinfo->udev; |
709 | int err; | ||
710 | 533 | ||
711 | devinfo->resetting = 1; | 534 | sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__, |
712 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); | 535 | cmnd->request->tag); |
713 | usb_kill_anchored_urbs(&devinfo->sense_urbs); | ||
714 | usb_kill_anchored_urbs(&devinfo->data_urbs); | ||
715 | err = usb_reset_device(udev); | ||
716 | devinfo->resetting = 0; | ||
717 | 536 | ||
718 | if (err) { | 537 | if (usb_reset_device(udev)) |
719 | shost_printk(KERN_INFO, sdev->host, "%s FAILED\n", __func__); | 538 | return SUCCESS; |
720 | return FAILED; | ||
721 | } | ||
722 | 539 | ||
723 | shost_printk(KERN_INFO, sdev->host, "%s success\n", __func__); | 540 | return FAILED; |
724 | return SUCCESS; | ||
725 | } | 541 | } |
726 | 542 | ||
727 | static int uas_slave_alloc(struct scsi_device *sdev) | 543 | static int uas_slave_alloc(struct scsi_device *sdev) |
@@ -734,7 +550,7 @@ static int uas_slave_configure(struct scsi_device *sdev) | |||
734 | { | 550 | { |
735 | struct uas_dev_info *devinfo = sdev->hostdata; | 551 | struct uas_dev_info *devinfo = sdev->hostdata; |
736 | scsi_set_tag_type(sdev, MSG_ORDERED_TAG); | 552 | scsi_set_tag_type(sdev, MSG_ORDERED_TAG); |
737 | scsi_activate_tcq(sdev, devinfo->qdepth - 3); | 553 | scsi_activate_tcq(sdev, devinfo->qdepth - 1); |
738 | return 0; | 554 | return 0; |
739 | } | 555 | } |
740 | 556 | ||
@@ -746,6 +562,7 @@ static struct scsi_host_template uas_host_template = { | |||
746 | .slave_configure = uas_slave_configure, | 562 | .slave_configure = uas_slave_configure, |
747 | .eh_abort_handler = uas_eh_abort_handler, | 563 | .eh_abort_handler = uas_eh_abort_handler, |
748 | .eh_device_reset_handler = uas_eh_device_reset_handler, | 564 | .eh_device_reset_handler = uas_eh_device_reset_handler, |
565 | .eh_target_reset_handler = uas_eh_target_reset_handler, | ||
749 | .eh_bus_reset_handler = uas_eh_bus_reset_handler, | 566 | .eh_bus_reset_handler = uas_eh_bus_reset_handler, |
750 | .can_queue = 65536, /* Is there a limit on the _host_ ? */ | 567 | .can_queue = 65536, /* Is there a limit on the _host_ ? */ |
751 | .this_id = -1, | 568 | .this_id = -1, |
@@ -771,34 +588,22 @@ static int uas_is_interface(struct usb_host_interface *intf) | |||
771 | intf->desc.bInterfaceProtocol == USB_PR_UAS); | 588 | intf->desc.bInterfaceProtocol == USB_PR_UAS); |
772 | } | 589 | } |
773 | 590 | ||
774 | static int uas_isnt_supported(struct usb_device *udev) | ||
775 | { | ||
776 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
777 | |||
778 | dev_warn(&udev->dev, "The driver for the USB controller %s does not " | ||
779 | "support scatter-gather which is\n", | ||
780 | hcd->driver->description); | ||
781 | dev_warn(&udev->dev, "required by the UAS driver. Please try an" | ||
782 | "alternative USB controller if you wish to use UAS.\n"); | ||
783 | return -ENODEV; | ||
784 | } | ||
785 | |||
786 | static int uas_switch_interface(struct usb_device *udev, | 591 | static int uas_switch_interface(struct usb_device *udev, |
787 | struct usb_interface *intf) | 592 | struct usb_interface *intf) |
788 | { | 593 | { |
789 | int i; | 594 | int i; |
790 | int sg_supported = udev->bus->sg_tablesize != 0; | 595 | |
596 | if (uas_is_interface(intf->cur_altsetting)) | ||
597 | return 0; | ||
791 | 598 | ||
792 | for (i = 0; i < intf->num_altsetting; i++) { | 599 | for (i = 0; i < intf->num_altsetting; i++) { |
793 | struct usb_host_interface *alt = &intf->altsetting[i]; | 600 | struct usb_host_interface *alt = &intf->altsetting[i]; |
794 | 601 | if (alt == intf->cur_altsetting) | |
795 | if (uas_is_interface(alt)) { | 602 | continue; |
796 | if (!sg_supported) | 603 | if (uas_is_interface(alt)) |
797 | return uas_isnt_supported(udev); | ||
798 | return usb_set_interface(udev, | 604 | return usb_set_interface(udev, |
799 | alt->desc.bInterfaceNumber, | 605 | alt->desc.bInterfaceNumber, |
800 | alt->desc.bAlternateSetting); | 606 | alt->desc.bAlternateSetting); |
801 | } | ||
802 | } | 607 | } |
803 | 608 | ||
804 | return -ENODEV; | 609 | return -ENODEV; |
@@ -813,7 +618,6 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo) | |||
813 | unsigned i, n_endpoints = intf->cur_altsetting->desc.bNumEndpoints; | 618 | unsigned i, n_endpoints = intf->cur_altsetting->desc.bNumEndpoints; |
814 | 619 | ||
815 | devinfo->uas_sense_old = 0; | 620 | devinfo->uas_sense_old = 0; |
816 | devinfo->cmnd = NULL; | ||
817 | 621 | ||
818 | for (i = 0; i < n_endpoints; i++) { | 622 | for (i = 0; i < n_endpoints; i++) { |
819 | unsigned char *extra = endpoint[i].extra; | 623 | unsigned char *extra = endpoint[i].extra; |
@@ -865,17 +669,6 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo) | |||
865 | } | 669 | } |
866 | } | 670 | } |
867 | 671 | ||
868 | static void uas_free_streams(struct uas_dev_info *devinfo) | ||
869 | { | ||
870 | struct usb_device *udev = devinfo->udev; | ||
871 | struct usb_host_endpoint *eps[3]; | ||
872 | |||
873 | eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe); | ||
874 | eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe); | ||
875 | eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe); | ||
876 | usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL); | ||
877 | } | ||
878 | |||
879 | /* | 672 | /* |
880 | * XXX: What I'd like to do here is register a SCSI host for each USB host in | 673 | * XXX: What I'd like to do here is register a SCSI host for each USB host in |
881 | * the system. Follow usb-storage's design of registering a SCSI host for | 674 | * the system. Follow usb-storage's design of registering a SCSI host for |
@@ -905,31 +698,18 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
905 | shost->max_id = 1; | 698 | shost->max_id = 1; |
906 | shost->sg_tablesize = udev->bus->sg_tablesize; | 699 | shost->sg_tablesize = udev->bus->sg_tablesize; |
907 | 700 | ||
908 | devinfo->intf = intf; | ||
909 | devinfo->udev = udev; | ||
910 | devinfo->resetting = 0; | ||
911 | init_usb_anchor(&devinfo->cmd_urbs); | ||
912 | init_usb_anchor(&devinfo->sense_urbs); | ||
913 | init_usb_anchor(&devinfo->data_urbs); | ||
914 | spin_lock_init(&devinfo->lock); | ||
915 | uas_configure_endpoints(devinfo); | ||
916 | |||
917 | result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 3); | ||
918 | if (result) | ||
919 | goto free; | ||
920 | |||
921 | result = scsi_add_host(shost, &intf->dev); | 701 | result = scsi_add_host(shost, &intf->dev); |
922 | if (result) | 702 | if (result) |
923 | goto deconfig_eps; | 703 | goto free; |
924 | |||
925 | shost->hostdata[0] = (unsigned long)devinfo; | 704 | shost->hostdata[0] = (unsigned long)devinfo; |
926 | 705 | ||
706 | devinfo->intf = intf; | ||
707 | devinfo->udev = udev; | ||
708 | uas_configure_endpoints(devinfo); | ||
709 | |||
927 | scsi_scan_host(shost); | 710 | scsi_scan_host(shost); |
928 | usb_set_intfdata(intf, shost); | 711 | usb_set_intfdata(intf, shost); |
929 | return result; | 712 | return result; |
930 | |||
931 | deconfig_eps: | ||
932 | uas_free_streams(devinfo); | ||
933 | free: | 713 | free: |
934 | kfree(devinfo); | 714 | kfree(devinfo); |
935 | if (shost) | 715 | if (shost) |
@@ -951,14 +731,18 @@ static int uas_post_reset(struct usb_interface *intf) | |||
951 | 731 | ||
952 | static void uas_disconnect(struct usb_interface *intf) | 732 | static void uas_disconnect(struct usb_interface *intf) |
953 | { | 733 | { |
734 | struct usb_device *udev = interface_to_usbdev(intf); | ||
735 | struct usb_host_endpoint *eps[3]; | ||
954 | struct Scsi_Host *shost = usb_get_intfdata(intf); | 736 | struct Scsi_Host *shost = usb_get_intfdata(intf); |
955 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; | 737 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; |
956 | 738 | ||
957 | scsi_remove_host(shost); | 739 | scsi_remove_host(shost); |
958 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); | 740 | |
959 | usb_kill_anchored_urbs(&devinfo->sense_urbs); | 741 | eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe); |
960 | usb_kill_anchored_urbs(&devinfo->data_urbs); | 742 | eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe); |
961 | uas_free_streams(devinfo); | 743 | eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe); |
744 | usb_free_streams(intf, eps, 3, GFP_KERNEL); | ||
745 | |||
962 | kfree(devinfo); | 746 | kfree(devinfo); |
963 | } | 747 | } |
964 | 748 | ||
@@ -975,7 +759,18 @@ static struct usb_driver uas_driver = { | |||
975 | .id_table = uas_usb_ids, | 759 | .id_table = uas_usb_ids, |
976 | }; | 760 | }; |
977 | 761 | ||
978 | module_usb_driver(uas_driver); | 762 | static int uas_init(void) |
763 | { | ||
764 | return usb_register(&uas_driver); | ||
765 | } | ||
766 | |||
767 | static void uas_exit(void) | ||
768 | { | ||
769 | usb_deregister(&uas_driver); | ||
770 | } | ||
771 | |||
772 | module_init(uas_init); | ||
773 | module_exit(uas_exit); | ||
979 | 774 | ||
980 | MODULE_LICENSE("GPL"); | 775 | MODULE_LICENSE("GPL"); |
981 | MODULE_AUTHOR("Matthew Wilcox and Sarah Sharp"); | 776 | MODULE_AUTHOR("Matthew Wilcox and Sarah Sharp"); |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d305a5aa3a5..f5dcc4f214f 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -110,7 +110,7 @@ UNUSUAL_DEV( 0x040d, 0x6205, 0x0003, 0x0003, | |||
110 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 110 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
111 | US_FL_IGNORE_RESIDUE ), | 111 | US_FL_IGNORE_RESIDUE ), |
112 | 112 | ||
113 | /* Deduced by Jonathan Woithe <jwoithe@just42.net> | 113 | /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au> |
114 | * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message | 114 | * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message |
115 | * always fails and confuses drive. | 115 | * always fails and confuses drive. |
116 | */ | 116 | */ |
@@ -1004,12 +1004,6 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999, | |||
1004 | USB_SC_8070, USB_PR_CB, NULL, | 1004 | USB_SC_8070, USB_PR_CB, NULL, |
1005 | US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), | 1005 | US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), |
1006 | 1006 | ||
1007 | /* Submitted by Oleksandr Chumachenko <ledest@gmail.com> */ | ||
1008 | UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100, | ||
1009 | "Casio", | ||
1010 | "EX-N1 DigitalCamera", | ||
1011 | USB_SC_8070, USB_PR_DEVICE, NULL, 0), | ||
1012 | |||
1013 | /* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/ | 1007 | /* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/ |
1014 | UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, | 1008 | UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, |
1015 | "Samsung", | 1009 | "Samsung", |
@@ -1273,12 +1267,6 @@ UNUSUAL_DEV( 0x0af0, 0xd357, 0x0000, 0x0000, | |||
1273 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 1267 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
1274 | 0 ), | 1268 | 0 ), |
1275 | 1269 | ||
1276 | /* Reported by Namjae Jeon <namjae.jeon@samsung.com> */ | ||
1277 | UNUSUAL_DEV(0x0bc2, 0x2300, 0x0000, 0x9999, | ||
1278 | "Seagate", | ||
1279 | "Portable HDD", | ||
1280 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_WRITE_CACHE), | ||
1281 | |||
1282 | /* Reported by Ben Efros <ben@pc-doctor.com> */ | 1270 | /* Reported by Ben Efros <ben@pc-doctor.com> */ |
1283 | UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, | 1271 | UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, |
1284 | "Seagate", | 1272 | "Seagate", |
@@ -1480,12 +1468,6 @@ UNUSUAL_DEV( 0x1058, 0x0704, 0x0000, 0x9999, | |||
1480 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 1468 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
1481 | US_FL_SANE_SENSE), | 1469 | US_FL_SANE_SENSE), |
1482 | 1470 | ||
1483 | /* Reported by Namjae Jeon <namjae.jeon@samsung.com> */ | ||
1484 | UNUSUAL_DEV(0x1058, 0x070a, 0x0000, 0x9999, | ||
1485 | "Western Digital", | ||
1486 | "My Passport HDD", | ||
1487 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_WRITE_CACHE), | ||
1488 | |||
1489 | /* Reported by Fabio Venturi <f.venturi@tdnet.it> | 1471 | /* Reported by Fabio Venturi <f.venturi@tdnet.it> |
1490 | * The device reports a vendor-specific bDeviceClass. | 1472 | * The device reports a vendor-specific bDeviceClass. |
1491 | */ | 1473 | */ |
@@ -1858,6 +1840,12 @@ UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000, | |||
1858 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | 1840 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, |
1859 | 0), | 1841 | 0), |
1860 | 1842 | ||
1843 | UNUSUAL_DEV( 0x12d1, 0x1446, 0x0000, 0x0000, | ||
1844 | "HUAWEI MOBILE", | ||
1845 | "Mass Storage", | ||
1846 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1847 | 0), | ||
1848 | |||
1861 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ | 1849 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ |
1862 | UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001, | 1850 | UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001, |
1863 | "Minolta", | 1851 | "Minolta", |
@@ -1903,13 +1891,6 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201, | |||
1903 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 1891 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
1904 | US_FL_IGNORE_RESIDUE ), | 1892 | US_FL_IGNORE_RESIDUE ), |
1905 | 1893 | ||
1906 | /* Reported by Jesse Feddema <jdfeddema@gmail.com> */ | ||
1907 | UNUSUAL_DEV( 0x177f, 0x0400, 0x0000, 0x0000, | ||
1908 | "Yarvik", | ||
1909 | "PMP400", | ||
1910 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
1911 | US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ), | ||
1912 | |||
1913 | /* Reported by Hans de Goede <hdegoede@redhat.com> | 1894 | /* Reported by Hans de Goede <hdegoede@redhat.com> |
1914 | * These Appotech controllers are found in Picture Frames, they provide a | 1895 | * These Appotech controllers are found in Picture Frames, they provide a |
1915 | * (buggy) emulation of a cdrom drive which contains the windows software | 1896 | * (buggy) emulation of a cdrom drive which contains the windows software |
@@ -1939,7 +1920,7 @@ UNUSUAL_DEV( 0x1b1c, 0x1ab5, 0x0200, 0x0200, | |||
1939 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 1920 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
1940 | US_FL_INITIAL_READ10 ), | 1921 | US_FL_INITIAL_READ10 ), |
1941 | 1922 | ||
1942 | /* Patch by Richard Schütz <r.schtz@t-online.de> | 1923 | /* Patch by Richard Schütz <r.schtz@t-online.de> |
1943 | * This external hard drive enclosure uses a JMicron chip which | 1924 | * This external hard drive enclosure uses a JMicron chip which |
1944 | * needs the US_FL_IGNORE_RESIDUE flag to work properly. */ | 1925 | * needs the US_FL_IGNORE_RESIDUE flag to work properly. */ |
1945 | UNUSUAL_DEV( 0x1e68, 0x001b, 0x0000, 0x0000, | 1926 | UNUSUAL_DEV( 0x1e68, 0x001b, 0x0000, 0x0000, |
@@ -2044,25 +2025,25 @@ UNUSUAL_DEV( 0xed10, 0x7636, 0x0001, 0x0001, | |||
2044 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), | 2025 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), |
2045 | 2026 | ||
2046 | /* Control/Bulk transport for all SubClass values */ | 2027 | /* Control/Bulk transport for all SubClass values */ |
2047 | USUAL_DEV(USB_SC_RBC, USB_PR_CB), | 2028 | USUAL_DEV(USB_SC_RBC, USB_PR_CB, USB_US_TYPE_STOR), |
2048 | USUAL_DEV(USB_SC_8020, USB_PR_CB), | 2029 | USUAL_DEV(USB_SC_8020, USB_PR_CB, USB_US_TYPE_STOR), |
2049 | USUAL_DEV(USB_SC_QIC, USB_PR_CB), | 2030 | USUAL_DEV(USB_SC_QIC, USB_PR_CB, USB_US_TYPE_STOR), |
2050 | USUAL_DEV(USB_SC_UFI, USB_PR_CB), | 2031 | USUAL_DEV(USB_SC_UFI, USB_PR_CB, USB_US_TYPE_STOR), |
2051 | USUAL_DEV(USB_SC_8070, USB_PR_CB), | 2032 | USUAL_DEV(USB_SC_8070, USB_PR_CB, USB_US_TYPE_STOR), |
2052 | USUAL_DEV(USB_SC_SCSI, USB_PR_CB), | 2033 | USUAL_DEV(USB_SC_SCSI, USB_PR_CB, USB_US_TYPE_STOR), |
2053 | 2034 | ||
2054 | /* Control/Bulk/Interrupt transport for all SubClass values */ | 2035 | /* Control/Bulk/Interrupt transport for all SubClass values */ |
2055 | USUAL_DEV(USB_SC_RBC, USB_PR_CBI), | 2036 | USUAL_DEV(USB_SC_RBC, USB_PR_CBI, USB_US_TYPE_STOR), |
2056 | USUAL_DEV(USB_SC_8020, USB_PR_CBI), | 2037 | USUAL_DEV(USB_SC_8020, USB_PR_CBI, USB_US_TYPE_STOR), |
2057 | USUAL_DEV(USB_SC_QIC, USB_PR_CBI), | 2038 | USUAL_DEV(USB_SC_QIC, USB_PR_CBI, USB_US_TYPE_STOR), |
2058 | USUAL_DEV(USB_SC_UFI, USB_PR_CBI), | 2039 | USUAL_DEV(USB_SC_UFI, USB_PR_CBI, USB_US_TYPE_STOR), |
2059 | USUAL_DEV(USB_SC_8070, USB_PR_CBI), | 2040 | USUAL_DEV(USB_SC_8070, USB_PR_CBI, USB_US_TYPE_STOR), |
2060 | USUAL_DEV(USB_SC_SCSI, USB_PR_CBI), | 2041 | USUAL_DEV(USB_SC_SCSI, USB_PR_CBI, USB_US_TYPE_STOR), |
2061 | 2042 | ||
2062 | /* Bulk-only transport for all SubClass values */ | 2043 | /* Bulk-only transport for all SubClass values */ |
2063 | USUAL_DEV(USB_SC_RBC, USB_PR_BULK), | 2044 | USUAL_DEV(USB_SC_RBC, USB_PR_BULK, USB_US_TYPE_STOR), |
2064 | USUAL_DEV(USB_SC_8020, USB_PR_BULK), | 2045 | USUAL_DEV(USB_SC_8020, USB_PR_BULK, USB_US_TYPE_STOR), |
2065 | USUAL_DEV(USB_SC_QIC, USB_PR_BULK), | 2046 | USUAL_DEV(USB_SC_QIC, USB_PR_BULK, USB_US_TYPE_STOR), |
2066 | USUAL_DEV(USB_SC_UFI, USB_PR_BULK), | 2047 | USUAL_DEV(USB_SC_UFI, USB_PR_BULK, USB_US_TYPE_STOR), |
2067 | USUAL_DEV(USB_SC_8070, USB_PR_BULK), | 2048 | USUAL_DEV(USB_SC_8070, USB_PR_BULK, USB_US_TYPE_STOR), |
2068 | USUAL_DEV(USB_SC_SCSI, USB_PR_BULK), | 2049 | USUAL_DEV(USB_SC_SCSI, USB_PR_BULK, 0), |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 31b3e1a61bb..9e069efeefe 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -114,53 +114,21 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks"); | |||
114 | 114 | ||
115 | #define COMPLIANT_DEV UNUSUAL_DEV | 115 | #define COMPLIANT_DEV UNUSUAL_DEV |
116 | 116 | ||
117 | #define USUAL_DEV(use_protocol, use_transport) \ | 117 | #define USUAL_DEV(use_protocol, use_transport, use_type) \ |
118 | { \ | 118 | { \ |
119 | .useProtocol = use_protocol, \ | 119 | .useProtocol = use_protocol, \ |
120 | .useTransport = use_transport, \ | 120 | .useTransport = use_transport, \ |
121 | } | 121 | } |
122 | 122 | ||
123 | static struct us_unusual_dev us_unusual_dev_list[] = { | 123 | static struct us_unusual_dev us_unusual_dev_list[] = { |
124 | # include "unusual_devs.h" | 124 | # include "unusual_devs.h" |
125 | { } /* Terminating entry */ | 125 | { } /* Terminating entry */ |
126 | }; | 126 | }; |
127 | 127 | ||
128 | static struct us_unusual_dev for_dynamic_ids = | ||
129 | USUAL_DEV(USB_SC_SCSI, USB_PR_BULK); | ||
130 | |||
131 | #undef UNUSUAL_DEV | 128 | #undef UNUSUAL_DEV |
132 | #undef COMPLIANT_DEV | 129 | #undef COMPLIANT_DEV |
133 | #undef USUAL_DEV | 130 | #undef USUAL_DEV |
134 | 131 | ||
135 | #ifdef CONFIG_LOCKDEP | ||
136 | |||
137 | static struct lock_class_key us_interface_key[USB_MAXINTERFACES]; | ||
138 | |||
139 | static void us_set_lock_class(struct mutex *mutex, | ||
140 | struct usb_interface *intf) | ||
141 | { | ||
142 | struct usb_device *udev = interface_to_usbdev(intf); | ||
143 | struct usb_host_config *config = udev->actconfig; | ||
144 | int i; | ||
145 | |||
146 | for (i = 0; i < config->desc.bNumInterfaces; i++) { | ||
147 | if (config->interface[i] == intf) | ||
148 | break; | ||
149 | } | ||
150 | |||
151 | BUG_ON(i == config->desc.bNumInterfaces); | ||
152 | |||
153 | lockdep_set_class(mutex, &us_interface_key[i]); | ||
154 | } | ||
155 | |||
156 | #else | ||
157 | |||
158 | static void us_set_lock_class(struct mutex *mutex, | ||
159 | struct usb_interface *intf) | ||
160 | { | ||
161 | } | ||
162 | |||
163 | #endif | ||
164 | 132 | ||
165 | #ifdef CONFIG_PM /* Minimal support for suspend and resume */ | 133 | #ifdef CONFIG_PM /* Minimal support for suspend and resume */ |
166 | 134 | ||
@@ -261,17 +229,17 @@ EXPORT_SYMBOL_GPL(usb_stor_post_reset); | |||
261 | void fill_inquiry_response(struct us_data *us, unsigned char *data, | 229 | void fill_inquiry_response(struct us_data *us, unsigned char *data, |
262 | unsigned int data_len) | 230 | unsigned int data_len) |
263 | { | 231 | { |
264 | if (data_len < 36) /* You lose. */ | 232 | if (data_len<36) // You lose. |
265 | return; | 233 | return; |
266 | 234 | ||
267 | memset(data+8, ' ', 28); | 235 | memset(data+8, ' ', 28); |
268 | if (data[0]&0x20) { /* USB device currently not connected. Return | 236 | if(data[0]&0x20) { /* USB device currently not connected. Return |
269 | peripheral qualifier 001b ("...however, the | 237 | peripheral qualifier 001b ("...however, the |
270 | physical device is not currently connected | 238 | physical device is not currently connected |
271 | to this logical unit") and leave vendor and | 239 | to this logical unit") and leave vendor and |
272 | product identification empty. ("If the target | 240 | product identification empty. ("If the target |
273 | does store some of the INQUIRY data on the | 241 | does store some of the INQUIRY data on the |
274 | device, it may return zeros or ASCII spaces | 242 | device, it may return zeros or ASCII spaces |
275 | (20h) in those fields until the data is | 243 | (20h) in those fields until the data is |
276 | available from the device."). */ | 244 | available from the device."). */ |
277 | } else { | 245 | } else { |
@@ -298,7 +266,7 @@ static int usb_stor_control_thread(void * __us) | |||
298 | struct us_data *us = (struct us_data *)__us; | 266 | struct us_data *us = (struct us_data *)__us; |
299 | struct Scsi_Host *host = us_to_host(us); | 267 | struct Scsi_Host *host = us_to_host(us); |
300 | 268 | ||
301 | for (;;) { | 269 | for(;;) { |
302 | US_DEBUGP("*** thread sleeping.\n"); | 270 | US_DEBUGP("*** thread sleeping.\n"); |
303 | if (wait_for_completion_interruptible(&us->cmnd_ready)) | 271 | if (wait_for_completion_interruptible(&us->cmnd_ready)) |
304 | break; | 272 | break; |
@@ -327,7 +295,7 @@ static int usb_stor_control_thread(void * __us) | |||
327 | 295 | ||
328 | scsi_unlock(host); | 296 | scsi_unlock(host); |
329 | 297 | ||
330 | /* reject the command if the direction indicator | 298 | /* reject the command if the direction indicator |
331 | * is UNKNOWN | 299 | * is UNKNOWN |
332 | */ | 300 | */ |
333 | if (us->srb->sc_data_direction == DMA_BIDIRECTIONAL) { | 301 | if (us->srb->sc_data_direction == DMA_BIDIRECTIONAL) { |
@@ -338,7 +306,7 @@ static int usb_stor_control_thread(void * __us) | |||
338 | /* reject if target != 0 or if LUN is higher than | 306 | /* reject if target != 0 or if LUN is higher than |
339 | * the maximum known LUN | 307 | * the maximum known LUN |
340 | */ | 308 | */ |
341 | else if (us->srb->device->id && | 309 | else if (us->srb->device->id && |
342 | !(us->fflags & US_FL_SCM_MULT_TARG)) { | 310 | !(us->fflags & US_FL_SCM_MULT_TARG)) { |
343 | US_DEBUGP("Bad target number (%d:%d)\n", | 311 | US_DEBUGP("Bad target number (%d:%d)\n", |
344 | us->srb->device->id, us->srb->device->lun); | 312 | us->srb->device->id, us->srb->device->lun); |
@@ -351,7 +319,7 @@ static int usb_stor_control_thread(void * __us) | |||
351 | us->srb->result = DID_BAD_TARGET << 16; | 319 | us->srb->result = DID_BAD_TARGET << 16; |
352 | } | 320 | } |
353 | 321 | ||
354 | /* Handle those devices which need us to fake | 322 | /* Handle those devices which need us to fake |
355 | * their inquiry data */ | 323 | * their inquiry data */ |
356 | else if ((us->srb->cmnd[0] == INQUIRY) && | 324 | else if ((us->srb->cmnd[0] == INQUIRY) && |
357 | (us->fflags & US_FL_FIX_INQUIRY)) { | 325 | (us->fflags & US_FL_FIX_INQUIRY)) { |
@@ -376,7 +344,7 @@ static int usb_stor_control_thread(void * __us) | |||
376 | 344 | ||
377 | /* indicate that the command is done */ | 345 | /* indicate that the command is done */ |
378 | if (us->srb->result != DID_ABORT << 16) { | 346 | if (us->srb->result != DID_ABORT << 16) { |
379 | US_DEBUGP("scsi cmd done, result=0x%x\n", | 347 | US_DEBUGP("scsi cmd done, result=0x%x\n", |
380 | us->srb->result); | 348 | us->srb->result); |
381 | us->srb->scsi_done(us->srb); | 349 | us->srb->scsi_done(us->srb); |
382 | } else { | 350 | } else { |
@@ -414,7 +382,7 @@ SkipForAbort: | |||
414 | } | 382 | } |
415 | __set_current_state(TASK_RUNNING); | 383 | __set_current_state(TASK_RUNNING); |
416 | return 0; | 384 | return 0; |
417 | } | 385 | } |
418 | 386 | ||
419 | /*********************************************************************** | 387 | /*********************************************************************** |
420 | * Device probing and disconnecting | 388 | * Device probing and disconnecting |
@@ -473,7 +441,7 @@ static void adjust_quirks(struct us_data *us) | |||
473 | US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE | | 441 | US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE | |
474 | US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT | | 442 | US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT | |
475 | 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 | |
476 | US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE); | 444 | US_FL_INITIAL_READ10); |
477 | 445 | ||
478 | p = quirks; | 446 | p = quirks; |
479 | while (*p) { | 447 | while (*p) { |
@@ -529,9 +497,6 @@ static void adjust_quirks(struct us_data *us) | |||
529 | case 'o': | 497 | case 'o': |
530 | f |= US_FL_CAPACITY_OK; | 498 | f |= US_FL_CAPACITY_OK; |
531 | break; | 499 | break; |
532 | case 'p': | ||
533 | f |= US_FL_WRITE_CACHE; | ||
534 | break; | ||
535 | case 'r': | 500 | case 'r': |
536 | f |= US_FL_IGNORE_RESIDUE; | 501 | f |= US_FL_IGNORE_RESIDUE; |
537 | break; | 502 | break; |
@@ -564,7 +529,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id, | |||
564 | us->protocol = (unusual_dev->useTransport == USB_PR_DEVICE) ? | 529 | us->protocol = (unusual_dev->useTransport == USB_PR_DEVICE) ? |
565 | idesc->bInterfaceProtocol : | 530 | idesc->bInterfaceProtocol : |
566 | unusual_dev->useTransport; | 531 | unusual_dev->useTransport; |
567 | us->fflags = id->driver_info; | 532 | us->fflags = USB_US_ORIG_FLAGS(id->driver_info); |
568 | adjust_quirks(us); | 533 | adjust_quirks(us); |
569 | 534 | ||
570 | if (us->fflags & US_FL_IGNORE_DEVICE) { | 535 | if (us->fflags & US_FL_IGNORE_DEVICE) { |
@@ -735,7 +700,7 @@ static int get_pipes(struct us_data *us) | |||
735 | us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0); | 700 | us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0); |
736 | us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev, | 701 | us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev, |
737 | usb_endpoint_num(ep_out)); | 702 | usb_endpoint_num(ep_out)); |
738 | us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, | 703 | us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, |
739 | usb_endpoint_num(ep_in)); | 704 | usb_endpoint_num(ep_in)); |
740 | if (ep_int) { | 705 | if (ep_int) { |
741 | us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, | 706 | us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, |
@@ -823,19 +788,15 @@ static void quiesce_and_remove_host(struct us_data *us) | |||
823 | struct Scsi_Host *host = us_to_host(us); | 788 | struct Scsi_Host *host = us_to_host(us); |
824 | 789 | ||
825 | /* If the device is really gone, cut short reset delays */ | 790 | /* If the device is really gone, cut short reset delays */ |
826 | if (us->pusb_dev->state == USB_STATE_NOTATTACHED) { | 791 | if (us->pusb_dev->state == USB_STATE_NOTATTACHED) |
827 | set_bit(US_FLIDX_DISCONNECTING, &us->dflags); | 792 | set_bit(US_FLIDX_DISCONNECTING, &us->dflags); |
828 | wake_up(&us->delay_wait); | ||
829 | } | ||
830 | 793 | ||
831 | /* Prevent SCSI scanning (if it hasn't started yet) | 794 | /* Prevent SCSI-scanning (if it hasn't started yet) |
832 | * or wait for the SCSI-scanning routine to stop. | 795 | * and wait for the SCSI-scanning thread to stop. |
833 | */ | 796 | */ |
834 | cancel_delayed_work_sync(&us->scan_dwork); | 797 | set_bit(US_FLIDX_DONT_SCAN, &us->dflags); |
835 | 798 | wake_up(&us->delay_wait); | |
836 | /* Balance autopm calls if scanning was cancelled */ | 799 | wait_for_completion(&us->scanning_done); |
837 | if (test_bit(US_FLIDX_SCAN_PENDING, &us->dflags)) | ||
838 | usb_autopm_put_interface_no_suspend(us->pusb_intf); | ||
839 | 800 | ||
840 | /* Removing the host will perform an orderly shutdown: caches | 801 | /* Removing the host will perform an orderly shutdown: caches |
841 | * synchronized, disks spun down, etc. | 802 | * synchronized, disks spun down, etc. |
@@ -862,28 +823,52 @@ static void release_everything(struct us_data *us) | |||
862 | scsi_host_put(us_to_host(us)); | 823 | scsi_host_put(us_to_host(us)); |
863 | } | 824 | } |
864 | 825 | ||
865 | /* Delayed-work routine to carry out SCSI-device scanning */ | 826 | /* Thread to carry out delayed SCSI-device scanning */ |
866 | static void usb_stor_scan_dwork(struct work_struct *work) | 827 | static int usb_stor_scan_thread(void * __us) |
867 | { | 828 | { |
868 | struct us_data *us = container_of(work, struct us_data, | 829 | struct us_data *us = (struct us_data *)__us; |
869 | scan_dwork.work); | ||
870 | struct device *dev = &us->pusb_intf->dev; | 830 | struct device *dev = &us->pusb_intf->dev; |
871 | 831 | ||
872 | dev_dbg(dev, "starting scan\n"); | 832 | dev_dbg(dev, "device found\n"); |
873 | 833 | ||
874 | /* For bulk-only devices, determine the max LUN value */ | 834 | set_freezable_with_signal(); |
875 | if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) { | 835 | /* |
876 | mutex_lock(&us->dev_mutex); | 836 | * Wait for the timeout to expire or for a disconnect |
877 | us->max_lun = usb_stor_Bulk_max_lun(us); | 837 | * |
878 | mutex_unlock(&us->dev_mutex); | 838 | * We can't freeze in this thread or we risk causing khubd to |
839 | * fail to freeze, but we can't be non-freezable either. Nor can | ||
840 | * khubd freeze while waiting for scanning to complete as it may | ||
841 | * hold the device lock, causing a hang when suspending devices. | ||
842 | * So we request a fake signal when freezing and use | ||
843 | * interruptible sleep to kick us out of our wait early when | ||
844 | * freezing happens. | ||
845 | */ | ||
846 | if (delay_use > 0) { | ||
847 | dev_dbg(dev, "waiting for device to settle " | ||
848 | "before scanning\n"); | ||
849 | wait_event_interruptible_timeout(us->delay_wait, | ||
850 | test_bit(US_FLIDX_DONT_SCAN, &us->dflags), | ||
851 | delay_use * HZ); | ||
879 | } | 852 | } |
880 | scsi_scan_host(us_to_host(us)); | ||
881 | dev_dbg(dev, "scan complete\n"); | ||
882 | 853 | ||
883 | /* Should we unbind if no devices were detected? */ | 854 | /* If the device is still connected, perform the scanning */ |
855 | if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags)) { | ||
856 | |||
857 | /* For bulk-only devices, determine the max LUN value */ | ||
858 | if (us->protocol == USB_PR_BULK && | ||
859 | !(us->fflags & US_FL_SINGLE_LUN)) { | ||
860 | mutex_lock(&us->dev_mutex); | ||
861 | us->max_lun = usb_stor_Bulk_max_lun(us); | ||
862 | mutex_unlock(&us->dev_mutex); | ||
863 | } | ||
864 | scsi_scan_host(us_to_host(us)); | ||
865 | dev_dbg(dev, "scan complete\n"); | ||
866 | |||
867 | /* Should we unbind if no devices were detected? */ | ||
868 | } | ||
884 | 869 | ||
885 | usb_autopm_put_interface(us->pusb_intf); | 870 | usb_autopm_put_interface(us->pusb_intf); |
886 | clear_bit(US_FLIDX_SCAN_PENDING, &us->dflags); | 871 | complete_and_exit(&us->scanning_done, 0); |
887 | } | 872 | } |
888 | 873 | ||
889 | static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf) | 874 | static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf) |
@@ -925,12 +910,12 @@ int usb_stor_probe1(struct us_data **pus, | |||
925 | host->max_cmd_len = 16; | 910 | host->max_cmd_len = 16; |
926 | host->sg_tablesize = usb_stor_sg_tablesize(intf); | 911 | host->sg_tablesize = usb_stor_sg_tablesize(intf); |
927 | *pus = us = host_to_us(host); | 912 | *pus = us = host_to_us(host); |
913 | memset(us, 0, sizeof(struct us_data)); | ||
928 | mutex_init(&(us->dev_mutex)); | 914 | mutex_init(&(us->dev_mutex)); |
929 | us_set_lock_class(&us->dev_mutex, intf); | ||
930 | init_completion(&us->cmnd_ready); | 915 | init_completion(&us->cmnd_ready); |
931 | init_completion(&(us->notify)); | 916 | init_completion(&(us->notify)); |
932 | init_waitqueue_head(&us->delay_wait); | 917 | init_waitqueue_head(&us->delay_wait); |
933 | INIT_DELAYED_WORK(&us->scan_dwork, usb_stor_scan_dwork); | 918 | init_completion(&us->scanning_done); |
934 | 919 | ||
935 | /* Associate the us_data structure with the USB device */ | 920 | /* Associate the us_data structure with the USB device */ |
936 | result = associate_dev(us, intf); | 921 | result = associate_dev(us, intf); |
@@ -961,6 +946,7 @@ EXPORT_SYMBOL_GPL(usb_stor_probe1); | |||
961 | /* Second part of general USB mass-storage probing */ | 946 | /* Second part of general USB mass-storage probing */ |
962 | int usb_stor_probe2(struct us_data *us) | 947 | int usb_stor_probe2(struct us_data *us) |
963 | { | 948 | { |
949 | struct task_struct *th; | ||
964 | int result; | 950 | int result; |
965 | struct device *dev = &us->pusb_intf->dev; | 951 | struct device *dev = &us->pusb_intf->dev; |
966 | 952 | ||
@@ -1001,14 +987,20 @@ int usb_stor_probe2(struct us_data *us) | |||
1001 | goto BadDevice; | 987 | goto BadDevice; |
1002 | } | 988 | } |
1003 | 989 | ||
1004 | /* Submit the delayed_work for SCSI-device scanning */ | 990 | /* Start up the thread for delayed SCSI-device scanning */ |
991 | th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan"); | ||
992 | if (IS_ERR(th)) { | ||
993 | dev_warn(dev, | ||
994 | "Unable to start the device-scanning thread\n"); | ||
995 | complete(&us->scanning_done); | ||
996 | quiesce_and_remove_host(us); | ||
997 | result = PTR_ERR(th); | ||
998 | goto BadDevice; | ||
999 | } | ||
1000 | |||
1005 | usb_autopm_get_interface_no_resume(us->pusb_intf); | 1001 | usb_autopm_get_interface_no_resume(us->pusb_intf); |
1006 | set_bit(US_FLIDX_SCAN_PENDING, &us->dflags); | 1002 | wake_up_process(th); |
1007 | 1003 | ||
1008 | if (delay_use > 0) | ||
1009 | dev_dbg(dev, "waiting for device to settle before scanning\n"); | ||
1010 | queue_delayed_work(system_freezable_wq, &us->scan_dwork, | ||
1011 | delay_use * HZ); | ||
1012 | return 0; | 1004 | return 0; |
1013 | 1005 | ||
1014 | /* We come here if there are any problems */ | 1006 | /* We come here if there are any problems */ |
@@ -1034,16 +1026,17 @@ EXPORT_SYMBOL_GPL(usb_stor_disconnect); | |||
1034 | static int storage_probe(struct usb_interface *intf, | 1026 | static int storage_probe(struct usb_interface *intf, |
1035 | const struct usb_device_id *id) | 1027 | const struct usb_device_id *id) |
1036 | { | 1028 | { |
1037 | struct us_unusual_dev *unusual_dev; | ||
1038 | struct us_data *us; | 1029 | struct us_data *us; |
1039 | int result; | 1030 | int result; |
1040 | int size; | ||
1041 | 1031 | ||
1042 | /* | 1032 | /* |
1033 | * If libusual is configured, let it decide whether a standard | ||
1034 | * device should be handled by usb-storage or by ub. | ||
1043 | * If the device isn't standard (is handled by a subdriver | 1035 | * If the device isn't standard (is handled by a subdriver |
1044 | * module) then don't accept it. | 1036 | * module) then don't accept it. |
1045 | */ | 1037 | */ |
1046 | if (usb_usual_ignore_device(intf)) | 1038 | if (usb_usual_check_type(id, USB_US_TYPE_STOR) || |
1039 | usb_usual_ignore_device(intf)) | ||
1047 | return -ENXIO; | 1040 | return -ENXIO; |
1048 | 1041 | ||
1049 | /* | 1042 | /* |
@@ -1053,19 +1046,8 @@ static int storage_probe(struct usb_interface *intf, | |||
1053 | * table, so we use the index of the id entry to find the | 1046 | * table, so we use the index of the id entry to find the |
1054 | * corresponding unusual_devs entry. | 1047 | * corresponding unusual_devs entry. |
1055 | */ | 1048 | */ |
1056 | 1049 | result = usb_stor_probe1(&us, intf, id, | |
1057 | size = ARRAY_SIZE(us_unusual_dev_list); | 1050 | (id - usb_storage_usb_ids) + us_unusual_dev_list); |
1058 | if (id >= usb_storage_usb_ids && id < usb_storage_usb_ids + size) { | ||
1059 | unusual_dev = (id - usb_storage_usb_ids) + us_unusual_dev_list; | ||
1060 | } else { | ||
1061 | unusual_dev = &for_dynamic_ids; | ||
1062 | |||
1063 | US_DEBUGP("%s %s 0x%04x 0x%04x\n", "Use Bulk-Only transport", | ||
1064 | "with the Transparent SCSI protocol for dynamic id:", | ||
1065 | id->idVendor, id->idProduct); | ||
1066 | } | ||
1067 | |||
1068 | result = usb_stor_probe1(&us, intf, id, unusual_dev); | ||
1069 | if (result) | 1051 | if (result) |
1070 | return result; | 1052 | return result; |
1071 | 1053 | ||
@@ -1091,6 +1073,7 @@ static struct usb_driver usb_storage_driver = { | |||
1091 | .id_table = usb_storage_usb_ids, | 1073 | .id_table = usb_storage_usb_ids, |
1092 | .supports_autosuspend = 1, | 1074 | .supports_autosuspend = 1, |
1093 | .soft_unbind = 1, | 1075 | .soft_unbind = 1, |
1076 | .no_dynamic_id = 1, | ||
1094 | }; | 1077 | }; |
1095 | 1078 | ||
1096 | static int __init usb_stor_init(void) | 1079 | static int __init usb_stor_init(void) |
@@ -1101,8 +1084,10 @@ static int __init usb_stor_init(void) | |||
1101 | 1084 | ||
1102 | /* register the driver, return usb_register return code if error */ | 1085 | /* register the driver, return usb_register return code if error */ |
1103 | retval = usb_register(&usb_storage_driver); | 1086 | retval = usb_register(&usb_storage_driver); |
1104 | if (retval == 0) | 1087 | if (retval == 0) { |
1105 | pr_info("USB Mass Storage support registered.\n"); | 1088 | pr_info("USB Mass Storage support registered.\n"); |
1089 | usb_usual_set_present(USB_US_TYPE_STOR); | ||
1090 | } | ||
1106 | return retval; | 1091 | return retval; |
1107 | } | 1092 | } |
1108 | 1093 | ||
@@ -1116,6 +1101,8 @@ static void __exit usb_stor_exit(void) | |||
1116 | */ | 1101 | */ |
1117 | US_DEBUGP("-- calling usb_deregister()\n"); | 1102 | US_DEBUGP("-- calling usb_deregister()\n"); |
1118 | usb_deregister(&usb_storage_driver) ; | 1103 | usb_deregister(&usb_storage_driver) ; |
1104 | |||
1105 | usb_usual_clear_present(USB_US_TYPE_STOR); | ||
1119 | } | 1106 | } |
1120 | 1107 | ||
1121 | module_init(usb_stor_init); | 1108 | module_init(usb_stor_init); |
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 75f70f04f37..7b0f2113632 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/blkdev.h> | 47 | #include <linux/blkdev.h> |
48 | #include <linux/completion.h> | 48 | #include <linux/completion.h> |
49 | #include <linux/mutex.h> | 49 | #include <linux/mutex.h> |
50 | #include <linux/workqueue.h> | ||
51 | #include <scsi/scsi_host.h> | 50 | #include <scsi/scsi_host.h> |
52 | 51 | ||
53 | struct us_data; | 52 | struct us_data; |
@@ -73,7 +72,7 @@ struct us_unusual_dev { | |||
73 | #define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */ | 72 | #define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */ |
74 | #define US_FLIDX_RESETTING 4 /* device reset in progress */ | 73 | #define US_FLIDX_RESETTING 4 /* device reset in progress */ |
75 | #define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ | 74 | #define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ |
76 | #define US_FLIDX_SCAN_PENDING 6 /* scanning not yet done */ | 75 | #define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */ |
77 | #define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */ | 76 | #define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */ |
78 | #define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */ | 77 | #define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */ |
79 | 78 | ||
@@ -148,8 +147,8 @@ struct us_data { | |||
148 | /* mutual exclusion and synchronization structures */ | 147 | /* mutual exclusion and synchronization structures */ |
149 | struct completion cmnd_ready; /* to sleep thread on */ | 148 | struct completion cmnd_ready; /* to sleep thread on */ |
150 | struct completion notify; /* thread begin/end */ | 149 | struct completion notify; /* thread begin/end */ |
151 | wait_queue_head_t delay_wait; /* wait during reset */ | 150 | wait_queue_head_t delay_wait; /* wait during scan, reset */ |
152 | struct delayed_work scan_dwork; /* for async scanning */ | 151 | struct completion scanning_done; /* wait for scan thread */ |
153 | 152 | ||
154 | /* subdriver information */ | 153 | /* subdriver information */ |
155 | void *extra; /* Any extra data */ | 154 | void *extra; /* Any extra data */ |
diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c index b78a526910f..b96927914f8 100644 --- a/drivers/usb/storage/usual-tables.c +++ b/drivers/usb/storage/usual-tables.c | |||
@@ -34,23 +34,31 @@ | |||
34 | vendorName, productName, useProtocol, useTransport, \ | 34 | vendorName, productName, useProtocol, useTransport, \ |
35 | initFunction, flags) \ | 35 | initFunction, flags) \ |
36 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | 36 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ |
37 | .driver_info = (flags) } | 37 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } |
38 | 38 | ||
39 | #define COMPLIANT_DEV UNUSUAL_DEV | 39 | #define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ |
40 | vendorName, productName, useProtocol, useTransport, \ | ||
41 | initFunction, flags) \ | ||
42 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
43 | .driver_info = (flags) } | ||
40 | 44 | ||
41 | #define USUAL_DEV(useProto, useTrans) \ | 45 | #define USUAL_DEV(useProto, useTrans, useType) \ |
42 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans) } | 46 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ |
47 | .driver_info = ((useType)<<24) } | ||
43 | 48 | ||
44 | struct usb_device_id usb_storage_usb_ids[] = { | 49 | struct usb_device_id usb_storage_usb_ids[] = { |
45 | # include "unusual_devs.h" | 50 | # include "unusual_devs.h" |
46 | { } /* Terminating entry */ | 51 | { } /* Terminating entry */ |
47 | }; | 52 | }; |
53 | EXPORT_SYMBOL_GPL(usb_storage_usb_ids); | ||
54 | |||
48 | MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids); | 55 | MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids); |
49 | 56 | ||
50 | #undef UNUSUAL_DEV | 57 | #undef UNUSUAL_DEV |
51 | #undef COMPLIANT_DEV | 58 | #undef COMPLIANT_DEV |
52 | #undef USUAL_DEV | 59 | #undef USUAL_DEV |
53 | 60 | ||
61 | |||
54 | /* | 62 | /* |
55 | * The table of devices to ignore | 63 | * The table of devices to ignore |
56 | */ | 64 | */ |
@@ -87,6 +95,7 @@ static struct ignore_entry ignore_ids[] = { | |||
87 | 95 | ||
88 | #undef UNUSUAL_DEV | 96 | #undef UNUSUAL_DEV |
89 | 97 | ||
98 | |||
90 | /* Return an error if a device is in the ignore_ids list */ | 99 | /* Return an error if a device is in the ignore_ids list */ |
91 | int usb_usual_ignore_device(struct usb_interface *intf) | 100 | int usb_usual_ignore_device(struct usb_interface *intf) |
92 | { | 101 | { |
@@ -106,3 +115,4 @@ int usb_usual_ignore_device(struct usb_interface *intf) | |||
106 | } | 115 | } |
107 | return 0; | 116 | return 0; |
108 | } | 117 | } |
118 | EXPORT_SYMBOL_GPL(usb_usual_ignore_device); | ||