]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/char/virtio_console.c
Merge branch 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / char / virtio_console.c
index 7270e7b692622721adc50fa26d085fa33b50aa8f..3259426f01dc9776f5fdcfcebff966192b74616e 100644 (file)
@@ -1325,24 +1325,24 @@ static void set_console_size(struct port *port, u16 rows, u16 cols)
        port->cons.ws.ws_col = cols;
 }
 
-static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
+static int fill_queue(struct virtqueue *vq, spinlock_t *lock)
 {
        struct port_buffer *buf;
-       unsigned int nr_added_bufs;
+       int nr_added_bufs;
        int ret;
 
        nr_added_bufs = 0;
        do {
                buf = alloc_buf(vq->vdev, PAGE_SIZE, 0);
                if (!buf)
-                       break;
+                       return -ENOMEM;
 
                spin_lock_irq(lock);
                ret = add_inbuf(vq, buf);
                if (ret < 0) {
                        spin_unlock_irq(lock);
                        free_buf(buf, true);
-                       break;
+                       return ret;
                }
                nr_added_bufs++;
                spin_unlock_irq(lock);
@@ -1362,7 +1362,6 @@ static int add_port(struct ports_device *portdev, u32 id)
        char debugfs_name[16];
        struct port *port;
        dev_t devt;
-       unsigned int nr_added_bufs;
        int err;
 
        port = kmalloc(sizeof(*port), GFP_KERNEL);
@@ -1421,11 +1420,13 @@ static int add_port(struct ports_device *portdev, u32 id)
        spin_lock_init(&port->outvq_lock);
        init_waitqueue_head(&port->waitqueue);
 
-       /* Fill the in_vq with buffers so the host can send us data. */
-       nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock);
-       if (!nr_added_bufs) {
+       /* We can safely ignore ENOSPC because it means
+        * the queue already has buffers. Buffers are removed
+        * only by virtcons_remove(), not by unplug_port()
+        */
+       err = fill_queue(port->in_vq, &port->inbuf_lock);
+       if (err < 0 && err != -ENOSPC) {
                dev_err(port->dev, "Error allocating inbufs\n");
-               err = -ENOMEM;
                goto free_device;
        }
 
@@ -2059,14 +2060,11 @@ static int virtcons_probe(struct virtio_device *vdev)
        INIT_WORK(&portdev->control_work, &control_work_handler);
 
        if (multiport) {
-               unsigned int nr_added_bufs;
-
                spin_lock_init(&portdev->c_ivq_lock);
                spin_lock_init(&portdev->c_ovq_lock);
 
-               nr_added_bufs = fill_queue(portdev->c_ivq,
-                                          &portdev->c_ivq_lock);
-               if (!nr_added_bufs) {
+               err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
+               if (err < 0) {
                        dev_err(&vdev->dev,
                                "Error allocating buffers for control queue\n");
                        /*
@@ -2077,7 +2075,7 @@ static int virtcons_probe(struct virtio_device *vdev)
                                           VIRTIO_CONSOLE_DEVICE_READY, 0);
                        /* Device was functional: we need full cleanup. */
                        virtcons_remove(vdev);
-                       return -ENOMEM;
+                       return err;
                }
        } else {
                /*