aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2013-08-08 23:30:39 -0400
committerRusty Russell <rusty@rustcorp.com.au>2013-08-08 23:30:39 -0400
commit11489736177c5930514482b4db7af862d945335d (patch)
tree8590ec4ba037b79c94982e15922fe50a1f0193a3 /drivers/char
parent3f0d0c9b47e09d47fcb755fed786a1ee88e110b5 (diff)
parent6c2580c501c660fdfb506061e016d84570fceba1 (diff)
Merge branch 'master' into virtio-next
The next commit gets conflicts because it relies on patches which were cc:stable and thus had to be merged into Linus' tree before the coming merge window. So pull in master now. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/parisc-agp.c6
-rw-r--r--drivers/char/virtio_console.c70
2 files changed, 52 insertions, 24 deletions
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index bf5d2477cb77..15f2e7025b78 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -129,7 +129,8 @@ parisc_agp_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
129 off_t j, io_pg_start; 129 off_t j, io_pg_start;
130 int io_pg_count; 130 int io_pg_count;
131 131
132 if (type != 0 || mem->type != 0) { 132 if (type != mem->type ||
133 agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
133 return -EINVAL; 134 return -EINVAL;
134 } 135 }
135 136
@@ -175,7 +176,8 @@ parisc_agp_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
175 struct _parisc_agp_info *info = &parisc_agp_info; 176 struct _parisc_agp_info *info = &parisc_agp_info;
176 int i, io_pg_start, io_pg_count; 177 int i, io_pg_start, io_pg_count;
177 178
178 if (type != 0 || mem->type != 0) { 179 if (type != mem->type ||
180 agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
179 return -EINVAL; 181 return -EINVAL;
180 } 182 }
181 183
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 5b60956edc28..d0e75aa904ac 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -272,9 +272,12 @@ static struct port *find_port_by_devt_in_portdev(struct ports_device *portdev,
272 unsigned long flags; 272 unsigned long flags;
273 273
274 spin_lock_irqsave(&portdev->ports_lock, flags); 274 spin_lock_irqsave(&portdev->ports_lock, flags);
275 list_for_each_entry(port, &portdev->ports, list) 275 list_for_each_entry(port, &portdev->ports, list) {
276 if (port->cdev->dev == dev) 276 if (port->cdev->dev == dev) {
277 kref_get(&port->kref);
277 goto out; 278 goto out;
279 }
280 }
278 port = NULL; 281 port = NULL;
279out: 282out:
280 spin_unlock_irqrestore(&portdev->ports_lock, flags); 283 spin_unlock_irqrestore(&portdev->ports_lock, flags);
@@ -746,6 +749,10 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf,
746 749
747 port = filp->private_data; 750 port = filp->private_data;
748 751
752 /* Port is hot-unplugged. */
753 if (!port->guest_connected)
754 return -ENODEV;
755
749 if (!port_has_data(port)) { 756 if (!port_has_data(port)) {
750 /* 757 /*
751 * If nothing's connected on the host just return 0 in 758 * If nothing's connected on the host just return 0 in
@@ -762,7 +769,7 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf,
762 if (ret < 0) 769 if (ret < 0)
763 return ret; 770 return ret;
764 } 771 }
765 /* Port got hot-unplugged. */ 772 /* Port got hot-unplugged while we were waiting above. */
766 if (!port->guest_connected) 773 if (!port->guest_connected)
767 return -ENODEV; 774 return -ENODEV;
768 /* 775 /*
@@ -932,13 +939,25 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
932 if (is_rproc_serial(port->out_vq->vdev)) 939 if (is_rproc_serial(port->out_vq->vdev))
933 return -EINVAL; 940 return -EINVAL;
934 941
942 /*
943 * pipe->nrbufs == 0 means there are no data to transfer,
944 * so this returns just 0 for no data.
945 */
946 pipe_lock(pipe);
947 if (!pipe->nrbufs) {
948 ret = 0;
949 goto error_out;
950 }
951
935 ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK); 952 ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK);
936 if (ret < 0) 953 if (ret < 0)
937 return ret; 954 goto error_out;
938 955
939 buf = alloc_buf(port->out_vq, 0, pipe->nrbufs); 956 buf = alloc_buf(port->out_vq, 0, pipe->nrbufs);
940 if (!buf) 957 if (!buf) {
941 return -ENOMEM; 958 ret = -ENOMEM;
959 goto error_out;
960 }
942 961
943 sgl.n = 0; 962 sgl.n = 0;
944 sgl.len = 0; 963 sgl.len = 0;
@@ -946,12 +965,17 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
946 sgl.sg = buf->sg; 965 sgl.sg = buf->sg;
947 sg_init_table(sgl.sg, sgl.size); 966 sg_init_table(sgl.sg, sgl.size);
948 ret = __splice_from_pipe(pipe, &sd, pipe_to_sg); 967 ret = __splice_from_pipe(pipe, &sd, pipe_to_sg);
968 pipe_unlock(pipe);
949 if (likely(ret > 0)) 969 if (likely(ret > 0))
950 ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true); 970 ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true);
951 971
952 if (unlikely(ret <= 0)) 972 if (unlikely(ret <= 0))
953 free_buf(buf, true); 973 free_buf(buf, true);
954 return ret; 974 return ret;
975
976error_out:
977 pipe_unlock(pipe);
978 return ret;
955} 979}
956 980
957static unsigned int port_fops_poll(struct file *filp, poll_table *wait) 981static unsigned int port_fops_poll(struct file *filp, poll_table *wait)
@@ -1019,14 +1043,14 @@ static int port_fops_open(struct inode *inode, struct file *filp)
1019 struct port *port; 1043 struct port *port;
1020 int ret; 1044 int ret;
1021 1045
1046 /* We get the port with a kref here */
1022 port = find_port_by_devt(cdev->dev); 1047 port = find_port_by_devt(cdev->dev);
1048 if (!port) {
1049 /* Port was unplugged before we could proceed */
1050 return -ENXIO;
1051 }
1023 filp->private_data = port; 1052 filp->private_data = port;
1024 1053
1025 /* Prevent against a port getting hot-unplugged at the same time */
1026 spin_lock_irq(&port->portdev->ports_lock);
1027 kref_get(&port->kref);
1028 spin_unlock_irq(&port->portdev->ports_lock);
1029
1030 /* 1054 /*
1031 * Don't allow opening of console port devices -- that's done 1055 * Don't allow opening of console port devices -- that's done
1032 * via /dev/hvc 1056 * via /dev/hvc
@@ -1498,14 +1522,6 @@ static void remove_port(struct kref *kref)
1498 1522
1499 port = container_of(kref, struct port, kref); 1523 port = container_of(kref, struct port, kref);
1500 1524
1501 sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
1502 device_destroy(pdrvdata.class, port->dev->devt);
1503 cdev_del(port->cdev);
1504
1505 kfree(port->name);
1506
1507 debugfs_remove(port->debugfs_file);
1508
1509 kfree(port); 1525 kfree(port);
1510} 1526}
1511 1527
@@ -1544,12 +1560,14 @@ static void unplug_port(struct port *port)
1544 1560
1545 spin_lock_irq(&port->inbuf_lock); 1561 spin_lock_irq(&port->inbuf_lock);
1546 if (port->guest_connected) { 1562 if (port->guest_connected) {
1563 /* Let the app know the port is going down. */
1564 send_sigio_to_port(port);
1565
1566 /* Do this after sigio is actually sent */
1547 port->guest_connected = false; 1567 port->guest_connected = false;
1548 port->host_connected = false; 1568 port->host_connected = false;
1549 wake_up_interruptible(&port->waitqueue);
1550 1569
1551 /* Let the app know the port is going down. */ 1570 wake_up_interruptible(&port->waitqueue);
1552 send_sigio_to_port(port);
1553 } 1571 }
1554 spin_unlock_irq(&port->inbuf_lock); 1572 spin_unlock_irq(&port->inbuf_lock);
1555 1573
@@ -1569,6 +1587,14 @@ static void unplug_port(struct port *port)
1569 */ 1587 */
1570 port->portdev = NULL; 1588 port->portdev = NULL;
1571 1589
1590 sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
1591 device_destroy(pdrvdata.class, port->dev->devt);
1592 cdev_del(port->cdev);
1593
1594 kfree(port->name);
1595
1596 debugfs_remove(port->debugfs_file);
1597
1572 /* 1598 /*
1573 * Locks around here are not necessary - a port can't be 1599 * Locks around here are not necessary - a port can't be
1574 * opened after we removed the port struct from ports_list 1600 * opened after we removed the port struct from ports_list