diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2013-10-14 03:41:51 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2013-10-16 20:25:36 -0400 |
commit | 0b90d0622ad290b3717a13489b396af52aea9d2d (patch) | |
tree | b40dcc4d3ac3fb9d7c34381e82523b7e6cd8a0fa | |
parent | bb478d8b167cf875565ac7d927ffbdc0b6d280e8 (diff) |
virtio_config: introduce size-based accessors.
This lets the us do endian conversion if necessary, and insulates the
drivers from that change.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r-- | include/linux/virtio_config.h | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index 29b9104232b4..490a4bbd59a3 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h | |||
@@ -162,5 +162,139 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu) | |||
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | 164 | ||
165 | /* Config space accessors. */ | ||
166 | #define virtio_cread(vdev, structname, member, ptr) \ | ||
167 | do { \ | ||
168 | /* Must match the member's type, and be integer */ \ | ||
169 | if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ | ||
170 | (*ptr) = 1; \ | ||
171 | \ | ||
172 | switch (sizeof(*ptr)) { \ | ||
173 | case 1: \ | ||
174 | *(ptr) = virtio_cread8(vdev, \ | ||
175 | offsetof(structname, member)); \ | ||
176 | break; \ | ||
177 | case 2: \ | ||
178 | *(ptr) = virtio_cread16(vdev, \ | ||
179 | offsetof(structname, member)); \ | ||
180 | break; \ | ||
181 | case 4: \ | ||
182 | *(ptr) = virtio_cread32(vdev, \ | ||
183 | offsetof(structname, member)); \ | ||
184 | break; \ | ||
185 | case 8: \ | ||
186 | *(ptr) = virtio_cread64(vdev, \ | ||
187 | offsetof(structname, member)); \ | ||
188 | break; \ | ||
189 | default: \ | ||
190 | BUG(); \ | ||
191 | } \ | ||
192 | } while(0) | ||
193 | |||
194 | /* Config space accessors. */ | ||
195 | #define virtio_cwrite(vdev, structname, member, ptr) \ | ||
196 | do { \ | ||
197 | /* Must match the member's type, and be integer */ \ | ||
198 | if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ | ||
199 | BUG_ON((*ptr) == 1); \ | ||
200 | \ | ||
201 | switch (sizeof(*ptr)) { \ | ||
202 | case 1: \ | ||
203 | virtio_cwrite8(vdev, \ | ||
204 | offsetof(structname, member), \ | ||
205 | *(ptr)); \ | ||
206 | break; \ | ||
207 | case 2: \ | ||
208 | virtio_cwrite16(vdev, \ | ||
209 | offsetof(structname, member), \ | ||
210 | *(ptr)); \ | ||
211 | break; \ | ||
212 | case 4: \ | ||
213 | virtio_cwrite32(vdev, \ | ||
214 | offsetof(structname, member), \ | ||
215 | *(ptr)); \ | ||
216 | break; \ | ||
217 | case 8: \ | ||
218 | virtio_cwrite64(vdev, \ | ||
219 | offsetof(structname, member), \ | ||
220 | *(ptr)); \ | ||
221 | break; \ | ||
222 | default: \ | ||
223 | BUG(); \ | ||
224 | } \ | ||
225 | } while(0) | ||
226 | |||
227 | static inline u8 virtio_cread8(struct virtio_device *vdev, unsigned int offset) | ||
228 | { | ||
229 | u8 ret; | ||
230 | vdev->config->get(vdev, offset, &ret, sizeof(ret)); | ||
231 | return ret; | ||
232 | } | ||
233 | |||
234 | static inline void virtio_cread_bytes(struct virtio_device *vdev, | ||
235 | unsigned int offset, | ||
236 | void *buf, size_t len) | ||
237 | { | ||
238 | vdev->config->get(vdev, offset, buf, len); | ||
239 | } | ||
240 | |||
241 | static inline void virtio_cwrite8(struct virtio_device *vdev, | ||
242 | unsigned int offset, u8 val) | ||
243 | { | ||
244 | vdev->config->set(vdev, offset, &val, sizeof(val)); | ||
245 | } | ||
246 | |||
247 | static inline u16 virtio_cread16(struct virtio_device *vdev, | ||
248 | unsigned int offset) | ||
249 | { | ||
250 | u16 ret; | ||
251 | vdev->config->get(vdev, offset, &ret, sizeof(ret)); | ||
252 | return ret; | ||
253 | } | ||
254 | |||
255 | static inline void virtio_cwrite16(struct virtio_device *vdev, | ||
256 | unsigned int offset, u16 val) | ||
257 | { | ||
258 | vdev->config->set(vdev, offset, &val, sizeof(val)); | ||
259 | } | ||
260 | |||
261 | static inline u32 virtio_cread32(struct virtio_device *vdev, | ||
262 | unsigned int offset) | ||
263 | { | ||
264 | u32 ret; | ||
265 | vdev->config->get(vdev, offset, &ret, sizeof(ret)); | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | static inline void virtio_cwrite32(struct virtio_device *vdev, | ||
270 | unsigned int offset, u32 val) | ||
271 | { | ||
272 | vdev->config->set(vdev, offset, &val, sizeof(val)); | ||
273 | } | ||
274 | |||
275 | static inline u64 virtio_cread64(struct virtio_device *vdev, | ||
276 | unsigned int offset) | ||
277 | { | ||
278 | u64 ret; | ||
279 | vdev->config->get(vdev, offset, &ret, sizeof(ret)); | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | static inline void virtio_cwrite64(struct virtio_device *vdev, | ||
284 | unsigned int offset, u64 val) | ||
285 | { | ||
286 | vdev->config->set(vdev, offset, &val, sizeof(val)); | ||
287 | } | ||
288 | |||
289 | /* Conditional config space accessors. */ | ||
290 | #define virtio_cread_feature(vdev, fbit, structname, member, ptr) \ | ||
291 | ({ \ | ||
292 | int _r = 0; \ | ||
293 | if (!virtio_has_feature(vdev, fbit)) \ | ||
294 | _r = -ENOENT; \ | ||
295 | else \ | ||
296 | virtio_cread((vdev), structname, member, ptr); \ | ||
297 | _r; \ | ||
298 | }) | ||
165 | 299 | ||
166 | #endif /* _LINUX_VIRTIO_CONFIG_H */ | 300 | #endif /* _LINUX_VIRTIO_CONFIG_H */ |