diff options
Diffstat (limited to 'drivers/usb/storage/usb.c')
-rw-r--r-- | drivers/usb/storage/usb.c | 209 |
1 files changed, 111 insertions, 98 deletions
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index b01dade63cb3..490ea761398c 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Developed with the assistance of: | 6 | * Developed with the assistance of: |
7 | * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org) | 7 | * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org) |
8 | * (c) 2003 Alan Stern (stern@rowland.harvard.edu) | 8 | * (c) 2003-2009 Alan Stern (stern@rowland.harvard.edu) |
9 | * | 9 | * |
10 | * Initial work by: | 10 | * Initial work by: |
11 | * (c) 1999 Michael Gee (michael@linuxspecific.com) | 11 | * (c) 1999 Michael Gee (michael@linuxspecific.com) |
@@ -118,36 +118,8 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks"); | |||
118 | 118 | ||
119 | /* | 119 | /* |
120 | * The entries in this table correspond, line for line, | 120 | * The entries in this table correspond, line for line, |
121 | * with the entries of us_unusual_dev_list[]. | 121 | * with the entries in usb_storage_usb_ids[], defined in usual-tables.c. |
122 | */ | 122 | */ |
123 | #ifndef CONFIG_USB_LIBUSUAL | ||
124 | |||
125 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
126 | vendorName, productName,useProtocol, useTransport, \ | ||
127 | initFunction, flags) \ | ||
128 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ | ||
129 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
130 | |||
131 | #define COMPLIANT_DEV UNUSUAL_DEV | ||
132 | |||
133 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
134 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
135 | .driver_info = (USB_US_TYPE_STOR<<24) } | ||
136 | |||
137 | static struct usb_device_id storage_usb_ids [] = { | ||
138 | |||
139 | # include "unusual_devs.h" | ||
140 | #undef UNUSUAL_DEV | ||
141 | #undef COMPLIANT_DEV | ||
142 | #undef USUAL_DEV | ||
143 | /* Terminating entry */ | ||
144 | { } | ||
145 | }; | ||
146 | |||
147 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); | ||
148 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
149 | |||
150 | /* This is the list of devices we recognize, along with their flag data */ | ||
151 | 123 | ||
152 | /* The vendor name should be kept at eight characters or less, and | 124 | /* The vendor name should be kept at eight characters or less, and |
153 | * the product name should be kept at 16 characters or less. If a device | 125 | * the product name should be kept at 16 characters or less. If a device |
@@ -179,18 +151,17 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
179 | 151 | ||
180 | static struct us_unusual_dev us_unusual_dev_list[] = { | 152 | static struct us_unusual_dev us_unusual_dev_list[] = { |
181 | # include "unusual_devs.h" | 153 | # include "unusual_devs.h" |
182 | # undef UNUSUAL_DEV | 154 | { } /* Terminating entry */ |
183 | # undef COMPLIANT_DEV | ||
184 | # undef USUAL_DEV | ||
185 | |||
186 | /* Terminating entry */ | ||
187 | { NULL } | ||
188 | }; | 155 | }; |
189 | 156 | ||
157 | #undef UNUSUAL_DEV | ||
158 | #undef COMPLIANT_DEV | ||
159 | #undef USUAL_DEV | ||
160 | |||
190 | 161 | ||
191 | #ifdef CONFIG_PM /* Minimal support for suspend and resume */ | 162 | #ifdef CONFIG_PM /* Minimal support for suspend and resume */ |
192 | 163 | ||
193 | static int storage_suspend(struct usb_interface *iface, pm_message_t message) | 164 | int usb_stor_suspend(struct usb_interface *iface, pm_message_t message) |
194 | { | 165 | { |
195 | struct us_data *us = usb_get_intfdata(iface); | 166 | struct us_data *us = usb_get_intfdata(iface); |
196 | 167 | ||
@@ -207,8 +178,9 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) | |||
207 | mutex_unlock(&us->dev_mutex); | 178 | mutex_unlock(&us->dev_mutex); |
208 | return 0; | 179 | return 0; |
209 | } | 180 | } |
181 | EXPORT_SYMBOL_GPL(usb_stor_suspend); | ||
210 | 182 | ||
211 | static int storage_resume(struct usb_interface *iface) | 183 | int usb_stor_resume(struct usb_interface *iface) |
212 | { | 184 | { |
213 | struct us_data *us = usb_get_intfdata(iface); | 185 | struct us_data *us = usb_get_intfdata(iface); |
214 | 186 | ||
@@ -221,8 +193,9 @@ static int storage_resume(struct usb_interface *iface) | |||
221 | mutex_unlock(&us->dev_mutex); | 193 | mutex_unlock(&us->dev_mutex); |
222 | return 0; | 194 | return 0; |
223 | } | 195 | } |
196 | EXPORT_SYMBOL_GPL(usb_stor_resume); | ||
224 | 197 | ||
225 | static int storage_reset_resume(struct usb_interface *iface) | 198 | int usb_stor_reset_resume(struct usb_interface *iface) |
226 | { | 199 | { |
227 | struct us_data *us = usb_get_intfdata(iface); | 200 | struct us_data *us = usb_get_intfdata(iface); |
228 | 201 | ||
@@ -235,6 +208,7 @@ static int storage_reset_resume(struct usb_interface *iface) | |||
235 | * the device */ | 208 | * the device */ |
236 | return 0; | 209 | return 0; |
237 | } | 210 | } |
211 | EXPORT_SYMBOL_GPL(usb_stor_reset_resume); | ||
238 | 212 | ||
239 | #endif /* CONFIG_PM */ | 213 | #endif /* CONFIG_PM */ |
240 | 214 | ||
@@ -243,7 +217,7 @@ static int storage_reset_resume(struct usb_interface *iface) | |||
243 | * a USB port reset, whether from this driver or a different one. | 217 | * a USB port reset, whether from this driver or a different one. |
244 | */ | 218 | */ |
245 | 219 | ||
246 | static int storage_pre_reset(struct usb_interface *iface) | 220 | int usb_stor_pre_reset(struct usb_interface *iface) |
247 | { | 221 | { |
248 | struct us_data *us = usb_get_intfdata(iface); | 222 | struct us_data *us = usb_get_intfdata(iface); |
249 | 223 | ||
@@ -253,8 +227,9 @@ static int storage_pre_reset(struct usb_interface *iface) | |||
253 | mutex_lock(&us->dev_mutex); | 227 | mutex_lock(&us->dev_mutex); |
254 | return 0; | 228 | return 0; |
255 | } | 229 | } |
230 | EXPORT_SYMBOL_GPL(usb_stor_pre_reset); | ||
256 | 231 | ||
257 | static int storage_post_reset(struct usb_interface *iface) | 232 | int usb_stor_post_reset(struct usb_interface *iface) |
258 | { | 233 | { |
259 | struct us_data *us = usb_get_intfdata(iface); | 234 | struct us_data *us = usb_get_intfdata(iface); |
260 | 235 | ||
@@ -269,6 +244,7 @@ static int storage_post_reset(struct usb_interface *iface) | |||
269 | mutex_unlock(&us->dev_mutex); | 244 | mutex_unlock(&us->dev_mutex); |
270 | return 0; | 245 | return 0; |
271 | } | 246 | } |
247 | EXPORT_SYMBOL_GPL(usb_stor_post_reset); | ||
272 | 248 | ||
273 | /* | 249 | /* |
274 | * fill_inquiry_response takes an unsigned char array (which must | 250 | * fill_inquiry_response takes an unsigned char array (which must |
@@ -311,6 +287,7 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data, | |||
311 | 287 | ||
312 | usb_stor_set_xfer_buf(data, data_len, us->srb); | 288 | usb_stor_set_xfer_buf(data, data_len, us->srb); |
313 | } | 289 | } |
290 | EXPORT_SYMBOL_GPL(fill_inquiry_response); | ||
314 | 291 | ||
315 | static int usb_stor_control_thread(void * __us) | 292 | static int usb_stor_control_thread(void * __us) |
316 | { | 293 | { |
@@ -551,20 +528,13 @@ static void adjust_quirks(struct us_data *us) | |||
551 | vid, pid, f); | 528 | vid, pid, f); |
552 | } | 529 | } |
553 | 530 | ||
554 | /* Find an unusual_dev descriptor (always succeeds in the current code) */ | ||
555 | static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) | ||
556 | { | ||
557 | const int id_index = id - storage_usb_ids; | ||
558 | return &us_unusual_dev_list[id_index]; | ||
559 | } | ||
560 | |||
561 | /* Get the unusual_devs entries and the string descriptors */ | 531 | /* Get the unusual_devs entries and the string descriptors */ |
562 | static int get_device_info(struct us_data *us, const struct usb_device_id *id) | 532 | static int get_device_info(struct us_data *us, const struct usb_device_id *id, |
533 | struct us_unusual_dev *unusual_dev) | ||
563 | { | 534 | { |
564 | struct usb_device *dev = us->pusb_dev; | 535 | struct usb_device *dev = us->pusb_dev; |
565 | struct usb_interface_descriptor *idesc = | 536 | struct usb_interface_descriptor *idesc = |
566 | &us->pusb_intf->cur_altsetting->desc; | 537 | &us->pusb_intf->cur_altsetting->desc; |
567 | struct us_unusual_dev *unusual_dev = find_unusual(id); | ||
568 | 538 | ||
569 | /* Store the entries */ | 539 | /* Store the entries */ |
570 | us->unusual_dev = unusual_dev; | 540 | us->unusual_dev = unusual_dev; |
@@ -629,7 +599,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) | |||
629 | } | 599 | } |
630 | 600 | ||
631 | /* Get the transport settings */ | 601 | /* Get the transport settings */ |
632 | static int get_transport(struct us_data *us) | 602 | static void get_transport(struct us_data *us) |
633 | { | 603 | { |
634 | switch (us->protocol) { | 604 | switch (us->protocol) { |
635 | case US_PR_CB: | 605 | case US_PR_CB: |
@@ -732,19 +702,11 @@ static int get_transport(struct us_data *us) | |||
732 | break; | 702 | break; |
733 | #endif | 703 | #endif |
734 | 704 | ||
735 | default: | ||
736 | return -EIO; | ||
737 | } | 705 | } |
738 | US_DEBUGP("Transport: %s\n", us->transport_name); | ||
739 | |||
740 | /* fix for single-lun devices */ | ||
741 | if (us->fflags & US_FL_SINGLE_LUN) | ||
742 | us->max_lun = 0; | ||
743 | return 0; | ||
744 | } | 706 | } |
745 | 707 | ||
746 | /* Get the protocol settings */ | 708 | /* Get the protocol settings */ |
747 | static int get_protocol(struct us_data *us) | 709 | static void get_protocol(struct us_data *us) |
748 | { | 710 | { |
749 | switch (us->subclass) { | 711 | switch (us->subclass) { |
750 | case US_SC_RBC: | 712 | case US_SC_RBC: |
@@ -794,11 +756,7 @@ static int get_protocol(struct us_data *us) | |||
794 | break; | 756 | break; |
795 | #endif | 757 | #endif |
796 | 758 | ||
797 | default: | ||
798 | return -EIO; | ||
799 | } | 759 | } |
800 | US_DEBUGP("Protocol: %s\n", us->protocol_name); | ||
801 | return 0; | ||
802 | } | 760 | } |
803 | 761 | ||
804 | /* Get the pipe settings */ | 762 | /* Get the pipe settings */ |
@@ -1012,17 +970,15 @@ static int usb_stor_scan_thread(void * __us) | |||
1012 | } | 970 | } |
1013 | 971 | ||
1014 | 972 | ||
1015 | /* Probe to see if we can drive a newly-connected USB device */ | 973 | /* First part of general USB mass-storage probing */ |
1016 | static int storage_probe(struct usb_interface *intf, | 974 | int usb_stor_probe1(struct us_data **pus, |
1017 | const struct usb_device_id *id) | 975 | struct usb_interface *intf, |
976 | const struct usb_device_id *id, | ||
977 | struct us_unusual_dev *unusual_dev) | ||
1018 | { | 978 | { |
1019 | struct Scsi_Host *host; | 979 | struct Scsi_Host *host; |
1020 | struct us_data *us; | 980 | struct us_data *us; |
1021 | int result; | 981 | int result; |
1022 | struct task_struct *th; | ||
1023 | |||
1024 | if (usb_usual_check_type(id, USB_US_TYPE_STOR)) | ||
1025 | return -ENXIO; | ||
1026 | 982 | ||
1027 | US_DEBUGP("USB Mass Storage device detected\n"); | 983 | US_DEBUGP("USB Mass Storage device detected\n"); |
1028 | 984 | ||
@@ -1041,7 +997,7 @@ static int storage_probe(struct usb_interface *intf, | |||
1041 | * Allow 16-byte CDBs and thus > 2TB | 997 | * Allow 16-byte CDBs and thus > 2TB |
1042 | */ | 998 | */ |
1043 | host->max_cmd_len = 16; | 999 | host->max_cmd_len = 16; |
1044 | us = host_to_us(host); | 1000 | *pus = us = host_to_us(host); |
1045 | memset(us, 0, sizeof(struct us_data)); | 1001 | memset(us, 0, sizeof(struct us_data)); |
1046 | mutex_init(&(us->dev_mutex)); | 1002 | mutex_init(&(us->dev_mutex)); |
1047 | init_completion(&us->cmnd_ready); | 1003 | init_completion(&us->cmnd_ready); |
@@ -1054,24 +1010,46 @@ static int storage_probe(struct usb_interface *intf, | |||
1054 | if (result) | 1010 | if (result) |
1055 | goto BadDevice; | 1011 | goto BadDevice; |
1056 | 1012 | ||
1057 | /* | 1013 | /* Get the unusual_devs entries and the descriptors */ |
1058 | * Get the unusual_devs entries and the descriptors | 1014 | result = get_device_info(us, id, unusual_dev); |
1059 | * | ||
1060 | * id_index is calculated in the declaration to be the index number | ||
1061 | * of the match from the usb_device_id table, so we can find the | ||
1062 | * corresponding entry in the private table. | ||
1063 | */ | ||
1064 | result = get_device_info(us, id); | ||
1065 | if (result) | 1015 | if (result) |
1066 | goto BadDevice; | 1016 | goto BadDevice; |
1067 | 1017 | ||
1068 | /* Get the transport, protocol, and pipe settings */ | 1018 | /* Get standard transport and protocol settings */ |
1069 | result = get_transport(us); | 1019 | get_transport(us); |
1070 | if (result) | 1020 | get_protocol(us); |
1071 | goto BadDevice; | 1021 | |
1072 | result = get_protocol(us); | 1022 | /* Give the caller a chance to fill in specialized transport |
1073 | if (result) | 1023 | * or protocol settings. |
1024 | */ | ||
1025 | return 0; | ||
1026 | |||
1027 | BadDevice: | ||
1028 | US_DEBUGP("storage_probe() failed\n"); | ||
1029 | release_everything(us); | ||
1030 | return result; | ||
1031 | } | ||
1032 | EXPORT_SYMBOL_GPL(usb_stor_probe1); | ||
1033 | |||
1034 | /* Second part of general USB mass-storage probing */ | ||
1035 | int usb_stor_probe2(struct us_data *us) | ||
1036 | { | ||
1037 | struct task_struct *th; | ||
1038 | int result; | ||
1039 | |||
1040 | /* Make sure the transport and protocol have both been set */ | ||
1041 | if (!us->transport || !us->proto_handler) { | ||
1042 | result = -ENXIO; | ||
1074 | goto BadDevice; | 1043 | goto BadDevice; |
1044 | } | ||
1045 | US_DEBUGP("Transport: %s\n", us->transport_name); | ||
1046 | US_DEBUGP("Protocol: %s\n", us->protocol_name); | ||
1047 | |||
1048 | /* fix for single-lun devices */ | ||
1049 | if (us->fflags & US_FL_SINGLE_LUN) | ||
1050 | us->max_lun = 0; | ||
1051 | |||
1052 | /* Find the endpoints and calculate pipe values */ | ||
1075 | result = get_pipes(us); | 1053 | result = get_pipes(us); |
1076 | if (result) | 1054 | if (result) |
1077 | goto BadDevice; | 1055 | goto BadDevice; |
@@ -1080,7 +1058,7 @@ static int storage_probe(struct usb_interface *intf, | |||
1080 | result = usb_stor_acquire_resources(us); | 1058 | result = usb_stor_acquire_resources(us); |
1081 | if (result) | 1059 | if (result) |
1082 | goto BadDevice; | 1060 | goto BadDevice; |
1083 | result = scsi_add_host(host, &intf->dev); | 1061 | result = scsi_add_host(us_to_host(us), &us->pusb_intf->dev); |
1084 | if (result) { | 1062 | if (result) { |
1085 | printk(KERN_WARNING USB_STORAGE | 1063 | printk(KERN_WARNING USB_STORAGE |
1086 | "Unable to add the scsi host\n"); | 1064 | "Unable to add the scsi host\n"); |
@@ -1108,9 +1086,10 @@ BadDevice: | |||
1108 | release_everything(us); | 1086 | release_everything(us); |
1109 | return result; | 1087 | return result; |
1110 | } | 1088 | } |
1089 | EXPORT_SYMBOL_GPL(usb_stor_probe2); | ||
1111 | 1090 | ||
1112 | /* Handle a disconnect event from the USB core */ | 1091 | /* Handle a USB mass-storage disconnect */ |
1113 | static void storage_disconnect(struct usb_interface *intf) | 1092 | void usb_stor_disconnect(struct usb_interface *intf) |
1114 | { | 1093 | { |
1115 | struct us_data *us = usb_get_intfdata(intf); | 1094 | struct us_data *us = usb_get_intfdata(intf); |
1116 | 1095 | ||
@@ -1118,6 +1097,42 @@ static void storage_disconnect(struct usb_interface *intf) | |||
1118 | quiesce_and_remove_host(us); | 1097 | quiesce_and_remove_host(us); |
1119 | release_everything(us); | 1098 | release_everything(us); |
1120 | } | 1099 | } |
1100 | EXPORT_SYMBOL_GPL(usb_stor_disconnect); | ||
1101 | |||
1102 | /* The main probe routine for standard devices */ | ||
1103 | static int storage_probe(struct usb_interface *intf, | ||
1104 | const struct usb_device_id *id) | ||
1105 | { | ||
1106 | struct us_data *us; | ||
1107 | int result; | ||
1108 | |||
1109 | /* | ||
1110 | * If libusual is configured, let it decide whether a standard | ||
1111 | * device should be handled by usb-storage or by ub. | ||
1112 | * If the device isn't standard (is handled by a subdriver | ||
1113 | * module) then don't accept it. | ||
1114 | */ | ||
1115 | if (usb_usual_check_type(id, USB_US_TYPE_STOR) || | ||
1116 | usb_usual_ignore_device(intf)) | ||
1117 | return -ENXIO; | ||
1118 | |||
1119 | /* | ||
1120 | * Call the general probe procedures. | ||
1121 | * | ||
1122 | * The unusual_dev_list array is parallel to the usb_storage_usb_ids | ||
1123 | * table, so we use the index of the id entry to find the | ||
1124 | * corresponding unusual_devs entry. | ||
1125 | */ | ||
1126 | result = usb_stor_probe1(&us, intf, id, | ||
1127 | (id - usb_storage_usb_ids) + us_unusual_dev_list); | ||
1128 | if (result) | ||
1129 | return result; | ||
1130 | |||
1131 | /* No special transport or protocol settings in the main module */ | ||
1132 | |||
1133 | result = usb_stor_probe2(us); | ||
1134 | return result; | ||
1135 | } | ||
1121 | 1136 | ||
1122 | /*********************************************************************** | 1137 | /*********************************************************************** |
1123 | * Initialization and registration | 1138 | * Initialization and registration |
@@ -1126,15 +1141,13 @@ static void storage_disconnect(struct usb_interface *intf) | |||
1126 | static struct usb_driver usb_storage_driver = { | 1141 | static struct usb_driver usb_storage_driver = { |
1127 | .name = "usb-storage", | 1142 | .name = "usb-storage", |
1128 | .probe = storage_probe, | 1143 | .probe = storage_probe, |
1129 | .disconnect = storage_disconnect, | 1144 | .disconnect = usb_stor_disconnect, |
1130 | #ifdef CONFIG_PM | 1145 | .suspend = usb_stor_suspend, |
1131 | .suspend = storage_suspend, | 1146 | .resume = usb_stor_resume, |
1132 | .resume = storage_resume, | 1147 | .reset_resume = usb_stor_reset_resume, |
1133 | .reset_resume = storage_reset_resume, | 1148 | .pre_reset = usb_stor_pre_reset, |
1134 | #endif | 1149 | .post_reset = usb_stor_post_reset, |
1135 | .pre_reset = storage_pre_reset, | 1150 | .id_table = usb_storage_usb_ids, |
1136 | .post_reset = storage_post_reset, | ||
1137 | .id_table = storage_usb_ids, | ||
1138 | .soft_unbind = 1, | 1151 | .soft_unbind = 1, |
1139 | }; | 1152 | }; |
1140 | 1153 | ||