1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2016 NXP 3 */ 4 5 #ifndef _RTE_BUS_H_ 6 #define _RTE_BUS_H_ 7 8 /** 9 * @file 10 * 11 * DPDK device bus interface 12 * 13 * This file exposes API and interfaces for bus abstraction 14 * over the devices and drivers in EAL. 15 */ 16 17 #ifdef __cplusplus 18 extern "C" { 19 #endif 20 21 #include <stdio.h> 22 23 #include <rte_dev.h> 24 #include <rte_eal.h> 25 #include <rte_log.h> 26 27 /** Double linked list of buses */ 28 RTE_TAILQ_HEAD(rte_bus_list, rte_bus); 29 30 /** 31 * Bus specific scan for devices attached on the bus. 32 * For each bus object, the scan would be responsible for finding devices and 33 * adding them to its private device list. 34 * 35 * A bus should mandatorily implement this method. 36 * 37 * @return 38 * 0 for successful scan 39 * <0 for unsuccessful scan with error value 40 */ 41 typedef int (*rte_bus_scan_t)(void); 42 43 /** 44 * Implementation specific probe function which is responsible for linking 45 * devices on that bus with applicable drivers. 46 * 47 * This is called while iterating over each registered bus. 48 * 49 * @return 50 * 0 for successful probe 51 * !0 for any error while probing 52 */ 53 typedef int (*rte_bus_probe_t)(void); 54 55 /** 56 * Device iterator to find a device on a bus. 57 * 58 * This function returns an rte_device if one of those held by the bus 59 * matches the data passed as parameter. 60 * 61 * If the comparison function returns zero this function should stop iterating 62 * over any more devices. To continue a search the device of a previous search 63 * can be passed via the start parameter. 64 * 65 * @param cmp 66 * Comparison function. 67 * 68 * @param data 69 * Data to compare each device against. 70 * 71 * @param start 72 * starting point for the iteration 73 * 74 * @return 75 * The first device matching the data, NULL if none exists. 76 */ 77 typedef struct rte_device * 78 (*rte_bus_find_device_t)(const struct rte_device *start, rte_dev_cmp_t cmp, 79 const void *data); 80 81 /** 82 * Implementation specific probe function which is responsible for linking 83 * devices on that bus with applicable drivers. 84 * 85 * @param dev 86 * Device pointer that was returned by a previous call to find_device. 87 * 88 * @return 89 * 0 on success. 90 * !0 on error. 91 */ 92 typedef int (*rte_bus_plug_t)(struct rte_device *dev); 93 94 /** 95 * Implementation specific remove function which is responsible for unlinking 96 * devices on that bus from assigned driver. 97 * 98 * @param dev 99 * Device pointer that was returned by a previous call to find_device. 100 * 101 * @return 102 * 0 on success. 103 * !0 on error. 104 */ 105 typedef int (*rte_bus_unplug_t)(struct rte_device *dev); 106 107 /** 108 * Bus specific parsing function. 109 * Validates the syntax used in the textual representation of a device, 110 * If the syntax is valid and ``addr`` is not NULL, writes the bus-specific 111 * device representation to ``addr``. 112 * 113 * @param[in] name 114 * device textual description 115 * 116 * @param[out] addr 117 * device information location address, into which parsed info 118 * should be written. If NULL, nothing should be written, which 119 * is not an error. 120 * 121 * @return 122 * 0 if parsing was successful. 123 * !0 for any error. 124 */ 125 typedef int (*rte_bus_parse_t)(const char *name, void *addr); 126 127 /** 128 * Parse bus part of the device arguments. 129 * 130 * The field name of the struct rte_devargs will be set. 131 * 132 * @param da 133 * Pointer to the devargs to parse. 134 * 135 * @return 136 * 0 on successful parsing, otherwise rte_errno is set. 137 * -EINVAL: on parsing error. 138 * -ENODEV: if no key matching a device argument is specified. 139 * -E2BIG: device name is too long. 140 */ 141 typedef int (*rte_bus_devargs_parse_t)(struct rte_devargs *da); 142 143 /** 144 * Device level DMA map function. 145 * After a successful call, the memory segment will be mapped to the 146 * given device. 147 * 148 * @param dev 149 * Device pointer. 150 * @param addr 151 * Virtual address to map. 152 * @param iova 153 * IOVA address to map. 154 * @param len 155 * Length of the memory segment being mapped. 156 * 157 * @return 158 * 0 if mapping was successful. 159 * Negative value and rte_errno is set otherwise. 160 */ 161 typedef int (*rte_dev_dma_map_t)(struct rte_device *dev, void *addr, 162 uint64_t iova, size_t len); 163 164 /** 165 * Device level DMA unmap function. 166 * After a successful call, the memory segment will no longer be 167 * accessible by the given device. 168 * 169 * @param dev 170 * Device pointer. 171 * @param addr 172 * Virtual address to unmap. 173 * @param iova 174 * IOVA address to unmap. 175 * @param len 176 * Length of the memory segment being mapped. 177 * 178 * @return 179 * 0 if un-mapping was successful. 180 * Negative value and rte_errno is set otherwise. 181 */ 182 typedef int (*rte_dev_dma_unmap_t)(struct rte_device *dev, void *addr, 183 uint64_t iova, size_t len); 184 185 /** 186 * Implement a specific hot-unplug handler, which is responsible for 187 * handle the failure when device be hot-unplugged. When the event of 188 * hot-unplug be detected, it could call this function to handle 189 * the hot-unplug failure and avoid app crash. 190 * @param dev 191 * Pointer of the device structure. 192 * 193 * @return 194 * 0 on success. 195 * !0 on error. 196 */ 197 typedef int (*rte_bus_hot_unplug_handler_t)(struct rte_device *dev); 198 199 /** 200 * Implement a specific sigbus handler, which is responsible for handling 201 * the sigbus error which is either original memory error, or specific memory 202 * error that caused of device be hot-unplugged. When sigbus error be captured, 203 * it could call this function to handle sigbus error. 204 * @param failure_addr 205 * Pointer of the fault address of the sigbus error. 206 * 207 * @return 208 * 0 for success handle the sigbus for hot-unplug. 209 * 1 for not process it, because it is a generic sigbus error. 210 * -1 for failed to handle the sigbus for hot-unplug. 211 */ 212 typedef int (*rte_bus_sigbus_handler_t)(const void *failure_addr); 213 214 /** 215 * Bus scan policies 216 */ 217 enum rte_bus_scan_mode { 218 RTE_BUS_SCAN_UNDEFINED, 219 RTE_BUS_SCAN_ALLOWLIST, 220 RTE_BUS_SCAN_BLOCKLIST, 221 }; 222 223 /** 224 * A structure used to configure bus operations. 225 */ 226 struct rte_bus_conf { 227 enum rte_bus_scan_mode scan_mode; /**< Scan policy. */ 228 }; 229 230 231 /** 232 * Get common iommu class of the all the devices on the bus. The bus may 233 * check that those devices are attached to iommu driver. 234 * If no devices are attached to the bus. The bus may return with don't care 235 * (_DC) value. 236 * Otherwise, The bus will return appropriate _pa or _va iova mode. 237 * 238 * @return 239 * enum rte_iova_mode value. 240 */ 241 typedef enum rte_iova_mode (*rte_bus_get_iommu_class_t)(void); 242 243 244 /** 245 * A structure describing a generic bus. 246 */ 247 struct rte_bus { 248 RTE_TAILQ_ENTRY(rte_bus) next; /**< Next bus object in linked list */ 249 const char *name; /**< Name of the bus */ 250 rte_bus_scan_t scan; /**< Scan for devices attached to bus */ 251 rte_bus_probe_t probe; /**< Probe devices on bus */ 252 rte_bus_find_device_t find_device; /**< Find a device on the bus */ 253 rte_bus_plug_t plug; /**< Probe single device for drivers */ 254 rte_bus_unplug_t unplug; /**< Remove single device from driver */ 255 rte_bus_parse_t parse; /**< Parse a device name */ 256 rte_bus_devargs_parse_t devargs_parse; /**< Parse bus devargs */ 257 rte_dev_dma_map_t dma_map; /**< DMA map for device in the bus */ 258 rte_dev_dma_unmap_t dma_unmap; /**< DMA unmap for device in the bus */ 259 struct rte_bus_conf conf; /**< Bus configuration */ 260 rte_bus_get_iommu_class_t get_iommu_class; /**< Get iommu class */ 261 rte_dev_iterate_t dev_iterate; /**< Device iterator. */ 262 rte_bus_hot_unplug_handler_t hot_unplug_handler; 263 /**< handle hot-unplug failure on the bus */ 264 rte_bus_sigbus_handler_t sigbus_handler; 265 /**< handle sigbus error on the bus */ 266 267 }; 268 269 /** 270 * Retrieve a bus name. 271 * 272 * @warning 273 * @b EXPERIMENTAL: this API may change without prior notice 274 * 275 * @param bus 276 * A pointer to a rte_bus structure. 277 * @return 278 * A pointer to the bus name string. 279 */ 280 __rte_experimental 281 const char *rte_bus_name(const struct rte_bus *bus); 282 283 /** 284 * Register a Bus handler. 285 * 286 * @param bus 287 * A pointer to a rte_bus structure describing the bus 288 * to be registered. 289 */ 290 void rte_bus_register(struct rte_bus *bus); 291 292 /** 293 * Unregister a Bus handler. 294 * 295 * @param bus 296 * A pointer to a rte_bus structure describing the bus 297 * to be unregistered. 298 */ 299 void rte_bus_unregister(struct rte_bus *bus); 300 301 /** 302 * Scan all the buses. 303 * 304 * @return 305 * 0 in case of success in scanning all buses 306 * !0 in case of failure to scan 307 */ 308 int rte_bus_scan(void); 309 310 /** 311 * For each device on the buses, perform a driver 'match' and call the 312 * driver-specific probe for device initialization. 313 * 314 * @return 315 * 0 for successful match/probe 316 * !0 otherwise 317 */ 318 int rte_bus_probe(void); 319 320 /** 321 * Dump information of all the buses registered with EAL. 322 * 323 * @param f 324 * A valid and open output stream handle 325 */ 326 void rte_bus_dump(FILE *f); 327 328 /** 329 * Bus comparison function. 330 * 331 * @param bus 332 * Bus under test. 333 * 334 * @param data 335 * Data to compare against. 336 * 337 * @return 338 * 0 if the bus matches the data. 339 * !0 if the bus does not match. 340 * <0 if ordering is possible and the bus is lower than the data. 341 * >0 if ordering is possible and the bus is greater than the data. 342 */ 343 typedef int (*rte_bus_cmp_t)(const struct rte_bus *bus, const void *data); 344 345 /** 346 * Bus iterator to find a particular bus. 347 * 348 * This function compares each registered bus to find one that matches 349 * the data passed as parameter. 350 * 351 * If the comparison function returns zero this function will stop iterating 352 * over any more buses. To continue a search the bus of a previous search can 353 * be passed via the start parameter. 354 * 355 * @param start 356 * Starting point for the iteration. 357 * 358 * @param cmp 359 * Comparison function. 360 * 361 * @param data 362 * Data to pass to comparison function. 363 * 364 * @return 365 * A pointer to a rte_bus structure or NULL in case no bus matches 366 */ 367 struct rte_bus *rte_bus_find(const struct rte_bus *start, rte_bus_cmp_t cmp, 368 const void *data); 369 370 /** 371 * Find the registered bus for a particular device. 372 */ 373 struct rte_bus *rte_bus_find_by_device(const struct rte_device *dev); 374 375 /** 376 * Find the registered bus for a given name. 377 */ 378 struct rte_bus *rte_bus_find_by_name(const char *busname); 379 380 381 /** 382 * Get the common iommu class of devices bound on to buses available in the 383 * system. RTE_IOVA_DC means that no preference has been expressed. 384 * 385 * @return 386 * enum rte_iova_mode value. 387 */ 388 enum rte_iova_mode rte_bus_get_iommu_class(void); 389 390 /** 391 * Helper for Bus registration. 392 * The constructor has higher priority than PMD constructors. 393 */ 394 #define RTE_REGISTER_BUS(nm, bus) \ 395 RTE_INIT_PRIO(businitfn_ ##nm, BUS) \ 396 {\ 397 (bus).name = RTE_STR(nm);\ 398 rte_bus_register(&bus); \ 399 } 400 401 #ifdef __cplusplus 402 } 403 #endif 404 405 #endif /* _RTE_BUS_H */ 406