[sis900] Enable interrupts to allow UNDI to work
[people/pcmattman/gpxe.git] / src / drivers / bus / virtio-pci.c
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@bull.net>
6  *
7  * some parts from Linux Virtio PCI driver
8  *
9  *  Copyright IBM Corp. 2007
10  *  Authors: Anthony Liguori  <aliguori@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 }