patch "usb: cdns3: fix race condition before setting doorbell" added to usb-linus
Subsystems (3)
This is a note to let you know that I've just added the patch titled
usb: cdns3: fix race condition before setting doorbell
to my usb git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
From b69ec50b3e55c4b2a85c8bc46763eaf330605847 Mon Sep 17 00:00:00 2001
From: Pawel Laszczak <[email protected]>
Date: Tue, 7 Sep 2021 08:26:19 +0200
Subject: usb: cdns3: fix race condition before setting doorbell
For DEV_VER_V3 version there exist race condition between clearing ep_sts.EP_STS_TRBERR and setting ep_cmd.EP_CMD_DRDY bit. Setting EP_CMD_DRDY will be ignored by controller when EP_STS_TRBERR is set. So, between these two instructions we have a small time gap in which the EP_STSS_TRBERR can be set. In such case the transfer will not start after setting doorbell.
--- drivers/usb/cdns3/cdns3-gadget.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/usb/cdns3/cdns3-gadget.c +14 -0
@@ -1100,6 +1100,19 @@ static int cdns3_ep_run_stream_transfer(struct cdns3_endpoint *priv_ep,return 0 ; } +static void cdns3_rearm_drdy_if_needed (struct cdns3_endpoint *priv_ep) +{ +struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + +if (priv_dev->dev_ver <DEV_VER_V3 ) +return ; + +if (readl (&priv_dev->regs->ep_sts) &EP_STS_TRBERR ) { +writel (EP_STS_TRBERR , &priv_dev->regs->ep_sts); +writel (EP_CMD_DRDY , &priv_dev->regs->ep_cmd); + } +} +/** * cdns3_ep_run_transfer - start transfer on no-default endpoint hardware * @priv_ep: endpoint object
@@ -1351,6 +1364,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,/*clearing TRBERR and EP_STS_DESCMIS before seting DRDY*/ writel (EP_STS_TRBERR |EP_STS_DESCMIS , &priv_dev->regs->ep_sts);writel (EP_CMD_DRDY , &priv_dev->regs->ep_cmd); +cdns3_rearm_drdy_if_needed (priv_ep);trace_cdns3_doorbell_epx (priv_ep->name,readl (&priv_dev->regs->ep_traddr)); }
Signature · 1 line
2.33.0