diff options
author | Thinh Nguyen <Thinh.Nguyen@synopsys.com> | 2024-12-11 00:34:03 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-12-24 08:56:07 +0100 |
commit | a4d7274d07ae4b3e77b3b35f46cab7c90b95ef21 (patch) | |
tree | c53f669184fa0c4159775a165714cd997fe114df /drivers/usb/gadget | |
parent | 29ed170538729c3c59cb8176ebb62673bbf6c799 (diff) | |
download | linux-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.c | 16 | ||||
-rw-r--r-- | drivers/usb/gadget/function/tcm.h | 1 |
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; |