aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-05-02 22:50:49 -0400
committerRusty Russell <rusty@rustcorp.com.au>2008-05-02 07:50:50 -0400
commit72e61eb40b55dd57031ec5971e810649f82b0259 (patch)
tree66a836c7799b21156d4fc87f42e5817d7d95535b /include
parent5539ae9613587e4a4eec42d420b8bdd9ff552a65 (diff)
virtio: change config to guest endian.
A recent proposed feature addition to the virtio block driver revealed some flaws in the API, in particular how easy it is to break big endian machines. The virtio config space was originally chosen to be little-endian, because we thought the config might be part of the PCI config space for virtio_pci. It's actually a separate mmio region, so that argument holds little water; as only x86 is currently using the virtio mechanism, we can change this (but must do so now, before the impending s390 merge). API changes: - __virtio_config_val() just becomes a striaght vdev->config_get() call. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'include')
-rw-r--r--include/linux/virtio_config.h47
1 files changed, 16 insertions, 31 deletions
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index d581b2914b34..475572e976fe 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -16,7 +16,7 @@
16#define VIRTIO_CONFIG_S_FAILED 0x80 16#define VIRTIO_CONFIG_S_FAILED 0x80
17 17
18#ifdef __KERNEL__ 18#ifdef __KERNEL__
19struct virtio_device; 19#include <linux/virtio.h>
20 20
21/** 21/**
22 * virtio_config_ops - operations for configuring a virtio device 22 * virtio_config_ops - operations for configuring a virtio device
@@ -30,13 +30,11 @@ struct virtio_device;
30 * offset: the offset of the configuration field 30 * offset: the offset of the configuration field
31 * buf: the buffer to write the field value into. 31 * buf: the buffer to write the field value into.
32 * len: the length of the buffer 32 * len: the length of the buffer
33 * Note that contents are conventionally little-endian.
34 * @set: write the value of a configuration field 33 * @set: write the value of a configuration field
35 * vdev: the virtio_device 34 * vdev: the virtio_device
36 * offset: the offset of the configuration field 35 * offset: the offset of the configuration field
37 * buf: the buffer to read the field value from. 36 * buf: the buffer to read the field value from.
38 * len: the length of the buffer 37 * len: the length of the buffer
39 * Note that contents are conventionally little-endian.
40 * @get_status: read the status byte 38 * @get_status: read the status byte
41 * vdev: the virtio_device 39 * vdev: the virtio_device
42 * Returns the status byte 40 * Returns the status byte
@@ -70,40 +68,27 @@ struct virtio_config_ops
70}; 68};
71 69
72/** 70/**
73 * virtio_config_val - look for a feature and get a single virtio config. 71 * virtio_config_val - look for a feature and get a virtio config entry.
74 * @vdev: the virtio device 72 * @vdev: the virtio device
75 * @fbit: the feature bit 73 * @fbit: the feature bit
76 * @offset: the type to search for. 74 * @offset: the type to search for.
77 * @val: a pointer to the value to fill in. 75 * @val: a pointer to the value to fill in.
78 * 76 *
79 * The return value is -ENOENT if the feature doesn't exist. Otherwise 77 * The return value is -ENOENT if the feature doesn't exist. Otherwise
80 * the value is endian-corrected and returned in v. */ 78 * the config value is copied into whatever is pointed to by v. */
81#define virtio_config_val(vdev, fbit, offset, v) ({ \ 79#define virtio_config_val(vdev, fbit, offset, v) \
82 int _err; \ 80 virtio_config_buf((vdev), (fbit), (offset), (v), sizeof(v))
83 if ((vdev)->config->feature((vdev), (fbit))) { \
84 __virtio_config_val((vdev), (offset), (v)); \
85 _err = 0; \
86 } else \
87 _err = -ENOENT; \
88 _err; \
89})
90 81
91/** 82static inline int virtio_config_buf(struct virtio_device *vdev,
92 * __virtio_config_val - get a single virtio config without feature check. 83 unsigned int fbit,
93 * @vdev: the virtio device 84 unsigned int offset,
94 * @offset: the type to search for. 85 void *buf, unsigned len)
95 * @val: a pointer to the value to fill in. 86{
96 * 87 if (!vdev->config->feature(vdev, fbit))
97 * The value is endian-corrected and returned in v. */ 88 return -ENOENT;
98#define __virtio_config_val(vdev, offset, v) do { \ 89
99 BUILD_BUG_ON(sizeof(*(v)) != 1 && sizeof(*(v)) != 2 \ 90 vdev->config->get(vdev, offset, buf, len);
100 && sizeof(*(v)) != 4 && sizeof(*(v)) != 8); \ 91 return 0;
101 (vdev)->config->get((vdev), (offset), (v), sizeof(*(v))); \ 92}
102 switch (sizeof(*(v))) { \
103 case 2: le16_to_cpus((__u16 *) v); break; \
104 case 4: le32_to_cpus((__u32 *) v); break; \
105 case 8: le64_to_cpus((__u64 *) v); break; \
106 } \
107} while(0)
108#endif /* __KERNEL__ */ 93#endif /* __KERNEL__ */
109#endif /* _LINUX_VIRTIO_CONFIG_H */ 94#endif /* _LINUX_VIRTIO_CONFIG_H */