diff options
| author | sakumisu <[email protected]> | 2022-02-23 17:46:48 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2022-02-23 17:46:48 +0800 |
| commit | 4db9c34d908c8df0e012d3901bf896a24e90bc9e (patch) | |
| tree | 8fbf47ce2cdfae44db49827d7e50ba40cd46a7af | |
| parent | 5c69ccff732f85d71a515543ae8f836e1cdda104 (diff) | |
add dcache clean and invalidate for ehci transfer when enable dcache
| -rw-r--r-- | port/ehci/usb_ehci.c | 284 |
1 files changed, 143 insertions, 141 deletions
diff --git a/port/ehci/usb_ehci.c b/port/ehci/usb_ehci.c index 448b4210..8e6e1175 100644 --- a/port/ehci/usb_ehci.c +++ b/port/ehci/usb_ehci.c @@ -67,10 +67,6 @@ #define usb_ehci_physramaddr(a) (a) #define usb_ehci_virtramaddr(a) (a) -/* Port numbers */ -// #define RHPNDX(rh) (rh) -// #define RHPORT(rh) (RHPNDX(rh) + 1) - /**************************************************************************** * Private Types ****************************************************************************/ @@ -176,6 +172,16 @@ static uint32_t usb_ehci_swap32(uint32_t value); #define usb_ehci_swap32(value) (value) #endif +#ifdef CONFIG_USB_DCACHE_ENABLE +void usb_ehci_dcache_clean(uintptr_t addr, uint32_t len); +void usb_ehci_dcache_invalidate(uintptr_t addr, uint32_t len); +void usb_ehci_dcache_clean_invalidate(uintptr_t addr, uint32_t len); +#else +#define usb_ehci_dcache_clean(addr, len) +#define usb_ehci_dcache_invalidate(addr, len) +#define usb_ehci_dcache_clean_invalidate(addr, len) +#endif + /**************************************************************************** * Private Data ****************************************************************************/ @@ -200,22 +206,22 @@ static struct usb_ehci_s g_ehci; /* The head of the asynchronous queue */ -USB_NOCACHE_RAM_SECTION struct usb_ehci_qh_s g_asynchead __attribute__((aligned(32))); +static struct usb_ehci_qh_s g_asynchead __attribute__((aligned(32))); /* The head of the periodic queue */ -USB_NOCACHE_RAM_SECTION struct usb_ehci_qh_s g_intrhead __attribute__((aligned(32))); +static struct usb_ehci_qh_s g_intrhead __attribute__((aligned(32))); /* Queue Head (QH) pool */ -USB_NOCACHE_RAM_SECTION struct usb_ehci_qh_s g_qhpool[CONFIG_USB_EHCI_QH_NUM] __attribute__((aligned(32))); +static struct usb_ehci_qh_s g_qhpool[CONFIG_USB_EHCI_QH_NUM] __attribute__((aligned(32))); /* Queue Element Transfer Descriptor (qTD) pool */ -USB_NOCACHE_RAM_SECTION struct usb_ehci_qtd_s g_qtdpool[CONFIG_USB_EHCI_QTD_NUM] __attribute__((aligned(32))); +static struct usb_ehci_qtd_s g_qtdpool[CONFIG_USB_EHCI_QTD_NUM] __attribute__((aligned(32))); /* The frame list */ -USB_NOCACHE_RAM_SECTION uint32_t g_framelist[FRAME_LIST_SIZE] __attribute__((aligned(4096))); +static uint32_t g_framelist[FRAME_LIST_SIZE] __attribute__((aligned(4096))); /**************************************************************************** * Private Functions ****************************************************************************/ @@ -592,7 +598,6 @@ static int usb_ehci_qh_discard(struct usb_ehci_qh_s *qh) ret = usb_ehci_qtd_foreach(qh, usb_ehci_qtd_discard, NULL); if (ret < 0) { - //usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); } /* Then free the QH itself */ @@ -600,8 +605,55 @@ static int usb_ehci_qh_discard(struct usb_ehci_qh_s *qh) usb_ehci_qh_free(qh); return ret; } +#ifdef CONFIG_USB_DCACHE_ENABLE +/**************************************************************************** + * Name: usb_ehci_qtd_flush + * + * Description: + * This is a callback from usb_ehci_qtd_foreach. It simply flushes D-cache + * for address range of the qTD entry. + * + ****************************************************************************/ + +static int usb_ehci_qtd_flush(struct usb_ehci_qtd_s *qtd, uint32_t **bp, void *arg) +{ + /* Flush the D-Cache, i.e., make the contents of the memory match the + * contents of the D-Cache in the specified address range and invalidate + * the D-Cache to force re-loading of the data from memory when next + * accessed. + */ + + usb_ehci_dcache_clean_invalidate((uintptr_t)&qtd->hw, sizeof(struct usb_ehci_qtd_s)); + + return 0; +} /**************************************************************************** + * Name: usb_ehci_qh_flush + * + * Description: + * Invalidate the Queue Head and all qTD entries in the queue. + * + ****************************************************************************/ + +static int usb_ehci_qh_flush(struct usb_ehci_qh_s *qh) +{ + /* Flush the QH first. This will write the contents of the D-cache to RAM + * and invalidate the contents of the D-cache so that the next access will + * be reloaded from D-Cache. + */ + + usb_ehci_dcache_clean_invalidate((uintptr_t)&qh->hw, sizeof(struct usb_ehci_qh_s)); + + /* Then flush all of the qTD entries in the queue */ + + return usb_ehci_qtd_foreach(qh, usb_ehci_qtd_flush, NULL); +} +#else +#define usb_ehci_qtd_flush(qtd, bp, arg) +#define usb_ehci_qtd_flush(qh) +#endif +/**************************************************************************** * Name: usb_ehci_speed * * Description: @@ -635,7 +687,6 @@ static struct usb_ehci_qh_s *usb_ehci_qh_create(struct usb_ehci_epinfo_s *epinfo qh = usb_ehci_qh_alloc(); if (qh == NULL) { - //usbhost_trace1(EHCI_TRACE1_QHALLOC_FAILED, 0); return NULL; } @@ -722,6 +773,7 @@ static int usb_ehci_qtd_addbpl(struct usb_ehci_qtd_s *qtd, const void *buffer, s uint32_t next; int ndx; + usb_ehci_dcache_clean_invalidate((uintptr_t)buffer, buflen); /* Loop, adding the aligned physical addresses of the buffer to the buffer * page list. Only the first entry need not be aligned (because only the * first entry has the offset field). The subsequent entries must begin on @@ -766,7 +818,6 @@ static int usb_ehci_qtd_addbpl(struct usb_ehci_qtd_s *qtd, const void *buffer, s /* Handle the case of a huge buffer > 4*4KB = 16KB */ if (ndx >= 5) { - //usbhost_trace1(EHCI_TRACE1_BUFTOOBIG, buflen); return -EFBIG; } @@ -783,7 +834,6 @@ static struct usb_ehci_qtd_s *usb_ehci_qtd_setupphase(struct usb_ehci_epinfo_s * qtd = usb_ehci_qtd_alloc(); if (qtd == NULL) { - //usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0); return NULL; } @@ -816,7 +866,6 @@ static struct usb_ehci_qtd_s *usb_ehci_qtd_setupphase(struct usb_ehci_epinfo_s * /* Add the buffer data */ ret = usb_ehci_qtd_addbpl(qtd, (uint8_t *)setup, 8); if (ret < 0) { - //usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret); usb_ehci_qtd_free(qtd); return NULL; } @@ -837,7 +886,6 @@ static struct usb_ehci_qtd_s *usb_ehci_qtd_dataphase(struct usb_ehci_epinfo_s *e qtd = usb_ehci_qtd_alloc(); if (qtd == NULL) { - //usbhost_trace1(EHCI_TRACE1_DATAQTDALLOC_FAILED, 0); return NULL; } @@ -869,7 +917,6 @@ static struct usb_ehci_qtd_s *usb_ehci_qtd_dataphase(struct usb_ehci_epinfo_s *e ret = usb_ehci_qtd_addbpl(qtd, buffer, buflen); if (ret < 0) { - //usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret); usb_ehci_qtd_free(qtd); return NULL; } @@ -889,7 +936,6 @@ static struct usb_ehci_qtd_s *usb_ehci_qtd_statusphase(uint32_t tokenbits) qtd = usb_ehci_qtd_alloc(); if (qtd == NULL) { - //usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0); return NULL; } @@ -931,7 +977,6 @@ static void usb_ehci_qh_enqueue(struct usb_ehci_qh_s *qhead, struct usb_ehci_qh_ */ qh->fqp = qh->hw.overlay.nqp; - //usb_ehci_qh_dump(qh, NULL, NULL); /* Add the new QH to the head of the asynchronous queue list. * @@ -940,11 +985,12 @@ static void usb_ehci_qh_enqueue(struct usb_ehci_qh_s *qhead, struct usb_ehci_qh_ */ qh->hw.hlp = qhead->hw.hlp; - + usb_ehci_qh_flush(qh); /* Then set the new QH as the first QH in the asynchronous queue */ physaddr = (uintptr_t)usb_ehci_physramaddr((uintptr_t)qh); qhead->hw.hlp = usb_ehci_swap32(physaddr | QH_HLP_TYP_QH); + usb_ehci_dcache_clean((uintptr_t)&qhead->hw, sizeof(struct usb_ehci_qh_s)); } static int usb_ehci_control_setup(struct usb_ehci_epinfo_s *epinfo, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen) @@ -962,7 +1008,6 @@ static int usb_ehci_control_setup(struct usb_ehci_epinfo_s *epinfo, struct usb_s /* Create and initialize a Queue Head (QH) structure for this transfer */ qh = usb_ehci_qh_create(epinfo); if (qh == NULL) { - //usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0); return -ENOMEM; } @@ -987,7 +1032,6 @@ static int usb_ehci_control_setup(struct usb_ehci_epinfo_s *epinfo, struct usb_s { qtd = usb_ehci_qtd_setupphase(epinfo, setup); if (qtd == NULL) { - //usbhost_trace1(EHCI_TRACE1_QTDSETUP_FAILED, 0); ret = -ENOMEM; goto errout_with_qh; } @@ -1034,7 +1078,6 @@ static int usb_ehci_control_setup(struct usb_ehci_epinfo_s *epinfo, struct usb_s qtd = usb_ehci_qtd_dataphase(epinfo, buffer, buflen, tokenbits); if (qtd == NULL) { - //usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0); ret = -ENOMEM; goto errout_with_qh; } @@ -1079,7 +1122,6 @@ static int usb_ehci_control_setup(struct usb_ehci_epinfo_s *epinfo, struct usb_s */ qtd = usb_ehci_qtd_statusphase(tokenbits); if (qtd == NULL) { - //usbhost_trace1(EHCI_TRACE1_QTDSTATUS_FAILED, 0); ret = -ENOMEM; goto errout_with_qh; } @@ -1119,7 +1161,6 @@ static int usb_ehci_bulk_setup(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer /* Create and initialize a Queue Head (QH) structure for this transfer */ qh = usb_ehci_qh_create(epinfo); if (qh == NULL) { - //usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0); return -ENOMEM; } @@ -1143,7 +1184,6 @@ static int usb_ehci_bulk_setup(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer qtd = usb_ehci_qtd_dataphase(epinfo, buffer, buflen, tokenbits); if (qtd == NULL) { - //usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0); ret = -ENOMEM; goto errout_with_qh; } @@ -1174,7 +1214,6 @@ static int usb_ehci_intr_setup(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer /* Create and initialize a Queue Head (QH) structure for this transfer */ qh = usb_ehci_qh_create(epinfo); if (qh == NULL) { - //usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0); return -ENOMEM; } @@ -1196,7 +1235,6 @@ static int usb_ehci_intr_setup(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer qtd = usb_ehci_qtd_dataphase(epinfo, buffer, buflen, tokenbits); if (qtd == NULL) { - //usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0); ret = -ENOMEM; goto errout_with_qh; } @@ -1426,7 +1464,6 @@ static int usb_ehci_transfer_wait(struct usb_ehci_epinfo_s *epinfo) /* Did epinfo->result or usb_osal_mutex_take() report an error? */ if (ret < 0) { - //usbhost_trace1(EHCI_TRACE1_TRANSFER_FAILED, -ret); epinfo->iocwait = false; return ret; } @@ -1451,7 +1488,7 @@ static int usb_ehci_qtd_ioccheck(struct usb_ehci_qtd_s *qtd, uint32_t **bp, struct usb_ehci_epinfo_s *epinfo = (struct usb_ehci_epinfo_s *)arg; DEBUGASSERT(qtd && epinfo); - //usb_ehci_qtd_print(qtd); + usb_ehci_dcache_invalidate((uintptr_t)&qtd->hw, sizeof(struct usb_ehci_qtd_s)); /* Remove the qTD from the list * @@ -1499,7 +1536,7 @@ static int usb_ehci_qh_ioccheck(struct usb_ehci_qh_s *qh, uint32_t **bp, void *a DEBUGASSERT(qh && bp); - //usb_ehci_qh_print(qh); + usb_ehci_dcache_invalidate((uintptr_t)&qh->hw, sizeof(struct ehci_qh_s)); /* Get the endpoint info pointer from the extended QH data. Only the * g_asynchead QH can have a NULL epinfo field. @@ -1522,7 +1559,6 @@ static int usb_ehci_qh_ioccheck(struct usb_ehci_qh_s *qh, uint32_t **bp, void *a /* Is the qTD still active? */ token = usb_ehci_swap32(qh->hw.overlay.token); - //usbhost_vtrace2(EHCI_VTRACE2_IOCCHECK, epinfo->epno, token); if ((token & QH_TOKEN_ACTIVE) != 0) { /* Yes... we cannot process the QH while it is still active. Return @@ -1535,7 +1571,6 @@ static int usb_ehci_qh_ioccheck(struct usb_ehci_qh_s *qh, uint32_t **bp, void *a /* Remove all active, attached qTD structures from the inactive QH */ ret = usb_ehci_qtd_foreach(qh, usb_ehci_qtd_ioccheck, (void *)qh->epinfo); if (ret < 0) { - //usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); } /* If there is no longer anything attached to the QH, then remove it from * the asynchronous queue. @@ -1547,7 +1582,7 @@ static int usb_ehci_qh_ioccheck(struct usb_ehci_qh_s *qh, uint32_t **bp, void *a */ **bp = qh->hw.hlp; - + usb_ehci_dcache_clean((uintptr_t)*bp, sizeof(uint32_t)); /* Check for errors, update the data toggle */ if ((token & QH_TOKEN_ERRORS) == 0) { @@ -1559,6 +1594,7 @@ static int usb_ehci_qh_ioccheck(struct usb_ehci_qh_s *qh, uint32_t **bp, void *a epinfo->status = 0; epinfo->result = 0; + } else { /* An error occurred */ @@ -1576,16 +1612,14 @@ static int usb_ehci_qh_ioccheck(struct usb_ehci_qh_s *qh, uint32_t **bp, void *a QH_TOKEN_HALTED && (token & QH_TOKEN_CERR_MASK) != 0) { /* It is a stall, Note that the data toggle is reset - * after the stall. - */ + * after the stall. + */ - //usbhost_trace2(EHCI_TRACE2_EPSTALLED, epinfo->epno, token); epinfo->result = -EPERM; epinfo->toggle = 0; } else { /* Otherwise, it is some kind of data transfer error */ - //usbhost_trace2(EHCI_TRACE2_EPIOERROR, epinfo->epno, token); epinfo->result = -EIO; } } @@ -1594,12 +1628,6 @@ static int usb_ehci_qh_ioccheck(struct usb_ehci_qh_s *qh, uint32_t **bp, void *a if (epinfo->iocwait) { /* Yes... wake it up */ epinfo->iocwait = false; - /* TODO */ - // clang-format off - for (size_t i = 0; i < 3200; i++) { - __asm volatile("nop" ::: "memory"); - } - // clang-format on usb_osal_sem_give(epinfo->iocsem); } #ifdef CONFIG_USBHOST_ASYNCH @@ -1611,7 +1639,6 @@ static int usb_ehci_qh_ioccheck(struct usb_ehci_qh_s *qh, uint32_t **bp, void *a usb_ehci_asynch_completion(epinfo); } #endif - /* Then release this QH by returning it to the free list */ usb_ehci_qh_free(qh); } else { @@ -1638,7 +1665,7 @@ static int usb_ehci_qtd_cancel(struct usb_ehci_qtd_s *qtd, uint32_t **bp, { DEBUGASSERT(qtd != NULL && bp != NULL); - //usb_ehci_qtd_print(qtd); + usb_ehci_dcache_invalidate((uintptr_t)&qtd->hw, sizeof(struct usb_ehci_qtd_s)); /* Remove the qTD from the list * @@ -1676,7 +1703,7 @@ static int usb_ehci_qh_cancel(struct usb_ehci_qh_s *qh, uint32_t **bp, void *arg DEBUGASSERT(qh != NULL && bp != NULL && epinfo != NULL); - //usb_ehci_qh_print(qh); + usb_ehci_dcache_invalidate((uintptr_t)&qh->hw, sizeof(struct usb_ehci_qh_s)); /* Check if this is the QH that we are looking for */ @@ -1703,7 +1730,7 @@ static int usb_ehci_qh_cancel(struct usb_ehci_qh_s *qh, uint32_t **bp, void *arg */ **bp = qh->hw.hlp; - + usb_ehci_dcache_clean((uintptr_t)*bp, sizeof(uint32_t)); /* Re-enable the schedules (if they were enabled before. */ usb_ehci_putreg(regval, &HCOR->usbcmd); @@ -1712,7 +1739,6 @@ static int usb_ehci_qh_cancel(struct usb_ehci_qh_s *qh, uint32_t **bp, void *arg ret = usb_ehci_qtd_foreach(qh, usb_ehci_qtd_cancel, NULL); if (ret < 0) { - //usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); } /* Then release this QH by returning it to the free list. Return 1 @@ -1729,6 +1755,7 @@ static inline void usb_ehci_ioc_bottomhalf(void) uint32_t *bp; int ret; + usb_ehci_dcache_invalidate((uintptr_t)&g_asynchead.hw, sizeof(struct usb_ehci_qh_s)); /* Set the back pointer to the forward qTD pointer of the asynchronous * queue head. */ @@ -1749,6 +1776,7 @@ static inline void usb_ehci_ioc_bottomhalf(void) #ifndef CONFIG_USBHOST_INT_DISABLE /* Check the Interrupt Queue */ + usb_ehci_dcache_invalidate((uintptr_t)&g_intrhead.hw, sizeof(struct usb_ehci_qh_s)); /* Set the back pointer to the forward qTD pointer of the asynchronous * queue head. */ @@ -1763,7 +1791,6 @@ static inline void usb_ehci_ioc_bottomhalf(void) ret = usb_ehci_qh_foreach(qh, &bp, usb_ehci_qh_ioccheck, NULL); if (ret < 0) { - //usbhost_trace1(EHCI_TRACE1_QHFOREACH_FAILED, -ret); } } #endif @@ -1802,14 +1829,10 @@ static inline void usb_ehci_portsc_bottomhalf(void) for (rhpndx = 0; rhpndx < CONFIG_USBHOST_RHPORTS; rhpndx++) { portsc = usb_ehci_getreg(&HCOR->portsc[rhpndx]); - //usbhost_vtrace2(EHCI_VTRACE2_PORTSC, rhpndx + 1, portsc); - /* Handle port connection status change (CSC) events */ if ((portsc & EHCI_PORTSC_CSC) != 0) { - //usbhost_vtrace1(EHCI_VTRACE1_PORTSC_CSC, portsc); - /* Check current connect status */ - if ((portsc & EHCI_PORTSC_CCS) != 0) { + if ((portsc & (EHCI_PORTSC_CCS | EHCI_PORTSC_PE)) != 0) { /* Connected ... Did we just become connected? */ if (!g_ehci.connected) { g_ehci.connected = 1; @@ -1921,7 +1944,6 @@ static int usb_ehci_reset(void) /* Is the EHCI still running? Did we timeout? */ if ((regval & EHCI_USBSTS_HALTED) == 0) { - //usbhost_trace1(EHCI_TRACE1_HCHALTED_TIMEOUT, regval); return -ETIMEDOUT; } @@ -1980,7 +2002,6 @@ static int usb_ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits, unsigned i regval = usb_ehci_getreg(&HCOR->usbsts); if ((regval & EHCI_INT_SYSERROR) != 0) { - //usbhost_trace1(EHCI_TRACE1_SYSTEMERROR, regval); return -EIO; } @@ -2000,11 +2021,7 @@ static int usb_ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits, unsigned i return (regval == donebits) ? 0 : -ETIMEDOUT; } -__WEAK void usb_ehci_pre_hw_init(void) -{ -} - -__WEAK void usb_ehci_last_hw_init(void) +__WEAK void usb_hc_low_level_init(void) { } @@ -2054,7 +2071,7 @@ int usb_hc_init(void) g_asynchead.hw.overlay.token = usb_ehci_swap32(QH_TOKEN_HALTED); g_asynchead.fqp = usb_ehci_swap32(QTD_NQP_T); - g_ehci.exclsem = usb_osal_mutex_create(); + usb_ehci_dcache_clean((uintptr_t)&g_asynchead.hw, sizeof(struct usb_ehci_qh_s)); /* Initialize the head of the periodic list. Since Isochronous * endpoints are not not yet supported, each element of the @@ -2070,7 +2087,6 @@ int usb_hc_init(void) g_intrhead.hw.epcaps = usb_ehci_swap32(QH_EPCAPS_SSMASK(1)); /* Attach the periodic QH to Period Frame List */ - physaddr2 = usb_ehci_physramaddr((uintptr_t)&g_intrhead); for (uint32_t i = 0; i < FRAME_LIST_SIZE; i++) { g_framelist[i] = usb_ehci_swap32(physaddr2) | PFL_TYP_QH; @@ -2079,13 +2095,17 @@ int usb_hc_init(void) /* Set the Periodic Frame List Base Address. */ physaddr2 = usb_ehci_physramaddr((uintptr_t)g_framelist); - usb_ehci_pre_hw_init(); + usb_ehci_dcache_clean((uintptr_t)&g_intrhead.hw, sizeof(struct usb_ehci_qh_s)); + usb_ehci_dcache_clean((uintptr_t)g_framelist, FRAME_LIST_SIZE * sizeof(uint32_t)); + + g_ehci.exclsem = usb_osal_mutex_create(); + + usb_hc_low_level_init(); /* Host Controller Initialization. Paragraph 4.1 */ /* Reset the EHCI hardware */ ret = usb_ehci_reset(); if (ret < 0) { - //usbhost_trace1(EHCI_TRACE1_RESET_FAILED, -ret); return -1; } @@ -2155,7 +2175,6 @@ int usb_hc_init(void) /* Wait for the EHCI to run (i.e., no longer report halted) */ ret = usb_ehci_wait_usbsts(EHCI_USBSTS_HALTED, 0, 100 * 1000); if (ret < 0) { - //usbhost_trace1(EHCI_TRACE1_RUN_FAILED, usb_ehci_getreg(&HCOR->usbsts)); return -2; } @@ -2164,7 +2183,6 @@ int usb_hc_init(void) */ usb_ehci_putreg(EHCI_HANDLED_INTS, &HCOR->usbintr); - usb_ehci_last_hw_init(); return ret; } @@ -2324,7 +2342,6 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint /* Set the request for the IOC event well BEFORE initiating the transfer. */ ret = usb_ehci_ioc_setup(epinfo); if (ret != 0) { - //usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); goto errout_with_sem; } @@ -2361,7 +2378,6 @@ int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen) ret = usb_ehci_ioc_setup(epinfo); if (ret != 0) { - //usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); goto errout_with_sem; } @@ -2399,7 +2415,6 @@ int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen) ret = usb_ehci_ioc_setup(epinfo); if (ret != 0) { - //usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); goto errout_with_sem; } @@ -2628,12 +2643,8 @@ int usb_ep_cancel(usbh_epinfo_t ep) } break; #endif -#ifndef CONFIG_USBHOST_ISOC_DISABLE case USB_ENDPOINT_TYPE_ISOCHRONOUS: -#warning "Isochronous endpoint support not emplemented" -#endif default: - //usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); ret = -ENOSYS; goto errout_with_sem; } @@ -2651,7 +2662,6 @@ int usb_ep_cancel(usbh_epinfo_t ep) ret = usb_ehci_qh_foreach(qh, &bp, usb_ehci_qh_cancel, epinfo); if (ret < 0) { - //usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); } /* Was there a pending synchronous transfer? */ @@ -2698,64 +2708,58 @@ static void usb_ehci_bottomhalf(void *arg) /* Handle all unmasked interrupt sources */ /* USB Interrupt (USBINT) - * - * "The Host Controller sets this bit to 1 on the completion of a USB - * transaction, which results in the retirement of a Transfer Descriptor - * that had its IOC bit set. - * - * "The Host Controller also sets this bit to 1 when a short packet is - * detected (actual number of bytes received was less than the expected - * number of bytes)." - * - * USB Error Interrupt (USBERRINT) - * - * "The Host Controller sets this bit to 1 when completion of a USB - * transaction results in an error condition (e.g., error counter - * underflow). If the TD on which the error interrupt occurred also - * had its IOC bit set, both this bit and USBINT bit are set. ..." - * - * We do the same thing in either case: Traverse the asynchronous queue - * and remove all of the transfers that are no longer active. - */ + * + * "The Host Controller sets this bit to 1 on the completion of a USB + * transaction, which results in the retirement of a Transfer Descriptor + * that had its IOC bit set. + * + * "The Host Controller also sets this bit to 1 when a short packet is + * detected (actual number of bytes received was less than the expected + * number of bytes)." + * + * USB Error Interrupt (USBERRINT) + * + * "The Host Controller sets this bit to 1 when completion of a USB + * transaction results in an error condition (e.g., error counter + * underflow). If the TD on which the error interrupt occurred also + * had its IOC bit set, both this bit and USBINT bit are set. ..." + * + * We do the same thing in either case: Traverse the asynchronous queue + * and remove all of the transfers that are no longer active. + */ if ((pending & (EHCI_INT_USBINT | EHCI_INT_USBERRINT)) != 0) { - if ((pending & EHCI_INT_USBERRINT) != 0) { - //usbhost_trace1(EHCI_TRACE1_USBERR_INTR, pending); - } else { - //usbhost_vtrace1(EHCI_VTRACE1_USBINTR, pending); - } - usb_ehci_ioc_bottomhalf(); } /* Port Change Detect - * - * "The Host Controller sets this bit to a one when any port for which - * the Port Owner bit is set to zero ... has a change bit transition - * from a zero to a one or a Force Port Resume bit transition from a zero - * to a one as a result of a J-K transition detected on a suspended port. - * This bit will also be set as a result of the Connect Status Change - * being set to a one after system software has relinquished ownership - * of a connected port by writing a one to a port's Port Owner bit... - * - * "This bit is allowed to be maintained in the Auxiliary power well. - * Alternatively, it is also acceptable that on a D3 to D0 transition - * of the EHCI HC device, this bit is loaded with the OR of all of the - * PORTSC change bits (including: Force port resume, over-current change, - * enable/disable change and connect status change)." - */ + * + * "The Host Controller sets this bit to a one when any port for which + * the Port Owner bit is set to zero ... has a change bit transition + * from a zero to a one or a Force Port Resume bit transition from a zero + * to a one as a result of a J-K transition detected on a suspended port. + * This bit will also be set as a result of the Connect Status Change + * being set to a one after system software has relinquished ownership + * of a connected port by writing a one to a port's Port Owner bit... + * + * "This bit is allowed to be maintained in the Auxiliary power well. + * Alternatively, it is also acceptable that on a D3 to D0 transition + * of the EHCI HC device, this bit is loaded with the OR of all of the + * PORTSC change bits (including: Force port resume, over-current change, + * enable/disable change and connect status change)." + */ if ((pending & EHCI_INT_PORTSC) != 0) { usb_ehci_portsc_bottomhalf(); } /* Frame List Rollover - * - * "The Host Controller sets this bit to a one when the Frame List Index - * ... rolls over from its maximum value to zero. The exact value at - * which the rollover occurs depends on the frame list size. For example, - * if the frame list size (as programmed in the Frame List Size field of - * the USBCMD register) is 1024, the Frame Index Register rolls over - * every time FRINDEX[13] toggles. Similarly, if the size is 512, the - * Host Controller sets this bit to a one every time FRINDEX[12] - * toggles." - */ + * + * "The Host Controller sets this bit to a one when the Frame List Index + * ... rolls over from its maximum value to zero. The exact value at + * which the rollover occurs depends on the frame list size. For example, + * if the frame list size (as programmed in the Frame List Size field of + * the USBCMD register) is 1024, the Frame Index Register rolls over + * every time FRINDEX[13] toggles. Similarly, if the size is 512, the + * Host Controller sets this bit to a one every time FRINDEX[12] + * toggles." + */ #if 0 /* Not used */ if ((pending & EHCI_INT_FLROLL) != 0) @@ -2764,28 +2768,26 @@ static void usb_ehci_bottomhalf(void *arg) } #endif /* Host System Error - * - * "The Host Controller sets this bit to 1 when a serious error occurs - * during a host system access involving the Host Controller module. ... - * When this error occurs, the Host Controller clears the Run/Stop bit - * in the Command register to prevent further execution of the scheduled - * TDs." - */ + * + * "The Host Controller sets this bit to 1 when a serious error occurs + * during a host system access involving the Host Controller module. ... + * When this error occurs, the Host Controller clears the Run/Stop bit + * in the Command register to prevent further execution of the scheduled + * TDs." + */ if ((pending & EHCI_INT_SYSERROR) != 0) { - //usbhost_trace1(EHCI_TRACE1_SYSERR_INTR, 0); } /* Interrupt on Async Advance - * - * "System software can force the host controller to issue an interrupt - * the next time the host controller advances the asynchronous schedule - * by writing a one to the Interrupt on Async Advance Doorbell bit in - * the USBCMD register. This status bit indicates the assertion of that - * interrupt source." - */ + * + * "System software can force the host controller to issue an interrupt + * the next time the host controller advances the asynchronous schedule + * by writing a one to the Interrupt on Async Advance Doorbell bit in + * the USBCMD register. This status bit indicates the assertion of that + * interrupt source." + */ if ((pending & EHCI_INT_AAINT) != 0) { - //usbhost_vtrace1(EHCI_VTRACE1_AAINTR, 0); } /* Re-enable relevant EHCI interrupts. Interrupts should still be enabled * at the level of the interrupt controller. |
