summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-05-02 21:50:50 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-05-02 21:50:50 +1000
commitc45a6816c19dee67b8f725e6646d428901a6dc24 (patch)
tree096e3263fd14e140685bcc3082394ff15f5aeddb /drivers/block
parent72e61eb40b55dd57031ec5971e810649f82b0259 (diff)
downloadlinux-c45a6816c19dee67b8f725e6646d428901a6dc24.tar.gz
linux-c45a6816c19dee67b8f725e6646d428901a6dc24.tar.bz2
linux-c45a6816c19dee67b8f725e6646d428901a6dc24.zip
virtio: explicit advertisement of driver features
A recent proposed feature addition to the virtio block driver revealed some flaws in the API: in particular, we assume that feature negotiation is complete once a driver's probe function returns. There is nothing in the API to require this, however, and even I didn't notice when it was violated. So instead, we require the driver to specify what features it supports in a table, we can then move the feature negotiation into the virtio core. The intersection of device and driver features are presented in a new 'features' bitmap in the struct virtio_device. Note that this highlights the difference between Linux unsigned-long bitmaps where each unsigned long is in native endian, and a straight-forward little-endian array of bytes. Drivers can still remove feature bits in their probe routine if they really have to. API changes: - dev->config->feature() no longer gets and acks a feature. - drivers should advertise their features in the 'feature_table' field - use virtio_has_feature() for extra sanity when checking feature bits Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/virtio_blk.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index cc6d39383a3f..78be6b8c89e0 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -242,7 +242,7 @@ static int virtblk_probe(struct virtio_device *vdev)
index++;
/* If barriers are supported, tell block layer that queue is ordered */
- if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER))
+ if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER))
blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL);
/* Host must always specify the capacity. */
@@ -308,7 +308,13 @@ static struct virtio_device_id id_table[] = {
{ 0 },
};
+static unsigned int features[] = {
+ VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
+};
+
static struct virtio_driver virtio_blk = {
+ .feature_table = features,
+ .feature_table_size = ARRAY_SIZE(features),
.driver.name = KBUILD_MODNAME,
.driver.owner = THIS_MODULE,
.id_table = id_table,