virtio.h 19 KB

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