virtio.h 19 KB

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