xref: /haiku/headers/os/drivers/device_manager.h (revision d1d811ec7007913f727f6b44d2d730554eacfa19)
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