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 | 665 | struct virtio_ccw_device *vcdev = to_vc_device(vdev); |
| 666 | 666 | struct virtio_feature_desc *features; |
| 667 | − int ret, rc; | |
| 667 | + int ret; | |
| 668 | + u64 rc; | |
| 668 | 669 | struct ccw1 *ccw; |
| 669 | 670 | |
| 670 | 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 | 678 | goto out_free; |
| 678 | 679 | } |
| 679 | 680 | /* Read the feature bits from the host. */ |
| 680 | − /* TODO: Features > 32 bits */ | |
| 681 | 681 | features->index = 0; |
| 682 | 682 | ccw->cmd_code = CCW_CMD_READ_FEAT; |
| 683 | 683 | ccw->flags = 0; |
| @@ -691,6 +691,16 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev) · 7 unmodified lines | ||
| 691 | 691 | |
| 692 | 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 | 704 | out_free: |
| 695 | 705 | kfree(features); |
| 696 | 706 | kfree(ccw); |
| @@ -714,12 +724,18 @@ static void virtio_ccw_finalize_features(struct virtio_device *vdev) · 17 unmodified lines | ||
| 714 | 724 | /* Give virtio_ring a chance to accept features. */ |
| 715 | 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 | 727 | features->index = 0; |
| 721 | − features->features = cpu_to_le32(vdev->features); | |
| 722 | − /* Write the feature bits to the host. */ | |
| 728 | + features->features = cpu_to_le32((u32)vdev->features); | |
| 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 | 739 | ccw->cmd_code = CCW_CMD_WRITE_FEAT; |
| 724 | 740 | ccw->flags = 0; |
| 725 | 741 | ccw->count = sizeof(*features); |