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