aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorThomas Huth <thuth@redhat.com>2016-11-24 09:56:07 +0100
committerAlexey Kardashevskiy <aik@ozlabs.ru>2016-11-24 23:24:18 +1100
commit9290756ae1195b331373dbcfd3b37d978b3b71f4 (patch)
tree10cbafc1acf44c10c055ac275ce642b3fd24f650 /lib
parent9b8945ecbde65b06ea2ab9e28a6178024b0420fb (diff)
downloadSLOF-9290756ae1195b331373dbcfd3b37d978b3b71f4.zip
SLOF-9290756ae1195b331373dbcfd3b37d978b3b71f4.tar.gz
SLOF-9290756ae1195b331373dbcfd3b37d978b3b71f4.tar.bz2
virtio-scsi: Fix descriptor order for SCSI WRITE commands
Virtio needs the descriptors ordered: All descriptors for buffers that contain data that should go *to* the device have to be put into the queue first. The descriptors for buffers that read *from* the device have to be sorted in last. For SCSI WRITE commands (which we never used in the past), the order was wrong, so QEMU complains with a "Incorrect order for descriptors" message as soon as we use it for SCSI WRITE commands. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Diffstat (limited to 'lib')
-rw-r--r--lib/libvirtio/virtio-scsi.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/lib/libvirtio/virtio-scsi.c b/lib/libvirtio/virtio-scsi.c
index 04181b0..36b62d1 100644
--- a/lib/libvirtio/virtio-scsi.c
+++ b/lib/libvirtio/virtio-scsi.c
@@ -49,18 +49,27 @@ int virtioscsi_send(struct virtio_device *dev,
virtio_fill_desc(&vq_desc[id], dev->is_modern, (uint64_t)req, sizeof(*req), VRING_DESC_F_NEXT,
(id + 1) % vq_size);
- /* Set up virtqueue descriptor for data */
- if (buf && buf_len) {
+ if (buf == NULL || buf_len == 0) {
+ /* Set up descriptor for response information */
+ virtio_fill_desc(&vq_desc[(id + 1) % vq_size], dev->is_modern,
+ (uint64_t)resp, sizeof(*resp),
+ VRING_DESC_F_WRITE, 0);
+ } else if (is_read) {
+ /* Set up descriptor for response information */
virtio_fill_desc(&vq_desc[(id + 1) % vq_size], dev->is_modern,
(uint64_t)resp, sizeof(*resp),
VRING_DESC_F_NEXT | VRING_DESC_F_WRITE,
(id + 2) % vq_size);
- /* Set up virtqueue descriptor for status */
+ /* Set up virtqueue descriptor for data from device */
virtio_fill_desc(&vq_desc[(id + 2) % vq_size], dev->is_modern,
- (uint64_t)buf, buf_len,
- (is_read ? VRING_DESC_F_WRITE : 0), 0);
+ (uint64_t)buf, buf_len, VRING_DESC_F_WRITE, 0);
} else {
+ /* Set up virtqueue descriptor for data to device */
virtio_fill_desc(&vq_desc[(id + 1) % vq_size], dev->is_modern,
+ (uint64_t)buf, buf_len, VRING_DESC_F_NEXT,
+ (id + 2) % vq_size);
+ /* Set up descriptor for response information */
+ virtio_fill_desc(&vq_desc[(id + 2) % vq_size], dev->is_modern,
(uint64_t)resp, sizeof(*resp),
VRING_DESC_F_WRITE, 0);
}