Home | History | Annotate | Download | only in bus
      1 /* virtio-pci.c - pci interface for virtio interface
      2  *
      3  * (c) Copyright 2008 Bull S.A.S.
      4  *
      5  *  Author: Laurent Vivier <Laurent.Vivier (at) bull.net>
      6  *
      7  * some parts from Linux Virtio PCI driver
      8  *
      9  *  Copyright IBM Corp. 2007
     10  *  Authors: Anthony Liguori  <aliguori (at) us.ibm.com>
     11  *
     12  */
     13 
     14 #include "etherboot.h"
     15 #include "gpxe/io.h"
     16 #include "gpxe/virtio-ring.h"
     17 #include "gpxe/virtio-pci.h"
     18 
     19 int vp_find_vq(unsigned int ioaddr, int queue_index,
     20                struct vring_virtqueue *vq)
     21 {
     22    struct vring * vr = &vq->vring;
     23    u16 num;
     24 
     25    /* select the queue */
     26 
     27    outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL);
     28 
     29    /* check if the queue is available */
     30 
     31    num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM);
     32    if (!num) {
     33            printf("ERROR: queue size is 0\n");
     34            return -1;
     35    }
     36 
     37    if (num > MAX_QUEUE_NUM) {
     38            printf("ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
     39            return -1;
     40    }
     41 
     42    /* check if the queue is already active */
     43 
     44    if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) {
     45            printf("ERROR: queue already active\n");
     46            return -1;
     47    }
     48 
     49    vq->queue_index = queue_index;
     50 
     51    /* initialize the queue */
     52 
     53    vring_init(vr, num, (unsigned char*)&vq->queue);
     54 
     55    /* activate the queue
     56     *
     57     * NOTE: vr->desc is initialized by vring_init()
     58     */
     59 
     60    outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT,
     61         ioaddr + VIRTIO_PCI_QUEUE_PFN);
     62 
     63    return num;
     64 }
     65