diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 511125a2d3b3..f69349363912 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1171,21 +1171,32 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) * status. usb_ep_dequeue API should guarantee no race * condition with req->complete callback. */ - usb_ep_dequeue(ep->ep, req); - wait_for_completion(&done); - interrupted = ep->status < 0; + spin_lock_irq(&epfile->ffs->eps_lock); + interrupted = true; + if (ep->ep) { + usb_ep_dequeue(ep->ep, req); + wait_for_completion(&done); + interrupted = ep->status < 0; + } + spin_unlock_irq(&epfile->ffs->eps_lock); } ffs_log("%s:ep status %d for req %pK", epfile->name, ep->status, req); - if (interrupted) + if (interrupted) { ret = -EINTR; - else if (io_data->read && ep->status > 0) + goto error_mutex; + } + + ret = -ENODEV; + spin_lock_irq(&epfile->ffs->eps_lock); + if (ep->ep) + ret = ep->status; + spin_unlock_irq(&epfile->ffs->eps_lock); + if (io_data->read && ret > 0) ret = __ffs_epfile_read_data(epfile, data, ep->status, &io_data->data); - else - ret = ep->status; goto error_mutex; } else if (!(req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC))) { ret = -ENOMEM;