diff options
Diffstat (limited to 'drivers/virtio/virtio.c')
-rw-r--r-- | drivers/virtio/virtio.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 13866789b356..5b78fd0aff0a 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -2,6 +2,9 @@ #include <linux/spinlock.h> #include <linux/virtio_config.h> +/* Unique numbering for virtio devices. */ +static unsigned int dev_index; + static ssize_t device_show(struct device *_d, struct device_attribute *attr, char *buf) { @@ -68,13 +71,6 @@ static int virtio_uevent(struct device *_dv, struct kobj_uevent_env *env) dev->id.device, dev->id.vendor); } -static struct bus_type virtio_bus = { - .name = "virtio", - .match = virtio_dev_match, - .dev_attrs = virtio_dev_attrs, - .uevent = virtio_uevent, -}; - static void add_status(struct virtio_device *dev, unsigned status) { dev->config->set_status(dev, dev->config->get_status(dev) | status); @@ -117,13 +113,17 @@ static int virtio_dev_probe(struct device *_d) set_bit(f, dev->features); } + /* Transport features always preserved to pass to finalize_features. */ + for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++) + if (device_features & (1 << i)) + set_bit(i, dev->features); + err = drv->probe(dev); if (err) add_status(dev, VIRTIO_CONFIG_S_FAILED); else { + dev->config->finalize_features(dev); add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); - /* They should never have set feature bits beyond 32 */ - dev->config->set_features(dev, dev->features[0]); } return err; } @@ -144,13 +144,20 @@ static int virtio_dev_remove(struct device *_d) return 0; } +static struct bus_type virtio_bus = { + .name = "virtio", + .match = virtio_dev_match, + .dev_attrs = virtio_dev_attrs, + .uevent = virtio_uevent, + .probe = virtio_dev_probe, + .remove = virtio_dev_remove, +}; + int register_virtio_driver(struct virtio_driver *driver) { /* Catch this early. */ BUG_ON(driver->feature_table_size && !driver->feature_table); driver->driver.bus = &virtio_bus; - driver->driver.probe = virtio_dev_probe; - driver->driver.remove = virtio_dev_remove; return driver_register(&driver->driver); } EXPORT_SYMBOL_GPL(register_virtio_driver); @@ -166,7 +173,10 @@ int register_virtio_device(struct virtio_device *dev) int err; dev->dev.bus = &virtio_bus; - sprintf(dev->dev.bus_id, "%u", dev->index); + + /* Assign a unique device index and hence name. */ + dev->index = dev_index++; + sprintf(dev->dev.bus_id, "virtio%u", dev->index); /* We always start by resetting the device, in case a previous * driver messed it up. This also tests that code path a little. */ |