Pārlūkot izejas kodu

update(core/usbh_core): do not use slist, we use recursion

sakumisu 1 gadu atpakaļ
vecāks
revīzija
10437a7d13
3 mainītis faili ar 148 papildinājumiem un 102 dzēšanām
  1. 17 14
      class/hub/usbh_hub.c
  2. 131 86
      core/usbh_core.c
  3. 0 2
      core/usbh_core.h

+ 17 - 14
class/hub/usbh_hub.c

@@ -366,8 +366,6 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
     hub->connected = true;
     hub->connected = true;
     snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, hub->index);
     snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, hub->index);
 
 
-    usb_slist_add_tail(&hub->bus->hub_list, &hub->list);
-
     USB_LOG_INFO("Register HUB Class:%s\r\n", hport->config.intf[intf].devname);
     USB_LOG_INFO("Register HUB Class:%s\r\n", hport->config.intf[intf].devname);
 
 
     hub->int_buffer = g_hub_intbuf[hub->bus->busid][hub->index - 1];
     hub->int_buffer = g_hub_intbuf[hub->bus->busid][hub->index - 1];
@@ -405,7 +403,6 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
 
 
         if (hport->config.intf[intf].devname[0] != '\0') {
         if (hport->config.intf[intf].devname[0] != '\0') {
             USB_LOG_INFO("Unregister HUB Class:%s\r\n", hport->config.intf[intf].devname);
             USB_LOG_INFO("Unregister HUB Class:%s\r\n", hport->config.intf[intf].devname);
-            usb_slist_remove(&hub->bus->hub_list, &hub->list);
         }
         }
 
 
         usbh_hub_class_free(hub);
         usbh_hub_class_free(hub);
@@ -555,8 +552,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
                         speed = USB_SPEED_HIGH;
                         speed = USB_SPEED_HIGH;
                     } else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) {
                     } else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) {
                         speed = USB_SPEED_LOW;
                         speed = USB_SPEED_LOW;
-                    }
-                    else {
+                    } else {
                         speed = USB_SPEED_FULL;
                         speed = USB_SPEED_FULL;
                     }
                     }
 
 
@@ -626,6 +622,17 @@ void usbh_hub_thread_wakeup(struct usbh_hub *hub)
 int usbh_hub_initialize(struct usbh_bus *bus)
 int usbh_hub_initialize(struct usbh_bus *bus)
 {
 {
     char thread_name[32] = { 0 };
     char thread_name[32] = { 0 };
+    struct usbh_hub *hub;
+
+    hub = &bus->hcd.roothub;
+    hub->connected = true;
+    hub->index = 1;
+    hub->is_roothub = true;
+    hub->parent = NULL;
+    hub->hub_addr = 1;
+    hub->hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS;
+    hub->int_buffer = bus->hcd.roothub_intbuf;
+    hub->bus = bus;
 
 
     bus->hub_mq = usb_osal_mq_create(7);
     bus->hub_mq = usb_osal_mq_create(7);
     if (bus->hub_mq == NULL) {
     if (bus->hub_mq == NULL) {
@@ -644,21 +651,17 @@ int usbh_hub_initialize(struct usbh_bus *bus)
 
 
 int usbh_hub_deinitialize(struct usbh_bus *bus)
 int usbh_hub_deinitialize(struct usbh_bus *bus)
 {
 {
-    usb_slist_t *hub_list;
     struct usbh_hubport *hport;
     struct usbh_hubport *hport;
+    struct usbh_hub *hub;
     size_t flags;
     size_t flags;
 
 
     flags = usb_osal_enter_critical_section();
     flags = usb_osal_enter_critical_section();
 
 
-    usb_slist_for_each(hub_list, &bus->hub_list)
-    {
-        struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
-
-        for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
-            hport = &hub->child[port];
+    hub = &bus->hcd.roothub;
+    for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+        hport = &hub->child[port];
 
 
-            usbh_hubport_release(hport);
-        }
+        usbh_hubport_release(hport);
     }
     }
 
 
     usb_hc_deinit(bus);
     usb_hc_deinit(bus);

+ 131 - 86
core/usbh_core.c

@@ -602,8 +602,6 @@ void usbh_hubport_release(struct usbh_hubport *hport)
 
 
 static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uint32_t reg_base)
 static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uint32_t reg_base)
 {
 {
-    struct usbh_hub *hub;
-
     memset(bus, 0, sizeof(struct usbh_bus));
     memset(bus, 0, sizeof(struct usbh_bus));
     bus->busid = busid;
     bus->busid = busid;
     bus->hcd.hcd_id = busid;
     bus->hcd.hcd_id = busid;
@@ -612,20 +610,6 @@ static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uint32_t reg_base
     /* devaddr 1 is for roothub */
     /* devaddr 1 is for roothub */
     bus->devgen.next = 2;
     bus->devgen.next = 2;
 
 
-    usb_slist_init(&bus->hub_list);
-
-    hub = &bus->hcd.roothub;
-    hub->connected = true;
-    hub->index = 1;
-    hub->is_roothub = true;
-    hub->parent = NULL;
-    hub->hub_addr = 1;
-    hub->hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS;
-    hub->int_buffer = bus->hcd.roothub_intbuf;
-    hub->bus = bus;
-
-    usb_slist_init(&bus->hub_list);
-    usb_slist_add_tail(&bus->hub_list, &hub->list);
     usb_slist_add_tail(&g_bus_head, &bus->list);
     usb_slist_add_tail(&g_bus_head, &bus->list);
 }
 }
 
 
@@ -669,7 +653,6 @@ int usbh_deinitialize(uint8_t busid)
 
 
     usbh_hub_deinitialize(bus);
     usbh_hub_deinitialize(bus);
 
 
-    usb_slist_init(&bus->hub_list);
     usb_slist_remove(&g_bus_head, &bus->list);
     usb_slist_remove(&g_bus_head, &bus->list);
 
 
     return 0;
     return 0;
@@ -742,37 +725,132 @@ int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsett
     return usbh_control_transfer(hport, setup, NULL);
     return usbh_control_transfer(hport, setup, NULL);
 }
 }
 
 
