aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage/usb.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-02-12 14:47:44 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-24 19:20:34 -0400
commite6e244b6cb1f70e7109381626293cd40a8334ed3 (patch)
treef3d1d9a23b603f9a4108799fb0a4fe21969dd695 /drivers/usb/storage/usb.c
parente4abe6658aa17a5d7e7321dfda807d287255511b (diff)
usb-storage: prepare for subdriver separation
This patch (as1206) is the first step in converting usb-storage's subdrivers into separate modules. It makes the following large-scale changes: Remove a bunch of unnecessary #ifdef's from usb_usual.h. Not truly necessary, but it does clean things up. Move the USB device-ID table (which is duplicated between libusual and usb-storage) into its own source file, usual-tables.c, and arrange for this to be linked with either libusual or usb-storage according to whether USB_LIBUSUAL is configured. Add to usual-tables.c a new usb_usual_ignore_device() function to detect whether a particular device needs to be managed by a subdriver and not by the standard handlers in usb-storage. Export a whole bunch of functions in usb-storage, renaming some of them because their names don't already begin with "usb_stor_". These functions will be needed by the new subdriver modules. Split usb-storage's probe routine into two functions. The subdrivers will call the probe1 routine, then fill in their transport and protocol settings, and then call the probe2 routine. Take the default cases and error checking out of get_transport() and get_protocol(), which run during probe1, and instead put a check for invalid transport or protocol values into the probe2 function. Add a new probe routine to be used for standard devices, i.e., those that don't need a subdriver. This new routine checks whether the device should be ignored (because it should be handled by ub or by a subdriver), and if not, calls the probe1 and probe2 functions. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> CC: Matthew Dharm <mdharm-usb@one-eyed-alien.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/storage/usb.c')
-rw-r--r--drivers/usb/storage/usb.c209
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
137static 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
147MODULE_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
180static struct us_unusual_dev us_unusual_dev_list[] = { 152static 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
193static int storage_suspend(struct usb_interface *iface, pm_message_t message) 164int 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}
181EXPORT_SYMBOL_GPL(usb_stor_suspend);
210 182
211static int storage_resume(struct usb_interface *iface) 183int 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}
196EXPORT_SYMBOL_GPL(usb_stor_resume);
224 197
225static int storage_reset_resume(struct usb_interface *iface) 198int 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}
211EXPORT_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
246static int storage_pre_reset(struct usb_interface *iface) 220int 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}
230EXPORT_SYMBOL_GPL(usb_stor_pre_reset);
256 231
257static int storage_post_reset(struct usb_interface *iface) 232int 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}
247EXPORT_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}
290EXPORT_SYMBOL_GPL(fill_inquiry_response);
314 291
315static int usb_stor_control_thread(void * __us) 292static 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) */
555static 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 */
562static int get_device_info(struct us_data *us, const struct usb_device_id *id) 532static 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 */
632static int get_transport(struct us_data *us) 602static 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 */
747static int get_protocol(struct us_data *us) 709static 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 */
1016static int storage_probe(struct usb_interface *intf, 974int 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
1027BadDevice:
1028 US_DEBUGP("storage_probe() failed\n");
1029 release_everything(us);
1030 return result;
1031}
1032EXPORT_SYMBOL_GPL(usb_stor_probe1);
1033
1034/* Second part of general USB mass-storage probing */
1035int 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}
1089EXPORT_SYMBOL_GPL(usb_stor_probe2);
1111 1090
1112/* Handle a disconnect event from the USB core */ 1091/* Handle a USB mass-storage disconnect */
1113static void storage_disconnect(struct usb_interface *intf) 1092void 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}
1100EXPORT_SYMBOL_GPL(usb_stor_disconnect);
1101
1102/* The main probe routine for standard devices */
1103static 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)
1126static struct usb_driver usb_storage_driver = { 1141static 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