mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 20:51:44 +00:00
usb: gadget: function: printer: avoid wrong list handling in printer_write()
When printer_write() calls usb_ep_queue(), a udc driver (e.g. renesas_usbhs driver) may call usb_gadget_giveback_request() in the udc .queue ops immediately. Then, printer_write() calls list_add(&req->list, &dev->tx_reqs_active) wrongly. After that, if we do unbind the printer driver, WARN_ON() happens in printer_func_unbind() because the list entry is not removed. So, this patch moves list_add(&req->list, &dev->tx_reqs_active) calling before usb_ep_queue(). Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
c97a8cc17f
commit
4a014a7339
@ -631,19 +631,19 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
list_add(&req->list, &dev->tx_reqs_active);
|
||||
|
||||
/* here, we unlock, and only unlock, to avoid deadlock. */
|
||||
spin_unlock(&dev->lock);
|
||||
value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
|
||||
spin_lock(&dev->lock);
|
||||
if (value) {
|
||||
list_del(&req->list);
|
||||
list_add(&req->list, &dev->tx_reqs);
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
mutex_unlock(&dev->lock_printer_io);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
list_add(&req->list, &dev->tx_reqs_active);
|
||||
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
|
Loading…
Reference in New Issue
Block a user