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>
This commit is contained in:
Michael S. Tsirkin 2014-11-27 13:54:28 +02:00
parent 93d389f820
commit 732c56e984

View File

@ -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_ccw_device *vcdev = to_vc_device(vdev);
struct virtio_feature_desc *features; struct virtio_feature_desc *features;
int ret, rc; int ret;
u64 rc;
struct ccw1 *ccw; struct ccw1 *ccw;
ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL); 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; goto out_free;
} }
/* Read the feature bits from the host. */ /* Read the feature bits from the host. */
/* TODO: Features > 32 bits */
features->index = 0; features->index = 0;
ccw->cmd_code = CCW_CMD_READ_FEAT; ccw->cmd_code = CCW_CMD_READ_FEAT;
ccw->flags = 0; ccw->flags = 0;
@ -691,6 +691,16 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev)
rc = le32_to_cpu(features->features); 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: out_free:
kfree(features); kfree(features);
kfree(ccw); kfree(ccw);
@ -714,12 +724,18 @@ static void virtio_ccw_finalize_features(struct virtio_device *vdev)
/* Give virtio_ring a chance to accept features. */ /* Give virtio_ring a chance to accept features. */
vring_transport_features(vdev); 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->index = 0;
features->features = cpu_to_le32(vdev->features); features->features = cpu_to_le32((u32)vdev->features);
/* Write the feature bits to the host. */ /* 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->cmd_code = CCW_CMD_WRITE_FEAT;
ccw->flags = 0; ccw->flags = 0;
ccw->count = sizeof(*features); ccw->count = sizeof(*features);