summaryrefslogtreecommitdiff
path: root/config/grub/xhci/patches/0014-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch
diff options
context:
space:
mode:
Diffstat (limited to 'config/grub/xhci/patches/0014-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch')
-rw-r--r--config/grub/xhci/patches/0014-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch246
1 files changed, 246 insertions, 0 deletions
diff --git a/config/grub/xhci/patches/0014-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch b/config/grub/xhci/patches/0014-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch
new file mode 100644
index 00000000..4c84b8c3
--- /dev/null
+++ b/config/grub/xhci/patches/0014-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch
@@ -0,0 +1,246 @@
+From 3273128b6dc6df83ef6b1d54d009a1ae26844bff Mon Sep 17 00:00:00 2001
+From: Patrick Rudolph <patrick.rudolph@9elements.com>
+Date: Sun, 15 Nov 2020 19:00:27 +0100
+Subject: [PATCH 14/22] grub-core/bus/usb: Parse SuperSpeed companion
+ descriptors
+
+Parse the SS_ENDPOINT_COMPANION descriptor, which is only present on USB 3.0
+capable devices and xHCI controllers. Make the descendp an array of pointers
+to the endpoint descriptor as it's no longer an continous array.
+
+Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
+---
+ grub-core/bus/usb/serial/common.c | 2 +-
+ grub-core/bus/usb/usb.c | 44 +++++++++++++++++++------------
+ grub-core/bus/usb/usbhub.c | 22 ++++++++++++----
+ grub-core/commands/usbtest.c | 2 +-
+ grub-core/disk/usbms.c | 2 +-
+ grub-core/term/usb_keyboard.c | 2 +-
+ include/grub/usb.h | 2 +-
+ include/grub/usbdesc.h | 11 +++++++-
+ 8 files changed, 59 insertions(+), 28 deletions(-)
+
+diff --git a/grub-core/bus/usb/serial/common.c b/grub-core/bus/usb/serial/common.c
+index e9c995a0a..fc847d66d 100644
+--- a/grub-core/bus/usb/serial/common.c
++++ b/grub-core/bus/usb/serial/common.c
+@@ -72,7 +72,7 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno,
+ for (j = 0; j < interf->endpointcnt; j++)
+ {
+ struct grub_usb_desc_endp *endp;
+- endp = &usbdev->config[0].interf[interfno].descendp[j];
++ endp = usbdev->config[0].interf[interfno].descendp[j];
+
+ if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2
+ && (in_endp == GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING
+diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c
+index 7bd49d201..e578af793 100644
+--- a/grub-core/bus/usb/usb.c
++++ b/grub-core/bus/usb/usb.c
+@@ -118,7 +118,7 @@ grub_usb_device_initialize (grub_usb_device_t dev)
+ struct grub_usb_desc_device *descdev;
+ struct grub_usb_desc_config config;
+ grub_usb_err_t err;
+- int i;
++ int i, j;
+
+ /* First we have to read first 8 bytes only and determine
+ * max. size of packet */
+@@ -152,6 +152,7 @@ grub_usb_device_initialize (grub_usb_device_t dev)
+ int currif;
+ char *data;
+ struct grub_usb_desc *desc;
++ struct grub_usb_desc_endp *endp;
+
+ /* First just read the first 4 bytes of the configuration
+ descriptor, after that it is known how many bytes really have
+@@ -201,24 +202,27 @@ grub_usb_device_initialize (grub_usb_device_t dev)
+ = (struct grub_usb_desc_if *) &data[pos];
+ pos += dev->config[i].interf[currif].descif->length;
+
++ dev->config[i].interf[currif].descendp = grub_malloc (
++ dev->config[i].interf[currif].descif->endpointcnt *
++ sizeof(struct grub_usb_desc_endp));
++
++ j = 0;
+ while (pos < config.totallen)
+ {
+ desc = (struct grub_usb_desc *)&data[pos];
+- if (desc->type == GRUB_USB_DESCRIPTOR_ENDPOINT)
+- break;
+- if (!desc->length)
+- {
+- err = GRUB_USB_ERR_BADDEVICE;
+- goto fail;
+- }
+- pos += desc->length;
+- }
+-
+- /* Point to the first endpoint. */
+- dev->config[i].interf[currif].descendp
+- = (struct grub_usb_desc_endp *) &data[pos];
+- pos += (sizeof (struct grub_usb_desc_endp)
+- * dev->config[i].interf[currif].descif->endpointcnt);
++ if (desc->type == GRUB_USB_DESCRIPTOR_ENDPOINT) {
++ endp = (struct grub_usb_desc_endp *) &data[pos];
++ dev->config[i].interf[currif].descendp[j++] = endp;
++ pos += desc->length;
++ } else {
++ if (!desc->length)
++ {
++ err = GRUB_USB_ERR_BADDEVICE;
++ goto fail;
++ }
++ pos += desc->length;
++ }
++ }
+ }
+ }
+
+@@ -226,8 +230,14 @@ grub_usb_device_initialize (grub_usb_device_t dev)
+
+ fail:
+
+- for (i = 0; i < GRUB_USB_MAX_CONF; i++)
++ for (i = 0; i < GRUB_USB_MAX_CONF; i++) {
++ int currif;
++
++ for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
++ grub_free (dev->config[i].interf[currif].descendp);
++
+ grub_free (dev->config[i].descconf);
++ }
+
+ return err;
+ }
+diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
+index f5608e330..2ae29cba1 100644
+--- a/grub-core/bus/usb/usbhub.c
++++ b/grub-core/bus/usb/usbhub.c
+@@ -82,8 +82,14 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
+ if (i == GRUB_USBHUB_MAX_DEVICES)
+ {
+ grub_error (GRUB_ERR_IO, "can't assign address to USB device");
+- for (i = 0; i < GRUB_USB_MAX_CONF; i++)
+- grub_free (dev->config[i].descconf);
++ for (i = 0; i < GRUB_USB_MAX_CONF; i++) {
++ int currif;
++
++ for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
++ grub_free (dev->config[i].interf[currif].descendp);
++
++ grub_free (dev->config[i].descconf);
++ }
+ grub_free (dev);
+ return NULL;
+ }
+@@ -96,8 +102,14 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
+ i, 0, 0, NULL);
+ if (err)
+ {
+- for (i = 0; i < GRUB_USB_MAX_CONF; i++)
+- grub_free (dev->config[i].descconf);
++ for (i = 0; i < GRUB_USB_MAX_CONF; i++) {
++ int currif;
++
++ for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
++ grub_free (dev->config[i].interf[currif].descendp);
++
++ grub_free (dev->config[i].descconf);
++ }
+ grub_free (dev);
+ return NULL;
+ }
+@@ -176,7 +188,7 @@ grub_usb_add_hub (grub_usb_device_t dev)
+ i++)
+ {
+ struct grub_usb_desc_endp *endp = NULL;
+- endp = &dev->config[0].interf[0].descendp[i];
++ endp = dev->config[0].interf[0].descendp[i];
+
+ if ((endp->endp_addr & 128) && grub_usb_get_ep_type(endp)
+ == GRUB_USB_EP_INTERRUPT)
+diff --git a/grub-core/commands/usbtest.c b/grub-core/commands/usbtest.c
+index 2c6d93fe6..55a657635 100644
+--- a/grub-core/commands/usbtest.c
++++ b/grub-core/commands/usbtest.c
+@@ -185,7 +185,7 @@ usb_iterate (grub_usb_device_t dev, void *data __attribute__ ((unused)))
+ for (j = 0; j < interf->endpointcnt; j++)
+ {
+ struct grub_usb_desc_endp *endp;
+- endp = &dev->config[0].interf[i].descendp[j];
++ endp = dev->config[0].interf[i].descendp[j];
+
+ grub_printf ("Endpoint #%d: %s, max packed size: %d, transfer type: %s, latency: %d\n",
+ endp->endp_addr & 15,
+diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c
+index b81e3ad9d..b1512dc12 100644
+--- a/grub-core/disk/usbms.c
++++ b/grub-core/disk/usbms.c
+@@ -184,7 +184,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno)
+ for (j = 0; j < interf->endpointcnt; j++)
+ {
+ struct grub_usb_desc_endp *endp;
+- endp = &usbdev->config[0].interf[interfno].descendp[j];
++ endp = usbdev->config[0].interf[interfno].descendp[j];
+
+ if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2)
+ /* Bulk IN endpoint. */
+diff --git a/grub-core/term/usb_keyboard.c b/grub-core/term/usb_keyboard.c
+index 7322d8dff..d590979f5 100644
+--- a/grub-core/term/usb_keyboard.c
++++ b/grub-core/term/usb_keyboard.c
+@@ -175,7 +175,7 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno)
+ for (j = 0; j < usbdev->config[configno].interf[interfno].descif->endpointcnt;
+ j++)
+ {
+- endp = &usbdev->config[configno].interf[interfno].descendp[j];
++ endp = usbdev->config[configno].interf[interfno].descendp[j];
+
+ if ((endp->endp_addr & 128) && grub_usb_get_ep_type(endp)
+ == GRUB_USB_EP_INTERRUPT)
+diff --git a/include/grub/usb.h b/include/grub/usb.h
+index 0f346af12..688c11f6d 100644
+--- a/include/grub/usb.h
++++ b/include/grub/usb.h
+@@ -153,7 +153,7 @@ struct grub_usb_interface
+ {
+ struct grub_usb_desc_if *descif;
+
+- struct grub_usb_desc_endp *descendp;
++ struct grub_usb_desc_endp **descendp;
+
+ /* A driver is handling this interface. Do we need to support multiple drivers
+ for single interface?
+diff --git a/include/grub/usbdesc.h b/include/grub/usbdesc.h
+index aac5ab05a..bb2ab2e27 100644
+--- a/include/grub/usbdesc.h
++++ b/include/grub/usbdesc.h
+@@ -29,7 +29,8 @@ typedef enum {
+ GRUB_USB_DESCRIPTOR_INTERFACE,
+ GRUB_USB_DESCRIPTOR_ENDPOINT,
+ GRUB_USB_DESCRIPTOR_DEBUG = 10,
+- GRUB_USB_DESCRIPTOR_HUB = 0x29
++ GRUB_USB_DESCRIPTOR_HUB = 0x29,
++ GRUB_USB_DESCRIPTOR_SS_ENDPOINT_COMPANION = 0x30
+ } grub_usb_descriptor_t;
+
+ struct grub_usb_desc
+@@ -105,6 +106,14 @@ struct grub_usb_desc_endp
+ grub_uint8_t interval;
+ } GRUB_PACKED;
+
++struct grub_usb_desc_ssep {
++ grub_uint8_t length;
++ grub_uint8_t type;
++ grub_uint8_t maxburst;
++ grub_uint8_t attrib;
++ grub_uint16_t interval;
++} GRUB_PACKED;
++
+ struct grub_usb_desc_str
+ {
+ grub_uint8_t length;
+--
+2.39.2
+