Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Aug 2010 15:46:22 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 181685 for review
Message-ID:  <201008011546.o71FkMK0006990@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@181685?ac=10

Change 181685 by hselasky@hselasky_laptop001 on 2010/08/01 15:45:30

	USB CORE:
		- add full USB 3.0 (SuperSpeed) support to HUB class driver.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/usb.h#53 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_hub.c#50 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_hub.h#17 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_request.c#35 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_request.h#12 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/usb.h#53 (text+ko) ====

@@ -226,6 +226,7 @@
 #define	UR_GET_TT_STATE		0x0a
 #define	UR_STOP_TT		0x0b
 #define	UR_SET_HUB_DEPTH	0x0c
+#define	USB_SS_HUB_DEPTH_MAX	4	/* exclusive */
 #define	UR_GET_PORT_ERR_COUNT	0x0d
 
 /* Feature numbers */

==== //depot/projects/usb/src/sys/dev/usb/usb_hub.c#50 (text+ko) ====

@@ -109,6 +109,7 @@
 #define	UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol)
 #define	UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
 #define	UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
+#define	UHUB_IS_SUPER_SPEED(sc) (UHUB_PROTO(sc) == UDPROTO_SSHUB)
 
 /* prototypes for type checking: */
 
@@ -267,14 +268,14 @@
 	}
 	/* start control transfer, if device mode */
 
-	if (child->flags.usb_mode == USB_MODE_DEVICE) {
+	if (child->flags.usb_mode == USB_MODE_DEVICE)
 		usbd_ctrl_transfer_setup(child);
-	}
+
 	/* if a HUB becomes present, do a recursive HUB explore */
 
-	if (child->hub) {
+	if (child->hub)
 		err = (child->hub->explore) (child);
-	}
+
 done:
 	return (err);
 }
@@ -373,11 +374,17 @@
 		DPRINTF("Port %d is in Host Mode\n", portno);
 
 		if (sc->sc_st.port_status & UPS_SUSPEND) {
+			/*
+			 * NOTE: Should not get here in SuperSpeed
+			 * mode, because the HUB should report this
+			 * bit as zero.
+			 */
 			DPRINTF("Port %d was still "
 			    "suspended, clearing.\n", portno);
-			err = usbd_req_clear_port_feature(sc->sc_udev,
+			err = usbd_req_clear_port_feature(udev,
 			    NULL, portno, UHF_PORT_SUSPEND);
 		}
+
 		/* USB Host Mode */
 
 		/* wait for maximum device power up time */
@@ -438,6 +445,27 @@
 	case USB_SPEED_LOW:
 		speed = USB_SPEED_LOW;
 		break;
+	case USB_SPEED_SUPER:
+		if (udev->parent_hub == NULL) {
+			/* Root HUB - special case */
+			switch (sc->sc_st.port_status & UPS_OTHER_SPEED) {
+			case 0:
+				speed = USB_SPEED_FULL;
+				break;
+			case UPS_LOW_SPEED:
+				speed = USB_SPEED_LOW;
+				break;
+			case UPS_HIGH_SPEED:
+				speed = USB_SPEED_HIGH;
+				break;
+			default:
+				speed = USB_SPEED_SUPER;
+				break;
+			}
+		} else {
+			speed = USB_SPEED_SUPER;
+		}
+		break;
 	default:
 		/* same speed like parent */
 		speed = udev->speed;
@@ -485,6 +513,28 @@
 }
 
 /*------------------------------------------------------------------------*
+ *	usb_device_20_compatible
+ *
+ * Returns:
+ *    0: HUB does not support suspend and resume
+ * Else: HUB supports suspend and resume
+ *------------------------------------------------------------------------*/
+static uint8_t
+usb_device_20_compatible(struct usb_device *udev)
+{
+	if (udev == NULL)
+		return (0);
+	switch (udev->speed) {
+	case USB_SPEED_LOW:
+	case USB_SPEED_FULL:
+	case USB_SPEED_HIGH:
+		return (1);
+	default:
+		return (0);
+	}
+}
+
+/*------------------------------------------------------------------------*
  *	uhub_suspend_resume_port
  *
  * Returns:
@@ -507,8 +557,14 @@
 
 	/* first clear the port suspend change bit */
 
