diff options
author | Amit Shah <amit.shah@redhat.com> | 2010-09-02 09:17:52 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-10-21 03:14:03 -0400 |
commit | 3eae0adea949d8fdd8fa3e5301192901219d2c64 (patch) | |
tree | 4b37348c448a77e1b6670e67e571a8eda4da9d8d /drivers/char/virtio_console.c | |
parent | e062013c7d22e40ee634b818d28fd615db36998e (diff) |
virtio: console: Send SIGIO to processes that request it for host events
A process can request for SIGIO on host connect / disconnect events
using the O_ASYNC file flag using fcntl().
If that's requested, and if the guest-side connection for the port is
open, any host-side open/close events for that port will raise a SIGIO.
The process can then use poll() within the signal handler to find out
which port triggered the signal.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/char/virtio_console.c')
-rw-r--r-- | drivers/char/virtio_console.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index c84486b3e43d..c4ca43694233 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -196,6 +196,9 @@ struct port { | |||
196 | /* The 'name' of the port that we expose via sysfs properties */ | 196 | /* The 'name' of the port that we expose via sysfs properties */ |
197 | char *name; | 197 | char *name; |
198 | 198 | ||
199 | /* We can notify apps of host connect / disconnect events via SIGIO */ | ||
200 | struct fasync_struct *async_queue; | ||
201 | |||
199 | /* The 'id' to identify the port with the Host */ | 202 | /* The 'id' to identify the port with the Host */ |
200 | u32 id; | 203 | u32 id; |
201 | 204 | ||
@@ -815,6 +818,14 @@ out: | |||
815 | return ret; | 818 | return ret; |
816 | } | 819 | } |
817 | 820 | ||
821 | static int port_fops_fasync(int fd, struct file *filp, int mode) | ||
822 | { | ||
823 | struct port *port; | ||
824 | |||
825 | port = filp->private_data; | ||
826 | return fasync_helper(fd, filp, mode, &port->async_queue); | ||
827 | } | ||
828 | |||
818 | /* | 829 | /* |
819 | * The file operations that we support: programs in the guest can open | 830 | * The file operations that we support: programs in the guest can open |
820 | * a console device, read from it, write to it, poll for data and | 831 | * a console device, read from it, write to it, poll for data and |
@@ -828,6 +839,7 @@ static const struct file_operations port_fops = { | |||
828 | .write = port_fops_write, | 839 | .write = port_fops_write, |
829 | .poll = port_fops_poll, | 840 | .poll = port_fops_poll, |
830 | .release = port_fops_release, | 841 | .release = port_fops_release, |
842 | .fasync = port_fops_fasync, | ||
831 | }; | 843 | }; |
832 | 844 | ||
833 | /* | 845 | /* |
@@ -1086,6 +1098,12 @@ static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock) | |||
1086 | return nr_added_bufs; | 1098 | return nr_added_bufs; |
1087 | } | 1099 | } |
1088 | 1100 | ||
1101 | static void send_sigio_to_port(struct port *port) | ||
1102 | { | ||
1103 | if (port->async_queue && port->guest_connected) | ||
1104 | kill_fasync(&port->async_queue, SIGIO, POLL_OUT); | ||
1105 | } | ||
1106 | |||
1089 | static int add_port(struct ports_device *portdev, u32 id) | 1107 | static int add_port(struct ports_device *portdev, u32 id) |
1090 | { | 1108 | { |
1091 | char debugfs_name[16]; | 1109 | char debugfs_name[16]; |
@@ -1108,6 +1126,7 @@ static int add_port(struct ports_device *portdev, u32 id) | |||
1108 | port->name = NULL; | 1126 | port->name = NULL; |
1109 | port->inbuf = NULL; | 1127 | port->inbuf = NULL; |
1110 | port->cons.hvc = NULL; | 1128 | port->cons.hvc = NULL; |
1129 | port->async_queue = NULL; | ||
1111 | 1130 | ||
1112 | port->cons.ws.ws_row = port->cons.ws.ws_col = 0; | 1131 | port->cons.ws.ws_row = port->cons.ws.ws_col = 0; |
1113 | 1132 | ||
@@ -1362,6 +1381,12 @@ static void handle_control_message(struct ports_device *portdev, | |||
1362 | spin_lock_irq(&port->outvq_lock); | 1381 | spin_lock_irq(&port->outvq_lock); |
1363 | reclaim_consumed_buffers(port); | 1382 | reclaim_consumed_buffers(port); |
1364 | spin_unlock_irq(&port->outvq_lock); | 1383 | spin_unlock_irq(&port->outvq_lock); |
1384 | |||
1385 | /* | ||
1386 | * If the guest is connected, it'll be interested in | ||
1387 | * knowing the host connection state changed. | ||
1388 | */ | ||
1389 | send_sigio_to_port(port); | ||
1365 | break; | 1390 | break; |
1366 | case VIRTIO_CONSOLE_PORT_NAME: | 1391 | case VIRTIO_CONSOLE_PORT_NAME: |
1367 | /* | 1392 | /* |