FreeBSD kernel usb device Code
usb_hub.c
Go to the documentation of this file.
1/* $FreeBSD$ */
2/*-
3 * SPDX-License-Identifier: BSD-2-Clause-NetBSD
4 *
5 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
6 * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
7 * Copyright (c) 2008-2022 Hans Petter Selasky
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/*
32 * USB spec: http://www.usb.org/developers/docs/usbspec.zip
33 */
34
35#ifdef USB_GLOBAL_INCLUDE_FILE
36#include USB_GLOBAL_INCLUDE_FILE
37#else
38#include <sys/stdint.h>
39#include <sys/stddef.h>
40#include <sys/param.h>
41#include <sys/queue.h>
42#include <sys/types.h>
43#include <sys/systm.h>
44#include <sys/kernel.h>
45#include <sys/bus.h>
46#include <sys/module.h>
47#include <sys/lock.h>
48#include <sys/mutex.h>
49#include <sys/condvar.h>
50#include <sys/sbuf.h>
51#include <sys/sysctl.h>
52#include <sys/sx.h>
53#include <sys/unistd.h>
54#include <sys/callout.h>
55#include <sys/malloc.h>
56#include <sys/priv.h>
57
58#include <dev/usb/usb.h>
59#include <dev/usb/usbdi.h>
60#include <dev/usb/usbdi_util.h>
61
62#define USB_DEBUG_VAR uhub_debug
63
64#include <dev/usb/usb_core.h>
65#include <dev/usb/usb_process.h>
66#include <dev/usb/usb_device.h>
67#include <dev/usb/usb_request.h>
68#include <dev/usb/usb_debug.h>
69#include <dev/usb/usb_hub.h>
70#include <dev/usb/usb_util.h>
71#include <dev/usb/usb_busdma.h>
73#include <dev/usb/usb_dynamic.h>
74
76#include <dev/usb/usb_bus.h>
77#endif /* USB_GLOBAL_INCLUDE_FILE */
78
80
81#ifdef USB_DEBUG
82static int uhub_debug = 0;
83
84static SYSCTL_NODE(_hw_usb, OID_AUTO, uhub, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
85 "USB HUB");
86SYSCTL_INT(_hw_usb_uhub, OID_AUTO, debug, CTLFLAG_RWTUN, &uhub_debug, 0,
87 "Debug level");
88#endif
89
90#if USB_HAVE_POWERD
91static int usb_power_timeout = 30; /* seconds */
92
93SYSCTL_INT(_hw_usb, OID_AUTO, power_timeout, CTLFLAG_RWTUN,
94 &usb_power_timeout, 0, "USB power timeout");
95#endif
96
97#if USB_HAVE_DISABLE_ENUM
98static int usb_disable_enumeration = 0;
99SYSCTL_INT(_hw_usb, OID_AUTO, disable_enumeration, CTLFLAG_RWTUN,
100 &usb_disable_enumeration, 0, "Set to disable all USB device enumeration. "
101 "This can secure against USB devices turning evil, "
102 "for example a USB memory stick becoming a USB keyboard.");
103
104static int usb_disable_port_power = 0;
105SYSCTL_INT(_hw_usb, OID_AUTO, disable_port_power, CTLFLAG_RWTUN,
106 &usb_disable_port_power, 0, "Set to disable all USB port power.");
107#endif
108
109#define UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol)
110#define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
111#define UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
112#define UHUB_IS_MULTI_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBMTT)
113#define UHUB_IS_SUPER_SPEED(sc) (UHUB_PROTO(sc) == UDPROTO_SSHUB)
114
115/* prototypes for type checking: */
116
117static device_suspend_t uhub_suspend;
118static device_resume_t uhub_resume;
119
120static bus_driver_added_t uhub_driver_added;
121static bus_child_pnpinfo_t uhub_child_pnpinfo;
122
124#if USB_HAVE_TT_SUPPORT
125static usb_callback_t uhub_reset_tt_callback;
126#endif
127
128static void usb_dev_resume_peer(struct usb_device *udev);
129static void usb_dev_suspend_peer(struct usb_device *udev);
130static uint8_t usb_peer_should_wakeup(struct usb_device *udev);
131
132static const struct usb_config uhub_config[UHUB_N_TRANSFER] = {
135 .endpoint = UE_ADDR_ANY,
136 .direction = UE_DIR_ANY,
137 .timeout = 0,
138 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
139 .bufsize = 0, /* use wMaxPacketSize */
140 .callback = &uhub_intr_callback,
141 .interval = UHUB_INTR_INTERVAL,
142 },
143#if USB_HAVE_TT_SUPPORT
144 [UHUB_RESET_TT_TRANSFER] = {
145 .type = UE_CONTROL,
146 .endpoint = 0x00, /* Control pipe */
147 .direction = UE_DIR_ANY,
148 .bufsize = sizeof(struct usb_device_request),
149 .callback = &uhub_reset_tt_callback,
150 .timeout = 1000, /* 1 second */
151 .usb_mode = USB_MODE_HOST,
152 },
153#endif
154};
155
156/*
157 * driver instance for "hub" connected to "usb"
158 * and "hub" connected to "hub"
159 */
160static devclass_t uhub_devclass;
161
162static device_method_t uhub_methods[] = {
163 DEVMETHOD(device_probe, uhub_probe),
164 DEVMETHOD(device_attach, uhub_attach),
165 DEVMETHOD(device_detach, uhub_detach),
166
167 DEVMETHOD(device_suspend, uhub_suspend),
168 DEVMETHOD(device_resume, uhub_resume),
169
170 DEVMETHOD(bus_child_location, uhub_child_location),
171 DEVMETHOD(bus_child_pnpinfo, uhub_child_pnpinfo),
172 DEVMETHOD(bus_get_device_path, uhub_get_device_path),
173 DEVMETHOD(bus_driver_added, uhub_driver_added),
174 DEVMETHOD_END
175};
176
177driver_t uhub_driver = {
178 .name = "uhub",
179 .methods = uhub_methods,
180 .size = sizeof(struct uhub_softc)
181};
182
186
187static void
189{
190 struct uhub_softc *sc = usbd_xfer_softc(xfer);
191
192 switch (USB_GET_STATE(xfer)) {
194 DPRINTFN(2, "\n");
195 /*
196 * This is an indication that some port
197 * has changed status. Notify the bus
198 * event handler thread that we need
199 * to be explored again:
200 */
202
203 case USB_ST_SETUP:
206 break;
207
208 default: /* Error */
209 if (xfer->error != USB_ERR_CANCELLED) {
210 /*
211 * Do a clear-stall. The "stall_pipe" flag
212 * will get cleared before next callback by
213 * the USB stack.
214 */
218 }
219 break;
220 }
221}
222
223/*------------------------------------------------------------------------*
224 * uhub_reset_tt_proc
225 *
226 * This function starts the TT reset USB request
227 *------------------------------------------------------------------------*/
228#if USB_HAVE_TT_SUPPORT
229static void
230uhub_reset_tt_proc(struct usb_proc_msg *_pm)
231{
232 struct usb_udev_msg *pm = (void *)_pm;
233 struct usb_device *udev = pm->udev;
234 struct usb_hub *hub;
235 struct uhub_softc *sc;
236
237 hub = udev->hub;
238 if (hub == NULL)
239 return;
240 sc = hub->hubsoftc;
241 if (sc == NULL)
242 return;
243
244 /* Change lock */
245 USB_BUS_UNLOCK(udev->bus);
246 USB_MTX_LOCK(&sc->sc_mtx);
247 /* Start transfer */
248 usbd_transfer_start(sc->sc_xfer[UHUB_RESET_TT_TRANSFER]);
249 /* Change lock */
251 USB_BUS_LOCK(udev->bus);
252}
253#endif
254
255/*------------------------------------------------------------------------*
256 * uhub_tt_buffer_reset_async_locked
257 *
258 * This function queues a TT reset for the given USB device and endpoint.
259 *------------------------------------------------------------------------*/
260#if USB_HAVE_TT_SUPPORT
261void
262uhub_tt_buffer_reset_async_locked(struct usb_device *child, struct usb_endpoint *ep)
263{
264 struct usb_device_request req;
265 struct usb_device *udev;
266 struct usb_hub *hub;
267 struct usb_port *up;
268 uint16_t wValue;
269 uint8_t port;
270
271 if (child == NULL || ep == NULL)
272 return;
273
274 udev = child->parent_hs_hub;
275 port = child->hs_port_no;
276
277 if (udev == NULL)
278 return;
279
280 hub = udev->hub;
281 if ((hub == NULL) ||
282 (udev->speed != USB_SPEED_HIGH) ||
283 (child->speed != USB_SPEED_LOW &&
284 child->speed != USB_SPEED_FULL) ||
285 (child->flags.usb_mode != USB_MODE_HOST) ||
286 (port == 0) || (ep->edesc == NULL)) {
287 /* not applicable */
288 return;
289 }
290
291 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
292
293 up = hub->ports + port - 1;
294
295 if (udev->ddesc.bDeviceClass == UDCLASS_HUB &&
297 port = 1;
298
299 /* if we already received a clear buffer request, reset the whole TT */
300 if (up->req_reset_tt.bRequest != 0) {
301 req.bmRequestType = UT_WRITE_CLASS_OTHER;
302 req.bRequest = UR_RESET_TT;
303 USETW(req.wValue, 0);
304 req.wIndex[0] = port;
305 req.wIndex[1] = 0;
306 USETW(req.wLength, 0);
307 } else {
308 wValue = (ep->edesc->bEndpointAddress & 0xF) |
309 ((child->address & 0x7F) << 4) |
310 ((ep->edesc->bEndpointAddress & 0x80) << 8) |
311 ((ep->edesc->bmAttributes & 3) << 12);
312
313 req.bmRequestType = UT_WRITE_CLASS_OTHER;
314 req.bRequest = UR_CLEAR_TT_BUFFER;
315 USETW(req.wValue, wValue);
316 req.wIndex[0] = port;
317 req.wIndex[1] = 0;
318 USETW(req.wLength, 0);
319 }
320 up->req_reset_tt = req;
321 /* get reset transfer started */
323 &hub->tt_msg[0], &hub->tt_msg[1]);
324}
325#endif
326
327#if USB_HAVE_TT_SUPPORT
328static void
329uhub_reset_tt_callback(struct usb_xfer *xfer, usb_error_t error)
330{
331 struct uhub_softc *sc;
332 struct usb_device *udev;
333 struct usb_port *up;
334 uint8_t x;
335
336 DPRINTF("TT buffer reset\n");
337
338 sc = usbd_xfer_softc(xfer);
339 udev = sc->sc_udev;
340
341 switch (USB_GET_STATE(xfer)) {
343 case USB_ST_SETUP:
344tr_setup:
345 USB_BUS_LOCK(udev->bus);
346 /* find first port which needs a TT reset */
347 for (x = 0; x != udev->hub->nports; x++) {
348 up = udev->hub->ports + x;
349
350 if (up->req_reset_tt.bRequest == 0)
351 continue;
352
353 /* copy in the transfer */
354 usbd_copy_in(xfer->frbuffers, 0, &up->req_reset_tt,
355 sizeof(up->req_reset_tt));
356 /* reset buffer */
357 memset(&up->req_reset_tt, 0, sizeof(up->req_reset_tt));
358
359 /* set length */
360 usbd_xfer_set_frame_len(xfer, 0, sizeof(up->req_reset_tt));
361 xfer->nframes = 1;
362 USB_BUS_UNLOCK(udev->bus);
363
365 return;
366 }
367 USB_BUS_UNLOCK(udev->bus);
368 break;
369
370 default:
372 break;
373
374 DPRINTF("TT buffer reset failed (%s)\n", usbd_errstr(error));
375 goto tr_setup;
376 }
377}
378#endif
379
380/*------------------------------------------------------------------------*
381 * uhub_count_active_host_ports
382 *
383 * This function counts the number of active ports at the given speed.
384 *------------------------------------------------------------------------*/
385uint8_t
387{
388 struct uhub_softc *sc;
389 struct usb_device *child;
390 struct usb_hub *hub;
391 struct usb_port *up;
392 uint8_t retval = 0;
393 uint8_t x;
394
395 if (udev == NULL)
396 goto done;
397 hub = udev->hub;
398 if (hub == NULL)
399 goto done;
400 sc = hub->hubsoftc;
401 if (sc == NULL)
402 goto done;
403
404 for (x = 0; x != hub->nports; x++) {
405 up = hub->ports + x;
406 child = usb_bus_port_get_device(udev->bus, up);
407 if (child != NULL &&
408 child->flags.usb_mode == USB_MODE_HOST &&
409 child->speed == speed)
410 retval++;
411 }
412done:
413 return (retval);
414}
415
416void
418{
419 uint8_t do_unlock;
420 usb_error_t err;
421
422 /* check if device should be re-enumerated */
423 if (child->flags.usb_mode != USB_MODE_HOST)
424 return;
425
426 do_unlock = usbd_enum_lock(child);
427 switch (child->re_enumerate_wait) {
431 if (err != 0) {
432 DPRINTF("Unconfigure failed: %s: Ignored.\n",
433 usbd_errstr(err));
434 }
435 if (child->parent_hub == NULL) {
436 /* the root HUB cannot be re-enumerated */
437 DPRINTFN(6, "cannot reset root HUB\n");
438 err = 0;
439 } else {
440 err = usbd_req_re_enumerate(child, NULL);
441 }
442 if (err == 0) {
443 /* refresh device strings */
446
447 /* set default configuration */
449 }
450 if (err == 0) {
453 }
454 child->re_enumerate_wait = USB_RE_ENUM_DONE;
455 break;
456
458 /* get the device unconfigured */
461 if (err) {
462 DPRINTFN(0, "Could not unconfigure "
463 "device (ignored)\n");
464 }
465 if (child->parent_hub == NULL) {
466 /* the root HUB cannot be re-enumerated */
467 DPRINTFN(6, "cannot set port feature\n");
468 err = 0;
469 } else {
470 /* clear port enable */
471 err = usbd_req_clear_port_feature(child->parent_hub,
472 NULL, child->port_no, UHF_PORT_ENABLE);
473 if (err) {
474 DPRINTFN(0, "Could not disable port "
475 "(ignored)\n");
476 }
477 }
478 child->re_enumerate_wait = USB_RE_ENUM_DONE;
479 break;
480
483 child->next_config_index);
484 if (err != 0) {
485 DPRINTF("Configure failed: %s: Ignored.\n",
486 usbd_errstr(err));
487 } else {
490 }
491 child->re_enumerate_wait = USB_RE_ENUM_DONE;
492 break;
493
494 default:
495 child->re_enumerate_wait = USB_RE_ENUM_DONE;
496 break;
497 }
498 if (do_unlock)
500}
501
502/*------------------------------------------------------------------------*
503 * uhub_explore_sub - subroutine
504 *
505 * Return values:
506 * 0: Success
507 * Else: A control transaction failed
508 *------------------------------------------------------------------------*/
509static usb_error_t
510uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up)
511{
512 struct usb_bus *bus;
513 struct usb_device *child;
514 uint8_t refcount;
515 usb_error_t err;
516
517 bus = sc->sc_udev->bus;
519
520 /* get driver added refcount from USB bus */
522
523 /* get device assosiated with the given port */
525 if (child == NULL) {
526 /* nothing to do */
527 goto done;
528 }
529
531
532 /* check if probe and attach should be done */
533
534 if (child->driver_added_refcount != refcount) {
535 child->driver_added_refcount = refcount;
538 if (err) {
539 goto done;
540 }
541 }
542 /* start control transfer, if device mode */
543
544 if (child->flags.usb_mode == USB_MODE_DEVICE)
546
547 /* if a HUB becomes present, do a recursive HUB explore */
548
549 if (child->hub)
550 err = (child->hub->explore) (child);
551
552done:
553 return (err);
554}
555
556/*------------------------------------------------------------------------*
557 * uhub_read_port_status - factored out code
558 *------------------------------------------------------------------------*/
559static usb_error_t
560uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
561{
562 struct usb_port_status ps;
563 usb_error_t err;
564
566 DPRINTFN(4, "port %d, HUB looks dead, too many errors\n", portno);
567 sc->sc_st.port_status = 0;
568 sc->sc_st.port_change = 0;
569 return (USB_ERR_TIMEOUT);
570 }
571
573 sc->sc_udev, NULL, &ps, portno);
574
575 if (err == 0) {
578 sc->sc_usb_port_errors = 0;
579 } else {
580 sc->sc_st.port_status = 0;
581 sc->sc_st.port_change = 0;
582 sc->sc_usb_port_errors++;
583 }
584
585 /* debugging print */
586
587 DPRINTFN(4, "port %d, wPortStatus=0x%04x, "
588 "wPortChange=0x%04x, err=%s\n",
589 portno, sc->sc_st.port_status,
590 sc->sc_st.port_change, usbd_errstr(err));
591 return (err);
592}
593
594/*------------------------------------------------------------------------*
595 * uhub_reattach_port
596 *
597 * Returns:
598 * 0: Success
599 * Else: A control transaction failed
600 *------------------------------------------------------------------------*/
601static usb_error_t
602uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
603{
604 struct usb_device *child;
605 struct usb_device *udev;
606 enum usb_dev_speed speed;
607 enum usb_hc_mode mode;
608 usb_error_t err;
609 uint16_t power_mask;
610 uint8_t timeout;
611
612 DPRINTF("reattaching port %d\n", portno);
613
614 timeout = 0;
615 udev = sc->sc_udev;
617 udev->hub->ports + portno - 1);
618
619repeat:
620
621 /* first clear the port connection change bit */
622
623 err = usbd_req_clear_port_feature(udev, NULL,
624 portno, UHF_C_PORT_CONNECTION);
625
626 if (err)
627 goto error;
628
629 /* check if there is a child */
630
631 if (child != NULL) {
632 /*
633 * Free USB device and all subdevices, if any.
634 */
636 child = NULL;
637 }
638 /* get fresh status */
639
640 err = uhub_read_port_status(sc, portno);
641 if (err)
642 goto error;
643
644#if USB_HAVE_DISABLE_ENUM
645 /* check if we should skip enumeration from this USB HUB */
646 if (usb_disable_enumeration != 0 ||
647 sc->sc_disable_enumeration != 0) {
648 DPRINTF("Enumeration is disabled!\n");
649 goto error;
650 }
651#endif
652 /* check if nothing is connected to the port */
653
655 goto error;
656
657 /* check if there is no power on the port and print a warning */
658
659 switch (udev->speed) {
660 case USB_SPEED_HIGH:
661 case USB_SPEED_FULL:
662 case USB_SPEED_LOW:
663 power_mask = UPS_PORT_POWER;
664 break;
665 case USB_SPEED_SUPER:
666 if (udev->parent_hub == NULL)
667 power_mask = 0; /* XXX undefined */
668 else
669 power_mask = UPS_PORT_POWER_SS;
670 break;
671 default:
672 power_mask = 0;
673 break;
674 }
675 if ((sc->sc_st.port_status & power_mask) != power_mask) {
676 DPRINTF("WARNING: strange, connected port %d "
677 "has no power\n", portno);
678 }
679
680 /* check if the device is in Host Mode */
681
683 DPRINTF("Port %d is in Host Mode\n", portno);
684
685 if (sc->sc_st.port_status & UPS_SUSPEND) {
686 /*
687 * NOTE: Should not get here in SuperSpeed
688 * mode, because the HUB should report this
689 * bit as zero.
690 */
691 DPRINTF("Port %d was still "
692 "suspended, clearing.\n", portno);
694 NULL, portno, UHF_PORT_SUSPEND);
695 }
696
697 /* USB Host Mode */
698
699 /* wait for maximum device power up time */
700
701 usb_pause_mtx(NULL,
703
704 /* reset port, which implies enabling it */
705
706 err = usbd_req_reset_port(udev, NULL, portno);
707
708 if (err) {
709 DPRINTFN(0, "port %d reset "
710 "failed, error=%s\n",
711 portno, usbd_errstr(err));
712 goto error;
713 }
714 /* get port status again, it might have changed during reset */
715
716 err = uhub_read_port_status(sc, portno);
717 if (err) {
718 goto error;
719 }
720 /* check if something changed during port reset */
721
724 if (timeout) {
725 DPRINTFN(1, "giving up port %d reset - "
726 "device vanished: change %#x status %#x\n",
727 portno, sc->sc_st.port_change,
728 sc->sc_st.port_status);
729 goto error;
730 }
731 timeout = 1;
732 goto repeat;
733 }
734 } else {
735 DPRINTF("Port %d is in Device Mode\n", portno);
736 }
737
738 /*
739 * Figure out the device speed
740 */
741 switch (udev->speed) {
742 case USB_SPEED_HIGH:
745 else if (sc->sc_st.port_status & UPS_LOW_SPEED)
747 else
749 break;
750 case USB_SPEED_FULL:
753 else
755 break;
756 case USB_SPEED_LOW:
758 break;
759 case USB_SPEED_SUPER:
760 if (udev->parent_hub == NULL) {
761 /* Root HUB - special case */
762 switch (sc->sc_st.port_status & UPS_OTHER_SPEED) {
763 case 0:
765 break;
766 case UPS_LOW_SPEED:
768 break;
769 case UPS_HIGH_SPEED:
771 break;
772 default:
774 break;
775 }
776 } else {
778 }
779 break;
780 default:
781 /* same speed like parent */
782 speed = udev->speed;
783 break;
784 }
785 if (speed == USB_SPEED_SUPER) {
786 err = usbd_req_set_hub_u1_timeout(udev, NULL,
787 portno, 128 - (2 * udev->depth));
788 if (err) {
789 DPRINTFN(0, "port %d U1 timeout "
790 "failed, error=%s\n",
791 portno, usbd_errstr(err));
792 }
793 err = usbd_req_set_hub_u2_timeout(udev, NULL,
794 portno, 128 - (2 * udev->depth));
795 if (err) {
796 DPRINTFN(0, "port %d U2 timeout "
797 "failed, error=%s\n",
798 portno, usbd_errstr(err));
799 }
800 }
801
802 /*
803 * Figure out the device mode
804 *
805 * NOTE: This part is currently FreeBSD specific.
806 */
807 if (udev->parent_hub != NULL) {
808 /* inherit mode from the parent HUB */
809 mode = udev->parent_hub->flags.usb_mode;
810 } else if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)
811 mode = USB_MODE_DEVICE;
812 else
813 mode = USB_MODE_HOST;
814
815 /* need to create a new child */
816 child = usb_alloc_device(sc->sc_dev, udev->bus, udev,
817 udev->depth + 1, portno - 1, portno, speed, mode);
818 if (child == NULL) {
819 DPRINTFN(0, "could not allocate new device\n");
820 goto error;
821 }
822 return (0); /* success */
823
824error:
825 if (child != NULL) {
826 /*
827 * Free USB device and all subdevices, if any.
828 */
830 child = NULL;
831 }
832 if (err == 0) {
835 sc->sc_udev, NULL,
836 portno, UHF_PORT_ENABLE);
837 }
838 }
839 if (err) {
840 DPRINTFN(0, "device problem (%s), "
841 "disabling port %d\n", usbd_errstr(err), portno);
842 }
843 return (err);
844}
845
846/*------------------------------------------------------------------------*
847 * usb_device_20_compatible
848 *
849 * Returns:
850 * 0: HUB does not support suspend and resume
851 * Else: HUB supports suspend and resume
852 *------------------------------------------------------------------------*/
853static uint8_t
855{
856 if (udev == NULL)
857 return (0);
858 switch (udev->speed) {
859 case USB_SPEED_LOW:
860 case USB_SPEED_FULL:
861 case USB_SPEED_HIGH:
862 return (1);
863 default:
864 return (0);
865 }
866}
867
868/*------------------------------------------------------------------------*
869 * uhub_suspend_resume_port
870 *
871 * Returns:
872 * 0: Success
873 * Else: A control transaction failed
874 *------------------------------------------------------------------------*/
875static usb_error_t
876uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno)
877{
878 struct usb_device *child;
879 struct usb_device *udev;
880 uint8_t is_suspend;
881 usb_error_t err;
882
883 DPRINTF("port %d\n", portno);
884
885 udev = sc->sc_udev;
887 udev->hub->ports + portno - 1);
888
889 /* first clear the port suspend change bit */
890
891 if (usb_device_20_compatible(udev)) {
892 err = usbd_req_clear_port_feature(udev, NULL,
893 portno, UHF_C_PORT_SUSPEND);
894 } else {
895 err = usbd_req_clear_port_feature(udev, NULL,
896 portno, UHF_C_PORT_LINK_STATE);
897 }
898
899 if (err) {
900 DPRINTF("clearing suspend failed.\n");
901 goto done;
902 }
903 /* get fresh status */
904
905 err = uhub_read_port_status(sc, portno);
906 if (err) {
907 DPRINTF("reading port status failed.\n");
908 goto done;
909 }
910 /* convert current state */
911
912 if (usb_device_20_compatible(udev)) {
913 if (sc->sc_st.port_status & UPS_SUSPEND) {
914 is_suspend = 1;
915 } else {
916 is_suspend = 0;
917 }
918 } else {
920 case UPS_PORT_LS_U3:
921 is_suspend = 1;
922 break;
924 usbd_req_warm_reset_port(udev, NULL, portno);
925 is_suspend = 0;
926 break;
927 default:
928 is_suspend = 0;
929 break;
930 }
931 }
932
933 DPRINTF("suspended=%u\n", is_suspend);
934
935 /* do the suspend or resume */
936
937 if (child) {
938 /*
939 * This code handle two cases: 1) Host Mode - we can only
940 * receive resume here 2) Device Mode - we can receive
941 * suspend and resume here
942 */
943 if (is_suspend == 0)
945 else if (child->flags.usb_mode == USB_MODE_DEVICE)
947 }
948done:
949 return (err);
950}
951
952/*------------------------------------------------------------------------*
953 * uhub_root_interrupt
954 *
955 * This function is called when a Root HUB interrupt has
956 * happened. "ptr" and "len" makes up the Root HUB interrupt
957 * packet. This function is called having the "bus_mtx" locked.
958 *------------------------------------------------------------------------*/
959void
960uhub_root_intr(struct usb_bus *bus, const uint8_t *ptr, uint8_t len)
961{
962 USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
963
965}
966
967static uint8_t
969{
970 switch (udev->speed) {
971 case USB_SPEED_FULL:
972 case USB_SPEED_LOW:
973 case USB_SPEED_HIGH:
974 if (udev->depth > USB_HUB_MAX_DEPTH)
975 return (1);
976 break;
977 case USB_SPEED_SUPER:
978 if (udev->depth > USB_SS_HUB_DEPTH_MAX)
979 return (1);
980 break;
981 default:
982 break;
983 }
984 return (0);
985}
986
987/*------------------------------------------------------------------------*
988 * uhub_explore
989 *
990 * Returns:
991 * 0: Success
992 * Else: Failure
993 *------------------------------------------------------------------------*/
994static usb_error_t
996{
997 struct usb_hub *hub;
998 struct uhub_softc *sc;
999 struct usb_port *up;
1000 usb_error_t retval;
1001 usb_error_t err;
1002 uint8_t portno;
1003 uint8_t x;
1004 uint8_t do_unlock;
1005
1006 hub = udev->hub;
1007 sc = hub->hubsoftc;
1008
1009 DPRINTFN(11, "udev=%p addr=%d\n", udev, udev->address);
1010
1011 /* ignore devices that are too deep */
1012 if (uhub_is_too_deep(udev))
1013 return (USB_ERR_TOO_DEEP);
1014
1015 /* check if device is suspended */
1016 if (udev->flags.self_suspended) {
1017 /* need to wait until the child signals resume */
1018 DPRINTF("Device is suspended!\n");
1020 }
1021
1022 /*
1023 * Make sure we don't race against user-space applications
1024 * like LibUSB:
1025 */
1026 do_unlock = usbd_enum_lock(udev);
1027
1028 /*
1029 * Set default error code to avoid compiler warnings.
1030 * Note that hub->nports cannot be zero.
1031 */
1033
1034 for (x = 0; x != hub->nports; x++) {
1035 up = hub->ports + x;
1036 portno = x + 1;
1037
1038 err = uhub_read_port_status(sc, portno);
1039 if (err != USB_ERR_NORMAL_COMPLETION)
1040 retval = err;
1041
1043 DPRINTF("Overcurrent on port %u.\n", portno);
1045 udev, NULL, portno, UHF_C_PORT_OVER_CURRENT);
1046 if (err != USB_ERR_NORMAL_COMPLETION)
1047 retval = err;
1048 }
1049 if (!(sc->sc_flags & UHUB_FLAG_DID_EXPLORE)) {
1050 /*
1051 * Fake a connect status change so that the
1052 * status gets checked initially!
1053 */
1054 sc->sc_st.port_change |=
1056 }
1059 udev, NULL, portno, UHF_C_PORT_ENABLE);
1060 if (err != USB_ERR_NORMAL_COMPLETION)
1061 retval = err;
1063 /*
1064 * Ignore the port error if the device
1065 * has vanished !
1066 */
1067 } else if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
1068 DPRINTFN(0, "illegal enable change, "
1069 "port %d\n", portno);
1070 } else {
1071 if (up->restartcnt == USB_RESTART_MAX) {
1072 /* XXX could try another speed ? */
1073 DPRINTFN(0, "port error, giving up "
1074 "port %d\n", portno);
1075 } else {
1076 sc->sc_st.port_change |=
1078 up->restartcnt++;
1079 }
1080 }
1081 }
1083 err = uhub_reattach_port(sc, portno);
1084 if (err != USB_ERR_NORMAL_COMPLETION)
1085 retval = err;
1086 }
1087 if (sc->sc_st.port_change & (UPS_C_SUSPEND |
1089 err = uhub_suspend_resume_port(sc, portno);
1090 if (err != USB_ERR_NORMAL_COMPLETION)
1091 retval = err;
1092 }
1093
1095 /* explore succeeded - reset restart counter */
1096 up->restartcnt = 0;
1097 }
1098 }
1099
1100 if (do_unlock)
1101 usbd_enum_unlock(udev);
1102
1103 /* initial status checked */
1105
1106 return (retval);
1107}
1108
1109int
1110uhub_probe(device_t dev)
1111{
1112 struct usb_attach_arg *uaa = device_get_ivars(dev);
1113
1114 if (uaa->usb_mode != USB_MODE_HOST)
1115 return (ENXIO);
1116
1117 /*
1118 * The subclass for USB HUBs is currently ignored because it
1119 * is 0 for some and 1 for others.
1120 */
1121 if (uaa->info.bConfigIndex == 0 &&
1123 return (BUS_PROBE_DEFAULT);
1124
1125 return (ENXIO);
1126}
1127
1128/* NOTE: The information returned by this function can be wrong. */
1130uhub_query_info(struct usb_device *udev, uint8_t *pnports, uint8_t *ptt)
1131{
1132 struct usb_hub_descriptor hubdesc20;
1133 struct usb_hub_ss_descriptor hubdesc30;
1134 usb_error_t err;
1135 uint8_t nports;
1136 uint8_t tt;
1137
1138 if (udev->ddesc.bDeviceClass != UDCLASS_HUB)
1139 return (USB_ERR_INVAL);
1140
1141 nports = 0;
1142 tt = 0;
1143
1144 switch (udev->speed) {
1145 case USB_SPEED_LOW:
1146 case USB_SPEED_FULL:
1147 case USB_SPEED_HIGH:
1148 /* assuming that there is one port */
1149 err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc20, 1);
1150 if (err) {
1151 DPRINTFN(0, "getting USB 2.0 HUB descriptor failed,"
1152 "error=%s\n", usbd_errstr(err));
1153 break;
1154 }
1155 nports = hubdesc20.bNbrPorts;
1156 if (nports > 127)
1157 nports = 127;
1158
1159 if (udev->speed == USB_SPEED_HIGH)
1160 tt = (UGETW(hubdesc20.wHubCharacteristics) >> 5) & 3;
1161 break;
1162
1163 case USB_SPEED_SUPER:
1164 err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30, 1);
1165 if (err) {
1166 DPRINTFN(0, "Getting USB 3.0 HUB descriptor failed,"
1167 "error=%s\n", usbd_errstr(err));
1168 break;
1169 }
1170 nports = hubdesc30.bNbrPorts;
1171 if (nports > 16)
1172 nports = 16;
1173 break;
1174
1175 default:
1176 err = USB_ERR_INVAL;
1177 break;
1178 }
1179
1180 if (pnports != NULL)
1181 *pnports = nports;
1182
1183 if (ptt != NULL)
1184 *ptt = tt;
1185
1186 return (err);
1187}
1188
1189int
1190uhub_attach(device_t dev)
1191{
1192 struct uhub_softc *sc = device_get_softc(dev);
1193 struct usb_attach_arg *uaa = device_get_ivars(dev);
1194 struct usb_device *udev = uaa->device;
1195 struct usb_device *parent_hub = udev->parent_hub;
1196 struct usb_hub *hub;
1197 struct usb_hub_descriptor hubdesc20;
1198 struct usb_hub_ss_descriptor hubdesc30;
1199#if USB_HAVE_DISABLE_ENUM
1200 struct sysctl_ctx_list *sysctl_ctx;
1201 struct sysctl_oid *sysctl_tree;
1202#endif
1203 uint16_t pwrdly;
1204 uint16_t nports;
1205 uint8_t x;
1206 uint8_t portno;
1207 uint8_t removable;
1208 uint8_t iface_index;
1209 usb_error_t err;
1210
1211 sc->sc_udev = udev;
1212 sc->sc_dev = dev;
1213
1214 mtx_init(&sc->sc_mtx, "USB HUB mutex", NULL, MTX_DEF);
1215
1217
1218 DPRINTFN(2, "depth=%d selfpowered=%d, parent=%p, "
1219 "parent->selfpowered=%d\n",
1220 udev->depth,
1221 udev->flags.self_powered,
1222 parent_hub,
1223 parent_hub ?
1224 parent_hub->flags.self_powered : 0);
1225
1226 if (uhub_is_too_deep(udev)) {
1227 DPRINTFN(0, "HUB at depth %d, "
1228 "exceeds maximum. HUB ignored\n", (int)udev->depth);
1229 goto error;
1230 }
1231
1232 if (!udev->flags.self_powered && parent_hub &&
1233 !parent_hub->flags.self_powered) {
1234 DPRINTFN(0, "Bus powered HUB connected to "
1235 "bus powered HUB. HUB ignored\n");
1236 goto error;
1237 }
1238
1239 if (UHUB_IS_MULTI_TT(sc)) {
1240 err = usbd_set_alt_interface_index(udev, 0, 1);
1241 if (err) {
1242 device_printf(dev, "MTT could not be enabled\n");
1243 goto error;
1244 }
1245 device_printf(dev, "MTT enabled\n");
1246 }
1247
1248 /* get HUB descriptor */
1249
1250 DPRINTFN(2, "Getting HUB descriptor\n");
1251
1252 switch (udev->speed) {
1253 case USB_SPEED_LOW:
1254 case USB_SPEED_FULL:
1255 case USB_SPEED_HIGH:
1256 /* assuming that there is one port */
1257 err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc20, 1);
1258 if (err) {
1259 DPRINTFN(0, "getting USB 2.0 HUB descriptor failed,"
1260 "error=%s\n", usbd_errstr(err));
1261 goto error;
1262 }
1263 /* get number of ports */
1264 nports = hubdesc20.bNbrPorts;
1265
1266 /* get power delay */
1267 pwrdly = ((hubdesc20.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
1269
1270 /* get complete HUB descriptor */
1271 if (nports >= 8) {
1272 /* check number of ports */
1273 if (nports > 127) {
1274 DPRINTFN(0, "Invalid number of USB 2.0 ports,"
1275 "error=%s\n", usbd_errstr(err));
1276 goto error;
1277 }
1278 /* get complete HUB descriptor */
1279 err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc20, nports);
1280
1281 if (err) {
1282 DPRINTFN(0, "Getting USB 2.0 HUB descriptor failed,"
1283 "error=%s\n", usbd_errstr(err));
1284 goto error;
1285 }
1286 if (hubdesc20.bNbrPorts != nports) {
1287 DPRINTFN(0, "Number of ports changed\n");
1288 goto error;
1289 }
1290 }
1291 break;
1292 case USB_SPEED_SUPER:
1293 if (udev->parent_hub != NULL) {
1294 err = usbd_req_set_hub_depth(udev, NULL,
1295 udev->depth - 1);
1296 if (err) {
1297 DPRINTFN(0, "Setting USB 3.0 HUB depth failed,"
1298 "error=%s\n", usbd_errstr(err));
1299 goto error;
1300 }
1301 }
1302 err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30, 1);
1303 if (err) {
1304 DPRINTFN(0, "Getting USB 3.0 HUB descriptor failed,"
1305 "error=%s\n", usbd_errstr(err));
1306 goto error;
1307 }
1308 /* get number of ports */
1309 nports = hubdesc30.bNbrPorts;
1310
1311 /* get power delay */
1312 pwrdly = ((hubdesc30.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
1314
1315 /* get complete HUB descriptor */
1316 if (nports >= 8) {
1317 /* check number of ports */
1318 if (nports > ((udev->parent_hub != NULL) ? 15 : 127)) {
1319 DPRINTFN(0, "Invalid number of USB 3.0 ports,"
1320 "error=%s\n", usbd_errstr(err));
1321 goto error;
1322 }
1323 /* get complete HUB descriptor */
1324 err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30, nports);
1325
1326 if (err) {
1327 DPRINTFN(0, "Getting USB 2.0 HUB descriptor failed,"
1328 "error=%s\n", usbd_errstr(err));
1329 goto error;
1330 }
1331 if (hubdesc30.bNbrPorts != nports) {
1332 DPRINTFN(0, "Number of ports changed\n");
1333 goto error;
1334 }
1335 }
1336 break;
1337 default:
1338 DPRINTF("Assuming HUB has only one port\n");
1339 /* default number of ports */
1340 nports = 1;
1341 /* default power delay */
1342 pwrdly = ((10 * UHD_PWRON_FACTOR) + usb_extra_power_up_time);
1343 break;
1344 }
1345 if (nports == 0) {
1346 DPRINTFN(0, "portless HUB\n");
1347 goto error;
1348 }
1349 if (nports > USB_MAX_PORTS) {
1350 DPRINTF("Port limit exceeded\n");
1351 goto error;
1352 }
1353#if (USB_HAVE_FIXED_PORT == 0)
1354 hub = malloc(sizeof(hub[0]) + (sizeof(hub->ports[0]) * nports),
1355 M_USBDEV, M_WAITOK | M_ZERO);
1356
1357 if (hub == NULL)
1358 goto error;
1359#else
1360 hub = &sc->sc_hub;
1361#endif
1362 udev->hub = hub;
1363
1364 /* initialize HUB structure */
1365 hub->hubsoftc = sc;
1366 hub->explore = &uhub_explore;
1367 hub->nports = nports;
1368 hub->hubudev = udev;
1369#if USB_HAVE_TT_SUPPORT
1370 hub->tt_msg[0].hdr.pm_callback = &uhub_reset_tt_proc;
1371 hub->tt_msg[0].udev = udev;
1372 hub->tt_msg[1].hdr.pm_callback = &uhub_reset_tt_proc;
1373 hub->tt_msg[1].udev = udev;
1374#endif
1375 /* if self powered hub, give ports maximum current */
1376 if (udev->flags.self_powered) {
1377 hub->portpower = USB_MAX_POWER;
1378 } else {
1379 hub->portpower = USB_MIN_POWER;
1380 }
1381
1382 /* set up interrupt pipe */
1383 iface_index = 0;
1384 if (udev->parent_hub == NULL) {
1385 /* root HUB is special */
1386 err = 0;
1387 } else {
1388 /* normal HUB */
1389 err = usbd_transfer_setup(udev, &iface_index, sc->sc_xfer,
1391 }
1392 if (err) {
1393 DPRINTFN(0, "cannot setup interrupt transfer, "
1394 "errstr=%s\n", usbd_errstr(err));
1395 goto error;
1396 }
1397 /* wait with power off for a while */
1399
1400#if USB_HAVE_DISABLE_ENUM
1401 /* Add device sysctls */
1402
1403 sysctl_ctx = device_get_sysctl_ctx(dev);
1404 sysctl_tree = device_get_sysctl_tree(dev);
1405
1406 if (sysctl_ctx != NULL && sysctl_tree != NULL) {
1407 (void) SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
1408 OID_AUTO, "disable_enumeration", CTLFLAG_RWTUN,
1409 &sc->sc_disable_enumeration, 0,
1410 "Set to disable enumeration on this USB HUB.");
1411
1412 (void) SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
1413 OID_AUTO, "disable_port_power", CTLFLAG_RWTUN,
1414 &sc->sc_disable_port_power, 0,
1415 "Set to disable USB port power on this USB HUB.");
1416 }
1417#endif
1418 /*
1419 * To have the best chance of success we do things in the exact same
1420 * order as Windoze98. This should not be necessary, but some
1421 * devices do not follow the USB specs to the letter.
1422 *
1423 * These are the events on the bus when a hub is attached:
1424 * Get device and config descriptors (see attach code)
1425 * Get hub descriptor (see above)
1426 * For all ports
1427 * turn on power
1428 * wait for power to become stable
1429 * (all below happens in explore code)
1430 * For all ports
1431 * clear C_PORT_CONNECTION
1432 * For all ports
1433 * get port status
1434 * if device connected
1435 * wait 100 ms
1436 * turn on reset
1437 * wait
1438 * clear C_PORT_RESET
1439 * get port status
1440 * proceed with device attachment
1441 */
1442
1443 /* XXX should check for none, individual, or ganged power? */
1444
1445 removable = 0;
1446
1447 for (x = 0; x != nports; x++) {
1448 /* set up data structures */
1449 struct usb_port *up = hub->ports + x;
1450
1451 up->device_index = 0;
1452 up->restartcnt = 0;
1453 portno = x + 1;
1454
1455 /* check if port is removable */
1456 switch (udev->speed) {
1457 case USB_SPEED_LOW:
1458 case USB_SPEED_FULL:
1459 case USB_SPEED_HIGH:
1460 if (!UHD_NOT_REMOV(&hubdesc20, portno))
1461 removable++;
1462 break;
1463 case USB_SPEED_SUPER:
1464 if (!UHD_NOT_REMOV(&hubdesc30, portno))
1465 removable++;
1466 break;
1467 default:
1468 DPRINTF("Assuming removable port\n");
1469 removable++;
1470 break;
1471 }
1472 if (err == 0) {
1473#if USB_HAVE_DISABLE_ENUM
1474 /* check if we should disable USB port power or not */
1475 if (usb_disable_port_power != 0 ||
1476 sc->sc_disable_port_power != 0) {
1477 /* turn the power off */
1478 DPRINTFN(2, "Turning port %d power off\n", portno);
1479 err = usbd_req_clear_port_feature(udev, NULL,
1480 portno, UHF_PORT_POWER);
1481 } else {
1482#endif
1483 /* turn the power on */
1484 DPRINTFN(2, "Turning port %d power on\n", portno);
1485 err = usbd_req_set_port_feature(udev, NULL,
1486 portno, UHF_PORT_POWER);
1487#if USB_HAVE_DISABLE_ENUM
1488 }
1489#endif
1490 }
1491 if (err != 0) {
1492 DPRINTFN(0, "port %d power on or off failed, %s\n",
1493 portno, usbd_errstr(err));
1494 }
1495 DPRINTF("turn on port %d power\n",
1496 portno);
1497
1498 /* wait for stable power */
1499 usb_pause_mtx(NULL, USB_MS_TO_TICKS(pwrdly));
1500 }
1501
1502 device_printf(dev, "%d port%s with %d "
1503 "removable, %s powered\n", nports, (nports != 1) ? "s" : "",
1504 removable, udev->flags.self_powered ? "self" : "bus");
1505
1506 /* Start the interrupt endpoint, if any */
1507
1508 USB_MTX_LOCK(&sc->sc_mtx);
1510 USB_MTX_UNLOCK(&sc->sc_mtx);
1511
1512 /* Enable automatic power save on all USB HUBs */
1513
1515
1516 return (0);
1517
1518error:
1520
1521#if (USB_HAVE_FIXED_PORT == 0)
1522 free(udev->hub, M_USBDEV);
1523#endif
1524 udev->hub = NULL;
1525
1526 mtx_destroy(&sc->sc_mtx);
1527
1528 return (ENXIO);
1529}
1530
1531/*
1532 * Called from process context when the hub is gone.
1533 * Detach all devices on active ports.
1534 */
1535int
1536uhub_detach(device_t dev)
1537{
1538 struct uhub_softc *sc = device_get_softc(dev);
1539 struct usb_hub *hub = sc->sc_udev->hub;
1540 struct usb_bus *bus = sc->sc_udev->bus;
1541 struct usb_device *child;
1542 uint8_t x;
1543
1544 if (hub == NULL) /* must be partially working */
1545 return (0);
1546
1547 /* Make sure interrupt transfer is gone. */
1549
1550 /* Detach all ports */
1551 for (x = 0; x != hub->nports; x++) {
1553
1554 if (child == NULL) {
1555 continue;
1556 }
1557
1558 /*
1559 * Free USB device and all subdevices, if any.
1560 */
1562 }
1563
1564#if USB_HAVE_TT_SUPPORT
1565 /* Make sure our TT messages are not queued anywhere */
1568 &hub->tt_msg[0], &hub->tt_msg[1]);
1570#endif
1571
1572#if (USB_HAVE_FIXED_PORT == 0)
1573 free(hub, M_USBDEV);
1574#endif
1575 sc->sc_udev->hub = NULL;
1576
1577 mtx_destroy(&sc->sc_mtx);
1578
1579 return (0);
1580}
1581
1582static int
1583uhub_suspend(device_t dev)
1584{
1585 DPRINTF("\n");
1586 /* Sub-devices are not suspended here! */
1587 return (0);
1588}
1589
1590static int
1591uhub_resume(device_t dev)
1592{
1593 DPRINTF("\n");
1594 /* Sub-devices are not resumed here! */
1595 return (0);
1596}
1597
1598static void
1599uhub_driver_added(device_t dev, driver_t *driver)
1600{
1602}
1603
1604void
1605uhub_find_iface_index(struct usb_hub *hub, device_t child,
1606 struct hub_result *res)
1607{
1608 struct usb_interface *iface;
1609 struct usb_device *udev;
1610 uint8_t nports;
1611 uint8_t x;
1612 uint8_t i;
1613
1614 nports = hub->nports;
1615 for (x = 0; x != nports; x++) {
1617 hub->ports + x);
1618 if (!udev) {
1619 continue;
1620 }
1621 for (i = 0; i != USB_IFACE_MAX; i++) {
1622 iface = usbd_get_iface(udev, i);
1623 if (iface &&
1624 (iface->subdev == child)) {
1625 res->iface_index = i;
1626 res->udev = udev;
1627 res->portno = x + 1;
1628 return;
1629 }
1630 }
1631 }
1632 res->iface_index = 0;
1633 res->udev = NULL;
1634 res->portno = 0;
1635}
1636
1637int
1638uhub_child_location(device_t parent, device_t child, struct sbuf *sb)
1639{
1640 struct uhub_softc *sc;
1641 struct usb_hub *hub;
1642 struct hub_result res;
1643
1644 if (!device_is_attached(parent))
1645 return (0);
1646
1647 sc = device_get_softc(parent);
1648 hub = sc->sc_udev->hub;
1649
1650 bus_topo_lock();
1651 uhub_find_iface_index(hub, child, &res);
1652 if (!res.udev) {
1653 DPRINTF("device not on hub\n");
1654 goto done;
1655 }
1656 sbuf_printf(sb, "bus=%u hubaddr=%u port=%u devaddr=%u"
1657 " interface=%u"
1658#if USB_HAVE_UGEN
1659 " ugen=%s"
1660#endif
1661 , device_get_unit(res.udev->bus->bdev)
1662 , (res.udev->parent_hub != NULL) ?
1663 res.udev->parent_hub->device_index : 0
1664 , res.portno, res.udev->device_index, res.iface_index
1665#if USB_HAVE_UGEN
1666 , res.udev->ugen_name
1667#endif
1668 );
1669done:
1670 bus_topo_unlock();
1671
1672 return (0);
1673}
1674
1675int
1676uhub_get_device_path(device_t bus, device_t child, const char *locator,
1677 struct sbuf *sb)
1678{
1679 struct uhub_softc *sc;
1680 struct usb_hub *hub;
1681 struct hub_result res;
1682 int rv;
1683
1684 if (strcmp(locator, BUS_LOCATOR_UEFI) == 0) {
1685 rv = bus_generic_get_device_path(device_get_parent(bus), bus, locator, sb);
1686 if (rv != 0)
1687 return (rv);
1688
1689 sc = device_get_softc(bus);
1690 hub = sc->sc_udev->hub;
1691
1692 bus_topo_lock();
1693 uhub_find_iface_index(hub, child, &res);
1694 if (!res.udev) {
1695 printf("device not on hub\n");
1696 goto done;
1697 }
1698 sbuf_printf(sb, "/USB(0x%x,0x%x)", res.portno - 1, res.iface_index);
1699 done:
1700 bus_topo_unlock();
1701 return (0);
1702 }
1703
1704 /* For the rest, punt to the default handler */
1705 return (bus_generic_get_device_path(bus, child, locator, sb));
1706}
1707
1708static int
1709uhub_child_pnpinfo(device_t parent, device_t child, struct sbuf*sb)
1710{
1711 struct uhub_softc *sc;
1712 struct usb_hub *hub;
1713 struct usb_interface *iface;
1714 struct hub_result res;
1715 uint8_t do_unlock;
1716
1717 if (!device_is_attached(parent))
1718 return (0);
1719
1720 sc = device_get_softc(parent);
1721 hub = sc->sc_udev->hub;
1722
1723 bus_topo_lock();
1724 uhub_find_iface_index(hub, child, &res);
1725 if (!res.udev) {
1726 DPRINTF("device not on hub\n");
1727 goto done;
1728 }
1729 iface = usbd_get_iface(res.udev, res.iface_index);
1730 if (iface && iface->idesc) {
1731 /* Make sure device information is not changed during the print. */
1732 do_unlock = usbd_ctrl_lock(res.udev);
1733
1734 sbuf_printf(sb, "vendor=0x%04x product=0x%04x "
1735 "devclass=0x%02x devsubclass=0x%02x "
1736 "devproto=0x%02x "
1737 "sernum=\"%s\" "
1738 "release=0x%04x "
1739 "mode=%s "
1740 "intclass=0x%02x intsubclass=0x%02x "
1741 "intprotocol=0x%02x" "%s%s",
1742 UGETW(res.udev->ddesc.idVendor),
1743 UGETW(res.udev->ddesc.idProduct),
1744 res.udev->ddesc.bDeviceClass,
1747 usb_get_serial(res.udev),
1748 UGETW(res.udev->ddesc.bcdDevice),
1749 (res.udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device",
1750 iface->idesc->bInterfaceClass,
1751 iface->idesc->bInterfaceSubClass,
1752 iface->idesc->bInterfaceProtocol,
1753 iface->pnpinfo ? " " : "",
1754 iface->pnpinfo ? iface->pnpinfo : "");
1755
1756 if (do_unlock)
1758 }
1759done:
1760 bus_topo_unlock();
1761
1762 return (0);
1763}
1764
1765/*
1766 * The USB Transaction Translator:
1767 * ===============================
1768 *
1769 * When doing LOW- and FULL-speed USB transfers across a HIGH-speed
1770 * USB HUB, bandwidth must be allocated for ISOCHRONOUS and INTERRUPT
1771 * USB transfers. To utilize bandwidth dynamically the "scatter and
1772 * gather" principle must be applied. This means that bandwidth must
1773 * be divided into equal parts of bandwidth. With regard to USB all
1774 * data is transferred in smaller packets with length
1775 * "wMaxPacketSize". The problem however is that "wMaxPacketSize" is
1776 * not a constant!
1777 *
1778 * The bandwidth scheduler which I have implemented will simply pack
1779 * the USB transfers back to back until there is no more space in the
1780 * schedule. Out of the 8 microframes which the USB 2.0 standard
1781 * provides, only 6 are available for non-HIGH-speed devices. I have
1782 * reserved the first 4 microframes for ISOCHRONOUS transfers. The
1783 * last 2 microframes I have reserved for INTERRUPT transfers. Without
1784 * this division, it is very difficult to allocate and free bandwidth
1785 * dynamically.
1786 *
1787 * NOTE about the Transaction Translator in USB HUBs:
1788 *
1789 * USB HUBs have a very simple Transaction Translator, that will
1790 * simply pipeline all the SPLIT transactions. That means that the
1791 * transactions will be executed in the order they are queued!
1792 *
1793 */
1794
1795/*------------------------------------------------------------------------*
1796 * usb_intr_find_best_slot
1797 *
1798 * Return value:
1799 * The best Transaction Translation slot for an interrupt endpoint.
1800 *------------------------------------------------------------------------*/
1801static uint8_t
1803 uint8_t end, uint8_t mask)
1804{
1805 usb_size_t min = (usb_size_t)-1;
1806 usb_size_t sum;
1807 uint8_t x;
1808 uint8_t y;
1809 uint8_t z;
1810
1811 y = 0;
1812
1813 /* find the last slot with lesser used bandwidth */
1814
1815 for (x = start; x < end; x++) {
1816 sum = 0;
1817
1818 /* compute sum of bandwidth */
1819 for (z = x; z < end; z++) {
1820 if (mask & (1U << (z - x)))
1821 sum += ptr[z];
1822 }
1823
1824 /* check if the current multi-slot is more optimal */
1825 if (min >= sum) {
1826 min = sum;
1827 y = x;
1828 }
1829
1830 /* check if the mask is about to be shifted out */
1831 if (mask & (1U << (end - 1 - x)))
1832 break;
1833 }
1834 return (y);
1835}
1836
1837/*------------------------------------------------------------------------*
1838 * usb_hs_bandwidth_adjust
1839 *
1840 * This function will update the bandwidth usage for the microframe
1841 * having index "slot" by "len" bytes. "len" can be negative. If the
1842 * "slot" argument is greater or equal to "USB_HS_MICRO_FRAMES_MAX"
1843 * the "slot" argument will be replaced by the slot having least used
1844 * bandwidth. The "mask" argument is used for multi-slot allocations.
1845 *
1846 * Returns:
1847 * The slot in which the bandwidth update was done: 0..7
1848 *------------------------------------------------------------------------*/
1849static uint8_t
1851 uint8_t slot, uint8_t mask)
1852{
1853 struct usb_bus *bus = udev->bus;
1854 struct usb_hub *hub;
1855 enum usb_dev_speed speed;
1856 uint8_t x;
1857
1858 USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
1859
1860 speed = usbd_get_speed(udev);
1861
1862 switch (speed) {
1863 case USB_SPEED_LOW:
1864 case USB_SPEED_FULL:
1865 if (speed == USB_SPEED_LOW) {
1866 len *= 8;
1867 }
1868 /*
1869 * The Host Controller Driver should have
1870 * performed checks so that the lookup
1871 * below does not result in a NULL pointer
1872 * access.
1873 */
1874
1875 hub = udev->parent_hs_hub->hub;
1878 USB_FS_ISOC_UFRAME_MAX, 6, mask);
1879 }
1880 for (x = slot; x < 8; x++) {
1881 if (mask & (1U << (x - slot))) {
1882 hub->uframe_usage[x] += len;
1883 bus->uframe_usage[x] += len;
1884 }
1885 }
1886 break;
1887 default:
1889 slot = usb_intr_find_best_slot(bus->uframe_usage, 0,
1891 }
1892 for (x = slot; x < 8; x++) {
1893 if (mask & (1U << (x - slot))) {
1894 bus->uframe_usage[x] += len;
1895 }
1896 }
1897 break;
1898 }
1899 return (slot);
1900}
1901
1902/*------------------------------------------------------------------------*
1903 * usb_hs_bandwidth_alloc
1904 *
1905 * This function is a wrapper function for "usb_hs_bandwidth_adjust()".
1906 *------------------------------------------------------------------------*/
1907void
1909{
1910 struct usb_device *udev;
1911 uint8_t slot;
1912 uint8_t mask;
1913 uint8_t speed;
1914
1915 udev = xfer->xroot->udev;
1916
1917 if (udev->flags.usb_mode != USB_MODE_HOST)
1918 return; /* not supported */
1919
1920 xfer->endpoint->refcount_bw++;
1921 if (xfer->endpoint->refcount_bw != 1)
1922 return; /* already allocated */
1923
1924 speed = usbd_get_speed(udev);
1925
1926 switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
1927 case UE_INTERRUPT:
1928 /* allocate a microframe slot */
1929
1930 mask = 0x01;
1933
1934 xfer->endpoint->usb_uframe = slot;
1935 xfer->endpoint->usb_smask = mask << slot;
1936
1937 if ((speed != USB_SPEED_FULL) &&
1938 (speed != USB_SPEED_LOW)) {
1939 xfer->endpoint->usb_cmask = 0x00 ;
1940 } else {
1941 xfer->endpoint->usb_cmask = (-(0x04 << slot)) & 0xFE;
1942 }
1943 break;
1944
1945 case UE_ISOCHRONOUS:
1946 switch (usbd_xfer_get_fps_shift(xfer)) {
1947 case 0:
1948 mask = 0xFF;
1949 break;
1950 case 1:
1951 mask = 0x55;
1952 break;
1953 case 2:
1954 mask = 0x11;
1955 break;
1956 default:
1957 mask = 0x01;
1958 break;
1959 }
1960
1961 /* allocate a microframe multi-slot */
1962
1965
1966 xfer->endpoint->usb_uframe = slot;
1967 xfer->endpoint->usb_cmask = 0;
1968 xfer->endpoint->usb_smask = mask << slot;
1969 break;
1970
1971 default:
1972 xfer->endpoint->usb_uframe = 0;
1973 xfer->endpoint->usb_cmask = 0;
1974 xfer->endpoint->usb_smask = 0;
1975 break;
1976 }
1977
1978 DPRINTFN(11, "slot=%d, mask=0x%02x\n",
1979 xfer->endpoint->usb_uframe,
1980 xfer->endpoint->usb_smask >> xfer->endpoint->usb_uframe);
1981}
1982
1983/*------------------------------------------------------------------------*
1984 * usb_hs_bandwidth_free
1985 *
1986 * This function is a wrapper function for "usb_hs_bandwidth_adjust()".
1987 *------------------------------------------------------------------------*/
1988void
1990{
1991 struct usb_device *udev;
1992 uint8_t slot;
1993 uint8_t mask;
1994
1995 udev = xfer->xroot->udev;
1996
1997 if (udev->flags.usb_mode != USB_MODE_HOST)
1998 return; /* not supported */
1999
2000 xfer->endpoint->refcount_bw--;
2001 if (xfer->endpoint->refcount_bw != 0)
2002 return; /* still allocated */
2003
2004 switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
2005 case UE_INTERRUPT:
2006 case UE_ISOCHRONOUS:
2007
2008 slot = xfer->endpoint->usb_uframe;
2009 mask = xfer->endpoint->usb_smask;
2010
2011 /* free microframe slot(s): */
2013 -xfer->max_frame_size, slot, mask >> slot);
2014
2015 DPRINTFN(11, "slot=%d, mask=0x%02x\n",
2016 slot, mask >> slot);
2017
2018 xfer->endpoint->usb_uframe = 0;
2019 xfer->endpoint->usb_cmask = 0;
2020 xfer->endpoint->usb_smask = 0;
2021 break;
2022
2023 default:
2024 break;
2025 }
2026}
2027
2028/*------------------------------------------------------------------------*
2029 * usb_isoc_time_expand
2030 *
2031 * This function will expand the time counter from 7-bit to 16-bit.
2032 *
2033 * Returns:
2034 * 16-bit isochronous time counter.
2035 *------------------------------------------------------------------------*/
2036uint16_t
2037usb_isoc_time_expand(struct usb_bus *bus, uint16_t isoc_time_curr)
2038{
2039 uint16_t rem;
2040
2041 USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
2042
2043 rem = bus->isoc_time_last & (USB_ISOC_TIME_MAX - 1);
2044
2045 isoc_time_curr &= (USB_ISOC_TIME_MAX - 1);
2046
2047 if (isoc_time_curr < rem) {
2048 /* the time counter wrapped around */
2050 }
2051 /* update the remainder */
2052
2054 bus->isoc_time_last |= isoc_time_curr;
2055
2056 return (bus->isoc_time_last);
2057}
2058
2059/*------------------------------------------------------------------------*
2060 * usbd_fs_isoc_schedule_alloc_slot
2061 *
2062 * This function will allocate bandwidth for an isochronous FULL speed
2063 * transaction in the FULL speed schedule.
2064 *
2065 * Returns:
2066 * <8: Success
2067 * Else: Error
2068 *------------------------------------------------------------------------*/
2069#if USB_HAVE_TT_SUPPORT
2070uint8_t
2071usbd_fs_isoc_schedule_alloc_slot(struct usb_xfer *isoc_xfer, uint16_t isoc_time)
2072{
2073 struct usb_xfer *xfer;
2074 struct usb_xfer *pipe_xfer;
2075 struct usb_bus *bus;
2077 usb_frlength_t data_len;
2078 uint16_t delta;
2079 uint16_t slot;
2080 uint8_t retval;
2081
2082 data_len = 0;
2083 slot = 0;
2084
2085 bus = isoc_xfer->xroot->bus;
2086
2087 TAILQ_FOREACH(xfer, &bus->intr_q.head, wait_entry) {
2088 /* skip self, if any */
2089
2090 if (xfer == isoc_xfer)
2091 continue;
2092
2093 /* check if this USB transfer is going through the same TT */
2094
2095 if (xfer->xroot->udev->parent_hs_hub !=
2096 isoc_xfer->xroot->udev->parent_hs_hub) {
2097 continue;
2098 }
2099 if ((isoc_xfer->xroot->udev->parent_hs_hub->
2100 ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) &&
2101 (xfer->xroot->udev->hs_port_no !=
2102 isoc_xfer->xroot->udev->hs_port_no)) {
2103 continue;
2104 }
2105 if (xfer->endpoint->methods != isoc_xfer->endpoint->methods)
2106 continue;
2107
2108 /* check if isoc_time is part of this transfer */
2109
2110 delta = xfer->isoc_time_complete - isoc_time;
2111 if (delta > 0 && delta <= xfer->nframes) {
2112 delta = xfer->nframes - delta;
2113
2114 len = xfer->frlengths[delta];
2115 len += 8;
2116 len *= 7;
2117 len /= 6;
2118
2119 data_len += len;
2120 }
2121
2122 /*
2123 * Check double buffered transfers. Only stream ID
2124 * equal to zero is valid here!
2125 */
2126 TAILQ_FOREACH(pipe_xfer, &xfer->endpoint->endpoint_q[0].head,
2127 wait_entry) {
2128 /* skip self, if any */
2129
2130 if (pipe_xfer == isoc_xfer)
2131 continue;
2132
2133 /* check if isoc_time is part of this transfer */
2134
2135 delta = pipe_xfer->isoc_time_complete - isoc_time;
2136 if (delta > 0 && delta <= pipe_xfer->nframes) {
2137 delta = pipe_xfer->nframes - delta;
2138
2139 len = pipe_xfer->frlengths[delta];
2140 len += 8;
2141 len *= 7;
2142 len /= 6;
2143
2144 data_len += len;
2145 }
2146 }
2147 }
2148
2149 while (data_len >= USB_FS_BYTES_PER_HS_UFRAME) {
2150 data_len -= USB_FS_BYTES_PER_HS_UFRAME;
2151 slot++;
2152 }
2153
2154 /* check for overflow */
2155
2156 if (slot >= USB_FS_ISOC_UFRAME_MAX)
2157 return (255);
2158
2159 retval = slot;
2160
2161 delta = isoc_xfer->isoc_time_complete - isoc_time;
2162 if (delta > 0 && delta <= isoc_xfer->nframes) {
2163 delta = isoc_xfer->nframes - delta;
2164
2165 len = isoc_xfer->frlengths[delta];
2166 len += 8;
2167 len *= 7;
2168 len /= 6;
2169
2170 data_len += len;
2171 }
2172
2173 while (data_len >= USB_FS_BYTES_PER_HS_UFRAME) {
2174 data_len -= USB_FS_BYTES_PER_HS_UFRAME;
2175 slot++;
2176 }
2177
2178 /* check for overflow */
2179
2180 if (slot >= USB_FS_ISOC_UFRAME_MAX)
2181 return (255);
2182
2183 return (retval);
2184}
2185#endif
2186
2187/*------------------------------------------------------------------------*
2188 * usb_bus_port_get_device
2189 *
2190 * This function is NULL safe.
2191 *------------------------------------------------------------------------*/
2192struct usb_device *
2194{
2195 if ((bus == NULL) || (up == NULL)) {
2196 /* be NULL safe */
2197 return (NULL);
2198 }
2199 if (up->device_index == 0) {
2200 /* nothing to do */
2201 return (NULL);
2202 }
2203 return (bus->devices[up->device_index]);
2204}
2205
2206/*------------------------------------------------------------------------*
2207 * usb_bus_port_set_device
2208 *
2209 * This function is NULL safe.
2210 *------------------------------------------------------------------------*/
2211void
2213 struct usb_device *udev, uint8_t device_index)
2214{
2215 if (bus == NULL) {
2216 /* be NULL safe */
2217 return;
2218 }
2219 /*
2220 * There is only one case where we don't
2221 * have an USB port, and that is the Root Hub!
2222 */
2223 if (up) {
2224 if (udev) {
2226 } else {
2228 up->device_index = 0;
2229 }
2230 }
2231 /*
2232 * Make relationships to our new device
2233 */
2234 if (device_index != 0) {
2235#if USB_HAVE_UGEN
2236 mtx_lock(&usb_ref_lock);
2237#endif
2238 bus->devices[device_index] = udev;
2239#if USB_HAVE_UGEN
2240 mtx_unlock(&usb_ref_lock);
2241#endif
2242 }
2243 /*
2244 * Debug print
2245 */
2246 DPRINTFN(2, "bus %p devices[%u] = %p\n", bus, device_index, udev);
2247}
2248
2249/*------------------------------------------------------------------------*
2250 * usb_needs_explore
2251 *
2252 * This functions is called when the USB event thread needs to run.
2253 *------------------------------------------------------------------------*/
2254void
2255usb_needs_explore(struct usb_bus *bus, uint8_t do_probe)
2256{
2257 uint8_t do_unlock;
2258
2259 DPRINTF("\n");
2260
2261 if (cold != 0) {
2262 DPRINTF("Cold\n");
2263 return;
2264 }
2265
2266 if (bus == NULL) {
2267 DPRINTF("No bus pointer!\n");
2268 return;
2269 }
2270 if ((bus->devices == NULL) ||
2271 (bus->devices[USB_ROOT_HUB_ADDR] == NULL)) {
2272 DPRINTF("No root HUB\n");
2273 return;
2274 }
2275 if (mtx_owned(&bus->bus_mtx)) {
2276 do_unlock = 0;
2277 } else {
2279 do_unlock = 1;
2280 }
2281 if (do_probe) {
2282 bus->do_probe = 1;
2283 }
2284 if (usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
2285 &bus->explore_msg[0], &bus->explore_msg[1])) {
2286 /* ignore */
2287 }
2288 if (do_unlock) {
2290 }
2291}
2292
2293/*------------------------------------------------------------------------*
2294 * usb_needs_explore_all
2295 *
2296 * This function is called whenever a new driver is loaded and will
2297 * cause that all USB buses are re-explored.
2298 *------------------------------------------------------------------------*/
2299void
2301{
2302 struct usb_bus *bus;
2303 devclass_t dc;
2304 device_t dev;
2305 int max;
2306
2307 DPRINTFN(3, "\n");
2308
2309 dc = usb_devclass_ptr;
2310 if (dc == NULL) {
2311 DPRINTFN(0, "no devclass\n");
2312 return;
2313 }
2314 /*
2315 * Explore all USB buses in parallel.
2316 */
2317 max = devclass_get_maxunit(dc);
2318 while (max >= 0) {
2319 dev = devclass_get_device(dc, max);
2320 if (dev) {
2321 bus = device_get_softc(dev);
2322 if (bus) {
2324 }
2325 }
2326 max--;
2327 }
2328}
2329
2330/*------------------------------------------------------------------------*
2331 * usb_needs_explore_init
2332 *
2333 * This function will ensure that the USB controllers are not enumerated
2334 * until the "cold" variable is cleared.
2335 *------------------------------------------------------------------------*/
2336static void
2338{
2339 /*
2340 * The cold variable should be cleared prior to this function
2341 * being called:
2342 */
2343 if (cold == 0)
2345 else
2346 DPRINTFN(-1, "Cold variable is still set!\n");
2347}
2348SYSINIT(usb_needs_explore_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_SECOND, usb_needs_explore_init, NULL);
2349
2350/*------------------------------------------------------------------------*
2351 * usb_bus_power_update
2352 *
2353 * This function will ensure that all USB devices on the given bus are
2354 * properly suspended or resumed according to the device transfer
2355 * state.
2356 *------------------------------------------------------------------------*/
2357#if USB_HAVE_POWERD
2358void
2359usb_bus_power_update(struct usb_bus *bus)
2360{
2361 usb_needs_explore(bus, 0 /* no probe */ );
2362}
2363#endif
2364
2365/*------------------------------------------------------------------------*
2366 * usbd_transfer_power_ref
2367 *
2368 * This function will modify the power save reference counts and
2369 * wakeup the USB device associated with the given USB transfer, if
2370 * needed.
2371 *------------------------------------------------------------------------*/
2372#if USB_HAVE_POWERD
2373void
2374usbd_transfer_power_ref(struct usb_xfer *xfer, int val)
2375{
2376 static const usb_power_mask_t power_mask[4] = {
2381 };
2382 struct usb_device *udev;
2383 uint8_t needs_explore;
2384 uint8_t needs_hw_power;
2385 uint8_t xfer_type;
2386
2387 udev = xfer->xroot->udev;
2388
2389 if (udev->device_index == USB_ROOT_HUB_ADDR) {
2390 /* no power save for root HUB */
2391 return;
2392 }
2393 USB_BUS_LOCK(udev->bus);
2394
2395 xfer_type = xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE;
2396
2397 udev->pwr_save.last_xfer_time = ticks;
2398 udev->pwr_save.type_refs[xfer_type] += val;
2399
2400 if (xfer->flags_int.control_xfr) {
2401 udev->pwr_save.read_refs += val;
2402 if (xfer->flags_int.usb_mode == USB_MODE_HOST) {
2403 /*
2404 * It is not allowed to suspend during a
2405 * control transfer:
2406 */
2407 udev->pwr_save.write_refs += val;
2408 }
2409 } else if (USB_GET_DATA_ISREAD(xfer)) {
2410 udev->pwr_save.read_refs += val;
2411 } else {
2412 udev->pwr_save.write_refs += val;
2413 }
2414
2415 if (val > 0) {
2416 if (udev->flags.self_suspended)
2417 needs_explore = usb_peer_should_wakeup(udev);
2418 else
2419 needs_explore = 0;
2420
2421 if (!(udev->bus->hw_power_state & power_mask[xfer_type])) {
2422 DPRINTF("Adding type %u to power state\n", xfer_type);
2423 udev->bus->hw_power_state |= power_mask[xfer_type];
2424 needs_hw_power = 1;
2425 } else {
2426 needs_hw_power = 0;
2427 }
2428 } else {
2429 needs_explore = 0;
2430 needs_hw_power = 0;
2431 }
2432
2433 USB_BUS_UNLOCK(udev->bus);
2434
2435 if (needs_explore) {
2436 DPRINTF("update\n");
2438 } else if (needs_hw_power) {
2439 DPRINTF("needs power\n");
2440 if (udev->bus->methods->set_hw_power != NULL) {
2441 (udev->bus->methods->set_hw_power) (udev->bus);
2442 }
2443 }
2444}
2445#endif
2446
2447/*------------------------------------------------------------------------*
2448 * usb_peer_should_wakeup
2449 *
2450 * This function returns non-zero if the current device should wake up.
2451 *------------------------------------------------------------------------*/
2452static uint8_t
2454{
2455 return (((udev->power_mode == USB_POWER_MODE_ON) &&
2456 (udev->flags.usb_mode == USB_MODE_HOST)) ||
2459 (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0) ||
2460 (udev->pwr_save.write_refs != 0) ||
2461 ((udev->pwr_save.read_refs != 0) &&
2462 (udev->flags.usb_mode == USB_MODE_HOST) &&
2463 (usb_peer_can_wakeup(udev) == 0)));
2464}
2465
2466/*------------------------------------------------------------------------*
2467 * usb_bus_powerd
2468 *
2469 * This function implements the USB power daemon and is called
2470 * regularly from the USB explore thread.
2471 *------------------------------------------------------------------------*/
2472#if USB_HAVE_POWERD
2473void
2474usb_bus_powerd(struct usb_bus *bus)
2475{
2476 struct usb_device *udev;
2477 usb_ticks_t temp;
2478 usb_ticks_t limit;
2479 usb_ticks_t mintime;
2480 usb_size_t type_refs[5];
2481 uint8_t x;
2482
2483 limit = usb_power_timeout;
2484 if (limit == 0)
2485 limit = hz;
2486 else if (limit > 255)
2487 limit = 255 * hz;
2488 else
2489 limit = limit * hz;
2490
2491 DPRINTF("bus=%p\n", bus);
2492
2494
2495 /*
2496 * The root HUB device is never suspended
2497 * and we simply skip it.
2498 */
2499 for (x = USB_ROOT_HUB_ADDR + 1;
2500 x != bus->devices_max; x++) {
2501 udev = bus->devices[x];
2502 if (udev == NULL)
2503 continue;
2504
2505 temp = ticks - udev->pwr_save.last_xfer_time;
2506
2507 if (usb_peer_should_wakeup(udev)) {
2508 /* check if we are suspended */
2509 if (udev->flags.self_suspended != 0) {
2511 usb_dev_resume_peer(udev);
2513 }
2514 } else if ((temp >= limit) &&
2515 (udev->flags.usb_mode == USB_MODE_HOST) &&
2516 (udev->flags.self_suspended == 0)) {
2517 /* try to do suspend */
2518
2522 }
2523 }
2524
2525 /* reset counters */
2526
2527 mintime = (usb_ticks_t)-1;
2528 type_refs[0] = 0;
2529 type_refs[1] = 0;
2530 type_refs[2] = 0;
2531 type_refs[3] = 0;
2532 type_refs[4] = 0;
2533
2534 /* Re-loop all the devices to get the actual state */
2535
2536 for (x = USB_ROOT_HUB_ADDR + 1;
2537 x != bus->devices_max; x++) {
2538 udev = bus->devices[x];
2539 if (udev == NULL)
2540 continue;
2541
2542 /* we found a non-Root-Hub USB device */
2543 type_refs[4] += 1;
2544
2545 /* "last_xfer_time" can be updated by a resume */
2546 temp = ticks - udev->pwr_save.last_xfer_time;
2547
2548 /*
2549 * Compute minimum time since last transfer for the complete
2550 * bus:
2551 */
2552 if (temp < mintime)
2553 mintime = temp;
2554
2555 if (udev->flags.self_suspended == 0) {
2556 type_refs[0] += udev->pwr_save.type_refs[0];
2557 type_refs[1] += udev->pwr_save.type_refs[1];
2558 type_refs[2] += udev->pwr_save.type_refs[2];
2559 type_refs[3] += udev->pwr_save.type_refs[3];
2560 }
2561 }
2562
2563 if (mintime >= (usb_ticks_t)(1 * hz)) {
2564 /* recompute power masks */
2565 DPRINTF("Recomputing power masks\n");
2566 bus->hw_power_state = 0;
2567 if (type_refs[UE_CONTROL] != 0)
2569 if (type_refs[UE_BULK] != 0)
2571 if (type_refs[UE_INTERRUPT] != 0)
2573 if (type_refs[UE_ISOCHRONOUS] != 0)
2575 if (type_refs[4] != 0)
2577 }
2579
2580 if (bus->methods->set_hw_power != NULL) {
2581 /* always update hardware power! */
2583 }
2584 return;
2585}
2586#endif
2587
2588static usb_error_t
2589usbd_device_30_remote_wakeup(struct usb_device *udev, uint8_t bRequest)
2590{
2591 struct usb_device_request req = {};
2592
2593 req.bmRequestType = UT_WRITE_INTERFACE;
2594 req.bRequest = bRequest;
2598
2599 return (usbd_do_request(udev, NULL, &req, 0));
2600}
2601
2602static usb_error_t
2604{
2605 usb_error_t err;
2606
2607 if (usb_device_20_compatible(udev)) {
2610 } else {
2613 }
2614 return (err);
2615}
2616
2617static usb_error_t
2619{
2620 usb_error_t err;
2621
2622 if (usb_device_20_compatible(udev)) {
2623 err = usbd_req_set_device_feature(udev,
2625 } else {
2628 }
2629 return (err);
2630}
2631
2632/*------------------------------------------------------------------------*
2633 * usb_dev_resume_peer
2634 *
2635 * This function will resume an USB peer and do the required USB
2636 * signalling to get an USB device out of the suspended state.
2637 *------------------------------------------------------------------------*/
2638static void
2640{
2641 struct usb_bus *bus;
2642 int err;
2643
2644 /* be NULL safe */
2645 if (udev == NULL)
2646 return;
2647
2648 /* check if already resumed */
2649 if (udev->flags.self_suspended == 0)
2650 return;
2651
2652 /* we need a parent HUB to do resume */
2653 if (udev->parent_hub == NULL)
2654 return;
2655
2656 DPRINTF("udev=%p\n", udev);
2657
2658 if ((udev->flags.usb_mode == USB_MODE_DEVICE) &&
2659 (udev->flags.remote_wakeup == 0)) {
2660 /*
2661 * If the host did not set the remote wakeup feature, we can
2662 * not wake it up either!
2663 */
2664 DPRINTF("remote wakeup is not set!\n");
2665 return;
2666 }
2667 /* get bus pointer */
2668 bus = udev->bus;
2669
2670 /* resume parent hub first */
2672
2673 /* reduce chance of instant resume failure by waiting a little bit */
2674 usb_pause_mtx(NULL, USB_MS_TO_TICKS(20));
2675
2676 if (usb_device_20_compatible(udev)) {
2677 /* resume current port (Valid in Host and Device Mode) */
2679 NULL, udev->port_no, UHF_PORT_SUSPEND);
2680 } else {
2681 /* resume current port (Valid in Host and Device Mode) */
2683 NULL, udev->port_no, UPS_PORT_LS_U0);
2684 }
2685
2686 if (err != 0) {
2687 DPRINTFN(0, "Resuming port failed: %s (ignored)\n",
2688 usbd_errstr(err));
2689 }
2690
2691 /* resume settle time */
2693
2694 if (bus->methods->device_resume != NULL) {
2695 /* resume USB device on the USB controller */
2696 (bus->methods->device_resume) (udev);
2697 }
2699 /* set that this device is now resumed */
2700 udev->flags.self_suspended = 0;
2701#if USB_HAVE_POWERD
2702 /* make sure that we don't go into suspend right away */
2703 udev->pwr_save.last_xfer_time = ticks;
2704
2705 /* make sure the needed power masks are on */
2706 if (udev->pwr_save.type_refs[UE_CONTROL] != 0)
2707 bus->hw_power_state |= USB_HW_POWER_CONTROL;
2708 if (udev->pwr_save.type_refs[UE_BULK] != 0)
2709 bus->hw_power_state |= USB_HW_POWER_BULK;
2710 if (udev->pwr_save.type_refs[UE_INTERRUPT] != 0)
2711 bus->hw_power_state |= USB_HW_POWER_INTERRUPT;
2712 if (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0)
2713 bus->hw_power_state |= USB_HW_POWER_ISOC;
2714#endif
2716
2717 if (bus->methods->set_hw_power != NULL) {
2718 /* always update hardware power! */
2719 (bus->methods->set_hw_power) (bus);
2720 }
2721
2722 usbd_sr_lock(udev);
2723
2724 /* notify all sub-devices about resume */
2725 err = usb_suspend_resume(udev, 0);
2726
2727 usbd_sr_unlock(udev);
2728
2729 /* check if peer has wakeup capability */
2730 if (usb_peer_can_wakeup(udev)) {
2731 /* clear remote wakeup */
2732 err = usbd_clear_dev_wakeup(udev);
2733 if (err) {
2734 DPRINTFN(0, "Clearing device "
2735 "remote wakeup failed: %s\n",
2736 usbd_errstr(err));
2737 }
2738 }
2739}
2740
2741/*------------------------------------------------------------------------*
2742 * usb_dev_suspend_peer
2743 *
2744 * This function will suspend an USB peer and do the required USB
2745 * signalling to get an USB device into the suspended state.
2746 *------------------------------------------------------------------------*/
2747static void
2749{
2750 struct usb_device *child;
2751 int err;
2752 uint8_t x;
2753 uint8_t nports;
2754
2755repeat:
2756 /* be NULL safe */
2757 if (udev == NULL)
2758 return;
2759
2760 /* check if already suspended */
2761 if (udev->flags.self_suspended)
2762 return;
2763
2764 /* we need a parent HUB to do suspend */
2765 if (udev->parent_hub == NULL)
2766 return;
2767
2768 DPRINTF("udev=%p\n", udev);
2769
2770 /* check if the current device is a HUB */
2771 if (udev->hub != NULL) {
2772 nports = udev->hub->nports;
2773
2774 /* check if all devices on the HUB are suspended */
2775 for (x = 0; x != nports; x++) {
2777 udev->hub->ports + x);
2778
2779 if (child == NULL)
2780 continue;
2781
2782 if (child->flags.self_suspended)
2783 continue;
2784
2785 DPRINTFN(1, "Port %u is busy on the HUB!\n", x + 1);
2786 return;
2787 }
2788 }
2789
2790 if (usb_peer_can_wakeup(udev)) {
2791 /*
2792 * This request needs to be done before we set
2793 * "udev->flags.self_suspended":
2794 */
2795
2796 /* allow device to do remote wakeup */
2797 err = usbd_set_dev_wakeup(udev);
2798 if (err) {
2799 DPRINTFN(0, "Setting device "
2800 "remote wakeup failed\n");
2801 }
2802 }
2803
2804 USB_BUS_LOCK(udev->bus);
2805 /*
2806 * Checking for suspend condition and setting suspended bit
2807 * must be atomic!
2808 */
2809 err = usb_peer_should_wakeup(udev);
2810 if (err == 0) {
2811 /*
2812 * Set that this device is suspended. This variable
2813 * must be set before calling USB controller suspend
2814 * callbacks.
2815 */
2816 udev->flags.self_suspended = 1;
2817 }
2818 USB_BUS_UNLOCK(udev->bus);
2819
2820 if (err != 0) {
2821 if (usb_peer_can_wakeup(udev)) {
2822 /* allow device to do remote wakeup */
2823 err = usbd_clear_dev_wakeup(udev);
2824 if (err) {
2825 DPRINTFN(0, "Setting device "
2826 "remote wakeup failed\n");
2827 }
2828 }
2829
2830 if (udev->flags.usb_mode == USB_MODE_DEVICE) {
2831 /* resume parent HUB first */
2833
2834 /* reduce chance of instant resume failure by waiting a little bit */
2835 usb_pause_mtx(NULL, USB_MS_TO_TICKS(20));
2836
2837 /* resume current port (Valid in Host and Device Mode) */
2839 NULL, udev->port_no, UHF_PORT_SUSPEND);
2840
2841 /* resume settle time */
2843 }
2844 DPRINTF("Suspend was cancelled!\n");
2845 return;
2846 }
2847
2848 usbd_sr_lock(udev);
2849
2850 /* notify all sub-devices about suspend */
2851 err = usb_suspend_resume(udev, 1);
2852
2853 usbd_sr_unlock(udev);
2854
2855 if (udev->bus->methods->device_suspend != NULL) {
2856 usb_timeout_t temp;
2857
2858 /* suspend device on the USB controller */
2859 (udev->bus->methods->device_suspend) (udev);
2860
2861 /* do DMA delay */
2862 temp = usbd_get_dma_delay(udev);
2863 if (temp != 0)
2864 usb_pause_mtx(NULL, USB_MS_TO_TICKS(temp));
2865 }
2866
2867 if (usb_device_20_compatible(udev)) {
2868 /* suspend current port */
2870 NULL, udev->port_no, UHF_PORT_SUSPEND);
2871 if (err) {
2872 DPRINTFN(0, "Suspending port failed\n");
2873 return;
2874 }
2875 } else {
2876 /* suspend current port */
2878 NULL, udev->port_no, UPS_PORT_LS_U3);
2879 if (err) {
2880 DPRINTFN(0, "Suspending port failed\n");
2881 return;
2882 }
2883 }
2884
2885 udev = udev->parent_hub;
2886 goto repeat;
2887}
2888
2889/*------------------------------------------------------------------------*
2890 * usbd_set_power_mode
2891 *
2892 * This function will set the power mode, see USB_POWER_MODE_XXX for a
2893 * USB device.
2894 *------------------------------------------------------------------------*/
2895void
2897{
2898 /* filter input argument */
2899 if ((power_mode != USB_POWER_MODE_ON) &&
2902
2904
2905 udev->power_mode = power_mode; /* update copy of power mode */
2906
2907#if USB_HAVE_POWERD
2909#else
2910 usb_needs_explore(udev->bus, 0 /* no probe */ );
2911#endif
2912}
2913
2914/*------------------------------------------------------------------------*
2915 * usbd_filter_power_mode
2916 *
2917 * This function filters the power mode based on hardware requirements.
2918 *------------------------------------------------------------------------*/
2919uint8_t
2921{
2922 const struct usb_bus_methods *mtod;
2923 int8_t temp;
2924
2925 mtod = udev->bus->methods;
2926 temp = -1;
2927
2928 if (mtod->get_power_mode != NULL)
2929 (mtod->get_power_mode) (udev, &temp);
2930
2931 /* check if we should not filter */
2932 if (temp < 0)
2933 return (power_mode);
2934
2935 /* use fixed power mode given by hardware driver */
2936 return (temp);
2937}
2938
2939/*------------------------------------------------------------------------*
2940 * usbd_start_re_enumerate
2941 *
2942 * This function starts re-enumeration of the given USB device. This
2943 * function does not need to be called BUS-locked. This function does
2944 * not wait until the re-enumeration is completed.
2945 *------------------------------------------------------------------------*/
2946void
2948{
2949 if (udev->re_enumerate_wait == USB_RE_ENUM_DONE) {
2951 usb_needs_explore(udev->bus, 0);
2952 }
2953}
2954
2955/*-----------------------------------------------------------------------*
2956 * usbd_start_set_config
2957 *
2958 * This function starts setting a USB configuration. This function
2959 * does not need to be called BUS-locked. This function does not wait
2960 * until the set USB configuratino is completed.
2961 *------------------------------------------------------------------------*/
2963usbd_start_set_config(struct usb_device *udev, uint8_t index)
2964{
2965 if (udev->re_enumerate_wait == USB_RE_ENUM_DONE) {
2966 if (udev->curr_config_index == index) {
2967 /* no change needed */
2968 return (0);
2969 }
2970 udev->next_config_index = index;
2972 usb_needs_explore(udev->bus, 0);
2973 return (0);
2974 } else if (udev->re_enumerate_wait == USB_RE_ENUM_SET_CONFIG) {
2975 if (udev->next_config_index == index) {
2976 /* no change needed */
2977 return (0);
2978 }
2979 }
2980 return (USB_ERR_PENDING_REQUESTS);
2981}
static int debug
Definition: cfumass.c:73
static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "USB DWC OTG")
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, phy_type, CTLFLAG_RDTUN, &dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2/3 - ULPI/HSIC/INTERNAL/UTMI+")
uint16_t len
Definition: ehci.h:41
uint32_t val
Definition: if_rum.c:284
struct @109 error
bool start
u_int index
device_t child
u_int bus
device_t dev
u_int slot
uint8_t portno
struct usb_device * udev
uint8_t iface_index
struct usb_xfer * sc_xfer[UHUB_N_TRANSFER]
struct usb_device * sc_udev
struct mtx sc_mtx
struct uhub_current_state sc_st
uint8_t sc_usb_port_errors
device_t sc_dev
uint8_t sc_flags
enum usb_hc_mode usb_mode
Definition: usbdi.h:432
struct usbd_lookup_info info
Definition: usbdi.h:426
struct usb_device * device
Definition: usbdi.h:430
void(* get_power_mode)(struct usb_device *udev, int8_t *pmode)
void(* device_suspend)(struct usb_device *)
void(* set_hw_power)(struct usb_bus *)
uint8_t driver_added_refcount
Definition: usb_bus.h:118
uint8_t do_probe
Definition: usb_bus.h:122
device_t bdev
Definition: usb_bus.h:101
uint16_t isoc_time_last
Definition: usb_bus.h:115
usb_power_mask_t hw_power_state
Definition: usb_bus.h:112
struct mtx bus_mtx
Definition: usb_bus.h:95
const struct usb_bus_methods * methods
Definition: usb_bus.h:107
struct usb_device ** devices
Definition: usb_bus.h:108
struct usb_bus_msg explore_msg[2]
Definition: usb_bus.h:81
uint8_t devices_max
Definition: usb_bus.h:121
uint8_t type
Definition: usbdi.h:238
uByte bDeviceProtocol
Definition: usb.h:298
uByte bDeviceSubClass
Definition: usb.h:297
uByte bDeviceClass
Definition: usb.h:296
uint8_t self_powered
Definition: usb_device.h:95
uint8_t remote_wakeup
Definition: usb_device.h:98
uint8_t self_suspended
Definition: usb_device.h:107
enum usb_hc_mode usb_mode
Definition: usb_device.h:94
uByte bRequest
Definition: usb.h:149
uint8_t power_mode
Definition: usb_device.h:255
struct usb_device * parent_hs_hub
Definition: usb_device.h:219
enum usb_dev_speed speed
Definition: usb_device.h:235
uint8_t hs_port_no
Definition: usb_device.h:253
uint8_t depth
Definition: usb_device.h:249
struct usb_hub * hub
Definition: usb_device.h:221
struct usb_bus * bus
Definition: usb_device.h:216
uint8_t device_index
Definition: usb_device.h:244
struct usb_power_save pwr_save
Definition: usb_device.h:215
struct usb_device_descriptor ddesc
Definition: usb_device.h:270
uint16_t refcount
Definition: usb_device.h:236
uint8_t curr_config_index
Definition: usb_device.h:247
struct usb_device * parent_hub
Definition: usb_device.h:218
uint8_t next_config_index
Definition: usb_device.h:246
uint8_t port_no
Definition: usb_device.h:251
uint8_t address
Definition: usb_device.h:243
uint8_t re_enumerate_wait
Definition: usb_device.h:256
uint8_t driver_added_refcount
Definition: usb_device.h:254
struct usb_device_flags flags
Definition: usb_device.h:266
uByte bEndpointAddress
Definition: usb.h:528
uint8_t usb_smask
Definition: usbdi.h:162
uint8_t refcount_bw
Definition: usbdi.h:157
struct usb_xfer_queue endpoint_q[USB_MAX_EP_STREAMS]
Definition: usbdi.h:142
const struct usb_pipe_methods * methods
Definition: usbdi.h:146
uint8_t usb_uframe
Definition: usbdi.h:164
struct usb_endpoint_descriptor * edesc
Definition: usbdi.h:144
uint8_t usb_cmask
Definition: usbdi.h:163
uWord wHubCharacteristics
Definition: usb.h:606
uByte bNbrPorts
Definition: usb.h:605
uByte bPwrOn2PwrGood
Definition: usb.h:622
uByte bPwrOn2PwrGood
Definition: usb.h:637
void * hubsoftc
Definition: usb_hub.h:51
usb_error_t(* explore)(struct usb_device *hub)
Definition: usb_hub.h:50
struct usb_port ports[0]
Definition: usb_hub.h:60
usb_size_t uframe_usage[USB_HS_MICRO_FRAMES_MAX]
Definition: usb_hub.h:55
struct usb_device * hubudev
Definition: usb_hub.h:49
uint16_t portpower
Definition: usb_hub.h:56
uint8_t nports
Definition: usb_hub.h:58
uByte bInterfaceSubClass
Definition: usb.h:409
uByte bInterfaceProtocol
Definition: usb.h:410
device_t subdev
Definition: usbdi.h:176
struct usb_interface_descriptor * idesc
Definition: usbdi.h:175
char * pnpinfo
Definition: usbdi.h:188
uWord wPortStatus
Definition: usb.h:704
uWord wPortChange
Definition: usb.h:735
uint8_t device_index
Definition: usb_hub.h:38
uint8_t restartcnt
Definition: usb_hub.h:36
usb_ticks_t last_xfer_time
Definition: usb_device.h:115
usb_size_t read_refs
Definition: usb_device.h:117
usb_size_t type_refs[4]
Definition: usb_device.h:116
usb_size_t write_refs
Definition: usb_device.h:118
struct usb_device * udev
Definition: usb_device.h:60
enum usb_hc_mode usb_mode
Definition: usb_core.h:91
uint8_t control_xfr
Definition: usb_core.h:103
struct usb_bus * bus
Definition: usb_transfer.h:78
struct usb_device * udev
Definition: usb_transfer.h:79
usb_frlength_t * frlengths
Definition: usb_core.h:150
usb_frcount_t nframes
Definition: usb_core.h:162
struct usb_page_cache * frbuffers
Definition: usb_core.h:151
usb_error_t error
Definition: usb_core.h:179
struct usb_endpoint * endpoint
Definition: usb_core.h:140
struct usb_xfer_flags_int flags_int
Definition: usb_core.h:182
struct usb_xfer_root * xroot
Definition: usb_core.h:141
uint16_t max_frame_size
Definition: usb_core.h:168
uint16_t isoc_time_complete
Definition: usb_core.h:170
uint8_t bDeviceClass
Definition: usbdi.h:411
uint8_t bConfigIndex
Definition: usbdi.h:419
#define DPRINTF(...)
Definition: umass.c:179
#define UE_INTERRUPT
Definition: usb.h:544
#define UE_DIR_ANY
Definition: usb.h:535
#define USB_INTERFACE_FUNC_SUSPEND_RW
Definition: usb.h:279
#define UT_WRITE_INTERFACE
Definition: usb.h:170
#define UE_ADDR_ANY
Definition: usb.h:537
#define UDPROTO_HSHUBMTT
Definition: usb.h:377
#define USB_INTERFACE_FUNC_SUSPEND
Definition: usb.h:277
#define UE_BULK
Definition: usb.h:543
#define UHF_PORT_POWER
Definition: usb.h:254
#define UPS_PORT_POWER_SS
Definition: usb.h:728
#define UT_WRITE_CLASS_OTHER
Definition: usb.h:178
#define UPS_C_PORT_ENABLED
Definition: usb.h:737
#define UPS_C_OVERCURRENT_INDICATOR
Definition: usb.h:739
#define UDCLASS_HUB
Definition: usb.h:373
#define UR_CLEAR_TT_BUFFER
Definition: usb.h:228
#define UHF_C_PORT_SUSPEND
Definition: usb.h:259
#define UR_CLEAR_FEATURE
Definition: usb.h:191
#define UPS_LOW_SPEED
Definition: usb.h:729
#define USB_POWER_DOWN_TIME
Definition: usb.h:92
#define UPS_PORT_LS_SS_INA
Definition: usb.h:720
#define UPS_PORT_POWER
Definition: usb.h:727
#define UF_DEVICE_REMOTE_WAKEUP
Definition: usb.h:239
#define USB_UNCONFIG_INDEX
Definition: usb.h:75
#define USB_ROOT_HUB_ADDR
Definition: usb.h:73
#define UHF_C_PORT_OVER_CURRENT
Definition: usb.h:260
#define UHF_PORT_SUSPEND
Definition: usb.h:250
#define UHD_PWRON_FACTOR
Definition: usb.h:623
#define USB_POWER_MODE_SAVE
Definition: usb.h:98
#define UDPROTO_HSHUBSTT
Definition: usb.h:376
#define UPS_PORT_MODE_DEVICE
Definition: usb.h:734
#define USB_SS_HUB_DEPTH_MAX
Definition: usb.h:234
#define USB_INTERFACE_FUNC_SUSPEND_LP
Definition: usb.h:278
#define UE_XFERTYPE
Definition: usb.h:540
#define UHF_PORT_ENABLE
Definition: usb.h:249
#define USB_MIN_POWER
Definition: usb.h:126
#define UPS_C_PORT_LINK_STATE
Definition: usb.h:743
#define USB_IFACE_INDEX_ANY
Definition: usb.h:76
#define UPS_HIGH_SPEED
Definition: usb.h:730
usb_dev_speed
Definition: usb.h:751
@ USB_SPEED_LOW
Definition: usb.h:753
@ USB_SPEED_FULL
Definition: usb.h:754
@ USB_SPEED_HIGH
Definition: usb.h:755
@ USB_SPEED_SUPER
Definition: usb.h:756
#define UR_RESET_TT
Definition: usb.h:229
#define UPS_PORT_LINK_STATE_GET(x)
Definition: usb.h:712
usb_hc_mode
Definition: usb.h:777
@ USB_MODE_HOST
Definition: usb.h:778
@ USB_MODE_DEVICE
Definition: usb.h:779
#define USB_HS_MICRO_FRAMES_MAX
Definition: usb.h:84
#define UPS_PORT_LS_U0
Definition: usb.h:714
#define USB_ISOC_TIME_MAX
Definition: usb.h:86
#define UPS_PORT_ENABLED
Definition: usb.h:706
#define USB_MAX_POWER
Definition: usb.h:127
#define UPS_OTHER_SPEED
Definition: usb.h:731
#define USB_POWER_MODE_ON
Definition: usb.h:97
#define USB_POWER_MODE_OFF
Definition: usb.h:96
#define UE_CONTROL
Definition: usb.h:541
#define UHD_NOT_REMOV(desc, i)
Definition: usb.h:626
#define USB_FS_BYTES_PER_HS_UFRAME
Definition: usb.h:83
#define UHF_C_PORT_LINK_STATE
Definition: usb.h:269
#define UPS_PORT_LS_U3
Definition: usb.h:717
#define UPS_C_SUSPEND
Definition: usb.h:738
#define UPS_C_CONNECT_STATUS
Definition: usb.h:736
#define UPS_CURRENT_CONNECT_STATUS
Definition: usb.h:705
#define UE_ISOCHRONOUS
Definition: usb.h:542
#define UHF_C_PORT_ENABLE
Definition: usb.h:258
#define UR_SET_FEATURE
Definition: usb.h:192
#define UPS_SUSPEND
Definition: usb.h:707
#define UHF_C_PORT_CONNECTION
Definition: usb.h:257
#define USB_BUS_TT_PROC(bus)
Definition: usb_bus.h:54
void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len)
Definition: usb_busdma.c:166
#define USB_HW_POWER_BULK
#define USB_HW_POWER_NON_ROOT_HUB
#define USB_HW_POWER_CONTROL
#define USB_HW_POWER_ISOC
#define USB_HW_POWER_INTERRUPT
#define USB_GET_DATA_ISREAD(xfer)
Definition: usb_core.h:40
#define USB_BUS_LOCK(_b)
Definition: usb_core.h:45
struct mtx usb_ref_lock
#define USB_BUS_UNLOCK(_b)
Definition: usb_core.h:46
#define USB_BUS_LOCK_ASSERT(_b, _t)
Definition: usb_core.h:47
#define usb_port_resume_delay
Definition: usb_debug.h:80
#define usb_extra_power_up_time
Definition: usb_debug.h:85
#define usb_port_powerup_delay
Definition: usb_debug.h:79
usb_error_t usbd_set_alt_interface_index(struct usb_device *udev, uint8_t iface_index, uint8_t alt_index)
Definition: usb_device.c:1034
uint8_t usbd_enum_lock(struct usb_device *udev)
Definition: usb_device.c:2896
usb_error_t usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index)
Definition: usb_device.c:1441
const char * usb_get_serial(struct usb_device *udev)
Definition: usb_device.c:293
void usbd_sr_lock(struct usb_device *udev)
Definition: usb_device.c:2946
enum usb_dev_speed usbd_get_speed(struct usb_device *udev)
Definition: usb_device.c:2589
usb_error_t usbd_set_config_index(struct usb_device *udev, uint8_t index)
Definition: usb_device.c:672
void usb_free_device(struct usb_device *udev, uint8_t flag)
Definition: usb_device.c:2271
void usbd_sr_unlock(struct usb_device *udev)
Definition: usb_device.c:2960
uint8_t usb_peer_can_wakeup(struct usb_device *udev)
Definition: usb_device.c:2845
usb_error_t usb_suspend_resume(struct usb_device *udev, uint8_t do_suspend)
Definition: usb_device.c:1586
void usbd_enum_unlock(struct usb_device *udev)
Definition: usb_device.c:2936
uint8_t usbd_ctrl_lock(struct usb_device *udev)
Definition: usb_device.c:2983
void usb_set_device_strings(struct usb_device *udev)
Definition: usb_device.c:2488
void usbd_ctrl_unlock(struct usb_device *udev)
Definition: usb_device.c:2999
struct usb_device * usb_alloc_device(device_t parent_dev, struct usb_bus *bus, struct usb_device *parent_hub, uint8_t depth, uint8_t port_index, uint8_t port_no, enum usb_dev_speed speed, enum usb_hc_mode mode)
Definition: usb_device.c:1737
void usb_get_langid(struct usb_device *udev)
Definition: usb_device.c:1651
struct usb_interface * usbd_get_iface(struct usb_device *udev, uint8_t iface_index)
Definition: usb_device.c:2370
#define USB_RE_ENUM_START
Definition: usb_device.h:258
#define USB_RE_ENUM_SET_CONFIG
Definition: usb_device.h:260
#define USB_RE_ENUM_DONE
Definition: usb_device.h:257
#define USB_RE_ENUM_PWR_OFF
Definition: usb_device.h:259
devclass_t usb_devclass_ptr
Definition: usb_dynamic.c:80
#define USETW(w, v)
Definition: usb_endian.h:77
#define UGETW(w)
Definition: usb_endian.h:53
const char * usbd_errstr(usb_error_t err)
Definition: usb_error.c:93
uint16_t usb_power_mask_t
Definition: usb_freebsd.h:104
#define USB_HUB_MAX_DEPTH
Definition: usb_freebsd.h:90
#define USB_HAVE_UGEN
Definition: usb_freebsd.h:37
uint32_t usb_frlength_t
Definition: usb_freebsd.h:100
uint32_t usb_ticks_t
Definition: usb_freebsd.h:103
#define USB_MAX_PORTS
Definition: usb_freebsd.h:85
#define USB_FS_ISOC_UFRAME_MAX
Definition: usb_freebsd.h:77
uint32_t usb_timeout_t
Definition: usb_freebsd.h:99
uint32_t usb_size_t
Definition: usb_freebsd.h:102
#define USB_IFACE_MAX
Definition: usb_freebsd.h:81
SYSINIT(usb_needs_explore_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_SECOND, usb_needs_explore_init, NULL)
static bus_child_pnpinfo_t uhub_child_pnpinfo
Definition: usb_hub.c:121
void usbd_set_power_mode(struct usb_device *udev, uint8_t power_mode)
Definition: usb_hub.c:2896
static void usb_dev_suspend_peer(struct usb_device *udev)
Definition: usb_hub.c:2748
int uhub_get_device_path(device_t bus, device_t child, const char *locator, struct sbuf *sb)
Definition: usb_hub.c:1676
static const struct usb_config uhub_config[UHUB_N_TRANSFER]
Definition: usb_hub.c:132
DRIVER_MODULE(uhub, usbus, uhub_driver, uhub_devclass, 0, 0)
static usb_error_t uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
Definition: usb_hub.c:602
MODULE_VERSION(uhub, 1)
int uhub_attach(device_t dev)
Definition: usb_hub.c:1190
uint8_t uhub_count_active_host_ports(struct usb_device *udev, enum usb_dev_speed speed)
Definition: usb_hub.c:386
static usb_callback_t uhub_intr_callback
Definition: usb_hub.c:123
void uhub_root_intr(struct usb_bus *bus, const uint8_t *ptr, uint8_t len)
Definition: usb_hub.c:960
static void usb_dev_resume_peer(struct usb_device *udev)
Definition: usb_hub.c:2639
static usb_error_t uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up)
Definition: usb_hub.c:510
static device_suspend_t uhub_suspend
Definition: usb_hub.c:117
int uhub_child_location(device_t parent, device_t child, struct sbuf *sb)
Definition: usb_hub.c:1638
static device_resume_t uhub_resume
Definition: usb_hub.c:118
void uhub_find_iface_index(struct usb_hub *hub, device_t child, struct hub_result *res)
Definition: usb_hub.c:1605
static uint8_t usb_device_20_compatible(struct usb_device *udev)
Definition: usb_hub.c:854
static device_method_t uhub_methods[]
Definition: usb_hub.c:162
usb_error_t usbd_start_set_config(struct usb_device *udev, uint8_t index)
Definition: usb_hub.c:2963
static uint8_t usb_hs_bandwidth_adjust(struct usb_device *udev, int16_t len, uint8_t slot, uint8_t mask)
Definition: usb_hub.c:1850
static void usb_needs_explore_init(void *arg)
Definition: usb_hub.c:2337
void usb_needs_explore(struct usb_bus *bus, uint8_t do_probe)
Definition: usb_hub.c:2255
void usb_hs_bandwidth_alloc(struct usb_xfer *xfer)
Definition: usb_hub.c:1908
uint8_t usbd_filter_power_mode(struct usb_device *udev, uint8_t power_mode)
Definition: usb_hub.c:2920
void usb_needs_explore_all(void)
Definition: usb_hub.c:2300
void uhub_explore_handle_re_enumerate(struct usb_device *child)
Definition: usb_hub.c:417
static uint8_t usb_peer_should_wakeup(struct usb_device *udev)
Definition: usb_hub.c:2453
void usb_hs_bandwidth_free(struct usb_xfer *xfer)
Definition: usb_hub.c:1989
static usb_error_t uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
Definition: usb_hub.c:560
static usb_error_t uhub_explore(struct usb_device *udev)
Definition: usb_hub.c:995
usb_error_t uhub_query_info(struct usb_device *udev, uint8_t *pnports, uint8_t *ptt)
Definition: usb_hub.c:1130
static usb_error_t uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno)
Definition: usb_hub.c:876
static devclass_t uhub_devclass
Definition: usb_hub.c:160
static uint8_t uhub_is_too_deep(struct usb_device *udev)
Definition: usb_hub.c:968
static usb_error_t usbd_device_30_remote_wakeup(struct usb_device *udev, uint8_t bRequest)
Definition: usb_hub.c:2589
int uhub_probe(device_t dev)
Definition: usb_hub.c:1110
static bus_driver_added_t uhub_driver_added
Definition: usb_hub.c:120
static uint8_t usb_intr_find_best_slot(usb_size_t *ptr, uint8_t start, uint8_t end, uint8_t mask)
Definition: usb_hub.c:1802
void usbd_start_re_enumerate(struct usb_device *udev)
Definition: usb_hub.c:2947
void usb_bus_port_set_device(struct usb_bus *bus, struct usb_port *up, struct usb_device *udev, uint8_t device_index)
Definition: usb_hub.c:2212
#define UHUB_IS_MULTI_TT(sc)
Definition: usb_hub.c:112
uint16_t usb_isoc_time_expand(struct usb_bus *bus, uint16_t isoc_time_curr)
Definition: usb_hub.c:2037
driver_t uhub_driver
Definition: usb_hub.c:177
int uhub_detach(device_t dev)
Definition: usb_hub.c:1536
static usb_error_t usbd_set_dev_wakeup(struct usb_device *udev)
Definition: usb_hub.c:2618
struct usb_device * usb_bus_port_get_device(struct usb_bus *bus, struct usb_port *up)
Definition: usb_hub.c:2193
static usb_error_t usbd_clear_dev_wakeup(struct usb_device *udev)
Definition: usb_hub.c:2603
#define USB_RESTART_MAX
Definition: usb_hub.h:37
void usb_bus_powerd(struct usb_bus *bus)
void usb_bus_power_update(struct usb_bus *bus)
#define UHUB_USB_PORT_ERRORS_MAX
#define UHUB_INTR_INTERVAL
@ UHUB_N_TRANSFER
@ UHUB_INTR_TRANSFER
#define UHUB_FLAG_DID_EXPLORE
const void * req
Definition: usb_if.m:51
void usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
Definition: usb_process.c:394
void * usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
Definition: usb_process.c:288
usb_error_t usbd_req_set_hub_u2_timeout(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint8_t timeout)
Definition: usb_request.c:1690
usb_error_t usbd_req_get_hub_descriptor(struct usb_device *udev, struct mtx *mtx, struct usb_hub_descriptor *hd, uint8_t nports)
Definition: usb_request.c:1493
usb_error_t usbd_req_get_ss_hub_descriptor(struct usb_device *udev, struct mtx *mtx, struct usb_hub_ss_descriptor *hd, uint8_t nports)
Definition: usb_request.c:1515
usb_error_t usbd_req_set_port_link_state(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint8_t link_state)
Definition: usb_request.c:2271
usb_error_t usbd_req_set_device_feature(struct usb_device *udev, struct mtx *mtx, uint16_t sel)
Definition: usb_request.c:2186
usb_error_t usbd_req_set_hub_u1_timeout(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint8_t timeout)
Definition: usb_request.c:1668
usb_error_t usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
Definition: usb_request.c:786
usb_error_t usbd_req_re_enumerate(struct usb_device *udev, struct mtx *mtx)
Definition: usb_request.c:2054
usb_error_t usbd_req_set_hub_depth(struct usb_device *udev, struct mtx *mtx, uint16_t depth)
Definition: usb_request.c:1712
usb_error_t usbd_req_clear_port_feature(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint16_t sel)
Definition: usb_request.c:1733
usb_error_t usbd_req_warm_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
Definition: usb_request.c:876
usb_error_t usbd_req_clear_device_feature(struct usb_device *udev, struct mtx *mtx, uint16_t sel)
Definition: usb_request.c:2165
usb_error_t usbd_req_set_port_feature(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint16_t sel)
Definition: usb_request.c:1755
usb_error_t usbd_req_get_port_status(struct usb_device *udev, struct mtx *mtx, struct usb_port_status *ps, uint8_t port)
Definition: usb_request.c:1603
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup)
void usbd_xfer_set_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex, usb_frlength_t len)
void usbd_ctrl_transfer_setup(struct usb_device *udev)
uint8_t usbd_xfer_get_fps_shift(struct usb_xfer *xfer)
usb_error_t usbd_transfer_setup(struct usb_device *udev, const uint8_t *ifaces, struct usb_xfer **ppxfer, const struct usb_config *setup_start, uint16_t n_setup, void *priv_sc, struct mtx *xfer_mtx)
Definition: usb_transfer.c:987
void usbd_transfer_start(struct usb_xfer *xfer)
usb_timeout_t usbd_get_dma_delay(struct usb_device *udev)
Definition: usb_transfer.c:187
void * usbd_xfer_softc(struct usb_xfer *xfer)
void usbd_xfer_set_stall(struct usb_xfer *xfer)
usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer)
void usbd_transfer_power_ref(struct usb_xfer *xfer, int val)
void device_set_usb_desc(device_t dev)
Definition: usb_util.c:73
void usb_pause_mtx(struct mtx *mtx, int timo)
Definition: usb_util.c:135
#define USB_MTX_UNLOCK(_m)
Definition: usbdi.h:458
#define USB_MTX_LOCK(_m)
Definition: usbdi.h:453
#define USB_ST_SETUP
Definition: usbdi.h:502
usb_error_t
Definition: usbdi.h:45
@ USB_ERR_NORMAL_COMPLETION
Definition: usbdi.h:46
@ USB_ERR_PENDING_REQUESTS
Definition: usbdi.h:47
@ USB_ERR_CANCELLED
Definition: usbdi.h:51
@ USB_ERR_INVAL
Definition: usbdi.h:49
@ USB_ERR_TIMEOUT
Definition: usbdi.h:66
@ USB_ERR_TOO_DEEP
Definition: usbdi.h:63
#define USB_ST_TRANSFERRED
Definition: usbdi.h:503
#define USB_MS_TO_TICKS(ms)
Definition: usbdi.h:120
void() usb_callback_t(struct usb_xfer *, usb_error_t)
Definition: usbdi.h:94
#define USB_GET_STATE(xfer)
Definition: usbdi.h:515
#define usbd_do_request(u, m, r, d)
Definition: usbdi.h:596