aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio/virtio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/virtio/virtio.c')
-rw-r--r--drivers/virtio/virtio.c34
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. */