Deleted Added
full compact
usb_hub.c (184610) usb_hub.c (184824)
1/* $FreeBSD: head/sys/dev/usb2/core/usb2_hub.c 184610 2008-11-04 02:31:03Z alfred $ */
1/* $FreeBSD: head/sys/dev/usb2/core/usb2_hub.c 184824 2008-11-10 20:54:31Z thompsa $ */
2/*-
3 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
4 * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
5 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29/*
30 * USB spec: http://www.usb.org/developers/docs/usbspec.zip
31 */
32
33#include <dev/usb2/include/usb2_defs.h>
34#include <dev/usb2/include/usb2_mfunc.h>
35#include <dev/usb2/include/usb2_error.h>
36#include <dev/usb2/include/usb2_standard.h>
37
38#define USB_DEBUG_VAR uhub_debug
39
40#include <dev/usb2/core/usb2_core.h>
41#include <dev/usb2/core/usb2_process.h>
42#include <dev/usb2/core/usb2_device.h>
43#include <dev/usb2/core/usb2_request.h>
44#include <dev/usb2/core/usb2_debug.h>
45#include <dev/usb2/core/usb2_hub.h>
46#include <dev/usb2/core/usb2_util.h>
47#include <dev/usb2/core/usb2_busdma.h>
48#include <dev/usb2/core/usb2_transfer.h>
49#include <dev/usb2/core/usb2_dynamic.h>
50
51#include <dev/usb2/controller/usb2_controller.h>
52#include <dev/usb2/controller/usb2_bus.h>
53
54#define UHUB_INTR_INTERVAL 250 /* ms */
55
56#if USB_DEBUG
57static int uhub_debug = 0;
58
59SYSCTL_NODE(_hw_usb2, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB HUB");
60SYSCTL_INT(_hw_usb2_uhub, OID_AUTO, debug, CTLFLAG_RW, &uhub_debug, 0,
61 "Debug level");
62#endif
63
64struct uhub_current_state {
65 uint16_t port_change;
66 uint16_t port_status;
67};
68
69struct uhub_softc {
70 struct uhub_current_state sc_st;/* current state */
71 device_t sc_dev; /* base device */
72 struct usb2_device *sc_udev; /* USB device */
73 struct usb2_xfer *sc_xfer[2]; /* interrupt xfer */
74 uint8_t sc_flags;
75#define UHUB_FLAG_INTR_STALL 0x02
76 char sc_name[32];
77};
78
79#define UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol)
80#define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
81#define UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
82
83/* prototypes for type checking: */
84
85static device_probe_t uhub_probe;
86static device_attach_t uhub_attach;
87static device_detach_t uhub_detach;
88
89static bus_driver_added_t uhub_driver_added;
90static bus_child_location_str_t uhub_child_location_string;
91static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string;
92
93static usb2_callback_t uhub_intr_callback;
94static usb2_callback_t uhub_intr_clear_stall_callback;
95
96static const struct usb2_config uhub_config[2] = {
97
98 [0] = {
99 .type = UE_INTERRUPT,
100 .endpoint = UE_ADDR_ANY,
101 .direction = UE_DIR_ANY,
102 .mh.timeout = 0,
103 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
104 .mh.bufsize = 0, /* use wMaxPacketSize */
105 .mh.callback = &uhub_intr_callback,
106 .mh.interval = UHUB_INTR_INTERVAL,
107 },
108
109 [1] = {
110 .type = UE_CONTROL,
111 .endpoint = 0,
112 .direction = UE_DIR_ANY,
113 .mh.timeout = 1000, /* 1 second */
114 .mh.interval = 50, /* 50ms */
115 .mh.flags = {},
116 .mh.bufsize = sizeof(struct usb2_device_request),
117 .mh.callback = &uhub_intr_clear_stall_callback,
118 },
119};
120
121/*
122 * driver instance for "hub" connected to "usb"
123 * and "hub" connected to "hub"
124 */
125static devclass_t uhub_devclass;
126
127static driver_t uhub_driver =
128{
129 .name = "ushub",
130 .methods = (device_method_t[]){
131 DEVMETHOD(device_probe, uhub_probe),
132 DEVMETHOD(device_attach, uhub_attach),
133 DEVMETHOD(device_detach, uhub_detach),
134
135 DEVMETHOD(device_suspend, bus_generic_suspend),
136 DEVMETHOD(device_resume, bus_generic_resume),
137 DEVMETHOD(device_shutdown, bus_generic_shutdown),
138
139 DEVMETHOD(bus_child_location_str, uhub_child_location_string),
140 DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string),
141 DEVMETHOD(bus_driver_added, uhub_driver_added),
142 {0, 0}
143 },
144 .size = sizeof(struct uhub_softc)
145};
146
147DRIVER_MODULE(ushub, usbus, uhub_driver, uhub_devclass, 0, 0);
148DRIVER_MODULE(ushub, ushub, uhub_driver, uhub_devclass, NULL, 0);
149
150static void
151uhub_intr_clear_stall_callback(struct usb2_xfer *xfer)
152{
153 struct uhub_softc *sc = xfer->priv_sc;
154 struct usb2_xfer *xfer_other = sc->sc_xfer[0];
155
156 if (usb2_clear_stall_callback(xfer, xfer_other)) {
157 DPRINTF("stall cleared\n");
158 sc->sc_flags &= ~UHUB_FLAG_INTR_STALL;
159 usb2_transfer_start(xfer_other);
160 }
161 return;
162}
163
164static void
165uhub_intr_callback(struct usb2_xfer *xfer)
166{
167 struct uhub_softc *sc = xfer->priv_sc;
168
169 switch (USB_GET_STATE(xfer)) {
170 case USB_ST_TRANSFERRED:
171 DPRINTFN(2, "\n");
172 /*
173 * This is an indication that some port
174 * has changed status. Notify the bus
175 * event handler thread that we need
176 * to be explored again:
177 */
178 usb2_needs_explore(sc->sc_udev->bus, 0);
179
180 case USB_ST_SETUP:
181 if (sc->sc_flags & UHUB_FLAG_INTR_STALL) {
182 usb2_transfer_start(sc->sc_xfer[1]);
183 } else {
184 xfer->frlengths[0] = xfer->max_data_length;
185 usb2_start_hardware(xfer);
186 }
187 return;
188
189 default: /* Error */
190 if (xfer->error != USB_ERR_CANCELLED) {
191 /* start clear stall */
192 sc->sc_flags |= UHUB_FLAG_INTR_STALL;
193 usb2_transfer_start(sc->sc_xfer[1]);
194 }
195 return;
196 }
197}
198
199/*------------------------------------------------------------------------*
200 * uhub_explore_sub - subroutine
201 *
202 * Return values:
203 * 0: Success
204 * Else: A control transaction failed
205 *------------------------------------------------------------------------*/
206static usb2_error_t
207uhub_explore_sub(struct uhub_softc *sc, struct usb2_port *up)
208{
209 struct usb2_bus *bus;
210 struct usb2_device *child;
211 uint8_t refcount;
212 usb2_error_t err;
213
214 bus = sc->sc_udev->bus;
215 err = 0;
216
217 /* get driver added refcount from USB bus */
218 refcount = bus->driver_added_refcount;
219
220 /* get device assosiated with the given port */
221 child = usb2_bus_port_get_device(bus, up);
222 if (child == NULL) {
223 /* nothing to do */
224 goto done;
225 }
226 /* check if probe and attach should be done */
227
228 if (child->driver_added_refcount != refcount) {
229 child->driver_added_refcount = refcount;
230 err = usb2_probe_and_attach(child,
231 USB_IFACE_INDEX_ANY);
232 if (err) {
233 goto done;
234 }
235 }
236 /* start control transfer, if device mode */
237
238 if (child->flags.usb2_mode == USB_MODE_DEVICE) {
239 usb2_default_transfer_setup(child);
240 }
241 /* if a HUB becomes present, do a recursive HUB explore */
242
243 if (child->hub) {
244 err = (child->hub->explore) (child);
245 }
246done:
247 return (err);
248}
249
250/*------------------------------------------------------------------------*
251 * uhub_read_port_status - factored out code
252 *------------------------------------------------------------------------*/
253static usb2_error_t
254uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
255{
256 struct usb2_port_status ps;
257 usb2_error_t err;
258
259 err = usb2_req_get_port_status(
260 sc->sc_udev, &Giant, &ps, portno);
261
262 /* update status regardless of error */
263
264 sc->sc_st.port_status = UGETW(ps.wPortStatus);
265 sc->sc_st.port_change = UGETW(ps.wPortChange);
266
267 /* debugging print */
268
269 DPRINTFN(4, "port %d, wPortStatus=0x%04x, "
270 "wPortChange=0x%04x, err=%s\n",
271 portno, sc->sc_st.port_status,
272 sc->sc_st.port_change, usb2_errstr(err));
273 return (err);
274}
275
276/*------------------------------------------------------------------------*
277 * uhub_reattach_port
278 *
279 * Returns:
280 * 0: Success
281 * Else: A control transaction failed
282 *------------------------------------------------------------------------*/
283static usb2_error_t
284uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
285{
286 struct usb2_device *child;
287 struct usb2_device *udev;
288 usb2_error_t err;
289 uint8_t timeout;
290 uint8_t speed;
291 uint8_t usb2_mode;
292
293 DPRINTF("reattaching port %d\n", portno);
294
295 err = 0;
296 timeout = 0;
297 udev = sc->sc_udev;
298 child = usb2_bus_port_get_device(udev->bus,
299 udev->hub->ports + portno - 1);
300
301repeat:
302
303 /* first clear the port connection change bit */
304
305 err = usb2_req_clear_port_feature
306 (udev, &Giant, portno, UHF_C_PORT_CONNECTION);
307
308 if (err) {
309 goto error;
310 }
311 /* detach any existing devices */
312
313 if (child) {
314 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 1);
315 usb2_free_device(child);
316 child = NULL;
317 }
318 /* get fresh status */
319
320 err = uhub_read_port_status(sc, portno);
321 if (err) {
322 goto error;
323 }
324 /* check if nothing is connected to the port */
325
326 if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS)) {
327 goto error;
328 }
329 /* check if there is no power on the port and print a warning */
330
331 if (!(sc->sc_st.port_status & UPS_PORT_POWER)) {
332 DPRINTF("WARNING: strange, connected port %d "
333 "has no power\n", portno);
334 }
335 /* check if the device is in Host Mode */
336
337 if (!(sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)) {
338
339 DPRINTF("Port %d is in Host Mode\n", portno);
340
341 /* USB Host Mode */
342
343 /* wait for maximum device power up time */
344
345 usb2_pause_mtx(&Giant, USB_PORT_POWERUP_DELAY);
346
347 /* reset port, which implies enabling it */
348
349 err = usb2_req_reset_port
350 (udev, &Giant, portno);
351
352 if (err) {
353 DPRINTFN(0, "port %d reset "
354 "failed, error=%s\n",
355 portno, usb2_errstr(err));
356 goto error;
357 }
358 /* get port status again, it might have changed during reset */
359
360 err = uhub_read_port_status(sc, portno);
361 if (err) {
362 goto error;
363 }
364 /* check if something changed during port reset */
365
366 if ((sc->sc_st.port_change & UPS_C_CONNECT_STATUS) ||
367 (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS))) {
368 if (timeout) {
369 DPRINTFN(0, "giving up port reset "
370 "- device vanished!\n");
371 goto error;
372 }
373 timeout = 1;
374 goto repeat;
375 }
376 } else {
377 DPRINTF("Port %d is in Device Mode\n", portno);
378 }
379
380 /*
381 * Figure out the device speed
382 */
383 speed =
384 (sc->sc_st.port_status & UPS_HIGH_SPEED) ? USB_SPEED_HIGH :
385 (sc->sc_st.port_status & UPS_LOW_SPEED) ? USB_SPEED_LOW : USB_SPEED_FULL;
386
387 /*
388 * Figure out the device mode
389 *
390 * NOTE: This part is currently FreeBSD specific.
391 */
392 usb2_mode =
393 (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) ?
394 USB_MODE_DEVICE : USB_MODE_HOST;
395
396 /* need to create a new child */
397
398 child = usb2_alloc_device(sc->sc_dev, udev->bus, udev,
399 udev->depth + 1, portno - 1, portno, speed, usb2_mode);
400 if (child == NULL) {
401 DPRINTFN(0, "could not allocate new device!\n");
402 goto error;
403 }
404 return (0); /* success */
405
406error:
407 if (child) {
408 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 1);
409 usb2_free_device(child);
410 child = NULL;
411 }
412 if (err == 0) {
413 if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
414 err = usb2_req_clear_port_feature
415 (sc->sc_udev, &Giant,
416 portno, UHF_PORT_ENABLE);
417 }
418 }
419 if (err) {
420 DPRINTFN(0, "device problem (%s), "
421 "disabling port %d\n", usb2_errstr(err), portno);
422 }
423 return (err);
424}
425
426/*------------------------------------------------------------------------*
427 * uhub_suspend_resume_port
428 *
429 * Returns:
430 * 0: Success
431 * Else: A control transaction failed
432 *------------------------------------------------------------------------*/
433static usb2_error_t
434uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno)
435{
436 struct usb2_device *child;
437 struct usb2_device *udev;
438 uint8_t is_suspend;
439 usb2_error_t err;
440
441 DPRINTF("port %d\n", portno);
442
443 udev = sc->sc_udev;
444 child = usb2_bus_port_get_device(udev->bus,
445 udev->hub->ports + portno - 1);
446
447 /* first clear the port suspend change bit */
448
449 err = usb2_req_clear_port_feature
450 (udev, &Giant, portno, UHF_C_PORT_SUSPEND);
451
452 if (err) {
453 goto done;
454 }
455 /* get fresh status */
456
457 err = uhub_read_port_status(sc, portno);
458 if (err) {
459 goto done;
460 }
461 /* get current state */
462
463 if (sc->sc_st.port_status & UPS_SUSPEND) {
464 is_suspend = 1;
465 } else {
466 is_suspend = 0;
467 }
468 /* do the suspend or resume */
469
470 if (child) {
471 sx_xlock(child->default_sx + 1);
472 err = usb2_suspend_resume(child, is_suspend);
473 sx_unlock(child->default_sx + 1);
474 }
475done:
476 return (err);
477}
478
479/*------------------------------------------------------------------------*
480 * uhub_explore
481 *
482 * Returns:
483 * 0: Success
484 * Else: Failure
485 *------------------------------------------------------------------------*/
486static usb2_error_t
487uhub_explore(struct usb2_device *udev)
488{
489 struct usb2_hub *hub;
490 struct uhub_softc *sc;
491 struct usb2_port *up;
492 usb2_error_t err;
493 uint8_t portno;
494 uint8_t x;
495
496 hub = udev->hub;
497 sc = hub->hubsoftc;
498
499 DPRINTFN(11, "udev=%p addr=%d\n", udev, udev->address);
500
501 /* ignore hubs that are too deep */
502 if (udev->depth > USB_HUB_MAX_DEPTH) {
503 return (USB_ERR_TOO_DEEP);
504 }
505 for (x = 0; x != hub->nports; x++) {
506 up = hub->ports + x;
507 portno = x + 1;
508
509 err = uhub_read_port_status(sc, portno);
510 if (err) {
511 /* most likely the HUB is gone */
512 break;
513 }
514 if (sc->sc_st.port_change & UPS_C_PORT_ENABLED) {
515 err = usb2_req_clear_port_feature(
516 udev, &Giant, portno, UHF_C_PORT_ENABLE);
517 if (err) {
518 /* most likely the HUB is gone */
519 break;
520 }
521 if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) {
522 /*
523 * Ignore the port error if the device
524 * has vanished !
525 */
526 } else if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
527 DPRINTFN(0, "illegal enable change, "
528 "port %d\n", portno);
529 } else {
530
531 if (up->restartcnt == USB_RESTART_MAX) {
532 /* XXX could try another speed ? */
533 DPRINTFN(0, "port error, giving up "
534 "port %d\n", portno);
535 } else {
536 sc->sc_st.port_change |= UPS_C_CONNECT_STATUS;
537 up->restartcnt++;
538 }
539 }
540 }
541 if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) {
542 err = uhub_reattach_port(sc, portno);
543 if (err) {
544 /* most likely the HUB is gone */
545 break;
546 }
547 }
548 if (sc->sc_st.port_change & UPS_C_SUSPEND) {
549 err = uhub_suspend_resume_port(sc, portno);
550 if (err) {
551 /* most likely the HUB is gone */
552 break;
553 }
554 }
555 err = uhub_explore_sub(sc, up);
556 if (err) {
557 /* no device(s) present */
558 continue;
559 }
560 /* explore succeeded - reset restart counter */
561 up->restartcnt = 0;
562 }
563 return (USB_ERR_NORMAL_COMPLETION);
564}
565
566static int
567uhub_probe(device_t dev)
568{
569 struct usb2_attach_arg *uaa = device_get_ivars(dev);
570
571 if (uaa->usb2_mode != USB_MODE_HOST) {
572 return (ENXIO);
573 }
574 /*
575 * The subclass for USB HUBs is ignored because it is 0 for
576 * some and 1 for others.
577 */
578 if ((uaa->info.bConfigIndex == 0) &&
579 (uaa->info.bDeviceClass == UDCLASS_HUB)) {
580 return (0);
581 }
582 return (ENXIO);
583}
584
585static int
586uhub_attach(device_t dev)
587{
588 struct uhub_softc *sc = device_get_softc(dev);
589 struct usb2_attach_arg *uaa = device_get_ivars(dev);
590 struct usb2_device *udev = uaa->device;
591 struct usb2_device *parent_hub = udev->parent_hub;
592 struct usb2_hub *hub;
593 struct usb2_hub_descriptor hubdesc;
594 uint16_t pwrdly;
595 uint8_t x;
596 uint8_t nports;
597 uint8_t portno;
598 uint8_t removable;
599 uint8_t iface_index;
600 usb2_error_t err;
601
602 if (sc == NULL) {
603 return (ENOMEM);
604 }
605 sc->sc_udev = udev;
606 sc->sc_dev = dev;
607
608 snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
609 device_get_nameunit(dev));
610
611 device_set_usb2_desc(dev);
612
613 DPRINTFN(2, "depth=%d selfpowered=%d, parent=%p, "
614 "parent->selfpowered=%d\n",
615 udev->depth,
616 udev->flags.self_powered,
617 parent_hub,
618 parent_hub ?
619 parent_hub->flags.self_powered : 0);
620
621 if (udev->depth > USB_HUB_MAX_DEPTH) {
622 DPRINTFN(0, "hub depth, %d, exceeded. HUB ignored!\n",
623 USB_HUB_MAX_DEPTH);
624 goto error;
625 }
626 if (!udev->flags.self_powered && parent_hub &&
627 (!parent_hub->flags.self_powered)) {
628 DPRINTFN(0, "bus powered HUB connected to "
629 "bus powered HUB. HUB ignored!\n");
630 goto error;
631 }
632 /* get HUB descriptor */
633
634 DPRINTFN(2, "getting HUB descriptor\n");
635
636 /* assuming that there is one port */
637 err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, 1);
638
639 nports = hubdesc.bNbrPorts;
640
641 if (!err && (nports >= 8)) {
642 /* get complete HUB descriptor */
643 err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, nports);
644 }
645 if (err) {
646 DPRINTFN(0, "getting hub descriptor failed,"
647 "error=%s\n", usb2_errstr(err));
648 goto error;
649 }
650 if (hubdesc.bNbrPorts != nports) {
651 DPRINTFN(0, "number of ports changed!\n");
652 goto error;
653 }
654 if (nports == 0) {
655 DPRINTFN(0, "portless HUB!\n");
656 goto error;
657 }
658 hub = malloc(sizeof(hub[0]) + (sizeof(hub->ports[0]) * nports),
659 M_USBDEV, M_WAITOK | M_ZERO);
660
661 if (hub == NULL) {
662 goto error;
663 }
664 udev->hub = hub;
665
666 /* init FULL-speed ISOCHRONOUS schedule */
667 usb2_fs_isoc_schedule_init_all(hub->fs_isoc_schedule);
668
669 /* initialize HUB structure */
670 hub->hubsoftc = sc;
671 hub->explore = &uhub_explore;
672 hub->nports = hubdesc.bNbrPorts;
673 hub->hubudev = udev;
674
675 /* if self powered hub, give ports maximum current */
676 if (udev->flags.self_powered) {
677 hub->portpower = USB_MAX_POWER;
678 } else {
679 hub->portpower = USB_MIN_POWER;
680 }
681
682 /* set up interrupt pipe */
683 iface_index = 0;
684 err = usb2_transfer_setup(udev, &iface_index, sc->sc_xfer,
685 uhub_config, 2, sc, &Giant);
686 if (err) {
687 DPRINTFN(0, "cannot setup interrupt transfer, "
688 "errstr=%s!\n", usb2_errstr(err));
689 goto error;
690 }
691 /* wait with power off for a while */
692 usb2_pause_mtx(&Giant, USB_POWER_DOWN_TIME);
693
694 /*
695 * To have the best chance of success we do things in the exact same
696 * order as Windoze98. This should not be necessary, but some
697 * devices do not follow the USB specs to the letter.
698 *
699 * These are the events on the bus when a hub is attached:
700 * Get device and config descriptors (see attach code)
701 * Get hub descriptor (see above)
702 * For all ports
703 * turn on power
704 * wait for power to become stable
705 * (all below happens in explore code)
706 * For all ports
707 * clear C_PORT_CONNECTION
708 * For all ports
709 * get port status
710 * if device connected
711 * wait 100 ms
712 * turn on reset
713 * wait
714 * clear C_PORT_RESET
715 * get port status
716 * proceed with device attachment
717 */
718
719 /* XXX should check for none, individual, or ganged power? */
720
721 removable = 0;
722 pwrdly = ((hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
723 USB_EXTRA_POWER_UP_TIME);
724
725 for (x = 0; x != nports; x++) {
726 /* set up data structures */
727 struct usb2_port *up = hub->ports + x;
728
729 up->device_index = 0;
730 up->restartcnt = 0;
731 portno = x + 1;
732
733 /* check if port is removable */
734 if (!UHD_NOT_REMOV(&hubdesc, portno)) {
735 removable++;
736 }
737 if (!err) {
738 /* turn the power on */
739 err = usb2_req_set_port_feature
740 (udev, &Giant, portno, UHF_PORT_POWER);
741 }
742 if (err) {
743 DPRINTFN(0, "port %d power on failed, %s\n",
744 portno, usb2_errstr(err));
745 }
746 DPRINTF("turn on port %d power\n",
747 portno);
748
749 /* wait for stable power */
750 usb2_pause_mtx(&Giant, pwrdly);
751 }
752
753 device_printf(dev, "%d port%s with %d "
754 "removable, %s powered\n", nports, (nports != 1) ? "s" : "",
755 removable, udev->flags.self_powered ? "self" : "bus");
756
757 /* start the interrupt endpoint */
758
2/*-
3 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
4 * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
5 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29/*
30 * USB spec: http://www.usb.org/developers/docs/usbspec.zip
31 */
32
33#include <dev/usb2/include/usb2_defs.h>
34#include <dev/usb2/include/usb2_mfunc.h>
35#include <dev/usb2/include/usb2_error.h>
36#include <dev/usb2/include/usb2_standard.h>
37
38#define USB_DEBUG_VAR uhub_debug
39
40#include <dev/usb2/core/usb2_core.h>
41#include <dev/usb2/core/usb2_process.h>
42#include <dev/usb2/core/usb2_device.h>
43#include <dev/usb2/core/usb2_request.h>
44#include <dev/usb2/core/usb2_debug.h>
45#include <dev/usb2/core/usb2_hub.h>
46#include <dev/usb2/core/usb2_util.h>
47#include <dev/usb2/core/usb2_busdma.h>
48#include <dev/usb2/core/usb2_transfer.h>
49#include <dev/usb2/core/usb2_dynamic.h>
50
51#include <dev/usb2/controller/usb2_controller.h>
52#include <dev/usb2/controller/usb2_bus.h>
53
54#define UHUB_INTR_INTERVAL 250 /* ms */
55
56#if USB_DEBUG
57static int uhub_debug = 0;
58
59SYSCTL_NODE(_hw_usb2, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB HUB");
60SYSCTL_INT(_hw_usb2_uhub, OID_AUTO, debug, CTLFLAG_RW, &uhub_debug, 0,
61 "Debug level");
62#endif
63
64struct uhub_current_state {
65 uint16_t port_change;
66 uint16_t port_status;
67};
68
69struct uhub_softc {
70 struct uhub_current_state sc_st;/* current state */
71 device_t sc_dev; /* base device */
72 struct usb2_device *sc_udev; /* USB device */
73 struct usb2_xfer *sc_xfer[2]; /* interrupt xfer */
74 uint8_t sc_flags;
75#define UHUB_FLAG_INTR_STALL 0x02
76 char sc_name[32];
77};
78
79#define UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol)
80#define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
81#define UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
82
83/* prototypes for type checking: */
84
85static device_probe_t uhub_probe;
86static device_attach_t uhub_attach;
87static device_detach_t uhub_detach;
88
89static bus_driver_added_t uhub_driver_added;
90static bus_child_location_str_t uhub_child_location_string;
91static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string;
92
93static usb2_callback_t uhub_intr_callback;
94static usb2_callback_t uhub_intr_clear_stall_callback;
95
96static const struct usb2_config uhub_config[2] = {
97
98 [0] = {
99 .type = UE_INTERRUPT,
100 .endpoint = UE_ADDR_ANY,
101 .direction = UE_DIR_ANY,
102 .mh.timeout = 0,
103 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
104 .mh.bufsize = 0, /* use wMaxPacketSize */
105 .mh.callback = &uhub_intr_callback,
106 .mh.interval = UHUB_INTR_INTERVAL,
107 },
108
109 [1] = {
110 .type = UE_CONTROL,
111 .endpoint = 0,
112 .direction = UE_DIR_ANY,
113 .mh.timeout = 1000, /* 1 second */
114 .mh.interval = 50, /* 50ms */
115 .mh.flags = {},
116 .mh.bufsize = sizeof(struct usb2_device_request),
117 .mh.callback = &uhub_intr_clear_stall_callback,
118 },
119};
120
121/*
122 * driver instance for "hub" connected to "usb"
123 * and "hub" connected to "hub"
124 */
125static devclass_t uhub_devclass;
126
127static driver_t uhub_driver =
128{
129 .name = "ushub",
130 .methods = (device_method_t[]){
131 DEVMETHOD(device_probe, uhub_probe),
132 DEVMETHOD(device_attach, uhub_attach),
133 DEVMETHOD(device_detach, uhub_detach),
134
135 DEVMETHOD(device_suspend, bus_generic_suspend),
136 DEVMETHOD(device_resume, bus_generic_resume),
137 DEVMETHOD(device_shutdown, bus_generic_shutdown),
138
139 DEVMETHOD(bus_child_location_str, uhub_child_location_string),
140 DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string),
141 DEVMETHOD(bus_driver_added, uhub_driver_added),
142 {0, 0}
143 },
144 .size = sizeof(struct uhub_softc)
145};
146
147DRIVER_MODULE(ushub, usbus, uhub_driver, uhub_devclass, 0, 0);
148DRIVER_MODULE(ushub, ushub, uhub_driver, uhub_devclass, NULL, 0);
149
150static void
151uhub_intr_clear_stall_callback(struct usb2_xfer *xfer)
152{
153 struct uhub_softc *sc = xfer->priv_sc;
154 struct usb2_xfer *xfer_other = sc->sc_xfer[0];
155
156 if (usb2_clear_stall_callback(xfer, xfer_other)) {
157 DPRINTF("stall cleared\n");
158 sc->sc_flags &= ~UHUB_FLAG_INTR_STALL;
159 usb2_transfer_start(xfer_other);
160 }
161 return;
162}
163
164static void
165uhub_intr_callback(struct usb2_xfer *xfer)
166{
167 struct uhub_softc *sc = xfer->priv_sc;
168
169 switch (USB_GET_STATE(xfer)) {
170 case USB_ST_TRANSFERRED:
171 DPRINTFN(2, "\n");
172 /*
173 * This is an indication that some port
174 * has changed status. Notify the bus
175 * event handler thread that we need
176 * to be explored again:
177 */
178 usb2_needs_explore(sc->sc_udev->bus, 0);
179
180 case USB_ST_SETUP:
181 if (sc->sc_flags & UHUB_FLAG_INTR_STALL) {
182 usb2_transfer_start(sc->sc_xfer[1]);
183 } else {
184 xfer->frlengths[0] = xfer->max_data_length;
185 usb2_start_hardware(xfer);
186 }
187 return;
188
189 default: /* Error */
190 if (xfer->error != USB_ERR_CANCELLED) {
191 /* start clear stall */
192 sc->sc_flags |= UHUB_FLAG_INTR_STALL;
193 usb2_transfer_start(sc->sc_xfer[1]);
194 }
195 return;
196 }
197}
198
199/*------------------------------------------------------------------------*
200 * uhub_explore_sub - subroutine
201 *
202 * Return values:
203 * 0: Success
204 * Else: A control transaction failed
205 *------------------------------------------------------------------------*/
206static usb2_error_t
207uhub_explore_sub(struct uhub_softc *sc, struct usb2_port *up)
208{
209 struct usb2_bus *bus;
210 struct usb2_device *child;
211 uint8_t refcount;
212 usb2_error_t err;
213
214 bus = sc->sc_udev->bus;
215 err = 0;
216
217 /* get driver added refcount from USB bus */
218 refcount = bus->driver_added_refcount;
219
220 /* get device assosiated with the given port */
221 child = usb2_bus_port_get_device(bus, up);
222 if (child == NULL) {
223 /* nothing to do */
224 goto done;
225 }
226 /* check if probe and attach should be done */
227
228 if (child->driver_added_refcount != refcount) {
229 child->driver_added_refcount = refcount;
230 err = usb2_probe_and_attach(child,
231 USB_IFACE_INDEX_ANY);
232 if (err) {
233 goto done;
234 }
235 }
236 /* start control transfer, if device mode */
237
238 if (child->flags.usb2_mode == USB_MODE_DEVICE) {
239 usb2_default_transfer_setup(child);
240 }
241 /* if a HUB becomes present, do a recursive HUB explore */
242
243 if (child->hub) {
244 err = (child->hub->explore) (child);
245 }
246done:
247 return (err);
248}
249
250/*------------------------------------------------------------------------*
251 * uhub_read_port_status - factored out code
252 *------------------------------------------------------------------------*/
253static usb2_error_t
254uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
255{
256 struct usb2_port_status ps;
257 usb2_error_t err;
258
259 err = usb2_req_get_port_status(
260 sc->sc_udev, &Giant, &ps, portno);
261
262 /* update status regardless of error */
263
264 sc->sc_st.port_status = UGETW(ps.wPortStatus);
265 sc->sc_st.port_change = UGETW(ps.wPortChange);
266
267 /* debugging print */
268
269 DPRINTFN(4, "port %d, wPortStatus=0x%04x, "
270 "wPortChange=0x%04x, err=%s\n",
271 portno, sc->sc_st.port_status,
272 sc->sc_st.port_change, usb2_errstr(err));
273 return (err);
274}
275
276/*------------------------------------------------------------------------*
277 * uhub_reattach_port
278 *
279 * Returns:
280 * 0: Success
281 * Else: A control transaction failed
282 *------------------------------------------------------------------------*/
283static usb2_error_t
284uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
285{
286 struct usb2_device *child;
287 struct usb2_device *udev;
288 usb2_error_t err;
289 uint8_t timeout;
290 uint8_t speed;
291 uint8_t usb2_mode;
292
293 DPRINTF("reattaching port %d\n", portno);
294
295 err = 0;
296 timeout = 0;
297 udev = sc->sc_udev;
298 child = usb2_bus_port_get_device(udev->bus,
299 udev->hub->ports + portno - 1);
300
301repeat:
302
303 /* first clear the port connection change bit */
304
305 err = usb2_req_clear_port_feature
306 (udev, &Giant, portno, UHF_C_PORT_CONNECTION);
307
308 if (err) {
309 goto error;
310 }
311 /* detach any existing devices */
312
313 if (child) {
314 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 1);
315 usb2_free_device(child);
316 child = NULL;
317 }
318 /* get fresh status */
319
320 err = uhub_read_port_status(sc, portno);
321 if (err) {
322 goto error;
323 }
324 /* check if nothing is connected to the port */
325
326 if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS)) {
327 goto error;
328 }
329 /* check if there is no power on the port and print a warning */
330
331 if (!(sc->sc_st.port_status & UPS_PORT_POWER)) {
332 DPRINTF("WARNING: strange, connected port %d "
333 "has no power\n", portno);
334 }
335 /* check if the device is in Host Mode */
336
337 if (!(sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)) {
338
339 DPRINTF("Port %d is in Host Mode\n", portno);
340
341 /* USB Host Mode */
342
343 /* wait for maximum device power up time */
344
345 usb2_pause_mtx(&Giant, USB_PORT_POWERUP_DELAY);
346
347 /* reset port, which implies enabling it */
348
349 err = usb2_req_reset_port
350 (udev, &Giant, portno);
351
352 if (err) {
353 DPRINTFN(0, "port %d reset "
354 "failed, error=%s\n",
355 portno, usb2_errstr(err));
356 goto error;
357 }
358 /* get port status again, it might have changed during reset */
359
360 err = uhub_read_port_status(sc, portno);
361 if (err) {
362 goto error;
363 }
364 /* check if something changed during port reset */
365
366 if ((sc->sc_st.port_change & UPS_C_CONNECT_STATUS) ||
367 (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS))) {
368 if (timeout) {
369 DPRINTFN(0, "giving up port reset "
370 "- device vanished!\n");
371 goto error;
372 }
373 timeout = 1;
374 goto repeat;
375 }
376 } else {
377 DPRINTF("Port %d is in Device Mode\n", portno);
378 }
379
380 /*
381 * Figure out the device speed
382 */
383 speed =
384 (sc->sc_st.port_status & UPS_HIGH_SPEED) ? USB_SPEED_HIGH :
385 (sc->sc_st.port_status & UPS_LOW_SPEED) ? USB_SPEED_LOW : USB_SPEED_FULL;
386
387 /*
388 * Figure out the device mode
389 *
390 * NOTE: This part is currently FreeBSD specific.
391 */
392 usb2_mode =
393 (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) ?
394 USB_MODE_DEVICE : USB_MODE_HOST;
395
396 /* need to create a new child */
397
398 child = usb2_alloc_device(sc->sc_dev, udev->bus, udev,
399 udev->depth + 1, portno - 1, portno, speed, usb2_mode);
400 if (child == NULL) {
401 DPRINTFN(0, "could not allocate new device!\n");
402 goto error;
403 }
404 return (0); /* success */
405
406error:
407 if (child) {
408 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 1);
409 usb2_free_device(child);
410 child = NULL;
411 }
412 if (err == 0) {
413 if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
414 err = usb2_req_clear_port_feature
415 (sc->sc_udev, &Giant,
416 portno, UHF_PORT_ENABLE);
417 }
418 }
419 if (err) {
420 DPRINTFN(0, "device problem (%s), "
421 "disabling port %d\n", usb2_errstr(err), portno);
422 }
423 return (err);
424}
425
426/*------------------------------------------------------------------------*
427 * uhub_suspend_resume_port
428 *
429 * Returns:
430 * 0: Success
431 * Else: A control transaction failed
432 *------------------------------------------------------------------------*/
433static usb2_error_t
434uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno)
435{
436 struct usb2_device *child;
437 struct usb2_device *udev;
438 uint8_t is_suspend;
439 usb2_error_t err;
440
441 DPRINTF("port %d\n", portno);
442
443 udev = sc->sc_udev;
444 child = usb2_bus_port_get_device(udev->bus,
445 udev->hub->ports + portno - 1);
446
447 /* first clear the port suspend change bit */
448
449 err = usb2_req_clear_port_feature
450 (udev, &Giant, portno, UHF_C_PORT_SUSPEND);
451
452 if (err) {
453 goto done;
454 }
455 /* get fresh status */
456
457 err = uhub_read_port_status(sc, portno);
458 if (err) {
459 goto done;
460 }
461 /* get current state */
462
463 if (sc->sc_st.port_status & UPS_SUSPEND) {
464 is_suspend = 1;
465 } else {
466 is_suspend = 0;
467 }
468 /* do the suspend or resume */
469
470 if (child) {
471 sx_xlock(child->default_sx + 1);
472 err = usb2_suspend_resume(child, is_suspend);
473 sx_unlock(child->default_sx + 1);
474 }
475done:
476 return (err);
477}
478
479/*------------------------------------------------------------------------*
480 * uhub_explore
481 *
482 * Returns:
483 * 0: Success
484 * Else: Failure
485 *------------------------------------------------------------------------*/
486static usb2_error_t
487uhub_explore(struct usb2_device *udev)
488{
489 struct usb2_hub *hub;
490 struct uhub_softc *sc;
491 struct usb2_port *up;
492 usb2_error_t err;
493 uint8_t portno;
494 uint8_t x;
495
496 hub = udev->hub;
497 sc = hub->hubsoftc;
498
499 DPRINTFN(11, "udev=%p addr=%d\n", udev, udev->address);
500
501 /* ignore hubs that are too deep */
502 if (udev->depth > USB_HUB_MAX_DEPTH) {
503 return (USB_ERR_TOO_DEEP);
504 }
505 for (x = 0; x != hub->nports; x++) {
506 up = hub->ports + x;
507 portno = x + 1;
508
509 err = uhub_read_port_status(sc, portno);
510 if (err) {
511 /* most likely the HUB is gone */
512 break;
513 }
514 if (sc->sc_st.port_change & UPS_C_PORT_ENABLED) {
515 err = usb2_req_clear_port_feature(
516 udev, &Giant, portno, UHF_C_PORT_ENABLE);
517 if (err) {
518 /* most likely the HUB is gone */
519 break;
520 }
521 if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) {
522 /*
523 * Ignore the port error if the device
524 * has vanished !
525 */
526 } else if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
527 DPRINTFN(0, "illegal enable change, "
528 "port %d\n", portno);
529 } else {
530
531 if (up->restartcnt == USB_RESTART_MAX) {
532 /* XXX could try another speed ? */
533 DPRINTFN(0, "port error, giving up "
534 "port %d\n", portno);
535 } else {
536 sc->sc_st.port_change |= UPS_C_CONNECT_STATUS;
537 up->restartcnt++;
538 }
539 }
540 }
541 if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) {
542 err = uhub_reattach_port(sc, portno);
543 if (err) {
544 /* most likely the HUB is gone */
545 break;
546 }
547 }
548 if (sc->sc_st.port_change & UPS_C_SUSPEND) {
549 err = uhub_suspend_resume_port(sc, portno);
550 if (err) {
551 /* most likely the HUB is gone */
552 break;
553 }
554 }
555 err = uhub_explore_sub(sc, up);
556 if (err) {
557 /* no device(s) present */
558 continue;
559 }
560 /* explore succeeded - reset restart counter */
561 up->restartcnt = 0;
562 }
563 return (USB_ERR_NORMAL_COMPLETION);
564}
565
566static int
567uhub_probe(device_t dev)
568{
569 struct usb2_attach_arg *uaa = device_get_ivars(dev);
570
571 if (uaa->usb2_mode != USB_MODE_HOST) {
572 return (ENXIO);
573 }
574 /*
575 * The subclass for USB HUBs is ignored because it is 0 for
576 * some and 1 for others.
577 */
578 if ((uaa->info.bConfigIndex == 0) &&
579 (uaa->info.bDeviceClass == UDCLASS_HUB)) {
580 return (0);
581 }
582 return (ENXIO);
583}
584
585static int
586uhub_attach(device_t dev)
587{
588 struct uhub_softc *sc = device_get_softc(dev);
589 struct usb2_attach_arg *uaa = device_get_ivars(dev);
590 struct usb2_device *udev = uaa->device;
591 struct usb2_device *parent_hub = udev->parent_hub;
592 struct usb2_hub *hub;
593 struct usb2_hub_descriptor hubdesc;
594 uint16_t pwrdly;
595 uint8_t x;
596 uint8_t nports;
597 uint8_t portno;
598 uint8_t removable;
599 uint8_t iface_index;
600 usb2_error_t err;
601
602 if (sc == NULL) {
603 return (ENOMEM);
604 }
605 sc->sc_udev = udev;
606 sc->sc_dev = dev;
607
608 snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
609 device_get_nameunit(dev));
610
611 device_set_usb2_desc(dev);
612
613 DPRINTFN(2, "depth=%d selfpowered=%d, parent=%p, "
614 "parent->selfpowered=%d\n",
615 udev->depth,
616 udev->flags.self_powered,
617 parent_hub,
618 parent_hub ?
619 parent_hub->flags.self_powered : 0);
620
621 if (udev->depth > USB_HUB_MAX_DEPTH) {
622 DPRINTFN(0, "hub depth, %d, exceeded. HUB ignored!\n",
623 USB_HUB_MAX_DEPTH);
624 goto error;
625 }
626 if (!udev->flags.self_powered && parent_hub &&
627 (!parent_hub->flags.self_powered)) {
628 DPRINTFN(0, "bus powered HUB connected to "
629 "bus powered HUB. HUB ignored!\n");
630 goto error;
631 }
632 /* get HUB descriptor */
633
634 DPRINTFN(2, "getting HUB descriptor\n");
635
636 /* assuming that there is one port */
637 err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, 1);
638
639 nports = hubdesc.bNbrPorts;
640
641 if (!err && (nports >= 8)) {
642 /* get complete HUB descriptor */
643 err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, nports);
644 }
645 if (err) {
646 DPRINTFN(0, "getting hub descriptor failed,"
647 "error=%s\n", usb2_errstr(err));
648 goto error;
649 }
650 if (hubdesc.bNbrPorts != nports) {
651 DPRINTFN(0, "number of ports changed!\n");
652 goto error;
653 }
654 if (nports == 0) {
655 DPRINTFN(0, "portless HUB!\n");
656 goto error;
657 }
658 hub = malloc(sizeof(hub[0]) + (sizeof(hub->ports[0]) * nports),
659 M_USBDEV, M_WAITOK | M_ZERO);
660
661 if (hub == NULL) {
662 goto error;
663 }
664 udev->hub = hub;
665
666 /* init FULL-speed ISOCHRONOUS schedule */
667 usb2_fs_isoc_schedule_init_all(hub->fs_isoc_schedule);
668
669 /* initialize HUB structure */
670 hub->hubsoftc = sc;
671 hub->explore = &uhub_explore;
672 hub->nports = hubdesc.bNbrPorts;
673 hub->hubudev = udev;
674
675 /* if self powered hub, give ports maximum current */
676 if (udev->flags.self_powered) {
677 hub->portpower = USB_MAX_POWER;
678 } else {
679 hub->portpower = USB_MIN_POWER;
680 }
681
682 /* set up interrupt pipe */
683 iface_index = 0;
684 err = usb2_transfer_setup(udev, &iface_index, sc->sc_xfer,
685 uhub_config, 2, sc, &Giant);
686 if (err) {
687 DPRINTFN(0, "cannot setup interrupt transfer, "
688 "errstr=%s!\n", usb2_errstr(err));
689 goto error;
690 }
691 /* wait with power off for a while */
692 usb2_pause_mtx(&Giant, USB_POWER_DOWN_TIME);
693
694 /*
695 * To have the best chance of success we do things in the exact same
696 * order as Windoze98. This should not be necessary, but some
697 * devices do not follow the USB specs to the letter.
698 *
699 * These are the events on the bus when a hub is attached:
700 * Get device and config descriptors (see attach code)
701 * Get hub descriptor (see above)
702 * For all ports
703 * turn on power
704 * wait for power to become stable
705 * (all below happens in explore code)
706 * For all ports
707 * clear C_PORT_CONNECTION
708 * For all ports
709 * get port status
710 * if device connected
711 * wait 100 ms
712 * turn on reset
713 * wait
714 * clear C_PORT_RESET
715 * get port status
716 * proceed with device attachment
717 */
718
719 /* XXX should check for none, individual, or ganged power? */
720
721 removable = 0;
722 pwrdly = ((hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
723 USB_EXTRA_POWER_UP_TIME);
724
725 for (x = 0; x != nports; x++) {
726 /* set up data structures */
727 struct usb2_port *up = hub->ports + x;
728
729 up->device_index = 0;
730 up->restartcnt = 0;
731 portno = x + 1;
732
733 /* check if port is removable */
734 if (!UHD_NOT_REMOV(&hubdesc, portno)) {
735 removable++;
736 }
737 if (!err) {
738 /* turn the power on */
739 err = usb2_req_set_port_feature
740 (udev, &Giant, portno, UHF_PORT_POWER);
741 }
742 if (err) {
743 DPRINTFN(0, "port %d power on failed, %s\n",
744 portno, usb2_errstr(err));
745 }
746 DPRINTF("turn on port %d power\n",
747 portno);
748
749 /* wait for stable power */
750 usb2_pause_mtx(&Giant, pwrdly);
751 }
752
753 device_printf(dev, "%d port%s with %d "
754 "removable, %s powered\n", nports, (nports != 1) ? "s" : "",
755 removable, udev->flags.self_powered ? "self" : "bus");
756
757 /* start the interrupt endpoint */
758
759 mtx_lock(sc->sc_xfer[0]->priv_mtx);
759 USB_XFER_LOCK(sc->sc_xfer[0]);
760 usb2_transfer_start(sc->sc_xfer[0]);
760 usb2_transfer_start(sc->sc_xfer[0]);
761 mtx_unlock(sc->sc_xfer[0]->priv_mtx);
761 USB_XFER_UNLOCK(sc->sc_xfer[0]);
762
763 return (0);
764
765error:
766 usb2_transfer_unsetup(sc->sc_xfer, 2);
767
768 if (udev->hub) {
769 free(udev->hub, M_USBDEV);
770 udev->hub = NULL;
771 }
772 return (ENXIO);
773}
774
775/*
776 * Called from process context when the hub is gone.
777 * Detach all devices on active ports.
778 */
779static int
780uhub_detach(device_t dev)
781{
782 struct uhub_softc *sc = device_get_softc(dev);
783 struct usb2_hub *hub = sc->sc_udev->hub;
784 struct usb2_device *child;
785 uint8_t x;
786
787 /* detach all children first */
788 bus_generic_detach(dev);
789
790 if (hub == NULL) { /* must be partially working */
791 return (0);
792 }
793 for (x = 0; x != hub->nports; x++) {
794
795 child = usb2_bus_port_get_device(sc->sc_udev->bus, hub->ports + x);
796
797 if (child == NULL) {
798 continue;
799 }
800 /*
801 * Subdevices are not freed, because the caller of
802 * uhub_detach() will do that.
803 */
804 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 0);
805 usb2_free_device(child);
806 child = NULL;
807 }
808
809 usb2_transfer_unsetup(sc->sc_xfer, 2);
810
811 free(hub, M_USBDEV);
812 sc->sc_udev->hub = NULL;
813 return (0);
814}
815
816static void
817uhub_driver_added(device_t dev, driver_t *driver)
818{
819 usb2_needs_explore_all();
820 return;
821}
822
823struct hub_result {
824 struct usb2_device *udev;
825 uint8_t portno;
826 uint8_t iface_index;
827};
828
829static void
830uhub_find_iface_index(struct usb2_hub *hub, device_t child,
831 struct hub_result *res)
832{
833 struct usb2_interface *iface;
834 struct usb2_device *udev;
835 uint8_t nports;
836 uint8_t x;
837 uint8_t i;
838
839 nports = hub->nports;
840 for (x = 0; x != nports; x++) {
841 udev = usb2_bus_port_get_device(hub->hubudev->bus,
842 hub->ports + x);
843 if (!udev) {
844 continue;
845 }
846 for (i = 0; i != USB_IFACE_MAX; i++) {
847 iface = usb2_get_iface(udev, i);
848 if (iface &&
849 (iface->subdev == child)) {
850 res->iface_index = i;
851 res->udev = udev;
852 res->portno = x + 1;
853 return;
854 }
855 }
856 }
857 res->iface_index = 0;
858 res->udev = NULL;
859 res->portno = 0;
860 return;
861}
862
863static int
864uhub_child_location_string(device_t parent, device_t child,
865 char *buf, size_t buflen)
866{
867 struct uhub_softc *sc = device_get_softc(parent);
868 struct usb2_hub *hub = sc->sc_udev->hub;
869 struct hub_result res;
870
871 mtx_lock(&Giant);
872 uhub_find_iface_index(hub, child, &res);
873 if (!res.udev) {
874 DPRINTF("device not on hub\n");
875 if (buflen) {
876 buf[0] = '\0';
877 }
878 goto done;
879 }
880 snprintf(buf, buflen, "port=%u interface=%u",
881 res.portno, res.iface_index);
882done:
883 mtx_unlock(&Giant);
884
885 return (0);
886}
887
888static int
889uhub_child_pnpinfo_string(device_t parent, device_t child,
890 char *buf, size_t buflen)
891{
892 struct uhub_softc *sc = device_get_softc(parent);
893 struct usb2_hub *hub = sc->sc_udev->hub;
894 struct usb2_interface *iface;
895 struct hub_result res;
896
897 mtx_lock(&Giant);
898 uhub_find_iface_index(hub, child, &res);
899 if (!res.udev) {
900 DPRINTF("device not on hub\n");
901 if (buflen) {
902 buf[0] = '\0';
903 }
904 goto done;
905 }
906 iface = usb2_get_iface(res.udev, res.iface_index);
907 if (iface && iface->idesc) {
908 snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
909 "devclass=0x%02x devsubclass=0x%02x "
910 "sernum=\"%s\" "
911 "intclass=0x%02x intsubclass=0x%02x",
912 UGETW(res.udev->ddesc.idVendor),
913 UGETW(res.udev->ddesc.idProduct),
914 res.udev->ddesc.bDeviceClass,
915 res.udev->ddesc.bDeviceSubClass,
916 res.udev->serial,
917 iface->idesc->bInterfaceClass,
918 iface->idesc->bInterfaceSubClass);
919 } else {
920 if (buflen) {
921 buf[0] = '\0';
922 }
923 goto done;
924 }
925done:
926 mtx_unlock(&Giant);
927
928 return (0);
929}
930
931/*
932 * The USB Transaction Translator:
933 * ===============================
934 *
935 * When doing LOW- and FULL-speed USB transfers accross a HIGH-speed
936 * USB HUB, bandwidth must be allocated for ISOCHRONOUS and INTERRUPT
937 * USB transfers. To utilize bandwidth dynamically the "scatter and
938 * gather" principle must be applied. This means that bandwidth must
939 * be divided into equal parts of bandwidth. With regard to USB all
940 * data is transferred in smaller packets with length
941 * "wMaxPacketSize". The problem however is that "wMaxPacketSize" is
942 * not a constant!
943 *
944 * The bandwidth scheduler which I have implemented will simply pack
945 * the USB transfers back to back until there is no more space in the
946 * schedule. Out of the 8 microframes which the USB 2.0 standard
947 * provides, only 6 are available for non-HIGH-speed devices. I have
948 * reserved the first 4 microframes for ISOCHRONOUS transfers. The
949 * last 2 microframes I have reserved for INTERRUPT transfers. Without
950 * this division, it is very difficult to allocate and free bandwidth
951 * dynamically.
952 *
953 * NOTE about the Transaction Translator in USB HUBs:
954 *
955 * USB HUBs have a very simple Transaction Translator, that will
956 * simply pipeline all the SPLIT transactions. That means that the
957 * transactions will be executed in the order they are queued!
958 *
959 */
960
961/*------------------------------------------------------------------------*
962 * usb2_intr_find_best_slot
963 *
964 * Return value:
965 * The best Transaction Translation slot for an interrupt endpoint.
966 *------------------------------------------------------------------------*/
967static uint8_t
968usb2_intr_find_best_slot(uint32_t *ptr, uint8_t start, uint8_t end)
969{
970 uint32_t max = 0xffffffff;
971 uint8_t x;
972 uint8_t y;
973
974 y = 0;
975
976 /* find the last slot with lesser used bandwidth */
977
978 for (x = start; x < end; x++) {
979 if (max >= ptr[x]) {
980 max = ptr[x];
981 y = x;
982 }
983 }
984 return (y);
985}
986
987/*------------------------------------------------------------------------*
988 * usb2_intr_schedule_adjust
989 *
990 * This function will update the bandwith usage for the microframe
991 * having index "slot" by "len" bytes. "len" can be negative. If the
992 * "slot" argument is greater or equal to "USB_HS_MICRO_FRAMES_MAX"
993 * the "slot" argument will be replaced by the slot having least used
994 * bandwidth.
995 *
996 * Returns:
997 * The slot on which the bandwidth update was done.
998 *------------------------------------------------------------------------*/
999uint8_t
1000usb2_intr_schedule_adjust(struct usb2_device *udev, int16_t len, uint8_t slot)
1001{
1002 struct usb2_bus *bus = udev->bus;
1003 struct usb2_hub *hub;
1004
762
763 return (0);
764
765error:
766 usb2_transfer_unsetup(sc->sc_xfer, 2);
767
768 if (udev->hub) {
769 free(udev->hub, M_USBDEV);
770 udev->hub = NULL;
771 }
772 return (ENXIO);
773}
774
775/*
776 * Called from process context when the hub is gone.
777 * Detach all devices on active ports.
778 */
779static int
780uhub_detach(device_t dev)
781{
782 struct uhub_softc *sc = device_get_softc(dev);
783 struct usb2_hub *hub = sc->sc_udev->hub;
784 struct usb2_device *child;
785 uint8_t x;
786
787 /* detach all children first */
788 bus_generic_detach(dev);
789
790 if (hub == NULL) { /* must be partially working */
791 return (0);
792 }
793 for (x = 0; x != hub->nports; x++) {
794
795 child = usb2_bus_port_get_device(sc->sc_udev->bus, hub->ports + x);
796
797 if (child == NULL) {
798 continue;
799 }
800 /*
801 * Subdevices are not freed, because the caller of
802 * uhub_detach() will do that.
803 */
804 usb2_detach_device(child, USB_IFACE_INDEX_ANY, 0);
805 usb2_free_device(child);
806 child = NULL;
807 }
808
809 usb2_transfer_unsetup(sc->sc_xfer, 2);
810
811 free(hub, M_USBDEV);
812 sc->sc_udev->hub = NULL;
813 return (0);
814}
815
816static void
817uhub_driver_added(device_t dev, driver_t *driver)
818{
819 usb2_needs_explore_all();
820 return;
821}
822
823struct hub_result {
824 struct usb2_device *udev;
825 uint8_t portno;
826 uint8_t iface_index;
827};
828
829static void
830uhub_find_iface_index(struct usb2_hub *hub, device_t child,
831 struct hub_result *res)
832{
833 struct usb2_interface *iface;
834 struct usb2_device *udev;
835 uint8_t nports;
836 uint8_t x;
837 uint8_t i;
838
839 nports = hub->nports;
840 for (x = 0; x != nports; x++) {
841 udev = usb2_bus_port_get_device(hub->hubudev->bus,
842 hub->ports + x);
843 if (!udev) {
844 continue;
845 }
846 for (i = 0; i != USB_IFACE_MAX; i++) {
847 iface = usb2_get_iface(udev, i);
848 if (iface &&
849 (iface->subdev == child)) {
850 res->iface_index = i;
851 res->udev = udev;
852 res->portno = x + 1;
853 return;
854 }
855 }
856 }
857 res->iface_index = 0;
858 res->udev = NULL;
859 res->portno = 0;
860 return;
861}
862
863static int
864uhub_child_location_string(device_t parent, device_t child,
865 char *buf, size_t buflen)
866{
867 struct uhub_softc *sc = device_get_softc(parent);
868 struct usb2_hub *hub = sc->sc_udev->hub;
869 struct hub_result res;
870
871 mtx_lock(&Giant);
872 uhub_find_iface_index(hub, child, &res);
873 if (!res.udev) {
874 DPRINTF("device not on hub\n");
875 if (buflen) {
876 buf[0] = '\0';
877 }
878 goto done;
879 }
880 snprintf(buf, buflen, "port=%u interface=%u",
881 res.portno, res.iface_index);
882done:
883 mtx_unlock(&Giant);
884
885 return (0);
886}
887
888static int
889uhub_child_pnpinfo_string(device_t parent, device_t child,
890 char *buf, size_t buflen)
891{
892 struct uhub_softc *sc = device_get_softc(parent);
893 struct usb2_hub *hub = sc->sc_udev->hub;
894 struct usb2_interface *iface;
895 struct hub_result res;
896
897 mtx_lock(&Giant);
898 uhub_find_iface_index(hub, child, &res);
899 if (!res.udev) {
900 DPRINTF("device not on hub\n");
901 if (buflen) {
902 buf[0] = '\0';
903 }
904 goto done;
905 }
906 iface = usb2_get_iface(res.udev, res.iface_index);
907 if (iface && iface->idesc) {
908 snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
909 "devclass=0x%02x devsubclass=0x%02x "
910 "sernum=\"%s\" "
911 "intclass=0x%02x intsubclass=0x%02x",
912 UGETW(res.udev->ddesc.idVendor),
913 UGETW(res.udev->ddesc.idProduct),
914 res.udev->ddesc.bDeviceClass,
915 res.udev->ddesc.bDeviceSubClass,
916 res.udev->serial,
917 iface->idesc->bInterfaceClass,
918 iface->idesc->bInterfaceSubClass);
919 } else {
920 if (buflen) {
921 buf[0] = '\0';
922 }
923 goto done;
924 }
925done:
926 mtx_unlock(&Giant);
927
928 return (0);
929}
930
931/*
932 * The USB Transaction Translator:
933 * ===============================
934 *
935 * When doing LOW- and FULL-speed USB transfers accross a HIGH-speed
936 * USB HUB, bandwidth must be allocated for ISOCHRONOUS and INTERRUPT
937 * USB transfers. To utilize bandwidth dynamically the "scatter and
938 * gather" principle must be applied. This means that bandwidth must
939 * be divided into equal parts of bandwidth. With regard to USB all
940 * data is transferred in smaller packets with length
941 * "wMaxPacketSize". The problem however is that "wMaxPacketSize" is
942 * not a constant!
943 *
944 * The bandwidth scheduler which I have implemented will simply pack
945 * the USB transfers back to back until there is no more space in the
946 * schedule. Out of the 8 microframes which the USB 2.0 standard
947 * provides, only 6 are available for non-HIGH-speed devices. I have
948 * reserved the first 4 microframes for ISOCHRONOUS transfers. The
949 * last 2 microframes I have reserved for INTERRUPT transfers. Without
950 * this division, it is very difficult to allocate and free bandwidth
951 * dynamically.
952 *
953 * NOTE about the Transaction Translator in USB HUBs:
954 *
955 * USB HUBs have a very simple Transaction Translator, that will
956 * simply pipeline all the SPLIT transactions. That means that the
957 * transactions will be executed in the order they are queued!
958 *
959 */
960
961/*------------------------------------------------------------------------*
962 * usb2_intr_find_best_slot
963 *
964 * Return value:
965 * The best Transaction Translation slot for an interrupt endpoint.
966 *------------------------------------------------------------------------*/
967static uint8_t
968usb2_intr_find_best_slot(uint32_t *ptr, uint8_t start, uint8_t end)
969{
970 uint32_t max = 0xffffffff;
971 uint8_t x;
972 uint8_t y;
973
974 y = 0;
975
976 /* find the last slot with lesser used bandwidth */
977
978 for (x = start; x < end; x++) {
979 if (max >= ptr[x]) {
980 max = ptr[x];
981 y = x;
982 }
983 }
984 return (y);
985}
986
987/*------------------------------------------------------------------------*
988 * usb2_intr_schedule_adjust
989 *
990 * This function will update the bandwith usage for the microframe
991 * having index "slot" by "len" bytes. "len" can be negative. If the
992 * "slot" argument is greater or equal to "USB_HS_MICRO_FRAMES_MAX"
993 * the "slot" argument will be replaced by the slot having least used
994 * bandwidth.
995 *
996 * Returns:
997 * The slot on which the bandwidth update was done.
998 *------------------------------------------------------------------------*/
999uint8_t
1000usb2_intr_schedule_adjust(struct usb2_device *udev, int16_t len, uint8_t slot)
1001{
1002 struct usb2_bus *bus = udev->bus;
1003 struct usb2_hub *hub;
1004
1005 mtx_assert(&bus->mtx, MA_OWNED);
1005 USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
1006
1007 if (usb2_get_speed(udev) == USB_SPEED_HIGH) {
1008 if (slot >= USB_HS_MICRO_FRAMES_MAX) {
1009 slot = usb2_intr_find_best_slot(bus->uframe_usage, 0,
1010 USB_HS_MICRO_FRAMES_MAX);
1011 }
1012 bus->uframe_usage[slot] += len;
1013 } else {
1014 if (usb2_get_speed(udev) == USB_SPEED_LOW) {
1015 len *= 8;
1016 }
1017 /*
1018 * The Host Controller Driver should have
1019 * performed checks so that the lookup
1020 * below does not result in a NULL pointer
1021 * access.
1022 */
1023
1024 hub = bus->devices[udev->hs_hub_addr]->hub;
1025 if (slot >= USB_HS_MICRO_FRAMES_MAX) {
1026 slot = usb2_intr_find_best_slot(hub->uframe_usage,
1027 USB_FS_ISOC_UFRAME_MAX, 6);
1028 }
1029 hub->uframe_usage[slot] += len;
1030 bus->uframe_usage[slot] += len;
1031 }
1032 return (slot);
1033}
1034
1035/*------------------------------------------------------------------------*
1036 * usb2_fs_isoc_schedule_init_sub
1037 *
1038 * This function initialises an USB FULL speed isochronous schedule
1039 * entry.
1040 *------------------------------------------------------------------------*/
1041static void
1042usb2_fs_isoc_schedule_init_sub(struct usb2_fs_isoc_schedule *fss)
1043{
1044 fss->total_bytes = (USB_FS_ISOC_UFRAME_MAX *
1045 USB_FS_BYTES_PER_HS_UFRAME);
1046 fss->frame_bytes = (USB_FS_BYTES_PER_HS_UFRAME);
1047 fss->frame_slot = 0;
1048 return;
1049}
1050
1051/*------------------------------------------------------------------------*
1052 * usb2_fs_isoc_schedule_init_all
1053 *
1054 * This function will reset the complete USB FULL speed isochronous
1055 * bandwidth schedule.
1056 *------------------------------------------------------------------------*/
1057void
1058usb2_fs_isoc_schedule_init_all(struct usb2_fs_isoc_schedule *fss)
1059{
1060 struct usb2_fs_isoc_schedule *fss_end = fss + USB_ISOC_TIME_MAX;
1061
1062 while (fss != fss_end) {
1063 usb2_fs_isoc_schedule_init_sub(fss);
1064 fss++;
1065 }
1066 return;
1067}
1068
1069/*------------------------------------------------------------------------*
1070 * usb2_isoc_time_expand
1071 *
1072 * This function will expand the time counter from 7-bit to 16-bit.
1073 *
1074 * Returns:
1075 * 16-bit isochronous time counter.
1076 *------------------------------------------------------------------------*/
1077uint16_t
1078usb2_isoc_time_expand(struct usb2_bus *bus, uint16_t isoc_time_curr)
1079{
1080 uint16_t rem;
1081
1006
1007 if (usb2_get_speed(udev) == USB_SPEED_HIGH) {
1008 if (slot >= USB_HS_MICRO_FRAMES_MAX) {
1009 slot = usb2_intr_find_best_slot(bus->uframe_usage, 0,
1010 USB_HS_MICRO_FRAMES_MAX);
1011 }
1012 bus->uframe_usage[slot] += len;
1013 } else {
1014 if (usb2_get_speed(udev) == USB_SPEED_LOW) {
1015 len *= 8;
1016 }
1017 /*
1018 * The Host Controller Driver should have
1019 * performed checks so that the lookup
1020 * below does not result in a NULL pointer
1021 * access.
1022 */
1023
1024 hub = bus->devices[udev->hs_hub_addr]->hub;
1025 if (slot >= USB_HS_MICRO_FRAMES_MAX) {
1026 slot = usb2_intr_find_best_slot(hub->uframe_usage,
1027 USB_FS_ISOC_UFRAME_MAX, 6);
1028 }
1029 hub->uframe_usage[slot] += len;
1030 bus->uframe_usage[slot] += len;
1031 }
1032 return (slot);
1033}
1034
1035/*------------------------------------------------------------------------*
1036 * usb2_fs_isoc_schedule_init_sub
1037 *
1038 * This function initialises an USB FULL speed isochronous schedule
1039 * entry.
1040 *------------------------------------------------------------------------*/
1041static void
1042usb2_fs_isoc_schedule_init_sub(struct usb2_fs_isoc_schedule *fss)
1043{
1044 fss->total_bytes = (USB_FS_ISOC_UFRAME_MAX *
1045 USB_FS_BYTES_PER_HS_UFRAME);
1046 fss->frame_bytes = (USB_FS_BYTES_PER_HS_UFRAME);
1047 fss->frame_slot = 0;
1048 return;
1049}
1050
1051/*------------------------------------------------------------------------*
1052 * usb2_fs_isoc_schedule_init_all
1053 *
1054 * This function will reset the complete USB FULL speed isochronous
1055 * bandwidth schedule.
1056 *------------------------------------------------------------------------*/
1057void
1058usb2_fs_isoc_schedule_init_all(struct usb2_fs_isoc_schedule *fss)
1059{
1060 struct usb2_fs_isoc_schedule *fss_end = fss + USB_ISOC_TIME_MAX;
1061
1062 while (fss != fss_end) {
1063 usb2_fs_isoc_schedule_init_sub(fss);
1064 fss++;
1065 }
1066 return;
1067}
1068
1069/*------------------------------------------------------------------------*
1070 * usb2_isoc_time_expand
1071 *
1072 * This function will expand the time counter from 7-bit to 16-bit.
1073 *
1074 * Returns:
1075 * 16-bit isochronous time counter.
1076 *------------------------------------------------------------------------*/
1077uint16_t
1078usb2_isoc_time_expand(struct usb2_bus *bus, uint16_t isoc_time_curr)
1079{
1080 uint16_t rem;
1081
1082 mtx_assert(&bus->mtx, MA_OWNED);
1082 USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
1083
1084 rem = bus->isoc_time_last & (USB_ISOC_TIME_MAX - 1);
1085
1086 isoc_time_curr &= (USB_ISOC_TIME_MAX - 1);
1087
1088 if (isoc_time_curr < rem) {
1089 /* the time counter wrapped around */
1090 bus->isoc_time_last += USB_ISOC_TIME_MAX;
1091 }
1092 /* update the remainder */
1093
1094 bus->isoc_time_last &= ~(USB_ISOC_TIME_MAX - 1);
1095 bus->isoc_time_last |= isoc_time_curr;
1096
1097 return (bus->isoc_time_last);
1098}
1099
1100/*------------------------------------------------------------------------*
1101 * usb2_fs_isoc_schedule_isoc_time_expand
1102 *
1103 * This function does multiple things. First of all it will expand the
1104 * passed isochronous time, which is the return value. Then it will
1105 * store where the current FULL speed isochronous schedule is
1106 * positioned in time and where the end is. See "pp_start" and
1107 * "pp_end" arguments.
1108 *
1109 * Returns:
1110 * Expanded version of "isoc_time".
1111 *
1112 * NOTE: This function depends on being called regularly with
1113 * intervals less than "USB_ISOC_TIME_MAX".
1114 *------------------------------------------------------------------------*/
1115uint16_t
1116usb2_fs_isoc_schedule_isoc_time_expand(struct usb2_device *udev,
1117 struct usb2_fs_isoc_schedule **pp_start,
1118 struct usb2_fs_isoc_schedule **pp_end,
1119 uint16_t isoc_time)
1120{
1121 struct usb2_fs_isoc_schedule *fss_end;
1122 struct usb2_fs_isoc_schedule *fss_a;
1123 struct usb2_fs_isoc_schedule *fss_b;
1124 struct usb2_hub *hs_hub;
1125
1126 isoc_time = usb2_isoc_time_expand(udev->bus, isoc_time);
1127
1128 hs_hub = udev->bus->devices[udev->hs_hub_addr]->hub;
1129
1130 if (hs_hub != NULL) {
1131
1132 fss_a = hs_hub->fs_isoc_schedule +
1133 (hs_hub->isoc_last_time % USB_ISOC_TIME_MAX);
1134
1135 hs_hub->isoc_last_time = isoc_time;
1136
1137 fss_b = hs_hub->fs_isoc_schedule +
1138 (isoc_time % USB_ISOC_TIME_MAX);
1139
1140 fss_end = hs_hub->fs_isoc_schedule + USB_ISOC_TIME_MAX;
1141
1142 *pp_start = hs_hub->fs_isoc_schedule;
1143 *pp_end = fss_end;
1144
1145 while (fss_a != fss_b) {
1146 if (fss_a == fss_end) {
1147 fss_a = hs_hub->fs_isoc_schedule;
1148 continue;
1149 }
1150 usb2_fs_isoc_schedule_init_sub(fss_a);
1151 fss_a++;
1152 }
1153
1154 } else {
1155
1156 *pp_start = NULL;
1157 *pp_end = NULL;
1158 }
1159 return (isoc_time);
1160}
1161
1162/*------------------------------------------------------------------------*
1163 * usb2_fs_isoc_schedule_alloc
1164 *
1165 * This function will allocate bandwidth for an isochronous FULL speed
1166 * transaction in the FULL speed schedule. The microframe slot where
1167 * the transaction should be started is stored in the byte pointed to
1168 * by "pstart". The "len" argument specifies the length of the
1169 * transaction in bytes.
1170 *
1171 * Returns:
1172 * 0: Success
1173 * Else: Error
1174 *------------------------------------------------------------------------*/
1175uint8_t
1176usb2_fs_isoc_schedule_alloc(struct usb2_fs_isoc_schedule *fss,
1177 uint8_t *pstart, uint16_t len)
1178{
1179 uint8_t slot = fss->frame_slot;
1180
1181 /* Compute overhead and bit-stuffing */
1182
1183 len += 8;
1184
1185 len *= 7;
1186 len /= 6;
1187
1188 if (len > fss->total_bytes) {
1189 *pstart = 0; /* set some dummy value */
1190 return (1); /* error */
1191 }
1192 if (len > 0) {
1193
1194 fss->total_bytes -= len;
1195
1196 while (len >= fss->frame_bytes) {
1197 len -= fss->frame_bytes;
1198 fss->frame_bytes = USB_FS_BYTES_PER_HS_UFRAME;
1199 fss->frame_slot++;
1200 }
1201
1202 fss->frame_bytes -= len;
1203 }
1204 *pstart = slot;
1205 return (0); /* success */
1206}
1207
1208/*------------------------------------------------------------------------*
1209 * usb2_bus_port_get_device
1210 *
1211 * This function is NULL safe.
1212 *------------------------------------------------------------------------*/
1213struct usb2_device *
1214usb2_bus_port_get_device(struct usb2_bus *bus, struct usb2_port *up)
1215{
1216 if ((bus == NULL) || (up == NULL)) {
1217 /* be NULL safe */
1218 return (NULL);
1219 }
1220 if (up->device_index == 0) {
1221 /* nothing to do */
1222 return (NULL);
1223 }
1224 return (bus->devices[up->device_index]);
1225}
1226
1227/*------------------------------------------------------------------------*
1228 * usb2_bus_port_set_device
1229 *
1230 * This function is NULL safe.
1231 *------------------------------------------------------------------------*/
1232void
1233usb2_bus_port_set_device(struct usb2_bus *bus, struct usb2_port *up,
1234 struct usb2_device *udev, uint8_t device_index)
1235{
1236 if (bus == NULL) {
1237 /* be NULL safe */
1238 return;
1239 }
1240 /*
1241 * There is only one case where we don't
1242 * have an USB port, and that is the Root Hub!
1243 */
1244 if (up) {
1245 if (udev) {
1246 up->device_index = device_index;
1247 } else {
1248 device_index = up->device_index;
1249 up->device_index = 0;
1250 }
1251 }
1252 /*
1253 * Make relationships to our new device
1254 */
1255 if (device_index != 0) {
1256 mtx_lock(&usb2_ref_lock);
1257 bus->devices[device_index] = udev;
1258 mtx_unlock(&usb2_ref_lock);
1259 }
1260 /*
1261 * Debug print
1262 */
1263 DPRINTFN(2, "bus %p devices[%u] = %p\n", bus, device_index, udev);
1264
1265 return;
1266}
1267
1268/*------------------------------------------------------------------------*
1269 * usb2_needs_explore
1270 *
1271 * This functions is called when the USB event thread needs to run.
1272 *------------------------------------------------------------------------*/
1273void
1274usb2_needs_explore(struct usb2_bus *bus, uint8_t do_probe)
1275{
1276 DPRINTF("\n");
1277
1278 if (bus == NULL) {
1279 DPRINTF("No bus pointer!\n");
1280 return;
1281 }
1083
1084 rem = bus->isoc_time_last & (USB_ISOC_TIME_MAX - 1);
1085
1086 isoc_time_curr &= (USB_ISOC_TIME_MAX - 1);
1087
1088 if (isoc_time_curr < rem) {
1089 /* the time counter wrapped around */
1090 bus->isoc_time_last += USB_ISOC_TIME_MAX;
1091 }
1092 /* update the remainder */
1093
1094 bus->isoc_time_last &= ~(USB_ISOC_TIME_MAX - 1);
1095 bus->isoc_time_last |= isoc_time_curr;
1096
1097 return (bus->isoc_time_last);
1098}
1099
1100/*------------------------------------------------------------------------*
1101 * usb2_fs_isoc_schedule_isoc_time_expand
1102 *
1103 * This function does multiple things. First of all it will expand the
1104 * passed isochronous time, which is the return value. Then it will
1105 * store where the current FULL speed isochronous schedule is
1106 * positioned in time and where the end is. See "pp_start" and
1107 * "pp_end" arguments.
1108 *
1109 * Returns:
1110 * Expanded version of "isoc_time".
1111 *
1112 * NOTE: This function depends on being called regularly with
1113 * intervals less than "USB_ISOC_TIME_MAX".
1114 *------------------------------------------------------------------------*/
1115uint16_t
1116usb2_fs_isoc_schedule_isoc_time_expand(struct usb2_device *udev,
1117 struct usb2_fs_isoc_schedule **pp_start,
1118 struct usb2_fs_isoc_schedule **pp_end,
1119 uint16_t isoc_time)
1120{
1121 struct usb2_fs_isoc_schedule *fss_end;
1122 struct usb2_fs_isoc_schedule *fss_a;
1123 struct usb2_fs_isoc_schedule *fss_b;
1124 struct usb2_hub *hs_hub;
1125
1126 isoc_time = usb2_isoc_time_expand(udev->bus, isoc_time);
1127
1128 hs_hub = udev->bus->devices[udev->hs_hub_addr]->hub;
1129
1130 if (hs_hub != NULL) {
1131
1132 fss_a = hs_hub->fs_isoc_schedule +
1133 (hs_hub->isoc_last_time % USB_ISOC_TIME_MAX);
1134
1135 hs_hub->isoc_last_time = isoc_time;
1136
1137 fss_b = hs_hub->fs_isoc_schedule +
1138 (isoc_time % USB_ISOC_TIME_MAX);
1139
1140 fss_end = hs_hub->fs_isoc_schedule + USB_ISOC_TIME_MAX;
1141
1142 *pp_start = hs_hub->fs_isoc_schedule;
1143 *pp_end = fss_end;
1144
1145 while (fss_a != fss_b) {
1146 if (fss_a == fss_end) {
1147 fss_a = hs_hub->fs_isoc_schedule;
1148 continue;
1149 }
1150 usb2_fs_isoc_schedule_init_sub(fss_a);
1151 fss_a++;
1152 }
1153
1154 } else {
1155
1156 *pp_start = NULL;
1157 *pp_end = NULL;
1158 }
1159 return (isoc_time);
1160}
1161
1162/*------------------------------------------------------------------------*
1163 * usb2_fs_isoc_schedule_alloc
1164 *
1165 * This function will allocate bandwidth for an isochronous FULL speed
1166 * transaction in the FULL speed schedule. The microframe slot where
1167 * the transaction should be started is stored in the byte pointed to
1168 * by "pstart". The "len" argument specifies the length of the
1169 * transaction in bytes.
1170 *
1171 * Returns:
1172 * 0: Success
1173 * Else: Error
1174 *------------------------------------------------------------------------*/
1175uint8_t
1176usb2_fs_isoc_schedule_alloc(struct usb2_fs_isoc_schedule *fss,
1177 uint8_t *pstart, uint16_t len)
1178{
1179 uint8_t slot = fss->frame_slot;
1180
1181 /* Compute overhead and bit-stuffing */
1182
1183 len += 8;
1184
1185 len *= 7;
1186 len /= 6;
1187
1188 if (len > fss->total_bytes) {
1189 *pstart = 0; /* set some dummy value */
1190 return (1); /* error */
1191 }
1192 if (len > 0) {
1193
1194 fss->total_bytes -= len;
1195
1196 while (len >= fss->frame_bytes) {
1197 len -= fss->frame_bytes;
1198 fss->frame_bytes = USB_FS_BYTES_PER_HS_UFRAME;
1199 fss->frame_slot++;
1200 }
1201
1202 fss->frame_bytes -= len;
1203 }
1204 *pstart = slot;
1205 return (0); /* success */
1206}
1207
1208/*------------------------------------------------------------------------*
1209 * usb2_bus_port_get_device
1210 *
1211 * This function is NULL safe.
1212 *------------------------------------------------------------------------*/
1213struct usb2_device *
1214usb2_bus_port_get_device(struct usb2_bus *bus, struct usb2_port *up)
1215{
1216 if ((bus == NULL) || (up == NULL)) {
1217 /* be NULL safe */
1218 return (NULL);
1219 }
1220 if (up->device_index == 0) {
1221 /* nothing to do */
1222 return (NULL);
1223 }
1224 return (bus->devices[up->device_index]);
1225}
1226
1227/*------------------------------------------------------------------------*
1228 * usb2_bus_port_set_device
1229 *
1230 * This function is NULL safe.
1231 *------------------------------------------------------------------------*/
1232void
1233usb2_bus_port_set_device(struct usb2_bus *bus, struct usb2_port *up,
1234 struct usb2_device *udev, uint8_t device_index)
1235{
1236 if (bus == NULL) {
1237 /* be NULL safe */
1238 return;
1239 }
1240 /*
1241 * There is only one case where we don't
1242 * have an USB port, and that is the Root Hub!
1243 */
1244 if (up) {
1245 if (udev) {
1246 up->device_index = device_index;
1247 } else {
1248 device_index = up->device_index;
1249 up->device_index = 0;
1250 }
1251 }
1252 /*
1253 * Make relationships to our new device
1254 */
1255 if (device_index != 0) {
1256 mtx_lock(&usb2_ref_lock);
1257 bus->devices[device_index] = udev;
1258 mtx_unlock(&usb2_ref_lock);
1259 }
1260 /*
1261 * Debug print
1262 */
1263 DPRINTFN(2, "bus %p devices[%u] = %p\n", bus, device_index, udev);
1264
1265 return;
1266}
1267
1268/*------------------------------------------------------------------------*
1269 * usb2_needs_explore
1270 *
1271 * This functions is called when the USB event thread needs to run.
1272 *------------------------------------------------------------------------*/
1273void
1274usb2_needs_explore(struct usb2_bus *bus, uint8_t do_probe)
1275{
1276 DPRINTF("\n");
1277
1278 if (bus == NULL) {
1279 DPRINTF("No bus pointer!\n");
1280 return;
1281 }
1282 mtx_lock(&bus->mtx);
1282 USB_BUS_LOCK(bus);
1283 if (do_probe) {
1284 bus->do_probe = 1;
1285 }
1286 if (usb2_proc_msignal(&bus->explore_proc,
1287 &bus->explore_msg[0], &bus->explore_msg[1])) {
1288 /* ignore */
1289 }
1283 if (do_probe) {
1284 bus->do_probe = 1;
1285 }
1286 if (usb2_proc_msignal(&bus->explore_proc,
1287 &bus->explore_msg[0], &bus->explore_msg[1])) {
1288 /* ignore */
1289 }
1290 mtx_unlock(&bus->mtx);
1290 USB_BUS_UNLOCK(bus);
1291 return;
1292}
1293
1294/*------------------------------------------------------------------------*
1295 * usb2_needs_explore_all
1296 *
1297 * This function is called whenever a new driver is loaded and will
1298 * cause that all USB busses are re-explored.
1299 *------------------------------------------------------------------------*/
1300void
1301usb2_needs_explore_all(void)
1302{
1303 struct usb2_bus *bus;
1304 devclass_t dc;
1305 device_t dev;
1306 int max;
1307
1308 DPRINTFN(3, "\n");
1309
1310 dc = usb2_devclass_ptr;
1311 if (dc == NULL) {
1312 DPRINTFN(0, "no devclass\n");
1313 return;
1314 }
1315 /*
1316 * Explore all USB busses in parallell.
1317 */
1318 max = devclass_get_maxunit(dc);
1319 while (max >= 0) {
1320 dev = devclass_get_device(dc, max);
1321 if (dev) {
1322 bus = device_get_softc(dev);
1323 if (bus) {
1324 usb2_needs_explore(bus, 1);
1325 }
1326 }
1327 max--;
1328 }
1329 return;
1330}
1291 return;
1292}
1293
1294/*------------------------------------------------------------------------*
1295 * usb2_needs_explore_all
1296 *
1297 * This function is called whenever a new driver is loaded and will
1298 * cause that all USB busses are re-explored.
1299 *------------------------------------------------------------------------*/
1300void
1301usb2_needs_explore_all(void)
1302{
1303 struct usb2_bus *bus;
1304 devclass_t dc;
1305 device_t dev;
1306 int max;
1307
1308 DPRINTFN(3, "\n");
1309
1310 dc = usb2_devclass_ptr;
1311 if (dc == NULL) {
1312 DPRINTFN(0, "no devclass\n");
1313 return;
1314 }
1315 /*
1316 * Explore all USB busses in parallell.
1317 */
1318 max = devclass_get_maxunit(dc);
1319 while (max >= 0) {
1320 dev = devclass_get_device(dc, max);
1321 if (dev) {
1322 bus = device_get_softc(dev);
1323 if (bus) {
1324 usb2_needs_explore(bus, 1);
1325 }
1326 }
1327 max--;
1328 }
1329 return;
1330}