diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2014-11-27 13:54:28 +0200 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2014-12-09 12:05:24 +0200 |
commit | 732c56e9845a5594a686eb4635397e91593dd4e1 (patch) | |
tree | c54a3dccf5e47c6a2a185a78ad825e165fbd1e23 | |
parent | 93d389f82078cf7197152fb10d21977da0883420 (diff) |
virtio_ccw: add support for 64 bit features.
Negotiate full 64 bit features.
Change u32 to u64, make sure to use 1ULL everywhere.
Note: devices guarantee that VERSION_1 is clear unless
revision 1 is negotiated.
Note: We don't need to re-setup the ccw, but we do it
for clarity.
Based on patches by Rusty, Thomas Huth and Cornelia.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: David Hildebrand <dahi@linux.vnet.ibm.com>
-rw-r--r-- | drivers/s390/kvm/virtio_ccw.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c index 244d611a0df2..65d0c80236ee 100644 --- a/drivers/s390/kvm/virtio_ccw.c +++ b/drivers/s390/kvm/virtio_ccw.c @@ -664,7 +664,8 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev) { struct virtio_ccw_device *vcdev = to_vc_device(vdev); struct virtio_feature_desc *features; - int ret, rc; + int ret; + u64 rc; struct ccw1 *ccw; ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL); @@ -677,7 +678,6 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev) goto out_free; } /* Read the feature bits from the host. */ - /* TODO: Features > 32 bits */ features->index = 0; ccw->cmd_code = CCW_CMD_READ_FEAT; ccw->flags = 0; @@ -691,6 +691,16 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev) rc = le32_to_cpu(features->features); + /* Read second half of the feature bits from the host. */ + features->index = 1; + ccw->cmd_code = CCW_CMD_READ_FEAT; + ccw->flags = 0; + ccw->count = sizeof(*features); + ccw->cda = (__u32)(unsigned long)features; + ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_FEAT); + if (ret == 0) + rc |= (u64)le32_to_cpu(features->features) << 32; + out_free: kfree(features); kfree(ccw); @@ -714,12 +724,18 @@ static void virtio_ccw_finalize_features(struct virtio_device *vdev) /* Give virtio_ring a chance to accept features. */ vring_transport_features(vdev); - /* Make sure we don't have any features > 32 bits! */ - BUG_ON((u32)vdev->features != vdev->features); - features->index = 0; - features->features = cpu_to_le32(vdev->features); - /* Write the feature bits to the host. */ + features->features = cpu_to_le32((u32)vdev->features); + /* Write the first half of the feature bits to the host. */ + ccw->cmd_code = CCW_CMD_WRITE_FEAT; + ccw->flags = 0; + ccw->count = sizeof(*features); + ccw->cda = (__u32)(unsigned long)features; + ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT); + + features->index = 1; + features->features = cpu_to_le32(vdev->features >> 32); + /* Write the second half of the feature bits to the host. */ ccw->cmd_code = CCW_CMD_WRITE_FEAT; ccw->flags = 0; ccw->count = sizeof(*features); |