diff options
author | Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> | 2016-02-01 11:18:08 +0530 |
---|---|---|
committer | Alexey Kardashevskiy <aik@ozlabs.ru> | 2016-02-08 16:40:39 +1100 |
commit | 940ac04abe83647fd72f13b1efe85bce645d2196 (patch) | |
tree | d439d883da3b11215a28e5b251c07383bcae4710 | |
parent | e3a281624b47c98dacd63572ed7ce0ed8dc61391 (diff) | |
download | SLOF-940ac04abe83647fd72f13b1efe85bce645d2196.zip SLOF-940ac04abe83647fd72f13b1efe85bce645d2196.tar.gz SLOF-940ac04abe83647fd72f13b1efe85bce645d2196.tar.bz2 |
virtio: update features set/get register accessor
The new specification has a 64-bit feature register, change the
signature and update the routine to handle them.
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>
-rw-r--r-- | lib/libvirtio/virtio-blk.c | 2 | ||||
-rw-r--r-- | lib/libvirtio/virtio.c | 42 | ||||
-rw-r--r-- | lib/libvirtio/virtio.h | 4 |
3 files changed, 41 insertions, 7 deletions
diff --git a/lib/libvirtio/virtio-blk.c b/lib/libvirtio/virtio-blk.c index 26c9685..7ced1c7 100644 --- a/lib/libvirtio/virtio-blk.c +++ b/lib/libvirtio/virtio-blk.c @@ -57,7 +57,7 @@ virtioblk_init(struct virtio_device *dev) status |= VIRTIO_STAT_DRIVER_OK; virtio_set_status(dev, status); - virtio_get_host_features(dev, &features); + features = virtio_get_host_features(dev); if (features & VIRTIO_BLK_F_BLK_SIZE) { blk_size = virtio_get_config(dev, offset_of(struct virtio_blk_cfg, blk_size), diff --git a/lib/libvirtio/virtio.c b/lib/libvirtio/virtio.c index 24d3bb8..ba7aced 100644 --- a/lib/libvirtio/virtio.c +++ b/lib/libvirtio/virtio.c @@ -301,19 +301,53 @@ void virtio_set_status(struct virtio_device *dev, int status) /** * Set guest feature bits */ -void virtio_set_guest_features(struct virtio_device *dev, int features) +void virtio_set_guest_features(struct virtio_device *dev, uint64_t features) { - ci_write_32(dev->base+VIRTIOHDR_GUEST_FEATURES, bswap_32(features)); + if (dev->is_modern) { + uint32_t f1 = (features >> 32) & 0xFFFFFFFF; + uint32_t f0 = features & 0xFFFFFFFF; + void *addr = dev->common.addr; + + ci_write_32(addr + offset_of(struct virtio_dev_common, drv_features_sel), + cpu_to_le32(1)); + ci_write_32(addr + offset_of(struct virtio_dev_common, drv_features), + cpu_to_le32(f1)); + + ci_write_32(addr + offset_of(struct virtio_dev_common, drv_features_sel), + cpu_to_le32(0)); + ci_write_32(addr + offset_of(struct virtio_dev_common, drv_features), + cpu_to_le32(f0)); + } else { + ci_write_32(dev->base+VIRTIOHDR_GUEST_FEATURES, cpu_to_le32(features)); + } } /** * Get host feature bits */ -void virtio_get_host_features(struct virtio_device *dev, int *features) +uint64_t virtio_get_host_features(struct virtio_device *dev) { - *features = bswap_32(ci_read_32(dev->base+VIRTIOHDR_DEVICE_FEATURES)); + uint64_t features = 0; + if (dev->is_modern) { + uint32_t f0 = 0, f1 = 0; + void *addr = dev->common.addr; + + ci_write_32(addr + offset_of(struct virtio_dev_common, dev_features_sel), + cpu_to_le32(1)); + f1 = ci_read_32(addr + + offset_of(struct virtio_dev_common, dev_features)); + ci_write_32(addr + offset_of(struct virtio_dev_common, dev_features_sel), + cpu_to_le32(0)); + f0 = ci_read_32(addr + + offset_of(struct virtio_dev_common, dev_features)); + + features = ((uint64_t)le32_to_cpu(f1) << 32) | le32_to_cpu(f0); + } else { + features = le32_to_cpu(ci_read_32(dev->base+VIRTIOHDR_DEVICE_FEATURES)); + } + return features; } diff --git a/lib/libvirtio/virtio.h b/lib/libvirtio/virtio.h index e2543a1..bf8ea28 100644 --- a/lib/libvirtio/virtio.h +++ b/lib/libvirtio/virtio.h @@ -117,8 +117,8 @@ extern void virtio_reset_device(struct virtio_device *dev); extern void virtio_queue_notify(struct virtio_device *dev, int queue); extern void virtio_set_status(struct virtio_device *dev, int status); extern void virtio_set_qaddr(struct virtio_device *dev, int queue, unsigned long qaddr); -extern void virtio_set_guest_features(struct virtio_device *dev, int features); -extern void virtio_get_host_features(struct virtio_device *dev, int *features); +extern void virtio_set_guest_features(struct virtio_device *dev, uint64_t features); +extern uint64_t virtio_get_host_features(struct virtio_device *dev); extern uint64_t virtio_get_config(struct virtio_device *dev, int offset, int size); extern int __virtio_read_config(struct virtio_device *dev, void *dst, int offset, int len); |