Another common bit that can be made generic.
Signed-off-by: Paolo Bonzini pbonzini@redhat.com --- src/virtio-blk.c | 11 ++++------- src/virtio-pci.c | 22 +++++++++++++++++----- src/virtio-pci.h | 2 +- 3 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/src/virtio-blk.c b/src/virtio-blk.c index 9ed82e0..e85250c 100644 --- a/src/virtio-blk.c +++ b/src/virtio-blk.c @@ -103,20 +103,17 @@ init_virtio_blk(struct pci_device *pci) dprintf(1, "found virtio-blk at %x:%x\n", pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf)); struct virtiodrive_s *vdrive_g = malloc_fseg(sizeof(*vdrive_g)); - struct vring_virtqueue *vq = memalign_low(PAGE_SIZE, sizeof(*vq)); - if (!vdrive_g || !vq) { + if (!vdrive_g) { warn_noalloc(); - goto fail; + return; } memset(vdrive_g, 0, sizeof(*vdrive_g)); - memset(vq, 0, sizeof(*vq)); vdrive_g->drive.type = DTYPE_VIRTIO_BLK; vdrive_g->drive.cntl_id = bdf; - vdrive_g->vq = vq;
u16 ioaddr = vp_init_simple(bdf); vdrive_g->ioaddr = ioaddr; - if (vp_find_vq(ioaddr, 0, vdrive_g->vq) < 0 ) { + if (vp_find_vq(ioaddr, 0, &vdrive_g->vq) < 0 ) { dprintf(1, "fail to find vq for virtio-blk %x:%x\n", pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf)); goto fail; @@ -154,8 +151,8 @@ init_virtio_blk(struct pci_device *pci) return;
fail: + free(vdrive_g->vq); free(vdrive_g); - free(vq); }
void diff --git a/src/virtio-pci.c b/src/virtio-pci.c index 6a23d5d..7e0c1a5 100644 --- a/src/virtio-pci.c +++ b/src/virtio-pci.c @@ -21,12 +21,18 @@ #include "util.h" // dprintf
int vp_find_vq(unsigned int ioaddr, int queue_index, - struct vring_virtqueue *vq) + struct vring_virtqueue **p_vq) { - struct vring * vr = &vq->vring; u16 num;
ASSERT32FLAT(); + struct vring_virtqueue *vq = *p_vq = memalign_low(PAGE_SIZE, sizeof(*vq)); + if (!vq) { + warn_noalloc(); + goto fail; + } + memset(vq, 0, sizeof(*vq)); + /* select the queue */
outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL); @@ -36,25 +42,26 @@ int vp_find_vq(unsigned int ioaddr, int queue_index, num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM); if (!num) { dprintf(1, "ERROR: queue size is 0\n"); - return -1; + goto fail; }
if (num > MAX_QUEUE_NUM) { dprintf(1, "ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM); - return -1; + goto fail; }
/* check if the queue is already active */
if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) { dprintf(1, "ERROR: queue already active\n"); - return -1; + goto fail; }
vq->queue_index = queue_index;
/* initialize the queue */
+ struct vring * vr = &vq->vring; vring_init(vr, num, (unsigned char*)&vq->queue);
/* activate the queue @@ -66,6 +73,11 @@ int vp_find_vq(unsigned int ioaddr, int queue_index, ioaddr + VIRTIO_PCI_QUEUE_PFN);
return num; + +fail: + free(vq); + *p_vq = NULL; + return -1; }
u16 vp_init_simple(u16 bdf) diff --git a/src/virtio-pci.h b/src/virtio-pci.h index 60e7b35..e1d972d 100644 --- a/src/virtio-pci.h +++ b/src/virtio-pci.h @@ -101,5 +101,5 @@ static inline void vp_del_vq(unsigned int ioaddr, int queue_index) struct vring_virtqueue; u16 vp_init_simple(u16 bdf); int vp_find_vq(unsigned int ioaddr, int queue_index, - struct vring_virtqueue *vq); + struct vring_virtqueue **p_vq); #endif /* _VIRTIO_PCI_H_ */