static int vop_finalize_features(struct virtio_device *vdev) { unsigned int i, bits; struct mic_device_desc __iomem *desc = to_vopvdev(vdev)->desc; u8 feature_len = ioread8(&desc->feature_len); /* Second half of bitmap is features we accept. */ u8 __iomem *out_features = _vop_vq_features(desc) + feature_len; /* Give virtio_ring a chance to accept features. */ vring_transport_features(vdev); /* Give virtio_vop a chance to accept features. */ vop_transport_features(vdev); memset_io(out_features, 0, feature_len); bits = min_t(unsigned, feature_len, sizeof(vdev->features)) * 8; for (i = 0; i < bits; i++) { if (__virtio_test_bit(vdev, i)) iowrite8(ioread8(&out_features[i / 8]) | (1 << (i % 8)), &out_features[i / 8]); } return 0; }
/* This gets the device's feature bits. */ static u64 vop_get_features(struct virtio_device *vdev) { unsigned int i, bits; u32 features = 0; struct mic_device_desc __iomem *desc = to_vopvdev(vdev)->desc; u8 __iomem *in_features = _vop_vq_features(desc); int feature_len = ioread8(&desc->feature_len); bits = min_t(unsigned, feature_len, sizeof(vdev->features)) * 8; for (i = 0; i < bits; i++) if (ioread8(&in_features[i / 8]) & (BIT(i % 8))) features |= BIT(i); return features; }
static inline u8 __iomem * _vop_vq_configspace(struct mic_device_desc __iomem *desc) { return _vop_vq_features(desc) + ioread8(&desc->feature_len) * 2; }