Dor Laor wrote:
Anthony Liguori wrote:
Subject: [PATCH 3/3] virtio block device
+
+static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+ VirtIOBlock *s = to_virtio_blk(vdev);
+ VirtQueueElement elem;
+ unsigned int count;
+
+ while ((count = virtqueue_pop(vq, &elem)) != 0) {
+ struct virtio_blk_inhdr *in;
+ struct virtio_blk_outhdr *out;
+ unsigned int wlen;
+ off_t off;
+ int i;
+
+ out = (void *)elem.out_sg[0].iov_base;
+ in = (void *)elem.in_sg[elem.in_num - 1].iov_base;
+ off = out->sector;
+
+ if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
+ wlen = sizeof(*in);
+ in->status = VIRTIO_BLK_S_UNSUPP;
+ } else if (out->type & VIRTIO_BLK_T_OUT) {
+ wlen = sizeof(*in);
+
+ for (i = 1; i < elem.out_num; i++) {
+ bdrv_write(s->bs, off,
+ elem.out_sg[i].iov_base,
+ elem.out_sg[i].iov_len / 512);
+ off += elem.out_sg[i].iov_len / 512;
+ }
+
+ in->status = VIRTIO_BLK_S_OK;
+ } else {
+ wlen = sizeof(*in);
+
+ for (i = 0; i < elem.in_num - 1; i++) {
+ bdrv_read(s->bs, off,
+ elem.in_sg[i].iov_base,
+ elem.in_sg[i].iov_len / 512);
+ off += elem.in_sg[i].iov_len / 512;
+ wlen += elem.in_sg[i].iov_len;
+ }
+
+ in->status = VIRTIO_BLK_S_OK;
+ }
+
+ virtqueue_push(vq, &elem, wlen);
+ virtio_notify(vdev, vq);
+ }
The notify here should also be outside the while loop.
Yeah, that's in the optimization patch.
===================================================================
--- qemu.orig/sysemu.h 2007-12-04 13:51:49.000000000 -0600
+++ qemu/sysemu.h 2007-12-04 14:18:57.000000000 -0600
@@ -117,7 +117,7 @@
#endif
typedef enum {
- IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD
+ IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO
} BlockInterfaceType;
typedef struct DriveInfo {
Index: qemu/hw/pc.c
===================================================================
--- qemu.orig/hw/pc.c 2007-12-04 13:51:49.000000000 -0600
+++ qemu/hw/pc.c 2007-12-04 14:18:57.000000000 -0600
@@ -1008,6 +1008,18 @@
}
}
}
+
+ /* Add virtio block devices */
+ if (pci_enabled) {
+ int index;
+ int unit_id = 0;
+
+ while ((index = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
+ virtio_blk_init(pci_bus, 0x5002, 0x2258,
The pci vendor id should be identical to the network (0x6900)
Indeed! That's for catching that.
Regards,
Anthony Liguori
regards,
Dor.