Getting config information is done in probe() as well as config_work_handler(). Separate it out so that we only code it once. Signed-off-by: Amit Shah <amit.shah@xxxxxxxxxx> --- drivers/char/virtio_console.c | 85 +++++++++++++++++++++++------------------ 1 files changed, 48 insertions(+), 37 deletions(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index dc15c92..9f2cbf0 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1227,6 +1227,46 @@ static u32 get_ports_map_size(u32 max_nr_ports) return sizeof(u32) * ((max_nr_ports + 31)/ 32); } +static struct virtio_console_config *get_config(struct virtio_device *vdev, + bool multiport) +{ + struct virtio_console_config *config; + u32 max_nr_ports; + + if (!multiport) { + config = kmalloc(sizeof(struct virtio_console_config), + GFP_KERNEL); + if (!config) + return NULL; + + config->max_nr_ports = 1; + return config; + } + + vdev->config->get(vdev, offsetof(struct virtio_console_config, + max_nr_ports), + &max_nr_ports, sizeof(max_nr_ports)); + + /* + * We have a variable-sized config space that's dependent on + * the maximum number of ports a guest can have. So we first + * get the max number of ports we can have and then allocate + * the config space + */ + config = kmalloc(sizeof(struct virtio_console_config) + + get_ports_map_size(max_nr_ports), + GFP_KERNEL); + if (!config) + return NULL; + + config->max_nr_ports = max_nr_ports; + vdev->config->get(vdev, offsetof(struct virtio_console_config, + ports_map), + config->ports_map, + get_ports_map_size(max_nr_ports)); + return config; +} + /* * The workhandler for config-space updates. * @@ -1394,49 +1434,20 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) goto free; } + multiport = false; if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) { - u32 max_nr_ports; - multiport = true; vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT; - vdev->config->get(vdev, offsetof(struct virtio_console_config, - max_nr_ports), - &max_nr_ports, sizeof(max_nr_ports)); - /* - * We have a variable-sized config space that's - * dependent on the maximum number of ports a guest - * can have. So we first get the max number of ports - * we can have and then allocate the config space - */ - portdev->config = kmalloc(sizeof(struct virtio_console_config) - + get_ports_map_size(max_nr_ports), - GFP_KERNEL); - if (!portdev->config) { - err = -ENOMEM; - goto free_chrdev; - } - - portdev->config->max_nr_ports = max_nr_ports; - vdev->config->get(vdev, offsetof(struct virtio_console_config, - ports_map), - portdev->config->ports_map, - get_ports_map_size(max_nr_ports)); - } else { - multiport = false; - - portdev->config = kmalloc(sizeof(struct virtio_console_config), - GFP_KERNEL); - if (!portdev->config) { - err = -ENOMEM; - goto free_chrdev; - } - - portdev->config->max_nr_ports = 1; + /* Let the Host know we support multiple ports.*/ + vdev->config->finalize_features(vdev); } - /* Let the Host know we support multiple ports.*/ - vdev->config->finalize_features(vdev); + portdev->config = get_config(vdev, multiport); + if (!portdev->config) { + err = -ENOMEM; + goto free_chrdev; + } err = init_vqs(portdev); if (err < 0) { -- 1.6.2.5 _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/virtualization