virtio: console: Check if port is valid in resize_console
[safe/jmp/linux-2.6] / drivers / char / virtio_console.c
index 213373b..44288ce 100644 (file)
@@ -379,7 +379,7 @@ static ssize_t send_control_msg(struct port *port, unsigned int event,
        struct scatterlist sg[1];
        struct virtio_console_control cpkt;
        struct virtqueue *vq;
-       int len;
+       unsigned int len;
 
        if (!use_multiport(port->portdev))
                return 0;
@@ -681,6 +681,10 @@ static void resize_console(struct port *port)
        struct virtio_device *vdev;
        struct winsize ws;
 
+       /* The port could have been hot-unplugged */
+       if (!port)
+               return;
+
        vdev = port->portdev->vdev;
        if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) {
                vdev->config->get(vdev,
@@ -947,11 +951,18 @@ static void handle_control_message(struct ports_device *portdev,
                 */
                err = sysfs_create_group(&port->dev->kobj,
                                         &port_attribute_group);
-               if (err)
+               if (err) {
                        dev_err(port->dev,
                                "Error %d creating sysfs device attributes\n",
                                err);
-
+               } else {
+                       /*
+                        * Generate a udev event so that appropriate
+                        * symlinks can be created based on udev
+                        * rules.
+                        */
+                       kobject_uevent(&port->dev->kobj, KOBJ_CHANGE);
+               }
                break;
        case VIRTIO_CONSOLE_PORT_REMOVE:
                /*
@@ -1071,27 +1082,27 @@ static void config_intr(struct virtio_device *vdev)
 static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
 {
        struct port_buffer *buf;
-       unsigned int ret;
-       int err;
+       unsigned int nr_added_bufs;
+       int ret;
 
-       ret = 0;
+       nr_added_bufs = 0;
        do {
                buf = alloc_buf(PAGE_SIZE);
                if (!buf)
                        break;
 
                spin_lock_irq(lock);
-               err = add_inbuf(vq, buf);
-               if (err < 0) {
+               ret = add_inbuf(vq, buf);
+               if (ret < 0) {
                        spin_unlock_irq(lock);
                        free_buf(buf);
                        break;
                }
-               ret++;
+               nr_added_bufs++;
                spin_unlock_irq(lock);
-       } while (err > 0);
+       } while (ret > 0);
 
-       return ret;
+       return nr_added_bufs;
 }
 
 static int add_port(struct ports_device *portdev, u32 id)
@@ -1100,6 +1111,7 @@ static int add_port(struct ports_device *portdev, u32 id)
        struct port *port;
        struct port_buffer *buf;
        dev_t devt;
+       unsigned int nr_added_bufs;
        int err;
 
        port = kmalloc(sizeof(*port), GFP_KERNEL);
@@ -1144,8 +1156,8 @@ static int add_port(struct ports_device *portdev, u32 id)
        init_waitqueue_head(&port->waitqueue);
 
        /* Fill the in_vq with buffers so the host can send us data. */
-       err = fill_queue(port->in_vq, &port->inbuf_lock);
-       if (!err) {
+       nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock);
+       if (!nr_added_bufs) {
                dev_err(port->dev, "Error allocating inbufs\n");
                err = -ENOMEM;
                goto free_device;
@@ -1442,12 +1454,14 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
        INIT_LIST_HEAD(&portdev->ports);
 
        if (multiport) {
+               unsigned int nr_added_bufs;
+
                spin_lock_init(&portdev->cvq_lock);
                INIT_WORK(&portdev->control_work, &control_work_handler);
                INIT_WORK(&portdev->config_work, &config_work_handler);
 
-               err = fill_queue(portdev->c_ivq, &portdev->cvq_lock);
-               if (!err) {
+               nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock);
+               if (!nr_added_bufs) {
                        dev_err(&vdev->dev,
                                "Error allocating buffers for control queue\n");
                        err = -ENOMEM;