xref: /openbmc/u-boot/include/virtio.h (revision 1d6edcbf)
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (C) 2018, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
4  * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
5  *
6  * VirtIO is a virtualization standard for network and disk device drivers
7  * where just the guest's device driver "knows" it is running in a virtual
8  * environment, and cooperates with the hypervisor. This enables guests to
9  * get high performance network and disk operations, and gives most of the
10  * performance benefits of paravirtualization. In the U-Boot case, the guest
11  * is U-Boot itself, while the virtual environment are normally QEMU targets
12  * like ARM, RISC-V and x86.
13  *
14  * See http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf for
15  * the VirtIO specification v1.0.
16  *
17  * This file is largely based on Linux kernel virtio_*.h files
18  */
19 
20 #ifndef __VIRTIO_H__
21 #define __VIRTIO_H__
22 
23 #define VIRTIO_ID_NET		1 /* virtio net */
24 #define VIRTIO_ID_BLOCK		2 /* virtio block */
25 #define VIRTIO_ID_MAX_NUM	3
26 
27 #define VIRTIO_NET_DRV_NAME	"virtio-net"
28 #define VIRTIO_BLK_DRV_NAME	"virtio-blk"
29 
30 /* Status byte for guest to report progress, and synchronize features */
31 
32 /* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
33 #define VIRTIO_CONFIG_S_ACKNOWLEDGE	1
34 /* We have found a driver for the device */
35 #define VIRTIO_CONFIG_S_DRIVER		2
36 /* Driver has used its parts of the config, and is happy */
37 #define VIRTIO_CONFIG_S_DRIVER_OK	4
38 /* Driver has finished configuring features */
39 #define VIRTIO_CONFIG_S_FEATURES_OK	8
40 /* Device entered invalid state, driver must reset it */
41 #define VIRTIO_CONFIG_S_NEEDS_RESET	0x40
42 /* We've given up on this device */
43 #define VIRTIO_CONFIG_S_FAILED		0x80
44 
45 /*
46  * Virtio feature bits VIRTIO_TRANSPORT_F_START through VIRTIO_TRANSPORT_F_END
47  * are reserved for the transport being used (eg: virtio_ring, virtio_pci etc.),
48  * the rest are per-device feature bits.
49  */
50 #define VIRTIO_TRANSPORT_F_START	28
51 #define VIRTIO_TRANSPORT_F_END		38
52 
53 #ifndef VIRTIO_CONFIG_NO_LEGACY
54 /*
55  * Do we get callbacks when the ring is completely used,
56  * even if we've suppressed them?
57  */
58 #define VIRTIO_F_NOTIFY_ON_EMPTY	24
59 
60 /* Can the device handle any descriptor layout? */
61 #define VIRTIO_F_ANY_LAYOUT		27
62 #endif /* VIRTIO_CONFIG_NO_LEGACY */
63 
64 /* v1.0 compliant */
65 #define VIRTIO_F_VERSION_1		32
66 
67 /*
68  * If clear - device has the IOMMU bypass quirk feature.
69  * If set - use platform tools to detect the IOMMU.
70  *
71  * Note the reverse polarity (compared to most other features),
72  * this is for compatibility with legacy systems.
73  */
74 #define VIRTIO_F_IOMMU_PLATFORM		33
75 
76 /* Does the device support Single Root I/O Virtualization? */
77 #define VIRTIO_F_SR_IOV			37
78 
79 /**
80  * virtio scatter-gather struct
81  *
82  * @addr:		sg buffer address
83  * @lengh:		sg buffer length
84  */
85 struct virtio_sg {
86 	void *addr;
87 	size_t length;
88 };
89 
90 struct virtqueue;
91 
92 /* virtio bus operations */
93 struct dm_virtio_ops {
94 	/**
95 	 * get_config() - read the value of a configuration field
96 	 *
97 	 * @vdev:	the real virtio device
98 	 * @offset:	the offset of the configuration field
99 	 * @buf:	the buffer to write the field value into
100 	 * @len:	the length of the buffer
101 	 * @return 0 if OK, -ve on error
102 	 */
103 	int (*get_config)(struct udevice *vdev, unsigned int offset,
104 			  void *buf, unsigned int len);
105 	/**
106 	 * set_config() - write the value of a configuration field
107 	 *
108 	 * @vdev:	the real virtio device
109 	 * @offset:	the offset of the configuration field
110 	 * @buf:	the buffer to read the field value from
111 	 * @len:	the length of the buffer
112 	 * @return 0 if OK, -ve on error
113 	 */
114 	int (*set_config)(struct udevice *vdev, unsigned int offset,
115 			  const void *buf, unsigned int len);
116 	/**
117 	 * generation() - config generation counter
118 	 *
119 	 * @vdev:	the real virtio device
120 	 * @counter:	the returned config generation counter
121 	 * @return 0 if OK, -ve on error
122 	 */
123 	int (*generation)(struct udevice *vdev, u32 *counter);
124 	/**
125 	 * get_status() - read the status byte
126 	 *
127 	 * @vdev:	the real virtio device
128 	 * @status:	the returned status byte
129 	 * @return 0 if OK, -ve on error
130 	 */
131 	int (*get_status)(struct udevice *vdev, u8 *status);
132 	/**
133 	 * set_status() - write the status byte
134 	 *
135 	 * @vdev:	the real virtio device
136 	 * @status:	the new status byte
137 	 * @return 0 if OK, -ve on error
138 	 */
139 	int (*set_status)(struct udevice *vdev, u8 status);
140 	/**
141 	 * reset() - reset the device
142 	 *
143 	 * @vdev:	the real virtio device
144 	 * @return 0 if OK, -ve on error
145 	 */
146 	int (*reset)(struct udevice *vdev);
147 	/**
148 	 * get_features() - get the array of feature bits for this device
149 	 *
150 	 * @vdev:	the real virtio device
151 	 * @features:	the first 32 feature bits (all we currently need)
152 	 * @return 0 if OK, -ve on error
153 	 */
154 	int (*get_features)(struct udevice *vdev, u64 *features);
155 	/**
156 	 * set_features() - confirm what device features we'll be using
157 	 *
158 	 * @vdev:	the real virtio device
159 	 * @return 0 if OK, -ve on error
160 	 */
161 	int (*set_features)(struct udevice *vdev);
162 	/**
163 	 * find_vqs() - find virtqueues and instantiate them
164 	 *
165 	 * @vdev:	the real virtio device
166 	 * @nvqs:	the number of virtqueues to find
167 	 * @vqs:	on success, includes new virtqueues
168 	 * @return 0 if OK, -ve on error
169 	 */
170 	int (*find_vqs)(struct udevice *vdev, unsigned int nvqs,
171 			struct virtqueue *vqs[]);
172 	/**
173 	 * del_vqs() - free virtqueues found by find_vqs()
174 	 *
175 	 * @vdev:	the real virtio device
176 	 * @return 0 if OK, -ve on error
177 	 */
178 	int (*del_vqs)(struct udevice *vdev);
179 	/**
180 	 * notify() - notify the device to process the queue
181 	 *
182 	 * @vdev:	the real virtio device
183 	 * @vq:		virtqueue to process
184 	 * @return 0 if OK, -ve on error
185 	 */
186 	int (*notify)(struct udevice *vdev, struct virtqueue *vq);
187 };
188 
189 /* Get access to a virtio bus' operations */
190 #define virtio_get_ops(dev)	((struct dm_virtio_ops *)(dev)->driver->ops)
191 
192 /**
193  * virtio uclass per device private data
194  *
195  * @vqs:			virtualqueue for the virtio device
196  * @vdev:			the real virtio device underneath
197  * @legacy:			is it a legacy device?
198  * @device:			virtio device ID
199  * @vendor:			virtio vendor ID
200  * @features:			negotiated supported features
201  * @feature_table:		an array of feature supported by the driver
202  * @feature_table_size:		number of entries in the feature table array
203  * @feature_table_legacy:	same as feature_table but working in legacy mode
204  * @feature_table_size_legacy:	number of entries in feature table legacy array
205  */
206 struct virtio_dev_priv {
207 	struct list_head vqs;
208 	struct udevice *vdev;
209 	bool legacy;
210 	u32 device;
211 	u32 vendor;
212 	u64 features;
213 	const u32 *feature_table;
214 	u32 feature_table_size;
215 	const u32 *feature_table_legacy;
216 	u32 feature_table_size_legacy;
217 };
218 
219 /**
220  * virtio_get_config() - read the value of a configuration field
221  *
222  * @vdev:	the real virtio device
223  * @offset:	the offset of the configuration field
224  * @buf:	the buffer to write the field value into
225  * @len:	the length of the buffer
226  * @return 0 if OK, -ve on error
227  */
228 int virtio_get_config(struct udevice *vdev, unsigned int offset,
229 		      void *buf, unsigned int len);
230 
231 /**
232  * virtio_set_config() - write the value of a configuration field
233  *
234  * @vdev:	the real virtio device
235  * @offset:	the offset of the configuration field
236  * @buf:	the buffer to read the field value from
237  * @len:	the length of the buffer
238  * @return 0 if OK, -ve on error
239  */
240 int virtio_set_config(struct udevice *vdev, unsigned int offset,
241 		      void *buf, unsigned int len);
242 
243 /**
244  * virtio_generation() - config generation counter
245  *
246  * @vdev:	the real virtio device
247  * @counter:	the returned config generation counter
248  * @return 0 if OK, -ve on error
249  */
250 int virtio_generation(struct udevice *vdev, u32 *counter);
251 
252 /**
253  * virtio_get_status() - read the status byte
254  *
255  * @vdev:	the real virtio device
256  * @status:	the returned status byte
257  * @return 0 if OK, -ve on error
258  */
259 int virtio_get_status(struct udevice *vdev, u8 *status);
260 
261 /**
262  * virtio_set_status() - write the status byte
263  *
264  * @vdev:	the real virtio device
265  * @status:	the new status byte
266  * @return 0 if OK, -ve on error
267  */
268 int virtio_set_status(struct udevice *vdev, u8 status);
269 
270 /**
271  * virtio_reset() - reset the device
272  *
273  * @vdev:	the real virtio device
274  * @return 0 if OK, -ve on error
275  */
276 int virtio_reset(struct udevice *vdev);
277 
278 /**
279  * virtio_get_features() - get the array of feature bits for this device
280  *
281  * @vdev:	the real virtio device
282  * @features:	the first 32 feature bits (all we currently need)
283  * @return 0 if OK, -ve on error
284  */
285 int virtio_get_features(struct udevice *vdev, u64 *features);
286 
287 /**
288  * virtio_set_features() - confirm what device features we'll be using
289  *
290  * @vdev:	the real virtio device
291  * @return 0 if OK, -ve on error
292  */
293 int virtio_set_features(struct udevice *vdev);
294 
295 /**
296  * virtio_find_vqs() - find virtqueues and instantiate them
297  *
298  * @vdev:	the real virtio device
299  * @nvqs:	the number of virtqueues to find
300  * @vqs:	on success, includes new virtqueues
301  * @return 0 if OK, -ve on error
302  */
303 int virtio_find_vqs(struct udevice *vdev, unsigned int nvqs,
304 		    struct virtqueue *vqs[]);
305 
306 /**
307  * virtio_del_vqs() - free virtqueues found by find_vqs()
308  *
309  * @vdev:	the real virtio device
310  * @return 0 if OK, -ve on error
311  */
312 int virtio_del_vqs(struct udevice *vdev);
313 
314 /**
315  * virtio_notify() - notify the device to process the queue
316  *
317  * @vdev:	the real virtio device
318  * @vq:		virtqueue to process
319  * @return 0 if OK, -ve on error
320  */
321 int virtio_notify(struct udevice *vdev, struct virtqueue *vq);
322 
323 /**
324  * virtio_add_status() - helper to set a new status code to the device
325  *
326  * @vdev:	the real virtio device
327  * @status:	new status code to be added
328  */
329 void virtio_add_status(struct udevice *vdev, u8 status);
330 
331 /**
332  * virtio_finalize_features() - helper to finalize features
333  *
334  * @vdev:	the real virtio device
335  * @return 0 if OK, -ve on error
336  */
337 int virtio_finalize_features(struct udevice *vdev);
338 
339 /**
340  * virtio_driver_features_init() - initialize driver supported features
341  *
342  * This fills in the virtio device parent per child private data with the given
343  * information, which contains driver supported features and legacy features.
344  *
345  * This API should be called in the virtio device driver's bind method, so that
346  * later virtio transport uclass driver can utilize the driver supplied features
347  * to negotiate with the device on the final supported features.
348  *
349  * @priv:		virtio uclass per device private data
350  * @feature:		an array of feature supported by the driver
351  * @feature_size:	number of entries in the feature table array
352  * @feature_legacy:	same as feature_table but working in legacy mode
353  * @feature_legacy_size:number of entries in feature table legacy array
354  */
355 void virtio_driver_features_init(struct virtio_dev_priv *priv,
356 				 const u32 *feature,
357 				 u32 feature_size,
358 				 const u32 *feature_legacy,
359 				 u32 feature_legacy_size);
360 
361 /**
362  * virtio_init() - helper to enumerate all known virtio devices
363  *
364  * @return 0 if OK, -ve on error
365  */
366 int virtio_init(void);
367 
__virtio16_to_cpu(bool little_endian,__virtio16 val)368 static inline u16 __virtio16_to_cpu(bool little_endian, __virtio16 val)
369 {
370 	if (little_endian)
371 		return le16_to_cpu((__force __le16)val);
372 	else
373 		return be16_to_cpu((__force __be16)val);
374 }
375 
__cpu_to_virtio16(bool little_endian,u16 val)376 static inline __virtio16 __cpu_to_virtio16(bool little_endian, u16 val)
377 {
378 	if (little_endian)
379 		return (__force __virtio16)cpu_to_le16(val);
380 	else
381 		return (__force __virtio16)cpu_to_be16(val);
382 }
383 
__virtio32_to_cpu(bool little_endian,__virtio32 val)384 static inline u32 __virtio32_to_cpu(bool little_endian, __virtio32 val)
385 {
386 	if (little_endian)
387 		return le32_to_cpu((__force __le32)val);
388 	else
389 		return be32_to_cpu((__force __be32)val);
390 }
391 
__cpu_to_virtio32(bool little_endian,u32 val)392 static inline __virtio32 __cpu_to_virtio32(bool little_endian, u32 val)
393 {
394 	if (little_endian)
395 		return (__force __virtio32)cpu_to_le32(val);
396 	else
397 		return (__force __virtio32)cpu_to_be32(val);
398 }
399 
__virtio64_to_cpu(bool little_endian,__virtio64 val)400 static inline u64 __virtio64_to_cpu(bool little_endian, __virtio64 val)
401 {
402 	if (little_endian)
403 		return le64_to_cpu((__force __le64)val);
404 	else
405 		return be64_to_cpu((__force __be64)val);
406 }
407 
__cpu_to_virtio64(bool little_endian,u64 val)408 static inline __virtio64 __cpu_to_virtio64(bool little_endian, u64 val)
409 {
410 	if (little_endian)
411 		return (__force __virtio64)cpu_to_le64(val);
412 	else
413 		return (__force __virtio64)cpu_to_be64(val);
414 }
415 
416 /**
417  * __virtio_test_bit - helper to test feature bits
418  *
419  * For use by transports. Devices should normally use virtio_has_feature,
420  * which includes more checks.
421  *
422  * @udev: the transport device
423  * @fbit: the feature bit
424  */
__virtio_test_bit(struct udevice * udev,unsigned int fbit)425 static inline bool __virtio_test_bit(struct udevice *udev, unsigned int fbit)
426 {
427 	struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
428 
429 	/* Did you forget to fix assumptions on max features? */
430 	if (__builtin_constant_p(fbit))
431 		BUILD_BUG_ON(fbit >= 64);
432 	else
433 		WARN_ON(fbit >= 64);
434 
435 	return uc_priv->features & BIT_ULL(fbit);
436 }
437 
438 /**
439  * __virtio_set_bit - helper to set feature bits
440  *
441  * For use by transports.
442  *
443  * @udev: the transport device
444  * @fbit: the feature bit
445  */
__virtio_set_bit(struct udevice * udev,unsigned int fbit)446 static inline void __virtio_set_bit(struct udevice *udev, unsigned int fbit)
447 {
448 	struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
449 
450 	/* Did you forget to fix assumptions on max features? */
451 	if (__builtin_constant_p(fbit))
452 		BUILD_BUG_ON(fbit >= 64);
453 	else
454 		WARN_ON(fbit >= 64);
455 
456 	uc_priv->features |= BIT_ULL(fbit);
457 }
458 
459 /**
460  * __virtio_clear_bit - helper to clear feature bits
461  *
462  * For use by transports.
463  *
464  * @vdev: the transport device
465  * @fbit: the feature bit
466  */
__virtio_clear_bit(struct udevice * udev,unsigned int fbit)467 static inline void __virtio_clear_bit(struct udevice *udev, unsigned int fbit)
468 {
469 	struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
470 
471 	/* Did you forget to fix assumptions on max features? */
472 	if (__builtin_constant_p(fbit))
473 		BUILD_BUG_ON(fbit >= 64);
474 	else
475 		WARN_ON(fbit >= 64);
476 
477 	uc_priv->features &= ~BIT_ULL(fbit);
478 }
479 
480 /**
481  * virtio_has_feature - helper to determine if this device has this feature
482  *
483  * Note this API is only usable after the virtio device driver's bind phase,
484  * as the feature has been negotiated between the device and the driver.
485  *
486  * @vdev: the virtio device
487  * @fbit: the feature bit
488  */
virtio_has_feature(struct udevice * vdev,unsigned int fbit)489 static inline bool virtio_has_feature(struct udevice *vdev, unsigned int fbit)
490 {
491 	if (!(vdev->flags & DM_FLAG_BOUND))
492 		WARN_ON(true);
493 
494 	return __virtio_test_bit(vdev->parent, fbit);
495 }
496 
virtio_legacy_is_little_endian(void)497 static inline bool virtio_legacy_is_little_endian(void)
498 {
499 #ifdef __LITTLE_ENDIAN
500 	return true;
501 #else
502 	return false;
503 #endif
504 }
505 
virtio_is_little_endian(struct udevice * vdev)506 static inline bool virtio_is_little_endian(struct udevice *vdev)
507 {
508 	struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(vdev->parent);
509 
510 	return !uc_priv->legacy || virtio_legacy_is_little_endian();
511 }
512 
513 /* Memory accessors */
virtio16_to_cpu(struct udevice * vdev,__virtio16 val)514 static inline u16 virtio16_to_cpu(struct udevice *vdev, __virtio16 val)
515 {
516 	return __virtio16_to_cpu(virtio_is_little_endian(vdev), val);
517 }
518 
cpu_to_virtio16(struct udevice * vdev,u16 val)519 static inline __virtio16 cpu_to_virtio16(struct udevice *vdev, u16 val)
520 {
521 	return __cpu_to_virtio16(virtio_is_little_endian(vdev), val);
522 }
523 
virtio32_to_cpu(struct udevice * vdev,__virtio32 val)524 static inline u32 virtio32_to_cpu(struct udevice *vdev, __virtio32 val)
525 {
526 	return __virtio32_to_cpu(virtio_is_little_endian(vdev), val);
527 }
528 
cpu_to_virtio32(struct udevice * vdev,u32 val)529 static inline __virtio32 cpu_to_virtio32(struct udevice *vdev, u32 val)
530 {
531 	return __cpu_to_virtio32(virtio_is_little_endian(vdev), val);
532 }
533 
virtio64_to_cpu(struct udevice * vdev,__virtio64 val)534 static inline u64 virtio64_to_cpu(struct udevice *vdev, __virtio64 val)
535 {
536 	return __virtio64_to_cpu(virtio_is_little_endian(vdev), val);
537 }
538 
cpu_to_virtio64(struct udevice * vdev,u64 val)539 static inline __virtio64 cpu_to_virtio64(struct udevice *vdev, u64 val)
540 {
541 	return __cpu_to_virtio64(virtio_is_little_endian(vdev), val);
542 }
543 
544 /* Read @count fields, @bytes each */
__virtio_cread_many(struct udevice * vdev,unsigned int offset,void * buf,size_t count,size_t bytes)545 static inline void __virtio_cread_many(struct udevice *vdev,
546 				       unsigned int offset,
547 				       void *buf, size_t count, size_t bytes)
548 {
549 	u32 old, gen;
550 	int i;
551 
552 	/* no need to check return value as generation can be optional */
553 	virtio_generation(vdev, &gen);
554 	do {
555 		old = gen;
556 
557 		for (i = 0; i < count; i++)
558 			virtio_get_config(vdev, offset + bytes * i,
559 					  buf + i * bytes, bytes);
560 
561 		virtio_generation(vdev, &gen);
562 	} while (gen != old);
563 }
564 
virtio_cread_bytes(struct udevice * vdev,unsigned int offset,void * buf,size_t len)565 static inline void virtio_cread_bytes(struct udevice *vdev,
566 				      unsigned int offset,
567 				      void *buf, size_t len)
568 {
569 	__virtio_cread_many(vdev, offset, buf, len, 1);
570 }
571 
virtio_cread8(struct udevice * vdev,unsigned int offset)572 static inline u8 virtio_cread8(struct udevice *vdev, unsigned int offset)
573 {
574 	u8 ret;
575 
576 	virtio_get_config(vdev, offset, &ret, sizeof(ret));
577 	return ret;
578 }
579 
virtio_cwrite8(struct udevice * vdev,unsigned int offset,u8 val)580 static inline void virtio_cwrite8(struct udevice *vdev,
581 				  unsigned int offset, u8 val)
582 {
583 	virtio_set_config(vdev, offset, &val, sizeof(val));
584 }
585 
virtio_cread16(struct udevice * vdev,unsigned int offset)586 static inline u16 virtio_cread16(struct udevice *vdev,
587 				 unsigned int offset)
588 {
589 	u16 ret;
590 
591 	virtio_get_config(vdev, offset, &ret, sizeof(ret));
592 	return virtio16_to_cpu(vdev, (__force __virtio16)ret);
593 }
594 
virtio_cwrite16(struct udevice * vdev,unsigned int offset,u16 val)595 static inline void virtio_cwrite16(struct udevice *vdev,
596 				   unsigned int offset, u16 val)
597 {
598 	val = (__force u16)cpu_to_virtio16(vdev, val);
599 	virtio_set_config(vdev, offset, &val, sizeof(val));
600 }
601 
virtio_cread32(struct udevice * vdev,unsigned int offset)602 static inline u32 virtio_cread32(struct udevice *vdev,
603 				 unsigned int offset)
604 {
605 	u32 ret;
606 
607 	virtio_get_config(vdev, offset, &ret, sizeof(ret));
608 	return virtio32_to_cpu(vdev, (__force __virtio32)ret);
609 }
610 
virtio_cwrite32(struct udevice * vdev,unsigned int offset,u32 val)611 static inline void virtio_cwrite32(struct udevice *vdev,
612 				   unsigned int offset, u32 val)
613 {
614 	val = (__force u32)cpu_to_virtio32(vdev, val);
615 	virtio_set_config(vdev, offset, &val, sizeof(val));
616 }
617 
virtio_cread64(struct udevice * vdev,unsigned int offset)618 static inline u64 virtio_cread64(struct udevice *vdev,
619 				 unsigned int offset)
620 {
621 	u64 ret;
622 
623 	__virtio_cread_many(vdev, offset, &ret, 1, sizeof(ret));
624 	return virtio64_to_cpu(vdev, (__force __virtio64)ret);
625 }
626 
virtio_cwrite64(struct udevice * vdev,unsigned int offset,u64 val)627 static inline void virtio_cwrite64(struct udevice *vdev,
628 				   unsigned int offset, u64 val)
629 {
630 	val = (__force u64)cpu_to_virtio64(vdev, val);
631 	virtio_set_config(vdev, offset, &val, sizeof(val));
632 }
633 
634 /* Config space read accessor */
635 #define virtio_cread(vdev, structname, member, ptr)			\
636 	do {								\
637 		/* Must match the member's type, and be integer */	\
638 		if (!typecheck(typeof((((structname *)0)->member)), *(ptr))) \
639 			(*ptr) = 1;					\
640 									\
641 		switch (sizeof(*ptr)) {					\
642 		case 1:							\
643 			*(ptr) = virtio_cread8(vdev,			\
644 					       offsetof(structname, member)); \
645 			break;						\
646 		case 2:							\
647 			*(ptr) = virtio_cread16(vdev,			\
648 						offsetof(structname, member)); \
649 			break;						\
650 		case 4:							\
651 			*(ptr) = virtio_cread32(vdev,			\
652 						offsetof(structname, member)); \
653 			break;						\
654 		case 8:							\
655 			*(ptr) = virtio_cread64(vdev,			\
656 						offsetof(structname, member)); \
657 			break;						\
658 		default:						\
659 			WARN_ON(true);					\
660 		}							\
661 	} while (0)
662 
663 /* Config space write accessor */
664 #define virtio_cwrite(vdev, structname, member, ptr)			\
665 	do {								\
666 		/* Must match the member's type, and be integer */	\
667 		if (!typecheck(typeof((((structname *)0)->member)), *(ptr))) \
668 			WARN_ON((*ptr) == 1);				\
669 									\
670 		switch (sizeof(*ptr)) {					\
671 		case 1:							\
672 			virtio_cwrite8(vdev,				\
673 				       offsetof(structname, member),	\
674 				       *(ptr));				\
675 			break;						\
676 		case 2:							\
677 			virtio_cwrite16(vdev,				\
678 					offsetof(structname, member),	\
679 					*(ptr));			\
680 			break;						\
681 		case 4:							\
682 			virtio_cwrite32(vdev,				\
683 					offsetof(structname, member),	\
684 					*(ptr));			\
685 			break;						\
686 		case 8:							\
687 			virtio_cwrite64(vdev,				\
688 					offsetof(structname, member),	\
689 					*(ptr));			\
690 			break;						\
691 		default:						\
692 			WARN_ON(true);					\
693 		}							\
694 	} while (0)
695 
696 /* Conditional config space accessors */
697 #define virtio_cread_feature(vdev, fbit, structname, member, ptr)	\
698 	({								\
699 		int _r = 0;						\
700 		if (!virtio_has_feature(vdev, fbit))			\
701 			_r = -ENOENT;					\
702 		else							\
703 			virtio_cread(vdev, structname, member, ptr);	\
704 		_r;							\
705 	})
706 
707 #endif /* __VIRTIO_H__ */
708