aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/usb.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2006-07-01 22:08:06 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-27 14:58:50 -0400
commit36e56a34586783c7986ce09d39db80b27c95ce24 (patch)
tree08637f4fbdd1fd46baba8a48645fcbe37b94cdf5 /drivers/usb/core/usb.c
parent140d8f687457c40a66af362838fac0d7893e7df5 (diff)
usbcore: move code among source files
This revised patch (as713b) moves a few routines among source files in usbcore. Some driver-related code in usb.c (claiming interfaces and matching IDs) is moved to driver.c, where it belongs. Also the usb_generic stuff in driver.c is moved to a new source file: generic.c. (That's the reason for revising the patch.) Although not very big now, it will get bigger in a later patch. None of the code has been changed; it has only been re-arranged. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/usb.c')
-rw-r--r--drivers/usb/core/usb.c307
1 files changed, 0 insertions, 307 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index b28a31b2030..0b8c67bcde6 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -112,87 +112,6 @@ struct usb_host_interface *usb_altnum_to_altsetting(struct usb_interface *intf,
112 return NULL; 112 return NULL;
113} 113}
114 114
115/**
116 * usb_driver_claim_interface - bind a driver to an interface
117 * @driver: the driver to be bound
118 * @iface: the interface to which it will be bound; must be in the
119 * usb device's active configuration
120 * @priv: driver data associated with that interface
121 *
122 * This is used by usb device drivers that need to claim more than one
123 * interface on a device when probing (audio and acm are current examples).
124 * No device driver should directly modify internal usb_interface or
125 * usb_device structure members.
126 *
127 * Few drivers should need to use this routine, since the most natural
128 * way to bind to an interface is to return the private data from
129 * the driver's probe() method.
130 *
131 * Callers must own the device lock and the driver model's usb_bus_type.subsys
132 * writelock. So driver probe() entries don't need extra locking,
133 * but other call contexts may need to explicitly claim those locks.
134 */
135int usb_driver_claim_interface(struct usb_driver *driver,
136 struct usb_interface *iface, void* priv)
137{
138 struct device *dev = &iface->dev;
139
140 if (dev->driver)
141 return -EBUSY;
142
143 dev->driver = &driver->driver;
144 usb_set_intfdata(iface, priv);
145 iface->condition = USB_INTERFACE_BOUND;
146 mark_active(iface);
147
148 /* if interface was already added, bind now; else let
149 * the future device_add() bind it, bypassing probe()
150 */
151 if (device_is_registered(dev))
152 device_bind_driver(dev);
153
154 return 0;
155}
156
157/**
158 * usb_driver_release_interface - unbind a driver from an interface
159 * @driver: the driver to be unbound
160 * @iface: the interface from which it will be unbound
161 *
162 * This can be used by drivers to release an interface without waiting
163 * for their disconnect() methods to be called. In typical cases this
164 * also causes the driver disconnect() method to be called.
165 *
166 * This call is synchronous, and may not be used in an interrupt context.
167 * Callers must own the device lock and the driver model's usb_bus_type.subsys
168 * writelock. So driver disconnect() entries don't need extra locking,
169 * but other call contexts may need to explicitly claim those locks.
170 */
171void usb_driver_release_interface(struct usb_driver *driver,
172 struct usb_interface *iface)
173{
174 struct device *dev = &iface->dev;
175
176 /* this should never happen, don't release something that's not ours */
177 if (!dev->driver || dev->driver != &driver->driver)
178 return;
179
180 /* don't release from within disconnect() */
181 if (iface->condition != USB_INTERFACE_BOUND)
182 return;
183
184 /* don't release if the interface hasn't been added yet */
185 if (device_is_registered(dev)) {
186 iface->condition = USB_INTERFACE_UNBINDING;
187 device_release_driver(dev);
188 }
189
190 dev->driver = NULL;
191 usb_set_intfdata(iface, NULL);
192 iface->condition = USB_INTERFACE_UNBOUND;
193 mark_quiesced(iface);
194}
195
196struct find_interface_arg { 115struct find_interface_arg {
197 int minor; 116 int minor;
198 struct usb_interface *interface; 117 struct usb_interface *interface;
@@ -234,120 +153,6 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
234 return argb.interface; 153 return argb.interface;
235} 154}
236 155
237#ifdef CONFIG_HOTPLUG
238
239/*
240 * This sends an uevent to userspace, typically helping to load driver
241 * or other modules, configure the device, and more. Drivers can provide
242 * a MODULE_DEVICE_TABLE to help with module loading subtasks.
243 *
244 * We're called either from khubd (the typical case) or from root hub
245 * (init, kapmd, modprobe, rmmod, etc), but the agents need to handle
246 * delays in event delivery. Use sysfs (and DEVPATH) to make sure the
247 * device (and this configuration!) are still present.
248 */
249static int usb_uevent(struct device *dev, char **envp, int num_envp,
250 char *buffer, int buffer_size)
251{
252 struct usb_interface *intf;
253 struct usb_device *usb_dev;
254 struct usb_host_interface *alt;
255 int i = 0;
256 int length = 0;
257
258 if (!dev)
259 return -ENODEV;
260
261 /* driver is often null here; dev_dbg() would oops */
262 pr_debug ("usb %s: uevent\n", dev->bus_id);
263
264 /* Must check driver_data here, as on remove driver is always NULL */
265 if ((dev->driver == &usb_generic_driver) ||
266 (dev->driver_data == &usb_generic_driver_data))
267 return 0;
268
269 intf = to_usb_interface(dev);
270 usb_dev = interface_to_usbdev (intf);
271 alt = intf->cur_altsetting;
272
273 if (usb_dev->devnum < 0) {
274 pr_debug ("usb %s: already deleted?\n", dev->bus_id);
275 return -ENODEV;
276 }
277 if (!usb_dev->bus) {
278 pr_debug ("usb %s: bus removed?\n", dev->bus_id);
279 return -ENODEV;
280 }
281
282#ifdef CONFIG_USB_DEVICEFS
283 /* If this is available, userspace programs can directly read
284 * all the device descriptors we don't tell them about. Or
285 * even act as usermode drivers.
286 *
287 * FIXME reduce hardwired intelligence here
288 */
289 if (add_uevent_var(envp, num_envp, &i,
290 buffer, buffer_size, &length,
291 "DEVICE=/proc/bus/usb/%03d/%03d",
292 usb_dev->bus->busnum, usb_dev->devnum))
293 return -ENOMEM;
294#endif
295
296 /* per-device configurations are common */
297 if (add_uevent_var(envp, num_envp, &i,
298 buffer, buffer_size, &length,
299 "PRODUCT=%x/%x/%x",
300 le16_to_cpu(usb_dev->descriptor.idVendor),
301 le16_to_cpu(usb_dev->descriptor.idProduct),
302 le16_to_cpu(usb_dev->descriptor.bcdDevice)))
303 return -ENOMEM;
304
305 /* class-based driver binding models */
306 if (add_uevent_var(envp, num_envp, &i,
307 buffer, buffer_size, &length,
308 "TYPE=%d/%d/%d",
309 usb_dev->descriptor.bDeviceClass,
310 usb_dev->descriptor.bDeviceSubClass,
311 usb_dev->descriptor.bDeviceProtocol))
312 return -ENOMEM;
313
314 if (add_uevent_var(envp, num_envp, &i,
315 buffer, buffer_size, &length,
316 "INTERFACE=%d/%d/%d",
317 alt->desc.bInterfaceClass,
318 alt->desc.bInterfaceSubClass,
319 alt->desc.bInterfaceProtocol))
320 return -ENOMEM;
321
322 if (add_uevent_var(envp, num_envp, &i,
323 buffer, buffer_size, &length,
324 "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
325 le16_to_cpu(usb_dev->descriptor.idVendor),
326 le16_to_cpu(usb_dev->descriptor.idProduct),
327 le16_to_cpu(usb_dev->descriptor.bcdDevice),
328 usb_dev->descriptor.bDeviceClass,
329 usb_dev->descriptor.bDeviceSubClass,
330 usb_dev->descriptor.bDeviceProtocol,
331 alt->desc.bInterfaceClass,
332 alt->desc.bInterfaceSubClass,
333 alt->desc.bInterfaceProtocol))
334 return -ENOMEM;
335
336 envp[i] = NULL;
337
338 return 0;
339}
340
341#else
342
343static int usb_uevent(struct device *dev, char **envp,
344 int num_envp, char *buffer, int buffer_size)
345{
346 return -ENODEV;
347}
348
349#endif /* CONFIG_HOTPLUG */
350
351/** 156/**
352 * usb_release_dev - free a usb device structure when all users of it are finished. 157 * usb_release_dev - free a usb device structure when all users of it are finished.
353 * @dev: device that's been disconnected 158 * @dev: device that's been disconnected
@@ -990,116 +795,6 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
990 usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); 795 usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
991} 796}
992 797
993static int verify_suspended(struct device *dev, void *unused)
994{
995 if (dev->driver == NULL)
996 return 0;
997 return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0;
998}
999
1000static int usb_generic_suspend(struct device *dev, pm_message_t message)
1001{
1002 struct usb_interface *intf;
1003 struct usb_driver *driver;
1004 int status;
1005
1006 /* USB devices enter SUSPEND state through their hubs, but can be
1007 * marked for FREEZE as soon as their children are already idled.
1008 * But those semantics are useless, so we equate the two (sigh).
1009 */
1010 if (dev->driver == &usb_generic_driver) {
1011 if (dev->power.power_state.event == message.event)
1012 return 0;
1013 /* we need to rule out bogus requests through sysfs */
1014 status = device_for_each_child(dev, NULL, verify_suspended);
1015 if (status)
1016 return status;
1017 return usb_port_suspend(to_usb_device(dev));
1018 }
1019
1020 if ((dev->driver == NULL) ||
1021 (dev->driver_data == &usb_generic_driver_data))
1022 return 0;
1023
1024 intf = to_usb_interface(dev);
1025 driver = to_usb_driver(dev->driver);
1026
1027 /* with no hardware, USB interfaces only use FREEZE and ON states */
1028 if (!is_active(intf))
1029 return 0;
1030
1031 if (driver->suspend && driver->resume) {
1032 status = driver->suspend(intf, message);
1033 if (status)
1034 dev_err(dev, "%s error %d\n", "suspend", status);
1035 else
1036 mark_quiesced(intf);
1037 } else {
1038 // FIXME else if there's no suspend method, disconnect...
1039 dev_warn(dev, "no suspend for driver %s?\n", driver->name);
1040 mark_quiesced(intf);
1041 status = 0;
1042 }
1043 return status;
1044}
1045
1046static int usb_generic_resume(struct device *dev)
1047{
1048 struct usb_interface *intf;
1049 struct usb_driver *driver;
1050 struct usb_device *udev;
1051 int status;
1052
1053 if (dev->power.power_state.event == PM_EVENT_ON)
1054 return 0;
1055
1056 /* mark things as "on" immediately, no matter what errors crop up */
1057 dev->power.power_state.event = PM_EVENT_ON;
1058
1059 /* devices resume through their hubs */
1060 if (dev->driver == &usb_generic_driver) {
1061 udev = to_usb_device(dev);
1062 if (udev->state == USB_STATE_NOTATTACHED)
1063 return 0;
1064 return usb_port_resume(udev);
1065 }
1066
1067 if ((dev->driver == NULL) ||
1068 (dev->driver_data == &usb_generic_driver_data)) {
1069 dev->power.power_state.event = PM_EVENT_FREEZE;
1070 return 0;
1071 }
1072
1073 intf = to_usb_interface(dev);
1074 driver = to_usb_driver(dev->driver);
1075
1076 udev = interface_to_usbdev(intf);
1077 if (udev->state == USB_STATE_NOTATTACHED)
1078 return 0;
1079
1080 /* if driver was suspended, it has a resume method;
1081 * however, sysfs can wrongly mark things as suspended
1082 * (on the "no suspend method" FIXME path above)
1083 */
1084 if (driver->resume) {
1085 status = driver->resume(intf);
1086 if (status) {
1087 dev_err(dev, "%s error %d\n", "resume", status);
1088 mark_quiesced(intf);
1089 }
1090 } else
1091 dev_warn(dev, "no resume for driver %s?\n", driver->name);
1092 return 0;
1093}
1094
1095struct bus_type usb_bus_type = {
1096 .name = "usb",
1097 .match = usb_device_match,
1098 .uevent = usb_uevent,
1099 .suspend = usb_generic_suspend,
1100 .resume = usb_generic_resume,
1101};
1102
1103/* format to disable USB on kernel command line is: nousb */ 798/* format to disable USB on kernel command line is: nousb */
1104__module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444); 799__module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444);
1105 800
@@ -1203,8 +898,6 @@ EXPORT_SYMBOL(usb_hub_tt_clear_buffer);
1203 898
1204EXPORT_SYMBOL(usb_lock_device_for_reset); 899EXPORT_SYMBOL(usb_lock_device_for_reset);
1205 900
1206EXPORT_SYMBOL(usb_driver_claim_interface);
1207EXPORT_SYMBOL(usb_driver_release_interface);
1208EXPORT_SYMBOL(usb_find_interface); 901EXPORT_SYMBOL(usb_find_interface);
1209EXPORT_SYMBOL(usb_ifnum_to_if); 902EXPORT_SYMBOL(usb_ifnum_to_if);
1210EXPORT_SYMBOL(usb_altnum_to_altsetting); 903EXPORT_SYMBOL(usb_altnum_to_altsetting);