diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2006-07-01 22:08:06 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-09-27 14:58:50 -0400 |
commit | 36e56a34586783c7986ce09d39db80b27c95ce24 (patch) | |
tree | 08637f4fbdd1fd46baba8a48645fcbe37b94cdf5 /drivers/usb/core/usb.c | |
parent | 140d8f687457c40a66af362838fac0d7893e7df5 (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.c | 307 |
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 | */ | ||
135 | int 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 | */ | ||
171 | void 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 | |||
196 | struct find_interface_arg { | 115 | struct 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 | */ | ||
249 | static 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 | |||
343 | static 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 | ||
993 | static 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 | |||
1000 | static 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 | |||
1046 | static 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 | |||
1095 | struct 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 | ||
1204 | EXPORT_SYMBOL(usb_lock_device_for_reset); | 899 | EXPORT_SYMBOL(usb_lock_device_for_reset); |
1205 | 900 | ||
1206 | EXPORT_SYMBOL(usb_driver_claim_interface); | ||
1207 | EXPORT_SYMBOL(usb_driver_release_interface); | ||
1208 | EXPORT_SYMBOL(usb_find_interface); | 901 | EXPORT_SYMBOL(usb_find_interface); |
1209 | EXPORT_SYMBOL(usb_ifnum_to_if); | 902 | EXPORT_SYMBOL(usb_ifnum_to_if); |
1210 | EXPORT_SYMBOL(usb_altnum_to_altsetting); | 903 | EXPORT_SYMBOL(usb_altnum_to_altsetting); |