فهرست منبع

support multi USB IP for host

sakumisu 2 سال پیش
والد
کامیت
1158fc3d8c

+ 1 - 0
README.md

@@ -111,6 +111,7 @@ CherryUSB Host Stack has the following functions:
 - Support Remote NDIS (RNDIS)
 - Support Vendor class
 - Support USB modeswitch
+- Support multi host with the same USB IP
 
 The CherryUSB Host stack also provides the lsusb function, which allows you to view information about all mounted devices, including those on external hubs, with the help of a shell plugin.
 

+ 1 - 0
README_zh.md

@@ -109,6 +109,7 @@ CherryUSB Host 协议栈当前实现以下功能:
 - 支持 Remote NDIS (RNDIS)
 - 支持 Vendor 类 class
 - 支持 USB modeswitch
+- 支持相同 USB IP 的多主机
 
 同时,CherryUSB Host 协议栈还提供了 lsusb 的功能,借助 shell 插件可以查看所有挂载设备的信息,包括外部 hub 上的设备的信息。
 

+ 3 - 4
cherryusb_config_template.h

@@ -91,6 +91,7 @@
 
 /* ================ USB HOST Stack Configuration ================== */
 
+#define CONFIG_USBHOST_MAX_BUS              1
 #define CONFIG_USBHOST_MAX_RHPORTS          1
 #define CONFIG_USBHOST_MAX_EXTHUBS          1
 #define CONFIG_USBHOST_MAX_EHPORTS          4
@@ -137,18 +138,16 @@
 
 /* ================ USB Host Port Configuration ==================*/
 
-// #define USBH_IRQHandler         USBH_IRQHandler
-// #define USBH_BASE               (0)
 // #define CONFIG_USBHOST_PIPE_NUM 10
 
 /* ================ EHCI Configuration ================ */
 
-#define CONFIG_USB_EHCI_HCCR_BASE       (0x20072000)
-#define CONFIG_USB_EHCI_HCOR_BASE       (0x20072000 + 0x10)
+#define CONFIG_USB_EHCI_HCOR_OFFSET     (0x10)
 #define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
 // #define CONFIG_USB_EHCI_INFO_ENABLE
 // #define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
 // #define CONFIG_USB_EHCI_CONFIGFLAG
 // #define CONFIG_USB_EHCI_PORT_POWER
+// #define CONFIG_USB_EHCI_PRINT_HW_PARAM
 
 #endif

+ 42 - 71
class/hub/usbh_hub.c

@@ -15,15 +15,8 @@
 
 #define EXTHUB_FIRST_INDEX 2
 
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_buf[32];
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_intbuf[CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USB_ALIGN_SIZE];
-
-usb_slist_t hub_class_head = USB_SLIST_OBJECT_INIT(hub_class_head);
-
-usb_osal_thread_t hub_thread;
-usb_osal_mq_t hub_mq;
-
-struct usbh_hub roothub;
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_buf[CONFIG_USBHOST_MAX_BUS][32];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_intbuf[CONFIG_USBHOST_MAX_BUS][CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USB_ALIGN_SIZE];
 
 extern int usbh_free_devaddr(struct usbh_hubport *hport);
 extern int usbh_enumerate(struct usbh_hubport *hport);
@@ -67,17 +60,7 @@ static void usbh_hub_class_free(struct usbh_hub *hub_class)
 }
 #endif
 
-static void usbh_hub_register(struct usbh_hub *hub)
-{
-    usb_slist_add_tail(&hub_class_head, &hub->list);
-}
-
 #if CONFIG_USBHOST_MAX_EXTHUBS > 0
-static void usbh_hub_unregister(struct usbh_hub *hub)
-{
-    usb_slist_remove(&hub_class_head, &hub->list);
-}
-
 static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
 {
     struct usb_setup_packet *setup;
@@ -100,7 +83,7 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
     setup->wIndex = 0;
     setup->wLength = USB_SIZEOF_HUB_DESC;
 
-    ret = usbh_control_transfer(hub->parent, setup, g_hub_buf);
+    ret = usbh_control_transfer(hub->parent, setup, g_hub_buf[hub->bus->busid]);
     if (ret < 0) {
         return ret;
     }
@@ -144,11 +127,11 @@ static int _usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct h
     setup->wIndex = port;
     setup->wLength = 4;
 
-    ret = usbh_control_transfer(hub->parent, setup, g_hub_buf);
+    ret = usbh_control_transfer(hub->parent, setup, g_hub_buf[hub->bus->busid]);
     if (ret < 0) {
         return ret;
     }
-    memcpy(port_status, g_hub_buf, 4);
+    memcpy(port_status, g_hub_buf[hub->bus->busid], 4);
     return ret;
 }
 
@@ -233,7 +216,7 @@ static int usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hu
         setup->wValue = 0;
         setup->wIndex = port;
         setup->wLength = 4;
-        return usbh_roothub_control(&roothub_setup, (uint8_t *)port_status);
+        return usbh_roothub_control(hub->bus, &roothub_setup, (uint8_t *)port_status);
     } else {
         return _usbh_hub_get_portstatus(hub, port, port_status);
     }
@@ -251,7 +234,7 @@ int usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature)
         setup->wValue = feature;
         setup->wIndex = port;
         setup->wLength = 0;
-        return usbh_roothub_control(setup, NULL);
+        return usbh_roothub_control(hub->bus, setup, NULL);
     } else {
         return _usbh_hub_set_feature(hub, port, feature);
     }
@@ -269,7 +252,7 @@ int usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature)
         setup->wValue = feature;
         setup->wIndex = port;
         setup->wLength = 0;
-        return usbh_roothub_control(setup, NULL);
+        return usbh_roothub_control(hub->bus, setup, NULL);
     } else {
         return _usbh_hub_clear_feature(hub, port, feature);
     }
@@ -287,17 +270,12 @@ static int usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth)
         setup->wValue = depth;
         setup->wIndex = 0;
         setup->wLength = 0;
-        return usbh_roothub_control(setup, NULL);
+        return usbh_roothub_control(hub->bus, setup, NULL);
     } else {
         return _usbh_hub_set_depth(hub, depth);
     }
 }
 
-static void usbh_hub_thread_wakeup(struct usbh_hub *hub)
-{
-    usb_osal_mq_send(hub_mq, (uintptr_t)hub);
-}
-
 static void usbh_hubport_release(struct usbh_hubport *child)
 {
     if (child->connected) {
@@ -341,6 +319,7 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
 
     hub->hub_addr = hport->dev_addr;
     hub->parent = hport;
+    hub->bus = hport->bus;
 
     hport->config.intf[intf].priv = hub;
 
@@ -354,6 +333,7 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
     for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
         hub->child[port].port = port + 1;
         hub->child[port].parent = hub;
+        hub->child[port].bus = hport->bus;
     }
 
     ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc;
@@ -394,10 +374,12 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
 
     hub->connected = true;
     snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, hub->index);
-    usbh_hub_register(hub);
+
+    usb_slist_add_tail(&hub->bus->hub_list, &hub->list);
+
     USB_LOG_INFO("Register HUB Class:%s\r\n", hport->config.intf[intf].devname);
 
-    hub->int_buffer = g_hub_intbuf[hub->index - 1];
+    hub->int_buffer = g_hub_intbuf[hub->bus->busid][hub->index - 1];
     usbh_int_urb_fill(&hub->intin_urb, hub->parent, hub->intin, hub->int_buffer, 1, 0, hub_int_complete_callback, hub);
     usbh_submit_urb(&hub->intin_urb);
     return 0;
@@ -423,7 +405,7 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
 
         if (hport->config.intf[intf].devname[0] != '\0') {
             USB_LOG_INFO("Unregister HUB Class:%s\r\n", hport->config.intf[intf].devname);
-            usbh_hub_unregister(hub);
+            usb_slist_remove(&hub->bus->hub_list, &hub->list);
         }
 
         usbh_hub_class_free(hub);
@@ -461,7 +443,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
     }
 
     portchange_index = hub->int_buffer[0];
-    hub->int_buffer[0] = 0;
+    hub->int_buffer[0] &= ~portchange_index;
 
     for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
         USB_LOG_DBG("Port change:0x%02x\r\n", portchange_index);
@@ -602,9 +584,10 @@ static void usbh_hub_events(struct usbh_hub *hub)
                     child->connected = true;
                     child->port = port + 1;
                     child->speed = speed;
+                    child->bus = hub->bus;
                     child->mutex = usb_osal_mutex_create();
 
-                    USB_LOG_INFO("New %s device on Hub %u, Port %u connected\r\n", speed_table[speed], hub->index, port + 1);
+                    USB_LOG_INFO("New %s device on Bus %u, Hub %u, Port %u connected\r\n", speed_table[speed], hub->bus->busid, hub->index, port + 1);
 
                     /* create disposable thread to enumerate device on current hport, do not block hub thread */
                     usb_osal_thread_create("usbh_enum", CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hubport_enumerate_thread, (void *)child);
@@ -622,7 +605,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
                 child = &hub->child[port];
                 /** release child sources */
                 usbh_hubport_release(child);
-                USB_LOG_INFO("Device on Hub %u, Port %u disconnected\r\n", hub->index, port + 1);
+                USB_LOG_INFO("Device on Bus %u, Hub %u, Port %u disconnected\r\n", hub->bus->busid, hub->index, port + 1);
             }
         }
     }
@@ -638,9 +621,11 @@ static void usbh_hub_thread(void *argument)
     struct usbh_hub *hub;
     int ret = 0;
 
-    usb_hc_init();
+    struct usbh_bus *bus = (struct usbh_bus *)argument;
+
+    usb_hc_init(bus);
     while (1) {
-        ret = usb_osal_mq_recv(hub_mq, (uintptr_t *)&hub, USB_OSAL_WAITING_FOREVER);
+        ret = usb_osal_mq_recv(bus->hub_mq, (uintptr_t *)&hub, USB_OSAL_WAITING_FOREVER);
         if (ret < 0) {
             continue;
         }
@@ -648,55 +633,41 @@ static void usbh_hub_thread(void *argument)
     }
 }
 
-static void usbh_roothub_register(void)
-{
-    usb_slist_init(&hub_class_head);
-
-    memset(&roothub, 0, sizeof(struct usbh_hub));
-
-    roothub.connected = true;
-    roothub.index = 1;
-    roothub.is_roothub = true;
-    roothub.parent = NULL;
-    roothub.hub_addr = 1;
-    roothub.hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS;
-    usbh_hub_register(&roothub);
-}
-
-void usbh_roothub_thread_wakeup(uint8_t port)
+void usbh_hub_thread_wakeup(struct usbh_hub *hub)
 {
-    roothub.int_buffer = g_hub_intbuf[roothub.index - 1];
-    roothub.int_buffer[0] |= (1 << port);
-    usbh_hub_thread_wakeup(&roothub);
+    usb_osal_mq_send(hub->bus->hub_mq, (uintptr_t)hub);
 }
 
-int usbh_hub_initialize(void)
+int usbh_hub_initialize(struct usbh_bus *bus)
 {
-    usbh_roothub_register();
+    char thread_name[32] = { 0 };
 
-    hub_mq = usb_osal_mq_create(7);
-    if (hub_mq == NULL) {
+    bus->hub_mq = usb_osal_mq_create(7);
+    if (bus->hub_mq == NULL) {
+        USB_LOG_ERR("Failed to create hub mq\r\n");
         return -1;
     }
 
-    hub_thread = usb_osal_thread_create("usbh_hub", CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO, usbh_hub_thread, NULL);
-    if (hub_thread == NULL) {
+    snprintf(thread_name, 32, "usbh_hub%u", bus->busid);
+    bus->hub_thread = usb_osal_thread_create(thread_name, CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO, usbh_hub_thread, bus);
+    if (bus->hub_thread == NULL) {
+        USB_LOG_ERR("Failed to create hub thread\r\n");
         return -1;
     }
     return 0;
 }
 
-int usbh_hub_deinitialize(void)
+int usbh_hub_deinitialize(struct usbh_bus *bus)
 {
-    usb_slist_t *i;
+    usb_slist_t *hub_list;
     struct usbh_hubport *hport;
     size_t flags;
 
     flags = usb_osal_enter_critical_section();
 
-    usb_slist_for_each(i, &hub_class_head)
+    usb_slist_for_each(hub_list, &bus->hub_list)
     {
-        struct usbh_hub *hub = usb_slist_entry(i, struct usbh_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];
@@ -705,12 +676,12 @@ int usbh_hub_deinitialize(void)
         }
     }
 
-    usb_hc_deinit();
+    usb_hc_deinit(bus);
 
     usb_osal_leave_critical_section(flags);
 
-    usb_osal_mq_delete(hub_mq);
-    usb_osal_thread_delete(hub_thread);
+    usb_osal_mq_delete(bus->hub_mq);
+    usb_osal_thread_delete(bus->hub_thread);
 
     return 0;
 }

+ 5 - 6
class/hub/usbh_hub.h

@@ -8,13 +8,12 @@
 
 #include "usb_hub.h"
 
+struct usbh_hub;
+
 #define USBH_HUB_MAX_PORTS 4
 /* Maximum size of an interrupt IN transfer */
 #define USBH_HUB_INTIN_BUFSIZE ((USBH_HUB_MAX_PORTS + 8) >> 3)
 
-extern usb_slist_t hub_class_head;
-extern struct usbh_hub roothub;
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -22,10 +21,10 @@ extern "C" {
 int usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature);
 int usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature);
 
-void usbh_roothub_thread_wakeup(uint8_t port);
+void usbh_hub_thread_wakeup(struct usbh_hub *hub);
 
-int usbh_hub_initialize(void);
-int usbh_hub_deinitialize(void);
+int usbh_hub_initialize(struct usbh_bus *bus);
+int usbh_hub_deinitialize(struct usbh_bus *bus);
 
 #ifdef __cplusplus
 }

+ 6 - 4
common/usb_hc.h

@@ -14,6 +14,8 @@ extern "C" {
 
 typedef void (*usbh_complete_callback_t)(void *arg, int nbytes);
 
+struct usbh_bus;
+
 /**
  * @brief USB Iso Configuration.
  *
@@ -59,21 +61,21 @@ struct usbh_urb {
  *
  * @return On success will return 0, and others indicate fail.
  */
-int usb_hc_init(void);
+int usb_hc_init(struct usbh_bus *bus);
 
 /**
  * @brief usb host controller hardware deinit.
  *
  * @return On success will return 0, and others indicate fail.
  */
-int usb_hc_deinit(void);
+int usb_hc_deinit(struct usbh_bus *bus);
 
 /**
  * @brief Get frame number.
  *
  * @return frame number.
  */
-uint16_t usbh_get_frame_number(void);
+uint16_t usbh_get_frame_number(struct usbh_bus *bus);
 /**
  * @brief control roothub.
  *
@@ -81,7 +83,7 @@ uint16_t usbh_get_frame_number(void);
  * @param buf buf for reading response or write data.
  * @return On success will return 0, and others indicate fail.
  */
-int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf);
+int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf);
 
 /**
  * @brief Submit a usb transfer request to an endpoint.

+ 145 - 92
core/usbh_core.c

@@ -8,33 +8,19 @@
 struct usbh_class_info *usbh_class_info_table_begin = NULL;
 struct usbh_class_info *usbh_class_info_table_end = NULL;
 
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t ep0_request_buffer[CONFIG_USBHOST_REQUEST_BUFFER_LEN];
-USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct usb_setup_packet g_setup[CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USBHOST_MAX_EHPORTS];
+usb_slist_t g_bus_head = USB_SLIST_OBJECT_INIT(g_bus_head);
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t ep0_request_buffer[CONFIG_USBHOST_MAX_BUS][CONFIG_USBHOST_REQUEST_BUFFER_LEN];
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct usb_setup_packet g_setup_buffer[CONFIG_USBHOST_MAX_BUS][CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USBHOST_MAX_EHPORTS];
 
 /* general descriptor field offsets */
-#define DESC_bLength             0 /** Length offset */
-#define DESC_bDescriptorType     1 /** Descriptor type offset */
+#define DESC_bLength         0 /** Length offset */
+#define DESC_bDescriptorType 1 /** Descriptor type offset */
 
 #define USB_DEV_ADDR_MAX         0x7f
 #define USB_DEV_ADDR_MARK_OFFSET 5
 #define USB_DEV_ADDR_MARK_MASK   0x1f
 
-struct usbh_devaddr_map {
-    /**
-     * alloctab[0]:addr from 0~31
-     * alloctab[1]:addr from 32~63
-     * alloctab[2]:addr from 64~95
-     * alloctab[3]:addr from 96~127
-     *
-     */
-    uint8_t next;         /* Next device address */
-    uint32_t alloctab[4]; /* Bit allocation table */
-};
-
-struct usbh_bus {
-    struct usbh_devaddr_map devgen;
-} g_usbh_bus;
-
 static int usbh_allocate_devaddr(struct usbh_devaddr_map *devgen)
 {
     uint8_t startaddr = devgen->next;
@@ -227,15 +213,18 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
                     cur_ep = 0;
                     if (cur_iface > (CONFIG_USBHOST_MAX_INTERFACES - 1)) {
                         USB_LOG_ERR("Interface num overflow\r\n");
-                        return -USB_ERR_NOMEM;
+                        while (1) {
+                        }
                     }
                     if (cur_alt_setting > (CONFIG_USBHOST_MAX_INTF_ALTSETTINGS - 1)) {
                         USB_LOG_ERR("Interface altsetting num overflow\r\n");
-                        return -USB_ERR_NOMEM;
+                        while (1) {
+                        }
                     }
                     if (cur_ep_num > CONFIG_USBHOST_MAX_ENDPOINTS) {
                         USB_LOG_ERR("Endpoint num overflow\r\n");
-                        return -USB_ERR_NOMEM;
+                        while (1) {
+                        }
                     }
 #if 0
                     USB_LOG_DBG("Interface Descriptor:\r\n");
@@ -343,7 +332,7 @@ int usbh_free_devaddr(struct usbh_hubport *hport)
 {
 #ifndef CONFIG_USBHOST_XHCI
     if (hport->dev_addr > 0) {
-        __usbh_free_devaddr(&g_usbh_bus.devgen, hport->dev_addr);
+        __usbh_free_devaddr(&hport->bus->devgen, hport->dev_addr);
     }
 #endif
 
@@ -368,12 +357,12 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
     setup->wIndex = 0x0409;
     setup->wLength = 255;
 
-    ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
+    ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
     if (ret < 0) {
         return ret;
     }
 
-    src = ep0_request_buffer;
+    src = ep0_request_buffer[hport->bus->busid];
     dst = output;
     len = src[0];
 
@@ -409,7 +398,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
     uint16_t ep_mps;
     int ret;
 
-    hport->setup = &g_setup[hport->parent->index - 1][hport->port - 1];
+    hport->setup = &g_setup_buffer[hport->bus->busid][hport->parent->index - 1][hport->port - 1];
     setup = hport->setup;
     ep = &hport->ep0;
 
@@ -431,16 +420,16 @@ int usbh_enumerate(struct usbh_hubport *hport)
     setup->wIndex = 0;
     setup->wLength = 8;
 
-    ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
+    ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
     if (ret < 0) {
         USB_LOG_ERR("Failed to get device descriptor,errorcode:%d\r\n", ret);
         goto errout;
     }
 
-    parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer, 8);
+    parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid], 8);
 
     /* Extract the correct max packetsize from the device descriptor */
