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
vp_find_vq(unsigned int ioaddr,int queue_index,struct vring_virtqueue * vq)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