00001 /* virtio-pci.c - pci interface for virtio interface 00002 * 00003 * (c) Copyright 2008 Bull S.A.S. 00004 * 00005 * Author: Laurent Vivier <Laurent.Vivier@bull.net> 00006 * 00007 * some parts from Linux Virtio PCI driver 00008 * 00009 * Copyright IBM Corp. 2007 00010 * Authors: Anthony Liguori <aliguori@us.ibm.com> 00011 * 00012 */ 00013 00014 #include "etherboot.h" 00015 #include "gpxe/io.h" 00016 #include "gpxe/virtio-ring.h" 00017 #include "gpxe/virtio-pci.h" 00018 00019 int vp_find_vq(unsigned int ioaddr, int queue_index, 00020 struct vring_virtqueue *vq) 00021 { 00022 struct vring * vr = &vq->vring; 00023 u16 num; 00024 00025 /* select the queue */ 00026 00027 outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL); 00028 00029 /* check if the queue is available */ 00030 00031 num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM); 00032 if (!num) { 00033 printf("ERROR: queue size is 0\n"); 00034 return -1; 00035 } 00036 00037 if (num > MAX_QUEUE_NUM) { 00038 printf("ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM); 00039 return -1; 00040 } 00041 00042 /* check if the queue is already active */ 00043 00044 if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) { 00045 printf("ERROR: queue already active\n"); 00046 return -1; 00047 } 00048 00049 vq->queue_index = queue_index; 00050 00051 /* initialize the queue */ 00052 00053 vring_init(vr, num, (unsigned char*)&vq->queue); 00054 00055 /* activate the queue 00056 * 00057 * NOTE: vr->desc is initialized by vring_init() 00058 */ 00059 00060 outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT, 00061 ioaddr + VIRTIO_PCI_QUEUE_PFN); 00062 00063 return num; 00064 }
1.5.7.1