diff options
Diffstat (limited to 'config/grub/xhci_nvme/patches/0020-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch')
| -rw-r--r-- | config/grub/xhci_nvme/patches/0020-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch | 127 | 
1 files changed, 127 insertions, 0 deletions
| diff --git a/config/grub/xhci_nvme/patches/0020-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch b/config/grub/xhci_nvme/patches/0020-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch new file mode 100644 index 00000000..31e831ec --- /dev/null +++ b/config/grub/xhci_nvme/patches/0020-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch @@ -0,0 +1,127 @@ +From d84ac94dc55baad9a2297980b2017cd22e4ecb3c Mon Sep 17 00:00:00 2001 +From: Patrick Rudolph <patrick.rudolph@9elements.com> +Date: Mon, 7 Dec 2020 08:41:27 +0100 +Subject: [PATCH 20/26] 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.5 + | 
