diff options
Diffstat (limited to 'src/hw/virtio-blk.c')
-rw-r--r-- | src/hw/virtio-blk.c | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c index 3b198965..2653dad2 100644 --- a/src/hw/virtio-blk.c +++ b/src/hw/virtio-blk.c @@ -121,12 +121,16 @@ init_virtio_blk(void *data) u64 version1 = 1ull << VIRTIO_F_VERSION_1; u64 iommu_platform = 1ull << VIRTIO_F_IOMMU_PLATFORM; u64 blk_size = 1ull << VIRTIO_BLK_F_BLK_SIZE; + u64 max_segments = 1ull << VIRTIO_BLK_F_SEG_MAX; + u64 max_segment_size = 1ull << VIRTIO_BLK_F_SIZE_MAX; + if (!(features & version1)) { dprintf(1, "modern device without virtio_1 feature bit: %pP\n", pci); goto fail; } - features = features & (version1 | iommu_platform | blk_size); + features = features & (version1 | iommu_platform | blk_size + | max_segments | max_segment_size); vp_set_features(vp, features); status |= VIRTIO_CONFIG_S_FEATURES_OK; vp_set_status(vp, status); @@ -135,6 +139,14 @@ init_virtio_blk(void *data) goto fail; } + if (features & max_segment_size) + vdrive->drive.max_segment_size = + vp_read(&vp->device, struct virtio_blk_config, size_max); + + if (features & max_segments) + vdrive->drive.max_segments = + vp_read(&vp->device, struct virtio_blk_config, seg_max); + vdrive->drive.sectors = vp_read(&vp->device, struct virtio_blk_config, capacity); if (features & blk_size) { @@ -148,8 +160,10 @@ init_virtio_blk(void *data) pci, vdrive->drive.blksize); goto fail; } - dprintf(3, "virtio-blk %pP blksize=%d sectors=%u\n", - pci, vdrive->drive.blksize, (u32)vdrive->drive.sectors); + dprintf(3, "virtio-blk %pP blksize=%d sectors=%u size_max=%u " + "seg_max=%u.\n", pci, vdrive->drive.blksize, + (u32)vdrive->drive.sectors, vdrive->drive.max_segment_size, + vdrive->drive.max_segments); vdrive->drive.pchs.cylinder = vp_read(&vp->device, struct virtio_blk_config, cylinders); @@ -165,9 +179,17 @@ init_virtio_blk(void *data) vdrive->drive.blksize = (f & (1 << VIRTIO_BLK_F_BLK_SIZE)) ? cfg.blk_size : DISK_SECTOR_SIZE; + if (f & (1 << VIRTIO_BLK_F_SIZE_MAX)) + vdrive->drive.max_segment_size = cfg.size_max; + + if (f & (1 << VIRTIO_BLK_F_SEG_MAX)) + vdrive->drive.max_segments = cfg.seg_max; + vdrive->drive.sectors = cfg.capacity; - dprintf(3, "virtio-blk %pP blksize=%d sectors=%u\n", - pci, vdrive->drive.blksize, (u32)vdrive->drive.sectors); + dprintf(3, "virtio-blk %pP blksize=%d sectors=%u size_max=%u " + "seg_max=%u.\n", pci, vdrive->drive.blksize, + (u32)vdrive->drive.sectors, vdrive->drive.max_segment_size, + vdrive->drive.max_segments); if (vdrive->drive.blksize != DISK_SECTOR_SIZE) { dprintf(1, "virtio-blk %pP block size %d is unsupported\n", @@ -218,8 +240,11 @@ init_virtio_blk_mmio(void *mmio) u64 features = vp_get_features(vp); u64 version1 = 1ull << VIRTIO_F_VERSION_1; u64 blk_size = 1ull << VIRTIO_BLK_F_BLK_SIZE; + u64 max_segments = 1ull << VIRTIO_BLK_F_SEG_MAX; + u64 max_segment_size = 1ull << VIRTIO_BLK_F_SIZE_MAX; - features = features & (version1 | blk_size); + features = features & (version1 | blk_size + | max_segments | max_segment_size); vp_set_features(vp, features); status |= VIRTIO_CONFIG_S_FEATURES_OK; vp_set_status(vp, status); @@ -228,6 +253,14 @@ init_virtio_blk_mmio(void *mmio) goto fail; } + if (features & max_segment_size) + vdrive->drive.max_segment_size = + vp_read(&vp->device, struct virtio_blk_config, size_max); + + if (features & max_segments) + vdrive->drive.max_segments = + vp_read(&vp->device, struct virtio_blk_config, seg_max); + vdrive->drive.sectors = vp_read(&vp->device, struct virtio_blk_config, capacity); if (features & blk_size) { @@ -241,8 +274,10 @@ init_virtio_blk_mmio(void *mmio) mmio, vdrive->drive.blksize); goto fail; } - dprintf(1, "virtio-blk-mmio %p blksize=%d sectors=%u\n", - mmio, vdrive->drive.blksize, (u32)vdrive->drive.sectors); + dprintf(1, "virtio-blk-mmio %p blksize=%d sectors=%u size_max=%u " + "seg_max=%u.\n", mmio, vdrive->drive.blksize, + (u32)vdrive->drive.sectors, vdrive->drive.max_segment_size, + vdrive->drive.max_segments); vdrive->drive.pchs.cylinder = vp_read(&vp->device, struct virtio_blk_config, cylinders); |