Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Aug 2010 21:19:28 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 181694 for review
Message-ID:  <201008012119.o71LJSEA059735@repoman.freebsd.org>

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

Change 181694 by hselasky@hselasky_laptop001 on 2010/08/01 21:19:01

	USB core:
		- add support for more than 15 Root-HUB USB ports (SuperSpeed)
		Ordinary SuperSpeed HUBs cannot have more than up to
		and including 15 ports.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/usb.h#54 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_hub.c#51 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_request.c#36 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_request.h#13 edit

Differences ...

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

@@ -226,7 +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	USB_SS_HUB_DEPTH_MAX	5
 #define	UR_GET_PORT_ERR_COUNT	0x0d
 
 /* Feature numbers */
@@ -596,13 +596,13 @@
 struct usb_hub_ss_descriptor {
 	uByte	bLength;
 	uByte	bDescriptorType;
-	uByte	bNbrPorts;		/* max 15 */
+	uByte	bNbrPorts;
 	uWord	wHubCharacteristics;
 	uByte	bPwrOn2PwrGood;		/* delay in 2 ms units */
 	uByte	bHubContrCurrent;
 	uByte	bHubHdrDecLat;
 	uWord	wHubDelay;
-	uByte	DeviceRemovable[2];	/* max 15 ports */
+	uByte	DeviceRemovable[32];	/* max 255 ports */
 } __packed;
 typedef struct usb_hub_ss_descriptor usb_hub_ss_descriptor_t;
 

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

@@ -642,7 +642,7 @@
 			return (1);
 		break;
 	case USB_SPEED_SUPER:
-		if (udev->depth >= USB_SS_HUB_DEPTH_MAX)
+		if (udev->depth > USB_SS_HUB_DEPTH_MAX)
 			return (1);
 		break;
 	default:
@@ -879,13 +879,16 @@
 		}
 		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;
+		if (udev->parent_hub != NULL) {
+			err = usbd_req_set_hub_depth(udev, NULL,
+			    udev->depth - 1);
+			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);
+		err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30, 1);
 		if (err) {
 			DPRINTFN(0, "Getting USB 3.0 HUB descriptor failed,"
 			    "error=%s\n", usbd_errstr(err));
@@ -898,11 +901,26 @@
 		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;
+		/* get complete HUB descriptor */
+		if (nports >= 8) {
+			/* check number of ports */
+			if (nports > ((udev->parent_hub != NULL) ? 15 : 127)) {
+				DPRINTFN(0, "Invalid number of USB 3.0 ports,"
+				    "error=%s\n", usbd_errstr(err));
+				goto error;
+			}
+			/* get complete HUB descriptor */
+			err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30, nports);
+
+			if (err) {
+				DPRINTFN(0, "Getting USB 2.0 HUB descriptor failed,"
+				    "error=%s\n", usbd_errstr(err));
+				goto error;
+			}
+			if (hubdesc30.bNbrPorts != nports) {
+				DPRINTFN(0, "Number of ports changed\n");
+				goto error;
+			}
 		}
 		break;
 	default:

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

@@ -1301,15 +1301,16 @@
  *------------------------------------------------------------------------*/
 usb_error_t
 usbd_req_get_ss_hub_descriptor(struct usb_device *udev, struct mtx *mtx,
-    struct usb_hub_ss_descriptor *hd)
+    struct usb_hub_ss_descriptor *hd, uint8_t nports)
 {
 	struct usb_device_request req;
+	uint16_t len = sizeof(*hd) - 32 + 1 + ((nports + 7) / 8);
 
 	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));
+	USETW(req.wLength, len);
 	return (usbd_do_request(udev, mtx, &req, hd));
 }
 

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

@@ -57,7 +57,8 @@
 		    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);
+		    struct mtx *mtx, struct usb_hub_ss_descriptor *hd,
+		    uint8_t nports);
 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,



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