0020-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. From 127961742cf7992f6989c6e89a18ab6d8f0b297f Mon Sep 17 00:00:00 2001
  2. From: Patrick Rudolph <patrick.rudolph@9elements.com>
  3. Date: Thu, 3 Dec 2020 13:44:55 +0100
  4. Subject: [PATCH 20/22] grub-core/bus/usb/usbhub: Add xHCI non root hub support
  5. Tested on Intel PCH C246, the USB3 hub can be configured by grub.
  6. Issues:
  7. * USB3 devices connected behind that hub are sometimes not detected.
  8. Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
  9. ---
  10. grub-core/bus/usb/usbhub.c | 38 +++++++++++++++++++++++++++++++++-----
  11. include/grub/usbdesc.h | 1 +
  12. include/grub/usbtrans.h | 4 ++++
  13. 3 files changed, 38 insertions(+), 5 deletions(-)
  14. diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
  15. index b4b3a1a61..e96505aa9 100644
  16. --- a/grub-core/bus/usb/usbhub.c
  17. +++ b/grub-core/bus/usb/usbhub.c
  18. @@ -148,19 +148,32 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
  19. return dev;
  20. }
  21. -
  22. +static grub_usb_err_t
  23. +grub_usb_set_hub_depth(grub_usb_device_t dev, grub_uint8_t depth)
  24. +{
  25. + return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
  26. + | GRUB_USB_REQTYPE_CLASS
  27. + | GRUB_USB_REQTYPE_TARGET_DEV),
  28. + GRUB_USB_HUB_REQ_SET_HUB_DEPTH, depth,
  29. + 0, 0, NULL);
  30. +}
  31. +
  32. static grub_usb_err_t
  33. grub_usb_add_hub (grub_usb_device_t dev)
  34. {
  35. struct grub_usb_usb_hubdesc hubdesc;
  36. grub_usb_err_t err;
  37. + grub_uint16_t req;
  38. int i;
  39. + req = (dev->speed == GRUB_USB_SPEED_SUPER) ? GRUB_USB_DESCRIPTOR_SS_HUB :
  40. + GRUB_USB_DESCRIPTOR_HUB;
  41. +
  42. err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
  43. | GRUB_USB_REQTYPE_CLASS
  44. | GRUB_USB_REQTYPE_TARGET_DEV),
  45. - GRUB_USB_REQ_GET_DESCRIPTOR,
  46. - (GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
  47. + GRUB_USB_REQ_GET_DESCRIPTOR,
  48. + (req << 8) | 0,
  49. 0, sizeof (hubdesc), (char *) &hubdesc);
  50. if (err)
  51. return err;
  52. @@ -183,6 +196,19 @@ grub_usb_add_hub (grub_usb_device_t dev)
  53. return GRUB_USB_ERR_INTERNAL;
  54. }
  55. + if (dev->speed == GRUB_USB_SPEED_SUPER)
  56. + {
  57. + grub_uint8_t depth;
  58. + grub_uint32_t route;
  59. + /* Depth maximum value is 5, but root hubs doesn't count */
  60. + for (depth = 0, route = dev->route; (route & 0xf) > 0; route >>= 4)
  61. + depth++;
  62. +
  63. + err = grub_usb_set_hub_depth(dev, depth);
  64. + if (err)
  65. + return err;
  66. + }
  67. +
  68. /* Power on all Hub ports. */
  69. for (i = 1; i <= hubdesc.portcnt; i++)
  70. {
  71. @@ -637,7 +663,9 @@ poll_nonroot_hub (grub_usb_device_t dev)
  72. int split_hubaddr = 0;
  73. /* Determine the device speed. */
  74. - if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED)
  75. + if (dev->speed == GRUB_USB_SPEED_SUPER)
  76. + speed = GRUB_USB_SPEED_SUPER;
  77. + else if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED)
  78. speed = GRUB_USB_SPEED_LOW;
  79. else
  80. {
  81. @@ -651,7 +679,7 @@ poll_nonroot_hub (grub_usb_device_t dev)
  82. grub_millisleep (10);
  83. /* Find correct values for SPLIT hubport and hubaddr */
  84. - if (speed == GRUB_USB_SPEED_HIGH)
  85. + if (speed == GRUB_USB_SPEED_HIGH || speed == GRUB_USB_SPEED_SUPER)
  86. {
  87. /* HIGH speed device needs not transaction translation */
  88. split_hubport = 0;
  89. diff --git a/include/grub/usbdesc.h b/include/grub/usbdesc.h
  90. index bb2ab2e27..1697aa465 100644
  91. --- a/include/grub/usbdesc.h
  92. +++ b/include/grub/usbdesc.h
  93. @@ -30,6 +30,7 @@ typedef enum {
  94. GRUB_USB_DESCRIPTOR_ENDPOINT,
  95. GRUB_USB_DESCRIPTOR_DEBUG = 10,
  96. GRUB_USB_DESCRIPTOR_HUB = 0x29,
  97. + GRUB_USB_DESCRIPTOR_SS_HUB = 0x2a,
  98. GRUB_USB_DESCRIPTOR_SS_ENDPOINT_COMPANION = 0x30
  99. } grub_usb_descriptor_t;
  100. diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h
  101. index 039ebed65..d6c3f71dc 100644
  102. --- a/include/grub/usbtrans.h
  103. +++ b/include/grub/usbtrans.h
  104. @@ -110,6 +110,10 @@ enum
  105. GRUB_USB_REQ_SET_INTERFACE = 0x0B,
  106. GRUB_USB_REQ_SYNC_FRAME = 0x0C
  107. };
  108. +enum
  109. + {
  110. + GRUB_USB_HUB_REQ_SET_HUB_DEPTH = 0x0C,
  111. + };
  112. #define GRUB_USB_FEATURE_ENDP_HALT 0x00
  113. #define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01
  114. --
  115. 2.39.2