diff options
| author | sakumisu <[email protected]> | 2024-03-26 20:41:17 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2024-03-26 20:41:17 +0800 |
| commit | 74bb03b8b4b36cf18732a74f2f8d63a47e466c62 (patch) | |
| tree | 71f356e4a27796db50c22370276e5fb56d0cae5d | |
| parent | bc6ed589b0337f485b48a4c66f4f71cf8ca6b7a1 (diff) | |
remove qtd alloc & free, use static pool instead
| -rw-r--r-- | port/ehci/usb_ehci_priv.h | 28 | ||||
| -rw-r--r-- | port/ehci/usb_hc_ehci.c | 141 |
2 files changed, 52 insertions, 117 deletions
diff --git a/port/ehci/usb_ehci_priv.h b/port/ehci/usb_ehci_priv.h index 3123346e..693cb805 100644 --- a/port/ehci/usb_ehci_priv.h +++ b/port/ehci/usb_ehci_priv.h @@ -13,34 +13,25 @@ #define EHCI_ADDR2QTD(x) ((struct ehci_qtd_hw *)((uint32_t)(x) & ~0x1F)) #define EHCI_ADDR2ITD(x) ((struct ehci_itd_hw *)((uint32_t)(x) & ~0x1F)) -#if CONFIG_USB_EHCI_FRAME_LIST_SIZE == 1024 -#define EHCI_PERIOIDIC_QH_NUM 11 -#elif CONFIG_USB_EHCI_FRAME_LIST_SIZE == 512 -#define EHCI_PERIOIDIC_QH_NUM 10 -#elif CONFIG_USB_EHCI_FRAME_LIST_SIZE == 256 -#define EHCI_PERIOIDIC_QH_NUM 9 -#else -#error Unsupported frame size list size -#endif - #define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM -#define CONFIG_USB_EHCI_QTD_NUM (CONFIG_USBHOST_PIPE_NUM + 3) +#define CONFIG_USB_EHCI_QTD_NUM 3 #define CONFIG_USB_EHCI_ITD_NUM 20 extern uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port); +struct ehci_qtd_hw { + struct ehci_qtd hw; + struct usbh_urb *urb; + uint32_t length; +} __attribute__((aligned(32))); + struct ehci_qh_hw { struct ehci_qh hw; + struct ehci_qtd_hw qtd_pool[CONFIG_USB_EHCI_QTD_NUM]; uint32_t first_qtd; struct usbh_urb *urb; - uint8_t remove_in_iaad; usb_osal_sem_t waitsem; -} __attribute__((aligned(32))); - -struct ehci_qtd_hw { - struct ehci_qtd hw; - struct usbh_urb *urb; - uint32_t total_len; + uint8_t remove_in_iaad; } __attribute__((aligned(32))); struct ehci_itd_hw { @@ -55,7 +46,6 @@ struct ehci_itd_hw { struct ehci_hcd { bool ehci_qh_used[CONFIG_USB_EHCI_QH_NUM]; - bool ehci_qtd_used[CONFIG_USB_EHCI_QTD_NUM]; bool ehci_itd_used[CONFIG_USB_EHCI_ITD_NUM]; }; diff --git a/port/ehci/usb_hc_ehci.c b/port/ehci/usb_hc_ehci.c index cb9b8825..eab31e59 100644 --- a/port/ehci/usb_hc_ehci.c +++ b/port/ehci/usb_hc_ehci.c @@ -14,7 +14,6 @@ struct ehci_hcd g_ehci_hcd[CONFIG_USBHOST_MAX_BUS]; 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[CONFIG_USBHOST_MAX_BUS]; @@ -27,7 +26,7 @@ USB_NOCACHE_RAM_SECTION uint32_t g_framelist[CONFIG_USBHOST_MAX_BUS][USB_ALIGN_U static struct ehci_qh_hw *ehci_qh_alloc(struct usbh_bus *bus) { struct ehci_qh_hw *qh; - usb_osal_sem_t waitsem; + struct ehci_qtd_hw *qtd; size_t flags; for (uint32_t i = 0; i < CONFIG_USB_EHCI_QH_NUM; i++) { @@ -37,12 +36,20 @@ static struct ehci_qh_hw *ehci_qh_alloc(struct usbh_bus *bus) usb_osal_leave_critical_section(flags); qh = &ehci_qh_pool[bus->hcd.hcd_id][i]; - waitsem = qh->waitsem; - memset(qh, 0, sizeof(struct ehci_qh_hw)); + memset(&qh->hw, 0, sizeof(struct ehci_qh)); qh->hw.hlp = QTD_LIST_END; qh->hw.overlay.next_qtd = QTD_LIST_END; qh->hw.overlay.alt_next_qtd = QTD_LIST_END; - qh->waitsem = waitsem; + qh->urb = NULL; + + for (uint32_t j = 0; j < CONFIG_USB_EHCI_QTD_NUM; j++) { + qtd = &qh->qtd_pool[j]; + qtd->hw.next_qtd = QTD_LIST_END; + qtd->hw.alt_next_qtd = QTD_LIST_END; + qtd->hw.token = QTD_TOKEN_STATUS_HALTED; + qtd->urb = NULL; + } + return qh; } } @@ -65,44 +72,6 @@ static void ehci_qh_free(struct usbh_bus *bus, struct ehci_qh_hw *qh) } } -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[bus->hcd.hcd_id].ehci_qtd_used[i]) { - flags = usb_osal_enter_critical_section(); - g_ehci_hcd[bus->hcd.hcd_id].ehci_qtd_used[i] = true; - usb_osal_leave_critical_section(flags); - - 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; - qtd->hw.token = QTD_TOKEN_STATUS_HALTED; - return qtd; - } - } - return NULL; -} - -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[bus->hcd.hcd_id][i] == qtd) { - flags = usb_osal_enter_critical_section(); - g_ehci_hcd[bus->hcd.hcd_id].ehci_qtd_used[i] = false; - usb_osal_leave_critical_section(flags); - - qtd->urb = NULL; - return; - } - } -} - static inline void ehci_qh_add_head(struct ehci_qh_hw *head, struct ehci_qh_hw *n) { n->hw.hlp = head->hw.hlp; @@ -281,7 +250,7 @@ static void ehci_qtd_fill(struct ehci_qtd_hw *qtd, uint32_t bufaddr, size_t bufl qtd->hw.token = token; ehci_qtd_bpl_fill(qtd, bufaddr, buflen); - qtd->total_len = buflen; + qtd->length = 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) @@ -298,22 +267,9 @@ static struct ehci_qh_hw *ehci_control_urb_init(struct usbh_bus *bus, struct usb return NULL; } - qtd_setup = ehci_qtd_alloc(bus); - if (buflen > 0) { - qtd_data = ehci_qtd_alloc(bus); - } - - qtd_status = ehci_qtd_alloc(bus); - if (qtd_status == NULL) { - ehci_qh_free(bus, qh); - if (qtd_setup) { - ehci_qtd_free(bus, qtd_setup); - } - if (qtd_data) { - ehci_qtd_free(bus, qtd_data); - } - return NULL; - } + qtd_setup = &qh->qtd_pool[0]; + qtd_data = &qh->qtd_pool[1]; + qtd_status = &qh->qtd_pool[2]; ehci_qh_fill(qh, urb->hport->dev_addr, @@ -408,17 +364,6 @@ static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_bus *bus, struct usbh_u return NULL; } - for (uint32_t i = 0; i < CONFIG_USB_EHCI_QTD_NUM; i++) { - if (!g_ehci_hcd[bus->hcd.hcd_id].ehci_qtd_used[i]) { - qtd_num++; - } - } - - if (qtd_num < ((buflen + 0x3fff) / 0x4000)) { - ehci_qh_free(bus, qh); - return NULL; - } - ehci_qh_fill(qh, urb->hport->dev_addr, urb->ep->bEndpointAddress, @@ -431,7 +376,7 @@ static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_bus *bus, struct usbh_u urb->hport->port); while (buflen >= 0) { - qtd = ehci_qtd_alloc(bus); + qtd = &qh->qtd_pool[qtd_num]; if (buflen > 0x4000) { xfer_len = 0x4000; @@ -470,6 +415,11 @@ static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_bus *bus, struct usbh_u if (buflen == 0) { break; } + qtd_num++; + + if (qtd_num == CONFIG_USB_EHCI_QTD_NUM) { + return NULL; + } } /* update qh first qtd */ @@ -515,17 +465,6 @@ static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_bus *bus, struct usbh_u return NULL; } - for (uint32_t i = 0; i < CONFIG_USB_EHCI_QTD_NUM; i++) { - if (!g_ehci_hcd[bus->hcd.hcd_id].ehci_qtd_used[i]) { - qtd_num++; - } - } - - if (qtd_num < ((buflen + 0x3fff) / 0x4000)) { - ehci_qh_free(bus, qh); - return NULL; - } - ehci_qh_fill(qh, urb->hport->dev_addr, urb->ep->bEndpointAddress, @@ -538,7 +477,7 @@ static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_bus *bus, struct usbh_u urb->hport->port); while (buflen >= 0) { - qtd = ehci_qtd_alloc(bus); + qtd = &qh->qtd_pool[qtd_num]; if (buflen > 0x4000) { xfer_len = 0x4000; @@ -577,6 +516,11 @@ static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_bus *bus, struct usbh_u if (buflen == 0) { break; } + qtd_num++; + + if (qtd_num == CONFIG_USB_EHCI_QTD_NUM) { + return NULL; + } } /* update qh first qtd */ @@ -641,9 +585,8 @@ static void ehci_qh_scan_qtds(struct usbh_bus *bus, struct ehci_qh_hw *qhead, st qtd = EHCI_ADDR2QTD(qh->first_qtd); while (qtd) { - qtd->urb->actual_length += (qtd->total_len - ((qtd->hw.token & QTD_TOKEN_NBYTES_MASK) >> QTD_TOKEN_NBYTES_SHIFT)); + qtd->urb->actual_length += (qtd->length - ((qtd->hw.token & QTD_TOKEN_NBYTES_MASK) >> QTD_TOKEN_NBYTES_SHIFT)); - ehci_qtd_free(bus, qtd); qh->first_qtd = qtd->hw.next_qtd; qtd = EHCI_ADDR2QTD(qh->first_qtd); } @@ -676,7 +619,7 @@ static void ehci_check_qh(struct usbh_bus *bus, struct ehci_qh_hw *qhead, struct urb = qh->urb; if ((token & QTD_TOKEN_STATUS_ERRORS) == 0) { - if (qh->hw.overlay.token & QTD_TOKEN_TOGGLE) { + if (token & QTD_TOKEN_TOGGLE) { urb->data_toggle = true; } else { urb->data_toggle = false; @@ -714,7 +657,6 @@ static void ehci_kill_qh(struct usbh_bus *bus, struct ehci_qh_hw *qhead, struct qtd = EHCI_ADDR2QTD(qh->first_qtd); while (qtd) { - ehci_qtd_free(bus, qtd); qh->first_qtd = qtd->hw.next_qtd; qtd = EHCI_ADDR2QTD(qh->first_qtd); } @@ -770,14 +712,20 @@ int usb_hc_init(struct usbh_bus *bus) uint32_t regval; memset(&g_ehci_hcd[bus->hcd.hcd_id], 0, sizeof(struct ehci_hcd)); + memset(ehci_qh_pool, 0, sizeof(struct ehci_qh_hw) * CONFIG_USB_EHCI_QH_NUM); - if (sizeof(struct ehci_qh_hw) % 32) { - USB_LOG_ERR("struct ehci_qh_hw is not align 32\r\n"); - return -USB_ERR_INVAL; - } - if (sizeof(struct ehci_qtd_hw) % 32) { - USB_LOG_ERR("struct ehci_qtd_hw is not align 32\r\n"); - return -USB_ERR_INVAL; + for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) { + qh = &ehci_qh_pool[bus->hcd.hcd_id][index]; + if ((uint32_t)&qh->hw % 32) { + USB_LOG_ERR("struct ehci_qh_hw is not align 32\r\n"); + return -USB_ERR_INVAL; + } + for (uint8_t i = 0; i < CONFIG_USB_EHCI_QTD_NUM; i++) { + if ((uint32_t)&qh->qtd_pool[i] % 32) { + USB_LOG_ERR("struct ehci_qtd_hw is not align 32\r\n"); + return -USB_ERR_INVAL; + } + } } for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) { @@ -1306,9 +1254,6 @@ void USBH_IRQHandler(uint8_t busid) for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) { 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[bus->hcd.hcd_id].ehci_qtd_used[index] = false; - } for (uint8_t index = 0; index < CONFIG_USB_EHCI_ITD_NUM; index++) { g_ehci_hcd[bus->hcd.hcd_id].ehci_itd_used[index] = false; } |
