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);
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) {
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);
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",
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);
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) {
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);