[SeaBIOS] [PATCH 16/16] virtio-pci: allocate vq in vp_find_vq
Paolo Bonzini
pbonzini at redhat.com
Wed Nov 16 13:02:57 CET 2011
Another common bit that can be made generic.
Signed-off-by: Paolo Bonzini <pbonzini at 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_ */
--
1.7.7.1
More information about the SeaBIOS
mailing list