blob: db19e974a8560b5aae4b8cd8943145723aa39c3c [file] [log] [blame]
Gleb Natapov89acfa32010-05-10 11:36:37 +03001/* 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 * Adopted for Seabios: Gleb Natapov <gleb@redhat.com>
13 *
14 * This work is licensed under the terms of the GNU LGPLv3
15 * See the COPYING file in the top-level directory.
16 */
17
18#include "virtio-ring.h"
19#include "virtio-pci.h"
Kevin O'Connor7d09d0e2010-05-10 21:51:38 -040020#include "config.h" // CONFIG_DEBUG_LEVEL
21#include "util.h" // dprintf
Gleb Natapov89acfa32010-05-10 11:36:37 +030022
23int vp_find_vq(unsigned int ioaddr, int queue_index,
24 struct vring_virtqueue *vq)
25{
26 struct vring * vr = &vq->vring;
27 u16 num;
28
29 ASSERT32FLAT();
30 /* select the queue */
31
32 outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL);
33
34 /* check if the queue is available */
35
36 num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM);
37 if (!num) {
38 dprintf(1, "ERROR: queue size is 0\n");
39 return -1;
40 }
41
42 if (num > MAX_QUEUE_NUM) {
43 dprintf(1, "ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
44 return -1;
45 }
46
47 /* check if the queue is already active */
48
49 if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) {
50 dprintf(1, "ERROR: queue already active\n");
51 return -1;
52 }
53
54 vq->queue_index = queue_index;
55
56 /* initialize the queue */
57
58 vring_init(vr, num, (unsigned char*)&vq->queue);
59
60 /* activate the queue
61 *
62 * NOTE: vr->desc is initialized by vring_init()
63 */
64
65 outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT,
66 ioaddr + VIRTIO_PCI_QUEUE_PFN);
67
68 return num;
69}