39#define DESC_INDEX(num, i) ((i) & ((num) - 1))
42#define VIRTQ_DESC_F_NEXT 1
44#define VIRTQ_DESC_F_WRITE 2
46#define VIRTQ_DESC_F_INDIRECT 4
51#define VIRTQ_USED_F_NO_NOTIFY 1
55#define VIRTQ_AVAIL_F_NO_INTERRUPT 1
58#pragma warning (disable:4200)
99#define VRING_AVAIL_ALIGN_SIZE 2
100#define VRING_USED_ALIGN_SIZE 4
101#define VRING_DESC_ALIGN_SIZE 16
140#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
141#define vring_avail_event(vr) (*(__virtio16 *)&(vr)->used->ring[(vr)->num])
155#pragma warning (push)
156#pragma warning (disable:4319)
174 return (
__u16)(new_idx - event_idx - 1) < (
__u16)(new_idx - old);
191#define splitvq(vq) ((struct virtqueue_split *)vq)
246 desc[
i].addr = sg[
i].physAddr.QuadPart;
247 desc[
i].len = sg[
i].length;
250 desc[
i - 1].flags &= ~VIRTQ_DESC_F_NEXT;
254 vq->
vring.desc[
idx].addr = phys_indirect;
282 vring->
desc[last_idx].addr = sg[
i].physAddr.QuadPart;
290 vring->
desc[last_idx].flags &= ~VIRTQ_DESC_F_NEXT;
311 if (
vq->last_used == (
int)
vq->vring.used->idx) {
318 *
len =
vq->vring.used->ring[
idx].len;
341 return (
vq->last_used !=
vq->vring.used->idx);
352 wrap_around = (
vq->num_added_since_kick >= (1 << 16));
354 old = (
u16)(
vq->master_vring_avail.idx -
vq->num_added_since_kick);
355 new =
vq->master_vring_avail.idx;
356 vq->num_added_since_kick = 0;
370 vq->num_added_since_kick = 0;
380 vq->master_vring_avail.flags &= ~VIRTQ_AVAIL_F_NO_INTERRUPT;
383 vq->vring.avail->flags =
vq->master_vring_avail.flags;
389 return (
vq->last_used ==
vq->vring.used->idx);
400 vq->master_vring_avail.flags &= ~VIRTQ_AVAIL_F_NO_INTERRUPT;
403 vq->vring.avail->flags =
vq->master_vring_avail.flags;
408 bufs = (
u16)(
vq->master_vring_avail.idx -
vq->last_used) * 3 / 4;
411 return ((
vq->vring.used->idx -
vq->last_used) <=
bufs);
422 vq->vring.avail->flags =
vq->master_vring_avail.flags;
438 unsigned int num =
vq->vring.num;
439 void *pages =
vq->vring.desc;
465 vq->vring.avail->idx = --
vq->master_vring_avail.idx;
481 res +=
sizeof(
void *) * qsize;
489 unsigned int vring_align,
499 DPrintf(0,
"Virtqueue length %u is not a power of 2\n",
num);
511 vq->num_unused =
num;
512 vq->first_unused = 0;
513 for (
i = 0;
i <
num - 1;
i++) {
515 vq->vring.desc[
i].next =
i + 1;
517 vq->vq.avail_va =
vq->vring.avail;
518 vq->vq.used_va =
vq->vring.used;
unsigned long vring_size_packed(unsigned int num, unsigned long align)
unsigned int vring_control_block_size_packed(u16 qsize)
unsigned long vring_size(unsigned int num, unsigned long align, bool packed)
static bool virtqueue_enable_cb_delayed_split(struct virtqueue *_vq)
#define VIRTQ_AVAIL_F_NO_INTERRUPT
#define VIRTQ_DESC_F_WRITE
#define VIRTQ_DESC_F_NEXT
u32 virtio_get_indirect_page_capacity()
static BOOLEAN virtqueue_is_interrupt_enabled_split(struct virtqueue *_vq)
#define DESC_INDEX(num, i)
static void virtqueue_shutdown_split(struct virtqueue *_vq)
static void virtqueue_kick_always_split(struct virtqueue *_vq)
static int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old)
static void put_unused_desc_chain(struct virtqueue_split *vq, u16 idx)
static void virtqueue_disable_cb_split(struct virtqueue *_vq)
struct virtqueue * vring_new_virtqueue_split(unsigned int index, unsigned int num, unsigned int vring_align, VirtIODevice *vdev, void *pages, void(*notify)(struct virtqueue *), void *control)
static bool virtqueue_kick_prepare_split(struct virtqueue *_vq)
static unsigned vring_size_split(unsigned int num, unsigned long align)
#define vring_avail_event(vr)
#define VIRTQ_DESC_F_INDIRECT
static BOOLEAN virtqueue_has_buf_split(struct virtqueue *_vq)
unsigned int vring_control_block_size(u16 qsize, bool packed)
#define vring_used_event(vr)
static void * virtqueue_get_buf_split(struct virtqueue *_vq, unsigned int *len)
static void * virtqueue_detach_unused_buf_split(struct virtqueue *_vq)
void vring_transport_features(VirtIODevice *vdev, u64 *features)
static int virtqueue_add_buf_split(struct virtqueue *_vq, struct scatterlist sg[], unsigned int out, unsigned int in, void *opaque, void *va_indirect, ULONGLONG phys_indirect)
#define VIRTQ_USED_F_NO_NOTIFY
static void vring_init(struct vring *vr, unsigned int num, void *p, unsigned long align)
static u16 get_unused_desc(struct virtqueue_split *vq)
static bool virtqueue_enable_cb_split(struct virtqueue *_vq)
static BOOLEAN virtqueue_is_interrupt_enabled(struct virtqueue *vq)
void virtqueue_notify(struct virtqueue *vq)
#define DPrintf(Level, Fmt)
int align(int length, int align)
GLuint GLenum GLsizei GLsizei GLint GLint GLboolean packed
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
static const WCHAR desc[]
FORCEINLINE VOID KeMemoryBarrier(VOID)
bool event_suppression_enabled
struct virtqueue_split::@4339 master_vring_avail
unsigned int num_added_since_kick
void(* notification_cb)(struct virtqueue *vq)
struct vring_used_elem ring[]
struct vring_avail * avail
#define RtlZeroMemory(Destination, Length)
#define VIRTIO_TRANSPORT_F_START
#define VIRTIO_TRANSPORT_F_END
#define VIRTIO_F_VERSION_1
#define virtio_feature_disable(FeaturesList, Feature)
#define VIRTIO_RING_F_INDIRECT_DESC
#define VIRTIO_RING_F_EVENT_IDX
__u64 __bitwise__ __virtio64
__u16 __bitwise__ __virtio16
__u32 __bitwise__ __virtio32