summaryrefslogtreecommitdiffstats
path: root/drivers/virtio
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2014-10-22 16:41:38 +0200
committerMichael S. Tsirkin <mst@redhat.com>2014-12-09 11:05:25 +0100
commitcb3f6d9da49929797f806b4e91ec005e6fc2e9c2 (patch)
treee345a69f99132bf1a88340229610e51d36cd5ecf /drivers/virtio
parentvirtio: allow transports to get avail/used addresses (diff)
downloadlinux-cb3f6d9da49929797f806b4e91ec005e6fc2e9c2.tar.xz
linux-cb3f6d9da49929797f806b4e91ec005e6fc2e9c2.zip
virtio: set FEATURES_OK
set FEATURES_OK as per virtio 1.0 spec Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'drivers/virtio')
-rw-r--r--drivers/virtio/virtio.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 746d350c8062..9248125d29c9 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -160,6 +160,7 @@ static int virtio_dev_probe(struct device *_d)
struct virtio_device *dev = dev_to_virtio(_d);
struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
u64 device_features;
+ unsigned status;
/* We have a driver! */
add_status(dev, VIRTIO_CONFIG_S_DRIVER);
@@ -183,18 +184,32 @@ static int virtio_dev_probe(struct device *_d)
dev->config->finalize_features(dev);
+ if (virtio_has_feature(dev, VIRTIO_F_VERSION_1)) {
+ add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
+ status = dev->config->get_status(dev);
+ if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
+ dev_err(_d, "virtio: device refuses features: %x\n",
+ status);
+ err = -ENODEV;
+ goto err;
+ }
+ }
+
err = drv->probe(dev);
if (err)
- add_status(dev, VIRTIO_CONFIG_S_FAILED);
- else {
- add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
- if (drv->scan)
- drv->scan(dev);
+ goto err;
- virtio_config_enable(dev);
- }
+ add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
+ if (drv->scan)
+ drv->scan(dev);
+
+ virtio_config_enable(dev);
+ return 0;
+err:
+ add_status(dev, VIRTIO_CONFIG_S_FAILED);
return err;
+
}
static int virtio_dev_remove(struct device *_d)