From fb8bceab287c1632b1cd3c5b1c6c4d2f27985561 Mon Sep 17 00:00:00 2001 From: Udipto Goswami Date: Mon, 28 Mar 2022 15:55:03 +0530 Subject: [PATCH] usb: gadget: u_serial: Rectify the list operations is rx/tx path Commit I714c7fe681 ("usb: gadget: u_serial: Dequeue request on gserial_disconnect") had introduced additional two pools, queued_write_pool & queued_read_pool in order to dequeue requests on gserial_disconnect. Currently in the rx/tx paths, the driver extracts the request from write/read_pool and moves it to the queued pool. This is done before the request is queued. Now when the completion is called, the request is added back to the head write/read_pool. The approach should be when the request is successfully queued, only then move it to the queued pool and when the request_completion is called move it back to the write/read pool. This will ensure that the request is only one list either read/write pool or the queued_read/write pool. Change-Id: Ic16cb8ec09c5a58b3ea673750f06468f184e724c Signed-off-by: Udipto Goswami --- drivers/usb/gadget/function/u_serial.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index ae749f22e1f1..2f226d15aea6 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -281,6 +281,7 @@ __acquires(&port->port_lock) break; } + list_move_tail(&req->list, &port->queued_write_pool); port->write_started++; /* abort immediately after disconnect */ @@ -319,7 +320,6 @@ __acquires(&port->port_lock) break; req = list_entry(pool->next, struct usb_request, list); - list_move_tail(&req->list, &port->queued_read_pool); req->length = out->maxpacket; /* drop lock while we call out; the controller driver @@ -335,6 +335,7 @@ __acquires(&port->port_lock) list_add(&req->list, pool); break; } + list_move_tail(&req->list, &port->queued_read_pool); port->read_started++; /* abort immediately after disconnect */ @@ -453,7 +454,7 @@ static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) /* Queue all received data until the tty layer is ready for it. */ spin_lock(&port->port_lock); - list_add_tail(&req->list, &port->read_queue); + list_move_tail(&req->list, &port->read_queue); schedule_delayed_work(&port->push, 0); spin_unlock(&port->port_lock); } @@ -463,7 +464,7 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) struct gs_port *port = ep->driver_data; spin_lock(&port->port_lock); - list_add(&req->list, &port->write_pool); + list_move_tail(&req->list, &port->write_pool); port->write_started--; switch (req->status) {