-void *usbh_find_class_instance(const char *devname)
+static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devname)
 {
 {
     struct usbh_hubport *hport;
     struct usbh_hubport *hport;
-    usb_slist_t *hub_list;
-    usb_slist_t *bus_list;
+    struct usbh_hub *hub_next;
+    void *priv;
+
+    for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+        hport = &hub->child[port];
+        if (hport->connected) {
+            for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
+                if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
+                    if ((strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0) && hport->config.intf[itf].priv)
+                        return hport->config.intf[itf].priv;
+
+                    if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
+                        hub_next = hport->config.intf[itf].priv;
+
+                        if (hub_next && hub_next->connected) {
+                            priv = usbh_list_all_interface_name(hub_next, devname);
+                            if (priv) {
+                                return priv;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return NULL;
+}
 
 
-    usb_slist_for_each(bus_list, &g_bus_head)
-    {
-        struct usbh_bus *bus = usb_slist_entry(bus_list, struct usbh_bus, list);
-        usb_slist_for_each(hub_list, &bus->hub_list)
-        {
-            struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
-            for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
-                hport = &hub->child[port];
-                if (hport->connected) {
-                    for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
-                        if ((strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0) && hport->config.intf[itf].priv)
-                            return hport->config.intf[itf].priv;
+static void usbh_list_all_interface_driver(struct usbh_hub *hub)
+{
+    struct usbh_hubport *hport;
+    struct usbh_hub *hub_next;
+
+    for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+        hport = &hub->child[port];
+        if (hport->connected) {
+            for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
+                if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
+                    for (uint8_t j = 0; j < hub->index; j++) {
+                        USB_LOG_RAW("\t");
+                    }
+
+                    USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s\r\n",
+                                hport->port,
+                                hport->dev_addr,
+                                itf,
+                                hport->config.intf[itf].class_driver->driver_name);
+
+                    if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
+                        hub_next = hport->config.intf[itf].priv;
+
+                        if (hub_next && hub_next->connected) {
+                            usbh_list_all_interface_driver(hub_next);
+                        }
                     }
                     }
                 }
                 }
             }
             }
         }
         }
     }
     }
