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

[cdi-devel] [PATCH 07/10] usb: Fix and simplify debugging code



+ emit_string_descriptor() makes debugging code simpler.
  (Incidentally, this fixes a bug in debug_configuration(); the upper
   limit of the for loop printing the interface name)
! Just as the main code, the debugging code assumed a certain order of
  descriptors with no gaps in between. Fix it.

Signed-off-by: Max Reitz <max@xxxxxxxxxx>
---
 usb/usb.c | 81 +++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 42 insertions(+), 39 deletions(-)

diff --git a/usb/usb.c b/usb/usb.c
index a8366e0..374ba57 100644
--- a/usb/usb.c
+++ b/usb/usb.c
@@ -333,6 +333,25 @@ static int choose_configuration(usb_device_t *dev)
 
 
 #ifdef DEBUG
+static void emit_string_descriptor(usb_device_t *dev, const char *format, int desc_i)
+{
+    if (!desc_i) {
+        return;
+    }
+
+    struct cdi_usb_string_descriptor str_desc;
+    get_string_descriptor(dev, desc_i, &str_desc);
+    int str_length = (str_desc.base.b_length - 2) / 2;
+    char str[str_length + 1];
+
+    for (int i = 0; i < str_length; i++) {
+        str[i] = str_desc.b_string[i] > 0x7f ? '?' : str_desc.b_string[i];
+    }
+    str[str_length] = 0;
+
+    printf(format, str);
+}
+
 static void debug_device(usb_device_t *dev)
 {
     printf("[usb] new %s device %04x:%04x (%x.%x.%x) ",
@@ -346,60 +365,44 @@ static void debug_device(usb_device_t *dev)
            dev->dev_desc.b_device_sub_class,
            dev->dev_desc.b_device_protocol);
 
-    struct cdi_usb_string_descriptor str;
-
-    if (dev->dev_desc.i_manufacturer) {
-        get_string_descriptor(dev, dev->dev_desc.i_manufacturer, &str);
-        for (int i = 0; i < (str.base.b_length - 2) / 2; i++) {
-            putchar(str.b_string[i] > 0x7f ? '?' : str.b_string[i]);
-        }
-        putchar(' ');
-    }
-
-    if (dev->dev_desc.i_product) {
-        get_string_descriptor(dev, dev->dev_desc.i_product, &str);
-        for (int i = 0; i < (str.base.b_length - 2) / 2; i++) {
-            putchar(str.b_string[i] > 0x7f ? '?' : str.b_string[i]);
-        }
-        putchar(' ');
-    }
+    emit_string_descriptor(dev, "%s ", dev->dev_desc.i_manufacturer);
+    emit_string_descriptor(dev, "%s ", dev->dev_desc.i_product);
 
     putchar('\n');
 }
 
+static struct cdi_usb_descriptor *next_desc(struct cdi_usb_descriptor *desc);
+
 static void debug_configuration(usb_device_t *dev)
 {
     printf("[usb] chose configuration %i ", dev->config->b_configuration_value);
+    emit_string_descriptor(dev, "(%s) ", dev->config->i_configuration);
+    printf("with %i interface(s):\n", dev->config->b_num_interfaces);
 
-    struct cdi_usb_string_descriptor str;
+    uintptr_t desc_end = (uintptr_t)dev->config + dev->config->w_total_length;
 
-    if (dev->config->i_configuration) {
-        get_string_descriptor(dev, dev->config->i_configuration, &str);
-        putchar('(');
-        for (int i = 0; i < (str.base.b_length - 2) / 2; i++) {
-            putchar(str.b_string[i] > 0x7f ? '?' : str.b_string[i]);
+    struct cdi_usb_descriptor *opaque_desc = next_desc(&dev->config->base);
+    int i = 0;
+    while ((uintptr_t)next_desc(opaque_desc) <= desc_end &&
+           i < (int)dev->config->b_num_interfaces)
+    {
+        struct cdi_usb_interface_descriptor *ifc = NULL;
+
+        if (opaque_desc->b_descriptor_type == CDI_USB_DESC_INTERFACE) {
+            i++;
+            ifc = CDI_UPCAST(opaque_desc,
+                             struct cdi_usb_interface_descriptor, base);
         }
-        putchar(')');
-        putchar(' ');
-    }
 
-    printf("with %i interface(s):\n", dev->config->b_num_interfaces);
+        opaque_desc = next_desc(opaque_desc);
+        if (!ifc) {
+            continue;
+        }
 
-    struct cdi_usb_interface_descriptor *ifc = (void *)(dev->config + 1);
-    for (int i = 0; i < (int)dev->config->b_num_interfaces; i++) {
         printf("[usb] ");
-        if (ifc->i_interface) {
-            get_string_descriptor(dev, ifc->i_interface, &str);
-            for (int j = 0; j < (int)dev->config->b_num_interfaces; j++) {
-                putchar(str.b_string[j] > 0x7f ? '?' : str.b_string[j]);
-            }
-            putchar(' ');
-        }
+        emit_string_descriptor(dev, "%s ", ifc->i_interface);
         printf("%x.%x.%x\n", ifc->b_interface_class,
                ifc->b_interface_sub_class, ifc->b_interface_protocol);
-
-        ifc = (void *)((struct cdi_usb_endpoint_descriptor *)(ifc + 1)
-                + ifc->b_num_endpoints);
     }
 }
 #endif
-- 
2.6.4