From: Chunfeng Yun <chunfeng.yun@mediatek.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Chunfeng Yun <chunfeng.yun@mediatek.com>,
Matthias Brugger <matthias.bgg@gmail.com>,
<linux-usb@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<linux-mediatek@lists.infradead.org>,
<linux-kernel@vger.kernel.org>,
Eddie Hung <eddie.hung@mediatek.com>,
Min Guo <min.guo@mediatek.com>,
Tianping Fang <tianping.fang@mediatek.com>,
<Stable@vger.kernel.org>
Subject: [PATCH 1/2] usb: mtu3: fix ep0's stall of out data stage
Date: Wed, 28 Sep 2022 17:17:20 +0800 [thread overview]
Message-ID: <20220928091721.26112-1-chunfeng.yun@mediatek.com> (raw)
It happens when enable uvc function, the flow as below:
the controller switch to data stage, then call
-> foward_to_driver() -> composite_setup() -> uvc_function_setup(),
it send out an event to user layer to notify it call
-> ioctl() -> uvc_send_response() -> usb_ep_queue(),
but before the user call ioctl to queue ep0's buffer, the host already send
out data, but the controller find that no buffer is queued to receive data,
it send out STALL handshake.
To fix the issue, don't send out ACK of setup stage to switch to out data
stage until the buffer is available.
Cc: <Stable@vger.kernel.org>
Reported-by: Min Guo <min.guo@mediatek.com>
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
---
drivers/usb/mtu3/mtu3.h | 4 ++++
drivers/usb/mtu3/mtu3_gadget_ep0.c | 22 +++++++++++++++++++---
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
index 2d7b57e07eee..6b64ad17724d 100644
--- a/drivers/usb/mtu3/mtu3.h
+++ b/drivers/usb/mtu3/mtu3.h
@@ -318,6 +318,9 @@ static inline struct ssusb_mtk *dev_to_ssusb(struct device *dev)
* for GET_STATUS and SET_SEL
* @setup_buf: ep0 response buffer for GET_STATUS and SET_SEL requests
* @u3_capable: is capable of supporting USB3
+ * @delayed_setup: delay the setup stage to avoid STALL handshake in
+ * out data stage due to the class driver doesn't queue buffer
+ * before the host send out data
*/
struct mtu3 {
spinlock_t lock;
@@ -360,6 +363,7 @@ struct mtu3 {
unsigned connected:1;
unsigned async_callbacks:1;
unsigned separate_fifo:1;
+ unsigned delayed_setup:1;
u8 address;
u8 test_mode_nr;
diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c b/drivers/usb/mtu3/mtu3_gadget_ep0.c
index e4fd1bb14a55..f7a71cc83e15 100644
--- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
+++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
@@ -162,6 +162,19 @@ static void ep0_do_status_stage(struct mtu3 *mtu)
mtu3_writel(mbase, U3D_EP0CSR, value | EP0_SETUPPKTRDY | EP0_DATAEND);
}
+/* delay sending out ACK of setup stage to wait for OUT buffer queued */
+static void ep0_setup_stage_send_ack(struct mtu3 *mtu)
+{
+ void __iomem *mbase = mtu->mac_base;
+ u32 value;
+
+ if (mtu->delayed_setup) {
+ value = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
+ mtu3_writel(mbase, U3D_EP0CSR, value | EP0_SETUPPKTRDY);
+ mtu->delayed_setup = 0;
+ }
+}
+
static int ep0_queue(struct mtu3_ep *mep0, struct mtu3_request *mreq);
static void ep0_dummy_complete(struct usb_ep *ep, struct usb_request *req)
@@ -628,8 +641,9 @@ static void ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
csr | EP0_SETUPPKTRDY | EP0_DPHTX);
mtu->ep0_state = MU3D_EP0_STATE_TX;
} else {
- mtu3_writel(mtu->mac_base, U3D_EP0CSR,
- (csr | EP0_SETUPPKTRDY) & (~EP0_DPHTX));
+ mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr & ~EP0_DPHTX);
+ /* send ACK when the buffer is queued */
+ mtu->delayed_setup = 1;
mtu->ep0_state = MU3D_EP0_STATE_RX;
}
}
@@ -804,9 +818,11 @@ static int ep0_queue(struct mtu3_ep *mep, struct mtu3_request *mreq)
switch (mtu->ep0_state) {
case MU3D_EP0_STATE_SETUP:
- case MU3D_EP0_STATE_RX: /* control-OUT data */
case MU3D_EP0_STATE_TX: /* control-IN data */
break;
+ case MU3D_EP0_STATE_RX: /* control-OUT data */
+ ep0_setup_stage_send_ack(mtu);
+ break;
default:
dev_err(mtu->dev, "%s, error in ep0 state %s\n", __func__,
decode_ep0_state(mtu));
--
2.18.0
next reply other threads:[~2022-09-28 9:18 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-28 9:17 Chunfeng Yun [this message]
2022-09-28 9:17 ` [PATCH 2/2] usb: mtu3: fix failed runtime suspend in host only mode Chunfeng Yun
2022-09-28 13:43 ` AngeloGioacchino Del Regno
2022-09-28 13:43 ` [PATCH 1/2] usb: mtu3: fix ep0's stall of out data stage AngeloGioacchino Del Regno
2022-09-29 6:38 ` Chunfeng Yun
2022-09-28 15:30 ` Alan Stern
2022-09-29 6:30 ` Chunfeng Yun
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220928091721.26112-1-chunfeng.yun@mediatek.com \
--to=chunfeng.yun@mediatek.com \
--cc=Stable@vger.kernel.org \
--cc=eddie.hung@mediatek.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-usb@vger.kernel.org \
--cc=matthias.bgg@gmail.com \
--cc=min.guo@mediatek.com \
--cc=tianping.fang@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox