123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- 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
|