mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-03 17:14:14 +08:00
virtio: console: Move code around for future patches
We're going to use add_port() from handle_control_message() in the next patch. Move the add_port() and fill_queue(), which depends on it, above handle_control_message() to avoid forward declarations. Signed-off-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
99f905f88a
commit
c446f8fcc9
@ -855,6 +855,139 @@ static const struct file_operations port_debugfs_ops = {
|
||||
.read = debugfs_read,
|
||||
};
|
||||
|
||||
static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
|
||||
{
|
||||
struct port_buffer *buf;
|
||||
unsigned int nr_added_bufs;
|
||||
int ret;
|
||||
|
||||
nr_added_bufs = 0;
|
||||
do {
|
||||
buf = alloc_buf(PAGE_SIZE);
|
||||
if (!buf)
|
||||
break;
|
||||
|
||||
spin_lock_irq(lock);
|
||||
ret = add_inbuf(vq, buf);
|
||||
if (ret < 0) {
|
||||
spin_unlock_irq(lock);
|
||||
free_buf(buf);
|
||||
break;
|
||||
}
|
||||
nr_added_bufs++;
|
||||
spin_unlock_irq(lock);
|
||||
} while (ret > 0);
|
||||
|
||||
return nr_added_bufs;
|
||||
}
|
||||
|
||||
static int add_port(struct ports_device *portdev, u32 id)
|
||||
{
|
||||
char debugfs_name[16];
|
||||
struct port *port;
|
||||
struct port_buffer *buf;
|
||||
dev_t devt;
|
||||
unsigned int nr_added_bufs;
|
||||
int err;
|
||||
|
||||
port = kmalloc(sizeof(*port), GFP_KERNEL);
|
||||
if (!port) {
|
||||
err = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
port->portdev = portdev;
|
||||
port->id = id;
|
||||
|
||||
port->name = NULL;
|
||||
port->inbuf = NULL;
|
||||
port->cons.hvc = NULL;
|
||||
|
||||
port->host_connected = port->guest_connected = false;
|
||||
|
||||
port->in_vq = portdev->in_vqs[port->id];
|
||||
port->out_vq = portdev->out_vqs[port->id];
|
||||
|
||||
cdev_init(&port->cdev, &port_fops);
|
||||
|
||||
devt = MKDEV(portdev->chr_major, id);
|
||||
err = cdev_add(&port->cdev, devt, 1);
|
||||
if (err < 0) {
|
||||
dev_err(&port->portdev->vdev->dev,
|
||||
"Error %d adding cdev for port %u\n", err, id);
|
||||
goto free_port;
|
||||
}
|
||||
port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev,
|
||||
devt, port, "vport%up%u",
|
||||
port->portdev->drv_index, id);
|
||||
if (IS_ERR(port->dev)) {
|
||||
err = PTR_ERR(port->dev);
|
||||
dev_err(&port->portdev->vdev->dev,
|
||||
"Error %d creating device for port %u\n",
|
||||
err, id);
|
||||
goto free_cdev;
|
||||
}
|
||||
|
||||
spin_lock_init(&port->inbuf_lock);
|
||||
init_waitqueue_head(&port->waitqueue);
|
||||
|
||||
/* Fill the in_vq with buffers so the host can send us data. */
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're not using multiport support, this has to be a console port
|
||||
*/
|
||||
if (!use_multiport(port->portdev)) {
|
||||
err = init_port_console(port);
|
||||
if (err)
|
||||
goto free_inbufs;
|
||||
}
|
||||
|
||||
spin_lock_irq(&portdev->ports_lock);
|
||||
list_add_tail(&port->list, &port->portdev->ports);
|
||||
spin_unlock_irq(&portdev->ports_lock);
|
||||
|
||||
/*
|
||||
* Tell the Host we're set so that it can send us various
|
||||
* configuration parameters for this port (eg, port name,
|
||||
* caching, whether this is a console port, etc.)
|
||||
*/
|
||||
send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
|
||||
|
||||
if (pdrvdata.debugfs_dir) {
|
||||
/*
|
||||
* Finally, create the debugfs file that we can use to
|
||||
* inspect a port's state at any time
|
||||
*/
|
||||
sprintf(debugfs_name, "vport%up%u",
|
||||
port->portdev->drv_index, id);
|
||||
port->debugfs_file = debugfs_create_file(debugfs_name, 0444,
|
||||
pdrvdata.debugfs_dir,
|
||||
port,
|
||||
&port_debugfs_ops);
|
||||
}
|
||||
return 0;
|
||||
|
||||
free_inbufs:
|
||||
while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
|
||||
free_buf(buf);
|
||||
free_device:
|
||||
device_destroy(pdrvdata.class, port->dev->devt);
|
||||
free_cdev:
|
||||
cdev_del(&port->cdev);
|
||||
free_port:
|
||||
kfree(port);
|
||||
fail:
|
||||
/* The host might want to notify management sw about port add failure */
|
||||
send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 0);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Remove all port-specific data. */
|
||||
static int remove_port(struct port *port)
|
||||
{
|
||||
@ -1093,139 +1226,6 @@ static void config_intr(struct virtio_device *vdev)
|
||||
resize_console(find_port_by_id(portdev, 0));
|
||||
}
|
||||
|
||||
static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
|
||||
{
|
||||
struct port_buffer *buf;
|
||||
unsigned int nr_added_bufs;
|
||||
int ret;
|
||||
|
||||
nr_added_bufs = 0;
|
||||
do {
|
||||
buf = alloc_buf(PAGE_SIZE);
|
||||
if (!buf)
|
||||
break;
|
||||
|
||||
spin_lock_irq(lock);
|
||||
ret = add_inbuf(vq, buf);
|
||||
if (ret < 0) {
|
||||
spin_unlock_irq(lock);
|
||||
free_buf(buf);
|
||||
break;
|
||||
}
|
||||
nr_added_bufs++;
|
||||
spin_unlock_irq(lock);
|
||||
} while (ret > 0);
|
||||
|
||||
return nr_added_bufs;
|
||||
}
|
||||
|
||||
static int add_port(struct ports_device *portdev, u32 id)
|
||||
{
|
||||
char debugfs_name[16];
|
||||
struct port *port;
|
||||
struct port_buffer *buf;
|
||||
dev_t devt;
|
||||
unsigned int nr_added_bufs;
|
||||
int err;
|
||||
|
||||
port = kmalloc(sizeof(*port), GFP_KERNEL);
|
||||
if (!port) {
|
||||
err = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
port->portdev = portdev;
|
||||
port->id = id;
|
||||
|
||||
port->name = NULL;
|
||||
port->inbuf = NULL;
|
||||
port->cons.hvc = NULL;
|
||||
|
||||
port->host_connected = port->guest_connected = false;
|
||||
|
||||
port->in_vq = portdev->in_vqs[port->id];
|
||||
port->out_vq = portdev->out_vqs[port->id];
|
||||
|
||||
cdev_init(&port->cdev, &port_fops);
|
||||
|
||||
devt = MKDEV(portdev->chr_major, id);
|
||||
err = cdev_add(&port->cdev, devt, 1);
|
||||
if (err < 0) {
|
||||
dev_err(&port->portdev->vdev->dev,
|
||||
"Error %d adding cdev for port %u\n", err, id);
|
||||
goto free_port;
|
||||
}
|
||||
port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev,
|
||||
devt, port, "vport%up%u",
|
||||
port->portdev->drv_index, id);
|
||||
if (IS_ERR(port->dev)) {
|
||||
err = PTR_ERR(port->dev);
|
||||
dev_err(&port->portdev->vdev->dev,
|
||||
"Error %d creating device for port %u\n",
|
||||
err, id);
|
||||
goto free_cdev;
|
||||
}
|
||||
|
||||
spin_lock_init(&port->inbuf_lock);
|
||||
init_waitqueue_head(&port->waitqueue);
|
||||
|
||||
/* Fill the in_vq with buffers so the host can send us data. */
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're not using multiport support, this has to be a console port
|
||||
*/
|
||||
if (!use_multiport(port->portdev)) {
|
||||
err = init_port_console(port);
|
||||
if (err)
|
||||
goto free_inbufs;
|
||||
}
|
||||
|
||||
spin_lock_irq(&portdev->ports_lock);
|
||||
list_add_tail(&port->list, &port->portdev->ports);
|
||||
spin_unlock_irq(&portdev->ports_lock);
|
||||
|
||||
/*
|
||||
* Tell the Host we're set so that it can send us various
|
||||
* configuration parameters for this port (eg, port name,
|
||||
* caching, whether this is a console port, etc.)
|
||||
*/
|
||||
send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
|
||||
|
||||
if (pdrvdata.debugfs_dir) {
|
||||
/*
|
||||
* Finally, create the debugfs file that we can use to
|
||||
* inspect a port's state at any time
|
||||
*/
|
||||
sprintf(debugfs_name, "vport%up%u",
|
||||
port->portdev->drv_index, id);
|
||||
port->debugfs_file = debugfs_create_file(debugfs_name, 0444,
|
||||
pdrvdata.debugfs_dir,
|
||||
port,
|
||||
&port_debugfs_ops);
|
||||
}
|
||||
return 0;
|
||||
|
||||
free_inbufs:
|
||||
while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
|
||||
free_buf(buf);
|
||||
free_device:
|
||||
device_destroy(pdrvdata.class, port->dev->devt);
|
||||
free_cdev:
|
||||
cdev_del(&port->cdev);
|
||||
free_port:
|
||||
kfree(port);
|
||||
fail:
|
||||
/* The host might want to notify management sw about port add failure */
|
||||
send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int init_vqs(struct ports_device *portdev)
|
||||
{
|
||||
vq_callback_t **io_callbacks;
|
||||
|
Loading…
Reference in New Issue
Block a user