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 <quic_prashk@quicinc.com>
This commit is contained in:
Prashanth K 2024-04-16 15:06:34 +05:30
commit 5caba72586

View file

@ -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;