-    dev_desc = (struct usb_device_descriptor *)ep0_request_buffer;
+    dev_desc = (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid];
     if (dev_desc->bcdUSB >= USB_3_0) {
         ep_mps = 1 << dev_desc->bMaxPacketSize0;
     } else {
@@ -465,7 +454,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
     }
 #else
     /* Assign a function address to the device connected to this port */
-    dev_addr = usbh_allocate_devaddr(&g_usbh_bus.devgen);
+    dev_addr = usbh_allocate_devaddr(&hport->bus->devgen);
     if (dev_addr < 0) {
         USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret);
         goto errout;
@@ -498,17 +487,17 @@ int usbh_enumerate(struct usbh_hubport *hport)
     setup->wIndex = 0;
     setup->wLength = USB_SIZEOF_DEVICE_DESC;
 
-    ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
+    ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
     if (ret < 0) {
         USB_LOG_ERR("Failed to get full device descriptor,errorcode:%d\r\n", ret);
         goto errout;
     }
 
-    parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer, USB_SIZEOF_DEVICE_DESC);
+    parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid], USB_SIZEOF_DEVICE_DESC);
     USB_LOG_INFO("New device found,idVendor:%04x,idProduct:%04x,bcdDevice:%04x\r\n",
-                 ((struct usb_device_descriptor *)ep0_request_buffer)->idVendor,
-                 ((struct usb_device_descriptor *)ep0_request_buffer)->idProduct,
-                 ((struct usb_device_descriptor *)ep0_request_buffer)->bcdDevice);
+                 ((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->idVendor,
+                 ((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->idProduct,
+                 ((struct usb_device_descriptor *)ep0_request_buffer[hport->bus->busid])->bcdDevice);
 
     /* Read the first 9 bytes of the config descriptor */
     setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
@@ -517,7 +506,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
     setup->wIndex = 0;
     setup->wLength = USB_SIZEOF_CONFIG_DESC;
 
-    ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
+    ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
     if (ret < 0) {
         USB_LOG_ERR("Failed to get config descriptor,errorcode:%d\r\n", ret);
         goto errout;
@@ -534,18 +523,18 @@ int usbh_enumerate(struct usbh_hubport *hport)
     setup->wIndex = 0;
     setup->wLength = wTotalLength;
 
-    ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
+    ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]);
     if (ret < 0) {
         USB_LOG_ERR("Failed to get full config descriptor,errorcode:%d\r\n", ret);
         goto errout;
     }
 
-    ret = parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer, wTotalLength);
+    ret = parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid], wTotalLength);
     if (ret < 0) {
         USB_LOG_ERR("Parse config fail\r\n");
         goto errout;
     }
-    USB_LOG_INFO("The device has %d interfaces\r\n", ((struct usb_configuration_descriptor *)ep0_request_buffer)->bNumInterfaces);
+    USB_LOG_INFO("The device has %d interfaces\r\n", ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->bNumInterfaces);
     hport->raw_config_desc = usb_malloc(wTotalLength);
     if (hport->raw_config_desc == NULL) {
         ret = -USB_ERR_NOMEM;
@@ -640,10 +629,53 @@ errout:
     return ret;
 }
 
-int usbh_initialize(void)
+struct usbh_bus *usbh_alloc_bus(uint8_t busid, uint32_t reg_base)
 {
-    memset(&g_usbh_bus, 0, sizeof(struct usbh_bus));
+    struct usbh_bus *bus;
+    struct usbh_hub *hub;
+
+    if (busid > CONFIG_USBHOST_MAX_BUS) {
+        USB_LOG_ERR("bus overflow\r\n");
+        while (1) {
+        }
+    }
 
+    bus = usb_malloc(sizeof(struct usbh_bus));
+    if (bus == NULL) {
+        USB_LOG_ERR("No memory to alloc bus\r\n");
+        while (1) {
+        }
+    }
+
+    memset(bus, 0, sizeof(struct usbh_bus));
+    bus->busid = busid;
+    bus->hcd.hcd_id = busid;
+    bus->hcd.reg_base = reg_base;
+
+    /* devaddr 1 is for roothub */
+    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);
+
+    return bus;
+}
+
+int usbh_initialize(struct usbh_bus *bus)
+{
 #ifdef __ARMCC_VERSION /* ARM C Compiler */
     extern const int usbh_class_info$$Base;
     extern const int usbh_class_info$$Limit;
@@ -658,17 +690,19 @@ int usbh_initialize(void)
     usbh_class_info_table_begin = (struct usbh_class_info *)__section_begin("usbh_class_info");
     usbh_class_info_table_end = (struct usbh_class_info *)__section_end("usbh_class_info");
 #endif
-
-    /* devaddr 1 is for roothub */
-    g_usbh_bus.devgen.next = 2;
-
-    usbh_hub_initialize();
+    usbh_hub_initialize(bus);
     return 0;
 }
 
-int usbh_deinitialize(void)
+int usbh_deinitialize(struct usbh_bus *bus)
 {
-    return usbh_hub_deinitialize();
+    usbh_hub_deinitialize(bus);
+
+    usb_slist_init(&bus->hub_list);
+    usb_slist_remove(&g_bus_head, &bus->list);
+
+    usb_free(bus);
+    return 0;
 }
 
 int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer)
@@ -695,16 +729,21 @@ void *usbh_find_class_instance(const char *devname)
 {
     struct usbh_hubport *hport;
     usb_slist_t *hub_list;
+    usb_slist_t *bus_list;
 
-    usb_slist_for_each(hub_list, &hub_class_head)
+    usb_slist_for_each(bus_list, &g_bus_head)
     {
-        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;
+        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;
+                    }
                 }
             }
         }
@@ -714,7 +753,8 @@ void *usbh_find_class_instance(const char *devname)
 
 int lsusb(int argc, char **argv)
 {
-    usb_slist_t *i;
+    usb_slist_t *hub_list;
+    usb_slist_t *bus_list;
     struct usbh_hubport *hport;
 
     if (argc < 2) {
@@ -739,30 +779,38 @@ int lsusb(int argc, char **argv)
     }
 
     if (strcmp(argv[1], "-t") == 0) {
-        usb_slist_for_each(i, &hub_class_head)
+        usb_slist_for_each(bus_list, &g_bus_head)
         {
-            struct usbh_hub *hub = usb_slist_entry(i, struct usbh_hub, list);
-
-            if (hub->is_roothub) {
-                USB_LOG_RAW("/: Hub %02u, ports=%u, is roothub\r\n", hub->index, hub->hub_desc.bNbrPorts);
-            } else {
-                USB_LOG_RAW("/: Hub %02u, ports=%u, mounted on Hub %02u:Port %u\r\n",
-                            hub->index,
-                            hub->hub_desc.bNbrPorts,
-                            hub->parent->parent->index,
-                            hub->parent->port);
-            }
+            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->driver_name) {
-                            USB_LOG_RAW("    |__Port %u,Port addr:0x%02x,If %u,ClassDriver=%s\r\n",
-                                        hport->port,
-                                        hport->dev_addr,
-                                        i,
-                                        hport->config.intf[i].class_driver->driver_name);
+                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->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);
+                            }
                         }
                     }
                 }
@@ -771,19 +819,24 @@ int lsusb(int argc, char **argv)
     }
 
     if (strcmp(argv[1], "-v") == 0) {
-        usb_slist_for_each(i, &hub_class_head)
+        usb_slist_for_each(bus_list, &g_bus_head)
         {
-            struct usbh_hub *hub = usb_slist_entry(i, 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("Hub %02u,Port %u,Port addr:0x%02x,VID:PID 0x%04x:0x%04x\r\n",
-                                hub->index,
-                                hport->port,
-                                hport->dev_addr,
-                                hport->device_desc.idVendor,
-                                hport->device_desc.idProduct);
-                    usbh_print_hubport_info(hport);
+            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);
+                    }
                 }
             }
         }

+ 36 - 4
core/usbh_core.h

