From: Christian Kellermann <ck@xxxxxxxxx> We check the reset_printer flag in the printer driver's wait queues to sense the reset propagation. Blocking read/write calls will fail with EBUSY, whereas poll/select/epoll calls will return with POLLHUP as revent value. --- drivers/usb/gadget/printer.c | 20 ++++++++++++++++---- 1 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 6c37fc5..fbdadd3 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -608,7 +608,8 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) /* Sleep until data is available */ wait_event_interruptible(dev->rx_wait, - (likely(!list_empty(&dev->rx_buffers)))); + ((likely(!list_empty(&dev->rx_buffers)) + || dev->reset_printer))); spin_lock_irqsave(&dev->lock, flags); } @@ -720,7 +721,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) /* Sleep until a write buffer is available */ wait_event_interruptible(dev->tx_wait, - (likely(!list_empty(&dev->tx_reqs)))); + (likely(!list_empty(&dev->tx_reqs)) + || dev->reset_printer)); spin_lock_irqsave(&dev->lock, flags); } @@ -805,12 +807,14 @@ printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync) mutex_lock(&inode->i_mutex); spin_lock_irqsave(&dev->lock, flags); tx_list_empty = (likely(list_empty(&dev->tx_reqs))); + dev->reset_printer = 0; spin_unlock_irqrestore(&dev->lock, flags); if (!tx_list_empty) { /* Sleep until all data has been sent */ wait_event_interruptible(dev->tx_flush_wait, - (likely(list_empty(&dev->tx_reqs_active)))); + (likely(list_empty(&dev->tx_reqs_active) + || dev->reset_printer))); } mutex_unlock(&inode->i_mutex); @@ -841,6 +845,9 @@ printer_poll(struct file *fd, poll_table *wait) likely(!list_empty(&dev->rx_buffers))) status |= POLLIN | POLLRDNORM; + if (dev->reset_printer) + status = POLLHUP; + spin_unlock_irqrestore(&dev->lock, flags); return status; @@ -1307,7 +1314,12 @@ printer_disconnect(struct usb_gadget *gadget) spin_lock_irqsave(&dev->lock, flags); - printer_reset_interface(dev); + + if (dev->printer_cdev_open) { + DBG(dev, "printer device open -> soft reset\n"); + printer_soft_reset(dev); + } else + printer_reset_interface(dev); spin_unlock_irqrestore(&dev->lock, flags); } -- 1.7.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html