diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2008-05-02 22:50:50 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2008-05-02 07:50:50 -0400 |
commit | c45a6816c19dee67b8f725e6646d428901a6dc24 (patch) | |
tree | 096e3263fd14e140685bcc3082394ff15f5aeddb /drivers/block | |
parent | 72e61eb40b55dd57031ec5971e810649f82b0259 (diff) |
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.c | 8 |
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) | |||
242 | index++; | 242 | index++; |
243 | 243 | ||
244 | /* If barriers are supported, tell block layer that queue is ordered */ | 244 | /* If barriers are supported, tell block layer that queue is ordered */ |
245 | if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) | 245 | if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) |
246 | blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); | 246 | blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); |
247 | 247 | ||
248 | /* Host must always specify the capacity. */ | 248 | /* Host must always specify the capacity. */ |
@@ -308,7 +308,13 @@ static struct virtio_device_id id_table[] = { | |||
308 | { 0 }, | 308 | { 0 }, |
309 | }; | 309 | }; |
310 | 310 | ||
311 | static unsigned int features[] = { | ||
312 | VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, | ||
313 | }; | ||
314 | |||
311 | static struct virtio_driver virtio_blk = { | 315 | static struct virtio_driver virtio_blk = { |
316 | .feature_table = features, | ||
317 | .feature_table_size = ARRAY_SIZE(features), | ||
312 | .driver.name = KBUILD_MODNAME, | 318 | .driver.name = KBUILD_MODNAME, |
313 | .driver.owner = THIS_MODULE, | 319 | .driver.owner = THIS_MODULE, |
314 | .id_table = id_table, | 320 | .id_table = id_table, |