diff options
Diffstat (limited to 'drivers/char/virtio_console.c')
-rw-r--r-- | drivers/char/virtio_console.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 5649234b7316..e9b7e0b3cabe 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -152,8 +152,8 @@ struct ports_device { spinlock_t c_ivq_lock; spinlock_t c_ovq_lock; - /* The current config space is stored here */ - struct virtio_console_config config; + /* max. number of ports this device can hold */ + u32 max_nr_ports; /* The virtio device we're associated with */ struct virtio_device *vdev; @@ -1136,6 +1136,8 @@ static int put_chars(u32 vtermno, const char *buf, int count) { struct port *port; struct scatterlist sg[1]; + void *data; + int ret; if (unlikely(early_put_chars)) return early_put_chars(vtermno, buf, count); @@ -1144,8 +1146,14 @@ static int put_chars(u32 vtermno, const char *buf, int count) if (!port) return -EPIPE; - sg_init_one(sg, buf, count); - return __send_to_port(port, sg, 1, count, (void *)buf, false); + data = kmemdup(buf, count, GFP_ATOMIC); + if (!data) + return -ENOMEM; + + sg_init_one(sg, data, count); + ret = __send_to_port(port, sg, 1, count, data, false); + kfree(data); + return ret; } /* @@ -1649,11 +1657,11 @@ static void handle_control_message(struct virtio_device *vdev, break; } if (virtio32_to_cpu(vdev, cpkt->id) >= - portdev->config.max_nr_ports) { + portdev->max_nr_ports) { dev_warn(&portdev->vdev->dev, "Request for adding port with " "out-of-bound id %u, max. supported id: %u\n", - cpkt->id, portdev->config.max_nr_ports - 1); + cpkt->id, portdev->max_nr_ports - 1); break; } add_port(portdev, virtio32_to_cpu(vdev, cpkt->id)); @@ -1862,7 +1870,7 @@ static void config_work_handler(struct work_struct *work) { struct ports_device *portdev; - portdev = container_of(work, struct ports_device, control_work); + portdev = container_of(work, struct ports_device, config_work); if (!use_multiport(portdev)) { struct virtio_device *vdev; struct port *port; @@ -1894,7 +1902,7 @@ static int init_vqs(struct ports_device *portdev) u32 i, j, nr_ports, nr_queues; int err; - nr_ports = portdev->config.max_nr_ports; + nr_ports = portdev->max_nr_ports; nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2; vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL); @@ -1939,7 +1947,7 @@ static int init_vqs(struct ports_device *portdev) /* Find the queues. */ err = portdev->vdev->config->find_vqs(portdev->vdev, nr_queues, vqs, io_callbacks, - (const char **)io_names); + (const char **)io_names, NULL); if (err) goto free; @@ -2047,13 +2055,13 @@ static int virtcons_probe(struct virtio_device *vdev) } multiport = false; - portdev->config.max_nr_ports = 1; + portdev->max_nr_ports = 1; /* Don't test MULTIPORT at all if we're rproc: not a valid feature! */ if (!is_rproc_serial(vdev) && virtio_cread_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT, struct virtio_console_config, max_nr_ports, - &portdev->config.max_nr_ports) == 0) { + &portdev->max_nr_ports) == 0) { multiport = true; } |