summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2022-06-16 22:24:03 +0800
committersakumisu <[email protected]>2022-06-16 22:24:03 +0800
commit12f74971ebaeeb463fad905227156d669a7e083b (patch)
tree3a20c886c25b91053b08bdb0b91da34208f27f5f
parent224c26bc23bd19a2c59f7aeea39b65a51bac74b7 (diff)
sync ehci code
-rw-r--r--port/ehci/usb_ehci.c229
1 files changed, 123 insertions, 106 deletions
diff --git a/port/ehci/usb_ehci.c b/port/ehci/usb_ehci.c
index 29da8d43..bd24e232 100644
--- a/port/ehci/usb_ehci.c
+++ b/port/ehci/usb_ehci.c
@@ -1,6 +1,10 @@
#include "usbh_core.h"
#include "usb_ehci.h"
+#ifndef USBH_IRQHandler
+#define USBH_IRQHandler USBH_IRQHandler
+#endif
+
#define DEBUGASSERT(f)
/* Configurable number of Queue Head (QH) structures. The default is one per
@@ -120,14 +124,14 @@ struct usb_ehci_epinfo_s {
#ifndef CONFIG_USBHOST_INT_DISABLE
uint8_t interval; /* Polling interval */
#endif
- uint8_t status; /* Retained token status bits (for debug purposes) */
- volatile bool iocwait; /* TRUE: Thread is waiting for transfer completion */
- uint16_t maxpacket : 11; /* Maximum packet size */
- uint16_t xfrtype : 2; /* See USB_EP_ATTR_XFER_* definitions in usb.h */
- uint16_t speed : 2; /* See USB_*_SPEED definitions in ehci.h */
- int result; /* The result of the transfer */
- uint32_t xfrd; /* On completion, will hold the number of bytes transferred */
bool inuse;
+ uint8_t status; /* Retained token status bits (for debug purposes) */
+ uint16_t maxpacket : 11; /* Maximum packet size */
+ uint16_t xfrtype : 2; /* See USB_EP_ATTR_XFER_* definitions in usb.h */
+ uint16_t speed : 2; /* See USB_*_SPEED definitions in ehci.h */
+ int result; /* The result of the transfer */
+ uint32_t xfrd; /* On completion, will hold the number of bytes transferred */
+ volatile bool iocwait; /* TRUE: Thread is waiting for transfer completion */
usb_osal_sem_t iocsem; /* Semaphore used to wait for transfer completion */
usb_osal_mutex_t exclsem; /* Support mutually exclusive access */
#ifdef CONFIG_USBHOST_ASYNCH
@@ -140,9 +144,11 @@ struct usb_ehci_epinfo_s {
/* This structure retains the overall state of the USB host controller */
-struct usb_ehci_s {
- struct usb_ehci_list_s *qhfree; /* List of free Queue Head (QH) structures */
- struct usb_ehci_list_s *qtdfree; /* List of free Queue Element Transfer Descriptor (qTD) */
+struct ehci_hcd {
+ struct usb_ehci_list_s *qhfree; /* List of free Queue Head (QH) structures */
+ struct usb_ehci_list_s *qtdfree; /* List of free Queue Element Transfer Descriptor (qTD) */
+ __attribute__((aligned(32))) struct usb_ehci_qh_s qhpool[CONFIG_USB_EHCI_QH_NUM]; /* Queue Head (QH) pool */
+ __attribute__((aligned(32))) struct usb_ehci_qtd_s qtdpool[CONFIG_USB_EHCI_QTD_NUM]; /* Queue Element Transfer Descriptor (qTD) pool */
struct usb_ehci_epinfo_s chan[CONFIG_USBHOST_PIPE_NUM];
};
@@ -197,7 +203,7 @@ static const uint8_t g_ehci_speed[4] = {
* global instance.
*/
-static struct usb_ehci_s g_ehci;
+static struct ehci_hcd g_ehci_hcd;
/* The head of the asynchronous queue */
@@ -207,14 +213,6 @@ static struct usb_ehci_qh_s g_asynchead __attribute__((aligned(32)));
static struct usb_ehci_qh_s g_intrhead __attribute__((aligned(32)));
-/* Queue Head (QH) pool */
-
-static struct usb_ehci_qh_s g_qhpool[CONFIG_USB_EHCI_QH_NUM] __attribute__((aligned(32)));
-
-/* Queue Element Transfer Descriptor (qTD) pool */
-
-static struct usb_ehci_qtd_s g_qtdpool[CONFIG_USB_EHCI_QTD_NUM] __attribute__((aligned(32)));
-
/* The frame list */
static uint32_t g_framelist[FRAME_LIST_SIZE] __attribute__((aligned(4096)));
/****************************************************************************
@@ -306,10 +304,10 @@ static int usb_ehci_chan_alloc(void)
for (chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
/* Is this channel available? */
- if (!g_ehci.chan[chidx].inuse) {
+ if (!g_ehci_hcd.chan[chidx].inuse) {
/* Yes... make it "in use" and return the index */
- g_ehci.chan[chidx].inuse = true;
+ g_ehci_hcd.chan[chidx].inuse = true;
return chidx;
}
}
@@ -340,9 +338,9 @@ static struct usb_ehci_qh_s *usb_ehci_qh_alloc(void)
/* Remove the QH structure from the freelist */
- qh = (struct usb_ehci_qh_s *)g_ehci.qhfree;
+ qh = (struct usb_ehci_qh_s *)g_ehci_hcd.qhfree;
if (qh) {
- g_ehci.qhfree = ((struct usb_ehci_list_s *)qh)->flink;
+ g_ehci_hcd.qhfree = ((struct usb_ehci_list_s *)qh)->flink;
memset(qh, 0, sizeof(struct usb_ehci_qh_s));
}
@@ -365,8 +363,8 @@ static void usb_ehci_qh_free(struct usb_ehci_qh_s *qh)
/* Put the QH structure back into the free list */
- entry->flink = g_ehci.qhfree;
- g_ehci.qhfree = entry;
+ entry->flink = g_ehci_hcd.qhfree;
+ g_ehci_hcd.qhfree = entry;
}
/****************************************************************************
@@ -386,9 +384,9 @@ static struct usb_ehci_qtd_s *usb_ehci_qtd_alloc(void)
/* Remove the qTD from the freelist */
- qtd = (struct usb_ehci_qtd_s *)g_ehci.qtdfree;
+ qtd = (struct usb_ehci_qtd_s *)g_ehci_hcd.qtdfree;
if (qtd) {
- g_ehci.qtdfree = ((struct usb_ehci_list_s *)qtd)->flink;
+ g_ehci_hcd.qtdfree = ((struct usb_ehci_list_s *)qtd)->flink;
memset(qtd, 0, sizeof(struct usb_ehci_qtd_s));
}
@@ -412,8 +410,8 @@ static void usb_ehci_qtd_free(struct usb_ehci_qtd_s *qtd)
/* Put the qTD back into the free list */
- entry->flink = g_ehci.qtdfree;
- g_ehci.qtdfree = entry;
+ entry->flink = g_ehci_hcd.qtdfree;
+ g_ehci_hcd.qtdfree = entry;
}
/****************************************************************************
@@ -1014,7 +1012,7 @@ static void usb_ehci_qh_enqueue(struct usb_ehci_qh_s *qhead, struct usb_ehci_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)
+static int usb_ehci_control_init(struct usb_ehci_epinfo_s *epinfo, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
{
struct usb_ehci_qh_s *qh;
struct usb_ehci_qtd_s *qtd;
@@ -1024,7 +1022,6 @@ static int usb_ehci_control_setup(struct usb_ehci_epinfo_s *epinfo, struct usb_s
uint32_t *alt;
uint32_t toggle;
bool dirin = false;
- int ret;
/* Create and initialize a Queue Head (QH) structure for this transfer */
qh = usb_ehci_qh_create(epinfo);
@@ -1032,13 +1029,13 @@ static int usb_ehci_control_setup(struct usb_ehci_epinfo_s *epinfo, struct usb_s
return -ENOMEM;
}
+ epinfo->qh = qh;
/* Initialize the QH link and get the next data toggle (not used for SETUP
* transfers)
*/
flink = &qh->hw.overlay.nqp;
toggle = (uint32_t)epinfo->toggle << QTD_TOKEN_TOGGLE_SHIFT;
- ret = -EIO;
/* Is there an EP0 SETUP request? If so, we will queue two or three qTDs:
*
@@ -1053,8 +1050,7 @@ 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) {
- ret = -ENOMEM;
- goto errout_with_qh;
+ return -ENOMEM;
}
/* Link the new qTD to the QH head. */
@@ -1099,8 +1095,7 @@ 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) {
- ret = -ENOMEM;
- goto errout_with_qh;
+ return -ENOMEM;
}
/* Link the new qTD to either QH head of the SETUP qTD. */
@@ -1143,8 +1138,7 @@ static int usb_ehci_control_setup(struct usb_ehci_epinfo_s *epinfo, struct usb_s
*/
qtd = usb_ehci_qtd_statusphase(tokenbits);
if (qtd == NULL) {
- ret = -ENOMEM;
- goto errout_with_qh;
+ return -ENOMEM;
}
/* Link the new qTD to either the SETUP or data qTD. */
@@ -1162,22 +1156,15 @@ static int usb_ehci_control_setup(struct usb_ehci_epinfo_s *epinfo, struct usb_s
}
/* Add the new QH to the head of the asynchronous queue list */
usb_ehci_qh_enqueue(&g_asynchead, qh);
- epinfo->qh = qh;
return 0;
-
-errout_with_qh:
- /* Clean-up after an error */
- usb_ehci_qh_discard(qh);
- return ret;
}
-static int usb_ehci_bulk_setup(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer, uint32_t buflen)
+static int usb_ehci_bulk_init(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer, uint32_t buflen)
{
struct usb_ehci_qh_s *qh;
struct usb_ehci_qtd_s *qtd;
uint32_t tokenbits;
uintptr_t physaddr;
- int ret;
/* Create and initialize a Queue Head (QH) structure for this transfer */
qh = usb_ehci_qh_create(epinfo);
@@ -1185,9 +1172,10 @@ static int usb_ehci_bulk_setup(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer
return -ENOMEM;
}
+ epinfo->qh = qh;
+
/* Initialize the QH link and get the next data toggle */
tokenbits = (uint32_t)epinfo->toggle << QTD_TOKEN_TOGGLE_SHIFT;
- ret = -EIO;
if (buffer != NULL && buflen > 0) {
/* Get the direction from the epinfo structure. Since this is not an EP0 SETUP request,
@@ -1205,8 +1193,7 @@ 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) {
- ret = -ENOMEM;
- goto errout_with_qh;
+ return -ENOMEM;
}
/* Link the new qTD to the QH. */
@@ -1216,22 +1203,16 @@ static int usb_ehci_bulk_setup(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer
/* Add the new QH to the head of the asynchronous queue list */
usb_ehci_qh_enqueue(&g_asynchead, qh);
- epinfo->qh = qh;
return 0;
-
-errout_with_qh:
- usb_ehci_qh_discard(qh);
- return ret;
}
-static int usb_ehci_intr_setup(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer, uint32_t buflen)
+static int usb_ehci_intr_init(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer, uint32_t buflen)
{
struct usb_ehci_qh_s *qh;
struct usb_ehci_qtd_s *qtd;
uint32_t tokenbits;
uintptr_t physaddr;
uint32_t regval;
- int ret;
/* Create and initialize a Queue Head (QH) structure for this transfer */
qh = usb_ehci_qh_create(epinfo);
@@ -1239,6 +1220,8 @@ static int usb_ehci_intr_setup(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer
return -ENOMEM;
}
+ epinfo->qh = qh;
+
/* Initialize the QH link and get the next data toggle */
tokenbits = (uint32_t)epinfo->toggle << QTD_TOKEN_TOGGLE_SHIFT;
@@ -1257,8 +1240,7 @@ 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) {
- ret = -ENOMEM;
- goto errout_with_qh;
+ return -ENOMEM;
}
/* Link the new qTD to the QH. */
@@ -1276,12 +1258,7 @@ static int usb_ehci_intr_setup(struct usb_ehci_epinfo_s *epinfo, uint8_t *buffer
/* Re-enable the periodic schedule */
regval |= EHCI_USBCMD_PSEN;
usb_ehci_putreg(regval, &HCOR->usbcmd);
- epinfo->qh = qh;
return 0;
-
-errout_with_qh:
- usb_ehci_qh_discard(qh);
- return ret;
}
/****************************************************************************
@@ -1299,7 +1276,7 @@ errout_with_qh:
static int usb_ehci_ioc_setup(struct usb_ehci_epinfo_s *epinfo)
{
- size_t flags;
+ uint32_t flags;
int ret = -ENODEV;
DEBUGASSERT(rhport && epinfo && !epinfo->iocwait);
@@ -1353,7 +1330,7 @@ static int usb_ehci_ioc_setup(struct usb_ehci_epinfo_s *epinfo)
#ifdef CONFIG_USBHOST_ASYNCH
static int usb_ehci_ioc_async_setup(struct usb_ehci_epinfo_s *epinfo, usbh_asynch_callback_t callback, void *arg)
{
- size_t flags;
+ uint32_t flags;
int ret = -ENODEV;
DEBUGASSERT(rhport && epinfo && !epinfo->iocwait);
@@ -1468,7 +1445,6 @@ static int usb_ehci_transfer_wait(struct usb_ehci_epinfo_s *epinfo, uint32_t tim
if (epinfo->iocwait) {
ret = usb_osal_sem_take(epinfo->iocsem, timeout);
if (ret < 0) {
- usb_ehci_qh_discard(epinfo->qh);
return ret;
}
}
@@ -1845,7 +1821,7 @@ static inline void usb_ehci_portsc_bottomhalf(void)
usbh_event_notify_handler(USBH_EVENT_CONNECTED, 1);
} else {
for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
- struct usb_ehci_epinfo_s *epinfo = &g_ehci.chan[chidx];
+ struct usb_ehci_epinfo_s *epinfo = &g_ehci_hcd.chan[chidx];
if (epinfo->iocwait) {
epinfo->iocwait = false;
usb_osal_sem_give(epinfo->iocsem);
@@ -2025,31 +2001,42 @@ __WEAK void usb_hc_low_level_init(void)
{
}
-int usb_hc_init(void)
+int usb_hc_sw_init(void)
{
- int ret;
- uint32_t regval;
- uintptr_t physaddr1;
- uintptr_t physaddr2;
-
- g_ehci.qhfree = NULL;
- g_ehci.qtdfree = NULL;
+ memset(&g_ehci_hcd, 0, sizeof(struct ehci_hcd));
/* Initialize the list of free Queue Head (QH) structures */
-
for (uint8_t i = 0; i < CONFIG_USB_EHCI_QH_NUM; i++) {
/* Put the QH structure in a free list */
- usb_ehci_qh_free(&g_qhpool[i]);
+ usb_ehci_qh_free(&g_ehci_hcd.qhpool[i]);
}
- /* Initialize the list of free Queue Head (QH) structures */
+ /* Initialize the list of free Queue Head (QH) structures */
for (uint8_t i = 0; i < CONFIG_USB_EHCI_QTD_NUM; i++) {
/* Put the QH structure in a free list */
- usb_ehci_qtd_free(&g_qtdpool[i]);
+ usb_ehci_qtd_free(&g_ehci_hcd.qtdpool[i]);
}
+ for (uint8_t chidx = 0; chidx < CONFIG_USB_EHCI_QH_NUM; chidx++) {
+ struct usb_ehci_epinfo_s *epinfo;
+
+ epinfo = &g_ehci_hcd.chan[chidx];
+ epinfo->iocsem = usb_osal_sem_create(0);
+ epinfo->exclsem = usb_osal_mutex_create();
+ }
+
+ return 0;
+}
+
+int usb_hc_hw_init(void)
+{
+ int ret;
+ uint32_t regval;
+ uintptr_t physaddr1;
+ uintptr_t physaddr2;
+
/* Initialize the head of the asynchronous queue/reclamation list.
*
* "In order to communicate with devices via the asynchronous schedule,
@@ -2270,6 +2257,8 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
{
struct usb_ehci_epinfo_s *epinfo;
struct usbh_hubport *hport;
+ usb_osal_sem_t iocsem;
+ usb_osal_mutex_t exclsem;
int chidx;
DEBUGASSERT(ep_cfg != NULL && ep_cfg->hport != NULL);
@@ -2278,10 +2267,13 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
chidx = usb_ehci_chan_alloc();
- epinfo = &g_ehci.chan[chidx];
+ epinfo = &g_ehci_hcd.chan[chidx];
+
+ iocsem = epinfo->iocsem;
+ exclsem = epinfo->exclsem;
+
memset(epinfo, 0, sizeof(struct usb_ehci_epinfo_s));
- epinfo->inuse = true;
epinfo->epno = ep_cfg->ep_addr & 0x7f;
epinfo->dirin = (ep_cfg->ep_addr & 0x80) ? 1 : 0;
epinfo->devaddr = hport->dev_addr;
@@ -2293,8 +2285,10 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
epinfo->speed = hport->speed;
epinfo->hport = hport;
- epinfo->iocsem = usb_osal_sem_create(0);
- epinfo->exclsem = usb_osal_mutex_create();
+ /* restore variable */
+ epinfo->inuse = true;
+ epinfo->iocsem = iocsem;
+ epinfo->exclsem = exclsem;
*ep = (usbh_epinfo_t)epinfo;
@@ -2305,8 +2299,6 @@ int usbh_ep_free(usbh_epinfo_t ep)
{
struct usb_ehci_epinfo_s *epinfo = (struct usb_ehci_epinfo_s *)ep;
- usb_osal_sem_delete(epinfo->iocsem);
- usb_osal_mutex_delete(epinfo->exclsem);
usb_ehci_chan_free(epinfo);
return 0;
@@ -2334,10 +2326,10 @@ 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) {
- goto errout_with_sem;
+ goto errout_with_setup;
}
- ret = usb_ehci_control_setup(epinfo, setup, buffer, setup->wLength);
+ ret = usb_ehci_control_init(epinfo, setup, buffer, setup->wLength);
if (ret < 0) {
goto errout_with_iocwait;
}
@@ -2353,7 +2345,12 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
errout_with_iocwait:
epinfo->iocwait = false;
-errout_with_sem:
+ /* Clean-up after an error */
+ if (epinfo->qh) {
+ usb_ehci_qh_discard(epinfo->qh);
+ epinfo->qh = NULL;
+ }
+errout_with_setup:
usb_osal_mutex_give(epinfo->exclsem);
return ret;
}
@@ -2373,10 +2370,10 @@ int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui
ret = usb_ehci_ioc_setup(epinfo);
if (ret < 0) {
- goto errout_with_sem;
+ goto errout_with_setup;
}
- ret = usb_ehci_bulk_setup(epinfo, buffer, buflen);
+ ret = usb_ehci_bulk_init(epinfo, buffer, buflen);
if (ret < 0) {
goto errout_with_iocwait;
}
@@ -2391,7 +2388,12 @@ int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui
errout_with_iocwait:
epinfo->iocwait = false;
-errout_with_sem:
+ /* Clean-up after an error */
+ if (epinfo->qh) {
+ usb_ehci_qh_discard(epinfo->qh);
+ epinfo->qh = NULL;
+ }
+errout_with_setup:
usb_osal_mutex_give(epinfo->exclsem);
return ret;
}
@@ -2411,10 +2413,10 @@ int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui
ret = usb_ehci_ioc_setup(epinfo);
if (ret < 0) {
- goto errout_with_sem;
+ goto errout_with_setup;
}
- ret = usb_ehci_intr_setup(epinfo, buffer, buflen);
+ ret = usb_ehci_intr_init(epinfo, buffer, buflen);
if (ret < 0) {
goto errout_with_iocwait;
}
@@ -2429,7 +2431,12 @@ int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui
errout_with_iocwait:
epinfo->iocwait = false;
-errout_with_sem:
+ /* Clean-up after an error */
+ if (epinfo->qh) {
+ usb_ehci_qh_discard(epinfo->qh);
+ epinfo->qh = NULL;
+ }
+errout_with_setup:
usb_osal_mutex_give(epinfo->exclsem);
return ret;
}
@@ -2450,23 +2457,28 @@ int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
/* Set the request for the callback well BEFORE initiating the transfer. */
ret = usb_ehci_ioc_async_setup(epinfo, callback, arg);
if (ret != 0) {
- goto errout_with_sem;
+ goto errout_with_setup;
}
/* Check for errors in the setup of the transfer */
- ret = usb_ehci_bulk_setup(epinfo, buffer, buflen);
+ ret = usb_ehci_bulk_init(epinfo, buffer, buflen);
if (ret < 0) {
- goto errout_with_callback;
+ goto errout_with_qh;
}
/* The transfer is in progress */
usb_osal_mutex_give(epinfo->exclsem);
return 0;
-errout_with_callback:
+errout_with_qh:
+ /* Clean-up after an error */
+ if (epinfo->qh) {
+ usb_ehci_qh_discard(epinfo->qh);
+ epinfo->qh = NULL;
+ }
+errout_with_setup:
epinfo->callback = NULL;
epinfo->arg = NULL;
-errout_with_sem:
usb_osal_mutex_give(epinfo->exclsem);
return ret;
}
@@ -2487,23 +2499,28 @@ int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
/* Set the request for the callback well BEFORE initiating the transfer. */
ret = usb_ehci_ioc_async_setup(epinfo, callback, arg);
if (ret != 0) {
- goto errout_with_sem;
+ goto errout_with_setup;
}
/* Check for errors in the setup of the transfer */
- ret = usb_ehci_intr_setup(epinfo, buffer, buflen);
+ ret = usb_ehci_intr_init(epinfo, buffer, buflen);
if (ret < 0) {
- goto errout_with_callback;
+ goto errout_with_qh;
}
/* The transfer is in progress */
usb_osal_mutex_give(epinfo->exclsem);
return 0;
-errout_with_callback:
+errout_with_qh:
+ /* Clean-up after an error */
+ if (epinfo->qh) {
+ usb_ehci_qh_discard(epinfo->qh);
+ epinfo->qh = NULL;
+ }
+errout_with_setup:
epinfo->callback = NULL;
epinfo->arg = NULL;
-errout_with_sem:
usb_osal_mutex_give(epinfo->exclsem);
return ret;
}
@@ -2536,7 +2553,7 @@ int usb_ep_cancel(usbh_epinfo_t ep)
void *arg;
#endif
uint32_t *bp;
- size_t flags;
+ uint32_t flags;
bool iocwait;
int ret;
@@ -2783,7 +2800,7 @@ static void usb_ehci_bottomhalf(void *arg)
}
}
-void usb_ehci_interrupt(void)
+void USBH_IRQHandler(void)
{
uint32_t usbsts;
uint32_t pending;