Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:11

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @brief Driver Manager Interface.
0007  */
0008 
0009 /*
0010  * COPYRIGHT (c) 2009 Cobham Gaisler AB.
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 #ifndef _DRIVER_MANAGER_H_
0035 #define _DRIVER_MANAGER_H_
0036 
0037 #include <rtems.h>
0038 #include <drvmgr/drvmgr_list.h>
0039 #include <stdint.h>
0040 #include <rtems/score/basedefs.h>
0041 #include <rtems/score/smpimpl.h>
0042 
0043 #ifdef __cplusplus
0044 extern "C" {
0045 #endif
0046 
0047 /*** Configure Driver manager ***/
0048 
0049 /* Define the number of initialization levels of device drivers */
0050 #define DRVMGR_LEVEL_MAX 4
0051 
0052 /* Default to use semahpores for protection. Initialization works without
0053  * locks and after initialization too if devices are not removed.
0054  */
0055 #ifndef DRVMGR_USE_LOCKS
0056 #define DRVMGR_USE_LOCKS 1
0057 #endif
0058 
0059 struct drvmgr_dev;  /* Device */
0060 struct drvmgr_bus;  /* Bus */
0061 struct drvmgr_drv;  /* Driver */
0062 
0063 /*** List Interface shortcuts ***/
0064 #define BUS_LIST_HEAD(list) LIST_HEAD(list, struct drvmgr_bus)
0065 #define BUS_LIST_TAIL(list) LIST_TAIL(list, struct drvmgr_bus)
0066 #define DEV_LIST_HEAD(list) LIST_HEAD(list, struct drvmgr_dev)
0067 #define DEV_LIST_TAIL(list) LIST_TAIL(list, struct drvmgr_dev)
0068 #define DRV_LIST_HEAD(list) LIST_HEAD(list, struct drvmgr_drv)
0069 #define DRV_LIST_TAIL(list) LIST_TAIL(list, struct drvmgr_drv)
0070 
0071 /*** Bus indentification ***/
0072 #define DRVMGR_BUS_TYPE_NONE 0      /* Not a valid bus */
0073 #define DRVMGR_BUS_TYPE_ROOT 1      /* Hard coded bus */
0074 #define DRVMGR_BUS_TYPE_PCI 2       /* PCI bus */
0075 #define DRVMGR_BUS_TYPE_AMBAPP 3    /* AMBA Plug & Play bus */
0076 #define DRVMGR_BUS_TYPE_LEON2_AMBA 4    /* LEON2 hardcoded bus */
0077 #define DRVMGR_BUS_TYPE_AMBAPP_DIST 5   /* Distibuted AMBA Plug & Play bus accessed using a communication interface */
0078 #define DRVMGR_BUS_TYPE_SPW_RMAP 6  /* SpaceWire Network bus */
0079 #define DRVMGR_BUS_TYPE_AMBAPP_RMAP 7   /* SpaceWire RMAP accessed AMBA Plug & Play bus */
0080 
0081 enum {
0082     DRVMGR_OBJ_NONE = 0,
0083     DRVMGR_OBJ_DRV = 1,
0084     DRVMGR_OBJ_BUS = 2,
0085     DRVMGR_OBJ_DEV = 3,
0086 };
0087 
0088 /*** Driver indentification ***
0089  *
0090  * 64-bit identification integer definition
0091  *  * Bus ID 8-bit [7..0]
0092  *  * Reserved 8-bit field [63..56]
0093  *  * Device ID specific for bus type 48-bit [55..8]  (Different buses have
0094  *    different unique identifications for hardware/driver.)
0095  *
0096  * ID Rules
0097  *  * A root bus driver must always have device ID set to 0. There can only by
0098  *    one root bus driver for a certain bus type.
0099  *  * A Driver ID must identify a unique hardware core
0100  *
0101  */
0102 
0103 /* Bus ID Mask */
0104 #define DRIVER_ID_BUS_MASK 0x00000000000000FFULL
0105 
0106 /* Reserved Mask for future use */
0107 #define DRIVER_ID_RSV_MASK 0xFF00000000000000ULL
0108 
0109 /* Reserved Mask for future use */
0110 #define DRIVER_ID_DEV_MASK 0x00FFFFFFFFFFFF00ULL
0111 
0112 /* Set Bus ID Mask. */
0113 #define DRIVER_ID(busid, devid) ((unsigned long long) \
0114     ((((unsigned long long)(devid) << 8) & DRIVER_ID_DEV_MASK) | \
0115      ((unsigned long long)(busid) & DRIVER_ID_BUS_MASK)))
0116 
0117 /* Get IDs */
0118 #define DRIVER_BUSID_GET(id)    ((unsigned long long)(id) & DRIVER_ID_BUS_MASK)
0119 #define DRIVER_DEVID_GET(id)    (((unsigned long long)(id) & DRIVER_ID_DEV_MASK) >> 8)
0120 
0121 #define DRIVER_ROOTBUS_ID(bus_type) DRIVER_ID(bus_type, 0)
0122 
0123 /*** Root Bus drivers ***/
0124 
0125 /* Generic Hard coded Root bus: Driver ID */
0126 #define DRIVER_ROOT_ID      DRIVER_ROOTBUS_ID(DRVMGR_BUS_TYPE_ROOT)
0127 
0128 /* PCI Plug & Play bus: Driver ID */
0129 #define DRIVER_PCIBUS_ID    DRIVER_ROOTBUS_ID(DRVMGR_BUS_TYPE_PCI)
0130 
0131 /* AMBA Plug & Play bus: Driver ID */
0132 #define DRIVER_GRLIB_AMBAPP_ID  DRIVER_ROOTBUS_ID(DRVMGR_BUS_TYPE_AMBAPP)
0133 
0134 /* AMBA Hard coded bus: Driver ID */
0135 #define DRIVER_LEON2_AMBA_ID    DRIVER_ROOTBUS_ID(DRVMGR_BUS_TYPE_LEON2_AMBA)
0136 
0137 /* Distributed AMBA Plug & Play bus: Driver ID */
0138 #define DRIVER_AMBAPP_DIST_ID   DRIVER_ROOTBUS_ID(DRVMGR_BUS_TYPE_AMBAPP_DIST)
0139 
0140 /*! Bus parameters used by driver interface functions to aquire information
0141  * about bus. All Bus drivers should implement the operation 'get_params' so
0142  * that the driver interface routines can access bus dependent information in
0143  * an non-dependent way.
0144  */
0145 struct drvmgr_bus_params {
0146     char        *dev_prefix;        /*!< Optional name prefix */
0147 };
0148 
0149 /* Interrupt Service Routine (ISR) */
0150 typedef void (*drvmgr_isr)(void *arg);
0151 
0152 /*! Bus operations */
0153 struct drvmgr_bus_ops {
0154     /* Functions used internally within driver manager */
0155     int (*init[DRVMGR_LEVEL_MAX])(struct drvmgr_bus *);
0156     int (*remove)(struct drvmgr_bus *);
0157     int (*unite)(struct drvmgr_drv *, struct drvmgr_dev *); /*!< Unite Hardware Device with Driver */
0158 
0159     /* Functions called indirectly from drivers */
0160     int (*int_register)(struct drvmgr_dev *, int index, const char *info, drvmgr_isr isr, void *arg);
0161     int (*int_unregister)(struct drvmgr_dev *, int index, drvmgr_isr isr, void *arg);
0162     int (*int_clear)(struct drvmgr_dev *, int index);
0163     int (*int_mask)(struct drvmgr_dev *, int index);
0164     int (*int_unmask)(struct drvmgr_dev *, int index);
0165 #ifdef RTEMS_SMP
0166     int (*int_set_affinity)(struct drvmgr_dev *, int index,
0167                     const Processor_mask *cpus);
0168 #endif
0169 
0170     /* Get Parameters */
0171     int (*get_params)(struct drvmgr_dev *, struct drvmgr_bus_params *);
0172     /* Get Frequency of Bus */
0173     int (*get_freq)(struct drvmgr_dev*, int, unsigned int*);
0174     /*! Function called to request information about a device. The bus
0175      *  driver interpret the bus-specific information about the device.
0176      */
0177     void    (*get_info_dev)(struct drvmgr_dev *,
0178                 void (*print)(void *p, char *str), void *p);
0179 };
0180 #define BUS_OPS_NUM (sizeof(struct drvmgr_bus_ops)/sizeof(void (*)(void)))
0181 
0182 struct drvmgr_func {
0183     int funcid;
0184     void *func;
0185 };
0186 #define DRVMGR_FUNC(_ID_, _FUNC_) {(int)(_ID_), (void *)(_FUNC_)}
0187 #define DRVMGR_FUNC_END {0, NULL}
0188 
0189 /*** Resource definitions ***
0190  *
0191  * Overview of structures:
0192  *  All bus resources entries (_bus_res) are linked together per bus
0193  *  (bus_info->reslist). One bus resource entry has a pointer to an array of
0194  *  driver resources (_drv_res). One driver resouces is made out of an array
0195  *  of keys (drvmgr_key). All keys belongs to the same driver and harwdare
0196  *  device. Each key has a Name, Type ID and Data interpreted differently
0197  *  depending on the Type ID (union drvmgr_key_value).
0198  *
0199  */
0200 
0201 /* Key Data Types */
0202 enum drvmgr_kt {
0203     DRVMGR_KT_ANY = -1,
0204     DRVMGR_KT_NONE = 0,
0205     DRVMGR_KT_INT = 1,
0206     DRVMGR_KT_STRING = 2,
0207     DRVMGR_KT_POINTER = 3,
0208 };
0209 
0210 #define DRVMGR_KEY_EMPTY    {NULL, DRVMGR_KT_NONE, {0}}
0211 #define DRVMGR_RES_EMPTY    {0, 0, NULL}
0212 #define MMAP_EMPTY  {0, 0, 0}
0213 
0214 /*! Union of different values */
0215 union drvmgr_key_value {
0216     unsigned int        i;  /*!< Key data type UNSIGNED INTEGER */
0217     char            *str;   /*!< Key data type STRING */
0218     void            *ptr;   /*!< Key data type ADDRESS/POINTER */
0219 };
0220 
0221 /* One key. One Value. Holding information relevant to the driver. */
0222 struct drvmgr_key {
0223     char            *key_name;  /* Name of key */
0224     enum drvmgr_kt      key_type;   /* How to interpret key_value */
0225     union drvmgr_key_value  key_value;  /* The value or pointer to value */
0226 };
0227 
0228 /*! Driver resource entry, Driver resources for a certain device instance,
0229  *  containing a number of keys where each key hold the data of interest.
0230  */
0231 struct drvmgr_drv_res {
0232     uint64_t        drv_id;     /*!< Identifies the driver this resource is aiming */
0233     int         minor_bus;  /*!< Indentifies a specfic device */
0234     struct drvmgr_key   *keys;      /*!< First key in key array, ended with KEY_EMPTY */
0235 };
0236 
0237 /*! Bus resource list node */
0238 struct drvmgr_bus_res {
0239     struct drvmgr_bus_res   *next;      /*!< Next resource node in list */
0240     struct drvmgr_drv_res   resource[]; /*!< Array of resources, one per device instance */
0241 };
0242 
0243 /*! MAP entry. Describes an linear address space translation. Untranslated
0244  *  Start, Translated Start and length.
0245  *
0246  * Used by bus drivers to describe the address translation needed for
0247  * the translation driver interface.
0248  */
0249 struct drvmgr_map_entry {
0250     char        *name;      /*!< Map Name */
0251     unsigned int    size;       /*!< Size of map window */
0252     char        *from_adr;  /*!< Start address of access window used
0253                      *   to reach into remote bus */
0254     char        *to_adr;    /*!< Start address of remote system
0255                      *   address range */
0256 };
0257 #define DRVMGR_TRANSLATE_ONE2ONE    NULL
0258 #define DRVMGR_TRANSLATE_NO_BRIDGE  ((void *)1)  /* No bridge, error */
0259 
0260 /*! Bus information. Describes a bus. */
0261 struct drvmgr_bus {
0262     int         obj_type;   /*!< DRVMGR_OBJ_BUS */
0263     unsigned char       bus_type;   /*!< Type of bus */
0264     unsigned char       depth;      /*!< Bus level distance from root bus */
0265     struct drvmgr_bus   *next;      /*!< Next Bus */
0266     struct drvmgr_dev   *dev;       /*!< Bus device, the hardware... */
0267     void            *priv;      /*!< Private data structure used by BUS driver */
0268     struct drvmgr_dev   *children;  /*!< Hardware devices on this bus */
0269     struct drvmgr_bus_ops   *ops;       /*!< Bus operations supported by this bus driver */
0270     struct drvmgr_func  *funcs;     /*!< Extra operations */
0271     int         dev_cnt;    /*!< Number of devices this bus has */
0272     struct drvmgr_bus_res   *reslist;   /*!< Bus resources, head of a linked list of resources. */
0273     struct drvmgr_map_entry *maps_up;   /*!< Map Translation, array of address spaces upstreams to CPU */
0274     struct drvmgr_map_entry *maps_down; /*!< Map Translation, array of address spaces downstreams to Hardware */
0275 
0276     /* Bus status */
0277     int         level;      /*!< Initialization Level of Bus */
0278     int         state;      /*!< Init State of Bus, BUS_STATE_* */
0279     int         error;      /*!< Return code from bus->ops->initN() */
0280 };
0281 
0282 /* States of a bus */
0283 #define BUS_STATE_INIT_FAILED   0x00000001  /* Initialization Failed */
0284 #define BUS_STATE_LIST_INACTIVE 0x00001000  /* In inactive bus list */
0285 #define BUS_STATE_DEPEND_FAILED 0x00000004  /* Device init failed */
0286 
0287 /* States of a device */
0288 #define DEV_STATE_INIT_FAILED   0x00000001  /* Initialization Failed */
0289 #define DEV_STATE_INIT_DONE 0x00000002  /* All init levels completed */
0290 #define DEV_STATE_DEPEND_FAILED 0x00000004  /* Parent Bus init failed */
0291 #define DEV_STATE_UNITED    0x00000100  /* Device United with Device Driver */
0292 #define DEV_STATE_REMOVED   0x00000200  /* Device has been removed (unregistered) */
0293 #define DEV_STATE_IGNORED   0x00000400  /* Device was ignored according to user's request, the device
0294                          * was never reported to it's driver (as expected).
0295                          */
0296 #define DEV_STATE_LIST_INACTIVE 0x00001000  /* In inactive device list */
0297 
0298 /*! Device information */
0299 struct drvmgr_dev {
0300     int         obj_type;   /*!< DRVMGR_OBJ_DEV */
0301     struct drvmgr_dev   *next;      /*!< Next device */
0302     struct drvmgr_dev   *next_in_bus;   /*!< Next device on the same bus */
0303     struct drvmgr_dev   *next_in_drv;   /*!< Next device using the same driver */
0304 
0305     struct drvmgr_drv   *drv;       /*!< The driver owning this device */
0306     struct drvmgr_bus   *parent;    /*!< Bus that this device resides on */
0307     short           minor_drv;  /*!< Device number within driver */
0308     short           minor_bus;  /*!< Device number on bus (for device separation) */
0309     char            *name;      /*!< Name of Device Hardware */
0310     void            *priv;      /*!< Pointer to driver private device structure */
0311     void            *businfo;   /*!< Host bus specific information */
0312     struct drvmgr_bus   *bus;       /*!< Pointer to bus, set only if this is a bridge */
0313 
0314     /* Device Status */
0315     unsigned int        state;      /*!< State of device, see DEV_STATE_* */
0316     int         level;      /*!< Init Level */
0317     int         error;      /*!< Error state returned by driver */
0318 };
0319 
0320 /*! Driver operations, function pointers. */
0321 struct drvmgr_drv_ops {
0322     int (*init[DRVMGR_LEVEL_MAX])(struct drvmgr_dev *); /*! Function doing Init Stage 1 of a hardware device */
0323     int (*remove)(struct drvmgr_dev *); /*! Function called when device instance is to be removed */
0324     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 */
0325 };
0326 #define DRVMGR_OPS_NUM(x) (sizeof(x)/sizeof(void (*)(void)))
0327 
0328 /*! Device driver description */
0329 struct drvmgr_drv {
0330     int         obj_type;   /*!< DRVMGR_OBJ_DRV */
0331     struct drvmgr_drv   *next;      /*!< Next Driver */
0332     struct drvmgr_dev   *dev;       /*!< Devices using this driver */
0333 
0334     uint64_t        drv_id;     /*!< Unique Driver ID */
0335     char            *name;      /*!< Name of Driver */
0336     int         bus_type;   /*!< Type of Bus this driver supports */
0337     struct drvmgr_drv_ops   *ops;       /*!< Driver operations */
0338     struct drvmgr_func  *funcs;     /*!< Extra Operations */
0339     unsigned int        dev_cnt;    /*!< Number of devices in dev */
0340     unsigned int        dev_priv_size;  /*!< If non-zero DRVMGR will allocate memory for dev->priv */
0341 };
0342 
0343 /*! Structure defines a function pointer called when driver manager is ready
0344  *  for drivers to register themselfs. Used to select drivers available to the
0345  *  driver manager.
0346  */
0347 typedef void (*drvmgr_drv_reg_func)(void);
0348 
0349 /*** DRIVER | DEVICE | BUS FUNCTIONS ***/
0350 
0351 /* Return Codes */
0352 enum {
0353     DRVMGR_OK = 0,      /* Sucess */
0354     DRVMGR_NOMEM = 1,   /* Memory allocation error */
0355     DRVMGR_EIO = 2,     /* I/O error */
0356     DRVMGR_EINVAL = 3,  /* Invalid parameter */
0357     DRVMGR_ENOSYS = 4,
0358     DRVMGR_TIMEDOUT = 5,    /* Operation timeout error */
0359     DRVMGR_EBUSY = 6,
0360     DRVMGR_ENORES = 7,  /* Not enough resources */
0361     DRVMGR_FAIL = -1    /* Unspecified failure */
0362 };
0363 
0364 /*! Initialize data structures of the driver management system.
0365  *  Calls predefined register driver functions so that drivers can
0366  *  register themselves.
0367  */
0368 extern void _DRV_Manager_initialization(void);
0369 
0370 /*! Take all devices into init level 'level', all devices registered later
0371  *  will directly be taken into this level as well, ensuring that all
0372  *  registerd devices has been taken into the level.
0373  *
0374  */
0375 extern void _DRV_Manager_init_level(int level);
0376 
0377 /*! Init driver manager all in one go, will call _DRV_Manager_initialization(),
0378  *  then _DRV_Manager_init_level([1..DRVMGR_LEVEL_MAX]).
0379  *  Typically called from Init task when user wants to initilize driver
0380  *  manager after startup, otherwise not used.
0381  */
0382 extern int drvmgr_init(void);
0383 
0384 /* Take registered buses and devices into the correct init level,
0385  * this function is called from _init_level() so normally
0386  * we don't need to call it directly.
0387  */
0388 extern void drvmgr_init_update(void);
0389 
0390 /*! Register Root Bus device driver */
0391 extern int drvmgr_root_drv_register(struct drvmgr_drv *drv);
0392 
0393 /*! Register a driver */
0394 extern int drvmgr_drv_register(struct drvmgr_drv *drv);
0395 
0396 /*! Register a device */
0397 extern int drvmgr_dev_register(struct drvmgr_dev *dev);
0398 
0399 /*! Remove a device, and all its children devices if device is a bus device. The
0400  *  device driver will be requested to remove the device and once gone from bus,
0401  *  device and driver list the device is put into a inactive list for debugging
0402  *  (this is optional by using remove argument).
0403  *
0404  * Removing the Root Bus Device is not supported.
0405  *
0406  * \param remove If non-zero the device will be deallocated, and not put into
0407  *               the inacitve list.
0408  */
0409 extern int drvmgr_dev_unregister(struct drvmgr_dev *dev);
0410 
0411 /*! Register a bus */
0412 extern int drvmgr_bus_register(struct drvmgr_bus *bus);
0413 
0414 /*! Unregister a bus */
0415 extern int drvmgr_bus_unregister(struct drvmgr_bus *bus);
0416 
0417 /*! Unregister all child devices of a bus.
0418  *
0419  * This function is called from the bus driver, from a "safe" state where
0420  * devices will not be added or removed on this particular bus at this time
0421  */
0422 extern int drvmgr_children_unregister(struct drvmgr_bus *bus);
0423 
0424 /* Separate a device from the driver it has been united with */
0425 extern int drvmgr_dev_drv_separate(struct drvmgr_dev *dev);
0426 
0427 /*! Allocate a device structure, if no memory available
0428  *  rtems_error_fatal_occurred is called.
0429  * The 'extra' argment tells how many bytes extra space is to be allocated after
0430  * the device structure, this is typically used for "businfo" structures. The extra
0431  * space is always aligned to a 4-byte boundary.
0432  */
0433 extern int drvmgr_alloc_dev(struct drvmgr_dev **pdev, int extra);
0434 
0435 /*! Allocate a bus structure, if no memory available rtems_error_fatal_occurred
0436  * is called.
0437  * The 'extra' argment tells how many bytes extra space is to be allocated after
0438  * the device structure, this is typically used for "businfo" structures. The
0439  * extra space is always aligned to a 4-byte boundary.
0440  */
0441 extern int drvmgr_alloc_bus(struct drvmgr_bus **pbus, int extra);
0442 
0443 /*** DRIVER RESOURCE FUNCTIONS ***/
0444 
0445 /*! Add resources to a bus, typically used by a bus driver.
0446  *
0447  * \param bus   The Bus to add the resources to.
0448  * \param res   An array with Driver resources, all together are called bus
0449  *              resources.
0450  */
0451 extern void drvmgr_bus_res_add(struct drvmgr_bus *bus,
0452                     struct drvmgr_bus_res *bres);
0453 
0454 /*! Find all the resource keys for a device among all driver resources on a
0455  *  bus. Typically used by a device driver to get configuration options.
0456  *
0457  * \param dev   Device to find resources for
0458  * \param key   Location where the pointer to the driver resource array (drvmgr_drv_res->keys) is stored.
0459  */
0460 extern int drvmgr_keys_get(struct drvmgr_dev *dev, struct drvmgr_key **keys);
0461 
0462 /*! Return the one key that matches key name from a driver keys array. The keys
0463  *  can be obtained using drvmgr_keys_get().
0464  *
0465  * \param keys       An array of keys ended with DRVMGR_KEY_EMPTY to search among.
0466  * \param key_name   Name of key to search for among the keys.
0467  */
0468 extern struct drvmgr_key *drvmgr_key_get(struct drvmgr_key *keys, char *key_name);
0469 
0470 /*! Extract key value from the key in the keys array matching name and type.
0471  *
0472  *  This function calls drvmgr_keys_get to get the key requested (from key
0473  *  name), then determines if the type is correct. A pointer to the key value
0474  *  is returned.
0475  *
0476  *  \param keys       An array of keys ended with DRVMGR_KEY_EMPTY to search among.
0477  *  \param key_name   Name of key to search for among the keys.
0478  *  \param key_type   Data Type of value. INTEGER, ADDRESS, STRING.
0479  *  \return           Returns NULL if no value found matching Key Name and Key
0480  *                    Type.
0481  */
0482 extern union drvmgr_key_value *drvmgr_key_val_get(
0483     struct drvmgr_key *keys,
0484     char *key_name,
0485     enum drvmgr_kt key_type);
0486 
0487 /*! Get key value from the bus resources matching [device, key name, key type]
0488  *  if no matching key is found NULL is returned.
0489  *
0490  * This is typically used by device drivers to find a particular device
0491  * resource.
0492  *
0493  * \param dev         The device to search resource for.
0494  * \param key_name    The key name to search for
0495  * \param key_type    The key type expected.
0496  * \return            Returns NULL if no value found matching Key Name and
0497  *                    Key Type was found for device.
0498  */
0499 extern union drvmgr_key_value *drvmgr_dev_key_get(
0500     struct drvmgr_dev *dev,
0501     char *key_name,
0502     enum drvmgr_kt key_type);
0503 
0504 /*** DRIVER INTERACE USED TO REQUEST INFORMATION/SERVICES FROM BUS DRIVER ***/
0505 
0506 /*! Get parent bus */
0507 static inline struct drvmgr_bus *drvmgr_get_parent(
0508     struct drvmgr_dev *dev)
0509 {
0510     if (dev)
0511         return dev->parent;
0512     else
0513         return NULL;
0514 }
0515 
0516 /*! Get Driver of device */
0517 static inline struct drvmgr_drv *drvmgr_get_drv(struct drvmgr_dev *dev)
0518 {
0519     if (dev)
0520         return dev->drv;
0521     else
0522         return NULL;
0523 }
0524 
0525 /*! Calls func() for every device found in the device tree, regardless of
0526  * device state or if a driver is assigned. With the options argument the user
0527  * can decide to do either a depth-first or a breadth-first search.
0528  *
0529  * If the function func() returns a non-zero value then for_each_dev will
0530  * return imediatly with the same return value as func() returned.
0531  *
0532  * \param func       Function called on each device
0533  * \param arg        Custom function argument
0534  * \param options    Search Options, see DRVMGR_FED_*
0535  *
0536  */
0537 #define DRVMGR_FED_BF 1     /* Breadth-first search */
0538 #define DRVMGR_FED_DF 0     /* Depth first search */
0539 extern intptr_t drvmgr_for_each_dev(
0540     intptr_t (*func)(struct drvmgr_dev *dev, void *arg),
0541     void *arg,
0542     int options);
0543 
0544 /*! Get Device pointer from Driver and Driver minor number
0545  *
0546  * \param drv         Driver the device is united with.
0547  * \param minor       Driver minor number assigned to device.
0548  * \param pdev        Location where the Device point will be stored.
0549  * \return            Zero on success. -1 on failure, when device was not
0550  *                    found in driver device list.
0551  */
0552 extern int drvmgr_get_dev(
0553     struct drvmgr_drv *drv,
0554     int minor,
0555     struct drvmgr_dev **pdev);
0556 
0557 /*! Get Bus frequency in Hertz. Frequency is stored into address of freq_hz.
0558  *
0559  * \param dev        The Device to get Bus frequency for.
0560  * \param options    Bus-type specific options
0561  * \param freq_hz    Location where Bus Frequency will be stored.
0562  */
0563 extern int drvmgr_freq_get(
0564     struct drvmgr_dev *dev,
0565     int options,
0566     unsigned int *freq_hz);
0567 
0568 /*! Return 0 if dev is not located on the root bus, 1 if on root bus */
0569 extern int drvmgr_on_rootbus(struct drvmgr_dev *dev);
0570 
0571 /*! Get device name prefix, this name can be used to register a unique name in
0572  *  the bus->error filesystem or to get an idea where the device is located.
0573  *
0574  * \param dev         The Device to get the device Prefix for.
0575  * \param dev_prefix  Location where the prefix will be stored.
0576  */
0577 extern int drvmgr_get_dev_prefix(struct drvmgr_dev *dev, char *dev_prefix);
0578 
0579 /*! Register a shared interrupt handler. Since this service is shared among
0580  *  interrupt drivers/handlers the handler[arg] must be installed before the
0581  *  interrupt can be cleared or disabled. The handler is by default disabled
0582  *  after registration.
0583  *
0584  *  \param index      Index is used to identify the IRQ number if hardware has
0585  *                    multiple IRQ sources. Normally Index is set to 0 to
0586  *                    indicated the first and only IRQ source.
0587  *                    A negative index is interpreted as a absolute bus IRQ
0588  *                    number.
0589  *  \param isr        Interrupt Service Routine.
0590  *  \param arg        Optional ISR argument.
0591  */
0592 extern int drvmgr_interrupt_register(
0593     struct drvmgr_dev *dev,
0594     int index,
0595     const char *info,
0596     drvmgr_isr isr,
0597     void *arg);
0598 
0599 /*! Unregister an interrupt handler. This also disables the interrupt before
0600  *  unregistering the interrupt handler.
0601  *  \param index      Index is used to identify the IRQ number if hardware has
0602  *                    multiple IRQ sources. Normally Index is set to 0 to
0603  *                    indicated the first and only IRQ source.
0604  *                    A negative index is interpreted as a absolute bus IRQ
0605  *                    number.
0606  *  \param isr        Interrupt Service Routine, previously registered.
0607  *  \param arg        Optional ISR argument, previously registered.
0608  */
0609 extern int drvmgr_interrupt_unregister(
0610     struct drvmgr_dev *dev,
0611     int index,
0612     drvmgr_isr isr,
0613     void *arg);
0614 
0615 /*! Clear (ACK) pending interrupt
0616  *
0617  *  \param dev        Device to clear interrupt for.
0618  *  \param index      Index is used to identify the IRQ number if hardware has multiple IRQ sources.
0619  *                    Normally Index is set to 0 to indicated the first and only IRQ source.
0620  *                    A negative index is interpreted as a absolute bus IRQ number.
0621  *  \param isr        Interrupt Service Routine, previously registered.
0622  *  \param arg        Optional ISR argument, previously registered.
0623  */
0624 extern int drvmgr_interrupt_clear(
0625     struct drvmgr_dev *dev,
0626     int index);
0627 
0628 /*! Force unmasking/enableing an interrupt on the interrupt controller, this is not normally used,
0629  *  if used the caller has masked/disabled the interrupt just before.
0630  *
0631  *  \param dev        Device to clear interrupt for.
0632  *  \param index      Index is used to identify the IRQ number if hardware has multiple IRQ sources.
0633  *                    Normally Index is set to 0 to indicated the first and only IRQ source.
0634  *                    A negative index is interpreted as a absolute bus IRQ number.
0635  *  \param isr        Interrupt Service Routine, previously registered.
0636  *  \param arg        Optional ISR argument, previously registered.
0637  */
0638 extern int drvmgr_interrupt_unmask(
0639     struct drvmgr_dev *dev,
0640     int index);
0641 
0642 /*! Force masking/disable an interrupt on the interrupt controller, this is not normally performed
0643  *  since this will stop all other (shared) ISRs to be disabled until _unmask() is called.
0644  *
0645  *  \param dev        Device to mask interrupt for.
0646  *  \param index      Index is used to identify the IRQ number if hardware has multiple IRQ sources.
0647  *                    Normally Index is set to 0 to indicated the first and only IRQ source.
0648  *                    A negative index is interpreted as a absolute bus IRQ number.
0649  */
0650 extern int drvmgr_interrupt_mask(
0651     struct drvmgr_dev *dev,
0652     int index);
0653 
0654 /*! Force masking/disable an interrupt on the interrupt controller, this is not normally performed
0655  *  since this will stop all other (shared) ISRs to be disabled until _unmask() is called.
0656  *
0657  *  \param dev        Device to mask interrupt for.
0658  *  \param index      Index is used to identify the IRQ number if hardware has multiple IRQ sources.
0659  *                    Normally Index is set to 0 to indicated the first and only IRQ source.
0660  *                    A negative index is interpreted as a absolute bus IRQ number.
0661  */
0662 #ifdef RTEMS_SMP
0663 extern int drvmgr_interrupt_set_affinity(
0664     struct drvmgr_dev *dev,
0665     int index,
0666     const Processor_mask *cpus);
0667 #endif
0668 
0669 /*! drvmgr_translate() translation options */
0670 enum drvmgr_tr_opts {
0671     /* Translate CPU RAM Address (input) to DMA unit accessible address
0672      * (output), this is an upstreams translation in reverse order.
0673      *
0674      * Typical Usage:
0675      * It is common to translate a CPU accessible RAM address to an
0676      * address that DMA units can access over bridges.
0677      */
0678     CPUMEM_TO_DMA = 0x0,
0679 
0680     /* Translate DMA Unit Accessible address mapped to CPU RAM (input) to
0681      * CPU accessible address (output). This is an upstreams translation.
0682      *
0683      * Typical Usage (not often used):
0684      * The DMA unit descriptors contain pointers to DMA buffers located at
0685      * CPU RAM addresses that the DMA unit can access, the CPU processes
0686      * the descriptors and want to access the data but a translation back
0687      * to CPU address is required.
0688      */
0689     CPUMEM_FROM_DMA = 0x1,
0690 
0691     /* Translate DMA Memory Address (input) to CPU accessible address
0692      * (output), this is a downstreams translation in reverse order.
0693      *
0694      * Typical Usage:
0695      * A PCI network card puts packets into its memory not doing DMA over
0696      * PCI, in order for the CPU to access them the PCI address must be
0697      * translated.
0698      */
0699     DMAMEM_TO_CPU = 0x2,
0700 
0701     /* Translate CPU accessible address (input) mapped to DMA Memory Address
0702      * to DMA Unit accessible address (output). This is a downstreams
0703      * translation.
0704      */
0705     DMAMEM_FROM_CPU = 0x3,
0706 };
0707 #define DRVMGR_TR_REVERSE 0x1   /* do reverse translation direction order */
0708 #define DRVMGR_TR_PATH 0x2  /* 0x0=down-stream 0x2=up-stream address path */
0709  
0710 /*! Translate an address on one bus to an address on another bus.
0711  *
0712  *  The device determines source or destination bus, the root bus is always
0713  *  the other bus. It is assumed that the CPU is located on the root bus or
0714  *  that it can access it without address translation (mapped 1:1). The CPU
0715  *  is thus assumed to be located on level 0 top most in the bus hierarchy.
0716  *
0717  *  If no map is present in the bus driver src_address is translated 1:1
0718  *  (just copied).
0719  *
0720  *  Addresses are typically converted up-streams from the DMA unit towards the
0721  *  CPU (DMAMEM_TO_CPU) or down-streams towards DMA hardware from the CPU
0722  *  (CPUMEM_TO_DMA) over one or multiple bridges depending on bus architecture.
0723  *  See 'enum drvmgr_tr_opts' for other translation direction options.
0724  *  For example:
0725  *  Two common operations is to translate a CPU accessible RAM address to an
0726  *  address that DMA units can access (dev=DMA-unit, CPUMEM_TO_DMA,
0727  *  src_address=CPU-RAM-ADR) and to translate an address of a PCI resource for
0728  *  example RAM mapped into a PCI BAR to an CPU accessible address
0729  *  (dev=PCI-device, DMAMEM_TO_CPU, src_address=PCI-BAR-ADR).
0730  *
0731  *  Source address is translated and the result is put into *dst_address, if
0732  *  the address is not accessible on the other bus -1 is returned.
0733  *
0734  *  \param dev             Device to translate addresses for
0735  *  \param options         Tanslation direction options, see enum drvmgr_tr_opts
0736  *  \param src_address     Address to translate
0737  *  \param dst_address     Location where translated address is stored
0738  *
0739  *  Returns 0 if unable to translate. The remaining length from the given
0740  *  address of the map is returned on success, for example if a map starts
0741  *  at 0x40000000 of size 0x100000 the result will be 0x40000 if the address
0742  *  was translated into 0x400C0000.
0743  *  If dev is on root-bus no translation is performed 0xffffffff is returned
0744  *  and src_address is stored in *dst_address.
0745  */
0746 extern unsigned int drvmgr_translate(
0747     struct drvmgr_dev *dev,
0748     unsigned int options,
0749     void *src_address,
0750     void **dst_address);
0751 
0752 /* Translate addresses between buses, used internally to implement
0753  * drvmgr_translate. Function is not limited to translate from/to root bus
0754  * where CPU is resident, however buses must be on a straight path relative
0755  * to each other (parent of parent of parent and so on).
0756  *
0757  * \param from         src_address is given for this bus
0758  * \param to           src_address is translated to this bus
0759  * \param reverse      Selects translation method, if map entries are used in
0760  *                     the reverse order (map_up->to is used as map_up->from)
0761  * \param src_address  Address to be translated
0762  * \param dst_address  Translated address is stored here on success (return=0)
0763  *
0764  *  Returns 0 if unable to translate. The remaining length from the given
0765  *  address of the map is returned on success and the result is stored into
0766  *  *dst_address. For example if a map starts at 0x40000000 of size 0x100000
0767  *  the result will be 0x40000 if the address was translated into 0x400C0000.
0768  *  If dev is on root-bus no translation is performed 0xffffffff is returned.
0769  *  and src_address is stored in *dst_address.
0770  */
0771 extern unsigned int drvmgr_translate_bus(
0772     struct drvmgr_bus *from,
0773     struct drvmgr_bus *to,
0774     int reverse,
0775     void *src_address,
0776     void **dst_address);
0777 
0778 /* Calls drvmgr_translate() to translate an address range and checks the result,
0779  * a printout is generated if the check fails. All parameters are passed on to
0780  * drvmgr_translate() except for size, see paramters of drvmgr_translate().
0781  *
0782  * If size=0 only the starting address is not checked.
0783  *
0784  * If mapping failes a non-zero result is returned.
0785  */
0786 extern int drvmgr_translate_check(
0787     struct drvmgr_dev *dev,
0788     unsigned int options,
0789     void *src_address,
0790     void **dst_address,
0791     unsigned int size);
0792 
0793 /*! Get function pointer from Device Driver or Bus Driver.
0794  *
0795  *  Returns 0 if function is available
0796  */
0797 extern int drvmgr_func_get(void *obj, int funcid, void **func);
0798 
0799 /*! Lookup function and call it directly with the four optional arguments */
0800 extern int drvmgr_func_call(void *obj, int funcid, void *a, void *b, void *c, void *d);
0801 
0802 /* Builds a Function ID.
0803  *
0804  * Used to request optional functions by a bus or device driver
0805  */
0806 #define DRVMGR_FUNCID(major, minor) ((((major) & 0xfff) << 20) | ((minor) & 0xfffff))
0807 #define DRVMGR_FUNCID_NONE 0
0808 #define DRVMGR_FUNCID_END DRVMGR_FUNCID(DRVMGR_FUNCID_NONE, 0)
0809 
0810 /* Major Function ID. Most significant 12-bits. */
0811 enum {
0812     FUNCID_NONE             = 0x000,
0813     FUNCID_RW               = 0x001, /* Read/Write functions */
0814 };
0815 
0816 /* Select Sub-Function Read/Write function by ID */
0817 #define RW_SIZE_1   0x00001    /* Access Size */
0818 #define RW_SIZE_2   0x00002
0819 #define RW_SIZE_4   0x00004
0820 #define RW_SIZE_8   0x00008
0821 #define RW_SIZE_ANY 0x00000
0822 #define RW_SIZE(id) ((unsigned int)(id) & 0xf)
0823 
0824 #define RW_DIR_ANY  0x00000   /* Access Direction */
0825 #define RW_READ     0x00000   /* Read */
0826 #define RW_WRITE    0x00010   /* Write */
0827 #define RW_SET      0x00020   /* Write with same value (memset) */
0828 #define RW_DIR(id)  (((unsigned int)(id) >> 4) & 0x3)
0829 
0830 #define RW_RAW      0x00000  /* Raw access - no swapping (machine default) */
0831 #define RW_LITTLE   0x00040  /* Little Endian */
0832 #define RW_BIG      0x00080  /* Big Endian */
0833 #define RW_ENDIAN(id) (((unsigned int)(id) >> 6) & 0x3)
0834 
0835 #define RW_TYPE_ANY 0x00000  /* Access type */
0836 #define RW_REG      0x00100
0837 #define RW_MEM      0x00200
0838 #define RW_MEMREG   0x00300
0839 #define RW_CFG      0x00400
0840 #define RW_TYPE(id) (((unsigned int)(id) >> 8) & 0xf)
0841 
0842 #define RW_ARG      0x01000 /* Optional Argument */
0843 #define RW_ERR      0x02000 /* Optional Error Handler */
0844 
0845 /* Build a Read/Write function ID */
0846 #define DRVMGR_RWFUNC(minor) DRVMGR_FUNCID(FUNCID_RW, minor)
0847 
0848 /* Argument to Read/Write functions, the "void *arg" pointer is returned by
0849  * RW_ARG. If NULL is returned no argument is needed.
0850  */
0851 struct drvmgr_rw_arg {
0852     void *arg;
0853     struct drvmgr_dev *dev;
0854 };
0855 
0856 /* Standard Read/Write function types */
0857 typedef uint8_t (*drvmgr_r8)(uint8_t *srcadr);
0858 typedef uint16_t (*drvmgr_r16)(uint16_t *srcadr);
0859 typedef uint32_t (*drvmgr_r32)(uint32_t *srcadr);
0860 typedef uint64_t (*drvmgr_r64)(uint64_t *srcadr);
0861 typedef void (*drvmgr_w8)(uint8_t *dstadr, uint8_t data);
0862 typedef void (*drvmgr_w16)(uint16_t *dstadr, uint16_t data);
0863 typedef void (*drvmgr_w32)(uint32_t *dstadr, uint32_t data);
0864 typedef void (*drvmgr_w64)(uint64_t *dstadr, uint64_t data);
0865 /* READ/COPY a memory area located on bus into CPU memory.
0866  * From 'src' (remote) to the destination 'dest' (local), n=number of bytes
0867  */
0868 typedef int (*drvmgr_rmem)(void *dest, const void *src, int n);
0869 /* WRITE/COPY a user buffer located in CPU memory to a location on the bus.
0870  * From 'src' (local) to the destination 'dest' (remote), n=number of bytes
0871  */
0872 typedef int (*drvmgr_wmem)(void *dest, const void *src, int n);
0873 /* Set a memory area to the byte value given in c, see LIBC memset(). Memset is
0874  * implemented by calling wmem() multiple times with a "large" buffer.
0875  */
0876 typedef int (*drvmgr_memset)(void *dstadr, int c, size_t n);
0877 
0878 /* Read/Write function types with additional argument */
0879 typedef uint8_t (*drvmgr_r8_arg)(uint8_t *srcadr, void *a);
0880 typedef uint16_t (*drvmgr_r16_arg)(uint16_t *srcadr, void *a);
0881 typedef uint32_t (*drvmgr_r32_arg)(uint32_t *srcadr, void *a);
0882 typedef uint64_t (*drvmgr_r64_arg)(uint64_t *srcadr, void *a);
0883 typedef void (*drvmgr_w8_arg)(uint8_t *dstadr, uint8_t data, void *a);
0884 typedef void (*drvmgr_w16_arg)(uint16_t *dstadr, uint16_t data, void *a);
0885 typedef void (*drvmgr_w32_arg)(uint32_t *dstadr, uint32_t data, void *a);
0886 typedef void (*drvmgr_w64_arg)(uint64_t *dstadr, uint64_t data, void *a);
0887 typedef int (*drvmgr_rmem_arg)(void *dest, const void *src, int n, void *a);
0888 typedef int (*drvmgr_wmem_arg)(void *dest, const void *src, int n, void *a);
0889 typedef int (*drvmgr_memset_arg)(void *dstadr, int c, size_t n, void *a);
0890 
0891 /* Report an error to the parent bus of the device */
0892 typedef void (*drvmgr_rw_err)(struct drvmgr_rw_arg *a, struct drvmgr_bus *bus,
0893                 int funcid, void *adr);
0894 
0895 /* Helper function for buses that implement the memset() over wmem() */
0896 extern void drvmgr_rw_memset(
0897     void *dstadr,
0898     int c,
0899     size_t n,
0900     void *a,
0901     drvmgr_wmem_arg wmem
0902     );
0903 
0904 /*** PRINT INFORMATION ABOUT DRIVER MANAGER ***/
0905 
0906 /*! Calls func() for every device found matching the search requirements of
0907  * set_mask and clr_mask. Each bit set in set_mask must be set in the
0908  * device state bit mask (dev->state), and Each bit in the clr_mask must
0909  * be cleared in the device state bit mask (dev->state). There are three
0910  * special cases:
0911  *
0912  * 1. If state_set_mask and state_clr_mask are zero the state bits are
0913  *    ignored and all cores are treated as a match.
0914  *
0915  * 2. If state_set_mask is zero the function func will not be called due to
0916  *    a bit being set in the state mask.
0917  *
0918  * 3. If state_clr_mask is zero the function func will not be called due to
0919  *    a bit being cleared in the state mask.
0920  *
0921  * If the function func() returns a non-zero value then for_each_dev will
0922  * return imediatly with the same return value as func() returned.
0923  *
0924  * \param devlist            The list to iterate though searching for devices.
0925  * \param state_set_mask     Defines the bits that must be set in dev->state
0926  * \param state_clr_mask     Defines the bits that must be cleared in dev->state
0927  * \param func               Function called on each
0928  *
0929  */
0930 extern int drvmgr_for_each_listdev(
0931     struct drvmgr_list *devlist,
0932     unsigned int state_set_mask,
0933     unsigned int state_clr_mask,
0934     int (*func)(struct drvmgr_dev *dev, void *arg),
0935     void *arg);
0936 
0937 /* Print all devices */
0938 #define PRINT_DEVS_FAILED   0x01    /* Failed during initialization */
0939 #define PRINT_DEVS_ASSIGNED 0x02    /* Driver assigned */
0940 #define PRINT_DEVS_UNASSIGNED   0x04    /* Driver not assigned */
0941 #define PRINT_DEVS_IGNORED  0x08    /* Device ignored on user's request */
0942 #define PRINT_DEVS_ALL      (PRINT_DEVS_FAILED | \
0943                 PRINT_DEVS_ASSIGNED | \
0944                 PRINT_DEVS_UNASSIGNED |\
0945                 PRINT_DEVS_IGNORED)
0946 
0947 /*! Print number of devices, buses and drivers */
0948 extern void drvmgr_summary(void);
0949 
0950 /*! Print devices with certain condictions met according to 'options' */
0951 extern void drvmgr_print_devs(unsigned int options);
0952 
0953 /*! Print device/bus topology */
0954 extern void drvmgr_print_topo(void);
0955 
0956 /*! Print the memory usage
0957  * Only accounts for data structures. Not for the text size.
0958  */
0959 extern void drvmgr_print_mem(void);
0960 
0961 #define OPTION_DEV_GENINFO   0x00000001
0962 #define OPTION_DEV_BUSINFO   0x00000002
0963 #define OPTION_DEV_DRVINFO   0x00000004
0964 #define OPTION_DRV_DEVS      0x00000100
0965 #define OPTION_BUS_DEVS      0x00010000
0966 #define OPTION_RECURSIVE     0x01000000
0967 #define OPTION_INFO_ALL      0xffffffff
0968 
0969 /*! Print information about a driver manager object (device, driver, bus) */
0970 extern void drvmgr_info(void *id, unsigned int options);
0971 
0972 /*! Get information about a device */
0973 extern void drvmgr_info_dev(struct drvmgr_dev *dev, unsigned int options);
0974 
0975 /*! Get information about a bus */
0976 extern void drvmgr_info_bus(struct drvmgr_bus *bus, unsigned int options);
0977 
0978 /*! Get information about a driver */
0979 extern void drvmgr_info_drv(struct drvmgr_drv *drv, unsigned int options);
0980 
0981 /*! Get information about all devices on a bus */
0982 extern void drvmgr_info_devs_on_bus(struct drvmgr_bus *bus, unsigned int options);
0983 
0984 /*! Get information about all devices in the system (on all buses) */
0985 extern void drvmgr_info_devs(unsigned int options);
0986 
0987 /*! Get information about all drivers in the system */
0988 extern void drvmgr_info_drvs(unsigned int options);
0989 
0990 /*! Get information about all buses in the system */
0991 extern void drvmgr_info_buses(unsigned int options);
0992 
0993 /*! Get Driver by Driver ID */
0994 extern struct drvmgr_drv *drvmgr_drv_by_id(uint64_t id);
0995 
0996 /*! Get Driver by Driver Name */
0997 extern struct drvmgr_drv *drvmgr_drv_by_name(const char *name);
0998 
0999 /*! Get Device by Device Name */
1000 extern struct drvmgr_dev *drvmgr_dev_by_name(const char *name);
1001 
1002 #ifdef __cplusplus
1003 }
1004 #endif
1005 
1006 #endif