1#ifndef _LINUX_VIRTIO_RING_H
2#define _LINUX_VIRTIO_RING_H
3
4
5
6
7
8
9
10
11#include <linux/types.h>
12
13
14#define VRING_DESC_F_NEXT 1
15
16#define VRING_DESC_F_WRITE 2
17
18#define VRING_DESC_F_INDIRECT 4
19
20
21
22
23#define VRING_USED_F_NO_NOTIFY 1
24
25
26
27#define VRING_AVAIL_F_NO_INTERRUPT 1
28
29
30#define VIRTIO_RING_F_INDIRECT_DESC 28
31
32
33struct vring_desc {
34
35 __u64 addr;
36
37 __u32 len;
38
39 __u16 flags;
40
41 __u16 next;
42};
43
44struct vring_avail {
45 __u16 flags;
46 __u16 idx;
47 __u16 ring[];
48};
49
50
51struct vring_used_elem {
52
53 __u32 id;
54
55 __u32 len;
56};
57
58struct vring_used {
59 __u16 flags;
60 __u16 idx;
61 struct vring_used_elem ring[];
62};
63
64struct vring {
65 unsigned int num;
66
67 struct vring_desc *desc;
68
69 struct vring_avail *avail;
70
71 struct vring_used *used;
72};
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96static inline void vring_init(struct vring *vr, unsigned int num, void *p,
97 unsigned long align)
98{
99 vr->num = num;
100 vr->desc = p;
101 vr->avail = p + num*sizeof(struct vring_desc);
102 vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + align-1)
103 & ~(align - 1));
104}
105
106static inline unsigned vring_size(unsigned int num, unsigned long align)
107{
108 return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num)
109 + align - 1) & ~(align - 1))
110 + sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num;
111}
112
113#ifdef __KERNEL__
114#include <linux/irqreturn.h>
115struct virtio_device;
116struct virtqueue;
117
118struct virtqueue *vring_new_virtqueue(unsigned int num,
119 unsigned int vring_align,
120 struct virtio_device *vdev,
121 void *pages,
122 void (*notify)(struct virtqueue *vq),
123 void (*callback)(struct virtqueue *vq),
124 const char *name);
125void vring_del_virtqueue(struct virtqueue *vq);
126
127void vring_transport_features(struct virtio_device *vdev);
128
129irqreturn_t vring_interrupt(int irq, void *_vq);
130#endif
131#endif
132