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