usb: gadget: cdev: Requeue the request in cser_resume if start_rx fails

Consider a case where dut enters suspend before port_bridge is started.
In that case, ep_queue in start_rx function fails as dut is in suspend
mode. The expectation is that when host resumes the DUT, the request
must be requeued in cser_resume as ep_queue of start_rx which was
called earlier was a failure.

Change-Id: I87015f00267af20450d625e2ea7a19a9de45c79a
Signed-off-by: Rohith Kollalsi <quic_rkollals@quicinc.com>
This commit is contained in:
Rohith Kollalsi 2022-07-22 18:04:35 +05:30 • committed by Gerrit - the friendly Code Review server
commit 1be4ae7011

View file

@ -138,6 +138,7 @@ struct f_cdev {
unsigned long nbytes_from_port_bridge;
struct dentry *debugfs_root;
bool setup_pending;
/* To test remote wakeup using debugfs */
u8 debugfs_rw_enable;
@ -548,6 +549,7 @@ static int usb_cser_set_alt(struct usb_function *f, unsigned int intf,
}
static int port_notify_serial_state(struct cserial *cser);
static void usb_cser_start_rx(struct f_cdev *port);
static void usb_cser_resume(struct usb_function *f)
{
@ -566,6 +568,13 @@ static void usb_cser_resume(struct usb_function *f)
port_notify_serial_state(&port->port_usb);
spin_lock_irqsave(&port->port_lock, flags);
/* process pending read request */
if (port->setup_pending) {
pr_info("%s: start_rx called due to rx_out error.\n", __func__);
port->setup_pending = false;
usb_cser_start_rx(port);
}
in = port->port_usb.in;
/* process any pending requests */
list_for_each_entry_safe(req, t, &port->write_pending, list) {
@ -1055,7 +1064,10 @@ static void usb_cser_start_rx(struct f_cdev *port)
pr_err("port(%d):%pK usb ep(%s) queue failed\n",
port->port_num, port, ep->name);
list_add(&req->list, pool);
port->setup_pending = true;
break;
} else {
port->setup_pending = false;
}
}