![]() |
|
|||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |