source: rtems/cpukit/include/drvmgr/drvmgr.h @ 3a6c3c1

Last change on this file since 3a6c3c1 was 3a6c3c1, checked in by Joel Sherrill <joel@…>, on 04/02/22 at 19:15:16

cpukit/include; Remove SPDX from Gaisler files NOT changed to BSD-2

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