From 7574063e9481e245e604f094986c016a1c87638c Mon Sep 17 00:00:00 2001 From: sakimisu <1203593632@qq.com> Date: Wed, 5 Jul 2023 22:39:47 +0800 Subject: [PATCH] enum device with disposable thread, do not block hub thread --- class/hub/usbh_hub.c | 25 +++++++++++++++++-------- core/usbh_core.h | 1 + osal/usb_osal.h | 4 ++++ osal/usb_osal_freertos.c | 7 ++++++- osal/usb_osal_rtthread.c | 5 +++++ osal/usb_osal_yoc.c | 5 +++++ port/dwc2/usb_hc_dwc2.c | 9 --------- port/ehci/usb_hc_ehci.c | 17 ++++++----------- port/musb/usb_hc_musb.c | 11 ----------- 9 files changed, 44 insertions(+), 40 deletions(-) diff --git a/class/hub/usbh_hub.c b/class/hub/usbh_hub.c index 4222f381..1a100d7c 100644 --- a/class/hub/usbh_hub.c +++ b/class/hub/usbh_hub.c @@ -437,6 +437,21 @@ static void usbh_hubport_release(struct usbh_hubport *child) } } +static void usbh_hubport_enumerate_thread(void *argument) +{ + struct usbh_hubport *child = (struct usbh_hubport *)argument; + + /* Configure EP0 with the default maximum packet size */ + usbh_hport_activate_ep0(child); + + if (usbh_enumerate(child) < 0) { + /** release child sources */ + usbh_hubport_release(child); + USB_LOG_ERR("Port %u enumerate fail\r\n", child->port); + } + usb_osal_thread_delete(child->thread); +} + static void usbh_hub_events(struct usbh_hub *hub) { struct usbh_hubport *child; @@ -597,14 +612,8 @@ static void usbh_hub_events(struct usbh_hub *hub) USB_LOG_INFO("New %s device on Hub %u, Port %u connected\r\n", speed_table[speed], hub->index, port + 1); - /* Configure EP0 with the default maximum packet size */ - usbh_hport_activate_ep0(child); - - if (usbh_enumerate(child) < 0) { - /** release child sources */ - usbh_hubport_release(child); - USB_LOG_ERR("Port %u enumerate fail\r\n", port + 1); - } + /* create disposable thread to enumerate device on current hport, do not block hub thread */ + child->thread = usb_osal_thread_create("usbh_enum", CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hubport_enumerate_thread, (void *)child); } else { child = &hub->child[port]; /** release child sources */ diff --git a/core/usbh_core.h b/core/usbh_core.h index 9b17aacb..631e633b 100644 --- a/core/usbh_core.h +++ b/core/usbh_core.h @@ -152,6 +152,7 @@ struct usbh_hubport { #ifdef CONFIG_USBHOST_XHCI uint32_t protocol; /* port protocol, for xhci, some ports are USB2.0, others are USB3.0 */ #endif + usb_osal_thread_t thread; }; struct usbh_hub { diff --git a/osal/usb_osal.h b/osal/usb_osal.h index 7f723559..af65186a 100644 --- a/osal/usb_osal.h +++ b/osal/usb_osal.h @@ -15,7 +15,11 @@ typedef void *usb_osal_mutex_t; typedef void *usb_osal_mq_t; typedef void (*usb_thread_entry_t)(void *argument); +/* + * Task with smaller priority value indicates higher task priority +*/ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args); +void usb_osal_thread_delete(usb_osal_thread_t thread); usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count); void usb_osal_sem_delete(usb_osal_sem_t sem); diff --git a/osal/usb_osal_freertos.c b/osal/usb_osal_freertos.c index da8ccd60..de448d2d 100644 --- a/osal/usb_osal_freertos.c +++ b/osal/usb_osal_freertos.c @@ -14,10 +14,15 @@ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, { TaskHandle_t htask = NULL; stack_size /= sizeof(StackType_t); - xTaskCreate(entry, name, stack_size, args, prio, &htask); + xTaskCreate(entry, name, stack_size, args, configMAX_PRIORITIES - 1 - prio, &htask); return (usb_osal_thread_t)htask; } +void usb_osal_thread_delete(usb_osal_thread_t thread) +{ + vTaskDelete(thread); +} + usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) { return (usb_osal_sem_t)xSemaphoreCreateCounting(1, initial_count); diff --git a/osal/usb_osal_rtthread.c b/osal/usb_osal_rtthread.c index e1c90499..1882830d 100644 --- a/osal/usb_osal_rtthread.c +++ b/osal/usb_osal_rtthread.c @@ -16,6 +16,11 @@ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, return (usb_osal_thread_t)htask; } +void usb_osal_thread_delete(usb_osal_thread_t thread) +{ + rt_thread_delete(thread); +} + usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) { return (usb_osal_sem_t)rt_sem_create("usbh_sem", initial_count, RT_IPC_FLAG_FIFO); diff --git a/osal/usb_osal_yoc.c b/osal/usb_osal_yoc.c index 2f802045..962f9021 100644 --- a/osal/usb_osal_yoc.c +++ b/osal/usb_osal_yoc.c @@ -17,6 +17,11 @@ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, return task_handle; } +void usb_osal_thread_delete(usb_osal_thread_t thread) +{ + aos_task_exit(0); +} + usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) { aos_sem_t sem = NULL; diff --git a/port/dwc2/usb_hc_dwc2.c b/port/dwc2/usb_hc_dwc2.c index 589fc5ea..e88c76ab 100644 --- a/port/dwc2/usb_hc_dwc2.c +++ b/port/dwc2/usb_hc_dwc2.c @@ -1218,15 +1218,6 @@ void USBH_IRQHandler(void) } if (gint_status & USB_OTG_GINTSTS_DISCINT) { g_dwc2_hcd.port_csc = 1; - for (uint8_t index = 0; index < CONFIG_USBHOST_PIPE_NUM; index++) { - struct dwc2_pipe *chan = &g_dwc2_hcd.pipe_pool[index]; - struct usbh_urb *urb = chan->urb; - if (chan->waiter) { - chan->waiter = false; - urb->errorcode = -ESHUTDOWN; - usb_osal_sem_give(chan->waitsem); - } - } usbh_roothub_thread_wakeup(1); USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_DISCINT; diff --git a/port/ehci/usb_hc_ehci.c b/port/ehci/usb_hc_ehci.c index fad79606..0c6aed3b 100644 --- a/port/ehci/usb_hc_ehci.c +++ b/port/ehci/usb_hc_ehci.c @@ -1177,6 +1177,12 @@ int usbh_kill_urb(struct usbh_urb *urb) pipe->qh = NULL; pipe->urb = NULL; + if (pipe->waiter) { + pipe->waiter = false; + urb->errorcode = -ESHUTDOWN; + usb_osal_sem_give(pipe->waitsem); + } + usb_osal_leave_critical_section(flags); return 0; @@ -1246,17 +1252,6 @@ void USBH_IRQHandler(void) if (portsc & EHCI_PORTSC_CSC) { if ((portsc & EHCI_PORTSC_CCS) == EHCI_PORTSC_CCS) { } else { - for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) { - struct ehci_pipe *pipe = &g_ehci_hcd.pipe_pool[index]; - struct usbh_urb *urb = pipe->urb; - - if (pipe->waiter) { - pipe->waiter = false; - urb->errorcode = -ESHUTDOWN; - usb_osal_sem_give(pipe->waitsem); - } - } - for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) { g_ehci_hcd.ehci_qh_used[index] = false; } diff --git a/port/musb/usb_hc_musb.c b/port/musb/usb_hc_musb.c index 26a284be..d5cd7da4 100644 --- a/port/musb/usb_hc_musb.c +++ b/port/musb/usb_hc_musb.c @@ -906,17 +906,6 @@ void USBH_IRQHandler(void) g_musb_hcd.port_csc = 1; g_musb_hcd.port_pec = 1; g_musb_hcd.port_pe = 0; - for (uint8_t index = 0; index < CONFIG_USBHOST_PIPE_NUM; index++) { - for (uint8_t j = 0; j < 2; j++) { - struct musb_pipe *pipe = &g_musb_hcd.pipe_pool[index][j]; - struct usbh_urb *urb = pipe->urb; - if (pipe->waiter) { - pipe->waiter = false; - urb->errorcode = -ESHUTDOWN; - usb_osal_sem_give(pipe->waitsem); - } - } - } usbh_roothub_thread_wakeup(1); }