From 5caba7258652fdc9ef541acba9a92d4723a6ba2f Mon Sep 17 00:00:00 2001 From: Prashanth K Date: Tue, 16 Apr 2024 15:06:34 +0530 Subject: [PATCH] usb: gadget: f_cdev: Bail out from cer_resume if func_suspended Currently when the device exits from U3, all the interfaces will be resumed. In f_cdev driver, cser_resume will be called, which will clear is_suspended flag and process pending requests. Consider a situation where DUN interface is function suspended, and gadget resume happens eventually clearing is_suspended flag. Now if userspace writes something into at_usb node, f_cdev_write will queue the request without calling func_wakeup. And since the DUN interface is function suspended, host expects func_wakeup to be called before queueing the data. Fix this by bailing out from cser_resume() if function is already suspended, and wait for the userspace to issue remote-wakeup by writing something into at_usb node. Change-Id: Iba9c1dfd8a5deeb6c73af3ff370d51af193ff0e9 Signed-off-by: Prashanth K --- drivers/usb/gadget/function/f_cdev.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c index 1f9751d251de..0ba2dda270c7 100644 --- a/drivers/usb/gadget/function/f_cdev.c +++ b/drivers/usb/gadget/function/f_cdev.c @@ -554,12 +554,21 @@ static void usb_cser_start_rx(struct f_cdev *port); static void usb_cser_resume(struct usb_function *f) { struct f_cdev *port = func_to_port(f); + struct usb_composite_dev *cdev = f->config->cdev; unsigned long flags; int ret; struct usb_request *req, *t; struct usb_ep *in; + /* + * Bail out if the interface is in USB3 Function Suspend state. + * In that case resume is done by Function Resume request (write). + */ + if ((cdev->gadget->speed >= USB_SPEED_SUPER) && + port->func_is_suspended) + return; + pr_debug("%s\n", __func__); port->is_suspended = false;