PERFORCE change 181694 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sun Aug 1 21:19:29 UTC 2010
http://p4web.freebsd.org/@@181694?ac=10
Change 181694 by hselasky at 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,
More information about the p4-projects
mailing list