8b0e92e3dcdad9b1e32d31ef3af69e4f3d3992c4
[dragonfly.git] / sys / bus / u4b / controller / usb_controller.c
1 /* $FreeBSD$ */
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.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include "opt_ddb.h"
28
29 #include <sys/stdint.h>
30 #include <sys/param.h>
31 #include <sys/queue.h>
32 #include <sys/types.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/bus.h>
36 #include <sys/module.h>
37 #include <sys/lock.h>
38 #include <sys/condvar.h>
39 #include <sys/sysctl.h>
40 #include <sys/unistd.h>
41 #include <sys/callout.h>
42 #include <sys/malloc.h>
43 #include <sys/priv.h>
44
45 #include <bus/u4b/usb.h>
46 #include <bus/u4b/usbdi.h>
47
48 #define USB_DEBUG_VAR usb_ctrl_debug
49
50 #include <bus/u4b/usb_core.h>
51 #include <bus/u4b/usb_debug.h>
52 #include <bus/u4b/usb_process.h>
53 #include <bus/u4b/usb_busdma.h>
54 #include <bus/u4b/usb_dynamic.h>
55 #include <bus/u4b/usb_device.h>
56 #include <bus/u4b/usb_hub.h>
57
58 #include <bus/u4b/usb_controller.h>
59 #include <bus/u4b/usb_bus.h>
60 #include <bus/u4b/usb_pf.h>
61 #include "usb_if.h"
62
63 /* function prototypes  */
64
65 static device_probe_t usb_probe;
66 static device_attach_t usb_attach;
67 static device_detach_t usb_detach;
68 static device_suspend_t usb_suspend;
69 static device_resume_t usb_resume;
70 static device_shutdown_t usb_shutdown;
71
72 static void     usb_attach_sub(device_t, struct usb_bus *);
73
74 /* static variables */
75
76 #ifdef USB_DEBUG
77 static int usb_ctrl_debug = 0;
78
79 static SYSCTL_NODE(_hw_usb, OID_AUTO, ctrl, CTLFLAG_RW, 0, "USB controller");
80 SYSCTL_INT(_hw_usb_ctrl, OID_AUTO, debug, CTLFLAG_RW, &usb_ctrl_debug, 0,
81     "Debug level");
82 #endif
83
84 static int usb_no_boot_wait = 0;
85 TUNABLE_INT("hw.usb.no_boot_wait", &usb_no_boot_wait);
86 /* XXX freebsd uses CTLFLAG_RDTUN here */
87 SYSCTL_INT(_hw_usb, OID_AUTO, no_boot_wait, CTLFLAG_RW, &usb_no_boot_wait, 0,
88     "No USB device enumerate waiting at boot.");
89
90 static int usb_no_shutdown_wait = 0;
91 TUNABLE_INT("hw.usb.no_shutdown_wait", &usb_no_shutdown_wait);
92 SYSCTL_INT(_hw_usb, OID_AUTO, no_shutdown_wait, CTLFLAG_RW, &usb_no_shutdown_wait, 0,
93     "No USB device waiting at system shutdown.");
94
95 static devclass_t usb_devclass;
96
97 static device_method_t usb_methods[] = {
98         DEVMETHOD(device_probe, usb_probe),
99         DEVMETHOD(device_attach, usb_attach),
100         DEVMETHOD(device_detach, usb_detach),
101         DEVMETHOD(device_suspend, usb_suspend),
102         DEVMETHOD(device_resume, usb_resume),
103         DEVMETHOD(device_shutdown, usb_shutdown),
104         {0, 0}
105 };
106
107 static driver_t usb_driver = {
108         .name = "usbus",
109         .methods = usb_methods,
110         .size = 0,
111 };
112
113 /* Host Only Drivers */
114 DRIVER_MODULE(usbus, ohci, usb_driver, usb_devclass, NULL, NULL);
115 DRIVER_MODULE(usbus, uhci, usb_driver, usb_devclass, NULL, NULL);
116 DRIVER_MODULE(usbus, ehci, usb_driver, usb_devclass, NULL, NULL);
117 DRIVER_MODULE(usbus, xhci, usb_driver, usb_devclass, NULL, NULL);
118
119 /*------------------------------------------------------------------------*
120  *      usb_probe
121  *
122  * This function is called from "{ehci,ohci,uhci}_pci_attach()".
123  *------------------------------------------------------------------------*/
124 static int
125 usb_probe(device_t dev)
126 {
127         DPRINTF("\n");
128         return (0);
129 }
130
131 static void
132 usb_root_mount_rel(struct usb_bus *bus)
133 {
134         if (bus->bus_roothold != NULL) {
135                 DPRINTF("Releasing root mount hold %p\n", bus->bus_roothold);
136 #if 0 /* XXX Dragonflybsd seems to not have this? */
137                 root_mount_rel(bus->bus_roothold);
138 #endif
139                 bus->bus_roothold = NULL;
140         }
141 }
142
143 /*------------------------------------------------------------------------*
144  *      usb_attach
145  *------------------------------------------------------------------------*/
146 static int
147 usb_attach(device_t dev)
148 {
149         struct usb_bus *bus = device_get_ivars(dev);
150
151         DPRINTF("\n");
152
153         if (bus == NULL) {
154                 device_printf(dev, "USB device has no ivars\n");
155                 return (ENXIO);
156         }
157
158 #if 0 /* XXX: Dragonfly does not seem to have this mechanism? */
159         if (usb_no_boot_wait == 0) {
160                 /* delay vfs_mountroot until the bus is explored */
161                 bus->bus_roothold = root_mount_hold(device_get_nameunit(dev));
162         }
163 #endif
164
165         usb_attach_sub(dev, bus);
166
167         return (0);                     /* return success */
168 }
169
170 /*------------------------------------------------------------------------*
171  *      usb_detach
172  *------------------------------------------------------------------------*/
173 static int
174 usb_detach(device_t dev)
175 {
176         struct usb_bus *bus = device_get_softc(dev);
177
178         DPRINTF("\n");
179
180         if (bus == NULL) {
181                 /* was never setup properly */
182                 return (0);
183         }
184         /* Stop power watchdog */
185         usb_callout_drain(&bus->power_wdog);
186
187         /* Let the USB explore process detach all devices. */
188         usb_root_mount_rel(bus);
189
190         USB_BUS_LOCK(bus);
191
192         /* Queue detach job */
193         usb_proc_msignal(&bus->explore_proc,
194             &bus->detach_msg[0], &bus->detach_msg[1]);
195
196         /* Wait for detach to complete */
197         usb_proc_mwait(&bus->explore_proc,
198             &bus->detach_msg[0], &bus->detach_msg[1]);
199
200         USB_BUS_UNLOCK(bus);
201
202         /* Get rid of USB callback processes */
203
204         usb_proc_free(&bus->giant_callback_proc);
205         usb_proc_free(&bus->non_giant_callback_proc);
206
207         /* Get rid of USB explore process */
208
209         usb_proc_free(&bus->explore_proc);
210
211         /* Get rid of control transfer process */
212
213         usb_proc_free(&bus->control_xfer_proc);
214
215 #if USB_HAVE_PF
216         usbpf_detach(bus);
217 #endif
218         return (0);
219 }
220
221 /*------------------------------------------------------------------------*
222  *      usb_suspend
223  *------------------------------------------------------------------------*/
224 static int
225 usb_suspend(device_t dev)
226 {
227         struct usb_bus *bus = device_get_softc(dev);
228
229         DPRINTF("\n");
230
231         if (bus == NULL) {
232                 /* was never setup properly */
233                 return (0);
234         }
235
236         USB_BUS_LOCK(bus);
237         usb_proc_msignal(&bus->explore_proc,
238             &bus->suspend_msg[0], &bus->suspend_msg[1]);
239         USB_BUS_UNLOCK(bus);
240
241         return (0);
242 }
243
244 /*------------------------------------------------------------------------*
245  *      usb_resume
246  *------------------------------------------------------------------------*/
247 static int
248 usb_resume(device_t dev)
249 {
250         struct usb_bus *bus = device_get_softc(dev);
251
252         DPRINTF("\n");
253
254         if (bus == NULL) {
255                 /* was never setup properly */
256                 return (0);
257         }
258
259         USB_BUS_LOCK(bus);
260         usb_proc_msignal(&bus->explore_proc,
261             &bus->resume_msg[0], &bus->resume_msg[1]);
262         USB_BUS_UNLOCK(bus);
263
264         return (0);
265 }
266
267 /*------------------------------------------------------------------------*
268  *      usb_shutdown
269  *------------------------------------------------------------------------*/
270 static int
271 usb_shutdown(device_t dev)
272 {
273         struct usb_bus *bus = device_get_softc(dev);
274
275         DPRINTF("\n");
276
277         if (bus == NULL) {
278                 /* was never setup properly */
279                 return (0);
280         }
281
282         device_printf(bus->bdev, "Controller shutdown\n");
283
284         USB_BUS_LOCK(bus);
285         usb_proc_msignal(&bus->explore_proc,
286             &bus->shutdown_msg[0], &bus->shutdown_msg[1]);
287         if (usb_no_shutdown_wait == 0) {
288                 /* wait for shutdown callback to be executed */
289                 usb_proc_mwait(&bus->explore_proc,
290                     &bus->shutdown_msg[0], &bus->shutdown_msg[1]);
291         }
292         USB_BUS_UNLOCK(bus);
293
294         device_printf(bus->bdev, "Controller shutdown complete\n");
295
296         return (0);
297 }
298
299 /*------------------------------------------------------------------------*
300  *      usb_bus_explore
301  *
302  * This function is used to explore the device tree from the root.
303  *------------------------------------------------------------------------*/
304 static void
305 usb_bus_explore(struct usb_proc_msg *pm)
306 {
307         struct usb_bus *bus;
308         struct usb_device *udev;
309
310         bus = ((struct usb_bus_msg *)pm)->bus;
311         udev = bus->devices[USB_ROOT_HUB_ADDR];
312
313         if (bus->no_explore != 0)
314                 return;
315
316         if (udev && udev->hub) {
317
318                 if (bus->do_probe) {
319                         bus->do_probe = 0;
320                         bus->driver_added_refcount++;
321                 }
322                 if (bus->driver_added_refcount == 0) {
323                         /* avoid zero, hence that is memory default */
324                         bus->driver_added_refcount = 1;
325                 }
326
327 #ifdef DDB
328                 /*
329                  * The following three lines of code are only here to
330                  * recover from DDB:
331                  */
332                 usb_proc_rewakeup(&bus->control_xfer_proc);
333                 usb_proc_rewakeup(&bus->giant_callback_proc);
334                 usb_proc_rewakeup(&bus->non_giant_callback_proc);
335 #endif
336
337                 USB_BUS_UNLOCK(bus);
338
339 #if USB_HAVE_POWERD
340                 /*
341                  * First update the USB power state!
342                  */
343                 usb_bus_powerd(bus);
344 #endif
345                  /* Explore the Root USB HUB. */
346                 (udev->hub->explore) (udev);
347                 USB_BUS_LOCK(bus);
348         }
349         usb_root_mount_rel(bus);
350 }
351
352 /*------------------------------------------------------------------------*
353  *      usb_bus_detach
354  *
355  * This function is used to detach the device tree from the root.
356  *------------------------------------------------------------------------*/
357 static void
358 usb_bus_detach(struct usb_proc_msg *pm)
359 {
360         struct usb_bus *bus;
361         struct usb_device *udev;
362         device_t dev;
363
364         bus = ((struct usb_bus_msg *)pm)->bus;
365         udev = bus->devices[USB_ROOT_HUB_ADDR];
366         dev = bus->bdev;
367         /* clear the softc */
368         device_set_softc(dev, NULL);
369         USB_BUS_UNLOCK(bus);
370
371         /* detach children first */
372         bus_generic_detach(dev);
373
374         /*
375          * Free USB device and all subdevices, if any.
376          */
377         usb_free_device(udev, 0);
378
379         USB_BUS_LOCK(bus);
380         /* clear bdev variable last */
381         bus->bdev = NULL;
382 }
383
384 /*------------------------------------------------------------------------*
385  *      usb_bus_suspend
386  *
387  * This function is used to suspend the USB contoller.
388  *------------------------------------------------------------------------*/
389 static void
390 usb_bus_suspend(struct usb_proc_msg *pm)
391 {
392         struct usb_bus *bus;
393         struct usb_device *udev;
394         usb_error_t err;
395
396         bus = ((struct usb_bus_msg *)pm)->bus;
397         udev = bus->devices[USB_ROOT_HUB_ADDR];
398
399         if (udev == NULL || bus->bdev == NULL)
400                 return;
401
402         USB_BUS_UNLOCK(bus);
403
404         bus_generic_shutdown(bus->bdev);
405
406         usbd_enum_lock(udev);
407
408         err = usbd_set_config_index(udev, USB_UNCONFIG_INDEX);
409         if (err)
410                 device_printf(bus->bdev, "Could not unconfigure root HUB\n");
411
412         USB_BUS_LOCK(bus);
413         bus->hw_power_state = 0;
414         bus->no_explore = 1;
415         USB_BUS_UNLOCK(bus);
416
417         if (bus->methods->set_hw_power != NULL)
418                 (bus->methods->set_hw_power) (bus);
419
420         if (bus->methods->set_hw_power_sleep != NULL)
421                 (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_SUSPEND);
422
423         usbd_enum_unlock(udev);
424
425         USB_BUS_LOCK(bus);
426 }
427
428 /*------------------------------------------------------------------------*
429  *      usb_bus_resume
430  *
431  * This function is used to resume the USB contoller.
432  *------------------------------------------------------------------------*/
433 static void
434 usb_bus_resume(struct usb_proc_msg *pm)
435 {
436         struct usb_bus *bus;
437         struct usb_device *udev;
438         usb_error_t err;
439
440         bus = ((struct usb_bus_msg *)pm)->bus;
441         udev = bus->devices[USB_ROOT_HUB_ADDR];
442
443         if (udev == NULL || bus->bdev == NULL)
444                 return;
445
446         USB_BUS_UNLOCK(bus);
447
448         usbd_enum_lock(udev);
449 #if 0
450         DEVMETHOD(usb_take_controller, NULL);   /* dummy */
451 #endif
452         USB_TAKE_CONTROLLER(device_get_parent(bus->bdev));
453
454         USB_BUS_LOCK(bus);
455         bus->hw_power_state =
456           USB_HW_POWER_CONTROL |
457           USB_HW_POWER_BULK |
458           USB_HW_POWER_INTERRUPT |
459           USB_HW_POWER_ISOC |
460           USB_HW_POWER_NON_ROOT_HUB;
461         bus->no_explore = 0;
462         USB_BUS_UNLOCK(bus);
463
464         if (bus->methods->set_hw_power_sleep != NULL)
465                 (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_RESUME);
466
467         if (bus->methods->set_hw_power != NULL)
468                 (bus->methods->set_hw_power) (bus);
469
470         /* restore USB configuration to index 0 */
471         err = usbd_set_config_index(udev, 0);
472         if (err)
473                 device_printf(bus->bdev, "Could not configure root HUB\n");
474
475         /* probe and attach */
476         err = usb_probe_and_attach(udev, USB_IFACE_INDEX_ANY);
477         if (err) {
478                 device_printf(bus->bdev, "Could not probe and "
479                     "attach root HUB\n");
480         }
481
482         usbd_enum_unlock(udev);
483
484         USB_BUS_LOCK(bus);
485 }
486
487 /*------------------------------------------------------------------------*
488  *      usb_bus_shutdown
489  *
490  * This function is used to shutdown the USB contoller.
491  *------------------------------------------------------------------------*/
492 static void
493 usb_bus_shutdown(struct usb_proc_msg *pm)
494 {
495         struct usb_bus *bus;
496         struct usb_device *udev;
497         usb_error_t err;
498
499         bus = ((struct usb_bus_msg *)pm)->bus;
500         udev = bus->devices[USB_ROOT_HUB_ADDR];
501
502         if (udev == NULL || bus->bdev == NULL)
503                 return;
504
505         USB_BUS_UNLOCK(bus);
506
507         bus_generic_shutdown(bus->bdev);
508
509         usbd_enum_lock(udev);
510
511         err = usbd_set_config_index(udev, USB_UNCONFIG_INDEX);
512         if (err)
513                 device_printf(bus->bdev, "Could not unconfigure root HUB\n");
514
515         USB_BUS_LOCK(bus);
516         bus->hw_power_state = 0;
517         bus->no_explore = 1;
518         USB_BUS_UNLOCK(bus);
519
520         if (bus->methods->set_hw_power != NULL)
521                 (bus->methods->set_hw_power) (bus);
522
523         if (bus->methods->set_hw_power_sleep != NULL)
524                 (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_SHUTDOWN);
525
526         usbd_enum_unlock(udev);
527
528         USB_BUS_LOCK(bus);
529 }
530
531 static void
532 usb_power_wdog(void *arg)
533 {
534         struct usb_bus *bus = arg;
535         USB_BUS_LOCK_ASSERT(bus);
536
537         usb_callout_reset(&bus->power_wdog,
538             4 * hz, usb_power_wdog, arg);
539
540 #ifdef DDB
541         /*
542          * The following line of code is only here to recover from
543          * DDB:
544          */
545         usb_proc_rewakeup(&bus->explore_proc);  /* recover from DDB */
546 #endif
547
548 #if USB_HAVE_POWERD
549         USB_BUS_UNLOCK(bus);
550
551         usb_bus_power_update(bus);
552
553         USB_BUS_LOCK(bus);
554 #endif
555 }
556
557 /*------------------------------------------------------------------------*
558  *      usb_bus_attach
559  *
560  * This function attaches USB in context of the explore thread.
561  *------------------------------------------------------------------------*/
562 static void
563 usb_bus_attach(struct usb_proc_msg *pm)
564 {
565         struct usb_bus *bus;
566         struct usb_device *child;
567         device_t dev;
568         usb_error_t err;
569         enum usb_dev_speed speed;
570
571         bus = ((struct usb_bus_msg *)pm)->bus;
572         dev = bus->bdev;
573
574         DPRINTF("\n");
575
576         switch (bus->usbrev) {
577         case USB_REV_1_0:
578                 speed = USB_SPEED_FULL;
579                 device_printf(bus->bdev, "12Mbps Full Speed USB v1.0\n");
580                 break;
581
582         case USB_REV_1_1:
583                 speed = USB_SPEED_FULL;
584                 device_printf(bus->bdev, "12Mbps Full Speed USB v1.1\n");
585                 break;
586
587         case USB_REV_2_0:
588                 speed = USB_SPEED_HIGH;
589                 device_printf(bus->bdev, "480Mbps High Speed USB v2.0\n");
590                 break;
591
592         case USB_REV_2_5:
593                 speed = USB_SPEED_VARIABLE;
594                 device_printf(bus->bdev, "480Mbps Wireless USB v2.5\n");
595                 break;
596
597         case USB_REV_3_0:
598                 speed = USB_SPEED_SUPER;
599                 device_printf(bus->bdev, "5.0Gbps Super Speed USB v3.0\n");
600                 break;
601
602         default:
603                 device_printf(bus->bdev, "Unsupported USB revision\n");
604                 usb_root_mount_rel(bus);
605                 return;
606         }
607
608         /* default power_mask value */
609         bus->hw_power_state =
610           USB_HW_POWER_CONTROL |
611           USB_HW_POWER_BULK |
612           USB_HW_POWER_INTERRUPT |
613           USB_HW_POWER_ISOC |
614           USB_HW_POWER_NON_ROOT_HUB;
615
616         USB_BUS_UNLOCK(bus);
617
618         /* make sure power is set at least once */
619
620         if (bus->methods->set_hw_power != NULL) {
621                 (bus->methods->set_hw_power) (bus);
622         }
623
624         /* allocate the Root USB device */
625
626         child = usb_alloc_device(bus->bdev, bus, NULL, 0, 0, 1,
627             speed, USB_MODE_HOST);
628         if (child) {
629                 err = usb_probe_and_attach(child,
630                     USB_IFACE_INDEX_ANY);
631                 if (!err) {
632                         if ((bus->devices[USB_ROOT_HUB_ADDR] == NULL) ||
633                             (bus->devices[USB_ROOT_HUB_ADDR]->hub == NULL)) {
634                                 err = USB_ERR_NO_ROOT_HUB;
635                         }
636                 }
637         } else {
638                 err = USB_ERR_NOMEM;
639         }
640
641         USB_BUS_LOCK(bus);
642
643         if (err) {
644                 device_printf(bus->bdev, "Root HUB problem, error=%s\n",
645                     usbd_errstr(err));
646                 usb_root_mount_rel(bus);
647         }
648
649         /* set softc - we are ready */
650         device_set_softc(dev, bus);
651
652         /* start watchdog */
653         usb_power_wdog(bus);
654 }
655
656 /*------------------------------------------------------------------------*
657  *      usb_attach_sub
658  *
659  * This function creates a thread which runs the USB attach code.
660  *------------------------------------------------------------------------*/
661 static void
662 usb_attach_sub(device_t dev, struct usb_bus *bus)
663 {
664         const char *pname = device_get_nameunit(dev);
665
666         if (usb_devclass_ptr == NULL)
667                 usb_devclass_ptr = devclass_find("usbus");
668
669 #if USB_HAVE_PF
670         usbpf_attach(bus);
671 #endif
672         /* Initialise USB process messages */
673         bus->explore_msg[0].hdr.pm_callback = &usb_bus_explore;
674         bus->explore_msg[0].bus = bus;
675         bus->explore_msg[1].hdr.pm_callback = &usb_bus_explore;
676         bus->explore_msg[1].bus = bus;
677
678         bus->detach_msg[0].hdr.pm_callback = &usb_bus_detach;
679         bus->detach_msg[0].bus = bus;
680         bus->detach_msg[1].hdr.pm_callback = &usb_bus_detach;
681         bus->detach_msg[1].bus = bus;
682
683         bus->attach_msg[0].hdr.pm_callback = &usb_bus_attach;
684         bus->attach_msg[0].bus = bus;
685         bus->attach_msg[1].hdr.pm_callback = &usb_bus_attach;
686         bus->attach_msg[1].bus = bus;
687
688         bus->suspend_msg[0].hdr.pm_callback = &usb_bus_suspend;
689         bus->suspend_msg[0].bus = bus;
690         bus->suspend_msg[1].hdr.pm_callback = &usb_bus_suspend;
691         bus->suspend_msg[1].bus = bus;
692
693         bus->resume_msg[0].hdr.pm_callback = &usb_bus_resume;
694         bus->resume_msg[0].bus = bus;
695         bus->resume_msg[1].hdr.pm_callback = &usb_bus_resume;
696         bus->resume_msg[1].bus = bus;
697
698         bus->shutdown_msg[0].hdr.pm_callback = &usb_bus_shutdown;
699         bus->shutdown_msg[0].bus = bus;
700         bus->shutdown_msg[1].hdr.pm_callback = &usb_bus_shutdown;
701         bus->shutdown_msg[1].bus = bus;
702
703         /* Create USB explore and callback processes */
704
705         if (usb_proc_create(&bus->giant_callback_proc,
706             &bus->bus_lock, pname, USB_PRI_MED)) {
707                 device_printf(dev, "WARNING: Creation of USB Giant "
708                     "callback process failed.\n");
709         } else if (usb_proc_create(&bus->non_giant_callback_proc,
710             &bus->bus_lock, pname, USB_PRI_HIGH)) {
711                 device_printf(dev, "WARNING: Creation of USB non-Giant "
712                     "callback process failed.\n");
713         } else if (usb_proc_create(&bus->explore_proc,
714             &bus->bus_lock, pname, USB_PRI_MED)) {
715                 device_printf(dev, "WARNING: Creation of USB explore "
716                     "process failed.\n");
717         } else if (usb_proc_create(&bus->control_xfer_proc,
718             &bus->bus_lock, pname, USB_PRI_MED)) {
719                 device_printf(dev, "WARNING: Creation of USB control transfer "
720                     "process failed.\n");
721         } else {
722                 /* Get final attach going */
723                 USB_BUS_LOCK(bus);
724                 usb_proc_msignal(&bus->explore_proc,
725                     &bus->attach_msg[0], &bus->attach_msg[1]);
726                 USB_BUS_UNLOCK(bus);
727
728                 /* Do initial explore */
729                 usb_needs_explore(bus, 1);
730         }
731 }
732
733 SYSUNINIT(usb_bus_unload, SI_SUB_CONFIGURE, SI_ORDER_ANY, usb_bus_unload, NULL);
734
735 /*------------------------------------------------------------------------*
736  *      usb_bus_mem_flush_all_cb
737  *------------------------------------------------------------------------*/
738 #if USB_HAVE_BUSDMA
739 static void
740 usb_bus_mem_flush_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
741     struct usb_page *pg, usb_size_t size, usb_size_t align)
742 {
743         usb_pc_cpu_flush(pc);
744 }
745 #endif
746
747 /*------------------------------------------------------------------------*
748  *      usb_bus_mem_flush_all - factored out code
749  *------------------------------------------------------------------------*/
750 #if USB_HAVE_BUSDMA
751 void
752 usb_bus_mem_flush_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
753 {
754         if (cb) {
755                 cb(bus, &usb_bus_mem_flush_all_cb);
756         }
757 }
758 #endif
759
760 /*------------------------------------------------------------------------*
761  *      usb_bus_mem_alloc_all_cb
762  *------------------------------------------------------------------------*/
763 #if USB_HAVE_BUSDMA
764 static void
765 usb_bus_mem_alloc_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
766     struct usb_page *pg, usb_size_t size, usb_size_t align)
767 {
768         /* need to initialize the page cache */
769         pc->tag_parent = bus->dma_parent_tag;
770
771         if (usb_pc_alloc_mem(pc, pg, size, align)) {
772                 bus->alloc_failed = 1;
773         }
774 }
775 #endif
776
777 /*------------------------------------------------------------------------*
778  *      usb_bus_mem_alloc_all - factored out code
779  *
780  * Returns:
781  *    0: Success
782  * Else: Failure
783  *------------------------------------------------------------------------*/
784 uint8_t
785 usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat,
786     usb_bus_mem_cb_t *cb)
787 {
788         bus->alloc_failed = 0;
789
790         lockinit(&bus->bus_lock, "USB bus mem", 0, LK_CANRECURSE);
791
792         usb_callout_init_mtx(&bus->power_wdog,
793             &bus->bus_lock, 0);
794
795         TAILQ_INIT(&bus->intr_q.head);
796
797 #if USB_HAVE_BUSDMA
798         usb_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags,
799             dmat, &bus->bus_lock, NULL, 32, USB_BUS_DMA_TAG_MAX);
800 #endif
801         if ((bus->devices_max > USB_MAX_DEVICES) ||
802             (bus->devices_max < USB_MIN_DEVICES) ||
803             (bus->devices == NULL)) {
804                 DPRINTFN(0, "Devices field has not been "
805                     "initialised properly\n");
806                 bus->alloc_failed = 1;          /* failure */
807         }
808 #if USB_HAVE_BUSDMA
809         if (cb) {
810                 cb(bus, &usb_bus_mem_alloc_all_cb);
811         }
812 #endif
813         if (bus->alloc_failed) {
814                 usb_bus_mem_free_all(bus, cb);
815         }
816         return (bus->alloc_failed);
817 }
818
819 /*------------------------------------------------------------------------*
820  *      usb_bus_mem_free_all_cb
821  *------------------------------------------------------------------------*/
822 #if USB_HAVE_BUSDMA
823 static void
824 usb_bus_mem_free_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
825     struct usb_page *pg, usb_size_t size, usb_size_t align)
826 {
827         usb_pc_free_mem(pc);
828 }
829 #endif
830
831 /*------------------------------------------------------------------------*
832  *      usb_bus_mem_free_all - factored out code
833  *------------------------------------------------------------------------*/
834 void
835 usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
836 {
837 #if USB_HAVE_BUSDMA
838         if (cb) {
839                 cb(bus, &usb_bus_mem_free_all_cb);
840         }
841         usb_dma_tag_unsetup(bus->dma_parent_tag);
842 #endif
843
844         lockuninit(&bus->bus_lock);
845 }