summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2024-03-25 19:20:05 +0800
committersakumisu <[email protected]>2024-03-25 19:53:22 +0800
commitf99e4ce1139131a40c08b74d0b0d4e965747fafc (patch)
treeee772c77619fd1669fc5cef2e206d6d3e60be49e
parentd6d1b677614cf8e5df2f59881cca4cd57a03d8ae (diff)
use only one qh for intr, following with linux driver
-rw-r--r--port/ehci/usb_hc_ehci.c74
1 files changed, 15 insertions, 59 deletions
diff --git a/port/ehci/usb_hc_ehci.c b/port/ehci/usb_hc_ehci.c
index e6f28ecc..cb9b8825 100644
--- a/port/ehci/usb_hc_ehci.c
+++ b/port/ehci/usb_hc_ehci.c
@@ -19,7 +19,7 @@ USB_NOCACHE_RAM_SECTION struct ehci_qtd_hw ehci_qtd_pool[CONFIG_USBHOST_MAX_BUS]
/* The head of the asynchronous queue */
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[CONFIG_USBHOST_MAX_BUS][EHCI_PERIOIDIC_QH_NUM];
+USB_NOCACHE_RAM_SECTION struct ehci_qh_hw g_periodic_qh_head[CONFIG_USBHOST_MAX_BUS];
/* The frame list */
USB_NOCACHE_RAM_SECTION uint32_t g_framelist[CONFIG_USBHOST_MAX_BUS][USB_ALIGN_UP(CONFIG_USB_EHCI_FRAME_LIST_SIZE, 1024)] __attribute__((aligned(4096)));
@@ -144,19 +144,6 @@ static int ehci_caculate_smask(int binterval)
return (0x1 << (order % 8));
}
-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[bus->hcd.hcd_id][i];
- }
- }
- return &g_periodic_qh_head[bus->hcd.hcd_id][EHCI_PERIOIDIC_QH_NUM - 1];
-}
-
static void ehci_qh_fill(struct ehci_qh_hw *qh,
uint8_t dev_addr,
uint8_t ep_addr,
@@ -611,11 +598,7 @@ static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_bus *bus, struct usbh_u
qh->urb = urb;
urb->hcpriv = qh;
/* add qh into periodic list */
- if (urb->hport->speed == USB_SPEED_HIGH) {
- ehci_qh_add_head(ehci_get_periodic_qhead(bus, urb->ep->bInterval), qh);
- } else {
- ehci_qh_add_head(ehci_get_periodic_qhead(bus, urb->ep->bInterval * 8), qh);
- }
+ ehci_qh_add_head(&g_periodic_qh_head[bus->hcd.hcd_id], qh);
EHCI_HCOR->usbcmd |= EHCI_USBCMD_PSEN;
@@ -781,7 +764,6 @@ __WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus)
int usb_hc_init(struct usbh_bus *bus)
{
- uint32_t interval;
struct ehci_qh_hw *qh;
volatile uint32_t timeout = 0;
@@ -813,34 +795,16 @@ int usb_hc_init(struct usbh_bus *bus)
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[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[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[bus->hcd.hcd_id][j]);
- while (1) {
- 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[bus->hcd.hcd_id][i]);
- break;
- }
+ memset(&g_periodic_qh_head[bus->hcd.hcd_id], 0, sizeof(struct ehci_qh_hw));
+ g_periodic_qh_head[bus->hcd.hcd_id].hw.hlp = QH_HLP_END;
+ g_periodic_qh_head[bus->hcd.hcd_id].hw.epchar = QH_EPCAPS_SSMASK(1);
+ g_periodic_qh_head[bus->hcd.hcd_id].hw.overlay.next_qtd = QTD_LIST_END;
+ g_periodic_qh_head[bus->hcd.hcd_id].hw.overlay.alt_next_qtd = QTD_LIST_END;
+ g_periodic_qh_head[bus->hcd.hcd_id].hw.overlay.token = QTD_TOKEN_STATUS_HALTED;
+ g_periodic_qh_head[bus->hcd.hcd_id].first_qtd = QTD_LIST_END;
- qh = EHCI_ADDR2QH(qh->hw.hlp);
- }
- }
- }
+ for (uint32_t i = 0; i < CONFIG_USB_EHCI_FRAME_LIST_SIZE; i++) {
+ g_framelist[bus->hcd.hcd_id][i] = QH_HLP_QH(&g_periodic_qh_head[bus->hcd.hcd_id]);
}
usb_hc_low_level_init(bus);
@@ -1245,14 +1209,10 @@ int usbh_kill_urb(struct usbh_urb *urb)
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[bus->hcd.hcd_id][EHCI_PERIOIDIC_QH_NUM - 1].hw.hlp);
+ qh = EHCI_ADDR2QH(g_periodic_qh_head[bus->hcd.hcd_id].hw.hlp);
while (qh) {
if (qh->urb == urb) {
- if (urb->hport->speed == USB_SPEED_HIGH) {
- ehci_kill_qh(bus, ehci_get_periodic_qhead(bus, urb->ep->bInterval), qh);
- } else {
- ehci_kill_qh(bus, ehci_get_periodic_qhead(bus, urb->ep->bInterval * 8), qh);
- }
+ ehci_kill_qh(bus, &g_periodic_qh_head[bus->hcd.hcd_id], qh);
}
qh = EHCI_ADDR2QH(qh->hw.hlp);
}
@@ -1301,14 +1261,10 @@ static void ehci_scan_periodic_list(struct usbh_bus *bus)
{
struct ehci_qh_hw *qh;
- qh = EHCI_ADDR2QH(g_periodic_qh_head[bus->hcd.hcd_id][EHCI_PERIOIDIC_QH_NUM - 1].hw.hlp);
+ qh = EHCI_ADDR2QH(g_periodic_qh_head[bus->hcd.hcd_id].hw.hlp);
while (qh) {
if (qh->urb) {
- if (qh->urb->hport->speed == USB_SPEED_HIGH) {
- ehci_check_qh(bus, ehci_get_periodic_qhead(bus, qh->urb->ep->bInterval), qh);
- } else {
- ehci_check_qh(bus, ehci_get_periodic_qhead(bus, qh->urb->ep->bInterval * 8), qh);
- }
+ ehci_check_qh(bus, &g_periodic_qh_head[bus->hcd.hcd_id], qh);
}
qh = EHCI_ADDR2QH(qh->hw.hlp);
}