^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/virtio_byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/virtio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <uapi/linux/virtio_config.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * __virtio_test_bit - helper to test feature bits. For use by transports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Devices should normally use virtio_has_feature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * which includes more checks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * @vdev: the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * @fbit: the feature bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) static inline bool __virtio_test_bit(const struct virtio_device *vdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) unsigned int fbit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) return vdev->features & (1ULL << fbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * __virtio_set_bit - helper to set feature bits. For use by transports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * @vdev: the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * @fbit: the feature bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static inline void __virtio_set_bit(struct virtio_device *vdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) unsigned int fbit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) vdev->features |= (1ULL << fbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * __virtio_clear_bit - helper to clear feature bits. For use by transports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * @vdev: the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * @fbit: the feature bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static inline void __virtio_clear_bit(struct virtio_device *vdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned int fbit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) vdev->features &= ~(1ULL << fbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define virtio_has_feature(dev, feature) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) (__virtio_test_bit((dev), feature))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * virtio_has_dma_quirk - determine whether this device has the DMA quirk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @vdev: the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static inline bool virtio_has_dma_quirk(const struct virtio_device *vdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Note the reverse polarity of the quirk feature (compared to most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * other features), this is for compatibility with legacy systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return !virtio_has_feature(vdev, VIRTIO_F_ACCESS_PLATFORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static inline bool virtio_is_little_endian(struct virtio_device *vdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return virtio_has_feature(vdev, VIRTIO_F_VERSION_1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) virtio_legacy_is_little_endian();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Memory accessors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return __virtio16_to_cpu(virtio_is_little_endian(vdev), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return __cpu_to_virtio16(virtio_is_little_endian(vdev), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return __virtio32_to_cpu(virtio_is_little_endian(vdev), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return __cpu_to_virtio32(virtio_is_little_endian(vdev), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return __virtio64_to_cpu(virtio_is_little_endian(vdev), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return __cpu_to_virtio64(virtio_is_little_endian(vdev), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }