|
@@ -1529,18 +1529,22 @@ static void remove_port_data(struct port *port)
|
|
|
{
|
|
|
struct port_buffer *buf;
|
|
|
|
|
|
+ spin_lock_irq(&port->inbuf_lock);
|
|
|
/* Remove unused data this port might have received. */
|
|
|
discard_port_data(port);
|
|
|
|
|
|
- reclaim_consumed_buffers(port);
|
|
|
-
|
|
|
/* Remove buffers we queued up for the Host to send us data in. */
|
|
|
while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
|
|
|
free_buf(buf, true);
|
|
|
+ spin_unlock_irq(&port->inbuf_lock);
|
|
|
+
|
|
|
+ spin_lock_irq(&port->outvq_lock);
|
|
|
+ reclaim_consumed_buffers(port);
|
|
|
|
|
|
/* Free pending buffers from the out-queue. */
|
|
|
while ((buf = virtqueue_detach_unused_buf(port->out_vq)))
|
|
|
free_buf(buf, true);
|
|
|
+ spin_unlock_irq(&port->outvq_lock);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1554,6 +1558,7 @@ static void unplug_port(struct port *port)
|
|
|
list_del(&port->list);
|
|
|
spin_unlock_irq(&port->portdev->ports_lock);
|
|
|
|
|
|
+ spin_lock_irq(&port->inbuf_lock);
|
|
|
if (port->guest_connected) {
|
|
|
/* Let the app know the port is going down. */
|
|
|
send_sigio_to_port(port);
|
|
@@ -1564,6 +1569,7 @@ static void unplug_port(struct port *port)
|
|
|
|
|
|
wake_up_interruptible(&port->waitqueue);
|
|
|
}
|
|
|
+ spin_unlock_irq(&port->inbuf_lock);
|
|
|
|
|
|
if (is_console_port(port)) {
|
|
|
spin_lock_irq(&pdrvdata_lock);
|
|
@@ -1585,9 +1591,8 @@ static void unplug_port(struct port *port)
|
|
|
device_destroy(pdrvdata.class, port->dev->devt);
|
|
|
cdev_del(port->cdev);
|
|
|
|
|
|
- kfree(port->name);
|
|
|
-
|
|
|
debugfs_remove(port->debugfs_file);
|
|
|
+ kfree(port->name);
|
|
|
|
|
|
/*
|
|
|
* Locks around here are not necessary - a port can't be
|
|
@@ -1681,7 +1686,9 @@ static void handle_control_message(struct ports_device *portdev,
|
|
|
* If the guest is connected, it'll be interested in
|
|
|
* knowing the host connection state changed.
|
|
|
*/
|
|
|
+ spin_lock_irq(&port->inbuf_lock);
|
|
|
send_sigio_to_port(port);
|
|
|
+ spin_unlock_irq(&port->inbuf_lock);
|
|
|
break;
|
|
|
case VIRTIO_CONSOLE_PORT_NAME:
|
|
|
/*
|
|
@@ -1801,13 +1808,13 @@ static void in_intr(struct virtqueue *vq)
|
|
|
if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev))
|
|
|
discard_port_data(port);
|
|
|
|
|
|
+ /* Send a SIGIO indicating new data in case the process asked for it */
|
|
|
+ send_sigio_to_port(port);
|
|
|
+
|
|
|
spin_unlock_irqrestore(&port->inbuf_lock, flags);
|
|
|
|
|
|
wake_up_interruptible(&port->waitqueue);
|
|
|
|
|
|
- /* Send a SIGIO indicating new data in case the process asked for it */
|
|
|
- send_sigio_to_port(port);
|
|
|
-
|
|
|
if (is_console_port(port) && hvc_poll(port->cons.hvc))
|
|
|
hvc_kick();
|
|
|
}
|
|
@@ -2241,10 +2248,8 @@ static int __init init(void)
|
|
|
}
|
|
|
|
|
|
pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL);
|
|
|
- if (!pdrvdata.debugfs_dir) {
|
|
|
- pr_warning("Error %ld creating debugfs dir for virtio-ports\n",
|
|
|
- PTR_ERR(pdrvdata.debugfs_dir));
|
|
|
- }
|
|
|
+ if (!pdrvdata.debugfs_dir)
|
|
|
+ pr_warning("Error creating debugfs dir for virtio-ports\n");
|
|
|
INIT_LIST_HEAD(&pdrvdata.consoles);
|
|
|
INIT_LIST_HEAD(&pdrvdata.portdevs);
|
|
|
|