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