summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorThinh Nguyen <Thinh.Nguyen@synopsys.com>2024-12-11 00:34:03 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-12-24 08:56:07 +0100
commita4d7274d07ae4b3e77b3b35f46cab7c90b95ef21 (patch)
treec53f669184fa0c4159775a165714cd997fe114df /drivers/usb/gadget
parent29ed170538729c3c59cb8176ebb62673bbf6c799 (diff)
downloadlinux-stable-a4d7274d07ae4b3e77b3b35f46cab7c90b95ef21.tar.gz
linux-stable-a4d7274d07ae4b3e77b3b35f46cab7c90b95ef21.tar.bz2
linux-stable-a4d7274d07ae4b3e77b3b35f46cab7c90b95ef21.zip
usb: gadget: f_tcm: Stall on invalid CBW
If the BOT command CBW is invalid, make sure to respond by setting status endpoint STALL until the next proper CBW or reset. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/96022e2d5225f01a20263a4ba9c2e2c8a63328b8.1733876548.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/function/f_tcm.c16
-rw-r--r--drivers/usb/gadget/function/tcm.h1
2 files changed, 16 insertions, 1 deletions
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index 0c7a41568f40..7ea48845f8c3 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -287,8 +287,17 @@ static void bot_cmd_complete(struct usb_ep *ep, struct usb_request *req)
return;
ret = bot_submit_command(fu, req->buf, req->actual);
- if (ret)
+ if (ret) {
pr_err("%s(%d): %d\n", __func__, __LINE__, ret);
+ if (!(fu->flags & USBG_BOT_WEDGED))
+ usb_ep_set_wedge(fu->ep_in);
+
+ fu->flags |= USBG_BOT_WEDGED;
+ bot_enqueue_cmd_cbw(fu);
+ } else if (fu->flags & USBG_BOT_WEDGED) {
+ fu->flags &= ~USBG_BOT_WEDGED;
+ usb_ep_clear_halt(fu->ep_in);
+ }
}
static int bot_prepare_reqs(struct f_uas *fu)
@@ -442,6 +451,11 @@ static int usbg_bot_setup(struct usb_function *f,
case US_BULK_RESET_REQUEST:
/* XXX maybe we should remove previous requests for IN + OUT */
+ if (fu->flags & USBG_BOT_WEDGED) {
+ fu->flags &= ~USBG_BOT_WEDGED;
+ usb_ep_clear_halt(fu->ep_in);
+ }
+
bot_enqueue_cmd_cbw(fu);
return 0;
}
diff --git a/drivers/usb/gadget/function/tcm.h b/drivers/usb/gadget/function/tcm.h
index f6d6c86d10b3..009974d81d66 100644
--- a/drivers/usb/gadget/function/tcm.h
+++ b/drivers/usb/gadget/function/tcm.h
@@ -130,6 +130,7 @@ struct f_uas {
#define USBG_USE_STREAMS (1 << 2)
#define USBG_IS_BOT (1 << 3)
#define USBG_BOT_CMD_PEND (1 << 4)
+#define USBG_BOT_WEDGED (1 << 5)
struct usbg_cdb cmd[USBG_NUM_CMDS];
struct usb_ep *ep_in;