Skip to content

Commit

Permalink
usb: f_mass_storage: forbid async queue when shutdown happen
Browse files Browse the repository at this point in the history
When write UDC to empty and unbind gadget driver from gadget device, it is
possible that there are many queue failures for mass storage function.

The root cause is mass storage main thread alaways try to queue request to
receive a command from host if running flag is on, on platform like dwc3,
if pull down called, it will not queue request again and return
-ESHUTDOWN, but it not affect running flag of mass storage function.

Check return code from mass storage function and clear running flag if it
is -ESHUTDOWN, also indicate start in/out transfer failure to break loops.

Cc: stable <stable@kernel.org>
Signed-off-by: yuan linyu <yuanlinyu@hihonor.com>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/20240123034829.3848409-1-yuanlinyu@hihonor.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
yuan linyu authored and Greg Kroah-Hartman committed Jan 28, 2024
1 parent f17c34f commit b2d2d7e
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions drivers/usb/gadget/function/f_mass_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,21 +545,37 @@ static int start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,

static bool start_in_transfer(struct fsg_common *common, struct fsg_buffhd *bh)
{
int rc;

if (!fsg_is_set(common))
return false;
bh->state = BUF_STATE_SENDING;
if (start_transfer(common->fsg, common->fsg->bulk_in, bh->inreq))
rc = start_transfer(common->fsg, common->fsg->bulk_in, bh->inreq);
if (rc) {
bh->state = BUF_STATE_EMPTY;
if (rc == -ESHUTDOWN) {
common->running = 0;
return false;
}
}
return true;
}

static bool start_out_transfer(struct fsg_common *common, struct fsg_buffhd *bh)
{
int rc;

if (!fsg_is_set(common))
return false;
bh->state = BUF_STATE_RECEIVING;
if (start_transfer(common->fsg, common->fsg->bulk_out, bh->outreq))
rc = start_transfer(common->fsg, common->fsg->bulk_out, bh->outreq);
if (rc) {
bh->state = BUF_STATE_FULL;
if (rc == -ESHUTDOWN) {
common->running = 0;
return false;
}
}
return true;
}

Expand Down

0 comments on commit b2d2d7e

Please sign in to comment.