@@ -31,8 +31,8 @@ extern "C" {
 #define USB_CLASS_MATCH_INTF_SUBCLASS 0x0008
 #define USB_CLASS_MATCH_INTF_PROTOCOL 0x0010
 
-#define CLASS_CONNECT(hport, i)       ((hport)->config.intf[i].class_driver->connect(hport, i))
-#define CLASS_DISCONNECT(hport, i)    ((hport)->config.intf[i].class_driver->disconnect(hport, i))
+#define CLASS_CONNECT(hport, i)    ((hport)->config.intf[i].class_driver->connect(hport, i))
+#define CLASS_DISCONNECT(hport, i) ((hport)->config.intf[i].class_driver->disconnect(hport, i))
 
 #ifdef __ARMCC_VERSION /* ARM C Compiler */
 #define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
@@ -106,6 +106,7 @@ struct usbh_hubport {
     uint8_t *raw_config_desc;
     struct usb_setup_packet *setup;
     struct usbh_hub *parent;
+    struct usbh_bus *bus;
 #ifdef CONFIG_USBHOST_XHCI
     uint32_t protocol; /* port protocol, for xhci, some ports are USB2.0, others are USB3.0 */
 #endif
@@ -123,11 +124,41 @@ struct usbh_hub {
     struct usb_hub_descriptor hub_desc;
     struct usbh_hubport child[CONFIG_USBHOST_MAX_EHPORTS];
     struct usbh_hubport *parent;
+    struct usbh_bus *bus;
     struct usb_endpoint_descriptor *intin;
     struct usbh_urb intin_urb;
     uint8_t *int_buffer;
 };
 
+struct usbh_devaddr_map {
+    /**
+     * alloctab[0]:addr from 0~31
+     * alloctab[1]:addr from 32~63
+     * alloctab[2]:addr from 64~95
+     * alloctab[3]:addr from 96~127
+     *
+     */
+    uint8_t next;         /* Next device address */
+    uint32_t alloctab[4]; /* Bit allocation table */
+};
+
+struct usbh_hcd {
+    uint32_t reg_base;
+    uint8_t hcd_id;
+    uint8_t roothub_intbuf[1];
+    struct usbh_hub roothub;
+};
+
+struct usbh_bus {
+    usb_slist_t list;
+    uint8_t busid;
+    struct usbh_hcd hcd;
+    struct usbh_devaddr_map devgen;
+    usb_osal_thread_t hub_thread;
+    usb_osal_mq_t hub_mq;
+    usb_slist_t hub_list;
+};
+
 static inline void usbh_control_urb_fill(struct usbh_urb *urb,
                                          struct usbh_hubport *hport,
                                          struct usb_setup_packet *setup,
@@ -225,8 +256,9 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
  */
 int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting);
 
-int usbh_initialize(void);
-int usbh_deinitialize(void);
+struct usbh_bus *usbh_alloc_bus(uint8_t busid, uint32_t reg_base);
+int usbh_initialize(struct usbh_bus *bus);
+int usbh_deinitialize(struct usbh_bus *bus);
 void *usbh_find_class_instance(const char *devname);
 
 int lsusb(int argc, char **argv);

+ 16 - 1
docs/source/api/api_host.rst

@@ -111,6 +111,19 @@ hub 结构体
         uint8_t *int_buffer;
     };
 
+usbh_alloc_bus
+""""""""""""""""""""""""""""""""""""
+
+``usbh_alloc_bus`` 用于创建一个 bus,并且根据 reg_base 分配一个 hcd
+
+.. code-block:: C
+
+    struct usbh_bus *usbh_alloc_bus(uint8_t busid, uint32_t reg_base);
+
+- **busid**  bus id,从 0开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
+- **reg_base**  hcd 寄存器基地址
+- 返回 bus 句柄
+
 usbh_initialize
 """"""""""""""""""""""""""""""""""""
 
@@ -118,7 +131,9 @@ usbh_initialize
 
 .. code-block:: C
 
-    int usbh_initialize(void);
+    int usbh_initialize(struct usbh_bus *bus);
+
+- **bus**  bus 句柄
 
 usbh_find_class_instance
 """"""""""""""""""""""""""""""""""""

+ 5 - 5
docs/source/porting_usbip.rst

@@ -216,17 +216,17 @@ EHCI 是 intel 制定的标准主机控制器接口,任何厂家都必须实
 
 .. code-block:: C
 
-  //Host Controller Capability Register BASE
-  #define CONFIG_USB_EHCI_HCCR_BASE (0xxx)
-  //Host Controller Operational Register BASE
-  #define CONFIG_USB_EHCI_HCOR_BASE (0xxx)
+  //Host Controller Operational Register BASE 距离基地址的偏移
+  #define CONFIG_USB_EHCI_HCOR_OFFSET (0x14)
   //是否打印 ehci 配置信息
   #define CONFIG_USB_EHCI_INFO_ENABLE
   //是否关闭保留寄存器的占位,默认保留 9 个双字的占位
-  #define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
+  #define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
   //是否使能 configflag 寄存器中的 bit0
   #define CONFIG_USB_EHCI_CONFIGFLAG
   //是否使能 port power bit
   #define CONFIG_USB_EHCI_PORT_POWER
+  //是否查看 ehci 配置信息
+  #define CONFIG_USB_EHCI_PRINT_HW_PARAM
 
 同时由于 EHCI 只是主机控制器并且只支持高速,一般配合一个 otg 控制器和一个低速全速兼容控制单元,而速度的获取一般是在 otg 寄存器中,所以需要用户实现 `usbh_get_port_speed` 函数。

BIN
docs/source/quick_start/img/stm32_18.png


BIN
docs/source/quick_start/img/stm32_19.png


+ 16 - 10
docs/source/quick_start/index.rst

@@ -4,7 +4,6 @@
 在学习 USB 或者是学习 CherryUSB 代码之前,我们需要先基于现有的 demo 进行快速验证,为什么?是为了提升对 USB 的兴趣,能有信心进行下一步的动作,如果 demo 都跑不起来,或者自己摸索写代码,或者先看 USB 基本概念,结果看到最后,
 发现一点都看不懂,概念好多,根本记不住,从而丧失对 USB 的兴趣。因此,先跑 demo 非常重要。下面我将给大家罗列目前支持的 demo 仓库。
 
-
 基于 bouffalolab 系列芯片
 ---------------------------
 
@@ -105,6 +104,15 @@ USB Device 移植要点
     #define CONFIG_USBDEV_EP_NUM 6          // pa11/pa12 引脚使用 4
     #define CONFIG_USB_DWC2_RAM_SIZE 4096 // pa11/pa12 引脚使用 1280
 
+- 如果使用 fsdev ip,在 `usb_config.h` 中实现以下宏:
+
+.. code-block:: C
+
+    #define USBD_IRQHandler USB_LP_CAN1_RX0_IRQHandler
+    #define USBD_BASE (0x40005C00UL)
+    #define CONFIG_USBDEV_EP_NUM 8
+    #define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2
+
 - 编译器推荐使用 **AC6**。勾选 **Microlib**,并实现 **printf** ,方便后续查看 log。
 
 .. figure:: img/stm32_10.png
@@ -134,12 +142,6 @@ USB Host 移植要点
 .. figure:: img/stm32_10.png
 .. figure:: img/stm32_11.png
 
-- 拷贝 **xxx_msp.c** 中的 **HAL_HCD_MspInit** 函数中的内容到 **usb_hc_low_level_init** 函数中,屏蔽 st 生成的 usb 中断函数和 usb 初始化
-
-.. figure:: img/stm32_18.png
-.. figure:: img/stm32_13.png
-.. figure:: img/stm32_19.png
-
 - 复制一份 **cherryusb_config_template.h**,放到 `Core/Inc` 目录下,并命名为 `usb_config.h`
 
 - 增加 **usb_glue_st.c** 文件,并在 `usb_config.h` 中实现以下宏:
@@ -147,12 +149,16 @@ USB Host 移植要点
 .. code-block:: C
 
     // 以下细节如有出入,请对照 stm32xxx.h 文件修改
-    #define USBH_BASE (0x40040000UL)
-    #define USBH_IRQHandler OTG_HS_IRQHandler
     #define CONFIG_USBHOST_PIPE_NUM 12
 
-- 调用 **usbh_initialize** 以及 os 需要的启动线程的函数即可使用
+- 拷贝 **xxx_msp.c** 中的 `HAL_HCD_MspInit` 函数中的内容到 `usb_hc_low_level_init` 函数中,屏蔽 st 生成的 usb 初始化
+- 在中断函数中调用 `USBH_IRQHandler`,并传入 bus 句柄
+- 调用 `usbh_alloc_bus` 创建 bus, `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
+- 调用 `usbh_initialize` 即可
+- 启动线程
 
+.. figure:: img/stm32_18.png
+.. figure:: img/stm32_19.png
 .. figure:: img/stm32_20.png
 
 - 如果使用 **msc**,并且带文件系统,需要自行添加文件系统文件了,对应的 porting 编写参考 **fatfs_usbh.c** 文件。

+ 5 - 5
docs/source/quick_start/other_chip.rst

@@ -20,14 +20,14 @@ USB Device 移植要点
 USB Host 移植要点
 -----------------------
 
+.. note:: 请注意,当前是最新版本,支持多 port 功能,`USBH_BASE` 和 `USBH_IRQHandler` 的宏不能再使用,并且必须调用 `usbh_alloc_bus`,具体按照以下步骤执行。
+
 - 拷贝 CherryUSB 源码到工程目录下,并按需添加源文件和头文件路径,其中 `usbh_core.c` 、 `usb_hc_xxx.c` 以及 **osal** 目录下源文件(根据不同的 os 选择对应的源文件)为必须添加项。而 `usb_hc_xxx.c` 是芯片所对应的 USB IP dcd 部分驱动,如果不知道自己芯片属于那个 USB IP,参考 **port** 目录下的不同 USB IP 的 readme。如果使用的 USB IP 没有支持,只能自己实现了
 - 拷贝 `cherryusb_config_template.h` 文件到自己工程目录下,命名为 `usb_config.h`,并添加相应的目录头文件路径
-- 在 `usb_config.h` 中添加 `USBH_IRQHandler=xxxx` 、 `CONFIG_USBHOST_PIPE_NUM=x` 以及 `USBH_BASE=0xxxxx` 三个常规 porting 需要的宏
-
-.. note:: 上述三个宏仅对 musb、dwc2 有效,因为这 2 个是通用 IP
-
 - 实现 `usb_hc_low_level_init` 函数(该函数主要负责 USB 时钟、引脚、中断的初始化)。该函数可以放在你想要放的任何参与编译的 c 文件中。如何进行 USB 的时钟、引脚、中断等初始化,请自行根据你使用的芯片原厂提供的源码中进行添加。
-- 调用 `usbh_initialize` 初始化 usb 硬件
+- 调用 `usbh_alloc_bus` 创建 bus,填入 USB IP 的基地址, `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
+- 在中断函数中调用 `USBH_IRQHandler`,并传入 bus 句柄, 如果你的 SDK 中中断入口已经存在 `USBH_IRQHandler` ,请更改 USB 协议栈中的名称
+- 调用 `usbh_initialize` 
 - 如果使用的是 GCC ,需要在链接脚本(ld)中添加如下代码:
 
 .. code-block:: C

+ 31 - 10
docs/source/quick_start/rt-thread/rtthread.rst

@@ -35,7 +35,7 @@
 
 .. figure:: img/config_file.png
 
-* 使用 `scons --target=mdk` 或者 `scons` 进行编译
+* 使用 `scons --target=mdk5` 或者 `scons` 进行编译
 
 主机配置
 --------------------------
@@ -48,15 +48,36 @@
 
 .. figure:: img/env8.png
 
-* 默认使能除了 hub 之外的所有 class 驱动。
-* 设置 psc 线程的线程栈以及线程优先级。
+* 根据需要勾选 class 驱动
 * 最后退出保存即可。
-* 退出以后不急着编译,需要在代码中实现 `usb_hc_low_level_init` 函数。
 * 复制一份 `usb_config.h` 到自己的目录中,并实现以下内容, 禁止包含 `"rtthread.h"` :
 
 .. figure:: img/config_file.png
 
-* 使用 `scons --target=mdk` 或者 `scons` 进行编译
+* 在代码中实现 `usb_hc_low_level_init` 函数,USB 中断中调用 `USBH_IRQHandler`, 
+* 应用中调用 `usbh_alloc_bus` 和 `usbh_initialize`, 
+* 以上内容我们推荐放在 **board.c** 中,如下代码:
+
+.. code-block:: C
+
+        struct usbh_bus *usb_otg_hs_bus;
+
+        void OTG_HS_IRQHandler(void)
+        {
+        extern void USBH_IRQHandler(struct usbh_bus *bus);
+        USBH_IRQHandler(usb_otg_hs_bus);
+        }
+
+        int usbh_init(void)
+        {
+        usb_otg_hs_bus = usbh_alloc_bus(0, USB_OTG_HS_PERIPH_BASE);
+        usbh_initialize(usb_otg_hs_bus);
+        return 0;
+        }
+
+        INIT_APP_EXPORT(usbh_init);
+
+* 使用 `scons --target=mdk5` 或者 `scons` 进行编译,需要使用 AC6 编译器
 * 如果使用的是 GCC ,需要在链接脚本(ld)中添加如下代码:
 
 .. code-block:: C
@@ -71,17 +92,17 @@
 借助 STM32CubeMX 生成 USB 初始化
 ----------------------------------
 
-使用 STM32CubeMX 主要是用来生成 usb 时钟、引脚、中断的配置。我们需要点击如图所示文件,并配置好 USB 的时钟、中断,点击 `Generate Code`。生成的时钟配置在 `main.c` 中的 `SystemClock_Config` 文件,将其拷贝到 `board.c` 中。
+使用 STM32CubeMX 主要是用来生成 usb 时钟、引脚、中断的配置。我们需要点击如图所示文件,并配置好 USB 的时钟、中断,点击 `Generate Code`。
 
 .. figure:: img/stm32cubemx0.png
 .. figure:: img/stm32cubemx1.png
 .. figure:: img/stm32cubemx2.png
 .. figure:: img/stm32cubemx_clk.png
 
-然后将 `stm32xxxx_hal_msp.c` 中的 `HAL_PCD_MspInit` 或者是 `HAL_HCD_MspInit` 中的内容复制到 `usb_dc_low_level_init` 和 `usb_hc_low_level_init` 函数中,举例如下:
+- 将 `main.c` 中的 `SystemClock_Config` 替换掉 `board.c` 中的配置
 
-.. figure:: img/stm32_init.png
+.. figure:: img/stm32_init2.png
 
-其次将 `main.c` 中的 `SystemClock_Config` 替换掉 `board.c` 中的配置
+- 将 `stm32xxxx_hal_msp.c` 中的 `HAL_PCD_MspInit` 或者是 `HAL_HCD_MspInit` 中的内容复制到 `usb_dc_low_level_init` 和 `usb_hc_low_level_init` 函数中,举例如下:
 
-.. figure:: img/stm32_init2.png
+.. figure:: img/stm32_init.png

+ 126 - 122
port/dwc2/usb_hc_dwc2.c

@@ -7,24 +7,16 @@
 #include "usbh_hub.h"
 #include "usb_dwc2_reg.h"
 
-#ifndef USBH_IRQHandler
-#error "please define USBH_IRQHandler in usb_config.h"
-#endif
-
-#ifndef USBH_BASE
-#error "please define USBH_BASE in usb_config.h"
-#endif
-
 #ifndef CONFIG_USBHOST_PIPE_NUM
 #define CONFIG_USBHOST_PIPE_NUM 12
 #endif
 
-#define USB_OTG_GLB     ((USB_OTG_GlobalTypeDef *)(USBH_BASE))
-#define USB_OTG_PCGCCTL *(__IO uint32_t *)((uint32_t)USBH_BASE + USB_OTG_PCGCCTL_BASE)
-#define USB_OTG_HPRT    *(__IO uint32_t *)((uint32_t)USBH_BASE + USB_OTG_HOST_PORT_BASE)
-#define USB_OTG_HOST    ((USB_OTG_HostTypeDef *)(USBH_BASE + USB_OTG_HOST_BASE))
-#define USB_OTG_HC(i)   ((USB_OTG_HostChannelTypeDef *)(USBH_BASE + USB_OTG_HOST_CHANNEL_BASE + ((i)*USB_OTG_HOST_CHANNEL_SIZE)))
-#define USB_OTG_FIFO(i) *(__IO uint32_t *)(USBH_BASE + USB_OTG_FIFO_BASE + ((i)*USB_OTG_FIFO_SIZE))
+#define USB_OTG_GLB     ((USB_OTG_GlobalTypeDef *)(bus->hcd.reg_base))
+#define USB_OTG_PCGCCTL *(__IO uint32_t *)((uint32_t)bus->hcd.reg_base + USB_OTG_PCGCCTL_BASE)
+#define USB_OTG_HPRT    *(__IO uint32_t *)((uint32_t)bus->hcd.reg_base + USB_OTG_HOST_PORT_BASE)
+#define USB_OTG_HOST    ((USB_OTG_HostTypeDef *)(bus->hcd.reg_base + USB_OTG_HOST_BASE))
+#define USB_OTG_HC(i)   ((USB_OTG_HostChannelTypeDef *)(bus->hcd.reg_base + USB_OTG_HOST_CHANNEL_BASE + ((i)*USB_OTG_HOST_CHANNEL_SIZE)))
+#define USB_OTG_FIFO(i) *(__IO uint32_t *)(bus->hcd.reg_base + USB_OTG_FIFO_BASE + ((i)*USB_OTG_FIFO_SIZE))
 
 struct dwc2_chan {
     uint8_t ep0_state;
@@ -42,7 +34,7 @@ struct dwc2_hcd {
     volatile bool port_pec;
     volatile bool port_occ;
     struct dwc2_chan chan_pool[CONFIG_USBHOST_PIPE_NUM];
-} g_dwc2_hcd;
+} g_dwc2_hcd[CONFIG_USBHOST_MAX_BUS];
 
 #define DWC2_EP0_STATE_SETUP     0
 #define DWC2_EP0_STATE_INDATA    1
@@ -50,7 +42,7 @@ struct dwc2_hcd {
 #define DWC2_EP0_STATE_INSTATUS  3
 #define DWC2_EP0_STATE_OUTSTATUS 4
 
-static inline int dwc2_reset(void)
+static inline int dwc2_reset(struct usbh_bus *bus)
 {
     volatile uint32_t count = 0U;
 
@@ -74,7 +66,7 @@ static inline int dwc2_reset(void)
     return 0;
 }
 
-static inline int dwc2_core_init(void)
+static inline int dwc2_core_init(struct usbh_bus *bus)
 {
     int ret;
 #if defined(CONFIG_USB_DWC2_ULPI_PHY)
@@ -86,17 +78,17 @@ static inline int dwc2_core_init(void)
 
     //USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
     /* Reset after a PHY select */
-    ret = dwc2_reset();
+    ret = dwc2_reset(bus);
 #else
     /* Select FS Embedded PHY */
     USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
     /* Reset after a PHY select */
-    ret = dwc2_reset();
+    ret = dwc2_reset(bus);
 #endif
     return ret;
 }
 
-static inline void dwc2_set_mode(uint8_t mode)
+static inline void dwc2_set_mode(struct usbh_bus *bus, uint8_t mode)
 {
     USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
 
@@ -107,7 +99,7 @@ static inline void dwc2_set_mode(uint8_t mode)
     }
 }
 
-static inline int dwc2_flush_rxfifo(void)
+static inline int dwc2_flush_rxfifo(struct usbh_bus *bus)
 {
     volatile uint32_t count = 0;
 
@@ -122,7 +114,7 @@ static inline int dwc2_flush_rxfifo(void)
     return 0;
 }
 
-static inline int dwc2_flush_txfifo(uint32_t num)
+static inline int dwc2_flush_txfifo(struct usbh_bus *bus, uint32_t num)
 {
     volatile uint32_t count = 0U;
 
@@ -137,7 +129,7 @@ static inline int dwc2_flush_txfifo(uint32_t num)
     return 0;
 }
 
-static inline void dwc2_drivebus(uint8_t state)
+static inline void dwc2_drivebus(struct usbh_bus *bus, uint8_t state)
 {
     __IO uint32_t hprt0 = 0U;
 
@@ -154,7 +146,7 @@ static inline void dwc2_drivebus(uint8_t state)
     }
 }
 
