diff mbox

[U-Boot,06/20] usb: hub: Send correct wValue to get hub descriptor of a USB 3.0 hub

Message ID 1497619909-29454-7-git-send-email-bmeng.cn@gmail.com
State Superseded
Delegated to: Marek Vasut
Headers show

Commit Message

Bin Meng June 16, 2017, 1:31 p.m. UTC
Testing a USB 3.0 hub by connecting it to the xHCI port on Intel
MinnowMax, when issuing 'get hub descriptor' to the hub, xHCI
reports a transfer event TRB with a completion code 6 which means
'Stall Error'.

In fact super speed USB hub descriptor type is 0x2a, not 0x29.
Sending correct SETUP packet to the hub makes it not stall anymore.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
---

 common/usb_hub.c        | 12 +++++++++++-
 drivers/usb/host/xhci.c |  1 +
 include/usb_defs.h      |  1 +
 3 files changed, 13 insertions(+), 1 deletion(-)

Comments

Simon Glass June 17, 2017, 3:43 a.m. UTC | #1
On 16 June 2017 at 07:31, Bin Meng <bmeng.cn@gmail.com> wrote:
> Testing a USB 3.0 hub by connecting it to the xHCI port on Intel
> MinnowMax, when issuing 'get hub descriptor' to the hub, xHCI
> reports a transfer event TRB with a completion code 6 which means
> 'Stall Error'.
>
> In fact super speed USB hub descriptor type is 0x2a, not 0x29.
> Sending correct SETUP packet to the hub makes it not stall anymore.
>
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
>  common/usb_hub.c        | 12 +++++++++++-
>  drivers/usb/host/xhci.c |  1 +
>  include/usb_defs.h      |  1 +
>  3 files changed, 13 insertions(+), 1 deletion(-)

Reviewed-by: Simon Glass <sjg@chromium.org>
diff mbox

Patch

diff --git a/common/usb_hub.c b/common/usb_hub.c
index 8279e5c..ca830df 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -68,11 +68,21 @@  __weak void usb_hub_reset_devices(int port)
 	return;
 }
 
+static inline bool usb_hub_is_superspeed(struct usb_device *hdev)
+{
+	return hdev->descriptor.bDeviceProtocol == 3;
+}
+
 static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
 {
+	unsigned short dtype = USB_DT_HUB;
+
+	if (usb_hub_is_superspeed(dev))
+		dtype = USB_DT_SS_HUB;
+
 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 		USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
-		USB_DT_HUB << 8, 0, data, size, USB_CNTL_TIMEOUT);
+		dtype << 8, 0, data, size, USB_CNTL_TIMEOUT);
 }
 
 static int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index c949000..9fa0d8f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -727,6 +727,7 @@  static int xhci_submit_root(struct usb_device *udev, unsigned long pipe,
 	case USB_REQ_GET_DESCRIPTOR | ((USB_DIR_IN | USB_RT_HUB) << 8):
 		switch (le16_to_cpu(req->value) >> 8) {
 		case USB_DT_HUB:
+		case USB_DT_SS_HUB:
 			debug("USB_DT_HUB config\n");
 			srcptr = &descriptor.hub;
 			srclen = 0x8;
diff --git a/include/usb_defs.h b/include/usb_defs.h
index 8214ba9..608a0ca 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -93,6 +93,7 @@ 
 #define USB_DT_REPORT       (USB_TYPE_CLASS | 0x02)
 #define USB_DT_PHYSICAL     (USB_TYPE_CLASS | 0x03)
 #define USB_DT_HUB          (USB_TYPE_CLASS | 0x09)
+#define USB_DT_SS_HUB       (USB_TYPE_CLASS | 0x0a)
 
 /* Descriptor sizes per descriptor type */
 #define USB_DT_DEVICE_SIZE      18