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