xref: /spdk/lib/env_dpdk/22.11/bus_driver.h (revision 5497616e8ff768313a441980d44f439558509b4f)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2022 Red Hat, Inc.
3  */
4 
5 #ifndef BUS_DRIVER_H
6 #define BUS_DRIVER_H
7 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
12 #include "rte_bus.h"
13 #include <rte_compat.h>
14 #include "rte_dev.h"
15 #include <rte_eal.h>
16 #include <rte_tailq.h>
17 
18 struct rte_devargs;
19 struct rte_device;
20 
21 /** Double linked list of buses */
22 RTE_TAILQ_HEAD(rte_bus_list, rte_bus);
23 
24 /**
25  * Bus specific scan for devices attached on the bus.
26  * For each bus object, the scan would be responsible for finding devices and
27  * adding them to its private device list.
28  *
29  * A bus should mandatorily implement this method.
30  *
31  * @return
32  *	0 for successful scan
33  *	<0 for unsuccessful scan with error value
34  */
35 typedef int (*rte_bus_scan_t)(void);
36 
37 /**
38  * Implementation specific probe function which is responsible for linking
39  * devices on that bus with applicable drivers.
40  *
41  * This is called while iterating over each registered bus.
42  *
43  * @return
44  *	0 for successful probe
45  *	!0 for any error while probing
46  */
47 typedef int (*rte_bus_probe_t)(void);
48 
49 /**
50  * Device iterator to find a device on a bus.
51  *
52  * This function returns an rte_device if one of those held by the bus
53  * matches the data passed as parameter.
54  *
55  * If the comparison function returns zero this function should stop iterating
56  * over any more devices. To continue a search the device of a previous search
57  * can be passed via the start parameter.
58  *
59  * @param cmp
60  *	Comparison function.
61  *
62  * @param data
63  *	Data to compare each device against.
64  *
65  * @param start
66  *	starting point for the iteration
67  *
68  * @return
69  *	The first device matching the data, NULL if none exists.
70  */
71 typedef struct rte_device *
72 (*rte_bus_find_device_t)(const struct rte_device *start, rte_dev_cmp_t cmp,
73 			 const void *data);
74 
75 /**
76  * Implementation specific probe function which is responsible for linking
77  * devices on that bus with applicable drivers.
78  *
79  * @param dev
80  *	Device pointer that was returned by a previous call to find_device.
81  *
82  * @return
83  *	0 on success.
84  *	!0 on error.
85  */
86 typedef int (*rte_bus_plug_t)(struct rte_device *dev);
87 
88 /**
89  * Implementation specific remove function which is responsible for unlinking
90  * devices on that bus from assigned driver.
91  *
92  * @param dev
93  *	Device pointer that was returned by a previous call to find_device.
94  *
95  * @return
96  *	0 on success.
97  *	!0 on error.
98  */
99 typedef int (*rte_bus_unplug_t)(struct rte_device *dev);
100 
101 /**
102  * Bus specific parsing function.
103  * Validates the syntax used in the textual representation of a device,
104  * If the syntax is valid and ``addr`` is not NULL, writes the bus-specific
105  * device representation to ``addr``.
106  *
107  * @param[in] name
108  *	device textual description
109  *
110  * @param[out] addr
111  *	device information location address, into which parsed info
112  *	should be written. If NULL, nothing should be written, which
113  *	is not an error.
114  *
115  * @return
116  *	0 if parsing was successful.
117  *	!0 for any error.
118  */
119 typedef int (*rte_bus_parse_t)(const char *name, void *addr);
120 
121 /**
122  * Parse bus part of the device arguments.
123  *
124  * The field name of the struct rte_devargs will be set.
125  *
126  * @param da
127  *	Pointer to the devargs to parse.
128  *
129  * @return
130  *	0 on successful parsing, otherwise rte_errno is set.
131  *	-EINVAL: on parsing error.
132  *	-ENODEV: if no key matching a device argument is specified.
133  *	-E2BIG: device name is too long.
134  */
135 typedef int (*rte_bus_devargs_parse_t)(struct rte_devargs *da);
136 
137 /**
138  * Device level DMA map function.
139  * After a successful call, the memory segment will be mapped to the
140  * given device.
141  *
142  * @param dev
143  *	Device pointer.
144  * @param addr
145  *	Virtual address to map.
146  * @param iova
147  *	IOVA address to map.
148  * @param len
149  *	Length of the memory segment being mapped.
150  *
151  * @return
152  *	0 if mapping was successful.
153  *	Negative value and rte_errno is set otherwise.
154  */
155 typedef int (*rte_dev_dma_map_t)(struct rte_device *dev, void *addr,
156 				  uint64_t iova, size_t len);
157 
158 /**
159  * Device level DMA unmap function.
160  * After a successful call, the memory segment will no longer be
161  * accessible by the given device.
162  *
163  * @param dev
164  *	Device pointer.
165  * @param addr
166  *	Virtual address to unmap.
167  * @param iova
168  *	IOVA address to unmap.
169  * @param len
170  *	Length of the memory segment being mapped.
171  *
172  * @return
173  *	0 if un-mapping was successful.
174  *	Negative value and rte_errno is set otherwise.
175  */
176 typedef int (*rte_dev_dma_unmap_t)(struct rte_device *dev, void *addr,
177 				   uint64_t iova, size_t len);
178 
179 /**
180  * Implement a specific hot-unplug handler, which is responsible for
181  * handle the failure when device be hot-unplugged. When the event of
182  * hot-unplug be detected, it could call this function to handle
183  * the hot-unplug failure and avoid app crash.
184  * @param dev
185  *	Pointer of the device structure.
186  *
187  * @return
188  *	0 on success.
189  *	!0 on error.
190  */
191 typedef int (*rte_bus_hot_unplug_handler_t)(struct rte_device *dev);
192 
193 /**
194  * Implement a specific sigbus handler, which is responsible for handling
195  * the sigbus error which is either original memory error, or specific memory
196  * error that caused of device be hot-unplugged. When sigbus error be captured,
197  * it could call this function to handle sigbus error.
198  * @param failure_addr
199  *	Pointer of the fault address of the sigbus error.
200  *
201  * @return
202  *	0 for success handle the sigbus for hot-unplug.
203  *	1 for not process it, because it is a generic sigbus error.
204  *	-1 for failed to handle the sigbus for hot-unplug.
205  */
206 typedef int (*rte_bus_sigbus_handler_t)(const void *failure_addr);
207 
208 /**
209  * Implementation specific cleanup function which is responsible for cleaning up
210  * devices on that bus with applicable drivers.
211  *
212  * This is called while iterating over each registered bus.
213  *
214  * @return
215  * 0 for successful cleanup
216  * !0 for any error during cleanup
217  */
218 typedef int (*rte_bus_cleanup_t)(void);
219 
220 /**
221  * Bus scan policies
222  */
223 enum rte_bus_scan_mode {
224 	RTE_BUS_SCAN_UNDEFINED,
225 	RTE_BUS_SCAN_ALLOWLIST,
226 	RTE_BUS_SCAN_BLOCKLIST,
227 };
228 
229 /**
230  * A structure used to configure bus operations.
231  */
232 struct rte_bus_conf {
233 	enum rte_bus_scan_mode scan_mode; /**< Scan policy. */
234 };
235 
236 
237 /**
238  * Get common iommu class of the all the devices on the bus. The bus may
239  * check that those devices are attached to iommu driver.
240  * If no devices are attached to the bus. The bus may return with don't care
241  * (_DC) value.
242  * Otherwise, The bus will return appropriate _pa or _va iova mode.
243  *
244  * @return
245  *      enum rte_iova_mode value.
246  */
247 typedef enum rte_iova_mode (*rte_bus_get_iommu_class_t)(void);
248 
249 /**
250  * A structure describing a generic bus.
251  */
252 struct rte_bus {
253 	RTE_TAILQ_ENTRY(rte_bus) next; /**< Next bus object in linked list */
254 	const char *name;            /**< Name of the bus */
255 	rte_bus_scan_t scan;         /**< Scan for devices attached to bus */
256 	rte_bus_probe_t probe;       /**< Probe devices on bus */
257 	rte_bus_find_device_t find_device; /**< Find a device on the bus */
258 	rte_bus_plug_t plug;         /**< Probe single device for drivers */
259 	rte_bus_unplug_t unplug;     /**< Remove single device from driver */
260 	rte_bus_parse_t parse;       /**< Parse a device name */
261 	rte_bus_devargs_parse_t devargs_parse; /**< Parse bus devargs */
262 	rte_dev_dma_map_t dma_map;   /**< DMA map for device in the bus */
263 	rte_dev_dma_unmap_t dma_unmap; /**< DMA unmap for device in the bus */
264 	struct rte_bus_conf conf;    /**< Bus configuration */
265 	rte_bus_get_iommu_class_t get_iommu_class; /**< Get iommu class */
266 	rte_dev_iterate_t dev_iterate; /**< Device iterator. */
267 	rte_bus_hot_unplug_handler_t hot_unplug_handler;
268 				/**< handle hot-unplug failure on the bus */
269 	rte_bus_sigbus_handler_t sigbus_handler;
270 					/**< handle sigbus error on the bus */
271 	rte_bus_cleanup_t cleanup;   /**< Cleanup devices on bus */
272 };
273 
274 /**
275  * Register a Bus handler.
276  *
277  * @param bus
278  *   A pointer to a rte_bus structure describing the bus
279  *   to be registered.
280  */
281 __rte_internal
282 void rte_bus_register(struct rte_bus *bus);
283 
284 /**
285  * Helper for Bus registration.
286  * The constructor has higher priority than PMD constructors.
287  */
288 #define RTE_REGISTER_BUS(nm, bus) \
289 RTE_INIT_PRIO(businitfn_ ##nm, BUS) \
290 {\
291 	(bus).name = RTE_STR(nm);\
292 	rte_bus_register(&bus); \
293 }
294 
295 /**
296  * Unregister a Bus handler.
297  *
298  * @param bus
299  *   A pointer to a rte_bus structure describing the bus
300  *   to be unregistered.
301  */
302 __rte_internal
303 void rte_bus_unregister(struct rte_bus *bus);
304 
305 #ifdef __cplusplus
306 }
307 #endif
308 
309 #endif /* BUS_DRIVER_H */
310