[SLOF] [PATCH v2 13/19] virtio: make all virtio apis 1.0 aware
Alexey Kardashevskiy
aik at ozlabs.ru
Fri Jan 22 15:56:09 AEDT 2016
On 01/20/2016 11:10 PM, Nikunj A Dadhania wrote:
> Convert the following routines:
> virtio_get_qsize
> virtio_vring_desc
> virtio_get_vring_avail
> virtio_get_vring_used
> virtio_set_status: also use it in device reset.
> virtio_queue_notify
> virtio_set_qaddr
> virtio_{get,read}_config
> virtio_fill_desc
>
> Signed-off-by: Nikunj A Dadhania <nikunj at linux.vnet.ibm.com>
> ---
> lib/libvirtio/virtio.c | 127 +++++++++++++++++++++++++++++++++++++++++--------
> lib/libvirtio/virtio.h | 2 +-
> 2 files changed, 108 insertions(+), 21 deletions(-)
>
> diff --git a/lib/libvirtio/virtio.c b/lib/libvirtio/virtio.c
> index 1331efd..c2dd7dc 100644
> --- a/lib/libvirtio/virtio.c
> +++ b/lib/libvirtio/virtio.c
> @@ -94,11 +94,20 @@ unsigned long virtio_vring_size(unsigned int qsize)
> * @param queue virtio queue number
> * @return number of elements
> */
> -int virtio_get_qsize(struct virtio_device *dev, int queue)
> +unsigned int virtio_get_qsize(struct virtio_device *dev, int queue)
> {
> - int size = 0;
> + unsigned int size = 0;
>
> - if (dev->type == VIRTIO_TYPE_PCI) {
> + if (dev->type != VIRTIO_TYPE_PCI)
> + return 0;
> + if (dev->is_modern) {
> + void *addr = dev->common.addr + offset_of(struct virtio_dev_common, q_select);
> + ci_write_16(addr, cpu_to_le16(queue));
> + eieio();
> + /* read qsize */
addr = dev->common.addr + offset_of(struct virtio_dev_common, q_size);
> + size = le16_to_cpu(ci_read_16(addr + 2));
size = le16_to_cpu(ci_read_16(addr));
as the legacy code uses VIRTIOHDR_QUEUE_SELECT and VIRTIOHDR_QUEUE_SIZE,
not magic constant, like you have it done in virtio_get_vring_desc() and
other places.
> + }
> + else {
> ci_write_16(dev->base+VIRTIOHDR_QUEUE_SELECT,
> cpu_to_le16(queue));
> eieio();
> @@ -119,7 +128,16 @@ struct vring_desc *virtio_get_vring_desc(struct virtio_device *dev, int queue)
> {
> struct vring_desc *desc = 0;
>
> - if (dev->type == VIRTIO_TYPE_PCI) {
> + if (dev->type != VIRTIO_TYPE_PCI)
> + return NULL;
> + if (dev->is_modern) {
> + void *q_sel = dev->common.addr + offset_of(struct virtio_dev_common, q_select);
> + void *q_desc = dev->common.addr + offset_of(struct virtio_dev_common, q_desc);
> +
> + ci_write_16(q_sel, cpu_to_le16(queue));
> + eieio();
> + desc = (void *)(virtio_read64(q_desc));
> + } else {
> ci_write_16(dev->base+VIRTIOHDR_QUEUE_SELECT,
> cpu_to_le16(queue));
> eieio();
> @@ -139,8 +157,20 @@ struct vring_desc *virtio_get_vring_desc(struct virtio_device *dev, int queue)
> */
> struct vring_avail *virtio_get_vring_avail(struct virtio_device *dev, int queue)
> {
> - return (void*)((uint64_t)virtio_get_vring_desc(dev, queue)
> - + virtio_get_qsize(dev, queue) * sizeof(struct vring_desc));
> + if (dev->type != VIRTIO_TYPE_PCI)
> + return NULL;
> + if (dev->is_modern) {
> + void *q_sel = dev->common.addr + offset_of(struct virtio_dev_common, q_select);
> + void *q_avail = dev->common.addr + offset_of(struct virtio_dev_common, q_avail);
> +
> + ci_write_16(q_sel, cpu_to_le16(queue));
> + eieio();
> + return (void *)(virtio_read64(q_avail));
> + }
> + else {
> + return (void*)((uint64_t)virtio_get_vring_desc(dev, queue) +
> + virtio_get_qsize(dev, queue) * sizeof(struct vring_desc));
> + }
> }
>
>
> @@ -152,9 +182,20 @@ struct vring_avail *virtio_get_vring_avail(struct virtio_device *dev, int queue)
> */
> struct vring_used *virtio_get_vring_used(struct virtio_device *dev, int queue)
> {
> - return (void*)VQ_ALIGN((uint64_t)virtio_get_vring_avail(dev, queue)
> - + virtio_get_qsize(dev, queue)
> - * sizeof(struct vring_avail));
> + if (dev->type != VIRTIO_TYPE_PCI)
> + return NULL;
> + if (dev->is_modern) {
> + void *q_sel = dev->common.addr + offset_of(struct virtio_dev_common, q_select);
> + void *q_used = dev->common.addr + offset_of(struct virtio_dev_common, q_used);
> +
> + ci_write_16(q_sel, cpu_to_le16(queue));
> + eieio();
> + return (void *)(virtio_read64(q_used));
> + } else {
> + return (void*)VQ_ALIGN((uint64_t)virtio_get_vring_avail(dev, queue)
> + + virtio_get_qsize(dev, queue)
> + * sizeof(struct vring_avail));
> + }
> }
>
> /**
> @@ -182,9 +223,7 @@ void virtio_fill_desc(struct vring_desc *desc, bool is_modern,
> */
> void virtio_reset_device(struct virtio_device *dev)
> {
> - if (dev->type == VIRTIO_TYPE_PCI) {
> - ci_write_8(dev->base+VIRTIOHDR_DEVICE_STATUS, 0);
> - }
> + virtio_set_status(dev, 0);
> }
>
>
> @@ -193,7 +232,20 @@ void virtio_reset_device(struct virtio_device *dev)
> */
> void virtio_queue_notify(struct virtio_device *dev, int queue)
> {
> - if (dev->type == VIRTIO_TYPE_PCI) {
> + if (dev->type != VIRTIO_TYPE_PCI)
> + return;
> + if (dev->is_modern) {
> + void *q_sel = dev->common.addr + offset_of(struct virtio_dev_common, q_select);
> + void *q_ntfy = dev->common.addr + offset_of(struct virtio_dev_common, q_notify_off);
> + void *addr;
> + uint16_t q_notify_off = 0;
Redundant "= 0".
--
Alexey
More information about the SLOF
mailing list