xref: /openbmc/linux/include/linux/virtio.h (revision 8bd2f710)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2ec3d41c4SRusty Russell #ifndef _LINUX_VIRTIO_H
3ec3d41c4SRusty Russell #define _LINUX_VIRTIO_H
4ec3d41c4SRusty Russell /* Everything a virtio driver needs to work with any particular virtio
5ec3d41c4SRusty Russell  * implementation. */
6ec3d41c4SRusty Russell #include <linux/types.h>
7ec3d41c4SRusty Russell #include <linux/scatterlist.h>
8ec3d41c4SRusty Russell #include <linux/spinlock.h>
9ec3d41c4SRusty Russell #include <linux/device.h>
10ec3d41c4SRusty Russell #include <linux/mod_devicetable.h>
11bbd603efSMichael S. Tsirkin #include <linux/gfp.h>
12b6253b4eSXuan Zhuo #include <linux/dma-mapping.h>
13ec3d41c4SRusty Russell 
14ec3d41c4SRusty Russell /**
155c669c4aSRicardo Cañuelo  * struct virtqueue - a queue to register buffers for sending or receiving.
169499f5e7SRusty Russell  * @list: the chain of virtqueues for this device
17ec3d41c4SRusty Russell  * @callback: the function to call when buffers are consumed (can be NULL).
189499f5e7SRusty Russell  * @name: the name of this virtqueue (mainly for debugging)
19ec3d41c4SRusty Russell  * @vdev: the virtio device this queue was created for.
20ec3d41c4SRusty Russell  * @priv: a pointer for the virtqueue implementation to use.
2106ca287dSRusty Russell  * @index: the zero-based ordinal number for this queue.
2206ca287dSRusty Russell  * @num_free: number of elements we expect to be able to fit.
23da802961SXuan Zhuo  * @num_max: the maximum number of elements supported by the device.
244913e854SXuan Zhuo  * @reset: vq is in reset state or not.
2506ca287dSRusty Russell  *
2606ca287dSRusty Russell  * A note on @num_free: with indirect buffers, each buffer needs one
2706ca287dSRusty Russell  * element in the queue, otherwise a buffer will need one element per
2806ca287dSRusty Russell  * sg element.
29ec3d41c4SRusty Russell  */
309499f5e7SRusty Russell struct virtqueue {
319499f5e7SRusty Russell 	struct list_head list;
3218445c4dSRusty Russell 	void (*callback)(struct virtqueue *vq);
339499f5e7SRusty Russell 	const char *name;
34ec3d41c4SRusty Russell 	struct virtio_device *vdev;
3506ca287dSRusty Russell 	unsigned int index;
3606ca287dSRusty Russell 	unsigned int num_free;
37da802961SXuan Zhuo 	unsigned int num_max;
384913e854SXuan Zhuo 	bool reset;
3948cd6bc5SChristophe JAILLET 	void *priv;
40ec3d41c4SRusty Russell };
41ec3d41c4SRusty Russell 
42282edb36SRusty Russell int virtqueue_add_outbuf(struct virtqueue *vq,
43282edb36SRusty Russell 			 struct scatterlist sg[], unsigned int num,
44282edb36SRusty Russell 			 void *data,
45282edb36SRusty Russell 			 gfp_t gfp);
46282edb36SRusty Russell 
47282edb36SRusty Russell int virtqueue_add_inbuf(struct virtqueue *vq,
48282edb36SRusty Russell 			struct scatterlist sg[], unsigned int num,
49282edb36SRusty Russell 			void *data,
50282edb36SRusty Russell 			gfp_t gfp);
51282edb36SRusty Russell 
525a08b04fSMichael S. Tsirkin int virtqueue_add_inbuf_ctx(struct virtqueue *vq,
535a08b04fSMichael S. Tsirkin 			    struct scatterlist sg[], unsigned int num,
545a08b04fSMichael S. Tsirkin 			    void *data,
555a08b04fSMichael S. Tsirkin 			    void *ctx,
565a08b04fSMichael S. Tsirkin 			    gfp_t gfp);
575a08b04fSMichael S. Tsirkin 
5813816c76SRusty Russell int virtqueue_add_sgs(struct virtqueue *vq,
5913816c76SRusty Russell 		      struct scatterlist *sgs[],
6013816c76SRusty Russell 		      unsigned int out_sgs,
6113816c76SRusty Russell 		      unsigned int in_sgs,
6213816c76SRusty Russell 		      void *data,
6313816c76SRusty Russell 		      gfp_t gfp);
6413816c76SRusty Russell 
652df64759SXuan Zhuo struct device *virtqueue_dma_dev(struct virtqueue *vq);
662df64759SXuan Zhuo 
675b1bf7cbSHeinz Graalfs bool virtqueue_kick(struct virtqueue *vq);
68ec3d41c4SRusty Russell 
6941f0377fSRusty Russell bool virtqueue_kick_prepare(struct virtqueue *vq);
7041f0377fSRusty Russell 
715b1bf7cbSHeinz Graalfs bool virtqueue_notify(struct virtqueue *vq);
7241f0377fSRusty Russell 
737c5e9ed0SMichael S. Tsirkin void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len);
74ec3d41c4SRusty Russell 
755a08b04fSMichael S. Tsirkin void *virtqueue_get_buf_ctx(struct virtqueue *vq, unsigned int *len,
765a08b04fSMichael S. Tsirkin 			    void **ctx);
775a08b04fSMichael S. Tsirkin 
787c5e9ed0SMichael S. Tsirkin void virtqueue_disable_cb(struct virtqueue *vq);
79ec3d41c4SRusty Russell 
807c5e9ed0SMichael S. Tsirkin bool virtqueue_enable_cb(struct virtqueue *vq);
81316f25f5SMichael S. Tsirkin 
82cc229884SMichael S. Tsirkin unsigned virtqueue_enable_cb_prepare(struct virtqueue *vq);
83cc229884SMichael S. Tsirkin 
848daafe9eSXuan Zhuo int virtqueue_set_dma_premapped(struct virtqueue *_vq);
858daafe9eSXuan Zhuo 
86cc229884SMichael S. Tsirkin bool virtqueue_poll(struct virtqueue *vq, unsigned);
87cc229884SMichael S. Tsirkin 
887ab358c2SMichael S. Tsirkin bool virtqueue_enable_cb_delayed(struct virtqueue *vq);
897ab358c2SMichael S. Tsirkin 
907c5e9ed0SMichael S. Tsirkin void *virtqueue_detach_unused_buf(struct virtqueue *vq);
91316f25f5SMichael S. Tsirkin 
924b6ec919SFeng Liu unsigned int virtqueue_get_vring_size(const struct virtqueue *vq);
938f9f4668SRick Jones 
944b6ec919SFeng Liu bool virtqueue_is_broken(const struct virtqueue *vq);
95b3b32c94SHeinz Graalfs 
964b6ec919SFeng Liu const struct vring *virtqueue_get_vring(const struct virtqueue *vq);
974b6ec919SFeng Liu dma_addr_t virtqueue_get_desc_addr(const struct virtqueue *vq);
984b6ec919SFeng Liu dma_addr_t virtqueue_get_avail_addr(const struct virtqueue *vq);
994b6ec919SFeng Liu dma_addr_t virtqueue_get_used_addr(const struct virtqueue *vq);
1002a2d1382SAndy Lutomirski 
101c790e8e1SXuan Zhuo int virtqueue_resize(struct virtqueue *vq, u32 num,
102c790e8e1SXuan Zhuo 		     void (*recycle)(struct virtqueue *vq, void *buf));
103ba3e0c47SXuan Zhuo int virtqueue_reset(struct virtqueue *vq,
104ba3e0c47SXuan Zhuo 		    void (*recycle)(struct virtqueue *vq, void *buf));
105c790e8e1SXuan Zhuo 
106ec3d41c4SRusty Russell /**
1075c669c4aSRicardo Cañuelo  * struct virtio_device - representation of a device using virtio
108ec3d41c4SRusty Russell  * @index: unique position on the virtio bus
109cbd7f8d6SPaul Bolle  * @failed: saved value for VIRTIO_CONFIG_S_FAILED bit (for restore)
11022b7050aSMichael S. Tsirkin  * @config_enabled: configuration change reporting enabled
11122b7050aSMichael S. Tsirkin  * @config_change_pending: configuration change reported while disabled
11222b7050aSMichael S. Tsirkin  * @config_lock: protects configuration change reporting
11333bd91fdSSimon Horman  * @vqs_list_lock: protects @vqs.
114ec3d41c4SRusty Russell  * @dev: underlying device.
115ec3d41c4SRusty Russell  * @id: the device type identification (used to match it with a driver).
116ec3d41c4SRusty Russell  * @config: the configuration ops for this device.
1173beee86aSSjur Brændeland  * @vringh_config: configuration ops for host vrings.
1189499f5e7SRusty Russell  * @vqs: the list of virtqueues for this device.
119c45a6816SRusty Russell  * @features: the features supported by both driver and device.
120ec3d41c4SRusty Russell  * @priv: private pointer for the driver's use.
121ec3d41c4SRusty Russell  */
1229499f5e7SRusty Russell struct virtio_device {
123ec3d41c4SRusty Russell 	int index;
124c6716baeSMichael S. Tsirkin 	bool failed;
12522b7050aSMichael S. Tsirkin 	bool config_enabled;
12622b7050aSMichael S. Tsirkin 	bool config_change_pending;
12722b7050aSMichael S. Tsirkin 	spinlock_t config_lock;
12833bd91fdSSimon Horman 	spinlock_t vqs_list_lock;
129ec3d41c4SRusty Russell 	struct device dev;
130ec3d41c4SRusty Russell 	struct virtio_device_id id;
13193503932SStephen Hemminger 	const struct virtio_config_ops *config;
1323beee86aSSjur Brændeland 	const struct vringh_config_ops *vringh_config;
1339499f5e7SRusty Russell 	struct list_head vqs;
134d0254773SMichael S. Tsirkin 	u64 features;
135ec3d41c4SRusty Russell 	void *priv;
136ec3d41c4SRusty Russell };
137ec3d41c4SRusty Russell 
138af3011b6SGreg Kroah-Hartman #define dev_to_virtio(_dev)	container_of_const(_dev, struct virtio_device, dev)
1399bffdca8SWanlong Gao 
1409fe7bfceSJohn Fastabend void virtio_add_status(struct virtio_device *dev, unsigned int status);
141ec3d41c4SRusty Russell int register_virtio_device(struct virtio_device *dev);
142ec3d41c4SRusty Russell void unregister_virtio_device(struct virtio_device *dev);
143a0308938SDavid Stevens bool is_virtio_device(struct device *dev);
144ec3d41c4SRusty Russell 
145e2dcdfe9SRusty Russell void virtio_break_device(struct virtio_device *dev);
146be83f04dSJason Wang void __virtio_unbreak_device(struct virtio_device *dev);
147e2dcdfe9SRusty Russell 
14832510631SXuan Zhuo void __virtqueue_break(struct virtqueue *_vq);
14932510631SXuan Zhuo void __virtqueue_unbreak(struct virtqueue *_vq);
15032510631SXuan Zhuo 
151016c98c6SMichael S. Tsirkin void virtio_config_changed(struct virtio_device *dev);
152c6716baeSMichael S. Tsirkin #ifdef CONFIG_PM_SLEEP
153c6716baeSMichael S. Tsirkin int virtio_device_freeze(struct virtio_device *dev);
154c6716baeSMichael S. Tsirkin int virtio_device_restore(struct virtio_device *dev);
155c6716baeSMichael S. Tsirkin #endif
156d9679d00SMichael S. Tsirkin void virtio_reset_device(struct virtio_device *dev);
157016c98c6SMichael S. Tsirkin 
1584b6ec919SFeng Liu size_t virtio_max_dma_size(const struct virtio_device *vdev);
159e6d6dd6cSJoerg Roedel 
16024a7e4d2SMichael S. Tsirkin #define virtio_device_for_each_vq(vdev, vq) \
16124a7e4d2SMichael S. Tsirkin 	list_for_each_entry(vq, &vdev->vqs, list)
16224a7e4d2SMichael S. Tsirkin 
163ec3d41c4SRusty Russell /**
1645c669c4aSRicardo Cañuelo  * struct virtio_driver - operations for a virtio I/O driver
165ec3d41c4SRusty Russell  * @driver: underlying device driver (populate name and owner).
166ec3d41c4SRusty Russell  * @id_table: the ids serviced by this driver.
1675f41f8bfSWang Sheng-Hui  * @feature_table: an array of feature numbers supported by this driver.
168c45a6816SRusty Russell  * @feature_table_size: number of entries in the feature table array.
169b3bb62d1SMichael S. Tsirkin  * @feature_table_legacy: same as feature_table but when working in legacy mode.
170b3bb62d1SMichael S. Tsirkin  * @feature_table_size_legacy: number of entries in feature table legacy array.
17133bd91fdSSimon Horman  * @validate: the function to call to validate features and config space.
17233bd91fdSSimon Horman  *            Returns 0 or -errno.
17320f77f56SRusty Russell  * @probe: the function to call when a device is found.  Returns 0 or -errno.
1749ea762a5SCornelia Huck  * @scan: optional function to call after successful probe; intended
1759ea762a5SCornelia Huck  *    for virtio-scsi to invoke a scan.
1765f41f8bfSWang Sheng-Hui  * @remove: the function to call when a device is removed.
177f957d1f0SRusty Russell  * @config_changed: optional function to call when the device configuration
178f957d1f0SRusty Russell  *    changes; may be called in interrupt context.
1799ea762a5SCornelia Huck  * @freeze: optional function to call during suspend/hibernation.
1809ea762a5SCornelia Huck  * @restore: optional function to call on resume.
181ec3d41c4SRusty Russell  */
182ec3d41c4SRusty Russell struct virtio_driver {
183ec3d41c4SRusty Russell 	struct device_driver driver;
184ec3d41c4SRusty Russell 	const struct virtio_device_id *id_table;
185c45a6816SRusty Russell 	const unsigned int *feature_table;
186c45a6816SRusty Russell 	unsigned int feature_table_size;
187b3bb62d1SMichael S. Tsirkin 	const unsigned int *feature_table_legacy;
188b3bb62d1SMichael S. Tsirkin 	unsigned int feature_table_size_legacy;
189404123c2SMichael S. Tsirkin 	int (*validate)(struct virtio_device *dev);
190ec3d41c4SRusty Russell 	int (*probe)(struct virtio_device *dev);
19159057fbcSNicholas Bellinger 	void (*scan)(struct virtio_device *dev);
192ec3d41c4SRusty Russell 	void (*remove)(struct virtio_device *dev);
193f957d1f0SRusty Russell 	void (*config_changed)(struct virtio_device *dev);
194f0fe6f11SAmit Shah 	int (*freeze)(struct virtio_device *dev);
195f0fe6f11SAmit Shah 	int (*restore)(struct virtio_device *dev);
196f0fe6f11SAmit Shah };
197f0fe6f11SAmit Shah 
drv_to_virtio(struct device_driver * drv)198ec3d41c4SRusty Russell static inline struct virtio_driver *drv_to_virtio(struct device_driver *drv)
199ec3d41c4SRusty Russell {
2009a2bdcc8SWanlong Gao 	return container_of(drv, struct virtio_driver, driver);
2019a2bdcc8SWanlong Gao }
2029a2bdcc8SWanlong Gao 
2039a2bdcc8SWanlong Gao int register_virtio_driver(struct virtio_driver *drv);
2049a2bdcc8SWanlong Gao void unregister_virtio_driver(struct virtio_driver *drv);
205ec3d41c4SRusty Russell 
206ec3d41c4SRusty Russell /* module_virtio_driver() - Helper macro for drivers that don't do
2076e105e05SSjur Brændeland  * anything special in module init/exit.  This eliminates a lot of
2086e105e05SSjur Brændeland  * boilerplate.  Each module may only use this macro once, and
2096e105e05SSjur Brændeland  * calling it replaces module_init() and module_exit()
2106e105e05SSjur Brændeland  */
2116e105e05SSjur Brændeland #define module_virtio_driver(__virtio_driver) \
2126e105e05SSjur Brændeland 	module_driver(__virtio_driver, register_virtio_driver, \
2136e105e05SSjur Brændeland 			unregister_virtio_driver)
2146e105e05SSjur Brændeland 
2156e105e05SSjur Brændeland dma_addr_t virtqueue_dma_map_single_attrs(struct virtqueue *_vq, void *ptr, size_t size,
216b6253b4eSXuan Zhuo 					  enum dma_data_direction dir, unsigned long attrs);
217b6253b4eSXuan Zhuo void virtqueue_dma_unmap_single_attrs(struct virtqueue *_vq, dma_addr_t addr,
218b6253b4eSXuan Zhuo 				      size_t size, enum dma_data_direction dir,
219b6253b4eSXuan Zhuo 				      unsigned long attrs);
220b6253b4eSXuan Zhuo int virtqueue_dma_mapping_error(struct virtqueue *_vq, dma_addr_t addr);
221b6253b4eSXuan Zhuo 
222b6253b4eSXuan Zhuo bool virtqueue_dma_need_sync(struct virtqueue *_vq, dma_addr_t addr);
223*8bd2f710SXuan Zhuo void virtqueue_dma_sync_single_range_for_cpu(struct virtqueue *_vq, dma_addr_t addr,
224*8bd2f710SXuan Zhuo 					     unsigned long offset, size_t size,
225*8bd2f710SXuan Zhuo 					     enum dma_data_direction dir);
226*8bd2f710SXuan Zhuo void virtqueue_dma_sync_single_range_for_device(struct virtqueue *_vq, dma_addr_t addr,
227*8bd2f710SXuan Zhuo 						unsigned long offset, size_t size,
228*8bd2f710SXuan Zhuo 						enum dma_data_direction dir);
229*8bd2f710SXuan Zhuo #endif /* _LINUX_VIRTIO_H */
230*8bd2f710SXuan Zhuo