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.
Unified · Split
| @@ -664,7 +664,8 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev) · 663 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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) · 17 unmodified lines | |||
| 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); |