128 lines
4.0 KiB
Diff
128 lines
4.0 KiB
Diff
From 127961742cf7992f6989c6e89a18ab6d8f0b297f Mon Sep 17 00:00:00 2001
|
||
From: Patrick Rudolph <patrick.rudolph@9elements.com>
|
||
Date: Thu, 3 Dec 2020 13:44:55 +0100
|
||
Subject: [PATCH 20/22] grub-core/bus/usb/usbhub: Add xHCI non root hub support
|
||
|
||
Tested on Intel PCH C246, the USB3 hub can be configured by grub.
|
||
|
||
Issues:
|
||
* USB3 devices connected behind that hub are sometimes not detected.
|
||
|
||
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
|
||
---
|
||
grub-core/bus/usb/usbhub.c | 38 +++++++++++++++++++++++++++++++++-----
|
||
include/grub/usbdesc.h | 1 +
|
||
include/grub/usbtrans.h | 4 ++++
|
||
3 files changed, 38 insertions(+), 5 deletions(-)
|
||
|
||
diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
|
||
index b4b3a1a61..e96505aa9 100644
|
||
--- a/grub-core/bus/usb/usbhub.c
|
||
+++ b/grub-core/bus/usb/usbhub.c
|
||
@@ -148,19 +148,32 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
|
||
return dev;
|
||
}
|
||
|
||
-
|
||
+static grub_usb_err_t
|
||
+grub_usb_set_hub_depth(grub_usb_device_t dev, grub_uint8_t depth)
|
||
+{
|
||
+ return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||
+ | GRUB_USB_REQTYPE_CLASS
|
||
+ | GRUB_USB_REQTYPE_TARGET_DEV),
|
||
+ GRUB_USB_HUB_REQ_SET_HUB_DEPTH, depth,
|
||
+ 0, 0, NULL);
|
||
+}
|
||
+
|
||
static grub_usb_err_t
|
||
grub_usb_add_hub (grub_usb_device_t dev)
|
||
{
|
||
struct grub_usb_usb_hubdesc hubdesc;
|
||
grub_usb_err_t err;
|
||
+ grub_uint16_t req;
|
||
int i;
|
||
|
||
+ req = (dev->speed == GRUB_USB_SPEED_SUPER) ? GRUB_USB_DESCRIPTOR_SS_HUB :
|
||
+ GRUB_USB_DESCRIPTOR_HUB;
|
||
+
|
||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||
| GRUB_USB_REQTYPE_CLASS
|
||
| GRUB_USB_REQTYPE_TARGET_DEV),
|
||
- GRUB_USB_REQ_GET_DESCRIPTOR,
|
||
- (GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
|
||
+ GRUB_USB_REQ_GET_DESCRIPTOR,
|
||
+ (req << 8) | 0,
|
||
0, sizeof (hubdesc), (char *) &hubdesc);
|
||
if (err)
|
||
return err;
|
||
@@ -183,6 +196,19 @@ grub_usb_add_hub (grub_usb_device_t dev)
|
||
return GRUB_USB_ERR_INTERNAL;
|
||
}
|
||
|
||
+ if (dev->speed == GRUB_USB_SPEED_SUPER)
|
||
+ {
|
||
+ grub_uint8_t depth;
|
||
+ grub_uint32_t route;
|
||
+ /* Depth maximum value is 5, but root hubs doesn't count */
|
||
+ for (depth = 0, route = dev->route; (route & 0xf) > 0; route >>= 4)
|
||
+ depth++;
|
||
+
|
||
+ err = grub_usb_set_hub_depth(dev, depth);
|
||
+ if (err)
|
||
+ return err;
|
||
+ }
|
||
+
|
||
/* Power on all Hub ports. */
|
||
for (i = 1; i <= hubdesc.portcnt; i++)
|
||
{
|
||
@@ -637,7 +663,9 @@ poll_nonroot_hub (grub_usb_device_t dev)
|
||
int split_hubaddr = 0;
|
||
|
||
/* Determine the device speed. */
|
||
- if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED)
|
||
+ if (dev->speed == GRUB_USB_SPEED_SUPER)
|
||
+ speed = GRUB_USB_SPEED_SUPER;
|
||
+ else if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED)
|
||
speed = GRUB_USB_SPEED_LOW;
|
||
else
|
||
{
|
||
@@ -651,7 +679,7 @@ poll_nonroot_hub (grub_usb_device_t dev)
|
||
grub_millisleep (10);
|
||
|
||
/* Find correct values for SPLIT hubport and hubaddr */
|
||
- if (speed == GRUB_USB_SPEED_HIGH)
|
||
+ if (speed == GRUB_USB_SPEED_HIGH || speed == GRUB_USB_SPEED_SUPER)
|
||
{
|
||
/* HIGH speed device needs not transaction translation */
|
||
split_hubport = 0;
|
||
diff --git a/include/grub/usbdesc.h b/include/grub/usbdesc.h
|
||
index bb2ab2e27..1697aa465 100644
|
||
--- a/include/grub/usbdesc.h
|
||
+++ b/include/grub/usbdesc.h
|
||
@@ -30,6 +30,7 @@ typedef enum {
|
||
GRUB_USB_DESCRIPTOR_ENDPOINT,
|
||
GRUB_USB_DESCRIPTOR_DEBUG = 10,
|
||
GRUB_USB_DESCRIPTOR_HUB = 0x29,
|
||
+ GRUB_USB_DESCRIPTOR_SS_HUB = 0x2a,
|
||
GRUB_USB_DESCRIPTOR_SS_ENDPOINT_COMPANION = 0x30
|
||
} grub_usb_descriptor_t;
|
||
|
||
diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h
|
||
index 039ebed65..d6c3f71dc 100644
|
||
--- a/include/grub/usbtrans.h
|
||
+++ b/include/grub/usbtrans.h
|
||
@@ -110,6 +110,10 @@ enum
|
||
GRUB_USB_REQ_SET_INTERFACE = 0x0B,
|
||
GRUB_USB_REQ_SYNC_FRAME = 0x0C
|
||
};
|
||
+enum
|
||
+ {
|
||
+ GRUB_USB_HUB_REQ_SET_HUB_DEPTH = 0x0C,
|
||
+ };
|
||
|
||
#define GRUB_USB_FEATURE_ENDP_HALT 0x00
|
||
#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01
|
||
--
|
||
2.39.2
|
||
|