1 | /* Driver Manager Interface. |
---|
2 | * |
---|
3 | * COPYRIGHT (c) 2009 Cobham Gaisler AB. |
---|
4 | * |
---|
5 | * The license and distribution terms for this file may be |
---|
6 | * found in the file LICENSE in this distribution or at |
---|
7 | * http://www.rtems.org/license/LICENSE. |
---|
8 | */ |
---|
9 | |
---|
10 | #ifndef _DRIVER_MANAGER_H_ |
---|
11 | #define _DRIVER_MANAGER_H_ |
---|
12 | |
---|
13 | #include <rtems.h> |
---|
14 | #include <drvmgr/drvmgr_list.h> |
---|
15 | #include <stdint.h> |
---|
16 | #include <rtems/score/basedefs.h> |
---|
17 | |
---|
18 | #ifdef __cplusplus |
---|
19 | extern "C" { |
---|
20 | #endif |
---|
21 | |
---|
22 | /*** Configure Driver manager ***/ |
---|
23 | |
---|
24 | /* Define the number of initialization levels of device drivers */ |
---|
25 | #define DRVMGR_LEVEL_MAX 4 |
---|
26 | |
---|
27 | /* Default to use semahpores for protection. Initialization works without |
---|
28 | * locks and after initialization too if devices are not removed. |
---|
29 | */ |
---|
30 | #ifndef DRVMGR_USE_LOCKS |
---|
31 | #define DRVMGR_USE_LOCKS 1 |
---|
32 | #endif |
---|
33 | |
---|
34 | struct drvmgr_dev; /* Device */ |
---|
35 | struct drvmgr_bus; /* Bus */ |
---|
36 | struct drvmgr_drv; /* Driver */ |
---|
37 | |
---|
38 | /*** List Interface shortcuts ***/ |
---|
39 | #define BUS_LIST_HEAD(list) LIST_HEAD(list, struct drvmgr_bus) |
---|
40 | #define BUS_LIST_TAIL(list) LIST_TAIL(list, struct drvmgr_bus) |
---|
41 | #define DEV_LIST_HEAD(list) LIST_HEAD(list, struct drvmgr_dev) |
---|
42 | #define DEV_LIST_TAIL(list) LIST_TAIL(list, struct drvmgr_dev) |
---|
43 | #define DRV_LIST_HEAD(list) LIST_HEAD(list, struct drvmgr_drv) |
---|
44 | #define DRV_LIST_TAIL(list) LIST_TAIL(list, struct drvmgr_drv) |
---|
45 | |
---|
46 | /*** Bus indentification ***/ |
---|
47 | #define DRVMGR_BUS_TYPE_NONE 0 /* Not a valid bus */ |
---|
48 | #define DRVMGR_BUS_TYPE_ROOT 1 /* Hard coded bus */ |
---|
49 | #define DRVMGR_BUS_TYPE_PCI 2 /* PCI bus */ |
---|
50 | #define DRVMGR_BUS_TYPE_AMBAPP 3 /* AMBA Plug & Play bus */ |
---|
51 | #define DRVMGR_BUS_TYPE_LEON2_AMBA 4 /* LEON2 hardcoded bus */ |
---|
52 | #define DRVMGR_BUS_TYPE_AMBAPP_DIST 5 /* Distibuted AMBA Plug & Play bus accessed using a communication interface */ |
---|
53 | #define DRVMGR_BUS_TYPE_SPW_RMAP 6 /* SpaceWire Network bus */ |
---|
54 | #define DRVMGR_BUS_TYPE_AMBAPP_RMAP 7 /* SpaceWire RMAP accessed AMBA Plug & Play bus */ |
---|
55 | |
---|
56 | enum { |
---|
57 | DRVMGR_OBJ_NONE = 0, |
---|
58 | DRVMGR_OBJ_DRV = 1, |
---|
59 | DRVMGR_OBJ_BUS = 2, |
---|
60 | DRVMGR_OBJ_DEV = 3, |
---|
61 | }; |
---|
62 | |
---|
63 | /*** Driver indentification *** |
---|
64 | * |
---|
65 | * 64-bit identification integer definition |
---|
66 | * * Bus ID 8-bit [7..0] |
---|
67 | * * Reserved 8-bit field [63..56] |
---|
68 | * * Device ID specific for bus type 48-bit [55..8] (Different buses have |
---|
69 | * different unique identifications for hardware/driver.) |
---|
70 | * |
---|
71 | * ID Rules |
---|
72 | * * A root bus driver must always have device ID set to 0. There can only by |
---|
73 | * one root bus driver for a certain bus type. |
---|
74 | * * A Driver ID must identify a unique hardware core |
---|
75 | * |
---|
76 | */ |
---|
77 | |
---|
78 | /* Bus ID Mask */ |
---|
79 | #define DRIVER_ID_BUS_MASK 0x00000000000000FFULL |
---|
80 | |
---|
81 | /* Reserved Mask for future use */ |
---|
82 | #define DRIVER_ID_RSV_MASK 0xFF00000000000000ULL |
---|
83 | |
---|
84 | /* Reserved Mask for future use */ |
---|
85 | #define DRIVER_ID_DEV_MASK 0x00FFFFFFFFFFFF00ULL |
---|
86 | |
---|
87 | /* Set Bus ID Mask. */ |
---|
88 | #define DRIVER_ID(busid, devid) ((unsigned long long) \ |
---|
89 | ((((unsigned long long)(devid) << 8) & DRIVER_ID_DEV_MASK) | \ |
---|
90 | ((unsigned long long)(busid) & DRIVER_ID_BUS_MASK))) |
---|
91 | |
---|
92 | /* Get IDs */ |
---|
93 | #define DRIVER_BUSID_GET(id) ((unsigned long long)(id) & DRIVER_ID_BUS_MASK) |
---|
94 | #define DRIVER_DEVID_GET(id) (((unsigned long long)(id) & DRIVER_ID_DEV_MASK) >> 8) |
---|
95 | |
---|
96 | #define DRIVER_ROOTBUS_ID(bus_type) DRIVER_ID(bus_type, 0) |
---|
97 | |
---|
98 | /*** Root Bus drivers ***/ |
---|
99 | |
---|
100 | /* Generic Hard coded Root bus: Driver ID */ |
---|
101 | #define DRIVER_ROOT_ID DRIVER_ROOTBUS_ID(DRVMGR_BUS_TYPE_ROOT) |
---|
102 | |
---|
103 | /* PCI Plug & Play bus: Driver ID */ |
---|
104 | #define DRIVER_PCIBUS_ID DRIVER_ROOTBUS_ID(DRVMGR_BUS_TYPE_PCI) |
---|
105 | |
---|
106 | /* AMBA Plug & Play bus: Driver ID */ |
---|
107 | #define DRIVER_GRLIB_AMBAPP_ID DRIVER_ROOTBUS_ID(DRVMGR_BUS_TYPE_AMBAPP) |
---|
108 | |
---|
109 | /* AMBA Hard coded bus: Driver ID */ |
---|
110 | #define DRIVER_LEON2_AMBA_ID DRIVER_ROOTBUS_ID(DRVMGR_BUS_TYPE_LEON2_AMBA) |
---|
111 | |
---|
112 | /* Distributed AMBA Plug & Play bus: Driver ID */ |
---|
113 | #define DRIVER_AMBAPP_DIST_ID DRIVER_ROOTBUS_ID(DRVMGR_BUS_TYPE_AMBAPP_DIST) |
---|
114 | |
---|
115 | /*! Bus parameters used by driver interface functions to aquire information |
---|
116 | * about bus. All Bus drivers should implement the operation 'get_params' so |
---|
117 | * that the driver interface routines can access bus dependent information in |
---|
118 | * an non-dependent way. |
---|
119 | */ |
---|
120 | struct drvmgr_bus_params { |
---|
121 | char *dev_prefix; /*!< Optional name prefix */ |
---|
122 | }; |
---|
123 | |
---|
124 | /* Interrupt Service Routine (ISR) */ |
---|
125 | typedef void (*drvmgr_isr)(void *arg); |
---|
126 | |
---|
127 | /*! Bus operations */ |
---|
128 | struct drvmgr_bus_ops { |
---|
129 | /* Functions used internally within driver manager */ |
---|
130 | int (*init[DRVMGR_LEVEL_MAX])(struct drvmgr_bus *); |
---|
131 | int (*remove)(struct drvmgr_bus *); |
---|
132 | int (*unite)(struct drvmgr_drv *, struct drvmgr_dev *); /*!< Unite Hardware Device with Driver */ |
---|
133 | |
---|
134 | /* Functions called indirectly from drivers */ |
---|
135 | int (*int_register)(struct drvmgr_dev *, int index, const char *info, drvmgr_isr isr, void *arg); |
---|
136 | int (*int_unregister)(struct drvmgr_dev *, int index, drvmgr_isr isr, void *arg); |
---|
137 | int (*int_clear)(struct drvmgr_dev *, int index); |
---|
138 | int (*int_mask)(struct drvmgr_dev *, int index); |
---|
139 | int (*int_unmask)(struct drvmgr_dev *, int index); |
---|
140 | |
---|
141 | /* Get Parameters */ |
---|
142 | int (*get_params)(struct drvmgr_dev *, struct drvmgr_bus_params *); |
---|
143 | /* Get Frequency of Bus */ |
---|
144 | int (*get_freq)(struct drvmgr_dev*, int, unsigned int*); |
---|
145 | /*! Function called to request information about a device. The bus |
---|
146 | * driver interpret the bus-specific information about the device. |
---|
147 | */ |
---|
148 | void (*get_info_dev)(struct drvmgr_dev *, |
---|
149 | void (*print)(void *p, char *str), void *p); |
---|
150 | }; |
---|
151 | #define BUS_OPS_NUM (sizeof(struct drvmgr_bus_ops)/sizeof(void (*)(void))) |
---|
152 | |
---|
153 | struct drvmgr_func { |
---|
154 | int funcid; |
---|
155 | void *func; |
---|
156 | }; |
---|
157 | #define DRVMGR_FUNC(_ID_, _FUNC_) {(int)(_ID_), (void *)(_FUNC_)} |
---|
158 | #define DRVMGR_FUNC_END {0, NULL} |
---|
159 | |
---|
160 | /*** Resource definitions *** |
---|
161 | * |
---|
162 | * Overview of structures: |
---|
163 | * All bus resources entries (_bus_res) are linked together per bus |
---|
164 | * (bus_info->reslist). One bus resource entry has a pointer to an array of |
---|
165 | * driver resources (_drv_res). One driver resouces is made out of an array |
---|
166 | * of keys (drvmgr_key). All keys belongs to the same driver and harwdare |
---|
167 | * device. Each key has a Name, Type ID and Data interpreted differently |
---|
168 | * depending on the Type ID (union drvmgr_key_value). |
---|
169 | * |
---|
170 | */ |
---|
171 | |
---|
172 | /* Key Data Types */ |
---|
173 | enum drvmgr_kt { |
---|
174 | DRVMGR_KT_ANY = -1, |
---|
175 | DRVMGR_KT_NONE = 0, |
---|
176 | DRVMGR_KT_INT = 1, |
---|
177 | DRVMGR_KT_STRING = 2, |
---|
178 | DRVMGR_KT_POINTER = 3, |
---|
179 | }; |
---|
180 | |
---|
181 | #define DRVMGR_KEY_EMPTY {NULL, DRVMGR_KT_NONE, {0}} |
---|
182 | #define DRVMGR_RES_EMPTY {0, 0, NULL} |
---|
183 | #define MMAP_EMPTY {0, 0, 0} |
---|
184 | |
---|
185 | /*! Union of different values */ |
---|
186 | union drvmgr_key_value { |
---|
187 | unsigned int i; /*!< Key data type UNSIGNED INTEGER */ |
---|
188 | char *str; /*!< Key data type STRING */ |
---|
189 | void *ptr; /*!< Key data type ADDRESS/POINTER */ |
---|
190 | }; |
---|
191 | |
---|
192 | /* One key. One Value. Holding information relevant to the driver. */ |
---|
193 | struct drvmgr_key { |
---|
194 | char *key_name; /* Name of key */ |
---|
195 | enum drvmgr_kt key_type; /* How to interpret key_value */ |
---|
196 | union drvmgr_key_value key_value; /* The value or pointer to value */ |
---|
197 | }; |
---|
198 | |
---|
199 | /*! Driver resource entry, Driver resources for a certain device instance, |
---|
200 | * containing a number of keys where each key hold the data of interest. |
---|
201 | */ |
---|
202 | struct drvmgr_drv_res { |
---|
203 | uint64_t drv_id; /*!< Identifies the driver this resource is aiming */ |
---|
204 | int minor_bus; /*!< Indentifies a specfic device */ |
---|
205 | struct drvmgr_key *keys; /*!< First key in key array, ended with KEY_EMPTY */ |
---|
206 | }; |
---|
207 | |
---|
208 | /*! Bus resource list node */ |
---|
209 | struct drvmgr_bus_res { |
---|
210 | struct drvmgr_bus_res *next; /*!< Next resource node in list */ |
---|
211 | struct drvmgr_drv_res resource[]; /*!< Array of resources, one per device instance */ |
---|
212 | }; |
---|
213 | |
---|
214 | /*! MAP entry. Describes an linear address space translation. Untranslated |
---|
215 | * Start, Translated Start and length. |
---|
216 | * |
---|
217 | * Used by bus drivers to describe the address translation needed for |
---|
218 | * the translation driver interface. |
---|
219 | */ |
---|
220 | struct drvmgr_map_entry { |
---|
221 | char *name; /*!< Map Name */ |
---|
222 | unsigned int size; /*!< Size of map window */ |
---|
223 | char *from_adr; /*!< Start address of access window used |
---|
224 | * to reach into remote bus */ |
---|
225 | char *to_adr; /*!< Start address of remote system |
---|
226 | * address range */ |
---|
227 | }; |
---|
228 | #define DRVMGR_TRANSLATE_ONE2ONE NULL |
---|
229 | #define DRVMGR_TRANSLATE_NO_BRIDGE ((void *)1) /* No bridge, error */ |
---|
230 | |
---|
231 | /*! Bus information. Describes a bus. */ |
---|
232 | struct drvmgr_bus { |
---|
233 | int obj_type; /*!< DRVMGR_OBJ_BUS */ |
---|
234 | unsigned char bus_type; /*!< Type of bus */ |
---|
235 | unsigned char depth; /*!< Bus level distance from root bus */ |
---|
236 | struct drvmgr_bus *next; /*!< Next Bus */ |
---|
237 | struct drvmgr_dev *dev; /*!< Bus device, the hardware... */ |
---|
238 | void *priv; /*!< Private data structure used by BUS driver */ |
---|
239 | struct drvmgr_dev *children; /*!< Hardware devices on this bus */ |
---|
240 | struct drvmgr_bus_ops *ops; /*!< Bus operations supported by this bus driver */ |
---|
241 | struct drvmgr_func *funcs; /*!< Extra operations */ |
---|
242 | int dev_cnt; /*!< Number of devices this bus has */ |
---|
243 | struct drvmgr_bus_res *reslist; /*!< Bus resources, head of a linked list of resources. */ |
---|
244 | struct drvmgr_map_entry *maps_up; /*!< Map Translation, array of address spaces upstreams to CPU */ |
---|
245 | struct drvmgr_map_entry *maps_down; /*!< Map Translation, array of address spaces downstreams to Hardware */ |
---|
246 | |
---|
247 | /* Bus status */ |
---|
248 | int level; /*!< Initialization Level of Bus */ |
---|
249 | int state; /*!< Init State of Bus, BUS_STATE_* */ |
---|
250 | int error; /*!< Return code from bus->ops->initN() */ |
---|
251 | }; |
---|
252 | |
---|
253 | /* States of a bus */ |
---|
254 | #define BUS_STATE_INIT_FAILED 0x00000001 /* Initialization Failed */ |
---|
255 | #define BUS_STATE_LIST_INACTIVE 0x00001000 /* In inactive bus list */ |
---|
256 | #define BUS_STATE_DEPEND_FAILED 0x00000004 /* Device init failed */ |
---|
257 | |
---|
258 | /* States of a device */ |
---|
259 | #define DEV_STATE_INIT_FAILED 0x00000001 /* Initialization Failed */ |
---|
260 | #define DEV_STATE_INIT_DONE 0x00000002 /* All init levels completed */ |
---|
261 | #define DEV_STATE_DEPEND_FAILED 0x00000004 /* Parent Bus init failed */ |
---|
262 | #define DEV_STATE_UNITED 0x00000100 /* Device United with Device Driver */ |
---|
263 | #define DEV_STATE_REMOVED 0x00000200 /* Device has been removed (unregistered) */ |
---|
264 | #define DEV_STATE_IGNORED 0x00000400 /* Device was ignored according to user's request, the device |
---|
265 | * was never reported to it's driver (as expected). |
---|
266 | */ |
---|
267 | #define DEV_STATE_LIST_INACTIVE 0x00001000 /* In inactive device list */ |
---|
268 | |
---|
269 | /*! Device information */ |
---|
270 | struct drvmgr_dev { |
---|
271 | int obj_type; /*!< DRVMGR_OBJ_DEV */ |
---|
272 | struct drvmgr_dev *next; /*!< Next device */ |
---|
273 | struct drvmgr_dev *next_in_bus; /*!< Next device on the same bus */ |
---|
274 | struct drvmgr_dev *next_in_drv; /*!< Next device using the same driver */ |
---|
275 | |
---|
276 | struct drvmgr_drv *drv; /*!< The driver owning this device */ |
---|
277 | struct drvmgr_bus *parent; /*!< Bus that this device resides on */ |
---|
278 | short minor_drv; /*!< Device number within driver */ |
---|
279 | short minor_bus; /*!< Device number on bus (for device separation) */ |
---|
280 | char *name; /*!< Name of Device Hardware */ |
---|
281 | void *priv; /*!< Pointer to driver private device structure */ |
---|
282 | void *businfo; /*!< Host bus specific information */ |
---|
283 | struct drvmgr_bus *bus; /*!< Pointer to bus, set only if this is a bridge */ |
---|
284 | |
---|
285 | /* Device Status */ |
---|
286 | unsigned int state; /*!< State of device, see DEV_STATE_* */ |
---|
287 | int level; /*!< Init Level */ |
---|
288 | int error; /*!< Error state returned by driver */ |
---|
289 | }; |
---|
290 | |
---|
291 | /*! Driver operations, function pointers. */ |
---|
292 | struct drvmgr_drv_ops { |
---|
293 | int (*init[DRVMGR_LEVEL_MAX])(struct drvmgr_dev *); /*! Function doing Init Stage 1 of a hardware device */ |
---|
294 | int (*remove)(struct drvmgr_dev *); /*! Function called when device instance is to be removed */ |
---|
295 | int (*info)(struct drvmgr_dev *, void (*print)(void *p, char *str), void *p, int, char *argv[]);/*! Function called to request information about a device or driver */ |
---|
296 | }; |
---|
297 | #define DRVMGR_OPS_NUM(x) (sizeof(x)/sizeof(void (*)(void))) |
---|
298 | |
---|
299 | /*! Device driver description */ |
---|
300 | struct drvmgr_drv { |
---|
301 | int obj_type; /*!< DRVMGR_OBJ_DRV */ |
---|
302 | struct drvmgr_drv *next; /*!< Next Driver */ |
---|
303 | struct drvmgr_dev *dev; /*!< Devices using this driver */ |
---|
304 | |
---|
305 | uint64_t drv_id; /*!< Unique Driver ID */ |
---|
306 | char *name; /*!< Name of Driver */ |
---|
307 | int bus_type; /*!< Type of Bus this driver supports */ |
---|
308 | struct drvmgr_drv_ops *ops; /*!< Driver operations */ |
---|
309 | struct drvmgr_func *funcs; /*!< Extra Operations */ |
---|
310 | unsigned int dev_cnt; /*!< Number of devices in dev */ |
---|
311 | unsigned int dev_priv_size; /*!< If non-zero DRVMGR will allocate memory for dev->priv */ |
---|
312 | }; |
---|
313 | |
---|
314 | /*! Structure defines a function pointer called when driver manager is ready |
---|
315 | * for drivers to register themselfs. Used to select drivers available to the |
---|
316 | * driver manager. |
---|
317 | */ |
---|
318 | typedef void (*drvmgr_drv_reg_func)(void); |
---|
319 | |
---|
320 | /*** DRIVER | DEVICE | BUS FUNCTIONS ***/ |
---|
321 | |
---|
322 | /* Return Codes */ |
---|
323 | enum { |
---|
324 | DRVMGR_OK = 0, /* Sucess */ |
---|
325 | DRVMGR_NOMEM = 1, /* Memory allocation error */ |
---|
326 | DRVMGR_EIO = 2, /* I/O error */ |
---|
327 | DRVMGR_EINVAL = 3, /* Invalid parameter */ |
---|
328 | DRVMGR_ENOSYS = 4, |
---|
329 | DRVMGR_TIMEDOUT = 5, /* Operation timeout error */ |
---|
330 | DRVMGR_EBUSY = 6, |
---|
331 | DRVMGR_ENORES = 7, /* Not enough resources */ |
---|
332 | DRVMGR_FAIL = -1 /* Unspecified failure */ |
---|
333 | }; |
---|
334 | |
---|
335 | /*! Initialize data structures of the driver management system. |
---|
336 | * Calls predefined register driver functions so that drivers can |
---|
337 | * register themselves. |
---|
338 | */ |
---|
339 | extern void _DRV_Manager_initialization(void); |
---|
340 | |
---|
341 | /*! Take all devices into init level 'level', all devices registered later |
---|
342 | * will directly be taken into this level as well, ensuring that all |
---|
343 | * registerd devices has been taken into the level. |
---|
344 | * |
---|
345 | */ |
---|
346 | extern void _DRV_Manager_init_level(int level); |
---|
347 | |
---|
348 | /*! This function must be defined by the BSP when the driver manager is enabled |
---|
349 | * and initialized during BSP initialization. The function is called after a |
---|
350 | * init level is reached the first time by the driver manager. |
---|
351 | */ |
---|
352 | extern void bsp_driver_level_hook(int level); |
---|
353 | |
---|
354 | /*! Init driver manager all in one go, will call _DRV_Manager_initialization(), |
---|
355 | * then _DRV_Manager_init_level([1..DRVMGR_LEVEL_MAX]). |
---|
356 | * Typically called from Init task when user wants to initilize driver |
---|
357 | * manager after startup, otherwise not used. |
---|
358 | */ |
---|
359 | extern int drvmgr_init(void); |
---|
360 | |
---|
361 | /* Take registered buses and devices into the correct init level, |
---|
362 | * this function is called from _init_level() so normally |
---|
363 | * we don't need to call it directly. |
---|
364 | */ |
---|
365 | extern void drvmgr_init_update(void); |
---|
366 | |
---|
367 | /*! Register Root Bus device driver */ |
---|
368 | extern int drvmgr_root_drv_register(struct drvmgr_drv *drv); |
---|
369 | |
---|
370 | /*! Register a driver */ |
---|
371 | extern int drvmgr_drv_register(struct drvmgr_drv *drv); |
---|
372 | |
---|
373 | /*! Register a device */ |
---|
374 | extern int drvmgr_dev_register(struct drvmgr_dev *dev); |
---|
375 | |
---|
376 | /*! Remove a device, and all its children devices if device is a bus device. The |
---|
377 | * device driver will be requested to remove the device and once gone from bus, |
---|
378 | * device and driver list the device is put into a inactive list for debugging |
---|
379 | * (this is optional by using remove argument). |
---|
380 | * |
---|
381 | * Removing the Root Bus Device is not supported. |
---|
382 | * |
---|
383 | * \param remove If non-zero the device will be deallocated, and not put into |
---|
384 | * the inacitve list. |
---|
385 | */ |
---|
386 | extern int drvmgr_dev_unregister(struct drvmgr_dev *dev); |
---|
387 | |
---|
388 | /*! Register a bus */ |
---|
389 | extern int drvmgr_bus_register(struct drvmgr_bus *bus); |
---|
390 | |
---|
391 | /*! Unregister a bus */ |
---|
392 | extern int drvmgr_bus_unregister(struct drvmgr_bus *bus); |
---|
393 | |
---|
394 | /*! Unregister all child devices of a bus. |
---|
395 | * |
---|
396 | * This function is called from the bus driver, from a "safe" state where |
---|
397 | * devices will not be added or removed on this particular bus at this time |
---|
398 | */ |
---|
399 | extern int drvmgr_children_unregister(struct drvmgr_bus *bus); |
---|
400 | |
---|
401 | /* Separate a device from the driver it has been united with */ |
---|
402 | extern int drvmgr_dev_drv_separate(struct drvmgr_dev *dev); |
---|
403 | |
---|
404 | /*! Allocate a device structure, if no memory available |
---|
405 | * rtems_error_fatal_occurred is called. |
---|
406 | * The 'extra' argment tells how many bytes extra space is to be allocated after |
---|
407 | * the device structure, this is typically used for "businfo" structures. The extra |
---|
408 | * space is always aligned to a 4-byte boundary. |
---|
409 | */ |
---|
410 | extern int drvmgr_alloc_dev(struct drvmgr_dev **pdev, int extra); |
---|
411 | |
---|
412 | /*! Allocate a bus structure, if no memory available rtems_error_fatal_occurred |
---|
413 | * is called. |
---|
414 | * The 'extra' argment tells how many bytes extra space is to be allocated after |
---|
415 | * the device structure, this is typically used for "businfo" structures. The |
---|
416 | * extra space is always aligned to a 4-byte boundary. |
---|
417 | */ |
---|
418 | extern int drvmgr_alloc_bus(struct drvmgr_bus **pbus, int extra); |
---|
419 | |
---|
420 | /*** DRIVER RESOURCE FUNCTIONS ***/ |
---|
421 | |
---|
422 | /*! Add resources to a bus, typically used by a bus driver. |
---|
423 | * |
---|
424 | * \param bus The Bus to add the resources to. |
---|
425 | * \param res An array with Driver resources, all together are called bus |
---|
426 | * resources. |
---|
427 | */ |
---|
428 | extern void drvmgr_bus_res_add(struct drvmgr_bus *bus, |
---|
429 | struct drvmgr_bus_res *bres); |
---|
430 | |
---|
431 | /*! Find all the resource keys for a device among all driver resources on a |
---|
432 | * bus. Typically used by a device driver to get configuration options. |
---|
433 | * |
---|
434 | * \param dev Device to find resources for |
---|
435 | * \param key Location where the pointer to the driver resource array (drvmgr_drv_res->keys) is stored. |
---|
436 | */ |
---|
437 | extern int drvmgr_keys_get(struct drvmgr_dev *dev, struct drvmgr_key **keys); |
---|
438 | |
---|
439 | /*! Return the one key that matches key name from a driver keys array. The keys |
---|
440 | * can be obtained using drvmgr_keys_get(). |
---|
441 | * |
---|
442 | * \param keys An array of keys ended with DRVMGR_KEY_EMPTY to search among. |
---|
443 | * \param key_name Name of key to search for among the keys. |
---|
444 | */ |
---|
445 | extern struct drvmgr_key *drvmgr_key_get(struct drvmgr_key *keys, char *key_name); |
---|
446 | |
---|
447 | /*! Extract key value from the key in the keys array matching name and type. |
---|
448 | * |
---|
449 | * This function calls drvmgr_keys_get to get the key requested (from key |
---|
450 | * name), then determines if the type is correct. A pointer to the key value |
---|
451 | * is returned. |
---|
452 | * |
---|
453 | * \param keys An array of keys ended with DRVMGR_KEY_EMPTY to search among. |
---|
454 | * \param key_name Name of key to search for among the keys. |
---|
455 | * \param key_type Data Type of value. INTEGER, ADDRESS, STRING. |
---|
456 | * \return Returns NULL if no value found matching Key Name and Key |
---|
457 | * Type. |
---|
458 | */ |
---|
459 | extern union drvmgr_key_value *drvmgr_key_val_get( |
---|
460 | struct drvmgr_key *keys, |
---|
461 | char *key_name, |
---|
462 | enum drvmgr_kt key_type); |
---|
463 | |
---|
464 | /*! Get key value from the bus resources matching [device, key name, key type] |
---|
465 | * if no matching key is found NULL is returned. |
---|
466 | * |
---|
467 | * This is typically used by device drivers to find a particular device |
---|
468 | * resource. |
---|
469 | * |
---|
470 | * \param dev The device to search resource for. |
---|
471 | * \param key_name The key name to search for |
---|
472 | * \param key_type The key type expected. |
---|
473 | * \return Returns NULL if no value found matching Key Name and |
---|
474 | * Key Type was found for device. |
---|
475 | */ |
---|
476 | extern union drvmgr_key_value *drvmgr_dev_key_get( |
---|
477 | struct drvmgr_dev *dev, |
---|
478 | char *key_name, |
---|
479 | enum drvmgr_kt key_type); |
---|
480 | |
---|
481 | /*** DRIVER INTERACE USED TO REQUEST INFORMATION/SERVICES FROM BUS DRIVER ***/ |
---|
482 | |
---|
483 | /*! Get parent bus */ |
---|
484 | RTEMS_INLINE_ROUTINE struct drvmgr_bus *drvmgr_get_parent( |
---|
485 | struct drvmgr_dev *dev) |
---|
486 | { |
---|
487 | if (dev) |
---|
488 | return dev->parent; |
---|
489 | else |
---|
490 | return NULL; |
---|
491 | } |
---|
492 | |
---|
493 | /*! Get Driver of device */ |
---|
494 | RTEMS_INLINE_ROUTINE struct drvmgr_drv *drvmgr_get_drv(struct drvmgr_dev *dev) |
---|
495 | { |
---|
496 | if (dev) |
---|
497 | return dev->drv; |
---|
498 | else |
---|
499 | return NULL; |
---|
500 | } |
---|
501 | |
---|
502 | /*! Calls func() for every device found in the device tree, regardless of |
---|
503 | * device state or if a driver is assigned. With the options argument the user |
---|
504 | * can decide to do either a depth-first or a breadth-first search. |
---|
505 | * |
---|
506 | * If the function func() returns a non-zero value then for_each_dev will |
---|
507 | * return imediatly with the same return value as func() returned. |
---|
508 | * |
---|
509 | * \param func Function called on each device |
---|
510 | * \param arg Custom function argument |
---|
511 | * \param options Search Options, see DRVMGR_FED_* |
---|
512 | * |
---|
513 | */ |
---|
514 | #define DRVMGR_FED_BF 1 /* Breadth-first search */ |
---|
515 | #define DRVMGR_FED_DF 0 /* Depth first search */ |
---|
516 | extern int drvmgr_for_each_dev( |
---|
517 | int (*func)(struct drvmgr_dev *dev, void *arg), |
---|
518 | void *arg, |
---|
519 | int options); |
---|
520 | |
---|
521 | /*! Get Device pointer from Driver and Driver minor number |
---|
522 | * |
---|
523 | * \param drv Driver the device is united with. |
---|
524 | * \param minor Driver minor number assigned to device. |
---|
525 | * \param pdev Location where the Device point will be stored. |
---|
526 | * \return Zero on success. -1 on failure, when device was not |
---|
527 | * found in driver device list. |
---|
528 | */ |
---|
529 | extern int drvmgr_get_dev( |
---|
530 | struct drvmgr_drv *drv, |
---|
531 | int minor, |
---|
532 | struct drvmgr_dev **pdev); |
---|
533 | |
---|
534 | /*! Get Bus frequency in Hertz. Frequency is stored into address of freq_hz. |
---|
535 | * |
---|
536 | * \param dev The Device to get Bus frequency for. |
---|
537 | * \param options Bus-type specific options |
---|
538 | * \param freq_hz Location where Bus Frequency will be stored. |
---|
539 | */ |
---|
540 | extern int drvmgr_freq_get( |
---|
541 | struct drvmgr_dev *dev, |
---|
542 | int options, |
---|
543 | unsigned int *freq_hz); |
---|
544 | |
---|
545 | /*! Return 0 if dev is not located on the root bus, 1 if on root bus */ |
---|
546 | extern int drvmgr_on_rootbus(struct drvmgr_dev *dev); |
---|
547 | |
---|
548 | /*! Get device name prefix, this name can be used to register a unique name in |
---|
549 | * the bus->error filesystem or to get an idea where the device is located. |
---|
550 | * |
---|
551 | * \param dev The Device to get the device Prefix for. |
---|
552 | * \param dev_prefix Location where the prefix will be stored. |
---|
553 | */ |
---|
554 | extern int drvmgr_get_dev_prefix(struct drvmgr_dev *dev, char *dev_prefix); |
---|
555 | |
---|
556 | /*! Register a shared interrupt handler. Since this service is shared among |
---|
557 | * interrupt drivers/handlers the handler[arg] must be installed before the |
---|
558 | * interrupt can be cleared or disabled. The handler is by default disabled |
---|
559 | * after registration. |
---|
560 | * |
---|
561 | * \param index Index is used to identify the IRQ number if hardware has |
---|
562 | * multiple IRQ sources. Normally Index is set to 0 to |
---|
563 | * indicated the first and only IRQ source. |
---|
564 | * A negative index is interpreted as a absolute bus IRQ |
---|
565 | * number. |
---|
566 | * \param isr Interrupt Service Routine. |
---|
567 | * \param arg Optional ISR argument. |
---|
568 | */ |
---|
569 | extern int drvmgr_interrupt_register( |
---|
570 | struct drvmgr_dev *dev, |
---|
571 | int index, |
---|
572 | const char *info, |
---|
573 | drvmgr_isr isr, |
---|
574 | void *arg); |
---|
575 | |
---|
576 | /*! Unregister an interrupt handler. This also disables the interrupt before |
---|
577 | * unregistering the interrupt handler. |
---|
578 | * \param index Index is used to identify the IRQ number if hardware has |
---|
579 | * multiple IRQ sources. Normally Index is set to 0 to |
---|
580 | * indicated the first and only IRQ source. |
---|
581 | * A negative index is interpreted as a absolute bus IRQ |
---|
582 | * number. |
---|
583 | * \param isr Interrupt Service Routine, previously registered. |
---|
584 | * \param arg Optional ISR argument, previously registered. |
---|
585 | */ |
---|
586 | extern int drvmgr_interrupt_unregister( |
---|
587 | struct drvmgr_dev *dev, |
---|
588 | int index, |
---|
589 | drvmgr_isr isr, |
---|
590 | void *arg); |
---|
591 | |
---|
592 | /*! Clear (ACK) pending interrupt |
---|
593 | * |
---|
594 | * \param dev Device to clear interrupt for. |
---|
595 | * \param index Index is used to identify the IRQ number if hardware has multiple IRQ sources. |
---|
596 | * Normally Index is set to 0 to indicated the first and only IRQ source. |
---|
597 | * A negative index is interpreted as a absolute bus IRQ number. |
---|
598 | * \param isr Interrupt Service Routine, previously registered. |
---|
599 | * \param arg Optional ISR argument, previously registered. |
---|
600 | */ |
---|
601 | extern int drvmgr_interrupt_clear( |
---|
602 | struct drvmgr_dev *dev, |
---|
603 | int index); |
---|
604 | |
---|
605 | /*! Force unmasking/enableing an interrupt on the interrupt controller, this is not normally used, |
---|
606 | * if used the caller has masked/disabled the interrupt just before. |
---|
607 | * |
---|
608 | * \param dev Device to clear interrupt for. |
---|
609 | * \param index Index is used to identify the IRQ number if hardware has multiple IRQ sources. |
---|
610 | * Normally Index is set to 0 to indicated the first and only IRQ source. |
---|
611 | * A negative index is interpreted as a absolute bus IRQ number. |
---|
612 | * \param isr Interrupt Service Routine, previously registered. |
---|
613 | * \param arg Optional ISR argument, previously registered. |
---|
614 | */ |
---|
615 | extern int drvmgr_interrupt_unmask( |
---|
616 | struct drvmgr_dev *dev, |
---|
617 | int index); |
---|
618 | |
---|
619 | /*! Force masking/disable an interrupt on the interrupt controller, this is not normally performed |
---|
620 | * since this will stop all other (shared) ISRs to be disabled until _unmask() is called. |
---|
621 | * |
---|
622 | * \param dev Device to mask interrupt for. |
---|
623 | * \param index Index is used to identify the IRQ number if hardware has multiple IRQ sources. |
---|
624 | * Normally Index is set to 0 to indicated the first and only IRQ source. |
---|
625 | * A negative index is interpreted as a absolute bus IRQ number. |
---|
626 | */ |
---|
627 | extern int drvmgr_interrupt_mask( |
---|
628 | struct drvmgr_dev *dev, |
---|
629 | int index); |
---|
630 | |
---|
631 | /*! drvmgr_translate() translation options */ |
---|
632 | enum drvmgr_tr_opts { |
---|
633 | /* Translate CPU RAM Address (input) to DMA unit accessible address |
---|
634 | * (output), this is an upstreams translation in reverse order. |
---|
635 | * |
---|
636 | * Typical Usage: |
---|
637 | * It is common to translate a CPU accessible RAM address to an |
---|
638 | * address that DMA units can access over bridges. |
---|
639 | */ |
---|
640 | CPUMEM_TO_DMA = 0x0, |
---|
641 | |
---|
642 | /* Translate DMA Unit Accessible address mapped to CPU RAM (input) to |
---|
643 | * CPU accessible address (output). This is an upstreams translation. |
---|
644 | * |
---|
645 | * Typical Usage (not often used): |
---|
646 | * The DMA unit descriptors contain pointers to DMA buffers located at |
---|
647 | * CPU RAM addresses that the DMA unit can access, the CPU processes |
---|
648 | * the descriptors and want to access the data but a translation back |
---|
649 | * to CPU address is required. |
---|
650 | */ |
---|
651 | CPUMEM_FROM_DMA = 0x1, |
---|
652 | |
---|
653 | /* Translate DMA Memory Address (input) to CPU accessible address |
---|
654 | * (output), this is a downstreams translation in reverse order. |
---|
655 | * |
---|
656 | * Typical Usage: |
---|
657 | * A PCI network card puts packets into its memory not doing DMA over |
---|
658 | * PCI, in order for the CPU to access them the PCI address must be |
---|
659 | * translated. |
---|
660 | */ |
---|
661 | DMAMEM_TO_CPU = 0x2, |
---|
662 | |
---|
663 | /* Translate CPU accessible address (input) mapped to DMA Memory Address |
---|
664 | * to DMA Unit accessible address (output). This is a downstreams |
---|
665 | * translation. |
---|
666 | */ |
---|
667 | DMAMEM_FROM_CPU = 0x3, |
---|
668 | }; |
---|
669 | #define DRVMGR_TR_REVERSE 0x1 /* do reverse translation direction order */ |
---|
670 | #define DRVMGR_TR_PATH 0x2 /* 0x0=down-stream 0x2=up-stream address path */ |
---|
671 | |
---|
672 | /*! Translate an address on one bus to an address on another bus. |
---|
673 | * |
---|
674 | * The device determines source or destination bus, the root bus is always |
---|
675 | * the other bus. It is assumed that the CPU is located on the root bus or |
---|
676 | * that it can access it without address translation (mapped 1:1). The CPU |
---|
677 | * is thus assumed to be located on level 0 top most in the bus hierarchy. |
---|
678 | * |
---|
679 | * If no map is present in the bus driver src_address is translated 1:1 |
---|
680 | * (just copied). |
---|
681 | * |
---|
682 | * Addresses are typically converted up-streams from the DMA unit towards the |
---|
683 | * CPU (DMAMEM_TO_CPU) or down-streams towards DMA hardware from the CPU |
---|
684 | * (CPUMEM_TO_DMA) over one or multiple bridges depending on bus architecture. |
---|
685 | * See 'enum drvmgr_tr_opts' for other translation direction options. |
---|
686 | * For example: |
---|
687 | * Two common operations is to translate a CPU accessible RAM address to an |
---|
688 | * address that DMA units can access (dev=DMA-unit, CPUMEM_TO_DMA, |
---|
689 | * src_address=CPU-RAM-ADR) and to translate an address of a PCI resource for |
---|
690 | * example RAM mapped into a PCI BAR to an CPU accessible address |
---|
691 | * (dev=PCI-device, DMAMEM_TO_CPU, src_address=PCI-BAR-ADR). |
---|
692 | * |
---|
693 | * Source address is translated and the result is put into *dst_address, if |
---|
694 | * the address is not accessible on the other bus -1 is returned. |
---|
695 | * |
---|
696 | * \param dev Device to translate addresses for |
---|
697 | * \param options Tanslation direction options, see enum drvmgr_tr_opts |
---|
698 | * \param src_address Address to translate |
---|
699 | * \param dst_address Location where translated address is stored |
---|
700 | * |
---|
701 | * Returns 0 if unable to translate. The remaining length from the given |
---|
702 | * address of the map is returned on success, for example if a map starts |
---|
703 | * at 0x40000000 of size 0x100000 the result will be 0x40000 if the address |
---|
704 | * was translated into 0x400C0000. |
---|
705 | * If dev is on root-bus no translation is performed 0xffffffff is returned |
---|
706 | * and src_address is stored in *dst_address. |
---|
707 | */ |
---|
708 | extern unsigned int drvmgr_translate( |
---|
709 | struct drvmgr_dev *dev, |
---|
710 | unsigned int options, |
---|
711 | void *src_address, |
---|
712 | void **dst_address); |
---|
713 | |
---|
714 | /* Translate addresses between buses, used internally to implement |
---|
715 | * drvmgr_translate. Function is not limited to translate from/to root bus |
---|
716 | * where CPU is resident, however buses must be on a straight path relative |
---|
717 | * to each other (parent of parent of parent and so on). |
---|
718 | * |
---|
719 | * \param from src_address is given for this bus |
---|
720 | * \param to src_address is translated to this bus |
---|
721 | * \param reverse Selects translation method, if map entries are used in |
---|
722 | * the reverse order (map_up->to is used as map_up->from) |
---|
723 | * \param src_address Address to be translated |
---|
724 | * \param dst_address Translated address is stored here on success (return=0) |
---|
725 | * |
---|
726 | * Returns 0 if unable to translate. The remaining length from the given |
---|
727 | * address of the map is returned on success and the result is stored into |
---|
728 | * *dst_address. For example if a map starts at 0x40000000 of size 0x100000 |
---|
729 | * the result will be 0x40000 if the address was translated into 0x400C0000. |
---|
730 | * If dev is on root-bus no translation is performed 0xffffffff is returned. |
---|
731 | * and src_address is stored in *dst_address. |
---|
732 | */ |
---|
733 | extern unsigned int drvmgr_translate_bus( |
---|
734 | struct drvmgr_bus *from, |
---|
735 | struct drvmgr_bus *to, |
---|
736 | int reverse, |
---|
737 | void *src_address, |
---|
738 | void **dst_address); |
---|
739 | |
---|
740 | /* Calls drvmgr_translate() to translate an address range and checks the result, |
---|
741 | * a printout is generated if the check fails. All parameters are passed on to |
---|
742 | * drvmgr_translate() except for size, see paramters of drvmgr_translate(). |
---|
743 | * |
---|
744 | * If size=0 only the starting address is not checked. |
---|
745 | * |
---|
746 | * If mapping failes a non-zero result is returned. |
---|
747 | */ |
---|
748 | extern int drvmgr_translate_check( |
---|
749 | struct drvmgr_dev *dev, |
---|
750 | unsigned int options, |
---|
751 | void *src_address, |
---|
752 | void **dst_address, |
---|
753 | unsigned int size); |
---|
754 | |
---|
755 | /*! Get function pointer from Device Driver or Bus Driver. |
---|
756 | * |
---|
757 | * Returns 0 if function is available |
---|
758 | */ |
---|
759 | extern int drvmgr_func_get(void *obj, int funcid, void **func); |
---|
760 | |
---|
761 | /*! Lookup function and call it directly with the four optional arguments */ |
---|
762 | extern int drvmgr_func_call(void *obj, int funcid, void *a, void *b, void *c, void *d); |
---|
763 | |
---|
764 | /* Builds a Function ID. |
---|
765 | * |
---|
766 | * Used to request optional functions by a bus or device driver |
---|
767 | */ |
---|
768 | #define DRVMGR_FUNCID(major, minor) ((((major) & 0xfff) << 20) | ((minor) & 0xfffff)) |
---|
769 | #define DRVMGR_FUNCID_NONE 0 |
---|
770 | #define DRVMGR_FUNCID_END DRVMGR_FUNCID(DRVMGR_FUNCID_NONE, 0) |
---|
771 | |
---|
772 | /* Major Function ID. Most significant 12-bits. */ |
---|
773 | enum { |
---|
774 | FUNCID_NONE = 0x000, |
---|
775 | FUNCID_RW = 0x001, /* Read/Write functions */ |
---|
776 | }; |
---|
777 | |
---|
778 | /* Select Sub-Function Read/Write function by ID */ |
---|
779 | #define RW_SIZE_1 0x00001 /* Access Size */ |
---|
780 | #define RW_SIZE_2 0x00002 |
---|
781 | #define RW_SIZE_4 0x00004 |
---|
782 | #define RW_SIZE_8 0x00008 |
---|
783 | #define RW_SIZE_ANY 0x00000 |
---|
784 | #define RW_SIZE(id) ((unsigned int)(id) & 0xf) |
---|
785 | |
---|
786 | #define RW_DIR_ANY 0x00000 /* Access Direction */ |
---|
787 | #define RW_READ 0x00000 /* Read */ |
---|
788 | #define RW_WRITE 0x00010 /* Write */ |
---|
789 | #define RW_SET 0x00020 /* Write with same value (memset) */ |
---|
790 | #define RW_DIR(id) (((unsigned int)(id) >> 4) & 0x3) |
---|
791 | |
---|
792 | #define RW_RAW 0x00000 /* Raw access - no swapping (machine default) */ |
---|
793 | #define RW_LITTLE 0x00040 /* Little Endian */ |
---|
794 | #define RW_BIG 0x00080 /* Big Endian */ |
---|
795 | #define RW_ENDIAN(id) (((unsigned int)(id) >> 6) & 0x3) |
---|
796 | |
---|
797 | #define RW_TYPE_ANY 0x00000 /* Access type */ |
---|
798 | #define RW_REG 0x00100 |
---|
799 | #define RW_MEM 0x00200 |
---|
800 | #define RW_MEMREG 0x00300 |
---|
801 | #define RW_CFG 0x00400 |
---|
802 | #define RW_TYPE(id) (((unsigned int)(id) >> 8) & 0xf) |
---|
803 | |
---|
804 | #define RW_ARG 0x01000 /* Optional Argument */ |
---|
805 | #define RW_ERR 0x02000 /* Optional Error Handler */ |
---|
806 | |
---|
807 | /* Build a Read/Write function ID */ |
---|
808 | #define DRVMGR_RWFUNC(minor) DRVMGR_FUNCID(FUNCID_RW, minor) |
---|
809 | |
---|
810 | /* Argument to Read/Write functions, the "void *arg" pointer is returned by |
---|
811 | * RW_ARG. If NULL is returned no argument is needed. |
---|
812 | */ |
---|
813 | struct drvmgr_rw_arg { |
---|
814 | void *arg; |
---|
815 | struct drvmgr_dev *dev; |
---|
816 | }; |
---|
817 | |
---|
818 | /* Standard Read/Write function types */ |
---|
819 | typedef uint8_t (*drvmgr_r8)(uint8_t *srcadr); |
---|
820 | typedef uint16_t (*drvmgr_r16)(uint16_t *srcadr); |
---|
821 | typedef uint32_t (*drvmgr_r32)(uint32_t *srcadr); |
---|
822 | typedef uint64_t (*drvmgr_r64)(uint64_t *srcadr); |
---|
823 | typedef void (*drvmgr_w8)(uint8_t *dstadr, uint8_t data); |
---|
824 | typedef void (*drvmgr_w16)(uint16_t *dstadr, uint16_t data); |
---|
825 | typedef void (*drvmgr_w32)(uint32_t *dstadr, uint32_t data); |
---|
826 | typedef void (*drvmgr_w64)(uint64_t *dstadr, uint64_t data); |
---|
827 | /* READ/COPY a memory area located on bus into CPU memory. |
---|
828 | * From 'src' (remote) to the destination 'dest' (local), n=number of bytes |
---|
829 | */ |
---|
830 | typedef int (*drvmgr_rmem)(void *dest, const void *src, int n); |
---|
831 | /* WRITE/COPY a user buffer located in CPU memory to a location on the bus. |
---|
832 | * From 'src' (local) to the destination 'dest' (remote), n=number of bytes |
---|
833 | */ |
---|
834 | typedef int (*drvmgr_wmem)(void *dest, const void *src, int n); |
---|
835 | /* Set a memory area to the byte value given in c, see LIBC memset(). Memset is |
---|
836 | * implemented by calling wmem() multiple times with a "large" buffer. |
---|
837 | */ |
---|
838 | typedef int (*drvmgr_memset)(void *dstadr, int c, size_t n); |
---|
839 | |
---|
840 | /* Read/Write function types with additional argument */ |
---|
841 | typedef uint8_t (*drvmgr_r8_arg)(uint8_t *srcadr, void *a); |
---|
842 | typedef uint16_t (*drvmgr_r16_arg)(uint16_t *srcadr, void *a); |
---|
843 | typedef uint32_t (*drvmgr_r32_arg)(uint32_t *srcadr, void *a); |
---|
844 | typedef uint64_t (*drvmgr_r64_arg)(uint64_t *srcadr, void *a); |
---|
845 | typedef void (*drvmgr_w8_arg)(uint8_t *dstadr, uint8_t data, void *a); |
---|
846 | typedef void (*drvmgr_w16_arg)(uint16_t *dstadr, uint16_t data, void *a); |
---|
847 | typedef void (*drvmgr_w32_arg)(uint32_t *dstadr, uint32_t data, void *a); |
---|
848 | typedef void (*drvmgr_w64_arg)(uint64_t *dstadr, uint64_t data, void *a); |
---|
849 | typedef int (*drvmgr_rmem_arg)(void *dest, const void *src, int n, void *a); |
---|
850 | typedef int (*drvmgr_wmem_arg)(void *dest, const void *src, int n, void *a); |
---|
851 | typedef int (*drvmgr_memset_arg)(void *dstadr, int c, size_t n, void *a); |
---|
852 | |
---|
853 | /* Report an error to the parent bus of the device */ |
---|
854 | typedef void (*drvmgr_rw_err)(struct drvmgr_rw_arg *a, struct drvmgr_bus *bus, |
---|
855 | int funcid, void *adr); |
---|
856 | |
---|
857 | /* Helper function for buses that implement the memset() over wmem() */ |
---|
858 | extern void drvmgr_rw_memset( |
---|
859 | void *dstadr, |
---|
860 | int c, |
---|
861 | size_t n, |
---|
862 | void *a, |
---|
863 | drvmgr_wmem_arg wmem |
---|
864 | ); |
---|
865 | |
---|
866 | /*** PRINT INFORMATION ABOUT DRIVER MANAGER ***/ |
---|
867 | |
---|
868 | /*! Calls func() for every device found matching the search requirements of |
---|
869 | * set_mask and clr_mask. Each bit set in set_mask must be set in the |
---|
870 | * device state bit mask (dev->state), and Each bit in the clr_mask must |
---|
871 | * be cleared in the device state bit mask (dev->state). There are three |
---|
872 | * special cases: |
---|
873 | * |
---|
874 | * 1. If state_set_mask and state_clr_mask are zero the state bits are |
---|
875 | * ignored and all cores are treated as a match. |
---|
876 | * |
---|
877 | * 2. If state_set_mask is zero the function func will not be called due to |
---|
878 | * a bit being set in the state mask. |
---|
879 | * |
---|
880 | * 3. If state_clr_mask is zero the function func will not be called due to |
---|
881 | * a bit being cleared in the state mask. |
---|
882 | * |
---|
883 | * If the function func() returns a non-zero value then for_each_dev will |
---|
884 | * return imediatly with the same return value as func() returned. |
---|
885 | * |
---|
886 | * \param devlist The list to iterate though searching for devices. |
---|
887 | * \param state_set_mask Defines the bits that must be set in dev->state |
---|
888 | * \param state_clr_mask Defines the bits that must be cleared in dev->state |
---|
889 | * \param func Function called on each |
---|
890 | * |
---|
891 | */ |
---|
892 | extern int drvmgr_for_each_listdev( |
---|
893 | struct drvmgr_list *devlist, |
---|
894 | unsigned int state_set_mask, |
---|
895 | unsigned int state_clr_mask, |
---|
896 | int (*func)(struct drvmgr_dev *dev, void *arg), |
---|
897 | void *arg); |
---|
898 | |
---|
899 | /* Print all devices */ |
---|
900 | #define PRINT_DEVS_FAILED 0x01 /* Failed during initialization */ |
---|
901 | #define PRINT_DEVS_ASSIGNED 0x02 /* Driver assigned */ |
---|
902 | #define PRINT_DEVS_UNASSIGNED 0x04 /* Driver not assigned */ |
---|
903 | #define PRINT_DEVS_IGNORED 0x08 /* Device ignored on user's request */ |
---|
904 | #define PRINT_DEVS_ALL (PRINT_DEVS_FAILED | \ |
---|
905 | PRINT_DEVS_ASSIGNED | \ |
---|
906 | PRINT_DEVS_UNASSIGNED |\ |
---|
907 | PRINT_DEVS_IGNORED) |
---|
908 | |
---|
909 | /*! Print number of devices, buses and drivers */ |
---|
910 | extern void drvmgr_summary(void); |
---|
911 | |
---|
912 | /*! Print devices with certain condictions met according to 'options' */ |
---|
913 | extern void drvmgr_print_devs(unsigned int options); |
---|
914 | |
---|
915 | /*! Print device/bus topology */ |
---|
916 | extern void drvmgr_print_topo(void); |
---|
917 | |
---|
918 | /*! Print the memory usage |
---|
919 | * Only accounts for data structures. Not for the text size. |
---|
920 | */ |
---|
921 | extern void drvmgr_print_mem(void); |
---|
922 | |
---|
923 | #define OPTION_DEV_GENINFO 0x00000001 |
---|
924 | #define OPTION_DEV_BUSINFO 0x00000002 |
---|
925 | #define OPTION_DEV_DRVINFO 0x00000004 |
---|
926 | #define OPTION_DRV_DEVS 0x00000100 |
---|
927 | #define OPTION_BUS_DEVS 0x00010000 |
---|
928 | #define OPTION_RECURSIVE 0x01000000 |
---|
929 | #define OPTION_INFO_ALL 0xffffffff |
---|
930 | |
---|
931 | /*! Print information about a driver manager object (device, driver, bus) */ |
---|
932 | extern void drvmgr_info(void *id, unsigned int options); |
---|
933 | |
---|
934 | /*! Get information about a device */ |
---|
935 | extern void drvmgr_info_dev(struct drvmgr_dev *dev, unsigned int options); |
---|
936 | |
---|
937 | /*! Get information about a bus */ |
---|
938 | extern void drvmgr_info_bus(struct drvmgr_bus *bus, unsigned int options); |
---|
939 | |
---|
940 | /*! Get information about a driver */ |
---|
941 | extern void drvmgr_info_drv(struct drvmgr_drv *drv, unsigned int options); |
---|
942 | |
---|
943 | /*! Get information about all devices on a bus */ |
---|
944 | extern void drvmgr_info_devs_on_bus(struct drvmgr_bus *bus, unsigned int options); |
---|
945 | |
---|
946 | /*! Get information about all devices in the system (on all buses) */ |
---|
947 | extern void drvmgr_info_devs(unsigned int options); |
---|
948 | |
---|
949 | /*! Get information about all drivers in the system */ |
---|
950 | extern void drvmgr_info_drvs(unsigned int options); |
---|
951 | |
---|
952 | /*! Get information about all buses in the system */ |
---|
953 | extern void drvmgr_info_buses(unsigned int options); |
---|
954 | |
---|
955 | /*! Get Driver by Driver ID */ |
---|
956 | extern struct drvmgr_drv *drvmgr_drv_by_id(uint64_t id); |
---|
957 | |
---|
958 | /*! Get Driver by Driver Name */ |
---|
959 | extern struct drvmgr_drv *drvmgr_drv_by_name(const char *name); |
---|
960 | |
---|
961 | /*! Get Device by Device Name */ |
---|
962 | extern struct drvmgr_dev *drvmgr_dev_by_name(const char *name); |
---|
963 | |
---|
964 | #ifdef __cplusplus |
---|
965 | } |
---|
966 | #endif |
---|
967 | |
---|
968 | #endif |
---|