Commit | Line | Data |
---|---|---|
ec3d41c4 RR |
1 | #ifndef _LINUX_VIRTIO_CONFIG_H |
2 | #define _LINUX_VIRTIO_CONFIG_H | |
3 | /* Virtio devices use a standardized configuration space to define their | |
4 | * features and pass configuration information, but each implementation can | |
5 | * store and access that space differently. */ | |
6 | #include <linux/types.h> | |
7 | ||
8 | /* Status byte for guest to report progress, and synchronize config. */ | |
9 | /* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */ | |
10 | #define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 | |
11 | /* We have found a driver for the device. */ | |
12 | #define VIRTIO_CONFIG_S_DRIVER 2 | |
13 | /* Driver has used its parts of the config, and is happy */ | |
14 | #define VIRTIO_CONFIG_S_DRIVER_OK 4 | |
15 | /* We've given up on this device. */ | |
16 | #define VIRTIO_CONFIG_S_FAILED 0x80 | |
17 | ||
18 | /* Feature byte (actually 7 bits availabe): */ | |
19 | /* Requirements/features of the virtio implementation. */ | |
20 | #define VIRTIO_CONFIG_F_VIRTIO 1 | |
21 | /* Requirements/features of the virtqueue (may have more than one). */ | |
22 | #define VIRTIO_CONFIG_F_VIRTQUEUE 2 | |
23 | ||
24 | #ifdef __KERNEL__ | |
25 | struct virtio_device; | |
26 | ||
27 | /** | |
28 | * virtio_config_ops - operations for configuring a virtio device | |
29 | * @find: search for the next configuration field of the given type. | |
30 | * vdev: the virtio_device | |
31 | * type: the feature type | |
32 | * len: the (returned) length of the field if found. | |
33 | * Returns a token if found, or NULL. Never returnes the same field twice | |
34 | * (ie. it's used up). | |
35 | * @get: read the value of a configuration field after find(). | |
36 | * vdev: the virtio_device | |
37 | * token: the token returned from find(). | |
38 | * buf: the buffer to write the field value into. | |
39 | * len: the length of the buffer (given by find()). | |
40 | * Note that contents are conventionally little-endian. | |
41 | * @set: write the value of a configuration field after find(). | |
42 | * vdev: the virtio_device | |
43 | * token: the token returned from find(). | |
44 | * buf: the buffer to read the field value from. | |
45 | * len: the length of the buffer (given by find()). | |
46 | * Note that contents are conventionally little-endian. | |
47 | * @get_status: read the status byte | |
48 | * vdev: the virtio_device | |
49 | * Returns the status byte | |
50 | * @set_status: write the status byte | |
51 | * vdev: the virtio_device | |
52 | * status: the new status byte | |
53 | * @find_vq: find the first VIRTIO_CONFIG_F_VIRTQUEUE and create a virtqueue. | |
54 | * vdev: the virtio_device | |
55 | * callback: the virqtueue callback | |
56 | * Returns the new virtqueue or ERR_PTR(). | |
57 | * @del_vq: free a virtqueue found by find_vq(). | |
58 | */ | |
59 | struct virtio_config_ops | |
60 | { | |
61 | void *(*find)(struct virtio_device *vdev, u8 type, unsigned *len); | |
62 | void (*get)(struct virtio_device *vdev, void *token, | |
63 | void *buf, unsigned len); | |
64 | void (*set)(struct virtio_device *vdev, void *token, | |
65 | const void *buf, unsigned len); | |
66 | u8 (*get_status)(struct virtio_device *vdev); | |
67 | void (*set_status)(struct virtio_device *vdev, u8 status); | |
68 | struct virtqueue *(*find_vq)(struct virtio_device *vdev, | |
69 | bool (*callback)(struct virtqueue *)); | |
70 | void (*del_vq)(struct virtqueue *vq); | |
71 | }; | |
72 | ||
73 | /** | |
74 | * virtio_config_val - get a single virtio config and mark it used. | |
75 | * @config: the virtio config space | |
76 | * @type: the type to search for. | |
77 | * @val: a pointer to the value to fill in. | |
78 | * | |
79 | * Once used, the config type is marked with VIRTIO_CONFIG_F_USED so it can't | |
80 | * be found again. This version does endian conversion. */ | |
81 | #define virtio_config_val(vdev, type, v) ({ \ | |
82 | int _err = __virtio_config_val((vdev),(type),(v),sizeof(*(v))); \ | |
83 | \ | |
84 | BUILD_BUG_ON(sizeof(*(v)) != 1 && sizeof(*(v)) != 2 \ | |
85 | && sizeof(*(v)) != 4 && sizeof(*(v)) != 8); \ | |
86 | if (!_err) { \ | |
87 | switch (sizeof(*(v))) { \ | |
88 | case 2: le16_to_cpus((__u16 *) v); break; \ | |
89 | case 4: le32_to_cpus((__u32 *) v); break; \ | |
90 | case 8: le64_to_cpus((__u64 *) v); break; \ | |
91 | } \ | |
92 | } \ | |
93 | _err; \ | |
94 | }) | |
95 | ||
96 | int __virtio_config_val(struct virtio_device *dev, | |
97 | u8 type, void *val, size_t size); | |
98 | ||
99 | /** | |
100 | * virtio_use_bit - helper to use a feature bit in a bitfield value. | |
101 | * @dev: the virtio device | |
102 | * @token: the token as returned from vdev->config->find(). | |
103 | * @len: the length of the field. | |
104 | * @bitnum: the bit to test. | |
105 | * | |
106 | * If handed a NULL token, it returns false, otherwise returns bit status. | |
107 | * If it's one, it sets the mirroring acknowledgement bit. */ | |
108 | int virtio_use_bit(struct virtio_device *vdev, | |
109 | void *token, unsigned int len, unsigned int bitnum); | |
110 | #endif /* __KERNEL__ */ | |
111 | #endif /* _LINUX_VIRTIO_CONFIG_H */ |