History

virtio_config: LE config space accessors

To be used by modern code, as well as to handle LE only fields such as balloon.

Michael S. Tsirkin committed 6 years ago

Commit e5989601 parent 14191c11 file · +65 −0Browse files

Unified · Split

include/linux/virtio_config.h+65−0
@@ -375,6 +375,71 @@ static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val) · 374 unmodified lines
375375 sizeof(virtio_cwrite_v)); \
376376 } while(0)
377377
378+/*
379+ * Nothing virtio-specific about these, but let's worry about generalizing
380+ * these later.
381+ */
382+#define virtio_le_to_cpu(x) \
383+ _Generic((x), \
384+ __u8: (x), \
385+ __le16: le16_to_cpu(x), \
386+ __le32: le32_to_cpu(x), \
387+ __le64: le64_to_cpu(x) \
388+ )
389+
390+#define virtio_cpu_to_le(x, m) \
391+ _Generic((m), \
392+ __u8: (x), \
393+ __le16: cpu_to_le16(x), \
394+ __le32: cpu_to_le32(x), \
395+ __le64: cpu_to_le64(x) \
396+ )
397+
398+/* LE (e.g. modern) Config space accessors. */
399+#define virtio_cread_le(vdev, structname, member, ptr) \
400+ do { \
401+ typeof(((structname*)0)->member) virtio_cread_v; \
402+ \
403+ might_sleep(); \
404+ /* Sanity check: must match the member's type */ \
405+ typecheck(typeof(virtio_le_to_cpu(virtio_cread_v)), *(ptr)); \
406+ \
407+ switch (sizeof(virtio_cread_v)) { \
408+ case 1: \
409+ case 2: \
410+ case 4: \
411+ vdev->config->get((vdev), \
412+ offsetof(structname, member), \
413+ &virtio_cread_v, \
414+ sizeof(virtio_cread_v)); \
415+ break; \
416+ default: \
417+ __virtio_cread_many((vdev), \
418+ offsetof(structname, member), \
419+ &virtio_cread_v, \
420+ 1, \
421+ sizeof(virtio_cread_v)); \
422+ break; \
423+ } \
424+ *(ptr) = virtio_le_to_cpu(virtio_cread_v); \
425+ } while(0)
426+
427+/* Config space accessors. */
428+#define virtio_cwrite_le(vdev, structname, member, ptr) \
429+ do { \
430+ typeof(((structname*)0)->member) virtio_cwrite_v = \
431+ virtio_cpu_to_le(*(ptr), ((structname*)0)->member); \
432+ \
433+ might_sleep(); \
434+ /* Sanity check: must match the member's type */ \
435+ typecheck(typeof(virtio_le_to_cpu(virtio_cwrite_v)), *(ptr)); \
436+ \
437+ vdev->config->set((vdev), offsetof(structname, member), \
438+ &virtio_cwrite_v, \
439+ sizeof(virtio_cwrite_v)); \
440+ } while(0)
441+
442+
378443 /* Read @count fields, @bytes each. */
379444 static inline void __virtio_cread_many(struct virtio_device *vdev,
380445 unsigned int offset,