Deleted Added
full compact
usb_controller.c (193074) usb_controller.c (194228)
1/* $FreeBSD: head/sys/dev/usb/controller/usb_controller.c 193074 2009-05-30 00:22:57Z thompsa $ */
1/* $FreeBSD: head/sys/dev/usb/controller/usb_controller.c 194228 2009-06-15 01:02:43Z thompsa $ */
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 13 unchanged lines hidden (view full) ---

23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <dev/usb/usb_mfunc.h>
28#include <dev/usb/usb_error.h>
29#include <dev/usb/usb.h>
30
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 13 unchanged lines hidden (view full) ---

23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <dev/usb/usb_mfunc.h>
28#include <dev/usb/usb_error.h>
29#include <dev/usb/usb.h>
30
31#define USB_DEBUG_VAR usb2_ctrl_debug
31#define USB_DEBUG_VAR usb_ctrl_debug
32
33#include <dev/usb/usb_core.h>
34#include <dev/usb/usb_debug.h>
35#include <dev/usb/usb_process.h>
36#include <dev/usb/usb_busdma.h>
37#include <dev/usb/usb_dynamic.h>
38#include <dev/usb/usb_device.h>
39#include <dev/usb/usb_hub.h>
40
41#include <dev/usb/usb_controller.h>
42#include <dev/usb/usb_bus.h>
43
44/* function prototypes */
45
32
33#include <dev/usb/usb_core.h>
34#include <dev/usb/usb_debug.h>
35#include <dev/usb/usb_process.h>
36#include <dev/usb/usb_busdma.h>
37#include <dev/usb/usb_dynamic.h>
38#include <dev/usb/usb_device.h>
39#include <dev/usb/usb_hub.h>
40
41#include <dev/usb/usb_controller.h>
42#include <dev/usb/usb_bus.h>
43
44/* function prototypes */
45
46static device_probe_t usb2_probe;
47static device_attach_t usb2_attach;
48static device_detach_t usb2_detach;
46static device_probe_t usb_probe;
47static device_attach_t usb_attach;
48static device_detach_t usb_detach;
49
49
50static void usb2_attach_sub(device_t, struct usb_bus *);
51static void usb2_post_init(void *);
50static void usb_attach_sub(device_t, struct usb_bus *);
51static void usb_post_init(void *);
52
53/* static variables */
54
55#if USB_DEBUG
52
53/* static variables */
54
55#if USB_DEBUG
56static int usb2_ctrl_debug = 0;
56static int usb_ctrl_debug = 0;
57
58SYSCTL_NODE(_hw_usb, OID_AUTO, ctrl, CTLFLAG_RW, 0, "USB controller");
57
58SYSCTL_NODE(_hw_usb, OID_AUTO, ctrl, CTLFLAG_RW, 0, "USB controller");
59SYSCTL_INT(_hw_usb_ctrl, OID_AUTO, debug, CTLFLAG_RW, &usb2_ctrl_debug, 0,
59SYSCTL_INT(_hw_usb_ctrl, OID_AUTO, debug, CTLFLAG_RW, &usb_ctrl_debug, 0,
60 "Debug level");
61#endif
62
60 "Debug level");
61#endif
62
63static uint8_t usb2_post_init_called = 0;
63static uint8_t usb_post_init_called = 0;
64
64
65static devclass_t usb2_devclass;
65static devclass_t usb_devclass;
66
66
67static device_method_t usb2_methods[] = {
68 DEVMETHOD(device_probe, usb2_probe),
69 DEVMETHOD(device_attach, usb2_attach),
70 DEVMETHOD(device_detach, usb2_detach),
67static device_method_t usb_methods[] = {
68 DEVMETHOD(device_probe, usb_probe),
69 DEVMETHOD(device_attach, usb_attach),
70 DEVMETHOD(device_detach, usb_detach),
71 DEVMETHOD(device_suspend, bus_generic_suspend),
72 DEVMETHOD(device_resume, bus_generic_resume),
73 DEVMETHOD(device_shutdown, bus_generic_shutdown),
74 {0, 0}
75};
76
71 DEVMETHOD(device_suspend, bus_generic_suspend),
72 DEVMETHOD(device_resume, bus_generic_resume),
73 DEVMETHOD(device_shutdown, bus_generic_shutdown),
74 {0, 0}
75};
76
77static driver_t usb2_driver = {
77static driver_t usb_driver = {
78 .name = "usbus",
78 .name = "usbus",
79 .methods = usb2_methods,
79 .methods = usb_methods,
80 .size = 0,
81};
82
80 .size = 0,
81};
82
83DRIVER_MODULE(usbus, ohci, usb2_driver, usb2_devclass, 0, 0);
84DRIVER_MODULE(usbus, uhci, usb2_driver, usb2_devclass, 0, 0);
85DRIVER_MODULE(usbus, ehci, usb2_driver, usb2_devclass, 0, 0);
86DRIVER_MODULE(usbus, at91_udp, usb2_driver, usb2_devclass, 0, 0);
87DRIVER_MODULE(usbus, uss820, usb2_driver, usb2_devclass, 0, 0);
83DRIVER_MODULE(usbus, ohci, usb_driver, usb_devclass, 0, 0);
84DRIVER_MODULE(usbus, uhci, usb_driver, usb_devclass, 0, 0);
85DRIVER_MODULE(usbus, ehci, usb_driver, usb_devclass, 0, 0);
86DRIVER_MODULE(usbus, at91_udp, usb_driver, usb_devclass, 0, 0);
87DRIVER_MODULE(usbus, uss820, usb_driver, usb_devclass, 0, 0);
88
89/*------------------------------------------------------------------------*
88
89/*------------------------------------------------------------------------*
90 * usb2_probe
90 * usb_probe
91 *
92 * This function is called from "{ehci,ohci,uhci}_pci_attach()".
93 *------------------------------------------------------------------------*/
94static int
91 *
92 * This function is called from "{ehci,ohci,uhci}_pci_attach()".
93 *------------------------------------------------------------------------*/
94static int
95usb2_probe(device_t dev)
95usb_probe(device_t dev)
96{
97 DPRINTF("\n");
98 return (0);
99}
100
101/*------------------------------------------------------------------------*
96{
97 DPRINTF("\n");
98 return (0);
99}
100
101/*------------------------------------------------------------------------*
102 * usb2_attach
102 * usb_attach
103 *------------------------------------------------------------------------*/
104static int
103 *------------------------------------------------------------------------*/
104static int
105usb2_attach(device_t dev)
105usb_attach(device_t dev)
106{
107 struct usb_bus *bus = device_get_ivars(dev);
108
109 DPRINTF("\n");
110
111 if (bus == NULL) {
112 DPRINTFN(0, "USB device has no ivars\n");
113 return (ENXIO);
114 }
115
116 /* delay vfs_mountroot until the bus is explored */
117 bus->bus_roothold = root_mount_hold(device_get_nameunit(dev));
118
106{
107 struct usb_bus *bus = device_get_ivars(dev);
108
109 DPRINTF("\n");
110
111 if (bus == NULL) {
112 DPRINTFN(0, "USB device has no ivars\n");
113 return (ENXIO);
114 }
115
116 /* delay vfs_mountroot until the bus is explored */
117 bus->bus_roothold = root_mount_hold(device_get_nameunit(dev));
118
119 if (usb2_post_init_called) {
119 if (usb_post_init_called) {
120 mtx_lock(&Giant);
120 mtx_lock(&Giant);
121 usb2_attach_sub(dev, bus);
121 usb_attach_sub(dev, bus);
122 mtx_unlock(&Giant);
122 mtx_unlock(&Giant);
123 usb2_needs_explore(bus, 1);
123 usb_needs_explore(bus, 1);
124 }
125 return (0); /* return success */
126}
127
128/*------------------------------------------------------------------------*
124 }
125 return (0); /* return success */
126}
127
128/*------------------------------------------------------------------------*
129 * usb2_detach
129 * usb_detach
130 *------------------------------------------------------------------------*/
131static int
130 *------------------------------------------------------------------------*/
131static int
132usb2_detach(device_t dev)
132usb_detach(device_t dev)
133{
134 struct usb_bus *bus = device_get_softc(dev);
135
136 DPRINTF("\n");
137
138 if (bus == NULL) {
139 /* was never setup properly */
140 return (0);
141 }
142 /* Stop power watchdog */
133{
134 struct usb_bus *bus = device_get_softc(dev);
135
136 DPRINTF("\n");
137
138 if (bus == NULL) {
139 /* was never setup properly */
140 return (0);
141 }
142 /* Stop power watchdog */
143 usb2_callout_drain(&bus->power_wdog);
143 usb_callout_drain(&bus->power_wdog);
144
145 /* Let the USB explore process detach all devices. */
146 if (bus->bus_roothold != NULL) {
147 root_mount_rel(bus->bus_roothold);
148 bus->bus_roothold = NULL;
149 }
150
151 USB_BUS_LOCK(bus);
144
145 /* Let the USB explore process detach all devices. */
146 if (bus->bus_roothold != NULL) {
147 root_mount_rel(bus->bus_roothold);
148 bus->bus_roothold = NULL;
149 }
150
151 USB_BUS_LOCK(bus);
152 if (usb2_proc_msignal(&bus->explore_proc,
152 if (usb_proc_msignal(&bus->explore_proc,
153 &bus->detach_msg[0], &bus->detach_msg[1])) {
154 /* ignore */
155 }
156 /* Wait for detach to complete */
157
153 &bus->detach_msg[0], &bus->detach_msg[1])) {
154 /* ignore */
155 }
156 /* Wait for detach to complete */
157
158 usb2_proc_mwait(&bus->explore_proc,
158 usb_proc_mwait(&bus->explore_proc,
159 &bus->detach_msg[0], &bus->detach_msg[1]);
160
161 USB_BUS_UNLOCK(bus);
162
163 /* Get rid of USB callback processes */
164
159 &bus->detach_msg[0], &bus->detach_msg[1]);
160
161 USB_BUS_UNLOCK(bus);
162
163 /* Get rid of USB callback processes */
164
165 usb2_proc_free(&bus->giant_callback_proc);
166 usb2_proc_free(&bus->non_giant_callback_proc);
165 usb_proc_free(&bus->giant_callback_proc);
166 usb_proc_free(&bus->non_giant_callback_proc);
167
168 /* Get rid of USB explore process */
169
167
168 /* Get rid of USB explore process */
169
170 usb2_proc_free(&bus->explore_proc);
170 usb_proc_free(&bus->explore_proc);
171
172 /* Get rid of control transfer process */
173
171
172 /* Get rid of control transfer process */
173
174 usb2_proc_free(&bus->control_xfer_proc);
174 usb_proc_free(&bus->control_xfer_proc);
175
176 return (0);
177}
178
179/*------------------------------------------------------------------------*
175
176 return (0);
177}
178
179/*------------------------------------------------------------------------*
180 * usb2_bus_explore
180 * usb_bus_explore
181 *
182 * This function is used to explore the device tree from the root.
183 *------------------------------------------------------------------------*/
184static void
181 *
182 * This function is used to explore the device tree from the root.
183 *------------------------------------------------------------------------*/
184static void
185usb2_bus_explore(struct usb_proc_msg *pm)
185usb_bus_explore(struct usb_proc_msg *pm)
186{
187 struct usb_bus *bus;
188 struct usb_device *udev;
189
190 bus = ((struct usb_bus_msg *)pm)->bus;
191 udev = bus->devices[USB_ROOT_HUB_ADDR];
192
193 if (udev && udev->hub) {

--- 8 unchanged lines hidden (view full) ---

202 }
203 USB_BUS_UNLOCK(bus);
204
205 mtx_lock(&Giant);
206
207 /*
208 * First update the USB power state!
209 */
186{
187 struct usb_bus *bus;
188 struct usb_device *udev;
189
190 bus = ((struct usb_bus_msg *)pm)->bus;
191 udev = bus->devices[USB_ROOT_HUB_ADDR];
192
193 if (udev && udev->hub) {

--- 8 unchanged lines hidden (view full) ---

202 }
203 USB_BUS_UNLOCK(bus);
204
205 mtx_lock(&Giant);
206
207 /*
208 * First update the USB power state!
209 */
210 usb2_bus_powerd(bus);
210 usb_bus_powerd(bus);
211 /*
212 * Explore the Root USB HUB. This call can sleep,
213 * exiting Giant, which is actually Giant.
214 */
215 (udev->hub->explore) (udev);
216
217 mtx_unlock(&Giant);
218
219 USB_BUS_LOCK(bus);
220 }
221 if (bus->bus_roothold != NULL) {
222 root_mount_rel(bus->bus_roothold);
223 bus->bus_roothold = NULL;
224 }
225}
226
227/*------------------------------------------------------------------------*
211 /*
212 * Explore the Root USB HUB. This call can sleep,
213 * exiting Giant, which is actually Giant.
214 */
215 (udev->hub->explore) (udev);
216
217 mtx_unlock(&Giant);
218
219 USB_BUS_LOCK(bus);
220 }
221 if (bus->bus_roothold != NULL) {
222 root_mount_rel(bus->bus_roothold);
223 bus->bus_roothold = NULL;
224 }
225}
226
227/*------------------------------------------------------------------------*
228 * usb2_bus_detach
228 * usb_bus_detach
229 *
230 * This function is used to detach the device tree from the root.
231 *------------------------------------------------------------------------*/
232static void
229 *
230 * This function is used to detach the device tree from the root.
231 *------------------------------------------------------------------------*/
232static void
233usb2_bus_detach(struct usb_proc_msg *pm)
233usb_bus_detach(struct usb_proc_msg *pm)
234{
235 struct usb_bus *bus;
236 struct usb_device *udev;
237 device_t dev;
238
239 bus = ((struct usb_bus_msg *)pm)->bus;
240 udev = bus->devices[USB_ROOT_HUB_ADDR];
241 dev = bus->bdev;

--- 5 unchanged lines hidden (view full) ---

247
248 /* detach children first */
249 bus_generic_detach(dev);
250
251 /*
252 * Free USB Root device, but not any sub-devices, hence they
253 * are freed by the caller of this function:
254 */
234{
235 struct usb_bus *bus;
236 struct usb_device *udev;
237 device_t dev;
238
239 bus = ((struct usb_bus_msg *)pm)->bus;
240 udev = bus->devices[USB_ROOT_HUB_ADDR];
241 dev = bus->bdev;

--- 5 unchanged lines hidden (view full) ---

247
248 /* detach children first */
249 bus_generic_detach(dev);
250
251 /*
252 * Free USB Root device, but not any sub-devices, hence they
253 * are freed by the caller of this function:
254 */
255 usb2_free_device(udev,
255 usb_free_device(udev,
256 USB_UNCFG_FLAG_FREE_EP0);
257
258 mtx_unlock(&Giant);
259 USB_BUS_LOCK(bus);
260 /* clear bdev variable last */
261 bus->bdev = NULL;
262}
263
264static void
256 USB_UNCFG_FLAG_FREE_EP0);
257
258 mtx_unlock(&Giant);
259 USB_BUS_LOCK(bus);
260 /* clear bdev variable last */
261 bus->bdev = NULL;
262}
263
264static void
265usb2_power_wdog(void *arg)
265usb_power_wdog(void *arg)
266{
267 struct usb_bus *bus = arg;
268
269 USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
270
266{
267 struct usb_bus *bus = arg;
268
269 USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
270
271 usb2_callout_reset(&bus->power_wdog,
272 4 * hz, usb2_power_wdog, arg);
271 usb_callout_reset(&bus->power_wdog,
272 4 * hz, usb_power_wdog, arg);
273
274 USB_BUS_UNLOCK(bus);
275
273
274 USB_BUS_UNLOCK(bus);
275
276 usb2_bus_power_update(bus);
276 usb_bus_power_update(bus);
277
278 USB_BUS_LOCK(bus);
279}
280
281/*------------------------------------------------------------------------*
277
278 USB_BUS_LOCK(bus);
279}
280
281/*------------------------------------------------------------------------*
282 * usb2_bus_attach
282 * usb_bus_attach
283 *
284 * This function attaches USB in context of the explore thread.
285 *------------------------------------------------------------------------*/
286static void
283 *
284 * This function attaches USB in context of the explore thread.
285 *------------------------------------------------------------------------*/
286static void
287usb2_bus_attach(struct usb_proc_msg *pm)
287usb_bus_attach(struct usb_proc_msg *pm)
288{
289 struct usb_bus *bus;
290 struct usb_device *child;
291 device_t dev;
292 usb_error_t err;
293 enum usb_dev_speed speed;
294
295 bus = ((struct usb_bus_msg *)pm)->bus;

--- 41 unchanged lines hidden (view full) ---

337 /* make sure power is set at least once */
338
339 if (bus->methods->set_hw_power != NULL) {
340 (bus->methods->set_hw_power) (bus);
341 }
342
343 /* Allocate the Root USB device */
344
288{
289 struct usb_bus *bus;
290 struct usb_device *child;
291 device_t dev;
292 usb_error_t err;
293 enum usb_dev_speed speed;
294
295 bus = ((struct usb_bus_msg *)pm)->bus;

--- 41 unchanged lines hidden (view full) ---

337 /* make sure power is set at least once */
338
339 if (bus->methods->set_hw_power != NULL) {
340 (bus->methods->set_hw_power) (bus);
341 }
342
343 /* Allocate the Root USB device */
344
345 child = usb2_alloc_device(bus->bdev, bus, NULL, 0, 0, 1,
345 child = usb_alloc_device(bus->bdev, bus, NULL, 0, 0, 1,
346 speed, USB_MODE_HOST);
347 if (child) {
346 speed, USB_MODE_HOST);
347 if (child) {
348 err = usb2_probe_and_attach(child,
348 err = usb_probe_and_attach(child,
349 USB_IFACE_INDEX_ANY);
350 if (!err) {
351 if ((bus->devices[USB_ROOT_HUB_ADDR] == NULL) ||
352 (bus->devices[USB_ROOT_HUB_ADDR]->hub == NULL)) {
353 err = USB_ERR_NO_ROOT_HUB;
354 }
355 }
356 } else {
357 err = USB_ERR_NOMEM;
358 }
359
360 mtx_unlock(&Giant);
361 USB_BUS_LOCK(bus);
362
363 if (err) {
364 device_printf(bus->bdev, "Root HUB problem, error=%s\n",
349 USB_IFACE_INDEX_ANY);
350 if (!err) {
351 if ((bus->devices[USB_ROOT_HUB_ADDR] == NULL) ||
352 (bus->devices[USB_ROOT_HUB_ADDR]->hub == NULL)) {
353 err = USB_ERR_NO_ROOT_HUB;
354 }
355 }
356 } else {
357 err = USB_ERR_NOMEM;
358 }
359
360 mtx_unlock(&Giant);
361 USB_BUS_LOCK(bus);
362
363 if (err) {
364 device_printf(bus->bdev, "Root HUB problem, error=%s\n",
365 usb2_errstr(err));
365 usbd_errstr(err));
366 }
367
368 /* set softc - we are ready */
369 device_set_softc(dev, bus);
370
371 /* start watchdog */
366 }
367
368 /* set softc - we are ready */
369 device_set_softc(dev, bus);
370
371 /* start watchdog */
372 usb2_power_wdog(bus);
372 usb_power_wdog(bus);
373}
374
375/*------------------------------------------------------------------------*
373}
374
375/*------------------------------------------------------------------------*
376 * usb2_attach_sub
376 * usb_attach_sub
377 *
378 * This function creates a thread which runs the USB attach code. It
379 * is factored out, hence it can be called at two different places in
380 * time. During bootup this function is called from
377 *
378 * This function creates a thread which runs the USB attach code. It
379 * is factored out, hence it can be called at two different places in
380 * time. During bootup this function is called from
381 * "usb2_post_init". During hot-plug it is called directly from the
382 * "usb2_attach()" method.
381 * "usb_post_init". During hot-plug it is called directly from the
382 * "usb_attach()" method.
383 *------------------------------------------------------------------------*/
384static void
383 *------------------------------------------------------------------------*/
384static void
385usb2_attach_sub(device_t dev, struct usb_bus *bus)
385usb_attach_sub(device_t dev, struct usb_bus *bus)
386{
387 const char *pname = device_get_nameunit(dev);
388
389 /* Initialise USB process messages */
386{
387 const char *pname = device_get_nameunit(dev);
388
389 /* Initialise USB process messages */
390 bus->explore_msg[0].hdr.pm_callback = &usb2_bus_explore;
390 bus->explore_msg[0].hdr.pm_callback = &usb_bus_explore;
391 bus->explore_msg[0].bus = bus;
391 bus->explore_msg[0].bus = bus;
392 bus->explore_msg[1].hdr.pm_callback = &usb2_bus_explore;
392 bus->explore_msg[1].hdr.pm_callback = &usb_bus_explore;
393 bus->explore_msg[1].bus = bus;
394
393 bus->explore_msg[1].bus = bus;
394
395 bus->detach_msg[0].hdr.pm_callback = &usb2_bus_detach;
395 bus->detach_msg[0].hdr.pm_callback = &usb_bus_detach;
396 bus->detach_msg[0].bus = bus;
396 bus->detach_msg[0].bus = bus;
397 bus->detach_msg[1].hdr.pm_callback = &usb2_bus_detach;
397 bus->detach_msg[1].hdr.pm_callback = &usb_bus_detach;
398 bus->detach_msg[1].bus = bus;
399
398 bus->detach_msg[1].bus = bus;
399
400 bus->attach_msg[0].hdr.pm_callback = &usb2_bus_attach;
400 bus->attach_msg[0].hdr.pm_callback = &usb_bus_attach;
401 bus->attach_msg[0].bus = bus;
401 bus->attach_msg[0].bus = bus;
402 bus->attach_msg[1].hdr.pm_callback = &usb2_bus_attach;
402 bus->attach_msg[1].hdr.pm_callback = &usb_bus_attach;
403 bus->attach_msg[1].bus = bus;
404
405 /* Create USB explore and callback processes */
406
403 bus->attach_msg[1].bus = bus;
404
405 /* Create USB explore and callback processes */
406
407 if (usb2_proc_create(&bus->giant_callback_proc,
407 if (usb_proc_create(&bus->giant_callback_proc,
408 &bus->bus_mtx, pname, USB_PRI_MED)) {
409 printf("WARNING: Creation of USB Giant "
410 "callback process failed.\n");
408 &bus->bus_mtx, pname, USB_PRI_MED)) {
409 printf("WARNING: Creation of USB Giant "
410 "callback process failed.\n");
411 } else if (usb2_proc_create(&bus->non_giant_callback_proc,
411 } else if (usb_proc_create(&bus->non_giant_callback_proc,
412 &bus->bus_mtx, pname, USB_PRI_HIGH)) {
413 printf("WARNING: Creation of USB non-Giant "
414 "callback process failed.\n");
412 &bus->bus_mtx, pname, USB_PRI_HIGH)) {
413 printf("WARNING: Creation of USB non-Giant "
414 "callback process failed.\n");
415 } else if (usb2_proc_create(&bus->explore_proc,
415 } else if (usb_proc_create(&bus->explore_proc,
416 &bus->bus_mtx, pname, USB_PRI_MED)) {
417 printf("WARNING: Creation of USB explore "
418 "process failed.\n");
416 &bus->bus_mtx, pname, USB_PRI_MED)) {
417 printf("WARNING: Creation of USB explore "
418 "process failed.\n");
419 } else if (usb2_proc_create(&bus->control_xfer_proc,
419 } else if (usb_proc_create(&bus->control_xfer_proc,
420 &bus->bus_mtx, pname, USB_PRI_MED)) {
421 printf("WARNING: Creation of USB control transfer "
422 "process failed.\n");
423 } else {
424 /* Get final attach going */
425 USB_BUS_LOCK(bus);
420 &bus->bus_mtx, pname, USB_PRI_MED)) {
421 printf("WARNING: Creation of USB control transfer "
422 "process failed.\n");
423 } else {
424 /* Get final attach going */
425 USB_BUS_LOCK(bus);
426 if (usb2_proc_msignal(&bus->explore_proc,
426 if (usb_proc_msignal(&bus->explore_proc,
427 &bus->attach_msg[0], &bus->attach_msg[1])) {
428 /* ignore */
429 }
430 USB_BUS_UNLOCK(bus);
431 }
432}
433
434/*------------------------------------------------------------------------*
427 &bus->attach_msg[0], &bus->attach_msg[1])) {
428 /* ignore */
429 }
430 USB_BUS_UNLOCK(bus);
431 }
432}
433
434/*------------------------------------------------------------------------*
435 * usb2_post_init
435 * usb_post_init
436 *
437 * This function is called to attach all USB busses that were found
438 * during bootup.
439 *------------------------------------------------------------------------*/
440static void
436 *
437 * This function is called to attach all USB busses that were found
438 * during bootup.
439 *------------------------------------------------------------------------*/
440static void
441usb2_post_init(void *arg)
441usb_post_init(void *arg)
442{
443 struct usb_bus *bus;
444 devclass_t dc;
445 device_t dev;
446 int max;
447 int n;
448
449 mtx_lock(&Giant);
450
442{
443 struct usb_bus *bus;
444 devclass_t dc;
445 device_t dev;
446 int max;
447 int n;
448
449 mtx_lock(&Giant);
450
451 usb2_devclass_ptr = devclass_find("usbus");
451 usb_devclass_ptr = devclass_find("usbus");
452
452
453 dc = usb2_devclass_ptr;
453 dc = usb_devclass_ptr;
454 if (dc) {
455 max = devclass_get_maxunit(dc) + 1;
456 for (n = 0; n != max; n++) {
457 dev = devclass_get_device(dc, n);
458 if (dev && device_is_attached(dev)) {
459 bus = device_get_ivars(dev);
460 if (bus) {
461 mtx_lock(&Giant);
454 if (dc) {
455 max = devclass_get_maxunit(dc) + 1;
456 for (n = 0; n != max; n++) {
457 dev = devclass_get_device(dc, n);
458 if (dev && device_is_attached(dev)) {
459 bus = device_get_ivars(dev);
460 if (bus) {
461 mtx_lock(&Giant);
462 usb2_attach_sub(dev, bus);
462 usb_attach_sub(dev, bus);
463 mtx_unlock(&Giant);
464 }
465 }
466 }
467 } else {
468 DPRINTFN(0, "no devclass\n");
469 }
463 mtx_unlock(&Giant);
464 }
465 }
466 }
467 } else {
468 DPRINTFN(0, "no devclass\n");
469 }
470 usb2_post_init_called = 1;
470 usb_post_init_called = 1;
471
472 /* explore all USB busses in parallell */
473
471
472 /* explore all USB busses in parallell */
473
474 usb2_needs_explore_all();
474 usb_needs_explore_all();
475
476 mtx_unlock(&Giant);
477}
478
475
476 mtx_unlock(&Giant);
477}
478
479SYSINIT(usb2_post_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb2_post_init, NULL);
480SYSUNINIT(usb2_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb2_bus_unload, NULL);
479SYSINIT(usb_post_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb_post_init, NULL);
480SYSUNINIT(usb_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb_bus_unload, NULL);
481
482/*------------------------------------------------------------------------*
481
482/*------------------------------------------------------------------------*
483 * usb2_bus_mem_flush_all_cb
483 * usb_bus_mem_flush_all_cb
484 *------------------------------------------------------------------------*/
485#if USB_HAVE_BUSDMA
486static void
484 *------------------------------------------------------------------------*/
485#if USB_HAVE_BUSDMA
486static void
487usb2_bus_mem_flush_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
487usb_bus_mem_flush_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
488 struct usb_page *pg, usb_size_t size, usb_size_t align)
489{
488 struct usb_page *pg, usb_size_t size, usb_size_t align)
489{
490 usb2_pc_cpu_flush(pc);
490 usb_pc_cpu_flush(pc);
491}
492#endif
493
494/*------------------------------------------------------------------------*
491}
492#endif
493
494/*------------------------------------------------------------------------*
495 * usb2_bus_mem_flush_all - factored out code
495 * usb_bus_mem_flush_all - factored out code
496 *------------------------------------------------------------------------*/
497#if USB_HAVE_BUSDMA
498void
496 *------------------------------------------------------------------------*/
497#if USB_HAVE_BUSDMA
498void
499usb2_bus_mem_flush_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
499usb_bus_mem_flush_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
500{
501 if (cb) {
500{
501 if (cb) {
502 cb(bus, &usb2_bus_mem_flush_all_cb);
502 cb(bus, &usb_bus_mem_flush_all_cb);
503 }
504}
505#endif
506
507/*------------------------------------------------------------------------*
503 }
504}
505#endif
506
507/*------------------------------------------------------------------------*
508 * usb2_bus_mem_alloc_all_cb
508 * usb_bus_mem_alloc_all_cb
509 *------------------------------------------------------------------------*/
510#if USB_HAVE_BUSDMA
511static void
509 *------------------------------------------------------------------------*/
510#if USB_HAVE_BUSDMA
511static void
512usb2_bus_mem_alloc_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
512usb_bus_mem_alloc_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
513 struct usb_page *pg, usb_size_t size, usb_size_t align)
514{
515 /* need to initialize the page cache */
516 pc->tag_parent = bus->dma_parent_tag;
517
513 struct usb_page *pg, usb_size_t size, usb_size_t align)
514{
515 /* need to initialize the page cache */
516 pc->tag_parent = bus->dma_parent_tag;
517
518 if (usb2_pc_alloc_mem(pc, pg, size, align)) {
518 if (usb_pc_alloc_mem(pc, pg, size, align)) {
519 bus->alloc_failed = 1;
520 }
521}
522#endif
523
524/*------------------------------------------------------------------------*
519 bus->alloc_failed = 1;
520 }
521}
522#endif
523
524/*------------------------------------------------------------------------*
525 * usb2_bus_mem_alloc_all - factored out code
525 * usb_bus_mem_alloc_all - factored out code
526 *
527 * Returns:
528 * 0: Success
529 * Else: Failure
530 *------------------------------------------------------------------------*/
531uint8_t
526 *
527 * Returns:
528 * 0: Success
529 * Else: Failure
530 *------------------------------------------------------------------------*/
531uint8_t
532usb2_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat,
532usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat,
533 usb_bus_mem_cb_t *cb)
534{
535 bus->alloc_failed = 0;
536
537 mtx_init(&bus->bus_mtx, device_get_nameunit(bus->parent),
538 NULL, MTX_DEF | MTX_RECURSE);
539
533 usb_bus_mem_cb_t *cb)
534{
535 bus->alloc_failed = 0;
536
537 mtx_init(&bus->bus_mtx, device_get_nameunit(bus->parent),
538 NULL, MTX_DEF | MTX_RECURSE);
539
540 usb2_callout_init_mtx(&bus->power_wdog,
540 usb_callout_init_mtx(&bus->power_wdog,
541 &bus->bus_mtx, 0);
542
543 TAILQ_INIT(&bus->intr_q.head);
544
545#if USB_HAVE_BUSDMA
541 &bus->bus_mtx, 0);
542
543 TAILQ_INIT(&bus->intr_q.head);
544
545#if USB_HAVE_BUSDMA
546 usb2_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags,
546 usb_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags,
547 dmat, &bus->bus_mtx, NULL, 32, USB_BUS_DMA_TAG_MAX);
548#endif
549 if ((bus->devices_max > USB_MAX_DEVICES) ||
550 (bus->devices_max < USB_MIN_DEVICES) ||
551 (bus->devices == NULL)) {
552 DPRINTFN(0, "Devices field has not been "
553 "initialised properly!\n");
554 bus->alloc_failed = 1; /* failure */
555 }
556#if USB_HAVE_BUSDMA
557 if (cb) {
547 dmat, &bus->bus_mtx, NULL, 32, USB_BUS_DMA_TAG_MAX);
548#endif
549 if ((bus->devices_max > USB_MAX_DEVICES) ||
550 (bus->devices_max < USB_MIN_DEVICES) ||
551 (bus->devices == NULL)) {
552 DPRINTFN(0, "Devices field has not been "
553 "initialised properly!\n");
554 bus->alloc_failed = 1; /* failure */
555 }
556#if USB_HAVE_BUSDMA
557 if (cb) {
558 cb(bus, &usb2_bus_mem_alloc_all_cb);
558 cb(bus, &usb_bus_mem_alloc_all_cb);
559 }
560#endif
561 if (bus->alloc_failed) {
559 }
560#endif
561 if (bus->alloc_failed) {
562 usb2_bus_mem_free_all(bus, cb);
562 usb_bus_mem_free_all(bus, cb);
563 }
564 return (bus->alloc_failed);
565}
566
567/*------------------------------------------------------------------------*
563 }
564 return (bus->alloc_failed);
565}
566
567/*------------------------------------------------------------------------*
568 * usb2_bus_mem_free_all_cb
568 * usb_bus_mem_free_all_cb
569 *------------------------------------------------------------------------*/
570#if USB_HAVE_BUSDMA
571static void
569 *------------------------------------------------------------------------*/
570#if USB_HAVE_BUSDMA
571static void
572usb2_bus_mem_free_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
572usb_bus_mem_free_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
573 struct usb_page *pg, usb_size_t size, usb_size_t align)
574{
573 struct usb_page *pg, usb_size_t size, usb_size_t align)
574{
575 usb2_pc_free_mem(pc);
575 usb_pc_free_mem(pc);
576}
577#endif
578
579/*------------------------------------------------------------------------*
576}
577#endif
578
579/*------------------------------------------------------------------------*
580 * usb2_bus_mem_free_all - factored out code
580 * usb_bus_mem_free_all - factored out code
581 *------------------------------------------------------------------------*/
582void
581 *------------------------------------------------------------------------*/
582void
583usb2_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
583usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
584{
585#if USB_HAVE_BUSDMA
586 if (cb) {
584{
585#if USB_HAVE_BUSDMA
586 if (cb) {
587 cb(bus, &usb2_bus_mem_free_all_cb);
587 cb(bus, &usb_bus_mem_free_all_cb);
588 }
588 }
589 usb2_dma_tag_unsetup(bus->dma_parent_tag);
589 usb_dma_tag_unsetup(bus->dma_parent_tag);
590#endif
591
592 mtx_destroy(&bus->bus_mtx);
593}
590#endif
591
592 mtx_destroy(&bus->bus_mtx);
593}