risc-v/mpfs: usb: fix illegal reads

With faster data transfer rates, it was seen that the read
requests occasionally were issued while the USB RX operation
was actually in progress.  This patch makes sure the system
doesn't accidentally read the RX fifo while it's being filled
up, but rather, checks for the RXCSRL_REG_EPN_RX_PKT_RDY_MASK
flag.  This flag indicates the packet is ready to be read.

Signed-off-by: Eero Nurkkala <eero.nurkkala@offcode.fi>
This commit is contained in:
Eero Nurkkala 2022-07-12 09:27:07 +03:00 committed by Xiang Xiao
parent 1c80675e87
commit 14447600ac

View File

@ -1005,6 +1005,7 @@ static int mpfs_req_read(struct mpfs_usbdev_s *priv,
struct mpfs_ep_s *privep, uint16_t recvsize)
{
struct mpfs_req_s *privreq;
uint16_t reg;
int epno;
DEBUGASSERT(priv && privep);
@ -1013,6 +1014,8 @@ static int mpfs_req_read(struct mpfs_usbdev_s *priv,
epno = USB_EPNO(privep->ep.eplog);
reg = getreg16(MPFS_USB_ENDPOINT(epno) + MPFS_USB_ENDPOINT_RX_CSR_OFFSET);
uint16_t count = getreg16(MPFS_USB_ENDPOINT(epno) +
MPFS_USB_ENDPOINT_RX_COUNT_OFFSET);
@ -1026,11 +1029,9 @@ static int mpfs_req_read(struct mpfs_usbdev_s *priv,
if (privreq == NULL)
{
/* When no read requests are pending no EP descriptors are set to
* ready. This is fatal at the moment!
* ready.
*/
usbtrace(TRACE_DEVERROR(MPFS_TRACEERR_EPOUTQEMPTY), epno);
privep->epstate = USB_EPSTATE_RXSTOPPED;
return OK;
}
@ -1060,7 +1061,8 @@ static int mpfs_req_read(struct mpfs_usbdev_s *priv,
privreq = NULL;
}
if ((privreq->inflight) && (count != 0))
if ((privreq->inflight > 0) && (count != 0) &&
(reg & RXCSRL_REG_EPN_RX_PKT_RDY_MASK) != 0)
{
/* Update the total number of bytes transferred */