SAMA5 UDPHS: Fix bad setup for sam_req_write call introduce in last commit
This commit is contained in:
parent
54d5e1a49d
commit
ec01a41da7
@ -145,31 +145,32 @@
|
||||
#define SAM_TRACEERR_BADCLEARFEATURE 0x0002
|
||||
#define SAM_TRACEERR_BADDEVGETSTATUS 0x0003
|
||||
#define SAM_TRACEERR_BADEPGETSTATUS 0x0004
|
||||
#define SAM_TRACEERR_BADEPNO 0x0005
|
||||
#define SAM_TRACEERR_BADEPTYPE 0x0006
|
||||
#define SAM_TRACEERR_BADGETCONFIG 0x0007
|
||||
#define SAM_TRACEERR_BADGETSETDESC 0x0008
|
||||
#define SAM_TRACEERR_BADGETSTATUS 0x0009
|
||||
#define SAM_TRACEERR_BADSETADDRESS 0x000a
|
||||
#define SAM_TRACEERR_BADSETCONFIG 0x000b
|
||||
#define SAM_TRACEERR_BADSETFEATURE 0x000c
|
||||
#define SAM_TRACEERR_BINDFAILED 0x000d
|
||||
#define SAM_TRACEERR_DISPATCHSTALL 0x000e
|
||||
#define SAM_TRACEERR_DMAERR 0x000f
|
||||
#define SAM_TRACEERR_DRIVER 0x0010
|
||||
#define SAM_TRACEERR_DRIVERREGISTERED 0x0011
|
||||
#define SAM_TRACEERR_ENDBUFST 0x0012
|
||||
#define SAM_TRACEERR_EP0SETUPOUTSIZE 0x0013
|
||||
#define SAM_TRACEERR_EP0SETUPSTALLED 0x0014
|
||||
#define SAM_TRACEERR_EPOUTNULLPACKET 0x0015
|
||||
#define SAM_TRACEERR_EPRESERVE 0x0016
|
||||
#define SAM_TRACEERR_EPTCFGMAPD 0x0017
|
||||
#define SAM_TRACEERR_INVALIDCTRLREQ 0x0018
|
||||
#define SAM_TRACEERR_INVALIDPARMS 0x0019
|
||||
#define SAM_TRACEERR_IRQREGISTRATION 0x001a
|
||||
#define SAM_TRACEERR_NOTCONFIGURED 0x001b
|
||||
#define SAM_TRACEERR_REQABORTED 0x001c
|
||||
#define SAM_TRACEERR_TXRDYERR 0x001d
|
||||
#define SAM_TRACEERR_BADEOBSTATE 0x0005
|
||||
#define SAM_TRACEERR_BADEPNO 0x0006
|
||||
#define SAM_TRACEERR_BADEPTYPE 0x0007
|
||||
#define SAM_TRACEERR_BADGETCONFIG 0x0008
|
||||
#define SAM_TRACEERR_BADGETSETDESC 0x0009
|
||||
#define SAM_TRACEERR_BADGETSTATUS 0x000a
|
||||
#define SAM_TRACEERR_BADSETADDRESS 0x000b
|
||||
#define SAM_TRACEERR_BADSETCONFIG 0x000c
|
||||
#define SAM_TRACEERR_BADSETFEATURE 0x000d
|
||||
#define SAM_TRACEERR_BINDFAILED 0x000e
|
||||
#define SAM_TRACEERR_DISPATCHSTALL 0x000f
|
||||
#define SAM_TRACEERR_DMAERR 0x0010
|
||||
#define SAM_TRACEERR_DRIVER 0x0011
|
||||
#define SAM_TRACEERR_DRIVERREGISTERED 0x0012
|
||||
#define SAM_TRACEERR_ENDBUFST 0x0013
|
||||
#define SAM_TRACEERR_EP0SETUPOUTSIZE 0x0014
|
||||
#define SAM_TRACEERR_EP0SETUPSTALLED 0x0015
|
||||
#define SAM_TRACEERR_EPOUTNULLPACKET 0x0016
|
||||
#define SAM_TRACEERR_EPRESERVE 0x0017
|
||||
#define SAM_TRACEERR_EPTCFGMAPD 0x0018
|
||||
#define SAM_TRACEERR_INVALIDCTRLREQ 0x0019
|
||||
#define SAM_TRACEERR_INVALIDPARMS 0x001a
|
||||
#define SAM_TRACEERR_IRQREGISTRATION 0x001b
|
||||
#define SAM_TRACEERR_NOTCONFIGURED 0x001c
|
||||
#define SAM_TRACEERR_REQABORTED 0x001d
|
||||
#define SAM_TRACEERR_TXRDYERR 0x001e
|
||||
|
||||
/* 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_BADDEVGETSTATUS),
|
||||
TRACE_STR(SAM_TRACEERR_BADEPGETSTATUS),
|
||||
TRACE_STR(SAM_TRACEERR_BADEOBSTATE),
|
||||
TRACE_STR(SAM_TRACEERR_BADEPNO),
|
||||
TRACE_STR(SAM_TRACEERR_BADEPTYPE),
|
||||
TRACE_STR(SAM_TRACEERR_BADGETCONFIG),
|
||||
@ -1281,9 +1283,10 @@ static void sam_req_wrsetup(struct sam_usbdev_s *priv,
|
||||
*
|
||||
* Description:
|
||||
* Process the next queued write request. This function is called in one
|
||||
* of three contexts: (1) When a new write request is submitted (with
|
||||
* interrupts disabled, (2) from interrupt handling when a previous
|
||||
* transfer completes, or (3) resuming a stalled IN endpoint.
|
||||
* of three contexts: (1) When the endpoint is IDLE and a new write 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 IN or control endpoint.
|
||||
*
|
||||
* Calling rules:
|
||||
*
|
||||
@ -1543,8 +1546,13 @@ static void sam_req_rddisable(uint8_t epno)
|
||||
* Name: sam_req_read
|
||||
*
|
||||
* Description:
|
||||
* Called only from interrupt handling logic when on OUT packet is received
|
||||
* on an endpoint in the RECEIVING state.
|
||||
* Complete the last read request, return the read request to the class
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* if we need to setup the next tranfer.
|
||||
* - When receiving via the FIFO, then transfer is not complete. The
|
||||
* if we need to setup the tranfer for the next request.
|
||||
* - 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
|
||||
* 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:
|
||||
*
|
||||
@ -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);
|
||||
|
||||
/* BUFF_COUNT holds the number of untransmitted bytes. BUFF_COUNT is
|
||||
* 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 now decremented to zero
|
||||
* 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
|
||||
* now decremented to zero
|
||||
*/
|
||||
|
||||
xfrsize = privreq->inflight;
|
||||
privreq->inflight = 0;
|
||||
|
||||
/* This is just debug logic that only does any if USB debug or tracing
|
||||
* 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)
|
||||
{
|
||||
/* 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));
|
||||
privep->epstate = UDPHS_EPSTATE_IDLE;
|
||||
(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
|
||||
* region that just completed DMA. This will force the
|
||||
* 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];
|
||||
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;
|
||||
(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
|
||||
@ -2451,9 +2471,10 @@ static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno)
|
||||
* give us the actual size of the transfer.
|
||||
*/
|
||||
|
||||
bufcnt = ((dmastatus & UDPHS_DMASTATUS_BUFCNT_MASK)
|
||||
>> UDPHS_DMASTATUS_BUFCNT_SHIFT);
|
||||
xfrsize = privreq->inflight - bufcnt;
|
||||
bufcnt = ((dmastatus & UDPHS_DMASTATUS_BUFCNT_MASK)
|
||||
>> UDPHS_DMASTATUS_BUFCNT_SHIFT);
|
||||
xfrsize = privreq->inflight - bufcnt;
|
||||
privreq->inflight = 0;
|
||||
|
||||
/* Invalidate the data cache for region that just completed DMA.
|
||||
* 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];
|
||||
cp15_invalidate_dcache((uintptr_t)buf, (uintptr_t)buf + xfrsize);
|
||||
|
||||
/* Complete this transfer now and return the request to the class
|
||||
* implementation.
|
||||
/* Complete this transfer, return the request to the class
|
||||
* implementation, and try to start the next, queue read request.
|
||||
*/
|
||||
|
||||
privep->epstate = UDPHS_EPSTATE_IDLE;
|
||||
privreq->req.xfrd += 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);
|
||||
privep->epstate = UDPHS_EPSTATE_IDLE;
|
||||
(void)sam_req_read(priv, privep, xfrsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3670,8 +3685,8 @@ static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume)
|
||||
privep = (struct sam_ep_s *)ep;
|
||||
DEBUGASSERT(privep->epstate == UDPHS_EPSTATE_IDLE && privep->dev);
|
||||
|
||||
priv = (struct sam_usbdev_s *)privep->dev;
|
||||
epno = USB_EPNO(ep->eplog);
|
||||
priv = (struct sam_usbdev_s *)privep->dev;
|
||||
epno = USB_EPNO(ep->eplog);
|
||||
|
||||
/* STALL or RESUME the endpoint */
|
||||
|
||||
@ -3704,13 +3719,22 @@ static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume)
|
||||
|
||||
/* Resuming any blocked data transfers on the endpoint */
|
||||
|
||||
if (USB_ISEPIN(ep->eplog))
|
||||
if (epno == 0 || USB_ISEPIN(ep->eplog))
|
||||
{
|
||||
/* IN endpoint */
|
||||
/* Restart any queued write requests */
|
||||
/* IN endpoint (or EP0). Restart any queued write requests */
|
||||
|
||||
(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user