aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/virtio_config.h
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-05-02 22:50:50 -0400
committerRusty Russell <rusty@rustcorp.com.au>2008-05-02 07:50:50 -0400
commitc45a6816c19dee67b8f725e6646d428901a6dc24 (patch)
tree096e3263fd14e140685bcc3082394ff15f5aeddb /include/linux/virtio_config.h
parent72e61eb40b55dd57031ec5971e810649f82b0259 (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 'include/linux/virtio_config.h')
-rw-r--r--include/linux/virtio_config.h36
1 files changed, 29 insertions, 7 deletions
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 475572e976fe..50db245c81ad 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -20,11 +20,6 @@
20 20
21/** 21/**
22 * virtio_config_ops - operations for configuring a virtio device 22 * virtio_config_ops - operations for configuring a virtio device
23 * @feature: search for a feature in this config
24 * vdev: the virtio_device
25 * bit: the feature bit
26 * Returns true if the feature is supported. Acknowledges the feature
27 * so the host can see it.
28 * @get: read the value of a configuration field 23 * @get: read the value of a configuration field
29 * vdev: the virtio_device 24 * vdev: the virtio_device
30 * offset: the offset of the configuration field 25 * offset: the offset of the configuration field
@@ -50,10 +45,15 @@
50 * callback: the virqtueue callback 45 * callback: the virqtueue callback
51 * Returns the new virtqueue or ERR_PTR() (eg. -ENOENT). 46 * Returns the new virtqueue or ERR_PTR() (eg. -ENOENT).
52 * @del_vq: free a virtqueue found by find_vq(). 47 * @del_vq: free a virtqueue found by find_vq().
48 * @get_features: get the array of feature bits for this device.
49 * vdev: the virtio_device
50 * Returns the first 32 feature bits (all we currently need).
51 * @set_features: confirm what device features we'll be using.
52 * vdev: the virtio_device
53 * feature: the first 32 feature bits
53 */ 54 */
54struct virtio_config_ops 55struct virtio_config_ops
55{ 56{
56 bool (*feature)(struct virtio_device *vdev, unsigned bit);
57 void (*get)(struct virtio_device *vdev, unsigned offset, 57 void (*get)(struct virtio_device *vdev, unsigned offset,
58 void *buf, unsigned len); 58 void *buf, unsigned len);
59 void (*set)(struct virtio_device *vdev, unsigned offset, 59 void (*set)(struct virtio_device *vdev, unsigned offset,
@@ -65,8 +65,30 @@ struct virtio_config_ops
65 unsigned index, 65 unsigned index,
66 void (*callback)(struct virtqueue *)); 66 void (*callback)(struct virtqueue *));
67 void (*del_vq)(struct virtqueue *vq); 67 void (*del_vq)(struct virtqueue *vq);
68 u32 (*get_features)(struct virtio_device *vdev);
69 void (*set_features)(struct virtio_device *vdev, u32 features);
68}; 70};
69 71
72/* If driver didn't advertise the feature, it will never appear. */
73void virtio_check_driver_offered_feature(const struct virtio_device *vdev,
74 unsigned int fbit);
75
76/**
77 * virtio_has_feature - helper to determine if this device has this feature.
78 * @vdev: the device
79 * @fbit: the feature bit
80 */
81static inline bool virtio_has_feature(const struct virtio_device *vdev,
82 unsigned int fbit)
83{
84 /* Did you forget to fix assumptions on max features? */
85 if (__builtin_constant_p(fbit))
86 BUILD_BUG_ON(fbit >= 32);
87
88 virtio_check_driver_offered_feature(vdev, fbit);
89 return test_bit(fbit, vdev->features);
90}
91
70/** 92/**
71 * virtio_config_val - look for a feature and get a virtio config entry. 93 * virtio_config_val - look for a feature and get a virtio config entry.
72 * @vdev: the virtio device 94 * @vdev: the virtio device
@@ -84,7 +106,7 @@ static inline int virtio_config_buf(struct virtio_device *vdev,
84 unsigned int offset, 106 unsigned int offset,
85 void *buf, unsigned len) 107 void *buf, unsigned len)
86{ 108{
87 if (!vdev->config->feature(vdev, fbit)) 109 if (!virtio_has_feature(vdev, fbit))
88 return -ENOENT; 110 return -ENOENT;
89 111
90 vdev->config->get(vdev, offset, buf, len); 112 vdev->config->get(vdev, offset, buf, len);