virtio.h 3.6 KB
Newer Older
R
Rusty Russell 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#ifndef _LINUX_VIRTIO_H
#define _LINUX_VIRTIO_H
/* Everything a virtio driver needs to work with any particular virtio
 * implementation. */
#include <linux/types.h>
#include <linux/scatterlist.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>

/**
 * virtqueue - a queue to register buffers for sending or receiving.
 * @callback: the function to call when buffers are consumed (can be NULL).
 * @vdev: the virtio device this queue was created for.
 * @vq_ops: the operations for this virtqueue (see below).
 * @priv: a pointer for the virtqueue implementation to use.
 */
struct virtqueue
{
20
	void (*callback)(struct virtqueue *vq);
R
Rusty Russell 已提交
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
	struct virtio_device *vdev;
	struct virtqueue_ops *vq_ops;
	void *priv;
};

/**
 * virtqueue_ops - operations for virtqueue abstraction layer
 * @add_buf: expose buffer to other end
 *	vq: the struct virtqueue we're talking about.
 *	sg: the description of the buffer(s).
 *	out_num: the number of sg readable by other side
 *	in_num: the number of sg which are writable (after readable ones)
 *	data: the token identifying the buffer.
 *      Returns 0 or an error.
 * @kick: update after add_buf
 *	vq: the struct virtqueue
 *	After one or more add_buf calls, invoke this to kick the other side.
 * @get_buf: get the next used buffer
 *	vq: the struct virtqueue we're talking about.
 *	len: the length written into the buffer
 *	Returns NULL or the "data" token handed to add_buf.
42 43 44
 * @disable_cb: disable callbacks
 *	vq: the struct virtqueue we're talking about.
 * @enable_cb: restart callbacks after disable_cb.
R
Rusty Russell 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
 *	vq: the struct virtqueue we're talking about.
 *	This returns "false" (and doesn't re-enable) if there are pending
 *	buffers in the queue, to avoid a race.
 * @shutdown: "unadd" all buffers.
 *	vq: the struct virtqueue we're talking about.
 *	Remove everything from the queue.
 *
 * Locking rules are straightforward: the driver is responsible for
 * locking.  No two operations may be invoked simultaneously.
 *
 * All operations can be called in any context.
 */
struct virtqueue_ops {
	int (*add_buf)(struct virtqueue *vq,
		       struct scatterlist sg[],
		       unsigned int out_num,
		       unsigned int in_num,
		       void *data);

	void (*kick)(struct virtqueue *vq);

	void *(*get_buf)(struct virtqueue *vq, unsigned int *len);

68 69
	void (*disable_cb)(struct virtqueue *vq);
	bool (*enable_cb)(struct virtqueue *vq);
R
Rusty Russell 已提交
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

	void (*shutdown)(struct virtqueue *vq);
};

/**
 * virtio_device - representation of a device using virtio
 * @index: unique position on the virtio bus
 * @dev: underlying device.
 * @id: the device type identification (used to match it with a driver).
 * @config: the configuration ops for this device.
 * @priv: private pointer for the driver's use.
 */
struct virtio_device
{
	int index;
	struct device dev;
	struct virtio_device_id id;
	struct virtio_config_ops *config;
	void *priv;
};

int register_virtio_device(struct virtio_device *dev);
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.
 * @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.
 */
struct virtio_driver {
	struct device_driver driver;
	const struct virtio_device_id *id_table;
	int (*probe)(struct virtio_device *dev);
	void (*remove)(struct virtio_device *dev);
};

int register_virtio_driver(struct virtio_driver *drv);
void unregister_virtio_driver(struct virtio_driver *drv);
#endif /* _LINUX_VIRTIO_H */