mirror of
https://github.com/apache/nuttx.git
synced 2026-06-01 16:59:28 +08:00
SAMA5 UDPHS: Fix bad setup for sam_req_write call introduce in last commit
This commit is contained in:
@@ -145,31 +145,32 @@
|
|||||||
#define SAM_TRACEERR_BADCLEARFEATURE 0x0002
|
#define SAM_TRACEERR_BADCLEARFEATURE 0x0002
|
||||||
#define SAM_TRACEERR_BADDEVGETSTATUS 0x0003
|
#define SAM_TRACEERR_BADDEVGETSTATUS 0x0003
|
||||||
#define SAM_TRACEERR_BADEPGETSTATUS 0x0004
|
#define SAM_TRACEERR_BADEPGETSTATUS 0x0004
|
||||||
#define SAM_TRACEERR_BADEPNO 0x0005
|
#define SAM_TRACEERR_BADEOBSTATE 0x0005
|
||||||
#define SAM_TRACEERR_BADEPTYPE 0x0006
|
#define SAM_TRACEERR_BADEPNO 0x0006
|
||||||
#define SAM_TRACEERR_BADGETCONFIG 0x0007
|
#define SAM_TRACEERR_BADEPTYPE 0x0007
|
||||||
#define SAM_TRACEERR_BADGETSETDESC 0x0008
|
#define SAM_TRACEERR_BADGETCONFIG 0x0008
|
||||||
#define SAM_TRACEERR_BADGETSTATUS 0x0009
|
#define SAM_TRACEERR_BADGETSETDESC 0x0009
|
||||||
#define SAM_TRACEERR_BADSETADDRESS 0x000a
|
#define SAM_TRACEERR_BADGETSTATUS 0x000a
|
||||||
#define SAM_TRACEERR_BADSETCONFIG 0x000b
|
#define SAM_TRACEERR_BADSETADDRESS 0x000b
|
||||||
#define SAM_TRACEERR_BADSETFEATURE 0x000c
|
#define SAM_TRACEERR_BADSETCONFIG 0x000c
|
||||||
#define SAM_TRACEERR_BINDFAILED 0x000d
|
#define SAM_TRACEERR_BADSETFEATURE 0x000d
|
||||||
#define SAM_TRACEERR_DISPATCHSTALL 0x000e
|
#define SAM_TRACEERR_BINDFAILED 0x000e
|
||||||
#define SAM_TRACEERR_DMAERR 0x000f
|
#define SAM_TRACEERR_DISPATCHSTALL 0x000f
|
||||||
#define SAM_TRACEERR_DRIVER 0x0010
|
#define SAM_TRACEERR_DMAERR 0x0010
|
||||||
#define SAM_TRACEERR_DRIVERREGISTERED 0x0011
|
#define SAM_TRACEERR_DRIVER 0x0011
|
||||||
#define SAM_TRACEERR_ENDBUFST 0x0012
|
#define SAM_TRACEERR_DRIVERREGISTERED 0x0012
|
||||||
#define SAM_TRACEERR_EP0SETUPOUTSIZE 0x0013
|
#define SAM_TRACEERR_ENDBUFST 0x0013
|
||||||
#define SAM_TRACEERR_EP0SETUPSTALLED 0x0014
|
#define SAM_TRACEERR_EP0SETUPOUTSIZE 0x0014
|
||||||
#define SAM_TRACEERR_EPOUTNULLPACKET 0x0015
|
#define SAM_TRACEERR_EP0SETUPSTALLED 0x0015
|
||||||
#define SAM_TRACEERR_EPRESERVE 0x0016
|
#define SAM_TRACEERR_EPOUTNULLPACKET 0x0016
|
||||||
#define SAM_TRACEERR_EPTCFGMAPD 0x0017
|
#define SAM_TRACEERR_EPRESERVE 0x0017
|
||||||
#define SAM_TRACEERR_INVALIDCTRLREQ 0x0018
|
#define SAM_TRACEERR_EPTCFGMAPD 0x0018
|
||||||
#define SAM_TRACEERR_INVALIDPARMS 0x0019
|
#define SAM_TRACEERR_INVALIDCTRLREQ 0x0019
|
||||||
#define SAM_TRACEERR_IRQREGISTRATION 0x001a
|
#define SAM_TRACEERR_INVALIDPARMS 0x001a
|
||||||
#define SAM_TRACEERR_NOTCONFIGURED 0x001b
|
#define SAM_TRACEERR_IRQREGISTRATION 0x001b
|
||||||
#define SAM_TRACEERR_REQABORTED 0x001c
|
#define SAM_TRACEERR_NOTCONFIGURED 0x001c
|
||||||
#define SAM_TRACEERR_TXRDYERR 0x001d
|
#define SAM_TRACEERR_REQABORTED 0x001d
|
||||||
|
#define SAM_TRACEERR_TXRDYERR 0x001e
|
||||||
|
|
||||||
/* Trace interrupt codes */
|
/* Trace interrupt codes */
|
||||||
|
|
||||||
@@ -573,6 +574,7 @@ const struct trace_msg_t g_usb_trace_strings_deverror[] =
|
|||||||
TRACE_STR(SAM_TRACEERR_BADCLEARFEATURE),
|
TRACE_STR(SAM_TRACEERR_BADCLEARFEATURE),
|
||||||
TRACE_STR(SAM_TRACEERR_BADDEVGETSTATUS),
|
TRACE_STR(SAM_TRACEERR_BADDEVGETSTATUS),
|
||||||
TRACE_STR(SAM_TRACEERR_BADEPGETSTATUS),
|
TRACE_STR(SAM_TRACEERR_BADEPGETSTATUS),
|
||||||
|
TRACE_STR(SAM_TRACEERR_BADEOBSTATE),
|
||||||
TRACE_STR(SAM_TRACEERR_BADEPNO),
|
TRACE_STR(SAM_TRACEERR_BADEPNO),
|
||||||
TRACE_STR(SAM_TRACEERR_BADEPTYPE),
|
TRACE_STR(SAM_TRACEERR_BADEPTYPE),
|
||||||
TRACE_STR(SAM_TRACEERR_BADGETCONFIG),
|
TRACE_STR(SAM_TRACEERR_BADGETCONFIG),
|
||||||
@@ -1281,9 +1283,10 @@ static void sam_req_wrsetup(struct sam_usbdev_s *priv,
|
|||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Process the next queued write request. This function is called in one
|
* Process the next queued write request. This function is called in one
|
||||||
* of three contexts: (1) When a new write request is submitted (with
|
* of three contexts: (1) When the endpoint is IDLE and a new write request
|
||||||
* interrupts disabled, (2) from interrupt handling when a previous
|
* is submitted (with interrupts disabled), (2) from interrupt handling
|
||||||
* transfer completes, or (3) resuming a stalled IN endpoint.
|
* when the current transfer completes (either DMA or FIFO), or (3) when
|
||||||
|
* resuming a stalled IN or control endpoint.
|
||||||
*
|
*
|
||||||
* Calling rules:
|
* Calling rules:
|
||||||
*
|
*
|
||||||
@@ -1543,8 +1546,13 @@ static void sam_req_rddisable(uint8_t epno)
|
|||||||
* Name: sam_req_read
|
* Name: sam_req_read
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Called only from interrupt handling logic when on OUT packet is received
|
* Complete the last read request, return the read request to the class
|
||||||
* on an endpoint in the RECEIVING state.
|
* implementation, and try to started the next queued read request.
|
||||||
|
*
|
||||||
|
* This function is called in one of three contexts: (1) When the endpoint
|
||||||
|
* is IDLE and a new read request is submitted (with interrupts disabled),
|
||||||
|
* (2) from interrupt handling when the current transfer completes (either
|
||||||
|
* DMA or FIFO), or (3) when resuming a stalled OUT or control endpoint.
|
||||||
*
|
*
|
||||||
* There is a fundamental difference between receiving packets via DMA and
|
* There is a fundamental difference between receiving packets via DMA and
|
||||||
* via the FIFO:
|
* via the FIFO:
|
||||||
@@ -1552,10 +1560,11 @@ static void sam_req_rddisable(uint8_t epno)
|
|||||||
* - When receiving data via DMA, then data has already been transferred
|
* - When receiving data via DMA, then data has already been transferred
|
||||||
* and this function is called on the terminating event. The transfer
|
* and this function is called on the terminating event. The transfer
|
||||||
* is complete and we just need to check for end of request events and
|
* is complete and we just need to check for end of request events and
|
||||||
* if we need to setup the next tranfer.
|
* if we need to setup the tranfer for the next request.
|
||||||
* - When receiving via the FIFO, then transfer is not complete. The
|
* - When receiving via the FIFO, the transfer is not complete. The
|
||||||
* data is in the FIFO and must be transferred from the FIFO to the
|
* data is in the FIFO and must be transferred from the FIFO to the
|
||||||
* request buffer. No setup is needed for the next transfer.
|
* request buffer. No setup is needed for the next transfer other than
|
||||||
|
* assuring that the endpoint RXRDY_TXTK interrupt is enabled.
|
||||||
*
|
*
|
||||||
* Calling rules:
|
* Calling rules:
|
||||||
*
|
*
|
||||||
@@ -2372,15 +2381,11 @@ static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno)
|
|||||||
usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DMAEOB), (uint16_t)dmastatus);
|
usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_DMAEOB), (uint16_t)dmastatus);
|
||||||
|
|
||||||
/* BUFF_COUNT holds the number of untransmitted bytes. BUFF_COUNT is
|
/* BUFF_COUNT holds the number of untransmitted bytes. BUFF_COUNT is
|
||||||
* equal to zero in case of good transfer.
|
* equal to zero in case of good transfer. BUFF_COUNT was set to
|
||||||
*
|
* the 'inflight' count when the DMA started and the BUFF_COUNT has
|
||||||
* BUFF_COUNT was set to the 'inflight' count when the DMA started and
|
* now decremented to zero
|
||||||
* the BUFF_COUNT has now decremented to zero
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
xfrsize = privreq->inflight;
|
|
||||||
privreq->inflight = 0;
|
|
||||||
|
|
||||||
/* This is just debug logic that only does any if USB debug or tracing
|
/* This is just debug logic that only does any if USB debug or tracing
|
||||||
* are enabled. This just verifies taht BUFF_COUNT is zero.
|
* are enabled. This just verifies taht BUFF_COUNT is zero.
|
||||||
*/
|
*/
|
||||||
@@ -2398,15 +2403,21 @@ static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno)
|
|||||||
if (privep->epstate == UDPHS_EPSTATE_SENDING)
|
if (privep->epstate == UDPHS_EPSTATE_SENDING)
|
||||||
{
|
{
|
||||||
/* This is an IN endpoint. Continuing processing the write
|
/* This is an IN endpoint. Continuing processing the write
|
||||||
* request
|
* request. We must call sam_req_write in the IDLE state
|
||||||
|
* with the number of bytes transferred in 'inflight'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEBUGASSERT(USB_ISEPIN(privep->ep.eplog));
|
DEBUGASSERT(USB_ISEPIN(privep->ep.eplog));
|
||||||
privep->epstate = UDPHS_EPSTATE_IDLE;
|
privep->epstate = UDPHS_EPSTATE_IDLE;
|
||||||
(void)sam_req_write(priv, privep);
|
(void)sam_req_write(priv, privep);
|
||||||
}
|
}
|
||||||
else
|
else if (privep->epstate == UDPHS_EPSTATE_RECEIVING)
|
||||||
{
|
{
|
||||||
|
/* privreg->inflight holds the total transfer size */
|
||||||
|
|
||||||
|
xfrsize = privreq->inflight;
|
||||||
|
privreq->inflight = 0;
|
||||||
|
|
||||||
/* This is an OUT endpoint. Invalidate the data cache for
|
/* This is an OUT endpoint. Invalidate the data cache for
|
||||||
* region that just completed DMA. This will force the
|
* region that just completed DMA. This will force the
|
||||||
* buffer data to be reloaded from RAM. when it is accessed
|
* buffer data to be reloaded from RAM. when it is accessed
|
||||||
@@ -2416,11 +2427,20 @@ static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno)
|
|||||||
buf = &privreq->req.buf[privreq->req.xfrd];
|
buf = &privreq->req.buf[privreq->req.xfrd];
|
||||||
cp15_invalidate_dcache((uintptr_t)buf, (uintptr_t)buf + xfrsize);
|
cp15_invalidate_dcache((uintptr_t)buf, (uintptr_t)buf + xfrsize);
|
||||||
|
|
||||||
/* Continuing processing the read request */
|
/* Complete this transfer, return the request to the class
|
||||||
|
* implementation, and try to start the next, queue read request.
|
||||||
|
* We must call sam_req_read in the IDLE state, 'inflight' is
|
||||||
|
* ignored (should be zero) and the transfer size is passed as
|
||||||
|
* an argument to sam_req_read().
|
||||||
|
*/
|
||||||
|
|
||||||
privep->epstate = UDPHS_EPSTATE_IDLE;
|
privep->epstate = UDPHS_EPSTATE_IDLE;
|
||||||
(void)sam_req_read(priv, privep, xfrsize);
|
(void)sam_req_read(priv, privep, xfrsize);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_BADEOBSTATE), bufcnt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for end of channel transfer. END_TR_ST is set by hardware when
|
/* Check for end of channel transfer. END_TR_ST is set by hardware when
|
||||||
@@ -2454,6 +2474,7 @@ static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno)
|
|||||||
bufcnt = ((dmastatus & UDPHS_DMASTATUS_BUFCNT_MASK)
|
bufcnt = ((dmastatus & UDPHS_DMASTATUS_BUFCNT_MASK)
|
||||||
>> UDPHS_DMASTATUS_BUFCNT_SHIFT);
|
>> UDPHS_DMASTATUS_BUFCNT_SHIFT);
|
||||||
xfrsize = privreq->inflight - bufcnt;
|
xfrsize = privreq->inflight - bufcnt;
|
||||||
|
privreq->inflight = 0;
|
||||||
|
|
||||||
/* Invalidate the data cache for region that just completed DMA.
|
/* Invalidate the data cache for region that just completed DMA.
|
||||||
* This will force the buffer data to be reloaded from RAM.
|
* This will force the buffer data to be reloaded from RAM.
|
||||||
@@ -2462,18 +2483,12 @@ static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno)
|
|||||||
buf = &privreq->req.buf[privreq->req.xfrd];
|
buf = &privreq->req.buf[privreq->req.xfrd];
|
||||||
cp15_invalidate_dcache((uintptr_t)buf, (uintptr_t)buf + xfrsize);
|
cp15_invalidate_dcache((uintptr_t)buf, (uintptr_t)buf + xfrsize);
|
||||||
|
|
||||||
/* Complete this transfer now and return the request to the class
|
/* Complete this transfer, return the request to the class
|
||||||
* implementation.
|
* implementation, and try to start the next, queue read request.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
privep->epstate = UDPHS_EPSTATE_IDLE;
|
privep->epstate = UDPHS_EPSTATE_IDLE;
|
||||||
privreq->req.xfrd += xfrsize;
|
(void)sam_req_read(priv, privep, xfrsize);
|
||||||
privreq->inflight = 0;
|
|
||||||
sam_req_complete(privep, OK);
|
|
||||||
|
|
||||||
/* Now, try to start the next, queue read request */
|
|
||||||
|
|
||||||
(void)sam_req_read(priv, privep, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -3704,13 +3719,22 @@ static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume)
|
|||||||
|
|
||||||
/* Resuming any blocked data transfers on the endpoint */
|
/* Resuming any blocked data transfers on the endpoint */
|
||||||
|
|
||||||
if (USB_ISEPIN(ep->eplog))
|
if (epno == 0 || USB_ISEPIN(ep->eplog))
|
||||||
{
|
{
|
||||||
/* IN endpoint */
|
/* IN endpoint (or EP0). Restart any queued write requests */
|
||||||
/* Restart any queued write requests */
|
|
||||||
|
|
||||||
(void)sam_req_write(priv, privep);
|
(void)sam_req_write(priv, privep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((epno == 0 && privep->epstate == UDPHS_EPSTATE_IDLE) ||
|
||||||
|
USB_ISEPOUT(ep->eplog))
|
||||||
|
{
|
||||||
|
/* OUT endpoint (or EP0 with no write request started).
|
||||||
|
* Restart any queued read requests.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(void)sam_req_read(priv, privep, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user