1 /* 2 Copyright (c) 2003-04, Thomas Kurschel 3 4 PnP manager; Takes care of registration and loading of PnP drivers 5 6 Read pnp_driver.h first to understand the basic idea behind PnP drivers. 7 8 To register a driver node, use register_driver. If the device got lost, 9 use unregister_driver (note: if the parent node is removed, your node 10 get removed automatically as your driver has obviously nothing to work 11 with anymore). To get access to a (parent) device, use load_driver/ 12 unload_driver. 13 14 To let the manager find a consumer (see pnp_driver.h), you can either 15 specify its name directly during registration, using a 16 PNP_DRIVER_FIXED_CONSUMER attribute, or let the manager search the 17 appropriate consumer(s) via a PNP_DRIVER_DYNAMIC_CONSUMER attribute. 18 19 Searching of dynamic consumers is done as follows: 20 21 - First, the manager searches for a Specific driver in the base 22 directory (see below) 23 - If no Specific driver is found, all Generic drivers stored under 24 "generic" sub-directory are informed in turn until one returns success 25 - Finally, _all_ Universal drivers, stored in the "universal" sub- 26 directory, are informed 27 28 Specification of the base directory and of the names of Specific 29 drivers is done via a file name pattern given by a 30 PNP_DRIVER_DYNAMIC_CONSUMER attribute. 31 32 First, all substrings of the form "%attribute_name%" are replaced by the 33 content of the attribute "attribute_name" as follows: 34 35 - if the attribute contains an integer value, its content is converted to hex 36 (lowercase) with a fixed length according to the attribute's value range 37 - the content of string attributes is quoted by " and invalid characters 38 (i.e. /%" and all characters outside 32..126) are replaced by their 39 unsigned decimal value, delimited by % 40 - other attribute types cannot be used 41 42 Second, the resulting name is split into chunks according to the presence 43 of | characters (you can escape % and | with a ^ character). These 44 characters are only delimiters and get removed before further processing. 45 The directory before the first | character is the base directory (see 46 above). It contains the "generic" and the "universal" subdirectories. 47 The names of the specific drivers are created by first taking the entire 48 file name, then by removing the last chunk, then by removing the last 49 two chunks and so on until only the first chunk is left. 50 51 As drivers can contain multiple modules, the module name is constructed 52 by appending the content of the PNP_DRIVER_TYPE attribute to the driver's file 53 name, seperated by a slash character (note: this only applies to dynamic 54 consumers; for fixed consumers, you specify the module name directly via 55 PNP_DRIVER_FIXED_CONSUMER). 56 57 E.g. given a dynamic consumer pattern of 58 "pci/vendor=%vendor_id%|, device=%device_id%" for a device with the 59 attributes vendor_id=0x123 and device_id=0xabcd (both being uint16), the 60 PnP manager tries the specific drivers "pci/vendor=0123, device=abcd" and 61 (if the first one fails/doesn't exist) "pci/vendor=0123". If they both 62 refuse to handle the device, all drivers under "pci/generic" are tried 63 until one accepts the device. Finally, all drivers under "pci/universal" 64 are loaded, whatever happened before. 65 66 In practise, you should try to use specific drivers as much as possible. 67 If detection based on device IDs is impossible (e.g. because the bus 68 doesn't support them at all), you can put the driver under "generic". 69 Generic drivers can also be used to specify wrappers that try to load old- 70 style drivers if no new driver can be found. Also, they can be used to 71 report an error or invoke an user program that tries downloading a 72 proper Specific driver. Universal drivers are mainly used for 73 informational purposes, e.g. to publish data about each found device, 74 or to provide raw access to all devices. 75 76 If the device uses physical address space or I/O space or ISA DMA 77 channels (called I/O resources), the driver has to acquire these 78 resources. During hardware detection (usually via probe()), 79 acquire_io_resources() must be called to get exclusive access. 80 If no hardware could be found, they must be released via 81 release_io_resources(). If detection was successful, the list of 82 the (acquired) resources must be passed to register_device(). 83 Resources can either belong to one hardware detection or to a device. 84 If a hardware detection collides with another, it has to wait; 85 if it collides with a device whose driver is not loaded, the 86 driver loading is blocked. When detection fails, i.e. if 87 release_io_resources() is called, all blocked drivers can be loaded 88 again. If the detection fails, i.e. the resources are transferred 89 via register_device(), all blocked devices are unregistered and 90 pending load requests aborted. If a hardware detection collides 91 with a device whose driver is loaded, acquire_io_resources() fails 92 with B_BUSY. As this makes a hardware rescan impossible if the 93 driver is loaded, you should define PNP_DRIVER_NO_LIVE_RESCAN 94 for nodes that use I/O resources (see below). 95 96 To search for new drivers for a given device node, use rescan(). This 97 marks all consumer devices as being verified and calls probe() 98 of all consumers drivers (see above) to let them rescan the parent 99 for devices. The <depth> parameter determines the nesting level, e.g. 100 2 means that first the consumers are scanned and then the consumers 101 of the consumers. 102 103 Normally, all devices can be rescanned. If a driver cannot handle 104 a rescan safely when it is loaded (i.e. used by a consumer), it 105 must set PNP_DRIVER_NO_LIVE_RESCAN, in which case the device is 106 ignored during rescan if the driver is loaded and attempts 107 to load the driver during a rescan are blocked until the rescan 108 is finished. If rescanning a device is not possible at all, it must 109 have set PNP_DRIVER_NEVER_RESCAN to always ignore it. 110 111 To distinguish between new devices, lost devices and redetected 112 devices, consumer devices should provide a connection code and a 113 device identifier. They are specified by PNP_DRIVER_CONNECTION and 114 PNP_DRIVER_CONNECTION respectively, and are expanded in the same way 115 as PNP_DRIVER_DYNAMIC_CONSUMER. It is assumed that there can be only 116 one device per connection and that a device can be uniquely identify 117 by a device identifier. If a consumer device is registered on the 118 same connection as an existing device but with a different device 119 identifier, the old device gets unregistered automatically. If both 120 connection and device identifier are the same, registration is 121 handled as a redetection and ignored (unless a different type or 122 driver module is specified - in this case, the device is replaced). 123 Devices that were not redetected during a rescan get unregistered 124 unless they were ignored (see above). 125 */ 126 127 #ifndef _DEVICE_MANAGER_H 128 #define _DEVICE_MANAGER_H 129 130 #include <TypeConstants.h> 131 #include <Drivers.h> 132 #include <module.h> 133 134 135 // type of I/O resource 136 enum { 137 IO_MEM = 1, 138 IO_PORT = 2, 139 ISA_DMA_CHANNEL = 3 140 }; 141 142 143 // I/O resource description 144 typedef struct { 145 uint32 type; 146 // type of I/O resource 147 148 uint32 base; 149 // I/O memory: first physical address (32 bit) 150 // I/O port: first port address (16 bit) 151 // ISA DMA channel: channel number (0-7) 152 153 uint32 len; 154 // I/O memory: size of address range (32 bit) 155 // I/O port: size of port range (16 bit) 156 // ISA DMA channel: must be 1 157 } io_resource; 158 159 // attribute of device node 160 typedef struct { 161 const char *name; 162 type_code type; // for supported types, see value 163 union { 164 uint8 ui8; // B_UINT8_TYPE 165 uint16 ui16; // B_UINT16_TYPE 166 uint32 ui32; // B_UINT32_TYPE 167 uint64 ui64; // B_UINT64_TYPE 168 const char *string; // B_STRING_TYPE 169 struct { // B_RAW_TYPE 170 void *data; 171 size_t len; 172 } raw; 173 } value; 174 } pnp_node_attr; 175 176 177 // handle of PnP node 178 typedef struct pnp_node_info *pnp_node_handle; 179 180 // handle of acquired I/O resource 181 typedef struct io_resource_info *io_resource_handle; 182 183 // handle of node attribute 184 typedef struct pnp_node_attr_info *pnp_node_attr_handle; 185 186 187 typedef struct pnp_driver_info pnp_driver_info; 188 189 // interface of PnP manager 190 typedef struct device_manager_info { 191 module_info minfo; 192 193 // load driver 194 // node - node whos driver is to be loaded 195 // user_cookie - cookie to be passed to init_device of driver 196 // interface - interface of loaded driver 197 // cookie - device cookie issued by loaded driver 198 status_t (*load_driver) ( 199 pnp_node_handle node, 200 void *user_cookie, 201 pnp_driver_info **interface, 202 void **cookie 203 ); 204 // unload driver 205 status_t (*unload_driver) ( 206 pnp_node_handle node 207 ); 208 209 // rescan node for new dynamic drivers 210 // node - node whose dynamic drivers are to be scanned 211 // depth - recursive depth (>= 1) 212 status_t (*rescan) ( 213 pnp_node_handle node, 214 uint depth 215 ); 216 217 // register device 218 // parent - parent node 219 // attributes - NULL-terminated array of node attributes 220 // io_resources - NULL-terminated array of I/O resources (can be NULL) 221 // node - new node handle 222 // on return, io_resources are invalid: on success I/O resources belong 223 // to node, on fail they are released; 224 // if device is already registered, B_OK is returned but *node is NULL 225 status_t (*register_device) ( 226 pnp_node_handle parent, 227 const pnp_node_attr *attrs, 228 const io_resource_handle *io_resources, 229 pnp_node_handle *node 230 ); 231 // unregister device 232 // all nodes having this node as their parent are unregistered too. 233 // if the node contains PNP_MANAGER_ID_GENERATOR/PNP_MANAGER_AUTO_ID 234 // pairs, the id specified this way is freed too 235 status_t (*unregister_device) ( 236 pnp_node_handle node 237 ); 238 239 // acquire I/O resources 240 // resources - NULL-terminated array of resources to acquire 241 // handles - NULL-terminated array of handles (one per resource); 242 // array must be provided by caller 243 // return B_BUSY if a resource is used by a loaded driver 244 status_t (*acquire_io_resources) ( 245 io_resource *resources, 246 io_resource_handle *handles 247 ); 248 // release I/O resources 249 // handles - NULL-terminated array of handles 250 status_t (*release_io_resources) ( 251 const io_resource_handle *handles 252 ); 253 254 // find device by node content 255 // the given attributes must _uniquely_ identify a device node; 256 // parent - parent node (-1 for don't-care) 257 // attrs - list of attributes (can be NULL) 258 // return: NULL if no device or multiple(!) devices found 259 pnp_node_handle (*find_device) ( 260 pnp_node_handle parent, 261 const pnp_node_attr *attrs 262 ); 263 264 // create unique id 265 // generator - name of id set 266 // if result >= 0 - unique id 267 // result < 0 - error code 268 int32 (*create_id)( 269 const char *generator 270 ); 271 // free unique id 272 status_t (*free_id)( 273 const char *generator, 274 uint32 id 275 ); 276 277 // get parent device node 278 pnp_node_handle (*get_parent)( 279 pnp_node_handle node 280 ); 281 282 // helpers to extract attribute by name. 283 // if <recursive> is true, parent nodes are scanned if 284 // attribute isn't found in current node; unless you declared 285 // the attribute yourself, use recursive search to handle 286 // intermittent nodes, e.g. defined by filter drivers, transparently. 287 // for raw and string attributes, you get a copy that must 288 // be freed by caller 289 status_t (*get_attr_uint8)( 290 pnp_node_handle node, 291 const char *name, 292 uint8 *value, 293 bool recursive 294 ); 295 status_t (*get_attr_uint16)( 296 pnp_node_handle node, 297 const char *name, 298 uint16 *value, 299 bool recursive 300 ); 301 status_t (*get_attr_uint32)( 302 pnp_node_handle node, 303 const char *name, 304 uint32 *value, 305 bool recursive 306 ); 307 status_t (*get_attr_uint64)( 308 pnp_node_handle node, 309 const char *name, 310 uint64 *value, 311 bool recursive 312 ); 313 status_t (*get_attr_string)( 314 pnp_node_handle node, 315 const char *name, 316 char **value, 317 bool recursive 318 ); 319 status_t (*get_attr_raw)( 320 pnp_node_handle node, 321 const char *name, 322 void **data, 323 size_t *len, 324 bool recursive 325 ); 326 327 // get next attribute of node; 328 // on call, *<attr_handle> must contain handle of an attribute; 329 // on return, *<attr_handle> is replaced by the next attribute or 330 // NULL if it was the last; 331 // to get the first attribute, <attr_handle> must point to NULL; 332 // the returned handle must be released by either passing it to 333 // another get_next_attr() call or by using release_attr() 334 // directly 335 status_t (*get_next_attr)( 336 pnp_node_handle node, 337 pnp_node_attr_handle *attr_handle 338 ); 339 340 // release attribute handle <attr_handle> of <node>; 341 // see get_next_attr 342 status_t (*release_attr)( 343 pnp_node_handle node, 344 pnp_node_attr_handle attr_handle 345 ); 346 347 // retrieve attribute data with handle given; 348 // <attr> is only valid as long as you don't release <attr_handle> 349 // implicitely or explicitely 350 status_t (*retrieve_attr)( 351 pnp_node_attr_handle attr_handle, 352 const pnp_node_attr **attr 353 ); 354 355 // change/add attribute <attr> of/to node 356 status_t (*write_attr)( 357 pnp_node_handle node, 358 const pnp_node_attr *attr 359 ); 360 361 // remove attribute of node by name 362 // <name> is name of attribute 363 status_t (*remove_attr)( 364 pnp_node_handle node, 365 const char *name 366 ); 367 } device_manager_info; 368 369 370 // standard attributes: 371 372 // if you are using an id generator (see create_id), you can let the 373 // manager automatically free the id when the node is deleted by setting 374 // the following attributes: 375 // name of generator (string) 376 #define PNP_MANAGER_ID_GENERATOR "id_generator" 377 // generated id (uint32) 378 #define PNP_MANAGER_AUTO_ID "auto_id" 379 380 // modulename of PnP manager 381 #define DEVICE_MANAGER_MODULE_NAME "sys/device_manager/v1" 382 383 384 // former pnp_driver.h 385 /* 386 Copyright (c) 2003-04, Thomas Kurschel 387 388 Required interface of PnP drivers 389 390 In contrast to standard BeOS drivers, PnP drivers are normal modules 391 having the interface described below. 392 393 Every device is described by its driver via a PnP node with properties 394 described in PnP Node Attributes. Devices are organized in a hierarchy, 395 e.g. a devfs device is a hard disk device that is connected to a 396 controller, which is a PCI device, that is connected to a PCI bus. 397 Every device is connected to its lower-level device via a parent link 398 stored in its Node. The higher-level is called the consumer of the 399 lower-level device. If the lower-level device gets removed, all its 400 consumers are removed too. 401 402 In our example, the hierarchy is 403 404 devfs device -> hard disk -> controller -> PCI device -> PCI bus 405 406 If the PCI bus is removed, everything up to including the devfs device 407 is removed too. 408 409 The driver hierarchy is constructed bottom-up, i.e. the lower-level 410 driver searches for a corresponding consumer, which in turns searches 411 for its consumer and so on. The lowest driver is usually something like 412 a PCI bus, the highest driver is normally a devfs entry (see pnp_devfs.h). 413 Registration of devices and the search for appropriate consumers is 414 done via the pnp_manager (see pnp_manager.h). 415 416 When a potential consumer is found, it gets informed about the new 417 lower-level device and can either refuse its handling or accept it. 418 On accept, it has to create a new node with the lower-level device 419 node as its parent. 420 421 Loading of drivers is done on demand, i.e. if the consumer wants to 422 access its lower-level device, it explicitely loads the corresponding 423 driver, and once it doesn't need it anymore, the lower-level driver 424 must be unloaded. Usually, this process happens recursively, i.e. in 425 our example, the hard disk driver loads the controller driver, which 426 loads the PCI device driver which loads the PCI bus driver. The same 427 process applies to unloading. 428 429 Because of this dynamic loading, drivers must store persistent data 430 in the node of their devices. Please be aware that you cannot modify 431 a node once published. 432 433 If a device gets removed, you must unregister its node. As said, the 434 PnP manager will automatically unregister all consumers too. The 435 corresponding drivers are notified to stop talking to their lower-level 436 devices and to terminate running requests. Normally, you want to use a 437 dedicated variable that is verified at each call to make sure that the 438 parent is still there. The notification is done independantly of the 439 driver being loaded by its consumer(s) or not. If it isn't loaded, 440 the notification callback gets NULL as the device cookie; normally, the 441 driver returns immediately in this case. As soon as both the device 442 is removed and the driver is unloaded, device_cleanup gets called to 443 free resources that couldn't be safely removed in device_removed when 444 the driver was still loaded. 445 446 If a device has exactly one consumer, they often interact in some way. 447 To simplify that, the consumer can pass a user-cookie to its parent 448 during load. In this case, it's up to the parent driver to get a 449 pointer to the interface of the consumer. Effectively, such consumers 450 have one interface for their consumers (base on pnp_driver_info), and 451 a another for their parents (with a completely driver-specific 452 structure). 453 454 In terms of synchronization, loading/unloading/remove-notifications 455 are executed synchroniously, i.e. if e.g. a device is to be unloaded 456 but the drive currently handles a remove-notification, the unloading 457 is delayed until the nofication callback returns. If multiple consumers 458 load a driver, the driver gets initialized only once; subsequent load 459 requests increase an internal load count only and return immediately. 460 In turn, unloading only happens once the load count reaches zero. 461 */ 462 463 464 // interface of PnP driver 465 struct pnp_driver_info { 466 module_info minfo; 467 468 status_t (*init_device)(pnp_node_handle node, void *user_cookie, void **cookie); 469 // driver is loaded. 470 // node - node of device 471 // user_cookie - cookie passed by loading driver 472 // cookie - cookie issued by this driver 473 474 status_t (*uninit_device)(void *cookie); 475 // driver gets unloaded. 476 477 status_t (*probe)(pnp_node_handle parent); 478 // parent was added or is rescanned. 479 // check whether this parent is supported and register 480 // any consumer device. Dynamic consumers must return 481 // B_OK if they support this parent. All other return 482 // values are ignored. 483 484 void (*device_removed)(pnp_node_handle node, void *cookie); 485 // a device node, registered by this driver, got removed. 486 // if the driver wasn't loaded when this happenes, no (un)init_device 487 // is called and thus <cookie> is NULL; 488 489 void (*device_cleanup)(pnp_node_handle node); 490 // a device node, registered by this driver, got removed and 491 // the driver got unloaded 492 }; 493 494 495 // standard attributes: 496 497 // module name of driver (required, string) 498 #define PNP_DRIVER_DRIVER "driver" 499 // type of driver (required, string) 500 #define PNP_DRIVER_TYPE "type" 501 // module name of fixed consumer - see pnp_manager.h (optional, string) 502 // append "/0", "/1" etc. if there are multiple fixed consumers 503 #define PNP_DRIVER_FIXED_CONSUMER "consumer/fixed" 504 // dynamic consumers pattern - see pnp_manager.h (optional, string) 505 // append "/0", "/1" etc. if there are multiple dynamic consumers 506 #define PNP_DRIVER_DYNAMIC_CONSUMER "consumer/dynamic" 507 508 // connection of parent the device is attached to (optional, string) 509 // there can be only one device per connection 510 #define PNP_DRIVER_CONNECTION "connection" 511 // pattern device identifier (optional, string) 512 // it is expanded and used to detect changed devices 513 #define PNP_DRIVER_DEVICE_IDENTIFIER "device_identifier" 514 // driver must not be loaded during rescan (optional, uint8) 515 // if != 0, driver must not be loaded during rescan 516 // nor can rescan be started when driver is loaded 517 // if the device uses I/O resources, you _must_ set this 518 // flag as the rescan would always fail if the driver is loaded 519 // due to resource contention 520 #define PNP_DRIVER_NO_LIVE_RESCAN "no_live_rescan" 521 // never rescan this device (optional, uint8) 522 // if != 0, device is never checked during rescan 523 #define PNP_DRIVER_NEVER_RESCAN "never_rescan" 524 // keep driver loaded loaded (optional, uint8) 525 // if != 0, the driver is loaded automatically whenever the node 526 // is registered and unloaded whenever the node is unregistered. 527 // if = 1, driver is temporarily unloaded during rescan 528 // if = 2, driver is not unloaded during rescan 529 // avoid the second case (2) as this makes replacing the driver 530 // impossible without a reboot. 531 #define PNP_DRIVER_ALWAYS_LOADED "always_loaded" 532 533 534 // former pnp_bus.h 535 /* 536 Copyright (c) 2003-04, Thomas Kurschel 537 538 Required interface of PnP bus drivers 539 540 Busses consist of two node layers: the lower layer defines the bus, 541 the upper layer defines the abstract devices connected to the bus. 542 Both layers are handled by a bus manager. Actual device nodes are 543 on top of abstract device nodes. 544 545 E.g. if we have a PCI bus with an IDE controller on it, we get 546 547 IDE controller -> PCI device -> PCI bus 548 549 with: 550 IDE controller = actual device node 551 PCI device = abstract device node 552 PCI bus = bus node 553 554 The PCI bus manager establishes both the PCI devices and the PCI busses. 555 556 Abstract device nodes act as a gateway between actual device nodes 557 and the corresponding bus node. They are constructed by the bus 558 node driver via its rescan() hook. To identify a bus node, define 559 PNP_BUS_IS_BUS as an attribute of it. As a result, the PnP manager 560 will call the rescan() method of the bus driver whenever the 561 bus is to be rescanned. Afterwards, all possible dynamic consumers 562 are informed as done for normal nodes. 563 564 Normally, potential device drivers are notified immediately when 565 rescan() registers a new abstract device node. But sometimes, device 566 drivers need to know _all_ devices connected to the bus for correct 567 detection. To ensure this, the bus node must define 568 PNP_BUS_NOTIFY_CONSUMERS_AFTER_RESCAN. In this case, scanning for 569 consumers is postponed until rescan() has finished. 570 571 If hot-plugging of devices can be detected automatically (e.g. USB), 572 you should define PNP_DRIVER_ALWAYS_LOADED, so the bus driver is 573 always loaded and thus capable of handling hot-plug events generated 574 by the bus controller hardware. 575 */ 576 577 578 // interface of PnP bus 579 typedef struct pnp_bus_info { 580 pnp_driver_info dinfo; 581 582 // (re)scan bus and register all devices. 583 // driver is always loaded during this call, but other hooks may 584 // be called concurrently 585 status_t (*rescan) ( void *cookie ); 586 } pnp_bus_info; 587 588 589 // standard attributes: 590 591 // PnP bus identification (required, uint8) 592 // define this to let the PnP manager know that this is a PnP bus 593 // the actual content is ignored 594 #define PNP_BUS_IS_BUS "bus/is_bus" 595 596 // defer searching for consumers (optional, uint8) 597 // if != 0, probe() of consumers is called after rescan() of bus 598 // else, probe() of consumers is called during rescan() of bus 599 // normally, consumers are informed about a new device as soon as 600 // it is registered by rescan(), i.e. not all devices may have been 601 // detected and registered yet; 602 // with this flag, detection of consumers is postponed until 603 // rescan() has finished, i.e. when all devices are registered 604 #define PNP_BUS_DEFER_PROBE "bus/defer_probe" 605 606 #endif /* _DEVICE_MANAGER_H */ 607