diff options
Diffstat (limited to 'drivers/usb/storage/usb.c')
-rw-r--r-- | drivers/usb/storage/usb.c | 160 |
1 files changed, 56 insertions, 104 deletions
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 3847ebed2aa4..dbcf23980ff1 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -94,6 +94,9 @@ | |||
94 | #ifdef CONFIG_USB_STORAGE_ONETOUCH | 94 | #ifdef CONFIG_USB_STORAGE_ONETOUCH |
95 | #include "onetouch.h" | 95 | #include "onetouch.h" |
96 | #endif | 96 | #endif |
97 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
98 | #include "alauda.h" | ||
99 | #endif | ||
97 | 100 | ||
98 | /* Some informational data */ | 101 | /* Some informational data */ |
99 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); | 102 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); |
@@ -112,49 +115,33 @@ static atomic_t total_threads = ATOMIC_INIT(0); | |||
112 | static DECLARE_COMPLETION(threads_gone); | 115 | static DECLARE_COMPLETION(threads_gone); |
113 | 116 | ||
114 | 117 | ||
115 | /* The entries in this table, except for final ones here | 118 | /* |
116 | * (USB_MASS_STORAGE_CLASS and the empty entry), correspond, | 119 | * The entries in this table correspond, line for line, |
117 | * line for line with the entries of us_unsuaul_dev_list[]. | 120 | * with the entries of us_unusual_dev_list[]. |
118 | */ | 121 | */ |
122 | #ifndef CONFIG_USB_LIBUSUAL | ||
119 | 123 | ||
120 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | 124 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ |
121 | vendorName, productName,useProtocol, useTransport, \ | 125 | vendorName, productName,useProtocol, useTransport, \ |
122 | initFunction, flags) \ | 126 | initFunction, flags) \ |
123 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax) } | 127 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ |
128 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
129 | |||
130 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
131 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
132 | .driver_info = (USB_US_TYPE_STOR<<24) } | ||
124 | 133 | ||
125 | static struct usb_device_id storage_usb_ids [] = { | 134 | static struct usb_device_id storage_usb_ids [] = { |
126 | 135 | ||
127 | # include "unusual_devs.h" | 136 | # include "unusual_devs.h" |
128 | #undef UNUSUAL_DEV | 137 | #undef UNUSUAL_DEV |
129 | /* Control/Bulk transport for all SubClass values */ | 138 | #undef USUAL_DEV |
130 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CB) }, | ||
131 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CB) }, | ||
132 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CB) }, | ||
133 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CB) }, | ||
134 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CB) }, | ||
135 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CB) }, | ||
136 | |||
137 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
138 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CBI) }, | ||
139 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CBI) }, | ||
140 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CBI) }, | ||
141 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CBI) }, | ||
142 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CBI) }, | ||
143 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CBI) }, | ||
144 | |||
145 | /* Bulk-only transport for all SubClass values */ | ||
146 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_BULK) }, | ||
147 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_BULK) }, | ||
148 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_BULK) }, | ||
149 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_BULK) }, | ||
150 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_BULK) }, | ||
151 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, | ||
152 | |||
153 | /* Terminating entry */ | 139 | /* Terminating entry */ |
154 | { } | 140 | { } |
155 | }; | 141 | }; |
156 | 142 | ||
157 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); | 143 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); |
144 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
158 | 145 | ||
159 | /* This is the list of devices we recognize, along with their flag data */ | 146 | /* This is the list of devices we recognize, along with their flag data */ |
160 | 147 | ||
@@ -167,7 +154,6 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
167 | * are free to use as many characters as you like. | 154 | * are free to use as many characters as you like. |
168 | */ | 155 | */ |
169 | 156 | ||
170 | #undef UNUSUAL_DEV | ||
171 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | 157 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ |
172 | vendor_name, product_name, use_protocol, use_transport, \ | 158 | vendor_name, product_name, use_protocol, use_transport, \ |
173 | init_function, Flags) \ | 159 | init_function, Flags) \ |
@@ -177,53 +163,18 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
177 | .useProtocol = use_protocol, \ | 163 | .useProtocol = use_protocol, \ |
178 | .useTransport = use_transport, \ | 164 | .useTransport = use_transport, \ |
179 | .initFunction = init_function, \ | 165 | .initFunction = init_function, \ |
180 | .flags = Flags, \ | 166 | } |
167 | |||
168 | #define USUAL_DEV(use_protocol, use_transport, use_type) \ | ||
169 | { \ | ||
170 | .useProtocol = use_protocol, \ | ||
171 | .useTransport = use_transport, \ | ||
181 | } | 172 | } |
182 | 173 | ||
183 | static struct us_unusual_dev us_unusual_dev_list[] = { | 174 | static struct us_unusual_dev us_unusual_dev_list[] = { |
184 | # include "unusual_devs.h" | 175 | # include "unusual_devs.h" |
185 | # undef UNUSUAL_DEV | 176 | # undef UNUSUAL_DEV |
186 | /* Control/Bulk transport for all SubClass values */ | 177 | # undef USUAL_DEV |
187 | { .useProtocol = US_SC_RBC, | ||
188 | .useTransport = US_PR_CB}, | ||
189 | { .useProtocol = US_SC_8020, | ||
190 | .useTransport = US_PR_CB}, | ||
191 | { .useProtocol = US_SC_QIC, | ||
192 | .useTransport = US_PR_CB}, | ||
193 | { .useProtocol = US_SC_UFI, | ||
194 | .useTransport = US_PR_CB}, | ||
195 | { .useProtocol = US_SC_8070, | ||
196 | .useTransport = US_PR_CB}, | ||
197 | { .useProtocol = US_SC_SCSI, | ||
198 | .useTransport = US_PR_CB}, | ||
199 | |||
200 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
201 | { .useProtocol = US_SC_RBC, | ||
202 | .useTransport = US_PR_CBI}, | ||
203 | { .useProtocol = US_SC_8020, | ||
204 | .useTransport = US_PR_CBI}, | ||
205 | { .useProtocol = US_SC_QIC, | ||
206 | .useTransport = US_PR_CBI}, | ||
207 | { .useProtocol = US_SC_UFI, | ||
208 | .useTransport = US_PR_CBI}, | ||
209 | { .useProtocol = US_SC_8070, | ||
210 | .useTransport = US_PR_CBI}, | ||
211 | { .useProtocol = US_SC_SCSI, | ||
212 | .useTransport = US_PR_CBI}, | ||
213 | |||
214 | /* Bulk-only transport for all SubClass values */ | ||
215 | { .useProtocol = US_SC_RBC, | ||
216 | .useTransport = US_PR_BULK}, | ||
217 | { .useProtocol = US_SC_8020, | ||
218 | .useTransport = US_PR_BULK}, | ||
219 | { .useProtocol = US_SC_QIC, | ||
220 | .useTransport = US_PR_BULK}, | ||
221 | { .useProtocol = US_SC_UFI, | ||
222 | .useTransport = US_PR_BULK}, | ||
223 | { .useProtocol = US_SC_8070, | ||
224 | .useTransport = US_PR_BULK}, | ||
225 | { .useProtocol = US_SC_SCSI, | ||
226 | .useTransport = US_PR_BULK}, | ||
227 | 178 | ||
228 | /* Terminating entry */ | 179 | /* Terminating entry */ |
229 | { NULL } | 180 | { NULL } |
@@ -240,6 +191,8 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) | |||
240 | down(&us->dev_semaphore); | 191 | down(&us->dev_semaphore); |
241 | 192 | ||
242 | US_DEBUGP("%s\n", __FUNCTION__); | 193 | US_DEBUGP("%s\n", __FUNCTION__); |
194 | if (us->suspend_resume_hook) | ||
195 | (us->suspend_resume_hook)(us, US_SUSPEND); | ||
243 | iface->dev.power.power_state.event = message.event; | 196 | iface->dev.power.power_state.event = message.event; |
244 | 197 | ||
245 | /* When runtime PM is working, we'll set a flag to indicate | 198 | /* When runtime PM is working, we'll set a flag to indicate |
@@ -256,6 +209,8 @@ static int storage_resume(struct usb_interface *iface) | |||
256 | down(&us->dev_semaphore); | 209 | down(&us->dev_semaphore); |
257 | 210 | ||
258 | US_DEBUGP("%s\n", __FUNCTION__); | 211 | US_DEBUGP("%s\n", __FUNCTION__); |
212 | if (us->suspend_resume_hook) | ||
213 | (us->suspend_resume_hook)(us, US_RESUME); | ||
259 | iface->dev.power.power_state.event = PM_EVENT_ON; | 214 | iface->dev.power.power_state.event = PM_EVENT_ON; |
260 | 215 | ||
261 | up(&us->dev_semaphore); | 216 | up(&us->dev_semaphore); |
@@ -484,14 +439,20 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf) | |||
484 | return 0; | 439 | return 0; |
485 | } | 440 | } |
486 | 441 | ||
442 | /* Find an unusual_dev descriptor (always succeeds in the current code) */ | ||
443 | static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) | ||
444 | { | ||
445 | const int id_index = id - storage_usb_ids; | ||
446 | return &us_unusual_dev_list[id_index]; | ||
447 | } | ||
448 | |||
487 | /* Get the unusual_devs entries and the string descriptors */ | 449 | /* Get the unusual_devs entries and the string descriptors */ |
488 | static void get_device_info(struct us_data *us, int id_index) | 450 | static void get_device_info(struct us_data *us, const struct usb_device_id *id) |
489 | { | 451 | { |
490 | struct usb_device *dev = us->pusb_dev; | 452 | struct usb_device *dev = us->pusb_dev; |
491 | struct usb_interface_descriptor *idesc = | 453 | struct usb_interface_descriptor *idesc = |
492 | &us->pusb_intf->cur_altsetting->desc; | 454 | &us->pusb_intf->cur_altsetting->desc; |
493 | struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index]; | 455 | struct us_unusual_dev *unusual_dev = find_unusual(id); |
494 | struct usb_device_id *id = &storage_usb_ids[id_index]; | ||
495 | 456 | ||
496 | /* Store the entries */ | 457 | /* Store the entries */ |
497 | us->unusual_dev = unusual_dev; | 458 | us->unusual_dev = unusual_dev; |
@@ -501,7 +462,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
501 | us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ? | 462 | us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ? |
502 | idesc->bInterfaceProtocol : | 463 | idesc->bInterfaceProtocol : |
503 | unusual_dev->useTransport; | 464 | unusual_dev->useTransport; |
504 | us->flags = unusual_dev->flags; | 465 | us->flags = USB_US_ORIG_FLAGS(id->driver_info); |
505 | 466 | ||
506 | /* | 467 | /* |
507 | * This flag is only needed when we're in high-speed, so let's | 468 | * This flag is only needed when we're in high-speed, so let's |
@@ -516,7 +477,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
516 | * from the unusual_devs.h table. | 477 | * from the unusual_devs.h table. |
517 | */ | 478 | */ |
518 | if (id->idVendor || id->idProduct) { | 479 | if (id->idVendor || id->idProduct) { |
519 | static char *msgs[3] = { | 480 | static const char *msgs[3] = { |
520 | "an unneeded SubClass entry", | 481 | "an unneeded SubClass entry", |
521 | "an unneeded Protocol entry", | 482 | "an unneeded Protocol entry", |
522 | "unneeded SubClass and Protocol entries"}; | 483 | "unneeded SubClass and Protocol entries"}; |
@@ -529,7 +490,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
529 | if (unusual_dev->useTransport != US_PR_DEVICE && | 490 | if (unusual_dev->useTransport != US_PR_DEVICE && |
530 | us->protocol == idesc->bInterfaceProtocol) | 491 | us->protocol == idesc->bInterfaceProtocol) |
531 | msg += 2; | 492 | msg += 2; |
532 | if (msg >= 0 && !(unusual_dev->flags & US_FL_NEED_OVERRIDE)) | 493 | if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE)) |
533 | printk(KERN_NOTICE USB_STORAGE "This device " | 494 | printk(KERN_NOTICE USB_STORAGE "This device " |
534 | "(%04x,%04x,%04x S %02x P %02x)" | 495 | "(%04x,%04x,%04x S %02x P %02x)" |
535 | " has %s in unusual_devs.h\n" | 496 | " has %s in unusual_devs.h\n" |
@@ -686,6 +647,15 @@ static int get_protocol(struct us_data *us) | |||
686 | break; | 647 | break; |
687 | #endif | 648 | #endif |
688 | 649 | ||
650 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
651 | case US_PR_ALAUDA: | ||
652 | us->transport_name = "Alauda Control/Bulk"; | ||
653 | us->transport = alauda_transport; | ||
654 | us->transport_reset = usb_stor_Bulk_reset; | ||
655 | us->max_lun = 1; | ||
656 | break; | ||
657 | #endif | ||
658 | |||
689 | default: | 659 | default: |
690 | return -EIO; | 660 | return -EIO; |
691 | } | 661 | } |
@@ -921,10 +891,12 @@ static int storage_probe(struct usb_interface *intf, | |||
921 | { | 891 | { |
922 | struct Scsi_Host *host; | 892 | struct Scsi_Host *host; |
923 | struct us_data *us; | 893 | struct us_data *us; |
924 | const int id_index = id - storage_usb_ids; | ||
925 | int result; | 894 | int result; |
926 | struct task_struct *th; | 895 | struct task_struct *th; |
927 | 896 | ||
897 | if (usb_usual_check_type(id, USB_US_TYPE_STOR)) | ||
898 | return -ENXIO; | ||
899 | |||
928 | US_DEBUGP("USB Mass Storage device detected\n"); | 900 | US_DEBUGP("USB Mass Storage device detected\n"); |
929 | 901 | ||
930 | /* | 902 | /* |
@@ -957,29 +929,7 @@ static int storage_probe(struct usb_interface *intf, | |||
957 | * of the match from the usb_device_id table, so we can find the | 929 | * of the match from the usb_device_id table, so we can find the |
958 | * corresponding entry in the private table. | 930 | * corresponding entry in the private table. |
959 | */ | 931 | */ |
960 | get_device_info(us, id_index); | 932 | get_device_info(us, id); |
961 | |||
962 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
963 | if (us->protocol == US_PR_EUSB_SDDR09 || | ||
964 | us->protocol == US_PR_DPCM_USB) { | ||
965 | /* set the configuration -- STALL is an acceptable response here */ | ||
966 | if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) { | ||
967 | US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev | ||
968 | ->actconfig->desc.bConfigurationValue); | ||
969 | goto BadDevice; | ||
970 | } | ||
971 | result = usb_reset_configuration(us->pusb_dev); | ||
972 | |||
973 | US_DEBUGP("Result of usb_reset_configuration is %d\n", result); | ||
974 | if (result == -EPIPE) { | ||
975 | US_DEBUGP("-- stall on control interface\n"); | ||
976 | } else if (result != 0) { | ||
977 | /* it's not a stall, but another error -- time to bail */ | ||
978 | US_DEBUGP("-- Unknown error. Rejecting device\n"); | ||
979 | goto BadDevice; | ||
980 | } | ||
981 | } | ||
982 | #endif | ||
983 | 933 | ||
984 | /* Get the transport, protocol, and pipe settings */ | 934 | /* Get the transport, protocol, and pipe settings */ |
985 | result = get_transport(us); | 935 | result = get_transport(us); |
@@ -1044,7 +994,6 @@ static void storage_disconnect(struct usb_interface *intf) | |||
1044 | ***********************************************************************/ | 994 | ***********************************************************************/ |
1045 | 995 | ||
1046 | static struct usb_driver usb_storage_driver = { | 996 | static struct usb_driver usb_storage_driver = { |
1047 | .owner = THIS_MODULE, | ||
1048 | .name = "usb-storage", | 997 | .name = "usb-storage", |
1049 | .probe = storage_probe, | 998 | .probe = storage_probe, |
1050 | .disconnect = storage_disconnect, | 999 | .disconnect = storage_disconnect, |
@@ -1062,9 +1011,10 @@ static int __init usb_stor_init(void) | |||
1062 | 1011 | ||
1063 | /* register the driver, return usb_register return code if error */ | 1012 | /* register the driver, return usb_register return code if error */ |
1064 | retval = usb_register(&usb_storage_driver); | 1013 | retval = usb_register(&usb_storage_driver); |
1065 | if (retval == 0) | 1014 | if (retval == 0) { |
1066 | printk(KERN_INFO "USB Mass Storage support registered.\n"); | 1015 | printk(KERN_INFO "USB Mass Storage support registered.\n"); |
1067 | 1016 | usb_usual_set_present(USB_US_TYPE_STOR); | |
1017 | } | ||
1068 | return retval; | 1018 | return retval; |
1069 | } | 1019 | } |
1070 | 1020 | ||
@@ -1088,6 +1038,8 @@ static void __exit usb_stor_exit(void) | |||
1088 | wait_for_completion(&threads_gone); | 1038 | wait_for_completion(&threads_gone); |
1089 | atomic_dec(&total_threads); | 1039 | atomic_dec(&total_threads); |
1090 | } | 1040 | } |
1041 | |||
1042 | usb_usual_clear_present(USB_US_TYPE_STOR); | ||
1091 | } | 1043 | } |
1092 | 1044 | ||
1093 | module_init(usb_stor_init); | 1045 | module_init(usb_stor_init); |