-	err = usbd_req_clear_port_feature(udev, NULL,
-	    portno, UHF_C_PORT_SUSPEND);
+	if (usb_device_20_compatible(udev)) {
+		err = usbd_req_clear_port_feature(udev, NULL,
+		    portno, UHF_C_PORT_SUSPEND);
+	} else {
+		err = usbd_req_clear_port_feature(udev, NULL,
+		    portno, UHF_C_PORT_LINK_STATE);
+	}
+
 	if (err) {
 		DPRINTF("clearing suspend failed.\n");
 		goto done;
@@ -520,12 +576,24 @@
 		DPRINTF("reading port status failed.\n");
 		goto done;
 	}
-	/* get current state */
+	/* convert current state */
 
-	if (sc->sc_st.port_status & UPS_SUSPEND) {
-		is_suspend = 1;
+	if (usb_device_20_compatible(udev)) {
+		if (sc->sc_st.port_status & UPS_SUSPEND) {
+			is_suspend = 1;
+		} else {
+			is_suspend = 0;
+		}
 	} else {
-		is_suspend = 0;
+		switch (UPS_PORT_LINK_STATE_GET(sc->sc_st.port_status)) {
+		case UPS_PORT_LS_U0:
+		case UPS_PORT_LS_U1:
+			is_suspend = 0;
+			break;
+		default:
+			is_suspend = 1;
+			break;
+		}
 	}
 
 	DPRINTF("suspended=%u\n", is_suspend);
@@ -540,7 +608,8 @@
 		 */
 		if (is_suspend == 0)
 			usb_dev_resume_peer(child);
-		else if (child->flags.usb_mode == USB_MODE_DEVICE)
+		else if ((child->flags.usb_mode == USB_MODE_DEVICE) ||
+		    (usb_device_20_compatible(child) == 0))
 			usb_dev_suspend_peer(child);
 	}
 done:
@@ -562,6 +631,26 @@
 	usb_needs_explore(bus, 0);
 }
 
+static uint8_t
+uhub_is_too_deep(struct usb_device *udev)
+{
+	switch (udev->speed) {
+	case USB_SPEED_FULL:
+	case USB_SPEED_LOW:
+	case USB_SPEED_HIGH:
+		if (udev->depth > USB_HUB_MAX_DEPTH)
+			return (1);
+		break;
+	case USB_SPEED_SUPER:
+		if (udev->depth >= USB_SS_HUB_DEPTH_MAX)
+			return (1);
+		break;
+	default:
+		break;
+	}
+	return (0);
+}
+
 /*------------------------------------------------------------------------*
  *	uhub_explore
  *
@@ -584,11 +673,11 @@
 
 	DPRINTFN(11, "udev=%p addr=%d\n", udev, udev->address);
 
-	/* ignore hubs that are too deep */
-	if (udev->depth > USB_HUB_MAX_DEPTH) {
+	/* ignore devices that are too deep */
+	if (uhub_is_too_deep(udev))
 		return (USB_ERR_TOO_DEEP);
-	}
 
+	/* check if device is suspended */
 	if (udev->flags.self_suspended) {
 		/* need to wait until the child signals resume */
 		DPRINTF("Device is suspended!\n");
@@ -655,7 +744,7 @@
 				break;
 			}
 		}
