diff options
| author | Michael S. Tsirkin <mst@redhat.com> | 2014-11-27 06:54:28 -0500 |
|---|---|---|
| committer | Michael S. Tsirkin <mst@redhat.com> | 2014-12-09 05:05:24 -0500 |
| 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) | |||
| 664 | { | 664 | { |
| 665 | struct virtio_ccw_device *vcdev = to_vc_device(vdev); | 665 | struct virtio_ccw_device *vcdev = to_vc_device(vdev); |
| 666 | struct virtio_feature_desc *features; | 666 | struct virtio_feature_desc *features; |
| 667 | int ret, rc; | 667 | int ret; |
| 668 | u64 rc; | ||
| 668 | struct ccw1 *ccw; | 669 | struct ccw1 *ccw; |
| 669 | 670 | ||
| 670 | ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL); | 671 | ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL); |
| @@ -677,7 +678,6 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev) | |||
| 677 | goto out_free; | 678 | goto out_free; |
| 678 | } | 679 | } |
| 679 | /* Read the feature bits from the host. */ | 680 | /* Read the feature bits from the host. */ |
| 680 | /* TODO: Features > 32 bits */ | ||
| 681 | features->index = 0; | 681 | features->index = 0; |
| 682 | ccw->cmd_code = CCW_CMD_READ_FEAT; | 682 | ccw->cmd_code = CCW_CMD_READ_FEAT; |
| 683 | ccw->flags = 0; | 683 | ccw->flags = 0; |
| @@ -691,6 +691,16 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev) | |||
| 691 | 691 | ||
| 692 | rc = le32_to_cpu(features->features); | 692 | rc = le32_to_cpu(features->features); |
| 693 | 693 | ||
| 694 | /* Read second half of the feature bits from the host. */ | ||
| 695 | features->index = 1; | ||
| 696 | ccw->cmd_code = CCW_CMD_READ_FEAT; | ||
| 697 | ccw->flags = 0; | ||
| 698 | ccw->count = sizeof(*features); | ||
| 699 | ccw->cda = (__u32)(unsigned long)features; | ||
| 700 | ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_FEAT); | ||
| 701 | if (ret == 0) | ||
| 702 | rc |= (u64)le32_to_cpu(features->features) << 32; | ||
| 703 | |||
| 694 | out_free: | 704 | out_free: |
| 695 | kfree(features); | 705 | kfree(features); |
| 696 | kfree(ccw); | 706 | kfree(ccw); |
| @@ -714,12 +724,18 @@ static void virtio_ccw_finalize_features(struct virtio_device *vdev) | |||
| 714 | /* Give virtio_ring a chance to accept features. */ | 724 | /* Give virtio_ring a chance to accept features. */ |
| 715 | vring_transport_features(vdev); | 725 | vring_transport_features(vdev); |
| 716 | 726 | ||
| 717 | /* Make sure we don't have any features > 32 bits! */ | ||
| 718 | BUG_ON((u32)vdev->features != vdev->features); | ||
| 719 | |||
| 720 | features->index = 0; | 727 | features->index = 0; |
| 721 | features->features = cpu_to_le32(vdev->features); | 728 | features->features = cpu_to_le32((u32)vdev->features); |
| 722 | /* Write the feature bits to the host. */ | 729 | /* Write the first half of the feature bits to the host. */ |
| 730 | ccw->cmd_code = CCW_CMD_WRITE_FEAT; | ||
| 731 | ccw->flags = 0; | ||
| 732 | ccw->count = sizeof(*features); | ||
| 733 | ccw->cda = (__u32)(unsigned long)features; | ||
| 734 | ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT); | ||
| 735 | |||
| 736 | features->index = 1; | ||
| 737 | features->features = cpu_to_le32(vdev->features >> 32); | ||
| 738 | /* Write the second half of the feature bits to the host. */ | ||
| 723 | ccw->cmd_code = CCW_CMD_WRITE_FEAT; | 739 | ccw->cmd_code = CCW_CMD_WRITE_FEAT; |
| 724 | ccw->flags = 0; | 740 | ccw->flags = 0; |
| 725 | ccw->count = sizeof(*features); | 741 | ccw->count = sizeof(*features); |
