Annotation of qemu/roms/ipxe/src/drivers/bus/virtio-ring.c, revision 1.1.1.1

1.1       root        1: /* virtio-pci.c - virtio ring management
                      2:  *
                      3:  * (c) Copyright 2008 Bull S.A.S.
                      4:  *
                      5:  *  Author: Laurent Vivier <[email protected]>
                      6:  *
                      7:  *  some parts from Linux Virtio Ring
                      8:  *
                      9:  *  Copyright Rusty Russell IBM Corporation 2007
                     10:  *
                     11:  * This work is licensed under the terms of the GNU GPL, version 2 or later.
                     12:  * See the COPYING file in the top-level directory.
                     13:  *
                     14:  *
                     15:  */
                     16: 
                     17: FILE_LICENCE ( GPL2_OR_LATER );
                     18: 
                     19: #include "etherboot.h"
                     20: #include "ipxe/io.h"
                     21: #include "ipxe/virtio-ring.h"
                     22: #include "ipxe/virtio-pci.h"
                     23: 
                     24: #define BUG() do { \
                     25:    printf("BUG: failure at %s:%d/%s()!\n", \
                     26:           __FILE__, __LINE__, __FUNCTION__); \
                     27:    while(1); \
                     28: } while (0)
                     29: #define BUG_ON(condition) do { if (condition) BUG(); } while (0)
                     30: 
                     31: /*
                     32:  * vring_free
                     33:  *
                     34:  * put at the begin of the free list the current desc[head]
                     35:  */
                     36: 
                     37: void vring_detach(struct vring_virtqueue *vq, unsigned int head)
                     38: {
                     39:    struct vring *vr = &vq->vring;
                     40:    unsigned int i;
                     41: 
                     42:    /* find end of given descriptor */
                     43: 
                     44:    i = head;
                     45:    while (vr->desc[i].flags & VRING_DESC_F_NEXT)
                     46:            i = vr->desc[i].next;
                     47: 
                     48:    /* link it with free list and point to it */
                     49: 
                     50:    vr->desc[i].next = vq->free_head;
                     51:    wmb();
                     52:    vq->free_head = head;
                     53: }
                     54: 
                     55: /*
                     56:  * vring_get_buf
                     57:  *
                     58:  * get a buffer from the used list
                     59:  *
                     60:  */
                     61: 
                     62: void *vring_get_buf(struct vring_virtqueue *vq, unsigned int *len)
                     63: {
                     64:    struct vring *vr = &vq->vring;
                     65:    struct vring_used_elem *elem;
                     66:    u32 id;
                     67:    void *opaque;
                     68: 
                     69:    BUG_ON(!vring_more_used(vq));
                     70: 
                     71:    elem = &vr->used->ring[vq->last_used_idx % vr->num];
                     72:    wmb();
                     73:    id = elem->id;
                     74:    if (len != NULL)
                     75:            *len = elem->len;
                     76: 
                     77:    opaque = vq->vdata[id];
                     78: 
                     79:    vring_detach(vq, id);
                     80: 
                     81:    vq->last_used_idx++;
                     82: 
                     83:    return opaque;
                     84: }
                     85: 
                     86: void vring_add_buf(struct vring_virtqueue *vq,
                     87:                   struct vring_list list[],
                     88:                   unsigned int out, unsigned int in,
                     89:                   void *opaque, int num_added)
                     90: {
                     91:    struct vring *vr = &vq->vring;
                     92:    int i, avail, head, prev;
                     93: 
                     94:    BUG_ON(out + in == 0);
                     95: 
                     96:    prev = 0;
                     97:    head = vq->free_head;
                     98:    for (i = head; out; i = vr->desc[i].next, out--) {
                     99: 
                    100:            vr->desc[i].flags = VRING_DESC_F_NEXT;
                    101:            vr->desc[i].addr = (u64)virt_to_phys(list->addr);
                    102:            vr->desc[i].len = list->length;
                    103:            prev = i;
                    104:            list++;
                    105:    }
                    106:    for ( ; in; i = vr->desc[i].next, in--) {
                    107: 
                    108:            vr->desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
                    109:            vr->desc[i].addr = (u64)virt_to_phys(list->addr);
                    110:            vr->desc[i].len = list->length;
                    111:            prev = i;
                    112:            list++;
                    113:    }
                    114:    vr->desc[prev].flags &= ~VRING_DESC_F_NEXT;
                    115: 
                    116:    vq->free_head = i;
                    117: 
                    118:    vq->vdata[head] = opaque;
                    119: 
                    120:    avail = (vr->avail->idx + num_added) % vr->num;
                    121:    vr->avail->ring[avail] = head;
                    122:    wmb();
                    123: }
                    124: 
                    125: void vring_kick(unsigned int ioaddr, struct vring_virtqueue *vq, int num_added)
                    126: {
                    127:    struct vring *vr = &vq->vring;
                    128: 
                    129:    wmb();
                    130:    vr->avail->idx += num_added;
                    131: 
                    132:    mb();
                    133:    if (!(vr->used->flags & VRING_USED_F_NO_NOTIFY))
                    134:            vp_notify(ioaddr, vq->queue_index);
                    135: }
                    136: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.