+}
+
+static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub *hub)
+{
+    struct usbh_hubport *hport;
+    struct usbh_hub *hub_next;
+
+    for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+        hport = &hub->child[port];
+        if (hport->connected) {
+            USB_LOG_RAW("\r\nBus %u, Hub %u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n",
+                        bus->busid,
+                        hub->index,
+                        hport->port,
+                        hport->dev_addr,
+                        hport->device_desc.idVendor,
+                        hport->device_desc.idProduct);
+            usbh_print_hubport_info(hport);
+
+            for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
+                if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) {
+                    if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) {
+                        hub_next = hport->config.intf[itf].priv;
+
+                        if (hub_next && hub_next->connected) {
+                            usbh_list_all_interface_desc(bus, hub_next);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+void *usbh_find_class_instance(const char *devname)
+{
+    usb_slist_t *bus_list;
+    struct usbh_hub *hub;
+    struct usbh_bus *bus;
+    void *priv;
+    size_t flags;
+
+    flags = usb_osal_enter_critical_section();
+    usb_slist_for_each(bus_list, &g_bus_head)
+    {
+        bus = usb_slist_entry(bus_list, struct usbh_bus, list);
+        hub = &bus->hcd.roothub;
+
+        priv = usbh_list_all_interface_name(hub, devname);
+        if (priv) {
+            usb_osal_leave_critical_section(flags);
+            return priv;
+        }
+    }
+    usb_osal_leave_critical_section(flags);
     return NULL;
     return NULL;
 }
 }
 
 
 int lsusb(int argc, char **argv)
 int lsusb(int argc, char **argv)
 {
 {
-    usb_slist_t *hub_list;
     usb_slist_t *bus_list;
     usb_slist_t *bus_list;
-    struct usbh_hubport *hport;
+    struct usbh_hub *hub;
+    struct usbh_bus *bus;
+    size_t flags;
 
 
     if (argc < 2) {
     if (argc < 2) {
         USB_LOG_RAW("Usage: lsusb [options]...\r\n");
         USB_LOG_RAW("Usage: lsusb [options]...\r\n");
@@ -795,69 +873,36 @@ int lsusb(int argc, char **argv)
         return 0;
         return 0;
     }
     }
 
 
+    flags = usb_osal_enter_critical_section();
+
+    if (strcmp(argv[1], "-V") == 0) {
+        USB_LOG_RAW("CherryUSB Version %s\r\n", CHERRYUSB_VERSION_STR);
+    }
+
     if (strcmp(argv[1], "-t") == 0) {
     if (strcmp(argv[1], "-t") == 0) {
         usb_slist_for_each(bus_list, &g_bus_head)
         usb_slist_for_each(bus_list, &g_bus_head)
         {
         {
-            struct usbh_bus *bus = usb_slist_entry(bus_list, struct usbh_bus, list);
-            usb_slist_for_each(hub_list, &bus->hub_list)
-            {
-                struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
-
-                if (hub->is_roothub) {
-                    USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n",
-                                bus->busid,
-                                hub->index,
-                                hub->hub_desc.bNbrPorts);
-                } else {
-                    USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, mounted on Hub %02u:Port %u\r\n",
-                                bus->busid,
-                                hub->index,
-                                hub->hub_desc.bNbrPorts,
-                                hub->parent->parent->index,
-                                hub->parent->port);
-                }
-
-                for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
-                    hport = &hub->child[port];
-                    if (hport->connected) {
-                        for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
-                            if (hport->config.intf[i].class_driver && hport->config.intf[i].class_driver->driver_name) {
-                                USB_LOG_RAW("\t|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s\r\n",
-                                            hport->port,
-                                            hport->dev_addr,
-                                            i,
-                                            hport->config.intf[i].class_driver->driver_name);
-                            }
-                        }
-                    }
-                }
-            }
+            bus = usb_slist_entry(bus_list, struct usbh_bus, list);
+            hub = &bus->hcd.roothub;
+
+            USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n",
+                        bus->busid,
+                        hub->index,
+                        hub->hub_desc.bNbrPorts);
+            usbh_list_all_interface_driver(hub);
         }
         }
     }
     }
 
 
     if (strcmp(argv[1], "-v") == 0) {
     if (strcmp(argv[1], "-v") == 0) {
         usb_slist_for_each(bus_list, &g_bus_head)
         usb_slist_for_each(bus_list, &g_bus_head)
         {
         {
-            struct usbh_bus *bus = usb_slist_entry(bus_list, struct usbh_bus, list);
-            usb_slist_for_each(hub_list, &bus->hub_list)
-            {
-                struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
-                for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
-                    hport = &hub->child[port];
-                    if (hport->connected) {
-                        USB_LOG_RAW("Bus %u, Hub %02u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n",
-                                    bus->busid,
-                                    hub->index,
-                                    hport->port,
-                                    hport->dev_addr,
-                                    hport->device_desc.idVendor,
-                                    hport->device_desc.idProduct);
-                        usbh_print_hubport_info(hport);
-                    }
-                }
-            }
+            bus = usb_slist_entry(bus_list, struct usbh_bus, list);
+            hub = &bus->hcd.roothub;
+
+            usbh_list_all_interface_desc(bus, hub);
         }
         }
     }
     }
 
 
+    usb_osal_leave_critical_section(flags);
     return 0;
     return 0;
 }
 }

+ 0 - 2
core/usbh_core.h

@@ -116,7 +116,6 @@ struct usbh_hubport {
 };
 };
 
 
 struct usbh_hub {
 struct usbh_hub {
-    usb_slist_t list;
     bool connected;
     bool connected;
     bool is_roothub;
     bool is_roothub;
     uint8_t index;
     uint8_t index;
@@ -157,7 +156,6 @@ struct usbh_bus {
     struct usbh_devaddr_map devgen;
     struct usbh_devaddr_map devgen;
     usb_osal_thread_t hub_thread;
     usb_osal_thread_t hub_thread;
     usb_osal_mq_t hub_mq;
     usb_osal_mq_t hub_mq;
-    usb_slist_t hub_list;
 };
 };
 
 
 static inline void usbh_control_urb_fill(struct usbh_urb *urb,
 static inline void usbh_control_urb_fill(struct usbh_urb *urb,