aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/virtio_console.c49
1 files changed, 24 insertions, 25 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 3e56f328b4cb..26a66ffd943e 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1402,7 +1402,6 @@ static int add_port(struct ports_device *portdev, u32 id)
1402{ 1402{
1403 char debugfs_name[16]; 1403 char debugfs_name[16];
1404 struct port *port; 1404 struct port *port;
1405 struct port_buffer *buf;
1406 dev_t devt; 1405 dev_t devt;
1407 unsigned int nr_added_bufs; 1406 unsigned int nr_added_bufs;
1408 int err; 1407 int err;
@@ -1513,8 +1512,6 @@ static int add_port(struct ports_device *portdev, u32 id)
1513 return 0; 1512 return 0;
1514 1513
1515free_inbufs: 1514free_inbufs:
1516 while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
1517 free_buf(buf, true);
1518free_device: 1515free_device:
1519 device_destroy(pdrvdata.class, port->dev->devt); 1516 device_destroy(pdrvdata.class, port->dev->devt);
1520free_cdev: 1517free_cdev:
@@ -1539,34 +1536,14 @@ static void remove_port(struct kref *kref)
1539 1536
1540static void remove_port_data(struct port *port) 1537static void remove_port_data(struct port *port)
1541{ 1538{
1542 struct port_buffer *buf;
1543
1544 spin_lock_irq(&port->inbuf_lock); 1539 spin_lock_irq(&port->inbuf_lock);
1545 /* Remove unused data this port might have received. */ 1540 /* Remove unused data this port might have received. */
1546 discard_port_data(port); 1541 discard_port_data(port);
1547 spin_unlock_irq(&port->inbuf_lock); 1542 spin_unlock_irq(&port->inbuf_lock);
1548 1543
1549 /* Remove buffers we queued up for the Host to send us data in. */
1550 do {
1551 spin_lock_irq(&port->inbuf_lock);
1552 buf = virtqueue_detach_unused_buf(port->in_vq);
1553 spin_unlock_irq(&port->inbuf_lock);
1554 if (buf)
1555 free_buf(buf, true);
1556 } while (buf);
1557
1558 spin_lock_irq(&port->outvq_lock); 1544 spin_lock_irq(&port->outvq_lock);
1559 reclaim_consumed_buffers(port); 1545 reclaim_consumed_buffers(port);
1560 spin_unlock_irq(&port->outvq_lock); 1546 spin_unlock_irq(&port->outvq_lock);
1561
1562 /* Free pending buffers from the out-queue. */
1563 do {
1564 spin_lock_irq(&port->outvq_lock);
1565 buf = virtqueue_detach_unused_buf(port->out_vq);
1566 spin_unlock_irq(&port->outvq_lock);
1567 if (buf)
1568 free_buf(buf, true);
1569 } while (buf);
1570} 1547}
1571 1548
1572/* 1549/*
@@ -1791,13 +1768,24 @@ static void control_work_handler(struct work_struct *work)
1791 spin_unlock(&portdev->c_ivq_lock); 1768 spin_unlock(&portdev->c_ivq_lock);
1792} 1769}
1793 1770
1771static void flush_bufs(struct virtqueue *vq, bool can_sleep)
1772{
1773 struct port_buffer *buf;
1774 unsigned int len;
1775
1776 while ((buf = virtqueue_get_buf(vq, &len)))
1777 free_buf(buf, can_sleep);
1778}
1779
1794static void out_intr(struct virtqueue *vq) 1780static void out_intr(struct virtqueue *vq)
1795{ 1781{
1796 struct port *port; 1782 struct port *port;
1797 1783
1798 port = find_port_by_vq(vq->vdev->priv, vq); 1784 port = find_port_by_vq(vq->vdev->priv, vq);
1799 if (!port) 1785 if (!port) {
1786 flush_bufs(vq, false);
1800 return; 1787 return;
1788 }
1801 1789
1802 wake_up_interruptible(&port->waitqueue); 1790 wake_up_interruptible(&port->waitqueue);
1803} 1791}
@@ -1808,8 +1796,10 @@ static void in_intr(struct virtqueue *vq)
1808 unsigned long flags; 1796 unsigned long flags;
1809 1797
1810 port = find_port_by_vq(vq->vdev->priv, vq); 1798 port = find_port_by_vq(vq->vdev->priv, vq);
1811 if (!port) 1799 if (!port) {
1800 flush_bufs(vq, false);
1812 return; 1801 return;
1802 }
1813 1803
1814 spin_lock_irqsave(&port->inbuf_lock, flags); 1804 spin_lock_irqsave(&port->inbuf_lock, flags);
1815 port->inbuf = get_inbuf(port); 1805 port->inbuf = get_inbuf(port);
@@ -1984,6 +1974,15 @@ static const struct file_operations portdev_fops = {
1984 1974
1985static void remove_vqs(struct ports_device *portdev) 1975static void remove_vqs(struct ports_device *portdev)
1986{ 1976{
1977 struct virtqueue *vq;
1978
1979 virtio_device_for_each_vq(portdev->vdev, vq) {
1980 struct port_buffer *buf;
1981
1982 flush_bufs(vq, true);
1983 while ((buf = virtqueue_detach_unused_buf(vq)))
1984 free_buf(buf, true);
1985 }
1987 portdev->vdev->config->del_vqs(portdev->vdev); 1986 portdev->vdev->config->del_vqs(portdev->vdev);
1988 kfree(portdev->in_vqs); 1987 kfree(portdev->in_vqs);
1989 kfree(portdev->out_vqs); 1988 kfree(portdev->out_vqs);