Rev 846 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
846 | giacomo | 1 | /* |
2 | * (C) Copyright Linus Torvalds 1999 |
||
3 | * (C) Copyright Johannes Erdfelt 1999-2001 |
||
4 | * (C) Copyright Andreas Gal 1999 |
||
5 | * (C) Copyright Gregory P. Smith 1999 |
||
6 | * (C) Copyright Deti Fliegl 1999 |
||
7 | * (C) Copyright Randy Dunlap 2000 |
||
8 | * (C) Copyright David Brownell 2000-2002 |
||
9 | * |
||
10 | * This program is free software; you can redistribute it and/or modify it |
||
11 | * under the terms of the GNU General Public License as published by the |
||
12 | * Free Software Foundation; either version 2 of the License, or (at your |
||
13 | * option) any later version. |
||
14 | * |
||
15 | * This program is distributed in the hope that it will be useful, but |
||
16 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||
17 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
||
18 | * for more details. |
||
19 | * |
||
20 | * You should have received a copy of the GNU General Public License |
||
21 | * along with this program; if not, write to the Free Software Foundation, |
||
22 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
23 | */ |
||
24 | |||
25 | #include <linuxcomp.h> |
||
26 | |||
27 | #include <linux/config.h> |
||
28 | |||
29 | #ifdef CONFIG_USB_DEBUG |
||
30 | #define DEBUG |
||
31 | #endif |
||
32 | |||
33 | #include <linux/module.h> |
||
34 | #include <linux/version.h> |
||
35 | #include <linux/kernel.h> |
||
36 | #include <linux/slab.h> |
||
37 | #include <linux/completion.h> |
||
38 | #include <linux/uts.h> /* for UTS_SYSNAME */ |
||
39 | #include <linux/pci.h> /* for hcd->pdev and dma addressing */ |
||
40 | #include <linux/dma-mapping.h> |
||
41 | #include <asm/byteorder.h> |
||
42 | |||
43 | #include <linux/usb.h> |
||
44 | #include "hcd.h" |
||
45 | |||
46 | |||
47 | // #define USB_BANDWIDTH_MESSAGES |
||
48 | |||
49 | /*-------------------------------------------------------------------------*/ |
||
50 | |||
51 | /* |
||
52 | * USB Host Controller Driver framework |
||
53 | * |
||
54 | * Plugs into usbcore (usb_bus) and lets HCDs share code, minimizing |
||
55 | * HCD-specific behaviors/bugs. |
||
56 | * |
||
57 | * This does error checks, tracks devices and urbs, and delegates to a |
||
58 | * "hc_driver" only for code (and data) that really needs to know about |
||
59 | * hardware differences. That includes root hub registers, i/o queues, |
||
60 | * and so on ... but as little else as possible. |
||
61 | * |
||
62 | * Shared code includes most of the "root hub" code (these are emulated, |
||
63 | * though each HC's hardware works differently) and PCI glue, plus request |
||
64 | * tracking overhead. The HCD code should only block on spinlocks or on |
||
65 | * hardware handshaking; blocking on software events (such as other kernel |
||
66 | * threads releasing resources, or completing actions) is all generic. |
||
67 | * |
||
68 | * Happens the USB 2.0 spec says this would be invisible inside the "USBD", |
||
69 | * and includes mostly a "HCDI" (HCD Interface) along with some APIs used |
||
70 | * only by the hub driver ... and that neither should be seen or used by |
||
71 | * usb client device drivers. |
||
72 | * |
||
73 | * Contributors of ideas or unattributed patches include: David Brownell, |
||
74 | * Roman Weissgaerber, Rory Bolt, Greg Kroah-Hartman, ... |
||
75 | * |
||
76 | * HISTORY: |
||
77 | * 2002-02-21 Pull in most of the usb_bus support from usb.c; some |
||
78 | * associated cleanup. "usb_hcd" still != "usb_bus". |
||
79 | * 2001-12-12 Initial patch version for Linux 2.5.1 kernel. |
||
80 | */ |
||
81 | |||
82 | /*-------------------------------------------------------------------------*/ |
||
83 | |||
84 | /* host controllers we manage */ |
||
85 | LIST_HEAD (usb_bus_list); |
||
86 | EXPORT_SYMBOL_GPL (usb_bus_list); |
||
87 | |||
88 | /* used when allocating bus numbers */ |
||
89 | #define USB_MAXBUS 64 |
||
90 | struct usb_busmap { |
||
91 | unsigned long busmap [USB_MAXBUS / (8*sizeof (unsigned long))]; |
||
92 | }; |
||
93 | static struct usb_busmap busmap; |
||
94 | |||
95 | /* used when updating list of hcds */ |
||
96 | DECLARE_MUTEX (usb_bus_list_lock); /* exported only for usbfs */ |
||
97 | EXPORT_SYMBOL_GPL (usb_bus_list_lock); |
||
98 | |||
99 | /* used when updating hcd data */ |
||
100 | static spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED; |
||
101 | |||
102 | /*-------------------------------------------------------------------------*/ |
||
103 | |||
104 | /* |
||
105 | * Sharable chunks of root hub code. |
||
106 | */ |
||
107 | |||
108 | /*-------------------------------------------------------------------------*/ |
||
109 | |||
110 | #define KERNEL_REL ((LINUX_VERSION_CODE >> 16) & 0x0ff) |
||
111 | #define KERNEL_VER ((LINUX_VERSION_CODE >> 8) & 0x0ff) |
||
112 | |||
113 | /* usb 2.0 root hub device descriptor */ |
||
114 | static const u8 usb2_rh_dev_descriptor [18] = { |
||
115 | 0x12, /* __u8 bLength; */ |
||
116 | 0x01, /* __u8 bDescriptorType; Device */ |
||
117 | 0x00, 0x02, /* __u16 bcdUSB; v2.0 */ |
||
118 | |||
119 | 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ |
||
120 | 0x00, /* __u8 bDeviceSubClass; */ |
||
121 | 0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/ |
||
122 | 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ |
||
123 | |||
124 | 0x00, 0x00, /* __u16 idVendor; */ |
||
125 | 0x00, 0x00, /* __u16 idProduct; */ |
||
126 | KERNEL_VER, KERNEL_REL, /* __u16 bcdDevice */ |
||
127 | |||
128 | 0x03, /* __u8 iManufacturer; */ |
||
129 | 0x02, /* __u8 iProduct; */ |
||
130 | 0x01, /* __u8 iSerialNumber; */ |
||
131 | 0x01 /* __u8 bNumConfigurations; */ |
||
132 | }; |
||
133 | |||
134 | /* no usb 2.0 root hub "device qualifier" descriptor: one speed only */ |
||
135 | |||
136 | /* usb 1.1 root hub device descriptor */ |
||
137 | static const u8 usb11_rh_dev_descriptor [18] = { |
||
138 | 0x12, /* __u8 bLength; */ |
||
139 | 0x01, /* __u8 bDescriptorType; Device */ |
||
140 | 0x10, 0x01, /* __u16 bcdUSB; v1.1 */ |
||
141 | |||
142 | 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ |
||
143 | 0x00, /* __u8 bDeviceSubClass; */ |
||
144 | 0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */ |
||
145 | 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ |
||
146 | |||
147 | 0x00, 0x00, /* __u16 idVendor; */ |
||
148 | 0x00, 0x00, /* __u16 idProduct; */ |
||
149 | KERNEL_VER, KERNEL_REL, /* __u16 bcdDevice */ |
||
150 | |||
151 | 0x03, /* __u8 iManufacturer; */ |
||
152 | 0x02, /* __u8 iProduct; */ |
||
153 | 0x01, /* __u8 iSerialNumber; */ |
||
154 | 0x01 /* __u8 bNumConfigurations; */ |
||
155 | }; |
||
156 | |||
157 | |||
158 | /*-------------------------------------------------------------------------*/ |
||
159 | |||
160 | /* Configuration descriptors for our root hubs */ |
||
161 | |||
162 | static const u8 fs_rh_config_descriptor [] = { |
||
163 | |||
164 | /* one configuration */ |
||
165 | 0x09, /* __u8 bLength; */ |
||
166 | 0x02, /* __u8 bDescriptorType; Configuration */ |
||
167 | 0x19, 0x00, /* __u16 wTotalLength; */ |
||
168 | 0x01, /* __u8 bNumInterfaces; (1) */ |
||
169 | 0x01, /* __u8 bConfigurationValue; */ |
||
170 | 0x00, /* __u8 iConfiguration; */ |
||
171 | 0x40, /* __u8 bmAttributes; |
||
172 | Bit 7: Bus-powered, |
||
173 | 6: Self-powered, |
||
174 | 5 Remote-wakwup, |
||
175 | 4..0: resvd */ |
||
176 | 0x00, /* __u8 MaxPower; */ |
||
177 | |||
178 | /* USB 1.1: |
||
179 | * USB 2.0, single TT organization (mandatory): |
||
180 | * one interface, protocol 0 |
||
181 | * |
||
182 | * USB 2.0, multiple TT organization (optional): |
||
183 | * two interfaces, protocols 1 (like single TT) |
||
184 | * and 2 (multiple TT mode) ... config is |
||
185 | * sometimes settable |
||
186 | * NOT IMPLEMENTED |
||
187 | */ |
||
188 | |||
189 | /* one interface */ |
||
190 | 0x09, /* __u8 if_bLength; */ |
||
191 | 0x04, /* __u8 if_bDescriptorType; Interface */ |
||
192 | 0x00, /* __u8 if_bInterfaceNumber; */ |
||
193 | 0x00, /* __u8 if_bAlternateSetting; */ |
||
194 | 0x01, /* __u8 if_bNumEndpoints; */ |
||
195 | 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ |
||
196 | 0x00, /* __u8 if_bInterfaceSubClass; */ |
||
197 | 0x00, /* __u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ |
||
198 | 0x00, /* __u8 if_iInterface; */ |
||
199 | |||
200 | /* one endpoint (status change endpoint) */ |
||
201 | 0x07, /* __u8 ep_bLength; */ |
||
202 | 0x05, /* __u8 ep_bDescriptorType; Endpoint */ |
||
203 | 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ |
||
204 | 0x03, /* __u8 ep_bmAttributes; Interrupt */ |
||
205 | 0x02, 0x00, /* __u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ |
||
206 | 0xff /* __u8 ep_bInterval; (255ms -- usb 2.0 spec) */ |
||
207 | }; |
||
208 | |||
209 | static const u8 hs_rh_config_descriptor [] = { |
||
210 | |||
211 | /* one configuration */ |
||
212 | 0x09, /* __u8 bLength; */ |
||
213 | 0x02, /* __u8 bDescriptorType; Configuration */ |
||
214 | 0x19, 0x00, /* __u16 wTotalLength; */ |
||
215 | 0x01, /* __u8 bNumInterfaces; (1) */ |
||
216 | 0x01, /* __u8 bConfigurationValue; */ |
||
217 | 0x00, /* __u8 iConfiguration; */ |
||
218 | 0x40, /* __u8 bmAttributes; |
||
219 | Bit 7: Bus-powered, |
||
220 | 6: Self-powered, |
||
221 | 5 Remote-wakwup, |
||
222 | 4..0: resvd */ |
||
223 | 0x00, /* __u8 MaxPower; */ |
||
224 | |||
225 | /* USB 1.1: |
||
226 | * USB 2.0, single TT organization (mandatory): |
||
227 | * one interface, protocol 0 |
||
228 | * |
||
229 | * USB 2.0, multiple TT organization (optional): |
||
230 | * two interfaces, protocols 1 (like single TT) |
||
231 | * and 2 (multiple TT mode) ... config is |
||
232 | * sometimes settable |
||
233 | * NOT IMPLEMENTED |
||
234 | */ |
||
235 | |||
236 | /* one interface */ |
||
237 | 0x09, /* __u8 if_bLength; */ |
||
238 | 0x04, /* __u8 if_bDescriptorType; Interface */ |
||
239 | 0x00, /* __u8 if_bInterfaceNumber; */ |
||
240 | 0x00, /* __u8 if_bAlternateSetting; */ |
||
241 | 0x01, /* __u8 if_bNumEndpoints; */ |
||
242 | 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ |
||
243 | 0x00, /* __u8 if_bInterfaceSubClass; */ |
||
244 | 0x00, /* __u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ |
||
245 | 0x00, /* __u8 if_iInterface; */ |
||
246 | |||
247 | /* one endpoint (status change endpoint) */ |
||
248 | 0x07, /* __u8 ep_bLength; */ |
||
249 | 0x05, /* __u8 ep_bDescriptorType; Endpoint */ |
||
250 | 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ |
||
251 | 0x03, /* __u8 ep_bmAttributes; Interrupt */ |
||
252 | 0x02, 0x00, /* __u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ |
||
253 | 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ |
||
254 | }; |
||
255 | |||
256 | /*-------------------------------------------------------------------------*/ |
||
257 | |||
258 | /* |
||
259 | * helper routine for returning string descriptors in UTF-16LE |
||
260 | * input can actually be ISO-8859-1; ASCII is its 7-bit subset |
||
261 | */ |
||
262 | static int ascii2utf (char *s, u8 *utf, int utfmax) |
||
263 | { |
||
264 | int retval; |
||
265 | |||
266 | for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { |
||
267 | *utf++ = *s++; |
||
268 | *utf++ = 0; |
||
269 | } |
||
270 | return retval; |
||
271 | } |
||
272 | |||
273 | /* |
||
274 | * rh_string - provides manufacturer, product and serial strings for root hub |
||
275 | * @id: the string ID number (1: serial number, 2: product, 3: vendor) |
||
276 | * @hcd: the host controller for this root hub |
||
277 | * @type: string describing our driver |
||
278 | * @data: return packet in UTF-16 LE |
||
279 | * @len: length of the return packet |
||
280 | * |
||
281 | * Produces either a manufacturer, product or serial number string for the |
||
282 | * virtual root hub device. |
||
283 | */ |
||
284 | static int rh_string ( |
||
285 | int id, |
||
286 | struct usb_hcd *hcd, |
||
287 | u8 *data, |
||
288 | int len |
||
289 | ) { |
||
290 | char buf [100]; |
||
291 | |||
292 | // language ids |
||
293 | if (id == 0) { |
||
294 | *data++ = 4; *data++ = 3; /* 4 bytes string data */ |
||
295 | *data++ = 0x09; *data++ = 0x04; /* MSFT-speak for "en-us" */ |
||
296 | return 4; |
||
297 | |||
298 | // serial number |
||
299 | } else if (id == 1) { |
||
300 | strcpy (buf, hcd->self.bus_name); |
||
301 | |||
302 | // product description |
||
303 | } else if (id == 2) { |
||
304 | strcpy (buf, hcd->product_desc); |
||
305 | |||
306 | // id 3 == vendor description |
||
307 | } else if (id == 3) { |
||
308 | sprintf26 (buf, "%s %s %s", UTS_SYSNAME, UTS_RELEASE, |
||
309 | hcd->description); |
||
310 | |||
311 | // unsupported IDs --> "protocol stall" |
||
312 | } else |
||
313 | return 0; |
||
314 | |||
315 | data [0] = 2 * (strlen (buf) + 1); |
||
316 | data [1] = 3; /* type == string */ |
||
317 | return 2 + ascii2utf (buf, data + 2, len - 2); |
||
318 | } |
||
319 | |||
320 | |||
321 | /* Root hub control transfers execute synchronously */ |
||
322 | static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) |
||
323 | { |
||
324 | struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) urb->setup_packet; |
||
325 | u16 typeReq, wValue, wIndex, wLength; |
||
326 | const u8 *bufp = 0; |
||
327 | u8 *ubuf = urb->transfer_buffer; |
||
328 | int len = 0; |
||
329 | unsigned long flags; |
||
330 | |||
331 | typeReq = (cmd->bRequestType << 8) | cmd->bRequest; |
||
332 | wValue = le16_to_cpu (cmd->wValue); |
||
333 | wIndex = le16_to_cpu (cmd->wIndex); |
||
334 | wLength = le16_to_cpu (cmd->wLength); |
||
335 | |||
336 | if (wLength > urb->transfer_buffer_length) |
||
337 | goto error; |
||
338 | /* set up for success */ |
||
339 | urb->status = 0; |
||
340 | urb->actual_length = wLength; |
||
341 | |||
342 | switch (typeReq) { |
||
343 | |||
344 | /* DEVICE REQUESTS */ |
||
345 | |||
346 | case DeviceRequest | USB_REQ_GET_STATUS: |
||
347 | // DEVICE_REMOTE_WAKEUP |
||
348 | ubuf [0] = 1; // selfpowered |
||
349 | ubuf [1] = 0; |
||
350 | /* FALLTHROUGH */ |
||
351 | case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: |
||
352 | case DeviceOutRequest | USB_REQ_SET_FEATURE: |
||
353 | dev_dbg (hcd->controller, "no device features yet yet\n"); |
||
354 | break; |
||
355 | case DeviceRequest | USB_REQ_GET_CONFIGURATION: |
||
356 | ubuf [0] = 1; |
||
357 | /* FALLTHROUGH */ |
||
358 | case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: |
||
359 | break; |
||
360 | case DeviceRequest | USB_REQ_GET_DESCRIPTOR: |
||
361 | switch (wValue & 0xff00) { |
||
362 | case USB_DT_DEVICE << 8: |
||
363 | if (hcd->driver->flags & HCD_USB2) |
||
364 | bufp = usb2_rh_dev_descriptor; |
||
365 | else if (hcd->driver->flags & HCD_USB11) |
||
366 | bufp = usb11_rh_dev_descriptor; |
||
367 | else |
||
368 | goto error; |
||
369 | len = 18; |
||
370 | break; |
||
371 | case USB_DT_CONFIG << 8: |
||
372 | if (hcd->driver->flags & HCD_USB2) { |
||
373 | bufp = hs_rh_config_descriptor; |
||
374 | len = sizeof hs_rh_config_descriptor; |
||
375 | } else { |
||
376 | bufp = fs_rh_config_descriptor; |
||
377 | len = sizeof fs_rh_config_descriptor; |
||
378 | } |
||
379 | break; |
||
380 | case USB_DT_STRING << 8: |
||
381 | urb->actual_length = rh_string ( |
||
382 | wValue & 0xff, hcd, |
||
383 | ubuf, wLength); |
||
384 | break; |
||
385 | default: |
||
386 | goto error; |
||
387 | } |
||
388 | break; |
||
389 | case DeviceRequest | USB_REQ_GET_INTERFACE: |
||
390 | ubuf [0] = 0; |
||
391 | /* FALLTHROUGH */ |
||
392 | case DeviceOutRequest | USB_REQ_SET_INTERFACE: |
||
393 | break; |
||
394 | case DeviceOutRequest | USB_REQ_SET_ADDRESS: |
||
395 | // wValue == urb->dev->devaddr |
||
396 | dev_dbg (hcd->controller, "root hub device address %d\n", |
||
397 | wValue); |
||
398 | break; |
||
399 | |||
400 | /* INTERFACE REQUESTS (no defined feature/status flags) */ |
||
401 | |||
402 | /* ENDPOINT REQUESTS */ |
||
403 | |||
404 | case EndpointRequest | USB_REQ_GET_STATUS: |
||
405 | // ENDPOINT_HALT flag |
||
406 | ubuf [0] = 0; |
||
407 | ubuf [1] = 0; |
||
408 | /* FALLTHROUGH */ |
||
409 | case EndpointOutRequest | USB_REQ_CLEAR_FEATURE: |
||
410 | case EndpointOutRequest | USB_REQ_SET_FEATURE: |
||
411 | dev_dbg (hcd->controller, "no endpoint features yet\n"); |
||
412 | break; |
||
413 | |||
414 | /* CLASS REQUESTS (and errors) */ |
||
415 | |||
416 | default: |
||
417 | /* non-generic request */ |
||
418 | urb->status = hcd->driver->hub_control (hcd, |
||
419 | typeReq, wValue, wIndex, |
||
420 | ubuf, wLength); |
||
421 | break; |
||
422 | error: |
||
423 | /* "protocol stall" on error */ |
||
424 | urb->status = -EPIPE; |
||
425 | dev_dbg (hcd->controller, "unsupported hub control message (maxchild %d)\n", |
||
426 | urb->dev->maxchild); |
||
427 | } |
||
428 | if (urb->status) { |
||
429 | urb->actual_length = 0; |
||
430 | dev_dbg (hcd->controller, "CTRL: TypeReq=0x%x val=0x%x idx=0x%x len=%d ==> %d\n", |
||
431 | typeReq, wValue, wIndex, wLength, urb->status); |
||
432 | } |
||
433 | if (bufp) { |
||
434 | if (urb->transfer_buffer_length < len) |
||
435 | len = urb->transfer_buffer_length; |
||
436 | urb->actual_length = len; |
||
437 | // always USB_DIR_IN, toward host |
||
438 | memcpy (ubuf, bufp, len); |
||
439 | } |
||
440 | |||
441 | /* any errors get returned through the urb completion */ |
||
442 | local_irq_save (flags); |
||
443 | usb_hcd_giveback_urb (hcd, urb, NULL); |
||
444 | local_irq_restore (flags); |
||
445 | return 0; |
||
446 | } |
||
447 | |||
448 | /*-------------------------------------------------------------------------*/ |
||
449 | |||
450 | /* |
||
451 | * Root Hub interrupt transfers are synthesized with a timer. |
||
452 | * Completions are called in_interrupt() but not in_irq(). |
||
453 | */ |
||
454 | |||
455 | static void rh_report_status (unsigned long ptr); |
||
456 | |||
457 | static int rh_status_urb (struct usb_hcd *hcd, struct urb *urb) |
||
458 | { |
||
459 | int len = 1 + (urb->dev->maxchild / 8); |
||
460 | |||
461 | /* rh_timer protected by hcd_data_lock */ |
||
462 | if (hcd->rh_timer.data |
||
463 | || urb->status != -EINPROGRESS |
||
464 | || urb->transfer_buffer_length < len |
||
465 | || !HCD_IS_RUNNING (hcd->state)) { |
||
466 | dev_dbg (hcd->controller, |
||
467 | "not queuing rh status urb, stat %d\n", |
||
468 | urb->status); |
||
469 | return -EINVAL; |
||
470 | } |
||
471 | |||
472 | init_timer (&hcd->rh_timer); |
||
473 | hcd->rh_timer.function = rh_report_status; |
||
474 | hcd->rh_timer.data = (unsigned long) urb; |
||
475 | /* USB 2.0 spec says 256msec; this is close enough */ |
||
476 | hcd->rh_timer.expires = jiffies26 + HZ/4; |
||
477 | add_timer (&hcd->rh_timer); |
||
478 | urb->hcpriv = hcd; /* nonzero to indicate it's queued */ |
||
479 | return 0; |
||
480 | } |
||
481 | |||
482 | /* timer callback */ |
||
483 | |||
484 | static void rh_report_status (unsigned long ptr) |
||
485 | { |
||
486 | struct urb *urb; |
||
487 | struct usb_hcd *hcd; |
||
488 | int length = 0; |
||
489 | unsigned long flags; |
||
490 | |||
491 | urb = (struct urb *) ptr; |
||
492 | local_irq_save (flags); |
||
493 | spin_lock (&urb->lock); |
||
494 | |||
495 | /* do nothing if the urb's been unlinked */ |
||
496 | if (!urb->dev |
||
497 | || urb->status != -EINPROGRESS |
||
498 | || (hcd = urb->dev->bus->hcpriv) == 0) { |
||
499 | spin_unlock (&urb->lock); |
||
500 | local_irq_restore (flags); |
||
501 | return; |
||
502 | } |
||
503 | |||
504 | if (!HCD_IS_SUSPENDED (hcd->state)) |
||
505 | length = hcd->driver->hub_status_data ( |
||
506 | hcd, urb->transfer_buffer); |
||
507 | |||
508 | /* complete the status urb, or retrigger the timer */ |
||
509 | spin_lock (&hcd_data_lock); |
||
510 | if (length > 0) { |
||
511 | hcd->rh_timer.data = 0; |
||
512 | urb->actual_length = length; |
||
513 | urb->status = 0; |
||
514 | urb->hcpriv = 0; |
||
515 | } else |
||
516 | mod_timer (&hcd->rh_timer, jiffies26 + HZ/4); |
||
517 | spin_unlock (&hcd_data_lock); |
||
518 | spin_unlock (&urb->lock); |
||
519 | |||
520 | /* local irqs are always blocked in completions */ |
||
521 | if (length > 0) |
||
522 | usb_hcd_giveback_urb (hcd, urb, NULL); |
||
523 | local_irq_restore (flags); |
||
524 | } |
||
525 | |||
526 | /*-------------------------------------------------------------------------*/ |
||
527 | |||
528 | static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb) |
||
529 | { |
||
530 | if (usb_pipeint (urb->pipe)) { |
||
531 | int retval; |
||
532 | unsigned long flags; |
||
533 | |||
534 | spin_lock_irqsave (&hcd_data_lock, flags); |
||
535 | retval = rh_status_urb (hcd, urb); |
||
536 | |||
537 | spin_unlock_irqrestore (&hcd_data_lock, flags); |
||
538 | return retval; |
||
539 | } |
||
540 | if (usb_pipecontrol (urb->pipe)) |
||
541 | return rh_call_control (hcd, urb); |
||
542 | else |
||
543 | return -EINVAL; |
||
544 | } |
||
545 | |||
546 | /*-------------------------------------------------------------------------*/ |
||
547 | |||
548 | void usb_rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb) |
||
549 | { |
||
550 | unsigned long flags; |
||
551 | |||
552 | /* note: always a synchronous unlink */ |
||
553 | del_timer_sync (&hcd->rh_timer); |
||
554 | hcd->rh_timer.data = 0; |
||
555 | |||
556 | local_irq_save (flags); |
||
557 | urb->hcpriv = 0; |
||
558 | usb_hcd_giveback_urb (hcd, urb, NULL); |
||
559 | local_irq_restore (flags); |
||
560 | } |
||
561 | |||
562 | /*-------------------------------------------------------------------------*/ |
||
563 | |||
564 | /* exported only within usbcore */ |
||
565 | struct usb_bus *usb_bus_get (struct usb_bus *bus) |
||
566 | { |
||
567 | struct class_device *tmp; |
||
568 | |||
569 | if (!bus) |
||
570 | return NULL; |
||
571 | |||
572 | tmp = class_device_get(&bus->class_dev); |
||
573 | if (tmp) |
||
574 | return to_usb_bus(tmp); |
||
575 | else |
||
576 | return NULL; |
||
577 | } |
||
578 | |||
579 | /* exported only within usbcore */ |
||
580 | void usb_bus_put (struct usb_bus *bus) |
||
581 | { |
||
582 | if (bus) |
||
583 | class_device_put(&bus->class_dev); |
||
584 | } |
||
585 | |||
586 | /*-------------------------------------------------------------------------*/ |
||
587 | |||
588 | static void usb_host_release(struct class_device *class_dev) |
||
589 | { |
||
590 | struct usb_bus *bus = to_usb_bus(class_dev); |
||
591 | |||
592 | if (bus->release) |
||
593 | bus->release(bus); |
||
594 | } |
||
595 | |||
596 | static struct class usb_host_class = { |
||
597 | .name = "usb_host", |
||
598 | .release = &usb_host_release, |
||
599 | }; |
||
600 | |||
601 | void usb_host_init(void) |
||
602 | { |
||
603 | class_register(&usb_host_class); |
||
604 | } |
||
605 | |||
606 | void usb_host_cleanup(void) |
||
607 | { |
||
608 | class_unregister(&usb_host_class); |
||
609 | } |
||
610 | |||
611 | /** |
||
612 | * usb_bus_init - shared initialization code |
||
613 | * @bus: the bus structure being initialized |
||
614 | * |
||
615 | * This code is used to initialize a usb_bus structure, memory for which is |
||
616 | * separately managed. |
||
617 | */ |
||
618 | void usb_bus_init (struct usb_bus *bus) |
||
619 | { |
||
620 | memset (&bus->devmap, 0, sizeof(struct usb_devmap)); |
||
621 | |||
622 | bus->devnum_next = 1; |
||
623 | |||
624 | bus->root_hub = NULL; |
||
625 | bus->hcpriv = NULL; |
||
626 | bus->busnum = -1; |
||
627 | bus->bandwidth_allocated = 0; |
||
628 | bus->bandwidth_int_reqs = 0; |
||
629 | bus->bandwidth_isoc_reqs = 0; |
||
630 | |||
631 | INIT_LIST_HEAD (&bus->bus_list); |
||
632 | } |
||
633 | EXPORT_SYMBOL (usb_bus_init); |
||
634 | |||
635 | /** |
||
636 | * usb_alloc_bus - creates a new USB host controller structure |
||
637 | * @op: pointer to a struct usb_operations that this bus structure should use |
||
638 | * Context: !in_interrupt() |
||
639 | * |
||
640 | * Creates a USB host controller bus structure with the specified |
||
641 | * usb_operations and initializes all the necessary internal objects. |
||
642 | * |
||
643 | * If no memory is available, NULL is returned. |
||
644 | * |
||
645 | * The caller should call usb_put_bus() when it is finished with the structure. |
||
646 | */ |
||
647 | struct usb_bus *usb_alloc_bus (struct usb_operations *op) |
||
648 | { |
||
649 | struct usb_bus *bus; |
||
650 | |||
651 | bus = kmalloc (sizeof *bus, GFP_KERNEL); |
||
652 | if (!bus) |
||
653 | return NULL; |
||
654 | memset(bus, 0, sizeof(struct usb_bus)); |
||
655 | usb_bus_init (bus); |
||
656 | bus->op = op; |
||
657 | return bus; |
||
658 | } |
||
659 | EXPORT_SYMBOL (usb_alloc_bus); |
||
660 | |||
661 | /*-------------------------------------------------------------------------*/ |
||
662 | |||
663 | /** |
||
664 | * usb_register_bus - registers the USB host controller with the usb core |
||
665 | * @bus: pointer to the bus to register |
||
666 | * Context: !in_interrupt() |
||
667 | * |
||
668 | * Assigns a bus number, and links the controller into usbcore data |
||
669 | * structures so that it can be seen by scanning the bus list. |
||
670 | */ |
||
671 | int usb_register_bus(struct usb_bus *bus) |
||
672 | { |
||
673 | int busnum; |
||
674 | int retval; |
||
675 | |||
676 | down (&usb_bus_list_lock); |
||
677 | |||
678 | busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); |
||
679 | if (busnum < USB_MAXBUS) { |
||
680 | set_bit (busnum, busmap.busmap); |
||
681 | bus->busnum = busnum; |
||
682 | } else |
||
683 | warn ("too many buses"); |
||
684 | |||
685 | snprintf26(bus->class_dev.class_id, BUS_ID_SIZE, "usb%d", busnum); |
||
686 | bus->class_dev.class = &usb_host_class; |
||
687 | bus->class_dev.dev = bus->controller; |
||
688 | retval = class_device_register(&bus->class_dev); |
||
689 | if (retval) { |
||
690 | clear_bit(busnum, busmap.busmap); |
||
691 | up(&usb_bus_list_lock); |
||
692 | return retval; |
||
693 | } |
||
694 | |||
695 | /* Add it to the local list of buses */ |
||
696 | list_add (&bus->bus_list, &usb_bus_list); |
||
697 | up (&usb_bus_list_lock); |
||
698 | usbfs_add_bus (bus); |
||
699 | |||
700 | dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum); |
||
701 | return 0; |
||
702 | } |
||
703 | EXPORT_SYMBOL (usb_register_bus); |
||
704 | |||
705 | /** |
||
706 | * usb_deregister_bus - deregisters the USB host controller |
||
707 | * @bus: pointer to the bus to deregister |
||
708 | * Context: !in_interrupt() |
||
709 | * |
||
710 | * Recycles the bus number, and unlinks the controller from usbcore data |
||
711 | * structures so that it won't be seen by scanning the bus list. |
||
712 | */ |
||
713 | void usb_deregister_bus (struct usb_bus *bus) |
||
714 | { |
||
715 | dev_info (bus->controller, "USB bus %d deregistered\n", bus->busnum); |
||
716 | |||
717 | /* |
||
718 | * NOTE: make sure that all the devices are removed by the |
||
719 | * controller code, as well as having it call this when cleaning |
||
720 | * itself up |
||
721 | */ |
||
722 | down (&usb_bus_list_lock); |
||
723 | list_del (&bus->bus_list); |
||
724 | up (&usb_bus_list_lock); |
||
725 | |||
726 | usbfs_remove_bus (bus); |
||
727 | |||
728 | clear_bit (bus->busnum, busmap.busmap); |
||
729 | |||
730 | class_device_unregister(&bus->class_dev); |
||
731 | } |
||
732 | EXPORT_SYMBOL (usb_deregister_bus); |
||
733 | |||
734 | /** |
||
735 | * usb_register_root_hub - called by HCD to register its root hub |
||
736 | * @usb_dev: the usb root hub device to be registered. |
||
737 | * @parent_dev: the parent device of this root hub. |
||
738 | * |
||
739 | * The USB host controller calls this function to register the root hub |
||
740 | * properly with the USB subsystem. It sets up the device properly in |
||
741 | * the driverfs tree, and then calls usb_new_device() to register the |
||
742 | * usb device. It also assigns the root hub's USB address (always 1). |
||
743 | */ |
||
744 | int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev) |
||
745 | { |
||
746 | const int devnum = 1; |
||
747 | int retval; |
||
748 | |||
749 | sprintf26 (&usb_dev->dev.bus_id[0], "usb%d", usb_dev->bus->busnum); |
||
750 | usb_dev->state = USB_STATE_DEFAULT; |
||
751 | |||
752 | usb_dev->devnum = devnum; |
||
753 | usb_dev->bus->devnum_next = devnum + 1; |
||
754 | set_bit (devnum, usb_dev->bus->devmap.devicemap); |
||
755 | |||
756 | retval = usb_new_device (usb_dev, parent_dev); |
||
757 | |||
758 | if (retval) |
||
759 | dev_err (parent_dev, "can't register root hub for %s, %d\n", |
||
760 | usb_dev->dev.bus_id, retval); |
||
761 | return retval; |
||
762 | } |
||
763 | EXPORT_SYMBOL (usb_register_root_hub); |
||
764 | |||
765 | |||
766 | /*-------------------------------------------------------------------------*/ |
||
767 | |||
768 | /** |
||
769 | * usb_calc_bus_time - approximate periodic transaction time in nanoseconds |
||
770 | * @speed: from dev->speed; USB_SPEED_{LOW,FULL,HIGH} |
||
771 | * @is_input: true iff the transaction sends data to the host |
||
772 | * @isoc: true for isochronous transactions, false for interrupt ones |
||
773 | * @bytecount: how many bytes in the transaction. |
||
774 | * |
||
775 | * Returns approximate bus time in nanoseconds for a periodic transaction. |
||
776 | * See USB 2.0 spec section 5.11.3; only periodic transfers need to be |
||
777 | * scheduled in software, this function is only used for such scheduling. |
||
778 | */ |
||
779 | long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount) |
||
780 | { |
||
781 | unsigned long tmp; |
||
782 | |||
783 | switch (speed) { |
||
784 | case USB_SPEED_LOW: /* INTR only */ |
||
785 | if (is_input) { |
||
786 | tmp = (67667L * (31L + 10L * BitTime (bytecount))) / 1000L; |
||
787 | return (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp); |
||
788 | } else { |
||
789 | tmp = (66700L * (31L + 10L * BitTime (bytecount))) / 1000L; |
||
790 | return (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp); |
||
791 | } |
||
792 | case USB_SPEED_FULL: /* ISOC or INTR */ |
||
793 | if (isoc) { |
||
794 | tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L; |
||
795 | return (((is_input) ? 7268L : 6265L) + BW_HOST_DELAY + tmp); |
||
796 | } else { |
||
797 | tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L; |
||
798 | return (9107L + BW_HOST_DELAY + tmp); |
||
799 | } |
||
800 | case USB_SPEED_HIGH: /* ISOC or INTR */ |
||
801 | // FIXME adjust for input vs output |
||
802 | if (isoc) |
||
803 | tmp = HS_USECS (bytecount); |
||
804 | else |
||
805 | tmp = HS_USECS_ISO (bytecount); |
||
806 | return tmp; |
||
807 | default: |
||
808 | dbg ("bogus device speed!"); |
||
809 | return -1; |
||
810 | } |
||
811 | } |
||
812 | EXPORT_SYMBOL (usb_calc_bus_time); |
||
813 | |||
814 | /* |
||
815 | * usb_check_bandwidth(): |
||
816 | * |
||
817 | * old_alloc is from host_controller->bandwidth_allocated in microseconds; |
||
818 | * bustime is from calc_bus_time(), but converted to microseconds. |
||
819 | * |
||
820 | * returns <bustime in us> if successful, |
||
821 | * or -ENOSPC if bandwidth request fails. |
||
822 | * |
||
823 | * FIXME: |
||
824 | * This initial implementation does not use Endpoint.bInterval |
||
825 | * in managing bandwidth allocation. |
||
826 | * It probably needs to be expanded to use Endpoint.bInterval. |
||
827 | * This can be done as a later enhancement (correction). |
||
828 | * |
||
829 | * This will also probably require some kind of |
||
830 | * frame allocation tracking...meaning, for example, |
||
831 | * that if multiple drivers request interrupts every 10 USB frames, |
||
832 | * they don't all have to be allocated at |
||
833 | * frame numbers N, N+10, N+20, etc. Some of them could be at |
||
834 | * N+11, N+21, N+31, etc., and others at |
||
835 | * N+12, N+22, N+32, etc. |
||
836 | * |
||
837 | * Similarly for isochronous transfers... |
||
838 | * |
||
839 | * Individual HCDs can schedule more directly ... this logic |
||
840 | * is not correct for high speed transfers. |
||
841 | */ |
||
842 | int usb_check_bandwidth (struct usb_device *dev, struct urb *urb) |
||
843 | { |
||
844 | unsigned int pipe = urb->pipe; |
||
845 | long bustime; |
||
846 | int is_in = usb_pipein (pipe); |
||
847 | int is_iso = usb_pipeisoc (pipe); |
||
848 | int old_alloc = dev->bus->bandwidth_allocated; |
||
849 | int new_alloc; |
||
850 | |||
851 | |||
852 | bustime = NS_TO_US (usb_calc_bus_time (dev->speed, is_in, is_iso, |
||
853 | usb_maxpacket (dev, pipe, !is_in))); |
||
854 | if (is_iso) |
||
855 | bustime /= urb->number_of_packets; |
||
856 | |||
857 | new_alloc = old_alloc + (int) bustime; |
||
858 | if (new_alloc > FRAME_TIME_MAX_USECS_ALLOC) { |
||
859 | #ifdef DEBUG |
||
860 | char *mode = |
||
861 | #ifdef CONFIG_USB_BANDWIDTH |
||
862 | ""; |
||
863 | #else |
||
864 | "would have "; |
||
865 | #endif |
||
866 | dev_dbg (&dev->dev, "usb_check_bandwidth %sFAILED: %d + %ld = %d usec\n", |
||
867 | mode, old_alloc, bustime, new_alloc); |
||
868 | #endif |
||
869 | #ifdef CONFIG_USB_BANDWIDTH |
||
870 | bustime = -ENOSPC; /* report error */ |
||
871 | #endif |
||
872 | } |
||
873 | |||
874 | return bustime; |
||
875 | } |
||
876 | EXPORT_SYMBOL (usb_check_bandwidth); |
||
877 | |||
878 | |||
879 | /** |
||
880 | * usb_claim_bandwidth - records bandwidth for a periodic transfer |
||
881 | * @dev: source/target of request |
||
882 | * @urb: request (urb->dev == dev) |
||
883 | * @bustime: bandwidth consumed, in (average) microseconds per frame |
||
884 | * @isoc: true iff the request is isochronous |
||
885 | * |
||
886 | * Bus bandwidth reservations are recorded purely for diagnostic purposes. |
||
887 | * HCDs are expected not to overcommit periodic bandwidth, and to record such |
||
888 | * reservations whenever endpoints are added to the periodic schedule. |
||
889 | * |
||
890 | * FIXME averaging per-frame is suboptimal. Better to sum over the HCD's |
||
891 | * entire periodic schedule ... 32 frames for OHCI, 1024 for UHCI, settable |
||
892 | * for EHCI (256/512/1024 frames, default 1024) and have the bus expose how |
||
893 | * large its periodic schedule is. |
||
894 | */ |
||
895 | void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc) |
||
896 | { |
||
897 | dev->bus->bandwidth_allocated += bustime; |
||
898 | if (isoc) |
||
899 | dev->bus->bandwidth_isoc_reqs++; |
||
900 | else |
||
901 | dev->bus->bandwidth_int_reqs++; |
||
902 | urb->bandwidth = bustime; |
||
903 | |||
904 | #ifdef USB_BANDWIDTH_MESSAGES |
||
905 | dev_dbg (&dev->dev, "bandwidth alloc increased by %d (%s) to %d for %d requesters\n", |
||
906 | bustime, |
||
907 | isoc ? "ISOC" : "INTR", |
||
908 | dev->bus->bandwidth_allocated, |
||
909 | dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs); |
||
910 | #endif |
||
911 | } |
||
912 | EXPORT_SYMBOL (usb_claim_bandwidth); |
||
913 | |||
914 | |||
915 | /** |
||
916 | * usb_release_bandwidth - reverses effect of usb_claim_bandwidth() |
||
917 | * @dev: source/target of request |
||
918 | * @urb: request (urb->dev == dev) |
||
919 | * @isoc: true iff the request is isochronous |
||
920 | * |
||
921 | * This records that previously allocated bandwidth has been released. |
||
922 | * Bandwidth is released when endpoints are removed from the host controller's |
||
923 | * periodic schedule. |
||
924 | */ |
||
925 | void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, int isoc) |
||
926 | { |
||
927 | dev->bus->bandwidth_allocated -= urb->bandwidth; |
||
928 | if (isoc) |
||
929 | dev->bus->bandwidth_isoc_reqs--; |
||
930 | else |
||
931 | dev->bus->bandwidth_int_reqs--; |
||
932 | |||
933 | #ifdef USB_BANDWIDTH_MESSAGES |
||
934 | dev_dbg (&dev->dev, "bandwidth alloc reduced by %d (%s) to %d for %d requesters\n", |
||
935 | urb->bandwidth, |
||
936 | isoc ? "ISOC" : "INTR", |
||
937 | dev->bus->bandwidth_allocated, |
||
938 | dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs); |
||
939 | #endif |
||
940 | urb->bandwidth = 0; |
||
941 | } |
||
942 | EXPORT_SYMBOL (usb_release_bandwidth); |
||
943 | |||
944 | |||
945 | /*-------------------------------------------------------------------------*/ |
||
946 | |||
947 | /* |
||
948 | * Generic HC operations. |
||
949 | */ |
||
950 | |||
951 | /*-------------------------------------------------------------------------*/ |
||
952 | |||
953 | /* called from khubd, or root hub init threads for hcd-private init */ |
||
954 | static int hcd_alloc_dev (struct usb_device *udev) |
||
955 | { |
||
956 | struct hcd_dev *dev; |
||
957 | struct usb_hcd *hcd; |
||
958 | unsigned long flags; |
||
959 | |||
960 | if (!udev || udev->hcpriv) |
||
961 | return -EINVAL; |
||
962 | if (!udev->bus || !udev->bus->hcpriv) |
||
963 | return -ENODEV; |
||
964 | hcd = udev->bus->hcpriv; |
||
965 | if (hcd->state == USB_STATE_QUIESCING) |
||
966 | return -ENOLINK; |
||
967 | |||
968 | dev = (struct hcd_dev *) kmalloc (sizeof *dev, GFP_KERNEL); |
||
969 | if (dev == NULL) |
||
970 | return -ENOMEM; |
||
971 | memset (dev, 0, sizeof *dev); |
||
972 | |||
973 | INIT_LIST_HEAD (&dev->dev_list); |
||
974 | INIT_LIST_HEAD (&dev->urb_list); |
||
975 | |||
976 | spin_lock_irqsave (&hcd_data_lock, flags); |
||
977 | list_add (&dev->dev_list, &hcd->dev_list); |
||
978 | // refcount is implicit |
||
979 | udev->hcpriv = dev; |
||
980 | spin_unlock_irqrestore (&hcd_data_lock, flags); |
||
981 | |||
982 | return 0; |
||
983 | } |
||
984 | |||
985 | /*-------------------------------------------------------------------------*/ |
||
986 | |||
987 | static void urb_unlink (struct urb *urb) |
||
988 | { |
||
989 | unsigned long flags; |
||
990 | struct usb_device *dev; |
||
991 | |||
992 | /* Release any periodic transfer bandwidth */ |
||
993 | if (urb->bandwidth) |
||
994 | usb_release_bandwidth (urb->dev, urb, |
||
995 | usb_pipeisoc (urb->pipe)); |
||
996 | |||
997 | /* clear all state linking urb to this dev (and hcd) */ |
||
998 | |||
999 | spin_lock_irqsave (&hcd_data_lock, flags); |
||
1000 | list_del_init (&urb->urb_list); |
||
1001 | dev = urb->dev; |
||
1002 | spin_unlock_irqrestore (&hcd_data_lock, flags); |
||
1003 | usb_put_dev (dev); |
||
1004 | } |
||
1005 | |||
1006 | |||
1007 | /* may be called in any context with a valid urb->dev usecount |
||
1008 | * caller surrenders "ownership" of urb |
||
1009 | * expects usb_submit_urb() to have sanity checked and conditioned all |
||
1010 | * inputs in the urb |
||
1011 | */ |
||
1012 | static int hcd_submit_urb (struct urb *urb, int mem_flags) |
||
1013 | { |
||
1014 | int status; |
||
1015 | struct usb_hcd *hcd = urb->dev->bus->hcpriv; |
||
1016 | struct hcd_dev *dev = urb->dev->hcpriv; |
||
1017 | unsigned long flags; |
||
1018 | |||
1019 | if (!hcd || !dev) |
||
1020 | return -ENODEV; |
||
1021 | |||
1022 | /* |
||
1023 | * FIXME: make urb timeouts be generic, keeping the HCD cores |
||
1024 | * as simple as possible. |
||
1025 | */ |
||
1026 | |||
1027 | // NOTE: a generic device/urb monitoring hook would go here. |
||
1028 | // hcd_monitor_hook(MONITOR_URB_SUBMIT, urb) |
||
1029 | // It would catch submission paths for all urbs. |
||
1030 | |||
1031 | /* |
||
1032 | * Atomically queue the urb, first to our records, then to the HCD. |
||
1033 | * Access to urb->status is controlled by urb->lock ... changes on |
||
1034 | * i/o completion (normal or fault) or unlinking. |
||
1035 | */ |
||
1036 | |||
1037 | // FIXME: verify that quiescing hc works right (RH cleans up) |
||
1038 | spin_lock_irqsave (&hcd_data_lock, flags); |
||
1039 | if (HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_QUIESCING) { |
||
1040 | usb_get_dev (urb->dev); |
||
1041 | list_add_tail (&urb->urb_list, &dev->urb_list); |
||
1042 | status = 0; |
||
1043 | } else { |
||
1044 | INIT_LIST_HEAD (&urb->urb_list); |
||
1045 | status = -ESHUTDOWN; |
||
1046 | } |
||
1047 | spin_unlock_irqrestore (&hcd_data_lock, flags); |
||
1048 | if (status) |
||
1049 | return status; |
||
1050 | |||
1051 | /* increment urb's reference count as part of giving it to the HCD |
||
1052 | * (which now controls it). HCD guarantees that it either returns |
||
1053 | * an error or calls giveback(), but not both. |
||
1054 | */ |
||
1055 | urb = usb_get_urb (urb); |
||
1056 | if (urb->dev == hcd->self.root_hub) { |
||
1057 | /* NOTE: requirement on hub callers (usbfs and the hub |
||
1058 | * driver, for now) that URBs' urb->transfer_buffer be |
||
1059 | * valid and usb_buffer_{sync,unmap}() not be needed, since |
||
1060 | * they could clobber root hub response data. |
||
1061 | */ |
||
1062 | urb->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP |
||
1063 | | URB_NO_SETUP_DMA_MAP); |
||
1064 | status = rh_urb_enqueue (hcd, urb); |
||
1065 | goto done; |
||
1066 | } |
||
1067 | |||
1068 | /* lower level hcd code should use *_dma exclusively, |
||
1069 | * unless it uses pio or talks to another transport. |
||
1070 | */ |
||
1071 | if (hcd->controller->dma_mask) { |
||
1072 | if (usb_pipecontrol (urb->pipe) |
||
1073 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) |
||
1074 | urb->setup_dma = dma_map_single ( |
||
1075 | hcd->controller, |
||
1076 | urb->setup_packet, |
||
1077 | sizeof (struct usb_ctrlrequest), |
||
1078 | DMA_TO_DEVICE); |
||
1079 | if (urb->transfer_buffer_length != 0 |
||
1080 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) |
||
1081 | urb->transfer_dma = dma_map_single ( |
||
1082 | hcd->controller, |
||
1083 | urb->transfer_buffer, |
||
1084 | urb->transfer_buffer_length, |
||
1085 | usb_pipein (urb->pipe) |
||
1086 | ? DMA_FROM_DEVICE |
||
1087 | : DMA_TO_DEVICE); |
||
1088 | } |
||
1089 | status = hcd->driver->urb_enqueue (hcd, urb, mem_flags); |
||
1090 | |||
1091 | done: |
||
1092 | if (status) { |
||
1093 | usb_put_urb (urb); |
||
1094 | urb_unlink (urb); |
||
1095 | } |
||
1096 | return status; |
||
1097 | } |
||
1098 | |||
1099 | /*-------------------------------------------------------------------------*/ |
||
1100 | |||
1101 | /* called in any context */ |
||
1102 | static int hcd_get_frame_number (struct usb_device *udev) |
||
1103 | { |
||
1104 | struct usb_hcd *hcd = (struct usb_hcd *)udev->bus->hcpriv; |
||
1105 | if (!HCD_IS_RUNNING (hcd->state)) |
||
1106 | return -ESHUTDOWN; |
||
1107 | return hcd->driver->get_frame_number (hcd); |
||
1108 | } |
||
1109 | |||
1110 | /*-------------------------------------------------------------------------*/ |
||
1111 | |||
1112 | /* this makes the hcd giveback() the urb more quickly, by kicking it |
||
1113 | * off hardware queues (which may take a while) and returning it as |
||
1114 | * soon as practical. we've already set up the urb's return status, |
||
1115 | * but we can't know if the callback completed already. |
||
1116 | */ |
||
1117 | static void |
||
1118 | unlink1 (struct usb_hcd *hcd, struct urb *urb) |
||
1119 | { |
||
1120 | if (urb == (struct urb *) hcd->rh_timer.data) |
||
1121 | usb_rh_status_dequeue (hcd, urb); |
||
1122 | else { |
||
1123 | int value; |
||
1124 | |||
1125 | /* failures "should" be harmless */ |
||
1126 | value = hcd->driver->urb_dequeue (hcd, urb); |
||
1127 | if (value != 0) |
||
1128 | dev_dbg (hcd->controller, |
||
1129 | "dequeue %p --> %d\n", |
||
1130 | urb, value); |
||
1131 | } |
||
1132 | } |
||
1133 | |||
1134 | struct completion_splice { // modified urb context: |
||
1135 | /* did we complete? */ |
||
1136 | struct completion done; |
||
1137 | |||
1138 | /* original urb data */ |
||
1139 | usb_complete_t complete; |
||
1140 | void *context; |
||
1141 | }; |
||
1142 | |||
1143 | static void unlink_complete (struct urb *urb, struct pt_regs *regs) |
||
1144 | { |
||
1145 | struct completion_splice *splice; |
||
1146 | |||
1147 | splice = (struct completion_splice *) urb->context; |
||
1148 | |||
1149 | /* issue original completion call */ |
||
1150 | urb->complete = splice->complete; |
||
1151 | urb->context = splice->context; |
||
1152 | urb->complete (urb, regs); |
||
1153 | |||
1154 | /* then let the synchronous unlink call complete */ |
||
1155 | complete (&splice->done); |
||
1156 | } |
||
1157 | |||
1158 | /* |
||
1159 | * called in any context; note ASYNC_UNLINK restrictions |
||
1160 | * |
||
1161 | * caller guarantees urb won't be recycled till both unlink() |
||
1162 | * and the urb's completion function return |
||
1163 | */ |
||
1164 | static int hcd_unlink_urb (struct urb *urb) |
||
1165 | { |
||
1166 | struct hcd_dev *dev; |
||
1167 | struct usb_hcd *hcd = 0; |
||
1168 | struct device *sys = 0; |
||
1169 | unsigned long flags; |
||
1170 | struct completion_splice splice; |
||
1049 | mauro | 1171 | struct list_head *tmp; /* 2.6.1 */ |
846 | giacomo | 1172 | int retval; |
1173 | |||
1174 | if (!urb) |
||
1175 | return -EINVAL; |
||
1176 | |||
1177 | /* |
||
1178 | * we contend for urb->status with the hcd core, |
||
1179 | * which changes it while returning the urb. |
||
1180 | * |
||
1181 | * Caller guaranteed that the urb pointer hasn't been freed, and |
||
1182 | * that it was submitted. But as a rule it can't know whether or |
||
1183 | * not it's already been unlinked ... so we respect the reversed |
||
1184 | * lock sequence needed for the usb_hcd_giveback_urb() code paths |
||
1185 | * (urb lock, then hcd_data_lock) in case some other CPU is now |
||
1186 | * unlinking it. |
||
1187 | */ |
||
1188 | spin_lock_irqsave (&urb->lock, flags); |
||
1189 | spin_lock (&hcd_data_lock); |
||
1190 | |||
1191 | if (!urb->dev || !urb->dev->bus) { |
||
1192 | retval = -ENODEV; |
||
1193 | goto done; |
||
1194 | } |
||
1195 | |||
1196 | dev = urb->dev->hcpriv; |
||
1197 | sys = &urb->dev->dev; |
||
1198 | hcd = urb->dev->bus->hcpriv; |
||
1199 | if (!dev || !hcd) { |
||
1200 | retval = -ENODEV; |
||
1201 | goto done; |
||
1202 | } |
||
1203 | |||
1204 | /* running ~= hc unlink handshake works (irq, timer, etc) |
||
1205 | * halted ~= no unlink handshake is needed |
||
1206 | * suspended, resuming == should never happen |
||
1207 | */ |
||
1208 | WARN_ON (!HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_HALT); |
||
1209 | |||
1049 | mauro | 1210 | /* insist the urb is still queued */ |
1211 | list_for_each(tmp, &dev->urb_list) { |
||
1212 | if (tmp == &urb->urb_list) |
||
1213 | break; |
||
1214 | } |
||
1215 | if (tmp != &urb->urb_list) { |
||
1216 | retval = -EINVAL; |
||
1217 | goto done; |
||
1218 | } |
||
1219 | |||
1220 | /* removed for 2.6.1 |
||
846 | giacomo | 1221 | if (!urb->hcpriv) { |
1222 | retval = -EINVAL; |
||
1223 | goto done; |
||
1224 | } |
||
1049 | mauro | 1225 | */ |
846 | giacomo | 1226 | |
1227 | /* Any status except -EINPROGRESS means something already started to |
||
1228 | * unlink this URB from the hardware. So there's no more work to do. |
||
1229 | * |
||
1230 | * FIXME use better explicit urb state |
||
1231 | */ |
||
1232 | if (urb->status != -EINPROGRESS) { |
||
1233 | retval = -EBUSY; |
||
1234 | goto done; |
||
1235 | } |
||
1236 | |||
1237 | /* PCI IRQ setup can easily be broken so that USB controllers |
||
1238 | * never get completion IRQs ... maybe even the ones we need to |
||
1239 | * finish unlinking the initial failed usb_set_address(). |
||
1240 | */ |
||
1241 | if (!hcd->saw_irq) { |
||
1242 | dev_warn (hcd->controller, "Unlink after no-IRQ? " |
||
1243 | "Different ACPI or APIC settings may help." |
||
1244 | "\n"); |
||
1245 | hcd->saw_irq = 1; |
||
1246 | } |
||
1247 | |||
1248 | /* maybe set up to block until the urb's completion fires. the |
||
1249 | * lower level hcd code is always async, locking on urb->status |
||
1250 | * updates; an intercepted completion unblocks us. |
||
1251 | */ |
||
1252 | if (!(urb->transfer_flags & URB_ASYNC_UNLINK)) { |
||
1253 | if (in_interrupt ()) { |
||
1254 | dev_dbg (hcd->controller, "non-async unlink in_interrupt"); |
||
1255 | retval = -EWOULDBLOCK; |
||
1256 | goto done; |
||
1257 | } |
||
1258 | /* synchronous unlink: block till we see the completion */ |
||
1259 | init_completion (&splice.done); |
||
1260 | splice.complete = urb->complete; |
||
1261 | splice.context = urb->context; |
||
1262 | urb->complete = unlink_complete; |
||
1263 | urb->context = &splice; |
||
1264 | urb->status = -ENOENT; |
||
1265 | } else { |
||
1266 | /* asynchronous unlink */ |
||
1267 | urb->status = -ECONNRESET; |
||
1268 | } |
||
1269 | |||
1270 | spin_unlock (&hcd_data_lock); |
||
1271 | spin_unlock_irqrestore (&urb->lock, flags); |
||
1272 | // FIXME remove splicing, so this becomes unlink1 (hcd, urb); |
||
1273 | if (urb == (struct urb *) hcd->rh_timer.data) { |
||
1274 | usb_rh_status_dequeue (hcd, urb); |
||
1275 | retval = 0; |
||
1276 | } else { |
||
1277 | retval = hcd->driver->urb_dequeue (hcd, urb); |
||
1278 | /* hcds shouldn't really fail these calls, but... */ |
||
1279 | if (retval) { |
||
1280 | dev_dbg (sys, "dequeue %p --> %d\n", urb, retval); |
||
1281 | if (!(urb->transfer_flags & URB_ASYNC_UNLINK)) { |
||
1282 | spin_lock_irqsave (&urb->lock, flags); |
||
1283 | urb->complete = splice.complete; |
||
1284 | urb->context = splice.context; |
||
1285 | spin_unlock_irqrestore (&urb->lock, flags); |
||
1286 | } |
||
1287 | goto bye; |
||
1288 | } |
||
1289 | } |
||
1290 | |||
1291 | /* block till giveback, if needed */ |
||
1292 | if (urb->transfer_flags & URB_ASYNC_UNLINK) |
||
1293 | return -EINPROGRESS; |
||
1294 | wait_for_completion (&splice.done); |
||
1295 | return 0; |
||
1296 | |||
1297 | done: |
||
1298 | spin_unlock (&hcd_data_lock); |
||
1299 | spin_unlock_irqrestore (&urb->lock, flags); |
||
1300 | bye: |
||
1301 | if (retval && sys && sys->driver) |
||
1302 | dev_dbg (sys, "hcd_unlink_urb %p fail %d\n", urb, retval); |
||
1303 | return retval; |
||
1304 | } |
||
1305 | |||
1306 | /*-------------------------------------------------------------------------*/ |
||
1307 | |||
1308 | /* disables the endpoint: cancels any pending urbs, then synchronizes with |
||
1309 | * the hcd to make sure all endpoint state is gone from hardware. use for |
||
1310 | * set_configuration, set_interface, driver removal, physical disconnect. |
||
1311 | * |
||
1312 | * example: a qh stored in hcd_dev.ep[], holding state related to endpoint |
||
1313 | * type, maxpacket size, toggle, halt status, and scheduling. |
||
1314 | */ |
||
1315 | static void hcd_endpoint_disable (struct usb_device *udev, int endpoint) |
||
1316 | { |
||
1317 | struct hcd_dev *dev; |
||
1318 | struct usb_hcd *hcd; |
||
1319 | struct urb *urb; |
||
1320 | unsigned epnum = endpoint & USB_ENDPOINT_NUMBER_MASK; |
||
1321 | |||
1322 | dev = udev->hcpriv; |
||
1323 | hcd = udev->bus->hcpriv; |
||
1324 | |||
1325 | WARN_ON (!HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_HALT); |
||
1326 | |||
1327 | local_irq_disable (); |
||
1328 | |||
1329 | rescan: |
||
1330 | /* (re)block new requests, as best we can */ |
||
1331 | if (endpoint & USB_DIR_IN) { |
||
1332 | usb_endpoint_halt (udev, epnum, 0); |
||
1333 | udev->epmaxpacketin [epnum] = 0; |
||
1334 | } else { |
||
1335 | usb_endpoint_halt (udev, epnum, 1); |
||
1336 | udev->epmaxpacketout [epnum] = 0; |
||
1337 | } |
||
1338 | |||
1339 | /* then kill any current requests */ |
||
1340 | spin_lock (&hcd_data_lock); |
||
1341 | list_for_each_entry (urb, &dev->urb_list, urb_list) { |
||
1342 | int tmp = urb->pipe; |
||
1343 | |||
1344 | /* ignore urbs for other endpoints */ |
||
1345 | if (usb_pipeendpoint (tmp) != epnum) |
||
1346 | continue; |
||
1347 | /* NOTE assumption that only ep0 is a control endpoint */ |
||
1348 | if (epnum != 0 && ((tmp ^ endpoint) & USB_DIR_IN)) |
||
1349 | continue; |
||
1350 | |||
1351 | /* another cpu may be in hcd, spinning on hcd_data_lock |
||
1352 | * to giveback() this urb. the races here should be |
||
1353 | * small, but a full fix needs a new "can't submit" |
||
1354 | * urb state. |
||
1355 | */ |
||
1356 | if (urb->status != -EINPROGRESS) |
||
1357 | continue; |
||
1358 | usb_get_urb (urb); |
||
1359 | spin_unlock (&hcd_data_lock); |
||
1360 | |||
1361 | spin_lock (&urb->lock); |
||
1362 | tmp = urb->status; |
||
1363 | if (tmp == -EINPROGRESS) |
||
1364 | urb->status = -ESHUTDOWN; |
||
1365 | spin_unlock (&urb->lock); |
||
1366 | |||
1367 | /* kick hcd unless it's already returning this */ |
||
1368 | if (tmp == -EINPROGRESS) { |
||
1369 | tmp = urb->pipe; |
||
1370 | unlink1 (hcd, urb); |
||
1371 | dev_dbg (hcd->controller, |
||
1372 | "shutdown urb %p pipe %08x ep%d%s%s\n", |
||
1373 | urb, tmp, usb_pipeendpoint (tmp), |
||
1374 | (tmp & USB_DIR_IN) ? "in" : "out", |
||
1375 | ({ char *s; \ |
||
1376 | switch (usb_pipetype (tmp)) { \ |
||
1377 | case PIPE_CONTROL: s = ""; break; \ |
||
1378 | case PIPE_BULK: s = "-bulk"; break; \ |
||
1379 | case PIPE_INTERRUPT: s = "-intr"; break; \ |
||
1380 | default: s = "-iso"; break; \ |
||
1381 | }; s;})); |
||
1382 | } |
||
1383 | usb_put_urb (urb); |
||
1384 | |||
1385 | /* list contents may have changed */ |
||
1386 | goto rescan; |
||
1387 | } |
||
1388 | spin_unlock (&hcd_data_lock); |
||
1389 | local_irq_enable (); |
||
1390 | |||
1391 | /* synchronize with the hardware, so old configuration state |
||
1392 | * clears out immediately (and will be freed). |
||
1393 | */ |
||
1394 | might_sleep (); |
||
1395 | if (hcd->driver->endpoint_disable) |
||
1396 | hcd->driver->endpoint_disable (hcd, dev, endpoint); |
||
1397 | } |
||
1398 | |||
1399 | /*-------------------------------------------------------------------------*/ |
||
1400 | |||
1401 | /* called by khubd, rmmod, apmd, or other thread for hcd-private cleanup. |
||
1402 | * we're guaranteed that the device is fully quiesced. also, that each |
||
1403 | * endpoint has been hcd_endpoint_disabled. |
||
1404 | */ |
||
1405 | |||
1406 | static int hcd_free_dev (struct usb_device *udev) |
||
1407 | { |
||
1408 | struct hcd_dev *dev; |
||
1409 | struct usb_hcd *hcd; |
||
1410 | unsigned long flags; |
||
1411 | |||
1412 | if (!udev || !udev->hcpriv) |
||
1413 | return -EINVAL; |
||
1414 | |||
1415 | if (!udev->bus || !udev->bus->hcpriv) |
||
1416 | return -ENODEV; |
||
1417 | |||
1418 | // should udev->devnum == -1 ?? |
||
1419 | |||
1420 | dev = udev->hcpriv; |
||
1421 | hcd = udev->bus->hcpriv; |
||
1422 | |||
1423 | /* device driver problem with refcounts? */ |
||
1424 | if (!list_empty (&dev->urb_list)) { |
||
1425 | dev_dbg (hcd->controller, "free busy dev, %s devnum %d (bug!)\n", |
||
1426 | hcd->self.bus_name, udev->devnum); |
||
1427 | return -EINVAL; |
||
1428 | } |
||
1429 | |||
1430 | spin_lock_irqsave (&hcd_data_lock, flags); |
||
1431 | list_del (&dev->dev_list); |
||
1432 | udev->hcpriv = NULL; |
||
1433 | spin_unlock_irqrestore (&hcd_data_lock, flags); |
||
1434 | |||
1435 | kfree (dev); |
||
1436 | return 0; |
||
1437 | } |
||
1438 | |||
1439 | /* |
||
1440 | * usb_hcd_operations - adapts usb_bus framework to HCD framework (bus glue) |
||
1441 | * |
||
1442 | * When registering a USB bus through the HCD framework code, use this |
||
1443 | * usb_operations vector. The PCI glue layer does so automatically; only |
||
1444 | * bus glue for non-PCI system busses will need to use this. |
||
1445 | */ |
||
1446 | struct usb_operations usb_hcd_operations = { |
||
1447 | .allocate = hcd_alloc_dev, |
||
1448 | .get_frame_number = hcd_get_frame_number, |
||
1449 | .submit_urb = hcd_submit_urb, |
||
1450 | .unlink_urb = hcd_unlink_urb, |
||
1451 | .deallocate = hcd_free_dev, |
||
1452 | .buffer_alloc = hcd_buffer_alloc, |
||
1453 | .buffer_free = hcd_buffer_free, |
||
1454 | .disable = hcd_endpoint_disable, |
||
1455 | }; |
||
1456 | EXPORT_SYMBOL (usb_hcd_operations); |
||
1457 | |||
1458 | /*-------------------------------------------------------------------------*/ |
||
1459 | |||
1460 | /** |
||
1461 | * usb_hcd_giveback_urb - return URB from HCD to device driver |
||
1462 | * @hcd: host controller returning the URB |
||
1463 | * @urb: urb being returned to the USB device driver. |
||
1464 | * @regs: pt_regs, passed down to the URB completion handler |
||
1465 | * Context: in_interrupt() |
||
1466 | * |
||
1467 | * This hands the URB from HCD to its USB device driver, using its |
||
1468 | * completion function. The HCD has freed all per-urb resources |
||
1469 | * (and is done using urb->hcpriv). It also released all HCD locks; |
||
1470 | * the device driver won't cause problems if it frees, modifies, |
||
1471 | * or resubmits this URB. |
||
1472 | */ |
||
1473 | void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs) |
||
1474 | { |
||
1475 | urb_unlink (urb); |
||
1476 | |||
1477 | // NOTE: a generic device/urb monitoring hook would go here. |
||
1478 | // hcd_monitor_hook(MONITOR_URB_FINISH, urb, dev) |
||
1479 | // It would catch exit/unlink paths for all urbs. |
||
1480 | |||
1481 | |||
1482 | /* lower level hcd code should use *_dma exclusively */ |
||
1483 | if (hcd->controller->dma_mask) { |
||
1484 | if (usb_pipecontrol (urb->pipe) |
||
1485 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) |
||
1486 | pci_unmap_single (hcd->pdev, urb->setup_dma, |
||
1487 | sizeof (struct usb_ctrlrequest), |
||
1488 | PCI_DMA_TODEVICE); |
||
1489 | if (urb->transfer_buffer_length != 0 |
||
1490 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) |
||
1491 | pci_unmap_single (hcd->pdev, urb->transfer_dma, |
||
1492 | urb->transfer_buffer_length, |
||
1493 | usb_pipein (urb->pipe) |
||
1494 | ? PCI_DMA_FROMDEVICE |
||
1495 | : PCI_DMA_TODEVICE); |
||
1496 | } |
||
1497 | /* pass ownership to the completion handler */ |
||
1498 | urb->complete (urb, regs); |
||
1499 | usb_put_urb (urb); |
||
1500 | } |
||
1501 | EXPORT_SYMBOL (usb_hcd_giveback_urb); |
||
1502 | |||
1503 | /*-------------------------------------------------------------------------*/ |
||
1504 | |||
1505 | /** |
||
1506 | * usb_hcd_irq - hook IRQs to HCD framework (bus glue) |
||
1507 | * @irq: the IRQ being raised |
||
1508 | * @__hcd: pointer to the HCD whose IRQ is beinng signaled |
||
1509 | * @r: saved hardware registers |
||
1510 | * |
||
1511 | * When registering a USB bus through the HCD framework code, use this |
||
1512 | * to handle interrupts. The PCI glue layer does so automatically; only |
||
1513 | * bus glue for non-PCI system busses will need to use this. |
||
1514 | */ |
||
1515 | irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r) |
||
1516 | { |
||
1517 | struct usb_hcd *hcd = __hcd; |
||
1518 | int start = hcd->state; |
||
1519 | |||
1520 | if (/*unlikely*/ (hcd->state == USB_STATE_HALT)) /* irq sharing? */ |
||
1521 | return IRQ_NONE; |
||
1522 | |||
1523 | hcd->saw_irq = 1; |
||
1524 | hcd->driver->irq (hcd, r); |
||
1525 | if (hcd->state != start && hcd->state == USB_STATE_HALT) |
||
1526 | usb_hc_died (hcd); |
||
1527 | return IRQ_HANDLED; |
||
1528 | } |
||
1529 | EXPORT_SYMBOL (usb_hcd_irq); |
||
1530 | |||
1531 | /*-------------------------------------------------------------------------*/ |
||
1532 | |||
1533 | static void hcd_panic (void *_hcd) |
||
1534 | { |
||
1535 | struct usb_hcd *hcd = _hcd; |
||
1536 | struct usb_device *hub = hcd->self.root_hub; |
||
1537 | unsigned i; |
||
1538 | |||
1539 | /* hc's root hub is removed later removed in hcd->stop() */ |
||
1540 | hub->state = USB_STATE_NOTATTACHED; |
||
1541 | for (i = 0; i < hub->maxchild; i++) { |
||
1542 | if (hub->children [i]) |
||
1543 | usb_disconnect (&hub->children [i]); |
||
1544 | } |
||
1545 | } |
||
1546 | |||
1547 | /** |
||
1548 | * usb_hc_died - report abnormal shutdown of a host controller (bus glue) |
||
1549 | * @hcd: pointer to the HCD representing the controller |
||
1550 | * |
||
1551 | * This is called by bus glue to report a USB host controller that died |
||
1552 | * while operations may still have been pending. It's called automatically |
||
1553 | * by the PCI glue, so only glue for non-PCI busses should need to call it. |
||
1554 | */ |
||
1555 | void usb_hc_died (struct usb_hcd *hcd) |
||
1556 | { |
||
1557 | dev_err (hcd->controller, "HC died; cleaning up\n"); |
||
1558 | |||
1559 | /* clean up old urbs and devices; needs a task context */ |
||
1560 | INIT_WORK (&hcd->work, hcd_panic, hcd); |
||
1561 | (void) schedule_work (&hcd->work); |
||
1562 | } |
||
1563 | EXPORT_SYMBOL (usb_hc_died); |
||
1564 |