[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cdi-devel] [PATCH 04/10] usb: Make descriptors inherit from a common base



* All USB descriptors share a common base which defines the length and
  the type of the descriptor. In order to have code that does not
  completely rely on fixed descriptor orderings (such as
  "configuration (interface (endpoint)*)*"), we need this type to be
  able to represent descriptors of undetermined type.

Signed-off-by: Max Reitz <max@xxxxxxxxxx>
---
 include/cdi/usb-structures.h | 18 +++++++++---------
 usb/usb.c                    | 20 +++++++++++---------
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/include/cdi/usb-structures.h b/include/cdi/usb-structures.h
index fecb609..f894b9e 100644
--- a/include/cdi/usb-structures.h
+++ b/include/cdi/usb-structures.h
@@ -18,9 +18,13 @@
 #include <stdint.h>
 
 
-struct cdi_usb_device_descriptor {
+struct cdi_usb_descriptor {
     uint8_t b_length;
     uint8_t b_descriptor_type;
+} __attribute__((packed));
+
+struct cdi_usb_device_descriptor {
+    struct cdi_usb_descriptor base;
     uint16_t bcd_usb;
     uint8_t b_device_class;
     uint8_t b_device_sub_class;
@@ -36,8 +40,7 @@ struct cdi_usb_device_descriptor {
 } __attribute__((packed));
 
 struct cdi_usb_configuration_descriptor {
-    uint8_t b_length;
-    uint8_t b_descriptor_type;
+    struct cdi_usb_descriptor base;
     uint16_t w_total_length;
     uint8_t b_num_interfaces;
     uint8_t b_configuration_value;
@@ -47,14 +50,12 @@ struct cdi_usb_configuration_descriptor {
 } __attribute__((packed));
 
 struct cdi_usb_string_descriptor {
-    uint8_t b_length;
-    uint8_t b_descriptor_type;
+    struct cdi_usb_descriptor base;
     uint16_t b_string[127];
 } __attribute__((packed));
 
 struct cdi_usb_interface_descriptor {
-    uint8_t b_length;
-    uint8_t b_descriptor_type;
+    struct cdi_usb_descriptor base;
     uint8_t b_interface_number;
     uint8_t b_alternate_setting;
     uint8_t b_num_endpoints;
@@ -66,8 +67,7 @@ struct cdi_usb_interface_descriptor {
 
 
 struct cdi_usb_endpoint_descriptor {
-    uint8_t b_length;
-    uint8_t b_descriptor_type;
+    struct cdi_usb_descriptor base;
     uint8_t b_endpoint_address;
     uint8_t bm_attributes;
     uint16_t w_max_packet_size;
diff --git a/usb/usb.c b/usb/usb.c
index 1f69c1b..489f362 100644
--- a/usb/usb.c
+++ b/usb/usb.c
@@ -223,8 +223,8 @@ static void get_string_descriptor(usb_device_t *dev, int index,
             .w_value            = (CDI_USB_DESC_STRING << 8) | index,
             .w_length           = 1
         }, dst);
-    if (res != CDI_USB_OK || !dst->b_length) {
-        dst->b_length = 0;
+    if (res != CDI_USB_OK || !dst->base.b_length) {
+        dst->base.b_length = 0;
         return;
     }
 
@@ -232,10 +232,10 @@ static void get_string_descriptor(usb_device_t *dev, int index,
             .bm_request_type    = CDI_USB_CREQ_DEVICE | CDI_USB_CREQ_IN,
             .b_request          = CDI_USB_CREQ_GET_DESCRIPTOR,
             .w_value            = (CDI_USB_DESC_STRING << 8) | index,
-            .w_length           = dst->b_length
+            .w_length           = dst->base.b_length
         }, dst);
     if (res != CDI_USB_OK) {
-        dst->b_length = 0;
+        dst->base.b_length = 0;
         return;
     }
 }
@@ -348,7 +348,7 @@ static void debug_device(usb_device_t *dev)
 
     if (dev->dev_desc.i_manufacturer) {
         get_string_descriptor(dev, dev->dev_desc.i_manufacturer, &str);
-        for (int i = 0; i < (str.b_length - 2) / 2; i++) {
+        for (int i = 0; i < (str.base.b_length - 2) / 2; i++) {
             putchar(str.b_string[i] > 0x7f ? '?' : str.b_string[i]);
         }
         putchar(' ');
@@ -356,7 +356,7 @@ static void debug_device(usb_device_t *dev)
 
     if (dev->dev_desc.i_product) {
         get_string_descriptor(dev, dev->dev_desc.i_product, &str);
-        for (int i = 0; i < (str.b_length - 2) / 2; i++) {
+        for (int i = 0; i < (str.base.b_length - 2) / 2; i++) {
             putchar(str.b_string[i] > 0x7f ? '?' : str.b_string[i]);
         }
         putchar(' ');
@@ -374,7 +374,7 @@ static void debug_configuration(usb_device_t *dev)
     if (dev->config->i_configuration) {
         get_string_descriptor(dev, dev->config->i_configuration, &str);
         putchar('(');
-        for (int i = 0; i < (str.b_length - 2) / 2; i++) {
+        for (int i = 0; i < (str.base.b_length - 2) / 2; i++) {
             putchar(str.b_string[i] > 0x7f ? '?' : str.b_string[i]);
         }
         putchar(')');
@@ -616,8 +616,10 @@ void usb_get_endpoint_descriptor(struct cdi_usb_device *dev, int ep,
         memcpy(desc, ep_info->desc, sizeof(*desc));
     } else {
         *desc = (struct cdi_usb_endpoint_descriptor){
-            .b_length           = sizeof(*desc),
-            .b_descriptor_type  = CDI_USB_DESC_ENDPOINT,
+            .base = {
+                .b_length           = sizeof(*desc),
+                .b_descriptor_type  = CDI_USB_DESC_ENDPOINT,
+            },
             .b_endpoint_address = 0,
             .bm_attributes      = 0x00,
             .w_max_packet_size  = ep_info->mps,
-- 
2.6.4