virtio: find_vqs/del_vqs virtio operations

This replaces find_vq/del_vq with find_vqs/del_vqs virtio operations,
and updates all drivers. This is needed for MSI support, because MSI
needs to know the total number of vectors upfront.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (+ lguest/9p compile fixes)
This commit is contained in:
Michael S. Tsirkin 2009-06-12 22:16:36 -06:00 committed by Rusty Russell
parent 9499f5e7ed
commit d2a7ddda9f
10 changed files with 184 additions and 90 deletions

View file

@ -29,6 +29,7 @@
#define VIRTIO_F_NOTIFY_ON_EMPTY 24
#ifdef __KERNEL__
#include <linux/err.h>
#include <linux/virtio.h>
/**
@ -49,16 +50,26 @@
* @set_status: write the status byte
* vdev: the virtio_device
* status: the new status byte
* @request_vqs: request the specified number of virtqueues
* vdev: the virtio_device
* max_vqs: the max number of virtqueues we want
* If supplied, must call before any virtqueues are instantiated.
* To modify the max number of virtqueues after request_vqs has been
* called, call free_vqs and then request_vqs with a new value.
* @free_vqs: cleanup resources allocated by request_vqs
* vdev: the virtio_device
* If supplied, must call after all virtqueues have been deleted.
* @reset: reset the device
* vdev: the virtio device
* After this, status and feature negotiation must be done again
* @find_vq: find a virtqueue and instantiate it.
* @find_vqs: find virtqueues and instantiate them.
* vdev: the virtio_device
* index: the 0-based virtqueue number in case there's more than one.
* callback: the virtqueue callback
* name: the virtqueue name (mainly for debugging)
* Returns the new virtqueue or ERR_PTR() (eg. -ENOENT).
* @del_vq: free a virtqueue found by find_vq().
* nvqs: the number of virtqueues to find
* vqs: on success, includes new virtqueues
* callbacks: array of callbacks, for each virtqueue
* names: array of virtqueue names (mainly for debugging)
* Returns 0 on success or error status
* @del_vqs: free virtqueues found by find_vqs().
* @get_features: get the array of feature bits for this device.
* vdev: the virtio_device
* Returns the first 32 feature bits (all we currently need).
@ -67,6 +78,7 @@
* This gives the final feature bits for the device: it can change
* the dev->feature bits if it wants.
*/
typedef void vq_callback_t(struct virtqueue *);
struct virtio_config_ops
{
void (*get)(struct virtio_device *vdev, unsigned offset,
@ -76,11 +88,11 @@ struct virtio_config_ops
u8 (*get_status)(struct virtio_device *vdev);
void (*set_status)(struct virtio_device *vdev, u8 status);
void (*reset)(struct virtio_device *vdev);
struct virtqueue *(*find_vq)(struct virtio_device *vdev,
unsigned index,
void (*callback)(struct virtqueue *),
const char *name);
void (*del_vq)(struct virtqueue *vq);
int (*find_vqs)(struct virtio_device *, unsigned nvqs,
struct virtqueue *vqs[],
vq_callback_t *callbacks[],
const char *names[]);
void (*del_vqs)(struct virtio_device *);
u32 (*get_features)(struct virtio_device *vdev);
void (*finalize_features)(struct virtio_device *vdev);
};
@ -128,5 +140,18 @@ static inline int virtio_config_buf(struct virtio_device *vdev,
vdev->config->get(vdev, offset, buf, len);
return 0;
}
static inline
struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev,
vq_callback_t *c, const char *n)
{
vq_callback_t *callbacks[] = { c };
const char *names[] = { n };
struct virtqueue *vq;
int err = vdev->config->find_vqs(vdev, 1, &vq, callbacks, names);
if (err < 0)
return ERR_PTR(err);
return vq;
}
#endif /* __KERNEL__ */
#endif /* _LINUX_VIRTIO_CONFIG_H */