-		if (sc->sc_st.port_change & UPS_C_SUSPEND) {
+		if (sc->sc_st.port_change & (UPS_C_SUSPEND | UPS_C_PORT_LINK_STATE)) {
 			err = uhub_suspend_resume_port(sc, portno);
 			if (err) {
 				/* most likely the HUB is gone */
@@ -683,17 +772,17 @@
 {
 	struct usb_attach_arg *uaa = device_get_ivars(dev);
 
-	if (uaa->usb_mode != USB_MODE_HOST) {
+	if (uaa->usb_mode != USB_MODE_HOST)
 		return (ENXIO);
-	}
+
 	/*
-	 * The subclass for USB HUBs is ignored because it is 0 for
-	 * some and 1 for others.
+	 * The subclass for USB HUBs is currently ignored because it
+	 * is 0 for some and 1 for others.
 	 */
 	if ((uaa->info.bConfigIndex == 0) &&
-	    (uaa->info.bDeviceClass == UDCLASS_HUB)) {
+	    (uaa->info.bDeviceClass == UDCLASS_HUB))
 		return (0);
-	}
+
 	return (ENXIO);
 }
 
@@ -705,7 +794,8 @@
 	struct usb_device *udev = uaa->device;
 	struct usb_device *parent_hub = udev->parent_hub;
 	struct usb_hub *hub;
-	struct usb_hub_descriptor hubdesc;
+	struct usb_hub_descriptor hubdesc20;
+	struct usb_hub_ss_descriptor hubdesc30;
 	uint16_t pwrdly;
 	uint8_t x;
 	uint8_t nports;
@@ -732,38 +822,96 @@
 	    parent_hub ?
 	    parent_hub->flags.self_powered : 0);
 
-	if (udev->depth > USB_HUB_MAX_DEPTH) {
-		DPRINTFN(0, "hub depth, %d, exceeded. HUB ignored\n",
-		    USB_HUB_MAX_DEPTH);
+	if (uhub_is_too_deep(udev)) {
+		DPRINTFN(0, "HUB at depth %d, "
+		    "exceeds maximum. HUB ignored\n", (int)udev->depth);
 		goto error;
 	}
+
 	if (!udev->flags.self_powered && parent_hub &&
 	    (!parent_hub->flags.self_powered)) {
-		DPRINTFN(0, "bus powered HUB connected to "
+		DPRINTFN(0, "Bus powered HUB connected to "
 		    "bus powered HUB. HUB ignored\n");
 		goto error;
 	}
 	/* get HUB descriptor */
 
-	DPRINTFN(2, "getting HUB descriptor\n");
+	DPRINTFN(2, "Getting HUB descriptor\n");
 
-	/* assuming that there is one port */
-	err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc, 1);
+	switch (udev->speed) {
+	case USB_SPEED_LOW:
+	case USB_SPEED_FULL:
+	case USB_SPEED_HIGH:
+		/* assuming that there is one port */
+		err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc20, 1);
+		if (err) {
+			DPRINTFN(0, "getting USB 2.0 HUB descriptor failed,"
+			    "error=%s\n", usbd_errstr(err));
+			goto error;
+		}
+		/* get number of ports */
+		nports = hubdesc20.bNbrPorts;
 
-	nports = hubdesc.bNbrPorts;
+		/* get power delay */
+		pwrdly = ((hubdesc20.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
+		    USB_EXTRA_POWER_UP_TIME);
 
-	if (!err && (nports >= 8)) {
 		/* get complete HUB descriptor */
-		err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc, nports);
-	}
-	if (err) {
-		DPRINTFN(0, "getting hub descriptor failed,"
-		    "error=%s\n", usbd_errstr(err));
-		goto error;
-	}
-	if (hubdesc.bNbrPorts != nports) {
-		DPRINTFN(0, "number of ports changed\n");
-		goto error;
+		if (nports >= 8) {
+			/* check number of ports */
+			if (nports > 127) {
+				DPRINTFN(0, "Invalid number of USB 2.0 ports,"
+				    "error=%s\n", usbd_errstr(err));
+				goto error;
+			}
+			/* get complete HUB descriptor */
+			err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc20, nports);
+
+			if (err) {
+				DPRINTFN(0, "Getting USB 2.0 HUB descriptor failed,"
+				    "error=%s\n", usbd_errstr(err));
+				goto error;
+			}
+			if (hubdesc20.bNbrPorts != nports) {
+				DPRINTFN(0, "Number of ports changed\n");
+				goto error;
+			}
+		}
+		break;
+	case USB_SPEED_SUPER:
+		err = usbd_req_set_hub_depth(udev, NULL, udev->depth);
+		if (err) {
+			DPRINTFN(0, "Setting USB 3.0 HUB depth failed,"
+			    "error=%s\n", usbd_errstr(err));
+			goto error;
+		}
+		err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30);
+		if (err) {
+			DPRINTFN(0, "Getting USB 3.0 HUB descriptor failed,"
+			    "error=%s\n", usbd_errstr(err));
+			goto error;
+		}
+		/* get number of ports */
+		nports = hubdesc30.bNbrPorts;
+
+		/* get power delay */
+		pwrdly = ((hubdesc30.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
+		    USB_EXTRA_POWER_UP_TIME);
+
+		/* check number of ports */
+		if (nports > 15) {
+			DPRINTFN(0, "Invalid number of USB 3.0 ports,"
+			    "error=%s\n", usbd_errstr(err));
+			goto error;
+		}
+		break;
+	default:
+		DPRINTF("Assuming HUB has only one port\n");
+		/* default number of ports */
+		nports = 1;
+		/* default power delay */
+		pwrdly = ((10 * UHD_PWRON_FACTOR) + USB_EXTRA_POWER_UP_TIME);
+		break;
 	}
 	if (nports == 0) {
 		DPRINTFN(0, "portless HUB\n");
@@ -784,7 +932,7 @@
 	/* initialize HUB structure */
 	hub->hubsoftc = sc;
 	hub->explore = &uhub_explore;
-	hub->nports = hubdesc.bNbrPorts;
+	hub->nports = nports;
 	hub->hubudev = udev;
 
 	/* if self powered hub, give ports maximum current */
@@ -840,8 +988,6 @@
 	/* XXX should check for none, individual, or ganged power? */
 
 	removable = 0;
-	pwrdly = ((hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
-	    USB_EXTRA_POWER_UP_TIME);
 
 	for (x = 0; x != nports; x++) {
 		/* set up data structures */
@@ -852,8 +998,29 @@
 		portno = x + 1;
 
 		/* check if port is removable */
-		if (!UHD_NOT_REMOV(&hubdesc, portno)) {
+		switch (udev->speed) {
+		case USB_SPEED_LOW:
+		case USB_SPEED_FULL:
+		case USB_SPEED_HIGH:
+			if (!UHD_NOT_REMOV(&hubdesc20, portno))
+				removable++;
+			break;
+		case USB_SPEED_SUPER:
+			if (!err) {
+				err = usbd_req_set_hub_u1_timeout(udev, NULL,
+				    portno, 128 - (2 * udev->depth));
+			}
+			if (!err) {
+				err = usbd_req_set_hub_u2_timeout(udev, NULL,
+				    portno, 128 - (2 * udev->depth));
+			}
+			if (!UHD_NOT_REMOV(&hubdesc30, portno))
+				removable++;
+			break;
+		default:
+			DPRINTF("Assuming removable port\n");
 			removable++;
+			break;
 		}
 		if (!err) {
 			/* turn the power on */
@@ -914,9 +1081,8 @@
 	struct usb_device *child;
 	uint8_t x;
 
-	if (hub == NULL) {		/* must be partially working */
+	if (hub == NULL)		/* must be partially working */
 		return (0);
-	}
 
 	/* Make sure interrupt transfer is gone. */
 	usbd_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
@@ -1788,6 +1954,7 @@
 	    (udev->pwr_save.write_refs != 0) ||
 	    ((udev->pwr_save.read_refs != 0) &&
 	    (udev->flags.usb_mode == USB_MODE_HOST) &&
+	    (usb_device_20_compatible(udev) != 0) &&
 	    (usb_peer_can_wakeup(udev) == 0)));
 }
 
@@ -1959,13 +2126,16 @@
 	/* reduce chance of instant resume failure by waiting a little bit */
 	usb_pause_mtx(NULL, USB_MS_TO_TICKS(20));
 
-	/* resume current port (Valid in Host and Device Mode) */
-	err = usbd_req_clear_port_feature(udev->parent_hub,
-	    NULL, udev->port_no, UHF_PORT_SUSPEND);
-	if (err) {
-		DPRINTFN(0, "Resuming port failed\n");
-		return;
+	if (usb_device_20_compatible(udev)) {
+		/* resume current port (Valid in Host and Device Mode) */
+		err = usbd_req_clear_port_feature(udev->parent_hub,
+		    NULL, udev->port_no, UHF_PORT_SUSPEND);
+		if (err) {
+			DPRINTFN(0, "Resuming port failed\n");
+			return;
+		}
 	}
+
 	/* resume settle time */
 	usb_pause_mtx(NULL, USB_MS_TO_TICKS(USB_PORT_RESUME_DELAY));
 
@@ -2005,7 +2175,8 @@
 	usbd_sr_unlock(udev);
 
 	/* check if peer has wakeup capability */
-	if (usb_peer_can_wakeup(udev)) {
+	if (usb_peer_can_wakeup(udev) &&
+	    usb_device_20_compatible(udev)) {
 		/* clear remote wakeup */
 		err = usbd_req_clear_device_feature(udev,
 		    NULL, UF_DEVICE_REMOTE_WAKEUP);
@@ -2015,7 +2186,6 @@
 			    usbd_errstr(err));
 		}
 	}
-	return;
 }
 
 /*------------------------------------------------------------------------*
@@ -2110,7 +2280,8 @@
 
 	usbd_sr_unlock(udev);
 
-	if (usb_peer_can_wakeup(udev)) {
+	if (usb_peer_can_wakeup(udev) &&
+	    usb_device_20_compatible(udev)) {
 		/* allow device to do remote wakeup */
 		err = usbd_req_set_device_feature(udev,
 		    NULL, UF_DEVICE_REMOTE_WAKEUP);
@@ -2132,12 +2303,15 @@
 			usb_pause_mtx(NULL, USB_MS_TO_TICKS(temp));
 
 	}
-	/* suspend current port */
-	err = usbd_req_set_port_feature(udev->parent_hub,
-	    NULL, udev->port_no, UHF_PORT_SUSPEND);
-	if (err) {
-		DPRINTFN(0, "Suspending port failed\n");
-		return;
+
+	if (usb_device_20_compatible(udev)) {
+		/* suspend current port */
+		err = usbd_req_set_port_feature(udev->parent_hub,
+		    NULL, udev->port_no, UHF_PORT_SUSPEND);
+		if (err) {
+			DPRINTFN(0, "Suspending port failed\n");
+			return;
+		}
 	}
 
 	udev = udev->parent_hub;

==== //depot/projects/usb/src/sys/dev/usb/usb_hub.h#17 (text+ko) ====


==== //depot/projects/usb/src/sys/dev/usb/usb_request.c#35 (text+ko) ====

@@ -1293,6 +1293,27 @@
 }
 
 /*------------------------------------------------------------------------*
+ *	usbd_req_get_ss_hub_descriptor
+ *
+ * Returns:
+ *    0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usb_error_t
+usbd_req_get_ss_hub_descriptor(struct usb_device *udev, struct mtx *mtx,
+    struct usb_hub_ss_descriptor *hd)
+{
+	struct usb_device_request req;
+
+	req.bmRequestType = UT_READ_CLASS_DEVICE;
+	req.bRequest = UR_GET_DESCRIPTOR;
+	USETW2(req.wValue, UDESC_SS_HUB, 0);
+	USETW(req.wIndex, 0);
+	USETW(req.wLength, sizeof(*hd));
+	return (usbd_do_request(udev, mtx, &req, hd));
+}
+
+/*------------------------------------------------------------------------*
  *	usbd_req_get_hub_status
  *
  * Returns:
@@ -1406,6 +1427,71 @@
 }
 
 /*------------------------------------------------------------------------*
+ *	usbd_req_set_hub_u1_timeout
+ *
+ * Returns:
+ *    0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usb_error_t
+usbd_req_set_hub_u1_timeout(struct usb_device *udev, struct mtx *mtx,
+    uint8_t port, uint8_t timeout)
+{
+	struct usb_device_request req;
+
+	req.bmRequestType = UT_WRITE_CLASS_OTHER;
+	req.bRequest = UR_SET_FEATURE;
+	USETW(req.wValue, UHF_PORT_U1_TIMEOUT);
+	req.wIndex[0] = port;
+	req.wIndex[1] = timeout;
+	USETW(req.wLength, 0);
+	return (usbd_do_request(udev, mtx, &req, 0));
+}
+
+/*------------------------------------------------------------------------*
+ *	usbd_req_set_hub_u2_timeout
+ *
+ * Returns:
+ *    0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usb_error_t
+usbd_req_set_hub_u2_timeout(struct usb_device *udev, struct mtx *mtx,
+    uint8_t port, uint8_t timeout)
+{
+	struct usb_device_request req;
+
+	req.bmRequestType = UT_WRITE_CLASS_OTHER;
+	req.bRequest = UR_SET_FEATURE;
+	USETW(req.wValue, UHF_PORT_U2_TIMEOUT);
+	req.wIndex[0] = port;
+	req.wIndex[1] = timeout;
+	USETW(req.wLength, 0);
+	return (usbd_do_request(udev, mtx, &req, 0));
+}
+
+/*------------------------------------------------------------------------*
+ *	usbd_req_set_hub_depth
+ *
+ * Returns:
+ *    0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usb_error_t
+usbd_req_set_hub_depth(struct usb_device *udev, struct mtx *mtx,
+    uint16_t depth)
+{
+	struct usb_device_request req;
+
+	req.bmRequestType = UT_WRITE_CLASS_DEVICE;
+	req.bRequest = UR_SET_HUB_DEPTH;
+	USETW(req.wValue, depth);
+	USETW(req.wIndex, 0);
+	USETW(req.wLength, 0);
+	return (usbd_do_request(udev, mtx, &req, 0));
+}
+
+/*------------------------------------------------------------------------*
  *	usbd_req_clear_port_feature
  *
  * Returns:

==== //depot/projects/usb/src/sys/dev/usb/usb_request.h#12 (text+ko) ====

@@ -56,6 +56,8 @@
 usb_error_t usbd_req_get_hub_descriptor(struct usb_device *udev,
 		    struct mtx *mtx, struct usb_hub_descriptor *hd,
 		    uint8_t nports);
+usb_error_t usbd_req_get_ss_hub_descriptor(struct usb_device *udev,
+		    struct mtx *mtx, struct usb_hub_ss_descriptor *hd);
 usb_error_t usbd_req_get_hub_status(struct usb_device *udev, struct mtx *mtx,
 		    struct usb_hub_status *st);
 usb_error_t usbd_req_get_port_status(struct usb_device *udev, struct mtx *mtx,
@@ -69,7 +71,15 @@
 usb_error_t usbd_req_set_port_feature(struct usb_device *udev,
 		    struct mtx *mtx, uint8_t port, uint16_t sel);
 usb_error_t usbd_req_re_enumerate(struct usb_device *udev, struct mtx *mtx);
-usb_error_t usbd_req_clear_device_feature(struct usb_device *udev, struct mtx *mtx, uint16_t sel);
-usb_error_t usbd_req_set_device_feature(struct usb_device *udev, struct mtx *mtx, uint16_t sel);
+usb_error_t usbd_req_clear_device_feature(struct usb_device *udev,
+		    struct mtx *mtx, uint16_t sel);
+usb_error_t usbd_req_set_device_feature(struct usb_device *udev,
+		    struct mtx *mtx, uint16_t sel);
+usb_error_t usbd_req_set_hub_u1_timeout(struct usb_device *udev,
+		    struct mtx *mtx, uint8_t port, uint8_t timeout);
+usb_error_t usbd_req_set_hub_u2_timeout(struct usb_device *udev,
+		    struct mtx *mtx, uint8_t port, uint8_t timeout);
+usb_error_t usbd_req_set_hub_depth(struct usb_device *udev,
+		    struct mtx *mtx, uint16_t depth);
 
 #endif					/* _USB_REQUEST_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008011546.o71FkMK0006990>