virtio-ring.c File Reference

#include "etherboot.h"
#include "gpxe/io.h"
#include "gpxe/virtio-ring.h"
#include "gpxe/virtio-pci.h"

Go to the source code of this file.

Defines

#define BUG()
#define BUG_ON(condition)   do { if (condition) BUG(); } while (0)

Functions

void vring_detach (struct vring_virtqueue *vq, unsigned int head)
int vring_get_buf (struct vring_virtqueue *vq, unsigned int *len)
void vring_add_buf (struct vring_virtqueue *vq, struct vring_list list[], unsigned int out, unsigned int in, int index, int num_added)
void vring_kick (unsigned int ioaddr, struct vring_virtqueue *vq, int num_added)


Define Documentation

 
#define BUG (  ) 

Value:

do { \
   printf("BUG: failure at %s:%d/%s()!\n", \
          __FILE__, __LINE__, __FUNCTION__); \
   while(1); \
} while (0)

Definition at line 22 of file virtio-ring.c.

#define BUG_ON ( condition   )     do { if (condition) BUG(); } while (0)

Definition at line 27 of file virtio-ring.c.

Referenced by virtnet_poll(), virtnet_transmit(), vring_add_buf(), and vring_get_buf().


Function Documentation

void vring_detach ( struct vring_virtqueue vq,
unsigned int  head 
)

Definition at line 35 of file virtio-ring.c.

References vring::desc, vring_desc::flags, vring_virtqueue::free_head, vring_desc::next, vring_virtqueue::vring, VRING_DESC_F_NEXT, and wmb.

Referenced by vring_get_buf().

00036 {
00037    struct vring *vr = &vq->vring;
00038    unsigned int i;
00039 
00040    /* find end of given descriptor */
00041 
00042    i = head;
00043    while (vr->desc[i].flags & VRING_DESC_F_NEXT)
00044            i = vr->desc[i].next;
00045 
00046    /* link it with free list and point to it */
00047 
00048    vr->desc[i].next = vq->free_head;
00049    wmb();
00050    vq->free_head = head;
00051 }

int vring_get_buf ( struct vring_virtqueue vq,
unsigned int *  len 
)

Definition at line 60 of file virtio-ring.c.

References BUG_ON, vring_used_elem::id, id, vring_virtqueue::last_used_idx, vring_used_elem::len, NULL, vring::num, vring_used::ring, u32, vring::used, vring_virtqueue::vdata, vring_virtqueue::vring, vring_detach(), vring_more_used(), and wmb.

Referenced by virtnet_poll(), and virtnet_transmit().

00061 {
00062    struct vring *vr = &vq->vring;
00063    struct vring_used_elem *elem;
00064    u32 id;
00065    int ret;
00066 
00067    BUG_ON(!vring_more_used(vq));
00068 
00069    elem = &vr->used->ring[vq->last_used_idx % vr->num];
00070    wmb();
00071    id = elem->id;
00072    if (len != NULL)
00073            *len = elem->len;
00074 
00075    ret = vq->vdata[id];
00076 
00077    vring_detach(vq, id);
00078 
00079    vq->last_used_idx++;
00080 
00081    return ret;
00082 }

void vring_add_buf ( struct vring_virtqueue vq,
struct vring_list  list[],
unsigned int  out,
unsigned int  in,
int  index,
int  num_added 
)

Definition at line 84 of file virtio-ring.c.

References vring_list::addr, vring_desc::addr, vring::avail, BUG_ON, vring::desc, vring_desc::flags, vring_virtqueue::free_head, vring_avail::idx, vring_desc::len, vring_list::length, vring_desc::next, vring::num, vring_avail::ring, vring_virtqueue::vdata, virt_to_phys(), vring_virtqueue::vring, VRING_DESC_F_NEXT, VRING_DESC_F_WRITE, and wmb.

Referenced by provide_buffers(), virtnet_poll(), and virtnet_transmit().

00088 {
00089    struct vring *vr = &vq->vring;
00090    int i, avail, head, prev;
00091 
00092    BUG_ON(out + in == 0);
00093 
00094    prev = 0;
00095    head = vq->free_head;
00096    for (i = head; out; i = vr->desc[i].next, out--) {
00097 
00098            vr->desc[i].flags = VRING_DESC_F_NEXT;
00099            vr->desc[i].addr = (u64)virt_to_phys(list->addr);
00100            vr->desc[i].len = list->length;
00101            prev = i;
00102            list++;
00103    }
00104    for ( ; in; i = vr->desc[i].next, in--) {
00105 
00106            vr->desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
00107            vr->desc[i].addr = (u64)virt_to_phys(list->addr);
00108            vr->desc[i].len = list->length;
00109            prev = i;
00110            list++;
00111    }
00112    vr->desc[prev].flags &= ~VRING_DESC_F_NEXT;
00113 
00114    vq->free_head = i;
00115 
00116    vq->vdata[head] = index;
00117 
00118    avail = (vr->avail->idx + num_added) % vr->num;
00119    vr->avail->ring[avail] = head;
00120    wmb();
00121 }

void vring_kick ( unsigned int  ioaddr,
struct vring_virtqueue vq,
int  num_added 
)

Definition at line 123 of file virtio-ring.c.

References vring::avail, vring_used::flags, vring_avail::idx, mb(), vring_virtqueue::queue_index, vring::used, vp_notify(), vring_virtqueue::vring, VRING_USED_F_NO_NOTIFY, and wmb.

Referenced by provide_buffers(), virtnet_poll(), and virtnet_transmit().

00124 {
00125    struct vring *vr = &vq->vring;
00126 
00127    wmb();
00128    vr->avail->idx += num_added;
00129 
00130    mb();
00131    if (!(vr->used->flags & VRING_USED_F_NO_NOTIFY))
00132            vp_notify(ioaddr, vq->queue_index);
00133 }


Generated on Tue Apr 6 20:01:16 2010 for gPXE by  doxygen 1.5.7.1