Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus: hvc_console: Fix race between hvc_close and hvc_remove virtio: disable multiport console support. virtio: console makes incorrect assumption about virtio API virtio: console: Fix early_put_chars usage MAINTAINERS: Put the virtio-console entry in correct alphabetical order
This commit is contained in:
commit
f5284e7635
4 changed files with 54 additions and 51 deletions
13
MAINTAINERS
13
MAINTAINERS
|
@ -2474,12 +2474,6 @@ L: linuxppc-dev@ozlabs.org
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
F: drivers/char/hvc_*
|
F: drivers/char/hvc_*
|
||||||
|
|
||||||
VIRTIO CONSOLE DRIVER
|
|
||||||
M: Amit Shah <amit.shah@redhat.com>
|
|
||||||
L: virtualization@lists.linux-foundation.org
|
|
||||||
S: Maintained
|
|
||||||
F: drivers/char/virtio_console.c
|
|
||||||
|
|
||||||
iSCSI BOOT FIRMWARE TABLE (iBFT) DRIVER
|
iSCSI BOOT FIRMWARE TABLE (iBFT) DRIVER
|
||||||
M: Peter Jones <pjones@redhat.com>
|
M: Peter Jones <pjones@redhat.com>
|
||||||
M: Konrad Rzeszutek Wilk <konrad@kernel.org>
|
M: Konrad Rzeszutek Wilk <konrad@kernel.org>
|
||||||
|
@ -5971,6 +5965,13 @@ S: Maintained
|
||||||
F: Documentation/filesystems/vfat.txt
|
F: Documentation/filesystems/vfat.txt
|
||||||
F: fs/fat/
|
F: fs/fat/
|
||||||
|
|
||||||
|
VIRTIO CONSOLE DRIVER
|
||||||
|
M: Amit Shah <amit.shah@redhat.com>
|
||||||
|
L: virtualization@lists.linux-foundation.org
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/char/virtio_console.c
|
||||||
|
F: include/linux/virtio_console.h
|
||||||
|
|
||||||
VIRTIO HOST (VHOST)
|
VIRTIO HOST (VHOST)
|
||||||
M: "Michael S. Tsirkin" <mst@redhat.com>
|
M: "Michael S. Tsirkin" <mst@redhat.com>
|
||||||
L: kvm@vger.kernel.org
|
L: kvm@vger.kernel.org
|
||||||
|
|
|
@ -368,16 +368,12 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
|
||||||
hp = tty->driver_data;
|
hp = tty->driver_data;
|
||||||
|
|
||||||
spin_lock_irqsave(&hp->lock, flags);
|
spin_lock_irqsave(&hp->lock, flags);
|
||||||
tty_kref_get(tty);
|
|
||||||
|
|
||||||
if (--hp->count == 0) {
|
if (--hp->count == 0) {
|
||||||
/* We are done with the tty pointer now. */
|
/* We are done with the tty pointer now. */
|
||||||
hp->tty = NULL;
|
hp->tty = NULL;
|
||||||
spin_unlock_irqrestore(&hp->lock, flags);
|
spin_unlock_irqrestore(&hp->lock, flags);
|
||||||
|
|
||||||
/* Put the ref obtained in hvc_open() */
|
|
||||||
tty_kref_put(tty);
|
|
||||||
|
|
||||||
if (hp->ops->notifier_del)
|
if (hp->ops->notifier_del)
|
||||||
hp->ops->notifier_del(hp, hp->data);
|
hp->ops->notifier_del(hp, hp->data);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,35 @@
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include "hvc_console.h"
|
#include "hvc_console.h"
|
||||||
|
|
||||||
|
/* Moved here from .h file in order to disable MULTIPORT. */
|
||||||
|
#define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */
|
||||||
|
|
||||||
|
struct virtio_console_multiport_conf {
|
||||||
|
struct virtio_console_config config;
|
||||||
|
/* max. number of ports this device can hold */
|
||||||
|
__u32 max_nr_ports;
|
||||||
|
/* number of ports added so far */
|
||||||
|
__u32 nr_ports;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A message that's passed between the Host and the Guest for a
|
||||||
|
* particular port.
|
||||||
|
*/
|
||||||
|
struct virtio_console_control {
|
||||||
|
__u32 id; /* Port number */
|
||||||
|
__u16 event; /* The kind of control event (see below) */
|
||||||
|
__u16 value; /* Extra information for the key */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Some events for control messages */
|
||||||
|
#define VIRTIO_CONSOLE_PORT_READY 0
|
||||||
|
#define VIRTIO_CONSOLE_CONSOLE_PORT 1
|
||||||
|
#define VIRTIO_CONSOLE_RESIZE 2
|
||||||
|
#define VIRTIO_CONSOLE_PORT_OPEN 3
|
||||||
|
#define VIRTIO_CONSOLE_PORT_NAME 4
|
||||||
|
#define VIRTIO_CONSOLE_PORT_REMOVE 5
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a global struct for storing common data for all the devices
|
* This is a global struct for storing common data for all the devices
|
||||||
* this driver handles.
|
* this driver handles.
|
||||||
|
@ -121,7 +150,7 @@ struct ports_device {
|
||||||
spinlock_t cvq_lock;
|
spinlock_t cvq_lock;
|
||||||
|
|
||||||
/* The current config space is stored here */
|
/* The current config space is stored here */
|
||||||
struct virtio_console_config config;
|
struct virtio_console_multiport_conf config;
|
||||||
|
|
||||||
/* The virtio device we're associated with */
|
/* The virtio device we're associated with */
|
||||||
struct virtio_device *vdev;
|
struct virtio_device *vdev;
|
||||||
|
@ -416,20 +445,16 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count)
|
||||||
out_vq->vq_ops->kick(out_vq);
|
out_vq->vq_ops->kick(out_vq);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
len = 0;
|
in_count = 0;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Wait till the host acknowledges it pushed out the data we sent. */
|
||||||
* Wait till the host acknowledges it pushed out the data we
|
|
||||||
* sent. Also ensure we return to userspace the number of
|
|
||||||
* bytes that were successfully consumed by the host.
|
|
||||||
*/
|
|
||||||
while (!out_vq->vq_ops->get_buf(out_vq, &len))
|
while (!out_vq->vq_ops->get_buf(out_vq, &len))
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
fail:
|
fail:
|
||||||
/* We're expected to return the amount of data we wrote */
|
/* We're expected to return the amount of data we wrote */
|
||||||
return len;
|
return in_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -646,13 +671,13 @@ static int put_chars(u32 vtermno, const char *buf, int count)
|
||||||
{
|
{
|
||||||
struct port *port;
|
struct port *port;
|
||||||
|
|
||||||
|
if (unlikely(early_put_chars))
|
||||||
|
return early_put_chars(vtermno, buf, count);
|
||||||
|
|
||||||
port = find_port_by_vtermno(vtermno);
|
port = find_port_by_vtermno(vtermno);
|
||||||
if (!port)
|
if (!port)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (unlikely(early_put_chars))
|
|
||||||
return early_put_chars(vtermno, buf, count);
|
|
||||||
|
|
||||||
return send_buf(port, (void *)buf, count);
|
return send_buf(port, (void *)buf, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1218,7 +1243,7 @@ static int add_port(struct ports_device *portdev, u32 id)
|
||||||
*/
|
*/
|
||||||
static void config_work_handler(struct work_struct *work)
|
static void config_work_handler(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct virtio_console_config virtconconf;
|
struct virtio_console_multiport_conf virtconconf;
|
||||||
struct ports_device *portdev;
|
struct ports_device *portdev;
|
||||||
struct virtio_device *vdev;
|
struct virtio_device *vdev;
|
||||||
int err;
|
int err;
|
||||||
|
@ -1227,7 +1252,8 @@ static void config_work_handler(struct work_struct *work)
|
||||||
|
|
||||||
vdev = portdev->vdev;
|
vdev = portdev->vdev;
|
||||||
vdev->config->get(vdev,
|
vdev->config->get(vdev,
|
||||||
offsetof(struct virtio_console_config, nr_ports),
|
offsetof(struct virtio_console_multiport_conf,
|
||||||
|
nr_ports),
|
||||||
&virtconconf.nr_ports,
|
&virtconconf.nr_ports,
|
||||||
sizeof(virtconconf.nr_ports));
|
sizeof(virtconconf.nr_ports));
|
||||||
|
|
||||||
|
@ -1419,16 +1445,19 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
|
||||||
multiport = false;
|
multiport = false;
|
||||||
portdev->config.nr_ports = 1;
|
portdev->config.nr_ports = 1;
|
||||||
portdev->config.max_nr_ports = 1;
|
portdev->config.max_nr_ports = 1;
|
||||||
|
#if 0 /* Multiport is not quite ready yet --RR */
|
||||||
if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) {
|
if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) {
|
||||||
multiport = true;
|
multiport = true;
|
||||||
vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT;
|
vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT;
|
||||||
|
|
||||||
vdev->config->get(vdev, offsetof(struct virtio_console_config,
|
vdev->config->get(vdev,
|
||||||
nr_ports),
|
offsetof(struct virtio_console_multiport_conf,
|
||||||
|
nr_ports),
|
||||||
&portdev->config.nr_ports,
|
&portdev->config.nr_ports,
|
||||||
sizeof(portdev->config.nr_ports));
|
sizeof(portdev->config.nr_ports));
|
||||||
vdev->config->get(vdev, offsetof(struct virtio_console_config,
|
vdev->config->get(vdev,
|
||||||
max_nr_ports),
|
offsetof(struct virtio_console_multiport_conf,
|
||||||
|
max_nr_ports),
|
||||||
&portdev->config.max_nr_ports,
|
&portdev->config.max_nr_ports,
|
||||||
sizeof(portdev->config.max_nr_ports));
|
sizeof(portdev->config.max_nr_ports));
|
||||||
if (portdev->config.nr_ports > portdev->config.max_nr_ports) {
|
if (portdev->config.nr_ports > portdev->config.max_nr_ports) {
|
||||||
|
@ -1444,6 +1473,7 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
|
||||||
|
|
||||||
/* Let the Host know we support multiple ports.*/
|
/* Let the Host know we support multiple ports.*/
|
||||||
vdev->config->finalize_features(vdev);
|
vdev->config->finalize_features(vdev);
|
||||||
|
#endif
|
||||||
|
|
||||||
err = init_vqs(portdev);
|
err = init_vqs(portdev);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
@ -1526,7 +1556,6 @@ static struct virtio_device_id id_table[] = {
|
||||||
|
|
||||||
static unsigned int features[] = {
|
static unsigned int features[] = {
|
||||||
VIRTIO_CONSOLE_F_SIZE,
|
VIRTIO_CONSOLE_F_SIZE,
|
||||||
VIRTIO_CONSOLE_F_MULTIPORT,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct virtio_driver virtio_console = {
|
static struct virtio_driver virtio_console = {
|
||||||
|
|
|
@ -12,37 +12,14 @@
|
||||||
|
|
||||||
/* Feature bits */
|
/* Feature bits */
|
||||||
#define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */
|
#define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */
|
||||||
#define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */
|
|
||||||
|
|
||||||
struct virtio_console_config {
|
struct virtio_console_config {
|
||||||
/* colums of the screens */
|
/* colums of the screens */
|
||||||
__u16 cols;
|
__u16 cols;
|
||||||
/* rows of the screens */
|
/* rows of the screens */
|
||||||
__u16 rows;
|
__u16 rows;
|
||||||
/* max. number of ports this device can hold */
|
|
||||||
__u32 max_nr_ports;
|
|
||||||
/* number of ports added so far */
|
|
||||||
__u32 nr_ports;
|
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
/*
|
|
||||||
* A message that's passed between the Host and the Guest for a
|
|
||||||
* particular port.
|
|
||||||
*/
|
|
||||||
struct virtio_console_control {
|
|
||||||
__u32 id; /* Port number */
|
|
||||||
__u16 event; /* The kind of control event (see below) */
|
|
||||||
__u16 value; /* Extra information for the key */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Some events for control messages */
|
|
||||||
#define VIRTIO_CONSOLE_PORT_READY 0
|
|
||||||
#define VIRTIO_CONSOLE_CONSOLE_PORT 1
|
|
||||||
#define VIRTIO_CONSOLE_RESIZE 2
|
|
||||||
#define VIRTIO_CONSOLE_PORT_OPEN 3
|
|
||||||
#define VIRTIO_CONSOLE_PORT_NAME 4
|
|
||||||
#define VIRTIO_CONSOLE_PORT_REMOVE 5
|
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int));
|
int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int));
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
Loading…
Reference in a new issue