[PATCH 2/2] g_printer: disconnect device file on USB unplug event

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux