virtio-blk: add helpers for filling descriptors
Enable virtio_fill_desc/fill_blk_hdr with legacy and modern mode for further use Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
This commit is contained in:
parent
b5a692d3f7
commit
fdb62149dc
|
@ -13,6 +13,7 @@
|
|||
#include <stdio.h>
|
||||
#include <cpu.h>
|
||||
#include <helpers.h>
|
||||
#include <byteorder.h>
|
||||
#include "virtio.h"
|
||||
#include "virtio-blk.h"
|
||||
|
||||
|
@ -82,6 +83,19 @@ virtioblk_shutdown(struct virtio_device *dev)
|
|||
virtio_reset_device(dev);
|
||||
}
|
||||
|
||||
static void fill_blk_hdr(struct virtio_blk_req *blkhdr, bool is_modern,
|
||||
uint32_t type, uint32_t ioprio, uint32_t sector)
|
||||
{
|
||||
if (is_modern) {
|
||||
blkhdr->type = cpu_to_le32(type);
|
||||
blkhdr->ioprio = cpu_to_le32(ioprio);
|
||||
blkhdr->sector = cpu_to_le64(sector);
|
||||
} else {
|
||||
blkhdr->type = type;
|
||||
blkhdr->ioprio = ioprio;
|
||||
blkhdr->sector = sector;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read blocks
|
||||
|
@ -137,33 +151,25 @@ virtioblk_read(struct virtio_device *dev, char *buf, uint64_t blocknum, long cnt
|
|||
current_used_idx = &vq_used->idx;
|
||||
|
||||
/* Set up header */
|
||||
blkhdr.type = VIRTIO_BLK_T_IN | VIRTIO_BLK_T_BARRIER;
|
||||
blkhdr.ioprio = 1;
|
||||
blkhdr.sector = blocknum * blk_size / DEFAULT_SECTOR_SIZE;
|
||||
fill_blk_hdr(&blkhdr, false, VIRTIO_BLK_T_IN | VIRTIO_BLK_T_BARRIER,
|
||||
1, blocknum * blk_size / DEFAULT_SECTOR_SIZE);
|
||||
|
||||
/* Determine descriptor index */
|
||||
id = (vq_avail->idx * 3) % vq_size;
|
||||
|
||||
/* Set up virtqueue descriptor for header */
|
||||
desc = &vq_desc[id];
|
||||
desc->addr = (uint64_t)&blkhdr;
|
||||
desc->len = sizeof(struct virtio_blk_req);
|
||||
desc->flags = VRING_DESC_F_NEXT;
|
||||
desc->next = (id + 1) % vq_size;
|
||||
virtio_fill_desc(desc, false, (uint64_t)&blkhdr, sizeof(struct virtio_blk_req),
|
||||
VRING_DESC_F_NEXT, (id + 1) % vq_size);
|
||||
|
||||
/* Set up virtqueue descriptor for data */
|
||||
desc = &vq_desc[(id + 1) % vq_size];
|
||||
desc->addr = (uint64_t)buf;
|
||||
desc->len = cnt * blk_size;
|
||||
desc->flags = VRING_DESC_F_NEXT | VRING_DESC_F_WRITE;
|
||||
desc->next = (id + 2) % vq_size;
|
||||
virtio_fill_desc(desc, false, (uint64_t)buf, cnt * blk_size,
|
||||
VRING_DESC_F_NEXT | VRING_DESC_F_WRITE, (id + 2) % vq_size);
|
||||
|
||||
/* Set up virtqueue descriptor for status */
|
||||
desc = &vq_desc[(id + 2) % vq_size];
|
||||
desc->addr = (uint64_t)&status;
|
||||
desc->len = 1;
|
||||
desc->flags = VRING_DESC_F_WRITE;
|
||||
desc->next = 0;
|
||||
virtio_fill_desc(desc, false, (uint64_t)&status, 1, VRING_DESC_F_WRITE, 0);
|
||||
|
||||
vq_avail->ring[vq_avail->idx % vq_size] = id;
|
||||
mb();
|
||||
|
|
|
@ -113,6 +113,25 @@ struct vring_used *virtio_get_vring_used(struct virtio_device *dev, int queue)
|
|||
* sizeof(struct vring_avail));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the virtio ring descriptor depending on the legacy mode or virtio 1.0
|
||||
*/
|
||||
void virtio_fill_desc(struct vring_desc *desc, bool is_modern,
|
||||
uint64_t addr, uint32_t len,
|
||||
uint16_t flags, uint16_t next)
|
||||
{
|
||||
if (is_modern) {
|
||||
desc->addr = cpu_to_le64(addr);
|
||||
desc->len = cpu_to_le32(len);
|
||||
desc->flags = cpu_to_le16(flags);
|
||||
desc->next = cpu_to_le16(next);
|
||||
} else {
|
||||
desc->addr = addr;
|
||||
desc->len = len;
|
||||
desc->flags = flags;
|
||||
desc->next = next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset virtio device
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define _LIBVIRTIO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Device status bits */
|
||||
#define VIRTIO_STAT_ACKNOWLEDGE 1
|
||||
|
@ -83,6 +84,9 @@ extern int virtio_get_qsize(struct virtio_device *dev, int queue);
|
|||
extern struct vring_desc *virtio_get_vring_desc(struct virtio_device *dev, int queue);
|
||||
extern struct vring_avail *virtio_get_vring_avail(struct virtio_device *dev, int queue);
|
||||
extern struct vring_used *virtio_get_vring_used(struct virtio_device *dev, int queue);
|
||||
extern void virtio_fill_desc(struct vring_desc *desc, bool is_modern,
|
||||
uint64_t addr, uint32_t len,
|
||||
uint16_t flags, uint16_t next);
|
||||
extern int virtio_queue_init_vq(struct virtio_device *dev, struct vqs *vq, unsigned int id);
|
||||
|
||||
extern void virtio_reset_device(struct virtio_device *dev);
|
||||
|
|
Loading…
Reference in New Issue