source: rtems-libbsd/freebsd/sys/dev/usb/controller/usb_controller.c @ 1e77a45

55-freebsd-126-freebsd-12
Last change on this file since 1e77a45 was 3489e3b, checked in by Sebastian Huber <sebastian.huber@…>, on 08/22/18 at 12:59:50

Update to FreeBSD head 2018-09-17

Git mirror commit 6c2192b1ef8c50788c751f878552526800b1e319.

Update #3472.

  • Property mode set to 100644
File size: 26.8 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
3/* $FreeBSD$ */
4/*-
5 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
6 *
7 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#ifdef USB_GLOBAL_INCLUDE_FILE
32#include USB_GLOBAL_INCLUDE_FILE
33#else
34#include <rtems/bsd/local/opt_ddb.h>
35
36#include <sys/stdint.h>
37#include <sys/stddef.h>
38#include <sys/param.h>
39#include <sys/queue.h>
40#include <sys/types.h>
41#include <sys/systm.h>
42#include <sys/kernel.h>
43#include <sys/bus.h>
44#include <sys/module.h>
45#include <sys/lock.h>
46#include <sys/mutex.h>
47#include <sys/condvar.h>
48#include <sys/sysctl.h>
49#include <sys/sx.h>
50#include <rtems/bsd/sys/unistd.h>
51#include <sys/callout.h>
52#include <sys/malloc.h>
53#include <sys/priv.h>
54
55#include <dev/usb/usb.h>
56#include <dev/usb/usbdi.h>
57
58#define USB_DEBUG_VAR usb_ctrl_debug
59
60#include <dev/usb/usb_core.h>
61#include <dev/usb/usb_debug.h>
62#include <dev/usb/usb_process.h>
63#include <dev/usb/usb_busdma.h>
64#include <dev/usb/usb_dynamic.h>
65#include <dev/usb/usb_device.h>
66#include <dev/usb/usb_dev.h>
67#include <dev/usb/usb_hub.h>
68
69#include <dev/usb/usb_controller.h>
70#include <dev/usb/usb_bus.h>
71#include <dev/usb/usb_pf.h>
72#include <rtems/bsd/local/usb_if.h>
73#endif                  /* USB_GLOBAL_INCLUDE_FILE */
74
75/* function prototypes  */
76
77static device_probe_t usb_probe;
78static device_attach_t usb_attach;
79static device_detach_t usb_detach;
80static device_suspend_t usb_suspend;
81static device_resume_t usb_resume;
82static device_shutdown_t usb_shutdown;
83
84static void     usb_attach_sub(device_t, struct usb_bus *);
85
86/* static variables */
87
88#ifdef USB_DEBUG
89static int usb_ctrl_debug = 0;
90
91static SYSCTL_NODE(_hw_usb, OID_AUTO, ctrl, CTLFLAG_RW, 0, "USB controller");
92SYSCTL_INT(_hw_usb_ctrl, OID_AUTO, debug, CTLFLAG_RWTUN, &usb_ctrl_debug, 0,
93    "Debug level");
94#endif
95
96#if USB_HAVE_ROOT_MOUNT_HOLD
97static int usb_no_boot_wait = 0;
98SYSCTL_INT(_hw_usb, OID_AUTO, no_boot_wait, CTLFLAG_RDTUN, &usb_no_boot_wait, 0,
99    "No USB device enumerate waiting at boot.");
100#endif
101
102#ifndef __rtems__
103static int usb_no_suspend_wait = 0;
104SYSCTL_INT(_hw_usb, OID_AUTO, no_suspend_wait, CTLFLAG_RWTUN,
105    &usb_no_suspend_wait, 0, "No USB device waiting at system suspend.");
106
107static int usb_no_shutdown_wait = 0;
108SYSCTL_INT(_hw_usb, OID_AUTO, no_shutdown_wait, CTLFLAG_RWTUN,
109    &usb_no_shutdown_wait, 0, "No USB device waiting at system shutdown.");
110#endif /* __rtems__ */
111
112static devclass_t usb_devclass;
113
114static device_method_t usb_methods[] = {
115        DEVMETHOD(device_probe, usb_probe),
116        DEVMETHOD(device_attach, usb_attach),
117        DEVMETHOD(device_detach, usb_detach),
118        DEVMETHOD(device_suspend, usb_suspend),
119        DEVMETHOD(device_resume, usb_resume),
120        DEVMETHOD(device_shutdown, usb_shutdown),
121
122        DEVMETHOD_END
123};
124
125static driver_t usb_driver = {
126        .name = "usbus",
127        .methods = usb_methods,
128        .size = 0,
129};
130
131/* Host Only Drivers */
132DRIVER_MODULE(usbus, ohci, usb_driver, usb_devclass, 0, 0);
133DRIVER_MODULE(usbus, uhci, usb_driver, usb_devclass, 0, 0);
134DRIVER_MODULE(usbus, ehci, usb_driver, usb_devclass, 0, 0);
135DRIVER_MODULE(usbus, xhci, usb_driver, usb_devclass, 0, 0);
136
137/* Device Only Drivers */
138DRIVER_MODULE(usbus, musbotg, usb_driver, usb_devclass, 0, 0);
139DRIVER_MODULE(usbus, uss820dci, usb_driver, usb_devclass, 0, 0);
140DRIVER_MODULE(usbus, octusb, usb_driver, usb_devclass, 0, 0);
141
142/* Dual Mode Drivers */
143DRIVER_MODULE(usbus, dwcotg, usb_driver, usb_devclass, 0, 0);
144DRIVER_MODULE(usbus, saf1761otg, usb_driver, usb_devclass, 0, 0);
145
146/*------------------------------------------------------------------------*
147 *      usb_probe
148 *
149 * This function is called from "{ehci,ohci,uhci}_pci_attach()".
150 *------------------------------------------------------------------------*/
151static int
152usb_probe(device_t dev)
153{
154        DPRINTF("\n");
155        return (0);
156}
157
158#if USB_HAVE_ROOT_MOUNT_HOLD
159static void
160usb_root_mount_rel(struct usb_bus *bus)
161{
162#ifndef __rtems__
163        if (bus->bus_roothold != NULL) {
164                DPRINTF("Releasing root mount hold %p\n", bus->bus_roothold);
165                root_mount_rel(bus->bus_roothold);
166                bus->bus_roothold = NULL;
167        }
168#endif /* __rtems__ */
169}
170#endif
171
172/*------------------------------------------------------------------------*
173 *      usb_attach
174 *------------------------------------------------------------------------*/
175static int
176usb_attach(device_t dev)
177{
178        struct usb_bus *bus = device_get_ivars(dev);
179
180        DPRINTF("\n");
181
182        if (bus == NULL) {
183                device_printf(dev, "USB device has no ivars\n");
184                return (ENXIO);
185        }
186
187#if USB_HAVE_ROOT_MOUNT_HOLD
188        if (usb_no_boot_wait == 0) {
189                /* delay vfs_mountroot until the bus is explored */
190                bus->bus_roothold = root_mount_hold(device_get_nameunit(dev));
191        }
192#endif
193
194        usb_attach_sub(dev, bus);
195
196        return (0);                     /* return success */
197}
198
199/*------------------------------------------------------------------------*
200 *      usb_detach
201 *------------------------------------------------------------------------*/
202static int
203usb_detach(device_t dev)
204{
205        struct usb_bus *bus = device_get_softc(dev);
206
207        DPRINTF("\n");
208
209        if (bus == NULL) {
210                /* was never setup properly */
211                return (0);
212        }
213        /* Stop power watchdog */
214        usb_callout_drain(&bus->power_wdog);
215
216#if USB_HAVE_ROOT_MOUNT_HOLD
217        /* Let the USB explore process detach all devices. */
218        usb_root_mount_rel(bus);
219#endif
220
221        USB_BUS_LOCK(bus);
222
223        /* Queue detach job */
224        usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
225            &bus->detach_msg[0], &bus->detach_msg[1]);
226
227        /* Wait for detach to complete */
228        usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
229            &bus->detach_msg[0], &bus->detach_msg[1]);
230
231#if USB_HAVE_UGEN
232        /* Wait for cleanup to complete */
233        usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
234            &bus->cleanup_msg[0], &bus->cleanup_msg[1]);
235#endif
236        USB_BUS_UNLOCK(bus);
237
238#if USB_HAVE_PER_BUS_PROCESS
239        /* Get rid of USB callback processes */
240
241        usb_proc_free(USB_BUS_GIANT_PROC(bus));
242        usb_proc_free(USB_BUS_NON_GIANT_ISOC_PROC(bus));
243        usb_proc_free(USB_BUS_NON_GIANT_BULK_PROC(bus));
244
245        /* Get rid of USB explore process */
246
247        usb_proc_free(USB_BUS_EXPLORE_PROC(bus));
248
249        /* Get rid of control transfer process */
250
251        usb_proc_free(USB_BUS_CONTROL_XFER_PROC(bus));
252#endif
253
254#if USB_HAVE_PF
255        usbpf_detach(bus);
256#endif
257        return (0);
258}
259
260/*------------------------------------------------------------------------*
261 *      usb_suspend
262 *------------------------------------------------------------------------*/
263static int
264usb_suspend(device_t dev)
265{
266        struct usb_bus *bus = device_get_softc(dev);
267
268        DPRINTF("\n");
269
270        if (bus == NULL) {
271                /* was never setup properly */
272                return (0);
273        }
274
275        USB_BUS_LOCK(bus);
276        usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
277            &bus->suspend_msg[0], &bus->suspend_msg[1]);
278#ifndef __rtems__
279        if (usb_no_suspend_wait == 0) {
280                /* wait for suspend callback to be executed */
281                usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
282                    &bus->suspend_msg[0], &bus->suspend_msg[1]);
283        }
284#endif /* __rtems__ */
285        USB_BUS_UNLOCK(bus);
286
287        return (0);
288}
289
290/*------------------------------------------------------------------------*
291 *      usb_resume
292 *------------------------------------------------------------------------*/
293static int
294usb_resume(device_t dev)
295{
296        struct usb_bus *bus = device_get_softc(dev);
297
298        DPRINTF("\n");
299
300        if (bus == NULL) {
301                /* was never setup properly */
302                return (0);
303        }
304
305        USB_BUS_LOCK(bus);
306        usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
307            &bus->resume_msg[0], &bus->resume_msg[1]);
308        USB_BUS_UNLOCK(bus);
309
310        return (0);
311}
312
313/*------------------------------------------------------------------------*
314 *      usb_bus_reset_async_locked
315 *------------------------------------------------------------------------*/
316void
317usb_bus_reset_async_locked(struct usb_bus *bus)
318{
319        USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
320
321        DPRINTF("\n");
322
323        if (bus->reset_msg[0].hdr.pm_qentry.tqe_prev != NULL ||
324            bus->reset_msg[1].hdr.pm_qentry.tqe_prev != NULL) {
325                DPRINTF("Reset already pending\n");
326                return;
327        }
328
329        device_printf(bus->parent, "Resetting controller\n");
330
331        usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
332            &bus->reset_msg[0], &bus->reset_msg[1]);
333}
334
335/*------------------------------------------------------------------------*
336 *      usb_shutdown
337 *------------------------------------------------------------------------*/
338static int
339usb_shutdown(device_t dev)
340{
341        struct usb_bus *bus = device_get_softc(dev);
342
343        DPRINTF("\n");
344
345        if (bus == NULL) {
346                /* was never setup properly */
347                return (0);
348        }
349
350        DPRINTF("%s: Controller shutdown\n", device_get_nameunit(bus->bdev));
351
352        USB_BUS_LOCK(bus);
353#ifndef __rtems__
354        usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
355            &bus->shutdown_msg[0], &bus->shutdown_msg[1]);
356        if (usb_no_shutdown_wait == 0) {
357                /* wait for shutdown callback to be executed */
358                usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
359                    &bus->shutdown_msg[0], &bus->shutdown_msg[1]);
360        }
361#endif /* __rtems__ */
362        USB_BUS_UNLOCK(bus);
363
364        DPRINTF("%s: Controller shutdown complete\n",
365            device_get_nameunit(bus->bdev));
366
367        return (0);
368}
369
370/*------------------------------------------------------------------------*
371 *      usb_bus_explore
372 *
373 * This function is used to explore the device tree from the root.
374 *------------------------------------------------------------------------*/
375static void
376usb_bus_explore(struct usb_proc_msg *pm)
377{
378        struct usb_bus *bus;
379        struct usb_device *udev;
380
381        bus = ((struct usb_bus_msg *)pm)->bus;
382        udev = bus->devices[USB_ROOT_HUB_ADDR];
383
384        if (bus->no_explore != 0)
385                return;
386
387        if (udev != NULL) {
388                USB_BUS_UNLOCK(bus);
389                uhub_explore_handle_re_enumerate(udev);
390                USB_BUS_LOCK(bus);
391        }
392
393        if (udev != NULL && udev->hub != NULL) {
394
395                if (bus->do_probe) {
396                        bus->do_probe = 0;
397                        bus->driver_added_refcount++;
398                }
399                if (bus->driver_added_refcount == 0) {
400                        /* avoid zero, hence that is memory default */
401                        bus->driver_added_refcount = 1;
402                }
403
404#ifdef DDB
405                /*
406                 * The following three lines of code are only here to
407                 * recover from DDB:
408                 */
409                usb_proc_rewakeup(USB_BUS_CONTROL_XFER_PROC(bus));
410                usb_proc_rewakeup(USB_BUS_GIANT_PROC(bus));
411                usb_proc_rewakeup(USB_BUS_NON_GIANT_ISOC_PROC(bus));
412                usb_proc_rewakeup(USB_BUS_NON_GIANT_BULK_PROC(bus));
413#endif
414
415                USB_BUS_UNLOCK(bus);
416
417#if USB_HAVE_POWERD
418                /*
419                 * First update the USB power state!
420                 */
421                usb_bus_powerd(bus);
422#endif
423                 /* Explore the Root USB HUB. */
424                (udev->hub->explore) (udev);
425                USB_BUS_LOCK(bus);
426        }
427#if USB_HAVE_ROOT_MOUNT_HOLD
428        usb_root_mount_rel(bus);
429#endif
430}
431
432/*------------------------------------------------------------------------*
433 *      usb_bus_detach
434 *
435 * This function is used to detach the device tree from the root.
436 *------------------------------------------------------------------------*/
437static void
438usb_bus_detach(struct usb_proc_msg *pm)
439{
440        struct usb_bus *bus;
441        struct usb_device *udev;
442        device_t dev;
443
444        bus = ((struct usb_bus_msg *)pm)->bus;
445        udev = bus->devices[USB_ROOT_HUB_ADDR];
446        dev = bus->bdev;
447        /* clear the softc */
448        device_set_softc(dev, NULL);
449        USB_BUS_UNLOCK(bus);
450
451        /* detach children first */
452        mtx_lock(&Giant);
453        bus_generic_detach(dev);
454        mtx_unlock(&Giant);
455
456        /*
457         * Free USB device and all subdevices, if any.
458         */
459        usb_free_device(udev, 0);
460
461        USB_BUS_LOCK(bus);
462        /* clear bdev variable last */
463        bus->bdev = NULL;
464}
465
466/*------------------------------------------------------------------------*
467 *      usb_bus_suspend
468 *
469 * This function is used to suspend the USB controller.
470 *------------------------------------------------------------------------*/
471static void
472usb_bus_suspend(struct usb_proc_msg *pm)
473{
474        struct usb_bus *bus;
475        struct usb_device *udev;
476        usb_error_t err;
477        uint8_t do_unlock;
478
479        DPRINTF("\n");
480
481        bus = ((struct usb_bus_msg *)pm)->bus;
482        udev = bus->devices[USB_ROOT_HUB_ADDR];
483
484        if (udev == NULL || bus->bdev == NULL)
485                return;
486
487        USB_BUS_UNLOCK(bus);
488
489        /*
490         * We use the shutdown event here because the suspend and
491         * resume events are reserved for the USB port suspend and
492         * resume. The USB system suspend is implemented like full
493         * shutdown and all connected USB devices will be disconnected
494         * subsequently. At resume all USB devices will be
495         * re-connected again.
496         */
497
498        bus_generic_shutdown(bus->bdev);
499
500        do_unlock = usbd_enum_lock(udev);
501
502        err = usbd_set_config_index(udev, USB_UNCONFIG_INDEX);
503        if (err)
504                device_printf(bus->bdev, "Could not unconfigure root HUB\n");
505
506        USB_BUS_LOCK(bus);
507        bus->hw_power_state = 0;
508        bus->no_explore = 1;
509        USB_BUS_UNLOCK(bus);
510
511        if (bus->methods->set_hw_power != NULL)
512                (bus->methods->set_hw_power) (bus);
513
514        if (bus->methods->set_hw_power_sleep != NULL)
515                (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_SUSPEND);
516
517        if (do_unlock)
518                usbd_enum_unlock(udev);
519
520        USB_BUS_LOCK(bus);
521}
522
523/*------------------------------------------------------------------------*
524 *      usb_bus_resume
525 *
526 * This function is used to resume the USB controller.
527 *------------------------------------------------------------------------*/
528static void
529usb_bus_resume(struct usb_proc_msg *pm)
530{
531        struct usb_bus *bus;
532        struct usb_device *udev;
533        usb_error_t err;
534        uint8_t do_unlock;
535
536        DPRINTF("\n");
537
538        bus = ((struct usb_bus_msg *)pm)->bus;
539        udev = bus->devices[USB_ROOT_HUB_ADDR];
540
541        if (udev == NULL || bus->bdev == NULL)
542                return;
543
544        USB_BUS_UNLOCK(bus);
545
546        do_unlock = usbd_enum_lock(udev);
547#if 0
548        DEVMETHOD(usb_take_controller, NULL);   /* dummy */
549#endif
550        USB_TAKE_CONTROLLER(device_get_parent(bus->bdev));
551
552        USB_BUS_LOCK(bus);
553        bus->hw_power_state =
554          USB_HW_POWER_CONTROL |
555          USB_HW_POWER_BULK |
556          USB_HW_POWER_INTERRUPT |
557          USB_HW_POWER_ISOC |
558          USB_HW_POWER_NON_ROOT_HUB;
559        bus->no_explore = 0;
560        USB_BUS_UNLOCK(bus);
561
562        if (bus->methods->set_hw_power_sleep != NULL)
563                (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_RESUME);
564
565        if (bus->methods->set_hw_power != NULL)
566                (bus->methods->set_hw_power) (bus);
567
568        /* restore USB configuration to index 0 */
569        err = usbd_set_config_index(udev, 0);
570        if (err)
571                device_printf(bus->bdev, "Could not configure root HUB\n");
572
573        /* probe and attach */
574        err = usb_probe_and_attach(udev, USB_IFACE_INDEX_ANY);
575        if (err) {
576                device_printf(bus->bdev, "Could not probe and "
577                    "attach root HUB\n");
578        }
579
580        if (do_unlock)
581                usbd_enum_unlock(udev);
582
583        USB_BUS_LOCK(bus);
584}
585
586/*------------------------------------------------------------------------*
587 *      usb_bus_reset
588 *
589 * This function is used to reset the USB controller.
590 *------------------------------------------------------------------------*/
591static void
592usb_bus_reset(struct usb_proc_msg *pm)
593{
594        struct usb_bus *bus;
595
596        DPRINTF("\n");
597
598        bus = ((struct usb_bus_msg *)pm)->bus;
599
600        if (bus->bdev == NULL || bus->no_explore != 0)
601                return;
602
603        /* a suspend and resume will reset the USB controller */
604        usb_bus_suspend(pm);
605        usb_bus_resume(pm);
606}
607
608/*------------------------------------------------------------------------*
609 *      usb_bus_shutdown
610 *
611 * This function is used to shutdown the USB controller.
612 *------------------------------------------------------------------------*/
613static void
614usb_bus_shutdown(struct usb_proc_msg *pm)
615{
616        struct usb_bus *bus;
617        struct usb_device *udev;
618        usb_error_t err;
619        uint8_t do_unlock;
620
621        bus = ((struct usb_bus_msg *)pm)->bus;
622        udev = bus->devices[USB_ROOT_HUB_ADDR];
623
624        if (udev == NULL || bus->bdev == NULL)
625                return;
626
627        USB_BUS_UNLOCK(bus);
628
629        bus_generic_shutdown(bus->bdev);
630
631        do_unlock = usbd_enum_lock(udev);
632
633        err = usbd_set_config_index(udev, USB_UNCONFIG_INDEX);
634        if (err)
635                device_printf(bus->bdev, "Could not unconfigure root HUB\n");
636
637        USB_BUS_LOCK(bus);
638        bus->hw_power_state = 0;
639        bus->no_explore = 1;
640        USB_BUS_UNLOCK(bus);
641
642        if (bus->methods->set_hw_power != NULL)
643                (bus->methods->set_hw_power) (bus);
644
645        if (bus->methods->set_hw_power_sleep != NULL)
646                (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_SHUTDOWN);
647
648        if (do_unlock)
649                usbd_enum_unlock(udev);
650
651        USB_BUS_LOCK(bus);
652}
653
654/*------------------------------------------------------------------------*
655 *      usb_bus_cleanup
656 *
657 * This function is used to cleanup leftover USB character devices.
658 *------------------------------------------------------------------------*/
659#if USB_HAVE_UGEN
660static void
661usb_bus_cleanup(struct usb_proc_msg *pm)
662{
663        struct usb_bus *bus;
664        struct usb_fs_privdata *pd;
665
666        bus = ((struct usb_bus_msg *)pm)->bus;
667
668        while ((pd = LIST_FIRST(&bus->pd_cleanup_list)) != NULL) {
669
670                LIST_REMOVE(pd, pd_next);
671                USB_BUS_UNLOCK(bus);
672
673                usb_destroy_dev_sync(pd);
674
675                USB_BUS_LOCK(bus);
676        }
677}
678#endif
679
680static void
681usb_power_wdog(void *arg)
682{
683        struct usb_bus *bus = arg;
684
685        USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
686
687        usb_callout_reset(&bus->power_wdog,
688            4 * hz, usb_power_wdog, arg);
689
690#ifdef DDB
691        /*
692         * The following line of code is only here to recover from
693         * DDB:
694         */
695        usb_proc_rewakeup(USB_BUS_EXPLORE_PROC(bus));   /* recover from DDB */
696#endif
697
698#if USB_HAVE_POWERD
699        USB_BUS_UNLOCK(bus);
700
701        usb_bus_power_update(bus);
702
703        USB_BUS_LOCK(bus);
704#endif
705}
706
707/*------------------------------------------------------------------------*
708 *      usb_bus_attach
709 *
710 * This function attaches USB in context of the explore thread.
711 *------------------------------------------------------------------------*/
712static void
713usb_bus_attach(struct usb_proc_msg *pm)
714{
715        struct usb_bus *bus;
716        struct usb_device *child;
717        device_t dev;
718        usb_error_t err;
719        enum usb_dev_speed speed;
720
721        bus = ((struct usb_bus_msg *)pm)->bus;
722        dev = bus->bdev;
723
724        DPRINTF("\n");
725
726        switch (bus->usbrev) {
727        case USB_REV_1_0:
728                speed = USB_SPEED_FULL;
729                device_printf(bus->bdev, "12Mbps Full Speed USB v1.0\n");
730                break;
731
732        case USB_REV_1_1:
733                speed = USB_SPEED_FULL;
734                device_printf(bus->bdev, "12Mbps Full Speed USB v1.1\n");
735                break;
736
737        case USB_REV_2_0:
738                speed = USB_SPEED_HIGH;
739                device_printf(bus->bdev, "480Mbps High Speed USB v2.0\n");
740                break;
741
742        case USB_REV_2_5:
743                speed = USB_SPEED_VARIABLE;
744                device_printf(bus->bdev, "480Mbps Wireless USB v2.5\n");
745                break;
746
747        case USB_REV_3_0:
748                speed = USB_SPEED_SUPER;
749                device_printf(bus->bdev, "5.0Gbps Super Speed USB v3.0\n");
750                break;
751
752        default:
753                device_printf(bus->bdev, "Unsupported USB revision\n");
754#if USB_HAVE_ROOT_MOUNT_HOLD
755                usb_root_mount_rel(bus);
756#endif
757                return;
758        }
759
760        /* default power_mask value */
761        bus->hw_power_state =
762          USB_HW_POWER_CONTROL |
763          USB_HW_POWER_BULK |
764          USB_HW_POWER_INTERRUPT |
765          USB_HW_POWER_ISOC |
766          USB_HW_POWER_NON_ROOT_HUB;
767
768        USB_BUS_UNLOCK(bus);
769
770        /* make sure power is set at least once */
771
772        if (bus->methods->set_hw_power != NULL) {
773                (bus->methods->set_hw_power) (bus);
774        }
775
776        /* allocate the Root USB device */
777
778        child = usb_alloc_device(bus->bdev, bus, NULL, 0, 0, 1,
779            speed, USB_MODE_HOST);
780        if (child) {
781                err = usb_probe_and_attach(child,
782                    USB_IFACE_INDEX_ANY);
783                if (!err) {
784                        if ((bus->devices[USB_ROOT_HUB_ADDR] == NULL) ||
785                            (bus->devices[USB_ROOT_HUB_ADDR]->hub == NULL)) {
786                                err = USB_ERR_NO_ROOT_HUB;
787                        }
788                }
789        } else {
790                err = USB_ERR_NOMEM;
791        }
792
793        USB_BUS_LOCK(bus);
794
795        if (err) {
796                device_printf(bus->bdev, "Root HUB problem, error=%s\n",
797                    usbd_errstr(err));
798#if USB_HAVE_ROOT_MOUNT_HOLD
799                usb_root_mount_rel(bus);
800#endif
801        }
802
803        /* set softc - we are ready */
804        device_set_softc(dev, bus);
805
806        /* start watchdog */
807        usb_power_wdog(bus);
808}
809
810/*------------------------------------------------------------------------*
811 *      usb_attach_sub
812 *
813 * This function creates a thread which runs the USB attach code.
814 *------------------------------------------------------------------------*/
815static void
816usb_attach_sub(device_t dev, struct usb_bus *bus)
817{
818        mtx_lock(&Giant);
819        if (usb_devclass_ptr == NULL)
820                usb_devclass_ptr = devclass_find("usbus");
821        mtx_unlock(&Giant);
822
823#if USB_HAVE_PF
824        usbpf_attach(bus);
825#endif
826        /* Initialise USB process messages */
827        bus->explore_msg[0].hdr.pm_callback = &usb_bus_explore;
828        bus->explore_msg[0].bus = bus;
829        bus->explore_msg[1].hdr.pm_callback = &usb_bus_explore;
830        bus->explore_msg[1].bus = bus;
831
832        bus->detach_msg[0].hdr.pm_callback = &usb_bus_detach;
833        bus->detach_msg[0].bus = bus;
834        bus->detach_msg[1].hdr.pm_callback = &usb_bus_detach;
835        bus->detach_msg[1].bus = bus;
836
837        bus->attach_msg[0].hdr.pm_callback = &usb_bus_attach;
838        bus->attach_msg[0].bus = bus;
839        bus->attach_msg[1].hdr.pm_callback = &usb_bus_attach;
840        bus->attach_msg[1].bus = bus;
841
842        bus->suspend_msg[0].hdr.pm_callback = &usb_bus_suspend;
843        bus->suspend_msg[0].bus = bus;
844        bus->suspend_msg[1].hdr.pm_callback = &usb_bus_suspend;
845        bus->suspend_msg[1].bus = bus;
846
847        bus->resume_msg[0].hdr.pm_callback = &usb_bus_resume;
848        bus->resume_msg[0].bus = bus;
849        bus->resume_msg[1].hdr.pm_callback = &usb_bus_resume;
850        bus->resume_msg[1].bus = bus;
851
852        bus->reset_msg[0].hdr.pm_callback = &usb_bus_reset;
853        bus->reset_msg[0].bus = bus;
854        bus->reset_msg[1].hdr.pm_callback = &usb_bus_reset;
855        bus->reset_msg[1].bus = bus;
856
857        bus->shutdown_msg[0].hdr.pm_callback = &usb_bus_shutdown;
858        bus->shutdown_msg[0].bus = bus;
859        bus->shutdown_msg[1].hdr.pm_callback = &usb_bus_shutdown;
860        bus->shutdown_msg[1].bus = bus;
861
862#if USB_HAVE_UGEN
863        LIST_INIT(&bus->pd_cleanup_list);
864        bus->cleanup_msg[0].hdr.pm_callback = &usb_bus_cleanup;
865        bus->cleanup_msg[0].bus = bus;
866        bus->cleanup_msg[1].hdr.pm_callback = &usb_bus_cleanup;
867        bus->cleanup_msg[1].bus = bus;
868#endif
869
870#if USB_HAVE_PER_BUS_PROCESS
871        /* Create USB explore and callback processes */
872
873        if (usb_proc_create(USB_BUS_GIANT_PROC(bus),
874            &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
875                device_printf(dev, "WARNING: Creation of USB Giant "
876                    "callback process failed.\n");
877        } else if (usb_proc_create(USB_BUS_NON_GIANT_ISOC_PROC(bus),
878            &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_HIGHEST)) {
879                device_printf(dev, "WARNING: Creation of USB non-Giant ISOC "
880                    "callback process failed.\n");
881        } else if (usb_proc_create(USB_BUS_NON_GIANT_BULK_PROC(bus),
882            &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_HIGH)) {
883                device_printf(dev, "WARNING: Creation of USB non-Giant BULK "
884                    "callback process failed.\n");
885        } else if (usb_proc_create(USB_BUS_EXPLORE_PROC(bus),
886            &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
887                device_printf(dev, "WARNING: Creation of USB explore "
888                    "process failed.\n");
889        } else if (usb_proc_create(USB_BUS_CONTROL_XFER_PROC(bus),
890            &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
891                device_printf(dev, "WARNING: Creation of USB control transfer "
892                    "process failed.\n");
893        } else
894#endif
895        {
896                /* Get final attach going */
897                USB_BUS_LOCK(bus);
898                usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
899                    &bus->attach_msg[0], &bus->attach_msg[1]);
900                USB_BUS_UNLOCK(bus);
901
902                /* Do initial explore */
903                usb_needs_explore(bus, 1);
904        }
905}
906SYSUNINIT(usb_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb_bus_unload, NULL);
907
908/*------------------------------------------------------------------------*
909 *      usb_bus_mem_flush_all_cb
910 *------------------------------------------------------------------------*/
911#if USB_HAVE_BUSDMA
912static void
913usb_bus_mem_flush_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
914    struct usb_page *pg, usb_size_t size, usb_size_t align)
915{
916        usb_pc_cpu_flush(pc);
917}
918#endif
919
920/*------------------------------------------------------------------------*
921 *      usb_bus_mem_flush_all - factored out code
922 *------------------------------------------------------------------------*/
923#if USB_HAVE_BUSDMA
924void
925usb_bus_mem_flush_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
926{
927        if (cb) {
928                cb(bus, &usb_bus_mem_flush_all_cb);
929        }
930}
931#endif
932
933/*------------------------------------------------------------------------*
934 *      usb_bus_mem_alloc_all_cb
935 *------------------------------------------------------------------------*/
936#if USB_HAVE_BUSDMA
937static void
938usb_bus_mem_alloc_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
939    struct usb_page *pg, usb_size_t size, usb_size_t align)
940{
941        /* need to initialize the page cache */
942        pc->tag_parent = bus->dma_parent_tag;
943
944        if (usb_pc_alloc_mem(pc, pg, size, align)) {
945                bus->alloc_failed = 1;
946        }
947}
948#endif
949
950/*------------------------------------------------------------------------*
951 *      usb_bus_mem_alloc_all - factored out code
952 *
953 * Returns:
954 *    0: Success
955 * Else: Failure
956 *------------------------------------------------------------------------*/
957uint8_t
958usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat,
959    usb_bus_mem_cb_t *cb)
960{
961        bus->alloc_failed = 0;
962
963        mtx_init(&bus->bus_mtx, device_get_nameunit(bus->parent),
964            "usb_def_mtx", MTX_DEF | MTX_RECURSE);
965
966        mtx_init(&bus->bus_spin_lock, device_get_nameunit(bus->parent),
967            "usb_spin_mtx", MTX_SPIN | MTX_RECURSE);
968
969        usb_callout_init_mtx(&bus->power_wdog,
970            &bus->bus_mtx, 0);
971
972        TAILQ_INIT(&bus->intr_q.head);
973
974#if USB_HAVE_BUSDMA
975        usb_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags,
976            dmat, &bus->bus_mtx, NULL, bus->dma_bits, USB_BUS_DMA_TAG_MAX);
977#endif
978        if ((bus->devices_max > USB_MAX_DEVICES) ||
979            (bus->devices_max < USB_MIN_DEVICES) ||
980            (bus->devices == NULL)) {
981                DPRINTFN(0, "Devices field has not been "
982                    "initialised properly\n");
983                bus->alloc_failed = 1;          /* failure */
984        }
985#if USB_HAVE_BUSDMA
986        if (cb) {
987                cb(bus, &usb_bus_mem_alloc_all_cb);
988        }
989#endif
990        if (bus->alloc_failed) {
991                usb_bus_mem_free_all(bus, cb);
992        }
993        return (bus->alloc_failed);
994}
995
996/*------------------------------------------------------------------------*
997 *      usb_bus_mem_free_all_cb
998 *------------------------------------------------------------------------*/
999#if USB_HAVE_BUSDMA
1000static void
1001usb_bus_mem_free_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
1002    struct usb_page *pg, usb_size_t size, usb_size_t align)
1003{
1004        usb_pc_free_mem(pc);
1005}
1006#endif
1007
1008/*------------------------------------------------------------------------*
1009 *      usb_bus_mem_free_all - factored out code
1010 *------------------------------------------------------------------------*/
1011void
1012usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
1013{
1014#if USB_HAVE_BUSDMA
1015        if (cb) {
1016                cb(bus, &usb_bus_mem_free_all_cb);
1017        }
1018        usb_dma_tag_unsetup(bus->dma_parent_tag);
1019#endif
1020
1021        mtx_destroy(&bus->bus_mtx);
1022        mtx_destroy(&bus->bus_spin_lock);
1023}
1024
1025/* convenience wrappers */
1026void
1027usb_proc_explore_mwait(struct usb_device *udev, void *pm1, void *pm2)
1028{
1029        usb_proc_mwait(USB_BUS_EXPLORE_PROC(udev->bus), pm1, pm2);
1030}
1031
1032void    *
1033usb_proc_explore_msignal(struct usb_device *udev, void *pm1, void *pm2)
1034{
1035        return (usb_proc_msignal(USB_BUS_EXPLORE_PROC(udev->bus), pm1, pm2));
1036}
1037
1038void
1039usb_proc_explore_lock(struct usb_device *udev)
1040{
1041        USB_BUS_LOCK(udev->bus);
1042}
1043
1044void
1045usb_proc_explore_unlock(struct usb_device *udev)
1046{
1047        USB_BUS_UNLOCK(udev->bus);
1048}
Note: See TracBrowser for help on using the repository browser.