-static void dwc2_chan_init(uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps, uint8_t speed)
+static void dwc2_chan_init(struct usbh_bus *bus, uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps, uint8_t speed)
 {
     uint32_t regval;
 
@@ -217,7 +209,7 @@ static void dwc2_chan_init(uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uin
 }
 
 /* For IN channel HCTSIZ.XferSize is expected to be an integer multiple of ep_mps size.*/
-static inline void dwc2_chan_transfer(uint8_t ch_num, uint8_t ep_addr, uint32_t *buf, uint32_t size, uint8_t num_packets, uint8_t pid)
+static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint8_t ep_addr, uint32_t *buf, uint32_t size, uint8_t num_packets, uint8_t pid)
 {
     __IO uint32_t tmpreg;
     uint8_t is_oddframe;
@@ -241,7 +233,7 @@ static inline void dwc2_chan_transfer(uint8_t ch_num, uint8_t ep_addr, uint32_t
     USB_OTG_HC(ch_num)->HCCHAR = tmpreg;
 }
 
-static void dwc2_halt(uint8_t ch_num)
+static void dwc2_halt(struct usbh_bus *bus, uint8_t ch_num)
 {
     volatile uint32_t count = 0U;
     uint32_t HcEpType = (USB_OTG_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
@@ -288,7 +280,7 @@ static void dwc2_halt(uint8_t ch_num)
     }
 }
 
-static int usbh_reset_port(const uint8_t port)
+static int usbh_reset_port(struct usbh_bus *bus, const uint8_t port)
 {
     __IO uint32_t hprt0 = 0U;
 
@@ -308,7 +300,7 @@ static int usbh_reset_port(const uint8_t port)
     return 0;
 }
 
-static uint8_t usbh_get_port_speed(const uint8_t port)
+static uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
 {
     __IO uint32_t hprt0 = 0U;
     uint8_t speed;
@@ -332,7 +324,7 @@ static uint8_t usbh_get_port_speed(const uint8_t port)
   * @brief  dwc2_get_glb_intstatus: return the global USB interrupt status
   * @retval status
   */
-static inline uint32_t dwc2_get_glb_intstatus(void)
+static inline uint32_t dwc2_get_glb_intstatus(struct usbh_bus *bus)
 {
     uint32_t tmpreg;
 
@@ -342,13 +334,13 @@ static inline uint32_t dwc2_get_glb_intstatus(void)
     return tmpreg;
 }
 
-static int dwc2_chan_alloc(void)
+static int dwc2_chan_alloc(struct usbh_bus *bus)
 {
     int chidx;
 
     for (chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
-        if (!g_dwc2_hcd.chan_pool[chidx].inuse) {
-            g_dwc2_hcd.chan_pool[chidx].inuse = true;
+        if (!g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].inuse) {
+            g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].inuse = true;
             return chidx;
         }
     }
@@ -358,7 +350,11 @@ static int dwc2_chan_alloc(void)
 
 static void dwc2_chan_free(struct dwc2_chan *chan)
 {
+    size_t flags;
+    
+    flags = usb_osal_enter_critical_section();
     chan->inuse = false;
+    usb_osal_leave_critical_section(flags);
 }
 
 static uint8_t dwc2_calculate_packet_num(uint32_t input_size, uint8_t ep_addr, uint16_t ep_mps, uint32_t *output_size)
@@ -384,77 +380,77 @@ static uint8_t dwc2_calculate_packet_num(uint32_t input_size, uint8_t ep_addr, u
     return num_packets;
 }
 
-static void dwc2_control_urb_init(uint8_t chidx, struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
+static void dwc2_control_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
 {
     struct dwc2_chan *chan;
 
-    chan = &g_dwc2_hcd.chan_pool[chidx];
+    chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx];
 
     if (chan->ep0_state == DWC2_EP0_STATE_SETUP) /* fill setup */
     {
         chan->num_packets = dwc2_calculate_packet_num(8, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
-        dwc2_chan_init(chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
-        dwc2_chan_transfer(chidx, 0x00, (uint32_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP);
+        dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+        dwc2_chan_transfer(bus, chidx, 0x00, (uint32_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP);
     } else if (chan->ep0_state == DWC2_EP0_STATE_INDATA) /* fill in data */
     {
         chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
-        dwc2_chan_init(chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
-        dwc2_chan_transfer(chidx, 0x80, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+        dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+        dwc2_chan_transfer(bus, chidx, 0x80, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
     } else if (chan->ep0_state == DWC2_EP0_STATE_OUTDATA) /* fill out data */
     {
         chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
-        dwc2_chan_init(chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
-        dwc2_chan_transfer(chidx, 0x00, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+        dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+        dwc2_chan_transfer(bus, chidx, 0x00, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
     } else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) /* fill in status */
     {
         chan->num_packets = dwc2_calculate_packet_num(0, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
-        dwc2_chan_init(chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
-        dwc2_chan_transfer(chidx, 0x80, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+        dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+        dwc2_chan_transfer(bus, chidx, 0x80, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
     } else if (chan->ep0_state == DWC2_EP0_STATE_OUTSTATUS) /* fill out status */
     {
         chan->num_packets = dwc2_calculate_packet_num(0, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
-        dwc2_chan_init(chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
-        dwc2_chan_transfer(chidx, 0x00, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+        dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+        dwc2_chan_transfer(bus, chidx, 0x00, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
     }
 }
 
-static void dwc2_bulk_intr_urb_init(uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
+static void dwc2_bulk_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
 {
     struct dwc2_chan *chan;
 
-    chan = &g_dwc2_hcd.chan_pool[chidx];
+    chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx];
 
     chan->num_packets = dwc2_calculate_packet_num(buflen, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
-    dwc2_chan_init(chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes), USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
-    dwc2_chan_transfer(chidx, urb->ep->bEndpointAddress, (uint32_t *)buffer, chan->xferlen, chan->num_packets, urb->data_toggle);
+    dwc2_chan_init(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes), USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+    dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, (uint32_t *)buffer, chan->xferlen, chan->num_packets, urb->data_toggle);
 }
 
-static void dwc2_iso_urb_init(uint8_t chidx, struct usbh_urb *urb, struct usbh_iso_frame_packet *iso_packet)
+static void dwc2_iso_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, struct usbh_iso_frame_packet *iso_packet)
 {
     struct dwc2_chan *chan;
 
-    chan = &g_dwc2_hcd.chan_pool[chidx];
+    chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx];
 
     chan->num_packets = dwc2_calculate_packet_num(iso_packet->transfer_buffer_length, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
-    dwc2_chan_init(chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_ENDPOINT_TYPE_ISOCHRONOUS, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
-    dwc2_chan_transfer(chidx, urb->ep->bEndpointAddress, (uint32_t *)iso_packet->transfer_buffer, chan->xferlen, chan->num_packets, HC_PID_DATA0);
+    dwc2_chan_init(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_ENDPOINT_TYPE_ISOCHRONOUS, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+    dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, (uint32_t *)iso_packet->transfer_buffer, chan->xferlen, chan->num_packets, HC_PID_DATA0);
 }
 
-__WEAK void usb_hc_low_level_init(void)
+__WEAK void usb_hc_low_level_init(struct usbh_bus *bus)
 {
 }
 
-int usb_hc_init(void)
+int usb_hc_init(struct usbh_bus *bus)
 {
     int ret;
 
-    memset(&g_dwc2_hcd, 0, sizeof(struct dwc2_hcd));
+    memset(&g_dwc2_hcd[bus->hcd.hcd_id], 0, sizeof(struct dwc2_hcd));
 
     for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
-        g_dwc2_hcd.chan_pool[chidx].waitsem = usb_osal_sem_create(0);
+        g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].waitsem = usb_osal_sem_create(0);
     }
 
-    usb_hc_low_level_init();
+    usb_hc_low_level_init(bus);
 
     USB_LOG_INFO("========== dwc2 hcd params ==========\r\n");
     USB_LOG_INFO("GCCFG:%08x\r\n", USB_OTG_GLB->GCCFG);
@@ -478,10 +474,10 @@ int usb_hc_init(void)
     /* This is vendor register */
     USB_OTG_GLB->GCCFG = usbh_get_dwc2_gccfg_conf();
 
-    ret = dwc2_core_init();
+    ret = dwc2_core_init(bus);
 
     /* Force Host Mode*/
-    dwc2_set_mode(USB_OTG_MODE_HOST);
+    dwc2_set_mode(bus, USB_OTG_MODE_HOST);
     usb_osal_msleep(50);
 
     /* Restart the Phy Clock */
@@ -490,8 +486,8 @@ int usb_hc_init(void)
     /* Set default Max speed support */
     USB_OTG_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
 
-    ret = dwc2_flush_txfifo(0x10U);
-    ret = dwc2_flush_rxfifo();
+    ret = dwc2_flush_txfifo(bus, 0x10U);
+    ret = dwc2_flush_rxfifo(bus);
 
     /* Clear all pending HC Interrupts */
     for (uint8_t i = 0U; i < CONFIG_USBHOST_PIPE_NUM; i++) {
@@ -499,7 +495,7 @@ int usb_hc_init(void)
         USB_OTG_HC(i)->HCINTMSK = 0U;
     }
 
-    dwc2_drivebus(1);
+    dwc2_drivebus(bus, 1);
     usb_osal_msleep(200);
 
     /* Disable all interrupts. */
@@ -525,15 +521,15 @@ int usb_hc_init(void)
     return 0;
 }
 
-int usb_hc_deinit(void)
+int usb_hc_deinit(struct usbh_bus *bus)
 {
     volatile uint32_t count = 0U;
     uint32_t value;
 
     USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
 
-    dwc2_flush_txfifo(0x10U);
-    dwc2_flush_rxfifo();
+    dwc2_flush_txfifo(bus, 0x10U);
+    dwc2_flush_rxfifo(bus);
 
     /* Flush out any leftover queued requests. */
     for (uint32_t i = 0U; i <= 15U; i++) {
@@ -566,22 +562,22 @@ int usb_hc_deinit(void)
     USB_OTG_HOST->HAINT = 0xFFFFFFFFU;
     USB_OTG_GLB->GINTSTS = 0xFFFFFFFFU;
 
-    dwc2_drivebus(0);
+    dwc2_drivebus(bus, 0);
     usb_osal_msleep(200);
 
     for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
-        usb_osal_sem_delete(g_dwc2_hcd.chan_pool[chidx].waitsem);
+        usb_osal_sem_delete(g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].waitsem);
     }
 
     return 0;
 }
 
-uint16_t usbh_get_frame_number(void)
+uint16_t usbh_get_frame_number(struct usbh_bus *bus)
 {
     return (USB_OTG_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
 }
 
-int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
+int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf)
 {
     __IO uint32_t hprt0;
     uint8_t nports;
@@ -637,13 +633,13 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
                     case HUB_PORT_FEATURE_POWER:
                         break;
                     case HUB_PORT_FEATURE_C_CONNECTION:
-                        g_dwc2_hcd.port_csc = 0;
+                        g_dwc2_hcd[bus->hcd.hcd_id].port_csc = 0;
                         break;
                     case HUB_PORT_FEATURE_C_ENABLE:
-                        g_dwc2_hcd.port_pec = 0;
+                        g_dwc2_hcd[bus->hcd.hcd_id].port_pec = 0;
                         break;
                     case HUB_PORT_FEATURE_C_OVER_CURREN:
-                        g_dwc2_hcd.port_occ = 0;
+                        g_dwc2_hcd[bus->hcd.hcd_id].port_occ = 0;
                         break;
                     case HUB_PORT_FEATURE_C_RESET:
                         break;
@@ -663,7 +659,7 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
                         USB_OTG_HPRT &= ~USB_OTG_HPRT_PPWR;
                         break;
                     case HUB_PORT_FEATURE_RESET:
-                        usbh_reset_port(port);
+                        usbh_reset_port(bus, port);
                         break;
 
                     default:
@@ -677,13 +673,13 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
                 hprt0 = USB_OTG_HPRT;
 
                 status = 0;
-                if (g_dwc2_hcd.port_csc) {
+                if (g_dwc2_hcd[bus->hcd.hcd_id].port_csc) {
                     status |= (1 << HUB_PORT_FEATURE_C_CONNECTION);
                 }
-                if (g_dwc2_hcd.port_pec) {
+                if (g_dwc2_hcd[bus->hcd.hcd_id].port_pec) {
                     status |= (1 << HUB_PORT_FEATURE_C_ENABLE);
                 }
-                if (g_dwc2_hcd.port_occ) {
+                if (g_dwc2_hcd[bus->hcd.hcd_id].port_occ) {
                     status |= (1 << HUB_PORT_FEATURE_C_OVER_CURREN);
                 }
 
@@ -692,9 +688,9 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
                 }
                 if (hprt0 & USB_OTG_HPRT_PENA) {
                     status |= (1 << HUB_PORT_FEATURE_ENABLE);
-                    if (usbh_get_port_speed(port) == USB_SPEED_LOW) {
+                    if (usbh_get_port_speed(bus, port) == USB_SPEED_LOW) {
                         status |= (1 << HUB_PORT_FEATURE_LOWSPEED);
-                    } else if (usbh_get_port_speed(port) == USB_SPEED_HIGH) {
+                    } else if (usbh_get_port_speed(bus, port) == USB_SPEED_HIGH) {
                         status |= (1 << HUB_PORT_FEATURE_HIGHSPEED);
                     }
                 }
@@ -720,11 +716,12 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
 int usbh_submit_urb(struct usbh_urb *urb)
 {
     struct dwc2_chan *chan;
+    struct usbh_bus *bus;
     size_t flags;
     int ret = 0;
     int chidx;
 
-    if (!urb || !urb->hport || !urb->ep) {
+    if (!urb || !urb->hport || !urb->ep || !urb->hport->bus) {
         return -USB_ERR_INVAL;
     }
 
@@ -733,6 +730,8 @@ int usbh_submit_urb(struct usbh_urb *urb)
         return -USB_ERR_INVAL;
     }
 
+    bus = urb->hport->bus;
+
     if (!(USB_OTG_HPRT & USB_OTG_HPRT_PCSTS) || !urb->hport->connected) {
         return -USB_ERR_NOTCONN;
     }
@@ -743,13 +742,13 @@ int usbh_submit_urb(struct usbh_urb *urb)
 
     flags = usb_osal_enter_critical_section();
 
-    chidx = dwc2_chan_alloc();
+    chidx = dwc2_chan_alloc(bus);
     if (chidx == -1) {
         usb_osal_leave_critical_section(flags);
         return -USB_ERR_NOMEM;
     }
 
-    chan = &g_dwc2_hcd.chan_pool[chidx];
+    chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx];
     chan->chidx = chidx;
     chan->urb = urb;
 
@@ -762,11 +761,11 @@ int usbh_submit_urb(struct usbh_urb *urb)
     switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
         case USB_ENDPOINT_TYPE_CONTROL:
             chan->ep0_state = DWC2_EP0_STATE_SETUP;
-            dwc2_control_urb_init(chidx, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+            dwc2_control_urb_init(bus, chidx, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
             break;
         case USB_ENDPOINT_TYPE_BULK:
         case USB_ENDPOINT_TYPE_INTERRUPT:
-            dwc2_bulk_intr_urb_init(chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
+            dwc2_bulk_intr_urb_init(bus, chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
             break;
         case USB_ENDPOINT_TYPE_ISOCHRONOUS:
             break;
@@ -795,17 +794,20 @@ errout_timeout:
 int usbh_kill_urb(struct usbh_urb *urb)
 {
     struct dwc2_chan *chan;
+    struct usbh_bus *bus;
     size_t flags;
 
-    if (!urb || !urb->hcpriv) {
+    if (!urb || !urb->hcpriv || !urb->hport->bus) {
         return -USB_ERR_INVAL;
     }
 
+    bus = urb->hport->bus;
+
     flags = usb_osal_enter_critical_section();
 
     chan = (struct dwc2_chan *)urb->hcpriv;
 
-    dwc2_halt(chan->chidx);
+    dwc2_halt(bus, chan->chidx);
     CLEAR_HC_INT(chan->chidx, USB_OTG_HCINT_CHH);
 
     chan->urb = NULL;
@@ -848,7 +850,7 @@ static inline void dwc2_urb_waitup(struct usbh_urb *urb)
     }
 }
 
-static void dwc2_inchan_irq_handler(uint8_t ch_num)
+static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
 {
     uint32_t chan_intstatus;
     struct dwc2_chan *chan;
@@ -856,7 +858,7 @@ static void dwc2_inchan_irq_handler(uint8_t ch_num)
 
     chan_intstatus = (USB_OTG_HC(ch_num)->HCINT) & (USB_OTG_HC((uint32_t)ch_num)->HCINTMSK);
 
-    chan = &g_dwc2_hcd.chan_pool[ch_num];
+    chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[ch_num];
     urb = chan->urb;
     //printf("s1:%08x\r\n", chan_intstatus);
 
@@ -864,51 +866,51 @@ static void dwc2_inchan_irq_handler(uint8_t ch_num)
         urb->errorcode = 0;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) {
         urb->errorcode = -USB_ERR_IO;
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
     } else if ((chan_intstatus & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) {
         urb->errorcode = -USB_ERR_STALL;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK) {
         urb->errorcode = -USB_ERR_NAK;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK) {
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
     } else if ((chan_intstatus & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET) {
         urb->errorcode = -USB_ERR_NAK;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR) {
         urb->errorcode = -USB_ERR_IO;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR) {
         urb->errorcode = -USB_ERR_BABBLE;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR) {
         urb->errorcode = -USB_ERR_IO;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR) {
         urb->errorcode = -USB_ERR_DT;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH) {
         USB_MASK_HALT_HC_INT(ch_num);
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
@@ -931,7 +933,7 @@ static void dwc2_inchan_irq_handler(uint8_t ch_num)
             if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
                 if (chan->ep0_state == DWC2_EP0_STATE_INDATA) {
                     chan->ep0_state = DWC2_EP0_STATE_OUTSTATUS;
-                    dwc2_control_urb_init(ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+                    dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
                 } else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) {
                     chan->ep0_state = DWC2_EP0_STATE_SETUP;
                     dwc2_urb_waitup(urb);
@@ -946,7 +948,7 @@ static void dwc2_inchan_irq_handler(uint8_t ch_num)
     }
 }
 
-static void dwc2_outchan_irq_handler(uint8_t ch_num)
+static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
 {
     uint32_t chan_intstatus;
     struct dwc2_chan *chan;
@@ -955,7 +957,7 @@ static void dwc2_outchan_irq_handler(uint8_t ch_num)
 
     chan_intstatus = (USB_OTG_HC(ch_num)->HCINT) & (USB_OTG_HC((uint32_t)ch_num)->HCINTMSK);
 
-    chan = &g_dwc2_hcd.chan_pool[ch_num];
+    chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[ch_num];
     urb = chan->urb;
     //printf("s2:%08x\r\n", chan_intstatus);
 
@@ -963,48 +965,48 @@ static void dwc2_outchan_irq_handler(uint8_t ch_num)
         urb->errorcode = 0;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) {
         urb->errorcode = -USB_ERR_IO;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) {
         urb->errorcode = -USB_ERR_STALL;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK) {
         urb->errorcode = -USB_ERR_NAK;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET) {
         urb->errorcode = -USB_ERR_NAK;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR) {
         urb->errorcode = -USB_ERR_IO;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR) {
         urb->errorcode = -USB_ERR_BABBLE;
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR);
     } else if ((chan_intstatus & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR) {
         urb->errorcode = -USB_ERR_IO;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR) {
         urb->errorcode = -USB_ERR_DT;
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
         USB_UNMASK_HALT_HC_INT(ch_num);
-        dwc2_halt(ch_num);
+        dwc2_halt(bus, ch_num);
     } else if ((chan_intstatus & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH) {
         USB_MASK_HALT_HC_INT(ch_num);
         CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
@@ -1035,10 +1037,10 @@ static void dwc2_outchan_irq_handler(uint8_t ch_num)
                     } else {
                         chan->ep0_state = DWC2_EP0_STATE_INSTATUS;
                     }
-                    dwc2_control_urb_init(ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+                    dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
                 } else if (chan->ep0_state == DWC2_EP0_STATE_OUTDATA) {
                     chan->ep0_state = DWC2_EP0_STATE_INSTATUS;
-                    dwc2_control_urb_init(ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+                    dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
                 } else if (chan->ep0_state == DWC2_EP0_STATE_OUTSTATUS) {
                     chan->ep0_state = DWC2_EP0_STATE_SETUP;
                     dwc2_urb_waitup(urb);
@@ -1053,7 +1055,7 @@ static void dwc2_outchan_irq_handler(uint8_t ch_num)
     }
 }
 
-static void dwc2_port_irq_handler(void)
+static void dwc2_port_irq_handler(struct usbh_bus *bus)
 {
     __IO uint32_t hprt0, hprt0_dup, regval;
 
@@ -1067,16 +1069,17 @@ static void dwc2_port_irq_handler(void)
     /* Check whether Port Connect detected */
     if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET) {
         if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) {
-            usbh_roothub_thread_wakeup(1);
+            bus->hcd.roothub.int_buffer[0] = (1 << 1);
+            usbh_hub_thread_wakeup(&bus->hcd.roothub);
         }
         hprt0_dup |= USB_OTG_HPRT_PCDET;
-        g_dwc2_hcd.port_csc = 1;
+        g_dwc2_hcd[bus->hcd.hcd_id].port_csc = 1;
     }
 
     /* Check whether Port Enable Changed */
     if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG) {
         hprt0_dup |= USB_OTG_HPRT_PENCHNG;
-        g_dwc2_hcd.port_pec = 1;
+        g_dwc2_hcd[bus->hcd.hcd_id].port_pec = 1;
 
         if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) {
 #if defined(CONFIG_USB_DWC2_ULPI_PHY)
@@ -1106,16 +1109,16 @@ static void dwc2_port_irq_handler(void)
     /* Check for an overcurrent */
     if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG) {
         hprt0_dup |= USB_OTG_HPRT_POCCHNG;
-        g_dwc2_hcd.port_occ = 1;
+        g_dwc2_hcd[bus->hcd.hcd_id].port_occ = 1;
     }
     /* Clear Port Interrupts */
     USB_OTG_HPRT = hprt0_dup;
 }
 
-void USBH_IRQHandler(void)
+void USBH_IRQHandler(struct usbh_bus *bus)
 {
     uint32_t gint_status, chan_int;
-    gint_status = dwc2_get_glb_intstatus();
+    gint_status = dwc2_get_glb_intstatus(bus);
     if ((USB_OTG_GLB->GINTSTS & 0x1U) == USB_OTG_MODE_HOST) {
         /* Avoid spurious interrupt */
         if (gint_status == 0) {
@@ -1123,11 +1126,12 @@ void USBH_IRQHandler(void)
         }
 
         if (gint_status & USB_OTG_GINTSTS_HPRTINT) {
-            dwc2_port_irq_handler();
+            dwc2_port_irq_handler(bus);
         }
         if (gint_status & USB_OTG_GINTSTS_DISCINT) {
-            g_dwc2_hcd.port_csc = 1;
-            usbh_roothub_thread_wakeup(1);
+            g_dwc2_hcd[bus->hcd.hcd_id].port_csc = 1;
+            bus->hcd.roothub.int_buffer[0] = (1 << 1);
+            usbh_hub_thread_wakeup(&bus->hcd.roothub);
 
             USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_DISCINT;
         }
@@ -1136,9 +1140,9 @@ void USBH_IRQHandler(void)
             for (uint8_t i = 0U; i < CONFIG_USBHOST_PIPE_NUM; i++) {
                 if ((chan_int & (1UL << (i & 0xFU))) != 0U) {
                     if ((USB_OTG_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR) {
-                        dwc2_inchan_irq_handler(i);
+                        dwc2_inchan_irq_handler(bus, i);
                     } else {
-                        dwc2_outchan_irq_handler(i);
+                        dwc2_outchan_irq_handler(bus, i);
                     }
                 }
             }

+ 8 - 12
port/ehci/usb_ehci_priv.h

@@ -5,12 +5,8 @@
 #include "usbh_hub.h"
 #include "usb_hc_ehci.h"
 
-#ifndef USBH_IRQHandler
-#define USBH_IRQHandler USBH_IRQHandler
-#endif
-
-#define EHCI_HCCR        ((struct ehci_hccr *)CONFIG_USB_EHCI_HCCR_BASE)
-#define EHCI_HCOR        ((struct ehci_hcor *)CONFIG_USB_EHCI_HCOR_BASE)
+#define EHCI_HCCR ((struct ehci_hccr *)(bus->hcd.reg_base))
+#define EHCI_HCOR ((struct ehci_hcor *)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCOR_OFFSET))
 
 #define EHCI_PTR2ADDR(x) ((uint32_t)(x) & ~0x1F)
 #define EHCI_ADDR2QH(x)  ((struct ehci_qh_hw *)((uint32_t)(x) & ~0x1F))
@@ -31,7 +27,7 @@
 #define CONFIG_USB_EHCI_QTD_NUM (CONFIG_USBHOST_PIPE_NUM + 3)
 #define CONFIG_USB_EHCI_ITD_NUM 20
 
-extern uint8_t usbh_get_port_speed(const uint8_t port);
+extern uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port);
 
 struct ehci_qh_hw {
     struct ehci_qh hw;
@@ -63,11 +59,11 @@ struct ehci_hcd {
     bool ehci_itd_used[CONFIG_USB_EHCI_ITD_NUM];
 };
 
-extern struct ehci_hcd g_ehci_hcd;
-extern uint32_t g_framelist[];
+extern struct ehci_hcd g_ehci_hcd[CONFIG_USBHOST_MAX_BUS];
+extern uint32_t g_framelist[CONFIG_USBHOST_MAX_BUS][CONFIG_USB_EHCI_FRAME_LIST_SIZE];
 
-int ehci_iso_urb_init(struct usbh_urb *urb);
-void ehci_remove_itd_urb(struct usbh_urb *urb);
-void ehci_scan_isochronous_list(void);
+int ehci_iso_urb_init(struct usbh_bus *bus, struct usbh_urb *urb);
+void ehci_remove_itd_urb(struct usbh_bus *bus, struct usbh_urb *urb);
+void ehci_scan_isochronous_list(struct usbh_bus *bus);
 
 #endif

+ 18 - 11
port/ehci/usb_glue_aic.c

@@ -10,9 +10,16 @@
 #include "usbh_core.h"
 #include "usb_ehci_priv.h"
 
-extern void USBH_IRQHandler(void);
+extern void USBH_IRQHandler(struct usbh_bus *bus);
 
-void usb_hc_low_level_init(void)
+const uint8_t aic_irq_table[] = {
+    USB_HOST0_EHCI_IRQn,
+#ifdef HPM_USB1_BASE
+    USB_HOST1_EHCI_IRQn
+#endif
+};
+
+void usb_hc_low_level_init(struct usbh_bus *bus)
 {
     uint32_t val;
 
@@ -22,13 +29,13 @@ void usb_hc_low_level_init(void)
 #endif
 
     /* set phy type: UTMI/ULPI */
-    val = readl((volatile void *)(unsigned long)(CONFIG_USB_EHCI_HCCR_BASE+0x800));
+    val = readl((volatile void *)(unsigned long)(bus->hcd.reg_base+0x800));
 #ifdef FPGA_BOARD_ARTINCHIP
     /* fpga phy type = ULPI */
-    writel((val  & ~0x1U), (volatile void *)(unsigned long)(CONFIG_USB_EHCI_HCCR_BASE+0x800));
+    writel((val  & ~0x1U), (volatile void *)(unsigned long)(bus->hcd.reg_base+0x800));
 #else
     /* board phy type = UTMI */
-    writel((val | 0x1), (volatile void *)(unsigned long)(CONFIG_USB_EHCI_HCCR_BASE+0x800));
+    writel((val | 0x1), (volatile void *)(unsigned long)(bus->hcd.reg_base+0x800));
 #endif
 
 #if 0
@@ -37,9 +44,9 @@ void usb_hc_low_level_init(void)
         Must increase the OUT threshold to avoid underrun. (FIFO size - 4)
     */
 #ifdef FPGA_BOARD_ARTINCHIP
-    writel((32 | (127 << 16)), (volatile void *)(unsigned long)(CONFIG_USB_EHCI_HCCR_BASE+0x94));
+    writel((32 | (127 << 16)), (volatile void *)(unsigned long)(bus->hcd.reg_base+0x94));
 #else
-    writel((32 | (32 << 16)), (volatile void *)(unsigned long)(CONFIG_USB_EHCI_HCCR_BASE+0x94));
+    writel((32 | (32 << 16)), (volatile void *)(unsigned long)(bus->hcd.reg_base+0x94));
 #endif
 #endif
 
@@ -55,12 +62,12 @@ void usb_hc_low_level_init(void)
     aicos_udelay(300);
 
     /* register interrupt callback */
-    aicos_request_irq(CONFIG_USB_EHCI_IRQ_NUM, (irq_handler_t)USBH_IRQHandler,
-                      0, "usb_host_ehci", NULL);
-    aicos_irq_enable(CONFIG_USB_EHCI_IRQ_NUM);
+    aicos_request_irq(aic_irq_table[bus->hcd.hcd_id], (irq_handler_t)USBH_IRQHandler,
+                      0, "usb_host_ehci", bus);
+    aicos_irq_enable(aic_irq_table[bus->hcd.hcd_id]);
 }
 
-uint8_t usbh_get_port_speed(const uint8_t port)
+uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
 {
     /* Defined by individual manufacturers */
     uint32_t regval;

+ 3 - 3
port/ehci/usb_glue_bouffalo.c

@@ -32,7 +32,7 @@
 #define USB_SOF_TIMER_MASK_AFTER_RESET_HS (0x44C)
 #define USB_SOF_TIMER_MASK_AFTER_RESET_FS (0x2710)
 
-extern void USBH_IRQHandler();
+extern void USBH_IRQHandler(struct usbh_bus *bus);
 
 static void bflb_usb_phy_init(void)
 {
@@ -83,7 +83,7 @@ static void bflb_usb_phy_init(void)
     bflb_mtimer_delay_ms(2);
 }
 
-void usb_hc_low_level_init(void)
+void usb_hc_low_level_init(struct usbh_bus *bus)
 {
     uint32_t regval;
 
@@ -117,7 +117,7 @@ void usb_hc_low_level_init(void)
     putreg32(regval, BLFB_USB_BASE + USB_GLB_INT_OFFSET);
 }
 
-uint8_t usbh_get_port_speed(const uint8_t port)
+uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
 {
     uint8_t speed = 3;
 

+ 38 - 13
port/ehci/usb_glue_hpm.c

@@ -7,10 +7,27 @@
 #error "hpm ehci must set CONFIG_USB_EHCI_HPMICRO=1"
 #endif
 
-#if !defined(CONFIG_HPM_USBH_BASE) || !defined(CONFIG_HPM_USBH_IRQn)
-#error "hpm ehci must config CONFIG_HPM_USBH_BASE and CONFIG_HPM_USBH_IRQn"
+#if !defined(CONFIG_USB_EHCI_HCOR_OFFSET) || CONFIG_USB_EHCI_HCOR_OFFSET != 0x140
+#error "hpm ehci must config CONFIG_USB_EHCI_HCOR_OFFSET to 0x140"
 #endif
 
+#if defined(CONFIG_USB_EHCI_PRINT_HW_PARAM) || !defined(CONFIG_USB_EHCI_PORT_POWER)
+#error "hpm ehci must enable CONFIG_USB_EHCI_PORT_POWER and disable CONFIG_USB_EHCI_PRINT_HW_PARAM"
+#endif
+
+struct usbh_bus *hpm_usb_bus0;
+
+#ifdef HPM_USB1_BASE
+struct usbh_bus *hpm_usb_bus1;
+#endif
+
+const uint8_t hpm_irq_table[] = {
+    IRQn_USB0,
+#ifdef HPM_USB1_BASE
+    IRQn_USB1
+#endif
+};
+
 static void usb_host_mode_init(USB_Type *ptr)
 {
     /* Set mode to host, must be set immediately after reset */
@@ -30,23 +47,23 @@ static void usb_host_mode_init(USB_Type *ptr)
     ptr->USBCMD &= ~USB_USBCMD_ITC_MASK;
 }
 
-void usb_hc_low_level_init(void)
+void usb_hc_low_level_init(struct usbh_bus *bus)
 {
-    usb_phy_init((USB_Type *)CONFIG_HPM_USBH_BASE);
-    intc_m_enable_irq(CONFIG_HPM_USBH_IRQn);
+    usb_phy_init((USB_Type *)(bus->hcd.reg_base));
+    intc_m_enable_irq(hpm_irq_table[bus->hcd.hcd_id]);
 }
 
-void usb_hc_low_level2_init(void)
+void usb_hc_low_level2_init(struct usbh_bus *bus)
 {
-    usb_host_mode_init((USB_Type *)CONFIG_HPM_USBH_BASE);
+    usb_host_mode_init((USB_Type *)(bus->hcd.reg_base));
 }
 
-uint8_t usbh_get_port_speed(const uint8_t port)
+uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
 {
     (void)port;
     uint8_t speed;
 
-    speed = usb_get_port_speed((USB_Type *)CONFIG_HPM_USBH_BASE);
+    speed = usb_get_port_speed((USB_Type *)(bus->hcd.reg_base));
 
     if (speed == 0x00) {
         return USB_SPEED_FULL;
@@ -61,10 +78,18 @@ uint8_t usbh_get_port_speed(const uint8_t port)
     return 0;
 }
 
-extern void USBH_IRQHandler(void);
+extern void USBH_IRQHandler(struct usbh_bus *bus);
 
-void isr_usbh(void)
+void isr_usbh0(void)
 {
-    USBH_IRQHandler();
+    USBH_IRQHandler(hpm_usb_bus0);
 }
-SDK_DECLARE_EXT_ISR_M(CONFIG_HPM_USBH_IRQn, isr_usbh)
+SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbh0)
+
+#ifdef HPM_USB1_BASE
+void isr_usbh1(void)
+{
+    USBH_IRQHandler(hpm_usb_bus1);
+}
+SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbh1)
+#endif

+ 4 - 4
port/ehci/usb_glue_intel.c

@@ -11,7 +11,7 @@ static int ehci_slot;
 static int ehci_function;
 static int ehci_vector;
 
-extern void USBH_IRQHandler(void *para);
+extern void USBH_IRQHandler(struct usbh_bus *bus);
 
 void ehci_pci_scan(int bus, int slot, int fun, int vector)
 {
@@ -21,7 +21,7 @@ void ehci_pci_scan(int bus, int slot, int fun, int vector)
     ehci_vector = vector;
     pci_read_config_dword(bus, slot, fun, PCI_BASE_ADDRESS_0, &echi_base);
 }
-void usb_hc_low_level_init(void)
+void usb_hc_low_level_init(struct usbh_bus *bus)
 {
     //set software own ehci
     uint32_t legacy_val;
@@ -38,7 +38,7 @@ void usb_hc_low_level_init(void)
         "USBirq",
         RTEMS_INTERRUPT_SHARED,
         USBH_IRQHandler,
-        (void *)0);
+        (void *)bus);
 
     if (sc != RTEMS_SUCCESSFUL) {
         printf("USB install isr falied,%s\n", rtems_status_text(sc));
@@ -46,7 +46,7 @@ void usb_hc_low_level_init(void)
     }
 }
 
-uint8_t usbh_get_port_speed(const uint8_t port)
+uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
 {
     printf("USB_SPEED_HIGH present\n");
     return USB_SPEED_HIGH;

+ 146 - 135
port/ehci/usb_hc_ehci.c

@@ -11,32 +11,32 @@
 #define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */
 #define EHCI_TUNE_MULT_TT 1
 
-struct ehci_hcd g_ehci_hcd;
+struct ehci_hcd g_ehci_hcd[CONFIG_USBHOST_MAX_BUS];
 
-USB_NOCACHE_RAM_SECTION struct ehci_qh_hw ehci_qh_pool[CONFIG_USB_EHCI_QH_NUM];
-USB_NOCACHE_RAM_SECTION struct ehci_qtd_hw ehci_qtd_pool[CONFIG_USB_EHCI_QTD_NUM];
+USB_NOCACHE_RAM_SECTION struct ehci_qh_hw ehci_qh_pool[CONFIG_USBHOST_MAX_BUS][CONFIG_USB_EHCI_QH_NUM];
+USB_NOCACHE_RAM_SECTION struct ehci_qtd_hw ehci_qtd_pool[CONFIG_USBHOST_MAX_BUS][CONFIG_USB_EHCI_QTD_NUM];
 
 /* The head of the asynchronous queue */
-USB_NOCACHE_RAM_SECTION struct ehci_qh_hw g_async_qh_head;
+USB_NOCACHE_RAM_SECTION struct ehci_qh_hw g_async_qh_head[CONFIG_USBHOST_MAX_BUS];
 /* The head of the periodic queue */
-USB_NOCACHE_RAM_SECTION struct ehci_qh_hw g_periodic_qh_head[EHCI_PERIOIDIC_QH_NUM];
+USB_NOCACHE_RAM_SECTION struct ehci_qh_hw g_periodic_qh_head[CONFIG_USBHOST_MAX_BUS][EHCI_PERIOIDIC_QH_NUM];
 
 /* The frame list */
-USB_NOCACHE_RAM_SECTION uint32_t g_framelist[CONFIG_USB_EHCI_FRAME_LIST_SIZE] __attribute__((aligned(4096)));
+USB_NOCACHE_RAM_SECTION uint32_t g_framelist[CONFIG_USBHOST_MAX_BUS][CONFIG_USB_EHCI_FRAME_LIST_SIZE] __attribute__((aligned(4096)));
 
-static struct ehci_qh_hw *ehci_qh_alloc(void)
+static struct ehci_qh_hw *ehci_qh_alloc(struct usbh_bus *bus)
 {
     struct ehci_qh_hw *qh;
     usb_osal_sem_t waitsem;
     size_t flags;
 
     for (uint32_t i = 0; i < CONFIG_USB_EHCI_QH_NUM; i++) {
-        if (!g_ehci_hcd.ehci_qh_used[i]) {
+        if (!g_ehci_hcd[bus->hcd.hcd_id].ehci_qh_used[i]) {
             flags = usb_osal_enter_critical_section();
-            g_ehci_hcd.ehci_qh_used[i] = true;
+            g_ehci_hcd[bus->hcd.hcd_id].ehci_qh_used[i] = true;
             usb_osal_leave_critical_section(flags);
 
-            qh = &ehci_qh_pool[i];
+            qh = &ehci_qh_pool[bus->hcd.hcd_id][i];
             waitsem = qh->waitsem;
             memset(qh, 0, sizeof(struct ehci_qh_hw));
             qh->hw.hlp = QTD_LIST_END;
@@ -49,14 +49,14 @@ static struct ehci_qh_hw *ehci_qh_alloc(void)
     return NULL;
 }
 
-static void ehci_qh_free(struct ehci_qh_hw *qh)
+static void ehci_qh_free(struct usbh_bus *bus, struct ehci_qh_hw *qh)
 {
     size_t flags;
 
     for (uint32_t i = 0; i < CONFIG_USB_EHCI_QH_NUM; i++) {
-        if (&ehci_qh_pool[i] == qh) {
+        if (&ehci_qh_pool[bus->hcd.hcd_id][i] == qh) {
             flags = usb_osal_enter_critical_section();
-            g_ehci_hcd.ehci_qh_used[i] = false;
+            g_ehci_hcd[bus->hcd.hcd_id].ehci_qh_used[i] = false;
             usb_osal_leave_critical_section(flags);
 
             qh->urb = NULL;
@@ -65,18 +65,18 @@ static void ehci_qh_free(struct ehci_qh_hw *qh)
     }
 }
 
-static struct ehci_qtd_hw *ehci_qtd_alloc(void)
+static struct ehci_qtd_hw *ehci_qtd_alloc(struct usbh_bus *bus)
 {
     struct ehci_qtd_hw *qtd;
     size_t flags;
 
     for (uint32_t i = 0; i < CONFIG_USB_EHCI_QTD_NUM; i++) {
-        if (!g_ehci_hcd.ehci_qtd_used[i]) {
+        if (!g_ehci_hcd[bus->hcd.hcd_id].ehci_qtd_used[i]) {
             flags = usb_osal_enter_critical_section();
-            g_ehci_hcd.ehci_qtd_used[i] = true;
+            g_ehci_hcd[bus->hcd.hcd_id].ehci_qtd_used[i] = true;
             usb_osal_leave_critical_section(flags);
 
-            qtd = &ehci_qtd_pool[i];
+            qtd = &ehci_qtd_pool[bus->hcd.hcd_id][i];
             memset(qtd, 0, sizeof(struct ehci_qtd_hw));
             qtd->hw.next_qtd = QTD_LIST_END;
             qtd->hw.alt_next_qtd = QTD_LIST_END;
@@ -87,14 +87,14 @@ static struct ehci_qtd_hw *ehci_qtd_alloc(void)
     return NULL;
 }
 
-static void ehci_qtd_free(struct ehci_qtd_hw *qtd)
+static void ehci_qtd_free(struct usbh_bus *bus, struct ehci_qtd_hw *qtd)
 {
     size_t flags;
 
     for (uint32_t i = 0; i < CONFIG_USB_EHCI_QTD_NUM; i++) {
-        if (&ehci_qtd_pool[i] == qtd) {
+        if (&ehci_qtd_pool[bus->hcd.hcd_id][i] == qtd) {
             flags = usb_osal_enter_critical_section();
-            g_ehci_hcd.ehci_qtd_used[i] = false;
+            g_ehci_hcd[bus->hcd.hcd_id].ehci_qtd_used[i] = false;
             usb_osal_leave_critical_section(flags);
 
             qtd->urb = NULL;
@@ -144,17 +144,17 @@ static int ehci_caculate_smask(int binterval)
     return (0x1 << (order % 8));
 }
 
-static struct ehci_qh_hw *ehci_get_periodic_qhead(uint8_t interval)
+static struct ehci_qh_hw *ehci_get_periodic_qhead(struct usbh_bus *bus, uint8_t interval)
 {
     interval /= 8;
 
     for (uint8_t i = 0; i < EHCI_PERIOIDIC_QH_NUM - 1; i++) {
         interval >>= 1;
         if (interval == 0) {
-            return &g_periodic_qh_head[i];
+            return &g_periodic_qh_head[bus->hcd.hcd_id][i];
         }
     }
-    return &g_periodic_qh_head[EHCI_PERIOIDIC_QH_NUM - 1];
+    return &g_periodic_qh_head[bus->hcd.hcd_id][EHCI_PERIOIDIC_QH_NUM - 1];
 }
 
 static void ehci_qh_fill(struct ehci_qh_hw *qh,
@@ -297,7 +297,7 @@ static void ehci_qtd_fill(struct ehci_qtd_hw *qtd, uint32_t bufaddr, size_t bufl
     qtd->total_len = buflen;
 }
 
-static struct ehci_qh_hw *ehci_control_urb_init(struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
+static struct ehci_qh_hw *ehci_control_urb_init(struct usbh_bus *bus, struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
 {
     struct ehci_qh_hw *qh = NULL;
     struct ehci_qtd_hw *qtd_setup = NULL;
@@ -306,24 +306,24 @@ static struct ehci_qh_hw *ehci_control_urb_init(struct usbh_urb *urb, struct usb
     uint32_t token;
     size_t flags;
 
-    qh = ehci_qh_alloc();
+    qh = ehci_qh_alloc(bus);
     if (qh == NULL) {
         return NULL;
     }
 
-    qtd_setup = ehci_qtd_alloc();
+    qtd_setup = ehci_qtd_alloc(bus);
     if (buflen > 0) {
-        qtd_data = ehci_qtd_alloc();
+        qtd_data = ehci_qtd_alloc(bus);
     }
 
-    qtd_status = ehci_qtd_alloc();
+    qtd_status = ehci_qtd_alloc(bus);
     if (qtd_status == NULL) {
-        ehci_qh_free(qh);
+        ehci_qh_free(bus, qh);
         if (qtd_setup) {
-            ehci_qtd_free(qtd_setup);
+            ehci_qtd_free(bus, qtd_setup);
         }
         if (qtd_data) {
-            ehci_qtd_free(qtd_data);
+            ehci_qtd_free(bus, qtd_data);
         }
         return NULL;
     }
@@ -397,7 +397,7 @@ static struct ehci_qh_hw *ehci_control_urb_init(struct usbh_urb *urb, struct usb
     qh->urb = urb;
     urb->hcpriv = qh;
     /* add qh into async list */
-    ehci_qh_add_head(&g_async_qh_head, qh);
+    ehci_qh_add_head(&g_async_qh_head[bus->hcd.hcd_id], qh);
 
     EHCI_HCOR->usbcmd |= EHCI_USBCMD_ASEN;
 
@@ -405,7 +405,7 @@ static struct ehci_qh_hw *ehci_control_urb_init(struct usbh_urb *urb, struct usb
     return qh;
 }
 
-static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
+static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_bus *bus, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
 {
     struct ehci_qh_hw *qh = NULL;
     struct ehci_qtd_hw *qtd = NULL;
@@ -416,19 +416,19 @@ static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_urb *urb, uint8_t *buff
     uint32_t token;
     size_t flags;
 
-    qh = ehci_qh_alloc();
+    qh = ehci_qh_alloc(bus);
     if (qh == NULL) {
         return NULL;
     }
 
     for (uint32_t i = 0; i < CONFIG_USB_EHCI_QTD_NUM; i++) {
-        if (!g_ehci_hcd.ehci_qtd_used[i]) {
+        if (!g_ehci_hcd[bus->hcd.hcd_id].ehci_qtd_used[i]) {
             qtd_num++;
         }
     }
 
     if (qtd_num < ((buflen + 0x3fff) / 0x4000)) {
-        ehci_qh_free(qh);
+        ehci_qh_free(bus, qh);
         return NULL;
     }
 
@@ -444,7 +444,7 @@ static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_urb *urb, uint8_t *buff
                  urb->hport->port);
 
     while (buflen >= 0) {
-        qtd = ehci_qtd_alloc();
+        qtd = ehci_qtd_alloc(bus);
 
         if (buflen > 0x4000) {
             xfer_len = 0x4000;
@@ -504,7 +504,7 @@ static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_urb *urb, uint8_t *buff
     qh->urb = urb;
     urb->hcpriv = qh;
     /* add qh into async list */
-    ehci_qh_add_head(&g_async_qh_head, qh);
+    ehci_qh_add_head(&g_async_qh_head[bus->hcd.hcd_id], qh);
 
     EHCI_HCOR->usbcmd |= EHCI_USBCMD_ASEN;
 
@@ -512,7 +512,7 @@ static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_urb *urb, uint8_t *buff
     return qh;
 }
 
-static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
+static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_bus *bus, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
 {
     struct ehci_qh_hw *qh = NULL;
     struct ehci_qtd_hw *qtd = NULL;
@@ -523,19 +523,19 @@ static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_urb *urb, uint8_t *buff
     uint32_t token;
     size_t flags;
 
-    qh = ehci_qh_alloc();
+    qh = ehci_qh_alloc(bus);
     if (qh == NULL) {
         return NULL;
     }
 
     for (uint32_t i = 0; i < CONFIG_USB_EHCI_QTD_NUM; i++) {
-        if (!g_ehci_hcd.ehci_qtd_used[i]) {
+        if (!g_ehci_hcd[bus->hcd.hcd_id].ehci_qtd_used[i]) {
             qtd_num++;
         }
     }
 
     if (qtd_num < ((buflen + 0x3fff) / 0x4000)) {
-        ehci_qh_free(qh);
+        ehci_qh_free(bus, qh);
         return NULL;
     }
 
@@ -551,7 +551,7 @@ static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_urb *urb, uint8_t *buff
                  urb->hport->port);
 
     while (buflen >= 0) {
-        qtd = ehci_qtd_alloc();
+        qtd = ehci_qtd_alloc(bus);
 
         if (buflen > 0x4000) {
             xfer_len = 0x4000;
@@ -612,9 +612,9 @@ static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_urb *urb, uint8_t *buff
     urb->hcpriv = qh;
     /* add qh into periodic list */
     if (urb->hport->speed == USB_SPEED_HIGH) {
-        ehci_qh_add_head(ehci_get_periodic_qhead(urb->ep->bInterval), qh);
+        ehci_qh_add_head(ehci_get_periodic_qhead(bus, urb->ep->bInterval), qh);
     } else {
-        ehci_qh_add_head(ehci_get_periodic_qhead(urb->ep->bInterval * 8), qh);
+        ehci_qh_add_head(ehci_get_periodic_qhead(bus, urb->ep->bInterval * 8), qh);
     }
 
     EHCI_HCOR->usbcmd |= EHCI_USBCMD_PSEN;
@@ -623,7 +623,7 @@ static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_urb *urb, uint8_t *buff
     return qh;
 }
 
-static void ehci_urb_waitup(struct usbh_urb *urb)
+static void ehci_urb_waitup(struct usbh_bus *bus, struct usbh_urb *urb)
 {
     struct ehci_qh_hw *qh;
 
@@ -637,7 +637,7 @@ static void ehci_urb_waitup(struct usbh_urb *urb)
         urb->timeout = 0;
         usb_osal_sem_give(qh->waitsem);
     } else {
-        ehci_qh_free(qh);
+        ehci_qh_free(bus, qh);
     }
 
     if (urb->complete) {
@@ -649,7 +649,7 @@ static void ehci_urb_waitup(struct usbh_urb *urb)
     }
 }
 
-static void ehci_qh_scan_qtds(struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
+static void ehci_qh_scan_qtds(struct usbh_bus *bus, struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
 {
     struct ehci_qtd_hw *qtd;
 
@@ -660,13 +660,13 @@ static void ehci_qh_scan_qtds(struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
     while (qtd) {
         qtd->urb->actual_length += (qtd->total_len - ((qtd->hw.token & QTD_TOKEN_NBYTES_MASK) >> QTD_TOKEN_NBYTES_SHIFT));
 
-        ehci_qtd_free(qtd);
+        ehci_qtd_free(bus, qtd);
         qh->first_qtd = qtd->hw.next_qtd;
         qtd = EHCI_ADDR2QTD(qh->first_qtd);
     }
 }
 
-static void ehci_check_qh(struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
+static void ehci_check_qh(struct usbh_bus *bus, struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
 {
     struct usbh_urb *urb;
     struct ehci_qtd_hw *qtd;
@@ -711,10 +711,10 @@ static void ehci_check_qh(struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
         }
     }
 
-    ehci_qh_scan_qtds(qhead, qh);
+    ehci_qh_scan_qtds(bus, qhead, qh);
 
     if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) {
-        ehci_urb_waitup(urb);
+        ehci_urb_waitup(bus, urb);
     } else {
         qh->remove_in_iaad = 1;
 
@@ -722,7 +722,7 @@ static void ehci_check_qh(struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
     }
 }
 
-static void ehci_kill_qh(struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
+static void ehci_kill_qh(struct usbh_bus *bus, struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
 {
     struct ehci_qtd_hw *qtd;
 
@@ -731,19 +731,19 @@ static void ehci_kill_qh(struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
     qtd = EHCI_ADDR2QTD(qh->first_qtd);
 
     while (qtd) {
-        ehci_qtd_free(qtd);
+        ehci_qtd_free(bus, qtd);
         qh->first_qtd = qtd->hw.next_qtd;
         qtd = EHCI_ADDR2QTD(qh->first_qtd);
     }
 }
 
-static int usbh_reset_port(const uint8_t port)
+static int usbh_reset_port(struct usbh_bus *bus, const uint8_t port)
 {
     volatile uint32_t timeout = 0;
     uint32_t regval;
 
 #if defined(CONFIG_USB_EHCI_HPMICRO) && CONFIG_USB_EHCI_HPMICRO
-    if ((*(volatile uint32_t *)(CONFIG_HPM_USBH_BASE + 0x224) & 0xc0) == (2 << 6)) { /* Hardcode for hpm */
+    if ((*(volatile uint32_t *)(bus->hcd.reg_base + 0x224) & 0xc0) == (2 << 6)) { /* Hardcode for hpm */
         EHCI_HCOR->portsc[port - 1] |= (1 << 29);
     } else {
         EHCI_HCOR->portsc[port - 1] &= ~(1 << 29);
@@ -767,15 +767,15 @@ static int usbh_reset_port(const uint8_t port)
     return 0;
 }
 
-__WEAK void usb_hc_low_level_init(void)
+__WEAK void usb_hc_low_level_init(struct usbh_bus *bus)
 {
 }
 
-__WEAK void usb_hc_low_level2_init(void)
+__WEAK void usb_hc_low_level2_init(struct usbh_bus *bus)
 {
 }
 
-int usb_hc_init(void)
+int usb_hc_init(struct usbh_bus *bus)
 {
     uint32_t interval;
     struct ehci_qh_hw *qh;
@@ -783,7 +783,7 @@ int usb_hc_init(void)
     volatile uint32_t timeout = 0;
     uint32_t regval;
 
-    memset(&g_ehci_hcd, 0, sizeof(struct ehci_hcd));
+    memset(&g_ehci_hcd[bus->hcd.hcd_id], 0, sizeof(struct ehci_hcd));
 
     if (sizeof(struct ehci_qh_hw) % 32) {
         USB_LOG_ERR("struct ehci_qh_hw is not align 32\r\n");
@@ -795,41 +795,41 @@ int usb_hc_init(void)
     }
 
     for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) {
-        qh = &ehci_qh_pool[index];
+        qh = &ehci_qh_pool[bus->hcd.hcd_id][index];
         qh->waitsem = usb_osal_sem_create(0);
     }
 
-    memset(&g_async_qh_head, 0, sizeof(struct ehci_qh_hw));
-    g_async_qh_head.hw.hlp = QH_HLP_QH(&g_async_qh_head);
-    g_async_qh_head.hw.epchar = QH_EPCHAR_H;
-    g_async_qh_head.hw.overlay.next_qtd = QTD_LIST_END;
-    g_async_qh_head.hw.overlay.alt_next_qtd = QTD_LIST_END;
-    g_async_qh_head.hw.overlay.token = QTD_TOKEN_STATUS_HALTED;
-    g_async_qh_head.first_qtd = QTD_LIST_END;
+    memset(&g_async_qh_head[bus->hcd.hcd_id], 0, sizeof(struct ehci_qh_hw));
+    g_async_qh_head[bus->hcd.hcd_id].hw.hlp = QH_HLP_QH(&g_async_qh_head[bus->hcd.hcd_id]);
+    g_async_qh_head[bus->hcd.hcd_id].hw.epchar = QH_EPCHAR_H;
+    g_async_qh_head[bus->hcd.hcd_id].hw.overlay.next_qtd = QTD_LIST_END;
+    g_async_qh_head[bus->hcd.hcd_id].hw.overlay.alt_next_qtd = QTD_LIST_END;
+    g_async_qh_head[bus->hcd.hcd_id].hw.overlay.token = QTD_TOKEN_STATUS_HALTED;
+    g_async_qh_head[bus->hcd.hcd_id].first_qtd = QTD_LIST_END;
 
-    memset(g_framelist, 0, sizeof(uint32_t) * CONFIG_USB_EHCI_FRAME_LIST_SIZE);
+    memset(g_framelist[bus->hcd.hcd_id], 0, sizeof(uint32_t) * CONFIG_USB_EHCI_FRAME_LIST_SIZE);
 
     for (int i = EHCI_PERIOIDIC_QH_NUM - 1; i >= 0; i--) {
-        memset(&g_periodic_qh_head[i], 0, sizeof(struct ehci_qh_hw));
-        g_periodic_qh_head[i].hw.hlp = QH_HLP_END;
-        g_periodic_qh_head[i].hw.epchar = QH_EPCAPS_SSMASK(1);
-        g_periodic_qh_head[i].hw.overlay.next_qtd = QTD_LIST_END;
-        g_periodic_qh_head[i].hw.overlay.alt_next_qtd = QTD_LIST_END;
-        g_periodic_qh_head[i].hw.overlay.token = QTD_TOKEN_STATUS_HALTED;
-        g_periodic_qh_head[i].first_qtd = QTD_LIST_END;
+        memset(&g_periodic_qh_head[bus->hcd.hcd_id][i], 0, sizeof(struct ehci_qh_hw));
+        g_periodic_qh_head[bus->hcd.hcd_id][i].hw.hlp = QH_HLP_END;
+        g_periodic_qh_head[bus->hcd.hcd_id][i].hw.epchar = QH_EPCAPS_SSMASK(1);
+        g_periodic_qh_head[bus->hcd.hcd_id][i].hw.overlay.next_qtd = QTD_LIST_END;
+        g_periodic_qh_head[bus->hcd.hcd_id][i].hw.overlay.alt_next_qtd = QTD_LIST_END;
+        g_periodic_qh_head[bus->hcd.hcd_id][i].hw.overlay.token = QTD_TOKEN_STATUS_HALTED;
+        g_periodic_qh_head[bus->hcd.hcd_id][i].first_qtd = QTD_LIST_END;
 
         interval = 1 << i;
         for (uint32_t j = interval - 1; j < CONFIG_USB_EHCI_FRAME_LIST_SIZE; j += interval) {
-            if (g_framelist[j] == 0) {
-                g_framelist[j] = QH_HLP_QH(&g_periodic_qh_head[i]);
+            if (g_framelist[bus->hcd.hcd_id][j] == 0) {
+                g_framelist[bus->hcd.hcd_id][j] = QH_HLP_QH(&g_periodic_qh_head[bus->hcd.hcd_id][i]);
             } else {
-                qh = EHCI_ADDR2QH(g_framelist[j]);
+                qh = EHCI_ADDR2QH(g_framelist[bus->hcd.hcd_id][j]);
                 while (1) {
-                    if (qh == &g_periodic_qh_head[i]) {
+                    if (qh == &g_periodic_qh_head[bus->hcd.hcd_id][i]) {
                         break;
                     }
                     if (qh->hw.hlp == QH_HLP_END) {
-                        qh->hw.hlp = QH_HLP_QH(&g_periodic_qh_head[i]);
+                        qh->hw.hlp = QH_HLP_QH(&g_periodic_qh_head[bus->hcd.hcd_id][i]);
                         break;
                     }
 
@@ -839,7 +839,7 @@ int usb_hc_init(void)
         }
     }
 
-    usb_hc_low_level_init();
+    usb_hc_low_level_init(bus);
 
     EHCI_HCOR->usbcmd |= EHCI_USBCMD_HCRESET;
     while (EHCI_HCOR->usbcmd & EHCI_USBCMD_HCRESET) {
@@ -850,19 +850,19 @@ int usb_hc_init(void)
         }
     }
 
-    usb_hc_low_level2_init();
+    usb_hc_low_level2_init(bus);
 
     EHCI_HCOR->usbintr = 0;
     EHCI_HCOR->usbsts = EHCI_HCOR->usbsts;
-#if CONFIG_USB_EHCI_HCCR_BASE != 0
+#ifdef CONFIG_USB_EHCI_PRINT_HW_PARAM
     USB_LOG_INFO("EHCI HCIVERSION:%04x\r\n", (int)EHCI_HCCR->hciversion);
     USB_LOG_INFO("EHCI HCSPARAMS:%06x\r\n", (int)EHCI_HCCR->hcsparams);
     USB_LOG_INFO("EHCI HCCPARAMS:%04x\r\n", (int)EHCI_HCCR->hccparams);
 #endif
     /* Set the Current Asynchronous List Address. */
-    EHCI_HCOR->asynclistaddr = EHCI_PTR2ADDR(&g_async_qh_head);
+    EHCI_HCOR->asynclistaddr = EHCI_PTR2ADDR(&g_async_qh_head[bus->hcd.hcd_id]);
     /* Set the Periodic Frame List Base Address. */
-    EHCI_HCOR->periodiclistbase = EHCI_PTR2ADDR(g_framelist);
+    EHCI_HCOR->periodiclistbase = EHCI_PTR2ADDR(g_framelist[bus->hcd.hcd_id]);
 
     regval = 0;
 #if CONFIG_USB_EHCI_FRAME_LIST_SIZE == 1024
@@ -906,7 +906,7 @@ int usb_hc_init(void)
     return 0;
 }
 
-int usb_hc_deinit(void)
+int usb_hc_deinit(struct usbh_bus *bus)
 {
     struct ehci_qh_hw *qh;
 
@@ -944,19 +944,19 @@ int usb_hc_deinit(void)
     EHCI_HCOR->usbsts = EHCI_HCOR->usbsts;
 
     for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) {
-        qh = &ehci_qh_pool[index];
+        qh = &ehci_qh_pool[bus->hcd.hcd_id][index];
         usb_osal_sem_delete(qh->waitsem);
     }
 
     return 0;
 }
 
-uint16_t usbh_get_frame_number(void)
+uint16_t usbh_get_frame_number(struct usbh_bus *bus)
 {
     return (((EHCI_HCOR->frindex & EHCI_FRINDEX_MASK) >> 3) & 0x3ff);
 }
 
-int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
+int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf)
 {
     uint8_t nports;
     uint8_t port;
@@ -1010,7 +1010,8 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
                         EHCI_HCOR->portsc[port - 1] |= EHCI_PORTSC_RESUME;
                         usb_osal_msleep(20);
                         EHCI_HCOR->portsc[port - 1] &= ~EHCI_PORTSC_RESUME;
-                        while (EHCI_HCOR->portsc[port - 1] & EHCI_PORTSC_RESUME) {}
+                        while (EHCI_HCOR->portsc[port - 1] & EHCI_PORTSC_RESUME) {
+                        }
 
                         temp = EHCI_HCOR->usbcmd;
                         temp |= EHCI_USBCMD_ASEN;
@@ -1018,7 +1019,8 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
                         temp |= EHCI_USBCMD_RUN;
                         EHCI_HCOR->usbcmd = temp;
 
-                        while ((EHCI_HCOR->usbcmd & EHCI_USBCMD_RUN) == 0) {}
+                        while ((EHCI_HCOR->usbcmd & EHCI_USBCMD_RUN) == 0) {
+                        }
 
                     case HUB_PORT_FEATURE_C_SUSPEND:
                         break;
@@ -1055,10 +1057,12 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
                         temp &= ~EHCI_USBCMD_RUN;
                         EHCI_HCOR->usbcmd = temp;
 
-                        while (EHCI_HCOR->usbcmd & EHCI_USBCMD_RUN) {}
+                        while (EHCI_HCOR->usbcmd & EHCI_USBCMD_RUN) {
+                        }
 
                         EHCI_HCOR->portsc[port - 1] |= EHCI_PORTSC_SUSPEND;
-                        while ((EHCI_HCOR->portsc[port - 1] & EHCI_PORTSC_SUSPEND) == 0) {}
+                        while ((EHCI_HCOR->portsc[port - 1] & EHCI_PORTSC_SUSPEND) == 0) {
+                        }
                         break;
                     case HUB_PORT_FEATURE_POWER:
 #ifdef CONFIG_USB_EHCI_PORT_POWER
@@ -1066,7 +1070,7 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
 #endif
                         break;
                     case HUB_PORT_FEATURE_RESET:
-                        usbh_reset_port(port);
+                        usbh_reset_port(bus, port);
                         break;
 
                     default:
@@ -1096,9 +1100,9 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
                 if (temp & EHCI_PORTSC_PE) {
                     status |= (1 << HUB_PORT_FEATURE_ENABLE);
 
-                    if (usbh_get_port_speed(port) == USB_SPEED_LOW) {
+                    if (usbh_get_port_speed(bus, port) == USB_SPEED_LOW) {
                         status |= (1 << HUB_PORT_FEATURE_LOWSPEED);
-                    } else if (usbh_get_port_speed(port) == USB_SPEED_HIGH) {
+                    } else if (usbh_get_port_speed(bus, port) == USB_SPEED_HIGH) {
                         status |= (1 << HUB_PORT_FEATURE_HIGHSPEED);
                     }
                 }
@@ -1130,11 +1134,14 @@ int usbh_submit_urb(struct usbh_urb *urb)
     int ret = 0;
     struct usbh_hub *hub;
     struct usbh_hubport *hport;
+    struct usbh_bus *bus;
 
-    if (!urb || !urb->hport || !urb->ep) {
+    if (!urb || !urb->hport || !urb->ep || !urb->hport->bus) {
         return -USB_ERR_INVAL;
     }
 
+    bus = urb->hport->bus;
+
     /* find active hubport in roothub */
     hport = urb->hport;
     hub = urb->hport->parent;
@@ -1147,7 +1154,7 @@ int usbh_submit_urb(struct usbh_urb *urb)
         return -USB_ERR_NOTCONN;
     }
 
-    if ((urb->errorcode == -USB_ERR_BUSY) && (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) != USB_ENDPOINT_TYPE_ISOCHRONOUS)) {
+    if (urb->errorcode == -USB_ERR_BUSY) {
         return -USB_ERR_BUSY;
     }
 
@@ -1161,21 +1168,21 @@ int usbh_submit_urb(struct usbh_urb *urb)
 
     switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
         case USB_ENDPOINT_TYPE_CONTROL:
-            qh = ehci_control_urb_init(urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+            qh = ehci_control_urb_init(bus, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
             if (qh == NULL) {
                 return -USB_ERR_NOMEM;
             }
             urb->hcpriv = qh;
             break;
         case USB_ENDPOINT_TYPE_BULK:
-            qh = ehci_bulk_urb_init(urb, urb->transfer_buffer, urb->transfer_buffer_length);
+            qh = ehci_bulk_urb_init(bus, urb, urb->transfer_buffer, urb->transfer_buffer_length);
             if (qh == NULL) {
                 return -USB_ERR_NOMEM;
             }
             urb->hcpriv = qh;
             break;
         case USB_ENDPOINT_TYPE_INTERRUPT:
-            qh = ehci_intr_urb_init(urb, urb->transfer_buffer, urb->transfer_buffer_length);
+            qh = ehci_intr_urb_init(bus, urb, urb->transfer_buffer, urb->transfer_buffer_length);
             if (qh == NULL) {
                 return -USB_ERR_NOMEM;
             }
@@ -1183,7 +1190,7 @@ int usbh_submit_urb(struct usbh_urb *urb)
             break;
         case USB_ENDPOINT_TYPE_ISOCHRONOUS:
 #ifdef CONFIG_USB_EHCI_ISO
-            ret = ehci_iso_urb_init(urb);
+            ret = ehci_iso_urb_init(bus, urb);
 #endif
             break;
         default:
@@ -1199,7 +1206,7 @@ int usbh_submit_urb(struct usbh_urb *urb)
         urb->timeout = 0;
         ret = urb->errorcode;
         /* we can free qh when waitsem is done */
-        ehci_qh_free(qh);
+        ehci_qh_free(bus, qh);
     }
     return ret;
 errout_timeout:
@@ -1211,32 +1218,35 @@ errout_timeout:
 int usbh_kill_urb(struct usbh_urb *urb)
 {
     struct ehci_qh_hw *qh;
+    struct usbh_bus *bus;
     size_t flags;
 
-    if (!urb || !urb->hcpriv) {
+    if (!urb || !urb->hcpriv || !urb->hport->bus) {
         return -USB_ERR_INVAL;
     }
 
+    bus = urb->hport->bus;
+
     flags = usb_osal_enter_critical_section();
 
     EHCI_HCOR->usbcmd &= ~(EHCI_USBCMD_PSEN | EHCI_USBCMD_ASEN);
 
     if ((USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) || (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_BULK)) {
-        qh = EHCI_ADDR2QH(g_async_qh_head.hw.hlp);
-        while ((qh != &g_async_qh_head) && qh) {
+        qh = EHCI_ADDR2QH(g_async_qh_head[bus->hcd.hcd_id].hw.hlp);
+        while ((qh != &g_async_qh_head[bus->hcd.hcd_id]) && qh) {
             if (qh->urb == urb) {
-                ehci_kill_qh(&g_async_qh_head, qh);
+                ehci_kill_qh(bus, &g_async_qh_head[bus->hcd.hcd_id], qh);
             }
             qh = EHCI_ADDR2QH(qh->hw.hlp);
         }
     } else if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) {
-        qh = EHCI_ADDR2QH(g_periodic_qh_head[EHCI_PERIOIDIC_QH_NUM - 1].hw.hlp);
+        qh = EHCI_ADDR2QH(g_periodic_qh_head[bus->hcd.hcd_id][EHCI_PERIOIDIC_QH_NUM - 1].hw.hlp);
         while (qh) {
             if (qh->urb == urb) {
                 if (urb->hport->speed == USB_SPEED_HIGH) {
-                    ehci_kill_qh(ehci_get_periodic_qhead(urb->ep->bInterval), qh);
+                    ehci_kill_qh(bus, ehci_get_periodic_qhead(bus, urb->ep->bInterval), qh);
                 } else {
-                    ehci_kill_qh(ehci_get_periodic_qhead(urb->ep->bInterval * 8), qh);
+                    ehci_kill_qh(bus, ehci_get_periodic_qhead(bus, urb->ep->bInterval * 8), qh);
                 }
             }
             qh = EHCI_ADDR2QH(qh->hw.hlp);
@@ -1261,7 +1271,7 @@ int usbh_kill_urb(struct usbh_urb *urb)
         urb->errorcode = -USB_ERR_SHUTDOWN;
         usb_osal_sem_give(qh->waitsem);
     } else {
-        ehci_qh_free(qh);
+        ehci_qh_free(bus, qh);
     }
 
     usb_osal_leave_critical_section(flags);
@@ -1269,37 +1279,37 @@ int usbh_kill_urb(struct usbh_urb *urb)
     return 0;
 }
 
-static void ehci_scan_async_list(void)
+static void ehci_scan_async_list(struct usbh_bus *bus)
 {
     struct ehci_qh_hw *qh;
 
-    qh = EHCI_ADDR2QH(g_async_qh_head.hw.hlp);
-    while ((qh != &g_async_qh_head) && qh) {
+    qh = EHCI_ADDR2QH(g_async_qh_head[bus->hcd.hcd_id].hw.hlp);
+    while ((qh != &g_async_qh_head[bus->hcd.hcd_id]) && qh) {
         if (qh->urb) {
-            ehci_check_qh(&g_async_qh_head, qh);
+            ehci_check_qh(bus, &g_async_qh_head[bus->hcd.hcd_id], qh);
         }
         qh = EHCI_ADDR2QH(qh->hw.hlp);
     }
 }
 
-static void ehci_scan_periodic_list(void)
+static void ehci_scan_periodic_list(struct usbh_bus *bus)
 {
     struct ehci_qh_hw *qh;
 
-    qh = EHCI_ADDR2QH(g_periodic_qh_head[EHCI_PERIOIDIC_QH_NUM - 1].hw.hlp);
+    qh = EHCI_ADDR2QH(g_periodic_qh_head[bus->hcd.hcd_id][EHCI_PERIOIDIC_QH_NUM - 1].hw.hlp);
     while (qh) {
         if (qh->urb) {
             if (qh->urb->hport->speed == USB_SPEED_HIGH) {
-                ehci_check_qh(ehci_get_periodic_qhead(qh->urb->ep->bInterval), qh);
+                ehci_check_qh(bus, ehci_get_periodic_qhead(bus, qh->urb->ep->bInterval), qh);
             } else {
-                ehci_check_qh(ehci_get_periodic_qhead(qh->urb->ep->bInterval * 8), qh);
+                ehci_check_qh(bus, ehci_get_periodic_qhead(bus, qh->urb->ep->bInterval * 8), qh);
             }
         }
         qh = EHCI_ADDR2QH(qh->hw.hlp);
     }
 }
 
-void USBH_IRQHandler(void)
+void USBH_IRQHandler(struct usbh_bus *bus)
 {
     uint32_t usbsts;
 
@@ -1307,18 +1317,18 @@ void USBH_IRQHandler(void)
     EHCI_HCOR->usbsts = usbsts;
 
     if (usbsts & EHCI_USBSTS_INT) {
-        ehci_scan_async_list();
-        ehci_scan_periodic_list();
+        ehci_scan_async_list(bus);
+        ehci_scan_periodic_list(bus);
 #ifdef CONFIG_USB_EHCI_ISO
-        ehci_scan_isochronous_list();
+        ehci_scan_isochronous_list(bus);
 #endif
     }
 
     if (usbsts & EHCI_USBSTS_ERR) {
-        ehci_scan_async_list();
-        ehci_scan_periodic_list();
+        ehci_scan_async_list(bus);
+        ehci_scan_periodic_list(bus);
 #ifdef CONFIG_USB_EHCI_ISO
-        ehci_scan_isochronous_list();
+        ehci_scan_isochronous_list(bus);
 #endif
     }
 
@@ -1330,30 +1340,31 @@ void USBH_IRQHandler(void)
                 if ((portsc & EHCI_PORTSC_CCS) == EHCI_PORTSC_CCS) {
                 } else {
                     for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) {
-                        g_ehci_hcd.ehci_qh_used[index] = false;
+                        g_ehci_hcd[bus->hcd.hcd_id].ehci_qh_used[index] = false;
                     }
                     for (uint8_t index = 0; index < CONFIG_USB_EHCI_QTD_NUM; index++) {
-                        g_ehci_hcd.ehci_qtd_used[index] = false;
+                        g_ehci_hcd[bus->hcd.hcd_id].ehci_qtd_used[index] = false;
                     }
                     for (uint8_t index = 0; index < CONFIG_USB_EHCI_ITD_NUM; index++) {
-                        g_ehci_hcd.ehci_itd_used[index] = false;
+                        g_ehci_hcd[bus->hcd.hcd_id].ehci_itd_used[index] = false;
                     }
                 }
 
-                usbh_roothub_thread_wakeup(port + 1);
+                bus->hcd.roothub.int_buffer[0] |= (1 << (port + 1));
+                usbh_hub_thread_wakeup(&bus->hcd.roothub);
             }
         }
     }
 
     if (usbsts & EHCI_USBSTS_IAA) {
         for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) {
-            struct ehci_qh_hw *qh = &ehci_qh_pool[index];
-            if (g_ehci_hcd.ehci_qh_used[index] && qh->remove_in_iaad) {
-                ehci_urb_waitup(qh->urb);
+            struct ehci_qh_hw *qh = &ehci_qh_pool[bus->hcd.hcd_id][index];
+            if (g_ehci_hcd[bus->hcd.hcd_id].ehci_qh_used[index] && qh->remove_in_iaad) {
+                ehci_urb_waitup(bus, qh->urb);
             }
         }
     }
 
     if (usbsts & EHCI_USBSTS_FATAL) {
     }
-}
+}

+ 97 - 98
port/musb/usb_hc_musb.c

@@ -14,15 +14,7 @@
 #define HWREGB(x) \
     (*((volatile uint8_t *)(x)))
 
-#ifndef USBH_IRQHandler
-#error "please define USBH_IRQHandler in usb_config.h"
-#endif
-
-#ifndef USBH_BASE
-#error "please define USBH_BASE in usb_config.h"
-#endif
-
-#define USB_BASE USBH_BASE
+#define USB_BASE (bus->hcd.reg_base)
 
 #if CONFIG_USBHOST_PIPE_NUM != 4
 #error musb host ip only supports 4 pipe num
@@ -148,6 +140,7 @@ struct musb_pipe {
     uint8_t chidx;
     bool inuse;
     uint32_t xfrd;
+    volatile uint8_t ep0_state;
     usb_osal_sem_t waitsem;
     struct usbh_urb *urb;
 };
@@ -157,23 +150,21 @@ struct musb_hcd {
     volatile bool port_pec;
     volatile bool port_pe;
     struct musb_pipe pipe_pool[CONFIG_USBHOST_PIPE_NUM];
-} g_musb_hcd;
-
-static volatile uint8_t usb_ep0_state = USB_EP0_STATE_SETUP;
+} g_musb_hcd[CONFIG_USBHOST_MAX_BUS];
 
 /* get current active ep */
-static uint8_t musb_get_active_ep(void)
+static uint8_t musb_get_active_ep(struct usbh_bus *bus)
 {
     return HWREGB(USB_BASE + MUSB_EPIDX_OFFSET);
 }
 
 /* set the active ep */
-static void musb_set_active_ep(uint8_t ep_index)
+static void musb_set_active_ep(struct usbh_bus *bus, uint8_t ep_index)
 {
     HWREGB(USB_BASE + MUSB_EPIDX_OFFSET) = ep_index;
 }
 
-static void musb_fifo_flush(uint8_t ep)
+static void musb_fifo_flush(struct usbh_bus *bus, uint8_t ep)
 {
     uint8_t ep_idx = ep & 0x7f;
     if (ep_idx == 0) {
@@ -190,7 +181,7 @@ static void musb_fifo_flush(uint8_t ep)
     }
 }
 
-static void musb_write_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
+static void musb_write_packet(struct usbh_bus *bus, uint8_t ep_idx, uint8_t *buffer, uint16_t len)
 {
     uint32_t *buf32;
     uint8_t *buf8;
@@ -221,7 +212,7 @@ static void musb_write_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
     }
 }
 
-static void musb_read_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
+static void musb_read_packet(struct usbh_bus *bus, uint8_t ep_idx, uint8_t *buffer, uint16_t len)
 {
     uint32_t *buf32;
     uint8_t *buf8;
@@ -252,13 +243,13 @@ static void musb_read_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
     }
 }
 
-void musb_control_urb_init(uint8_t chidx, struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
+void musb_control_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
 {
     uint8_t old_ep_index;
     uint8_t speed = USB_TXTYPE1_SPEED_FULL;
 
-    old_ep_index = musb_get_active_ep();
-    musb_set_active_ep(chidx);
+    old_ep_index = musb_get_active_ep(bus);
+    musb_set_active_ep(bus, chidx);
 
     if (urb->hport->speed == USB_SPEED_HIGH) {
         speed = USB_TYPE0_SPEED_HIGH;
@@ -273,18 +264,18 @@ void musb_control_urb_init(uint8_t chidx, struct usbh_urb *urb, struct usb_setup
     HWREGB(USB_TXHUBADDR_BASE(chidx)) = 0;
     HWREGB(USB_TXHUBPORT_BASE(chidx)) = 0;
 
-    musb_write_packet(chidx, (uint8_t *)setup, 8);
+    musb_write_packet(bus, chidx, (uint8_t *)setup, 8);
     HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY | USB_CSRL0_SETUP;
-    musb_set_active_ep(old_ep_index);
+    musb_set_active_ep(bus, old_ep_index);
 }
 
-void musb_bulk_urb_init(uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
+void musb_bulk_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
 {
     uint8_t old_ep_index;
     uint8_t speed = USB_TXTYPE1_SPEED_FULL;
 
-    old_ep_index = musb_get_active_ep();
-    musb_set_active_ep(chidx);
+    old_ep_index = musb_get_active_ep(bus);
+    musb_set_active_ep(bus, chidx);
 
     if (urb->hport->speed == USB_SPEED_HIGH) {
         speed = USB_TXTYPE1_SPEED_HIGH;
@@ -315,23 +306,23 @@ void musb_bulk_urb_init(uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, ui
             buflen = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
         }
 
-        musb_write_packet(chidx, buffer, buflen);
+        musb_write_packet(bus, chidx, buffer, buflen);
         HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
         HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) |= USB_TXCSRH1_MODE;
         HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
 
         HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << chidx);
     }
-    musb_set_active_ep(old_ep_index);
+    musb_set_active_ep(bus, old_ep_index);
 }
 
-void musb_intr_urb_init(uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
+void musb_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
 {
     uint8_t old_ep_index;
     uint8_t speed = USB_TXTYPE1_SPEED_FULL;
 
-    old_ep_index = musb_get_active_ep();
-    musb_set_active_ep(chidx);
+    old_ep_index = musb_get_active_ep(bus);
+    musb_set_active_ep(bus, chidx);
 
     if (urb->hport->speed == USB_SPEED_HIGH) {
         speed = USB_TXTYPE1_SPEED_HIGH;
@@ -362,28 +353,28 @@ void musb_intr_urb_init(uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, ui
             buflen = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
         }
 
-        musb_write_packet(chidx, buffer, buflen);
+        musb_write_packet(bus, chidx, buffer, buflen);
         HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
         HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) |= USB_TXCSRH1_MODE;
         HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
 
         HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << chidx);
     }
-    musb_set_active_ep(old_ep_index);
+    musb_set_active_ep(bus, old_ep_index);
 }
 
-static int usbh_reset_port(const uint8_t port)
+static int usbh_reset_port(struct usbh_bus *bus, const uint8_t port)
 {
-    g_musb_hcd.port_pe = 0;
+    g_musb_hcd[bus->hcd.hcd_id].port_pe = 0;
     HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_RESET;
     usb_osal_msleep(20);
     HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~(USB_POWER_RESET);
     usb_osal_msleep(20);
-    g_musb_hcd.port_pe = 1;
+    g_musb_hcd[bus->hcd.hcd_id].port_pe = 1;
     return 0;
 }
 
-static uint8_t usbh_get_port_speed(const uint8_t port)
+static uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
 {
     uint8_t speed = USB_SPEED_UNKNOWN;
 
@@ -403,8 +394,8 @@ static int musb_pipe_alloc(void)
     int chidx;
 
     for (chidx = 1; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
-        if (!g_musb_hcd.pipe_pool[chidx].inuse) {
-            g_musb_hcd.pipe_pool[chidx].inuse = true;
+        if (!g_musb_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse) {
+            g_musb_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse = true;
             return chidx;
         }
     }
@@ -420,24 +411,24 @@ static void musb_pipe_free(struct musb_pipe *pipe)
 #endif
 }
 
-__WEAK void usb_hc_low_level_init(void)
+__WEAK void usb_hc_low_level_init(struct usbh_bus *bus)
 {
 }
 
-int usb_hc_init(void)
+int usb_hc_init(struct usbh_bus *bus)
 {
     uint8_t regval;
     uint32_t fifo_offset = 0;
 
-    memset(&g_musb_hcd, 0, sizeof(struct musb_hcd));
+    memset(&g_musb_hcd[bus->hcd.hcd_id], 0, sizeof(struct musb_hcd));
 
     for (uint8_t i = 0; i < CONFIG_USBHOST_PIPE_NUM; i++) {
-        g_musb_hcd.pipe_pool[i].waitsem = usb_osal_sem_create(0);
+        g_musb_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem = usb_osal_sem_create(0);
     }
 
-    usb_hc_low_level_init();
+    usb_hc_low_level_init(bus);
 
-    musb_set_active_ep(0);
+    musb_set_active_ep(bus, 0);
     HWREGB(USB_BASE + MUSB_IND_TXINTERVAL_OFFSET) = 0;
     HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = USB_TXFIFOSZ_SIZE_64;
     HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = 0;
@@ -446,7 +437,7 @@ int usb_hc_init(void)
     fifo_offset += 64;
 
     for (uint8_t i = 1; i < CONIFG_USB_MUSB_PIPE_NUM; i++) {
-        musb_set_active_ep(i);
+        musb_set_active_ep(bus, i);
         HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = USB_TXFIFOSZ_SIZE_512;
         HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = fifo_offset;
         HWREGB(USB_BASE + MUSB_RXFIFOSZ_OFFSET) = USB_TXFIFOSZ_SIZE_512;
@@ -474,7 +465,7 @@ int usb_hc_init(void)
     return 0;
 }
 
-int usb_hc_deinit(void)
+int usb_hc_deinit(struct usbh_bus *bus)
 {
     HWREGB(USB_BASE + MUSB_IE_OFFSET) = 0;
     HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = 0;
@@ -484,13 +475,13 @@ int usb_hc_deinit(void)
     HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) &= ~USB_DEVCTL_SESSION;
 
     for (uint8_t i = 0; i < CONFIG_USBHOST_PIPE_NUM; i++) {
-        usb_osal_sem_delete(g_musb_hcd.pipe_pool[i].waitsem);
+        usb_osal_sem_delete(g_musb_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem);
     }
 
     return 0;
 }
 
-int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
+int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf)
 {
     uint8_t nports;
     uint8_t port;
@@ -544,10 +535,10 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
                     case HUB_PORT_FEATURE_POWER:
                         break;
                     case HUB_PORT_FEATURE_C_CONNECTION:
-                        g_musb_hcd.port_csc = 0;
+                        g_musb_hcd[bus->hcd.hcd_id].port_csc = 0;
                         break;
                     case HUB_PORT_FEATURE_C_ENABLE:
-                        g_musb_hcd.port_pec = 0;
+                        g_musb_hcd[bus->hcd.hcd_id].port_pec = 0;
                         break;
                     case HUB_PORT_FEATURE_C_OVER_CURREN:
                         break;
@@ -568,7 +559,7 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
                     case HUB_PORT_FEATURE_POWER:
                         break;
                     case HUB_PORT_FEATURE_RESET:
-                        usbh_reset_port(port);
+                        usbh_reset_port(bus, port);
                         break;
 
                     default:
@@ -581,19 +572,19 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
                 }
 
                 status = 0;
-                if (g_musb_hcd.port_csc) {
+                if (g_musb_hcd[bus->hcd.hcd_id].port_csc) {
                     status |= (1 << HUB_PORT_FEATURE_C_CONNECTION);
                 }
-                if (g_musb_hcd.port_pec) {
+                if (g_musb_hcd[bus->hcd.hcd_id].port_pec) {
                     status |= (1 << HUB_PORT_FEATURE_C_ENABLE);
                 }
 
-                if (g_musb_hcd.port_pe) {
+                if (g_musb_hcd[bus->hcd.hcd_id].port_pe) {
                     status |= (1 << HUB_PORT_FEATURE_CONNECTION);
                     status |= (1 << HUB_PORT_FEATURE_ENABLE);
-                    if (usbh_get_port_speed(port) == USB_SPEED_LOW) {
+                    if (usbh_get_port_speed(bus, port) == USB_SPEED_LOW) {
                         status |= (1 << HUB_PORT_FEATURE_LOWSPEED);
-                    } else if (usbh_get_port_speed(port) == USB_SPEED_HIGH) {
+                    } else if (usbh_get_port_speed(bus, port) == USB_SPEED_HIGH) {
                         status |= (1 << HUB_PORT_FEATURE_HIGHSPEED);
                     }
                 }
@@ -610,11 +601,12 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
 int usbh_submit_urb(struct usbh_urb *urb)
 {
     struct musb_pipe *pipe;
+    struct usbh_bus *bus;
     int chidx;
     size_t flags;
     int ret = 0;
 
-    if (!urb || !urb->hport || !urb->ep) {
+    if (!urb || !urb->hport || !urb->ep || !urb->hport->bus) {
         return -USB_ERR_INVAL;
     }
 
@@ -626,6 +618,8 @@ int usbh_submit_urb(struct usbh_urb *urb)
         return -USB_ERR_BUSY;
     }
 
+    bus = urb->hport->bus;
+
     flags = usb_osal_enter_critical_section();
 
     if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
@@ -638,7 +632,7 @@ int usbh_submit_urb(struct usbh_urb *urb)
         }
     }
 
-    pipe = &g_musb_hcd.pipe_pool[chidx];
+    pipe = &g_musb_hcd[bus->hcd.hcd_id].pipe_pool[chidx];
     pipe->chidx = chidx;
     pipe->urb = urb;
 
@@ -650,17 +644,17 @@ int usbh_submit_urb(struct usbh_urb *urb)
 
     switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
         case USB_ENDPOINT_TYPE_CONTROL:
-            usb_ep0_state = USB_EP0_STATE_SETUP;
-            musb_control_urb_init(0, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+            pipe->ep0_state = USB_EP0_STATE_SETUP;
+            musb_control_urb_init(bus, 0, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
             break;
         case USB_ENDPOINT_TYPE_BULK:
-            musb_bulk_urb_init(chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
+            musb_bulk_urb_init(bus, chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
             break;
         case USB_ENDPOINT_TYPE_INTERRUPT:
-            musb_intr_urb_init(chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
+            musb_intr_urb_init(bus, chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
             break;
         case USB_ENDPOINT_TYPE_ISOCHRONOUS:
-            break;
+            return -USB_ERR_NOTSUPP;
         default:
             break;
     }
@@ -687,12 +681,15 @@ errout_timeout:
 int usbh_kill_urb(struct usbh_urb *urb)
 {
     struct musb_pipe *pipe;
+    struct usbh_bus *bus;
     size_t flags;
 
-    if (!urb || !urb->hcpriv) {
+    if (!urb || !urb->hcpriv || !urb->hport->bus) {
         return -USB_ERR_INVAL;
     }
 
+    bus = urb->hport->bus;
+
     flags = usb_osal_enter_critical_section();
 
     pipe = (struct musb_pipe *)urb->hcpriv;
@@ -735,59 +732,59 @@ static void musb_urb_waitup(struct usbh_urb *urb)
     }
 }
 
-void handle_ep0(void)
+void handle_ep0(struct usbh_bus *bus)
 {
     uint8_t ep0_status;
     struct musb_pipe *pipe;
     struct usbh_urb *urb;
     uint32_t size;
 
-    pipe = (struct musb_pipe *)&g_musb_hcd.pipe_pool[0];
+    pipe = (struct musb_pipe *)&g_musb_hcd[bus->hcd.hcd_id].pipe_pool[0];
     urb = pipe->urb;
     if (urb == NULL) {
         return;
     }
 
-    musb_set_active_ep(0);
+    musb_set_active_ep(bus, 0);
     ep0_status = HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET);
     if (ep0_status & USB_CSRL0_STALLED) {
         HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALLED;
-        usb_ep0_state = USB_EP0_STATE_SETUP;
+        pipe->ep0_state = USB_EP0_STATE_SETUP;
         urb->errorcode = -USB_ERR_STALL;
         musb_urb_waitup(urb);
         return;
     }
     if (ep0_status & USB_CSRL0_ERROR) {
         HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_ERROR;
-        musb_fifo_flush(0);
-        usb_ep0_state = USB_EP0_STATE_SETUP;
+        musb_fifo_flush(bus, 0);
+        pipe->ep0_state = USB_EP0_STATE_SETUP;
         urb->errorcode = -USB_ERR_IO;
         musb_urb_waitup(urb);
         return;
     }
     if (ep0_status & USB_CSRL0_STALL) {
         HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALL;
-        usb_ep0_state = USB_EP0_STATE_SETUP;
+        pipe->ep0_state = USB_EP0_STATE_SETUP;
         urb->errorcode = -USB_ERR_STALL;
         musb_urb_waitup(urb);
         return;
     }
 
-    switch (usb_ep0_state) {
+    switch (pipe->ep0_state) {
         case USB_EP0_STATE_SETUP:
             urb->actual_length += 8;
             if (urb->transfer_buffer_length) {
                 if (urb->setup->bmRequestType & 0x80) {
-                    usb_ep0_state = USB_EP0_STATE_IN_DATA;
+                    pipe->ep0_state = USB_EP0_STATE_IN_DATA;
                     HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_REQPKT;
                 } else {
-                    usb_ep0_state = USB_EP0_STATE_OUT_DATA;
+                    pipe->ep0_state = USB_EP0_STATE_OUT_DATA;
                     size = urb->transfer_buffer_length;
                     if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
                         size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
                     }
 
-                    musb_write_packet(0, urb->transfer_buffer, size);
+                    musb_write_packet(bus, 0, urb->transfer_buffer, size);
                     HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY;
 
                     urb->transfer_buffer += size;
@@ -795,7 +792,7 @@ void handle_ep0(void)
                     urb->actual_length += size;
                 }
             } else {
-                usb_ep0_state = USB_EP0_STATE_IN_STATUS;
+                pipe->ep0_state = USB_EP0_STATE_IN_STATUS;
                 HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_REQPKT | USB_CSRL0_STATUS);
             }
             break;
@@ -807,14 +804,14 @@ void handle_ep0(void)
                 }
 
                 size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
-                musb_read_packet(0, urb->transfer_buffer, size);
+                musb_read_packet(bus, 0, urb->transfer_buffer, size);
                 HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_RXRDY;
                 urb->transfer_buffer += size;
                 urb->transfer_buffer_length -= size;
                 urb->actual_length += size;
 
                 if ((size < USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) || (urb->transfer_buffer_length == 0)) {
-                    usb_ep0_state = USB_EP0_STATE_OUT_STATUS;
+                    pipe->ep0_state = USB_EP0_STATE_OUT_STATUS;
                     HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_TXRDY | USB_CSRL0_STATUS);
                 } else {
                     HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_REQPKT;
@@ -828,14 +825,14 @@ void handle_ep0(void)
                     size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
                 }
 
-                musb_write_packet(0, urb->transfer_buffer, size);
+                musb_write_packet(bus, 0, urb->transfer_buffer, size);
                 HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY;
 
                 urb->transfer_buffer += size;
                 urb->transfer_buffer_length -= size;
                 urb->actual_length += size;
             } else {
-                usb_ep0_state = USB_EP0_STATE_IN_STATUS;
+                pipe->ep0_state = USB_EP0_STATE_IN_STATUS;
                 HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_REQPKT | USB_CSRL0_STATUS);
             }
             break;
@@ -853,7 +850,7 @@ void handle_ep0(void)
     }
 }
 
-void USBH_IRQHandler(void)
+void USBH_IRQHandler(struct usbh_bus *bus)
 {
     uint32_t is;
     uint32_t txis;
@@ -871,20 +868,22 @@ void USBH_IRQHandler(void)
 
     HWREGB(USB_BASE + MUSB_IS_OFFSET) = is;
 
-    old_ep_idx = musb_get_active_ep();
+    old_ep_idx = musb_get_active_ep(bus);
 
     if (is & USB_IS_CONN) {
-        g_musb_hcd.port_csc = 1;
-        g_musb_hcd.port_pec = 1;
-        g_musb_hcd.port_pe = 1;
-        usbh_roothub_thread_wakeup(1);
+        g_musb_hcd[bus->hcd.hcd_id].port_csc = 1;
+        g_musb_hcd[bus->hcd.hcd_id].port_pec = 1;
+        g_musb_hcd[bus->hcd.hcd_id].port_pe = 1;
+        bus->hcd.roothub.int_buffer[0] = (1 << 1);
+        usbh_hub_thread_wakeup(&bus->hcd.roothub);
     }
 
     if (is & USB_IS_DISCON) {
-        g_musb_hcd.port_csc = 1;
-        g_musb_hcd.port_pec = 1;
-        g_musb_hcd.port_pe = 0;
-        usbh_roothub_thread_wakeup(1);
+        g_musb_hcd[bus->hcd.hcd_id].port_csc = 1;
+        g_musb_hcd[bus->hcd.hcd_id].port_pec = 1;
+        g_musb_hcd[bus->hcd.hcd_id].port_pe = 0;
+        bus->hcd.roothub.int_buffer[0] = (1 << 1);
+        usbh_hub_thread_wakeup(&bus->hcd.roothub);
     }
 
     if (is & USB_IS_SOF) {
@@ -910,16 +909,16 @@ void USBH_IRQHandler(void)
     if (txis & USB_TXIE_EP0) {
         txis &= ~USB_TXIE_EP0;
         HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = USB_TXIE_EP0;
-        handle_ep0();
+        handle_ep0(bus);
     }
 
     for (ep_idx = 1; ep_idx < CONIFG_USB_MUSB_PIPE_NUM; ep_idx++) {
         if (txis & (1 << ep_idx)) {
             HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = (1 << ep_idx);
 
-            pipe = &g_musb_hcd.pipe_pool[ep_idx];
+            pipe = &g_musb_hcd[bus->hcd.hcd_id].pipe_pool[ep_idx];
             urb = pipe->urb;
-            musb_set_active_ep(ep_idx);
+            musb_set_active_ep(bus, ep_idx);
 
             ep_csrl_status = HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET);
 
@@ -951,7 +950,7 @@ void USBH_IRQHandler(void)
                     urb->errorcode = 0;
                     musb_urb_waitup(urb);
                 } else {
-                    musb_write_packet(ep_idx, urb->transfer_buffer, size);
+                    musb_write_packet(bus, ep_idx, urb->transfer_buffer, size);
                     HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
                 }
             }
@@ -963,9 +962,9 @@ void USBH_IRQHandler(void)
         if (rxis & (1 << ep_idx)) {
             HWREGH(USB_BASE + MUSB_RXIS_OFFSET) = (1 << ep_idx); // clear isr flag
 
-            pipe = &g_musb_hcd.pipe_pool[ep_idx];
+            pipe = &g_musb_hcd[bus->hcd.hcd_id].pipe_pool[ep_idx];
             urb = pipe->urb;
-            musb_set_active_ep(ep_idx);
+            musb_set_active_ep(bus, ep_idx);
 
             ep_csrl_status = HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET);
             //ep_csrh_status = HWREGB(USB_BASE + MUSB_IND_RXCSRH_OFFSET); // todo:for iso transfer
@@ -989,7 +988,7 @@ void USBH_IRQHandler(void)
                 }
                 size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
 
-                musb_read_packet(ep_idx, urb->transfer_buffer, size);
+                musb_read_packet(bus, ep_idx, urb->transfer_buffer, size);
 
                 HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_RXRDY;
 
@@ -1007,5 +1006,5 @@ void USBH_IRQHandler(void)
             }
         }
     }
-    musb_set_active_ep(old_ep_idx);
+    musb_set_active_ep(bus, old_ep_idx);
 }

+ 0 - 7
third_party/rt-thread-5.0/msh_cmd.c

@@ -70,15 +70,8 @@ MSH_CMD_EXPORT(audio_v2_test, start audio_v2_test);
 #endif
 
 #if defined(PKG_CHERRYUSB_HOST)
-void usbh_class_test(void);
-MSH_CMD_EXPORT(usbh_class_test, start usbh_class_test);
-
 int lsusb(int argc, char **argv);
 MSH_CMD_EXPORT(lsusb, start lsusb);
-
-int usbh_initialize(void);
-//INIT_APP_EXPORT(usbh_initialize);
-MSH_CMD_EXPORT(usbh_initialize, start usbh_initialize);
 #endif
 
 #endif