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>
This commit is contained in:
@@ -76,6 +76,7 @@ struct virtqueue_ops {
|
||||
* @dev: underlying device.
|
||||
* @id: the device type identification (used to match it with a driver).
|
||||
* @config: the configuration ops for this device.
|
||||
* @features: the features supported by both driver and device.
|
||||
* @priv: private pointer for the driver's use.
|
||||
*/
|
||||
struct virtio_device
|
||||
@@ -84,6 +85,8 @@ struct virtio_device
|
||||
struct device dev;
|
||||
struct virtio_device_id id;
|
||||
struct virtio_config_ops *config;
|
||||
/* Note that this is a Linux set_bit-style bitmap. */
|
||||
unsigned long features[1];
|
||||
void *priv;
|
||||
};
|
||||
|
||||
@@ -94,6 +97,8 @@ void unregister_virtio_device(struct virtio_device *dev);
|
||||
* virtio_driver - operations for a virtio I/O driver
|
||||
* @driver: underlying device driver (populate name and owner).
|
||||
* @id_table: the ids serviced by this driver.
|
||||
* @feature_table: an array of feature numbers supported by this device.
|
||||
* @feature_table_size: number of entries in the feature table array.
|
||||
* @probe: the function to call when a device is found. Returns a token for
|
||||
* remove, or PTR_ERR().
|
||||
* @remove: the function when a device is removed.
|
||||
@@ -103,6 +108,8 @@ void unregister_virtio_device(struct virtio_device *dev);
|
||||
struct virtio_driver {
|
||||
struct device_driver driver;
|
||||
const struct virtio_device_id *id_table;
|
||||
const unsigned int *feature_table;
|
||||
unsigned int feature_table_size;
|
||||
int (*probe)(struct virtio_device *dev);
|
||||
void (*remove)(struct virtio_device *dev);
|
||||
void (*config_changed)(struct virtio_device *dev);
|
||||
|
Reference in New Issue
Block a user