virtio-pci: allocate vq in vp_find_vq
authorPaolo Bonzini <pbonzini@redhat.com>
Wed, 16 Nov 2011 12:02:57 +0000 (13:02 +0100)
committerKevin O'Connor <kevin@koconnor.net>
Fri, 18 Nov 2011 02:21:02 +0000 (21:21 -0500)
Another common bit that can be made generic.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
src/virtio-blk.c
src/virtio-pci.c
src/virtio-pci.h

index 9ed82e095304660553b7e95e682ca3c58e834308..b869189ee15b2ddb6e9657af860fc00f1c3ae924 100644 (file)
@@ -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
index 6a23d5d8c67fe9c2fda480536d9ec7bb16b5e88d..7e0c1a52d5b9ce696e4dddb3b68c8f42d7b95a9f 100644 (file)
 #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)
index 60e7b357f1b1b0b9a808775235aec410a073f8c9..e1d972dc53275bddfd4966c0295ed91682f9ac06 100644 (file)
@@ -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_ */