[SeaBIOS] [PATCHv2] fix two issues with virtio-blk
Kevin O'Connor
kevin at koconnor.net
Tue May 18 01:27:30 CEST 2010
On Mon, May 17, 2010 at 04:27:27PM +0300, Gleb Natapov wrote:
> 1. Check if blk_size is valid in virtio_blk config.
> 2. Disable interrupt otherwise interrupt may stuck
> with some guests.
>
> Signed-off-by: Gleb Natapov <gleb at redhat.com>
Thanks. I committed your change to my local repo. I don't much like
that goto though - is it okay if we break up virtio_blk_setup with the
patch below (on top of your patch)?
-Kevin
diff --git a/src/virtio-blk.c b/src/virtio-blk.c
index e6167e9..7f9b3d2 100644
--- a/src/virtio-blk.c
+++ b/src/virtio-blk.c
@@ -85,6 +85,79 @@ process_virtio_op(struct disk_op_s *op)
}
}
+static void
+init_virtio_blk(u16 bdf)
+{
+ dprintf(1, "found virtio-blk at %x:%x\n", pci_bdf_to_bus(bdf),
+ pci_bdf_to_dev(bdf));
+ char *desc = malloc_tmphigh(MAXDESCSIZE);
+ struct virtiodrive_s *vdrive_g = malloc_fseg(sizeof(*vdrive_g));
+ struct vring_virtqueue *vq = memalign_low(PAGE_SIZE, sizeof(*vq));
+ if (!vdrive_g || !desc || !vq) {
+ warn_noalloc();
+ goto fail;
+ }
+ memset(vdrive_g, 0, sizeof(*vdrive_g));
+ vdrive_g->drive.type = DTYPE_VIRTIO;
+ vdrive_g->drive.cntl_id = bdf;
+ vdrive_g->vq = vq;
+
+ u16 ioaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) &
+ PCI_BASE_ADDRESS_IO_MASK;
+
+ vdrive_g->ioaddr = ioaddr;
+
+ vp_reset(ioaddr);
+ vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
+ VIRTIO_CONFIG_S_DRIVER );
+
+ 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;
+ }
+
+ struct virtio_blk_config cfg;
+ vp_get(ioaddr, 0, &cfg, sizeof(cfg));
+
+ u32 f = vp_get_features(ioaddr);
+ vdrive_g->drive.blksize = (f & (1 << VIRTIO_BLK_F_BLK_SIZE)) ?
+ cfg.blk_size : DISK_SECTOR_SIZE;
+
+ vdrive_g->drive.sectors = cfg.capacity;
+ dprintf(3, "virtio-blk %x:%x blksize=%d sectors=%u\n",
+ pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf),
+ vdrive_g->drive.blksize, (u32)vdrive_g->drive.sectors);
+
+ if (vdrive_g->drive.blksize != DISK_SECTOR_SIZE) {
+ dprintf(1, "virtio-blk %x:%x block size %d is unsupported\n",
+ pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf),
+ vdrive_g->drive.blksize);
+ goto fail;
+ }
+
+ vdrive_g->drive.pchs.cylinders = cfg.cylinders;
+ vdrive_g->drive.pchs.heads = cfg.heads;
+ vdrive_g->drive.pchs.spt = cfg.sectors;
+
+ setup_translation(&vdrive_g->drive);
+ add_bcv_internal(&vdrive_g->drive);
+
+ snprintf(desc, MAXDESCSIZE, "Virtio disk PCI:%x:%x",
+ pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf));
+
+ vdrive_g->drive.desc = desc;
+
+ vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
+ VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK);
+ return;
+
+fail:
+ free(vdrive_g);
+ free(desc);
+ free(vq);
+}
+
void
virtio_blk_setup(void)
{
@@ -100,74 +173,6 @@ virtio_blk_setup(void)
u32 v = pci_config_readl(bdf, PCI_VENDOR_ID);
if (v != id)
continue;
- dprintf(3, "found virtio-blk at %x:%x\n", pci_bdf_to_bus(bdf),
- pci_bdf_to_dev(bdf));
- char *desc = malloc_tmphigh(MAXDESCSIZE);
- struct virtiodrive_s *vdrive_g = malloc_fseg(sizeof(*vdrive_g));
- struct vring_virtqueue *vq = memalign_low(PAGE_SIZE, sizeof(*vq));
- if (!vdrive_g || !desc || !vq) {
- free(vdrive_g);
- free(desc);
- free(vq);
- warn_noalloc();
- return;
- }
- memset(vdrive_g, 0, sizeof(*vdrive_g));
- vdrive_g->drive.type = DTYPE_VIRTIO;
- vdrive_g->drive.cntl_id = bdf;
- vdrive_g->vq = vq;
-
- u16 ioaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) &
- PCI_BASE_ADDRESS_IO_MASK;
-
- vdrive_g->ioaddr = ioaddr;
-
- vp_reset(ioaddr);
- vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
- VIRTIO_CONFIG_S_DRIVER );
-
- 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));
- next:
- free(vdrive_g);
- free(desc);
- free(vq);
- continue;
- }
-
- struct virtio_blk_config cfg;
- vp_get(ioaddr, 0, &cfg, sizeof(cfg));
-
- u32 f = vp_get_features(ioaddr);
- vdrive_g->drive.blksize = (f & (1 << VIRTIO_BLK_F_BLK_SIZE)) ?
- cfg.blk_size : DISK_SECTOR_SIZE;
-
- vdrive_g->drive.sectors = cfg.capacity;
- dprintf(3, "virtio-blk %x:%x blksize=%d sectors=%u\n",
- pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf),
- vdrive_g->drive.blksize, (u32)vdrive_g->drive.sectors);
-
- if (vdrive_g->drive.blksize != DISK_SECTOR_SIZE) {
- dprintf(1, "virtio-blk %x:%x block size %d is unsupported\n",
- pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf),
- vdrive_g->drive.blksize);
- goto next;
- }
-
- vdrive_g->drive.pchs.cylinders = cfg.cylinders;
- vdrive_g->drive.pchs.heads = cfg.heads;
- vdrive_g->drive.pchs.spt = cfg.sectors;
-
- setup_translation(&vdrive_g->drive);
- add_bcv_internal(&vdrive_g->drive);
-
- snprintf(desc, MAXDESCSIZE, "Virtio disk PCI:%x:%x",
- pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf));
-
- vdrive_g->drive.desc = desc;
-
- vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
- VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK);
+ init_virtio_blk(bdf);
}
}
More information about the SeaBIOS
mailing list