diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c index f195c0ed757..6709e16cba2 100644 --- a/arch/arm/src/lpc17xx/lpc17_usbhost.c +++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c @@ -190,6 +190,7 @@ struct lpc17_xfrinfo_s volatile bool wdhwait; /* Thread is waiting for WDH interrupt */ volatile uint8_t tdstatus; /* TD control status bits from last Writeback Done Head event */ uint8_t *buffer; /* Transfer buffer start */ + uint16_t buflen; /* Buffer length */ uint16_t xfrd; /* Number of bytes transferred */ #ifdef CONFIG_USBHOST_ASYNCH @@ -198,7 +199,6 @@ struct lpc17_xfrinfo_s * the transfer completes. */ - uint16_t buflen; /* Buffer length */ uint8_t *alloc; /* Allocated buffer */ #endif @@ -1516,9 +1516,7 @@ static int lpc17_ctrltd(struct lpc17_usbhost_s *priv, struct lpc17_ed_s *ed, memset(xfrinfo, 0, sizeof(struct lpc17_xfrinfo_s)); xfrinfo->buffer = buffer; -#if defined(CONFIG_USBHOST_ASYNCH) && LPC17_IOBUFFERS > 0 xfrinfo->buflen = buflen; -#endif ed->xfrinfo = xfrinfo; @@ -1780,12 +1778,18 @@ static int lpc17_usbinterrupt(int irq, void *context) #endif /* Determine the number of bytes actually transfer by - * subtracting the buffer start address from the CBP. But be - * careful, the CBP may be zero. + * subtracting the buffer start address from the CBP. A value + * of zero means that all bytes were transferred. */ tmp = (uintptr_t)td->hw.cbp; - if (tmp != 0) + if (tmp == 0) + { + /* Set the (fake) CBP to the end of the buffer + 1 */ + + tmp = xfrinfo->buflen; + } + else { DEBUGASSERT(tmp >= (uintptr_t)xfrinfo->buffer); @@ -2892,9 +2896,7 @@ static ssize_t lpc17_transfer(struct usbhost_driver_s *drvr, usbhost_ep_t ep, memset(xfrinfo, 0, sizeof(struct lpc17_xfrinfo_s)); xfrinfo->buffer = buffer; -#if defined(CONFIG_USBHOST_ASYNCH) && LPC17_IOBUFFERS > 0 xfrinfo->buflen = buflen; -#endif ed->xfrinfo = xfrinfo; @@ -3017,11 +3019,7 @@ static void lpc17_asynch_completion(struct lpc17_usbhost_s *priv, xfrinfo = ed->xfrinfo; DEBUGASSERT(xfrinfo->wdhwait == false && xfrinfo->callback != NULL && - xfrinfo->buffer != NULL); - -#if LPC17_IOBUFFERS > 0 - DEBUGASSERT(xfrinfo->buflen > 0); -#endif + xfrinfo->buffer != NULL && xfrinfo->buflen > 0); /* Check the TD completion status bits */ @@ -3132,9 +3130,7 @@ static int lpc17_asynch(struct usbhost_driver_s *drvr, usbhost_ep_t ep, memset(xfrinfo, 0, sizeof(struct lpc17_xfrinfo_s)); xfrinfo->buffer = buffer; -#if LPC17_IOBUFFERS > 0 xfrinfo->buflen = buflen; -#endif xfrinfo->callback = callback; xfrinfo->arg = arg; diff --git a/arch/arm/src/sama5/sam_ohci.c b/arch/arm/src/sama5/sam_ohci.c index a7d9a39ceef..2c4d5beb170 100644 --- a/arch/arm/src/sama5/sam_ohci.c +++ b/arch/arm/src/sama5/sam_ohci.c @@ -224,9 +224,9 @@ struct sam_eplist_s #ifdef CONFIG_USBHOST_ASYNCH usbhost_asynch_t callback; /* Transfer complete callback */ void *arg; /* Argument that accompanies the callback */ - uint16_t buflen; /* Length of the buffer */ #endif uint8_t *buffer; /* Buffer being transferred */ + uint16_t buflen; /* Length of the buffer */ uint16_t xfrd; /* Number of bytes completed in the last transfer */ struct sam_ed_s *ed; /* Endpoint descriptor (ED) */ struct sam_gtd_s *tail; /* Tail transfer descriptor (TD) */ @@ -400,7 +400,8 @@ static int sam_enqueuetd(struct sam_rhport_s *rhport, struct sam_eplist_s *eplis volatile uint8_t *buffer, size_t buflen); static int sam_ep0enqueue(struct sam_rhport_s *rhport); static void sam_ep0dequeue(struct sam_eplist_s *ep0); -static int sam_wdhwait(struct sam_rhport_s *rhport, struct sam_ed_s *ed); +static int sam_wdhwait(struct sam_rhport_s *rhport, struct sam_ed_s *ed, + uint8_t *buffer, uint16_t buflen); #ifdef CONFIG_USBHOST_ASYNCH static int sam_wdhasynch(struct sam_rhport_s *rhport, struct sam_ed_s *ed, usbhost_asynch_t callback, void *arg, @@ -1735,7 +1736,8 @@ static void sam_ep0dequeue(struct sam_eplist_s *ep0) * *******************************************************************************/ -static int sam_wdhwait(struct sam_rhport_s *rhport, struct sam_ed_s *ed) +static int sam_wdhwait(struct sam_rhport_s *rhport, struct sam_ed_s *ed, + uint8_t *buffer, uint16_t buflen) { struct sam_eplist_s *eplist; irqstate_t flags = irqsave(); @@ -1759,9 +1761,9 @@ static int sam_wdhwait(struct sam_rhport_s *rhport, struct sam_ed_s *ed) #ifdef CONFIG_USBHOST_ASYNCH eplist->callback = NULL; eplist->arg = NULL; - eplist->buffer = NULL; - eplist->buflen = 0; #endif + eplist->buffer = buffer; + eplist->buflen = buflen; ret = OK; } @@ -1843,7 +1845,7 @@ static int sam_ctrltd(struct sam_rhport_s *rhport, struct sam_eplist_s *eplist, */ edctrl = eplist->ed; - ret = sam_wdhwait(rhport, edctrl); + ret = sam_wdhwait(rhport, edctrl, buffer, buflen); if (ret != OK) { usbhost_trace1(OHCI_TRACE1_DEVDISCONN, RHPORT(rhport)); @@ -2156,12 +2158,18 @@ static void sam_wdh_bottomhalf(void) #endif /* Determine the number of bytes actually transfer by* subtracting the - * buffer start address from the CBP. But be careful, the CBP may be - * zero. + * buffer start address from the CBP. A value of zero means that all + * bytes were transferred. */ tmp = (uintptr_t)td->hw.cbp; - if (tmp != 0) + if (tmp == 0) + { + /* Set the (fake) CBP to the end of the buffer + 1 */ + + tmp = xfrinfo->buflen; + } + else { paddr = sam_physramaddr((uintptr_t)eplist->buffer); DEBUGASSERT(tmp >= paddr); @@ -3309,7 +3317,7 @@ static ssize_t sam_transfer(struct usbhost_driver_s *drvr, usbhost_ep_t ep, * transfer. */ - ret = sam_wdhwait(rhport, ed); + ret = sam_wdhwait(rhport, ed, buffer, buflen); if (ret != OK) { usbhost_trace1(OHCI_TRACE1_DEVDISCONN, RHPORT(rhport));