xref: /haiku/docs/develop/kernel/device_manager_introduction.rst (revision a5061ecec55353a5f394759473f1fd6df04890da)
1*a5061eceSAdrien DestuguesDevice Driver Architecture
2*a5061eceSAdrien Destugues==================================================
3*a5061eceSAdrien Destugues
4*a5061eceSAdrien DestuguesThis document tries to give you a short introduction into the new device
5*a5061eceSAdrien Destuguesmanager, and how to write drivers for it. Haiku still supports the
6*a5061eceSAdrien Destugueslegacy device driver architecture introduced with BeOS.
7*a5061eceSAdrien Destugues
8*a5061eceSAdrien DestuguesThe new device driver architecture of Haiku is still a moving target,
9*a5061eceSAdrien Destuguesalthough most of its details are already specificed.
10*a5061eceSAdrien Destugues
11*a5061eceSAdrien Destugues1. The Basics
12*a5061eceSAdrien Destugues-------------
13*a5061eceSAdrien Destugues
14*a5061eceSAdrien DestuguesThe device manager functionality builds upon *device_node* objects.
15*a5061eceSAdrien DestuguesEvery driver in the system publishes one or more of such nodes, building
16*a5061eceSAdrien Destuguesa tree of device nodes. This tree is in theory a dynamic representation
17*a5061eceSAdrien Destuguesof the current hardware devices in the system, but in practice will also
18*a5061eceSAdrien Destuguescontain implementation specific details; since every node comes with an
19*a5061eceSAdrien DestuguesAPI specific to that node, you'll find device nodes that only come with
20*a5061eceSAdrien Destuguesa number of support functions for a certain class of drivers.
21*a5061eceSAdrien Destugues
22*a5061eceSAdrien DestuguesStructurally, a *device_node* is a set of a module, attributes, and
23*a5061eceSAdrien Destuguesresources, as well as a parent and children. At a minimum, a node must
24*a5061eceSAdrien Destugueshave a module, all other components are optional.
25*a5061eceSAdrien Destugues
26*a5061eceSAdrien DestuguesTODO: picture of the device node tree
27*a5061eceSAdrien Destugues
28*a5061eceSAdrien DestuguesWhen the system starts, there is only a root node registered. Only
29*a5061eceSAdrien Destuguesprimary hardware busses register with the root node, such as PCI, and
30*a5061eceSAdrien DestuguesISA on x86. Since the PCI bus is an intelligent bus, it knows what
31*a5061eceSAdrien Destugueshardware is installed, and registers a child node for each device on the
32*a5061eceSAdrien Destuguesbus.
33*a5061eceSAdrien Destugues
34*a5061eceSAdrien DestuguesEvery driver can also publish a device in */dev* for communication with
35*a5061eceSAdrien Destuguesuserland applications. All drivers and devices are kernel modules.
36*a5061eceSAdrien Destugues
37*a5061eceSAdrien Destugues2. Exploring the Device Tree
38*a5061eceSAdrien Destugues----------------------------
39*a5061eceSAdrien Destugues
40*a5061eceSAdrien DestuguesSo how does it all work? When building the initial device tree, the
41*a5061eceSAdrien Destuguessystem only explores a minimum of device drivers only, resulting in a
42*a5061eceSAdrien Destuguestree that basically only shows the hardware found in the computer.
43*a5061eceSAdrien Destugues
44*a5061eceSAdrien DestuguesNow, if the system requires disk access, it will scan the device file
45*a5061eceSAdrien Destuguessystem for a driver that provides such functionality, in this case, it
46*a5061eceSAdrien Destugueswill look for drivers under "/dev/disk/". The device manager has a set
47*a5061eceSAdrien Destuguesof built-in rules for how to translate a device path into a device node,
48*a5061eceSAdrien Destuguesand vice versa: every node representing a device of an intelligent bus
49*a5061eceSAdrien Destugues(such as PCI) will also contain device type information following the
50*a5061eceSAdrien DestuguesPCI definitions. In this case, the "disk" sub-path will translate into
51*a5061eceSAdrien Destuguesthe *PCI_mass_storage* type, and hence, the device manager will then
52*a5061eceSAdrien Destuguescompletely explore all device nodes of that type.
53*a5061eceSAdrien Destugues
54*a5061eceSAdrien DestuguesIt will also use that path information to only ask drivers that actually
55*a5061eceSAdrien Destuguesare in a matching module directory. In the above example of a disk
56*a5061eceSAdrien Destuguesdriver, this would be either in "busses/scsi", "busses/ide",
57*a5061eceSAdrien Destugues"drivers/disk", ...
58*a5061eceSAdrien Destugues
59*a5061eceSAdrien DestuguesFor untyped or generic busses, it will use the context information
60*a5061eceSAdrien Destuguesgained from the devfs query directly, and will search for drivers in
61*a5061eceSAdrien Destuguesthat sub directory only. The only exception to this rule are the devfs
62*a5061eceSAdrien Destuguesdirectories "disk", "ports", and "bus", which will also allow to search
63*a5061eceSAdrien Destuguesmatching drivers in "busses". While this is relatively limited, it is a
64*a5061eceSAdrien Destuguesgood way to cut down the number of drivers to be loaded.
65*a5061eceSAdrien Destugues
66*a5061eceSAdrien Destugues3. Writing a Driver
67*a5061eceSAdrien Destugues-------------------
68*a5061eceSAdrien Destugues
69*a5061eceSAdrien DestuguesThe device manager assumes the following API from a driver module:
70*a5061eceSAdrien Destugues
71*a5061eceSAdrien Destugues-  **supports_device()**
72*a5061eceSAdrien Destugues   Determines wether or not the driver supports a given parent device
73*a5061eceSAdrien Destugues   node, that is the hardware device it represents (if any), and the API
74*a5061eceSAdrien Destugues   the node exports.
75*a5061eceSAdrien Destugues-  **register_device()**
76*a5061eceSAdrien Destugues   The driver should register its device node here. The parent driver is
77*a5061eceSAdrien Destugues   always initialized at this point. When registering the node, the
78*a5061eceSAdrien Destugues   driver can also attach certain I/O resources (like I/O ports, or
79*a5061eceSAdrien Destugues   memory ranges) to the node -- the device manager will make sure that
80*a5061eceSAdrien Destugues   only one node can claim these resources.
81*a5061eceSAdrien Destugues-  **init_driver()**
82*a5061eceSAdrien Destugues   Any initialization necessary to get the driver going. For most
83*a5061eceSAdrien Destugues   drivers, this will be reduced to the creation of a private data
84*a5061eceSAdrien Destugues   structure that is going to be used for all of the following
85*a5061eceSAdrien Destugues   functions.
86*a5061eceSAdrien Destugues-  **uninit_driver()**
87*a5061eceSAdrien Destugues   Uninitializes resources acquired by **init_driver()**.
88*a5061eceSAdrien Destugues-  **register_child_devices()**
89*a5061eceSAdrien Destugues   If the driver wants to register any child device nodes or to publish
90*a5061eceSAdrien Destugues   any devices, it should do so here. This function is called only
91*a5061eceSAdrien Destugues   during the initial registration process of the device node.
92*a5061eceSAdrien Destugues-  **rescan_child_devices()**
93*a5061eceSAdrien Destugues   Is called whenever a manual rescan is triggered.
94*a5061eceSAdrien Destugues-  **device_removed()** Is called when the device node is about to be
95*a5061eceSAdrien Destugues   unregistered when its device is gone, for example when a USB device
96*a5061eceSAdrien Destugues   is unplugged.
97*a5061eceSAdrien Destugues-  **suspend()**
98*a5061eceSAdrien Destugues   Enters different sleep modes.
99*a5061eceSAdrien Destugues-  **resume()**
100*a5061eceSAdrien Destugues   Resumes a device from a previous sleep mode.
101*a5061eceSAdrien Destugues
102*a5061eceSAdrien DestuguesTo ensure that a module exports this API, it **must** end its module
103*a5061eceSAdrien Destuguesname with "driver_v1" to denote the version of the API it supports. Note
104*a5061eceSAdrien Destuguesthat **suspend()** and **resume()** are currently never called, as Haiku
105*a5061eceSAdrien Destugueshas no power management implemented yet.
106*a5061eceSAdrien Destugues
107*a5061eceSAdrien DestuguesIf your driver can give the device it is attached to a nice name that
108*a5061eceSAdrien Destuguescan be presented to the user, it should add the **B_DEVICE_PRETTY_NAME**
109*a5061eceSAdrien Destuguesattribute to the device node.
110*a5061eceSAdrien Destugues
111*a5061eceSAdrien DestuguesThe **B_DEVICE_UNIQUE_ID** should be used in case the device has a
112*a5061eceSAdrien Destuguesunique ID that can be used to identify it, and also differentiate it
113*a5061eceSAdrien Destuguesfrom other devices of the same model and vendor. This information will
114*a5061eceSAdrien Destuguesbe added to the file system attributes of all devices published by your
115*a5061eceSAdrien Destuguesdriver, so that user applications can identify, say, a USB printer no
116*a5061eceSAdrien Destuguesmatter what USB slot it is attached to, and assign it additional data,
117*a5061eceSAdrien Destugueslike paper configuration, or recognize it as the default printer.
118*a5061eceSAdrien Destugues
119*a5061eceSAdrien DestuguesIf your driver implements an API that is used by a support or bus
120*a5061eceSAdrien Destuguesmodule, you will usually use the **B_DEVICE_FIXED_CHILD** attribute to
121*a5061eceSAdrien Destuguesspecify exactly which child device node you will be talking to. If you
122*a5061eceSAdrien Destuguessupport several child nodes, you may want to have a closer look at the
123*a5061eceSAdrien Destuguessection explaining `how to write a bus driver <#bus_driver>`__.
124*a5061eceSAdrien Destugues
125*a5061eceSAdrien DestuguesIn addition to the child nodes a driver registers itself, a driver can
126*a5061eceSAdrien Destugueseither have dynamic children or fixed children, never both. Also, fixed
127*a5061eceSAdrien Destugueschildren are registered before **register_child_devices()** is called,
128*a5061eceSAdrien Destugueswhile dynamic children are registered afterwards.
129*a5061eceSAdrien Destugues
130*a5061eceSAdrien Destugues4. Publishing a Device
131*a5061eceSAdrien Destugues----------------------
132*a5061eceSAdrien Destugues
133*a5061eceSAdrien DestuguesTo publish a device entry in the device file system under */dev*, all
134*a5061eceSAdrien Destuguesyour driver has to do is to call the
135*a5061eceSAdrien Destugues
136*a5061eceSAdrien Destugues::
137*a5061eceSAdrien Destugues
138*a5061eceSAdrien Destugues       publish_device(device_node *node, const char *path,
139*a5061eceSAdrien Destugues           const char *deviceModuleName);
140*a5061eceSAdrien Destugues
141*a5061eceSAdrien Destuguesfunction the device manager module exports. The *path* is the path
142*a5061eceSAdrien Destuguescomponent that follows "/dev", for example "net/ipro1000/0". The
143*a5061eceSAdrien Destugues*deviceModuleName* is the module exporting the device functionality. It
144*a5061eceSAdrien Destuguesshould end with "device_v1" to show the device manager which protocol it
145*a5061eceSAdrien Destuguessupports. If the device node your device belongs to is removed, your
146*a5061eceSAdrien Destuguesdevice is removed automatically with it. On the other hand, you are
147*a5061eceSAdrien Destuguesallowed to unpublish the device at any point using the
148*a5061eceSAdrien Destugues**unpublish_device()** function the device manager delivers for this.
149*a5061eceSAdrien Destugues
150*a5061eceSAdrien DestuguesA device module must export the following API:
151*a5061eceSAdrien Destugues
152*a5061eceSAdrien Destugues-  **init_device()**
153*a5061eceSAdrien Destugues   This is called when the open() is called on this device for the first
154*a5061eceSAdrien Destugues   time. You may want to create a private data structure that is passed
155*a5061eceSAdrien Destugues   on to all subsequent calls of the **open()** function that your
156*a5061eceSAdrien Destugues   device exports.
157*a5061eceSAdrien Destugues-  **uninit_device()**
158*a5061eceSAdrien Destugues   Is called when the last file descriptor to the device had been
159*a5061eceSAdrien Destugues   closed.
160*a5061eceSAdrien Destugues-  **device_removed()**
161*a5061eceSAdrien Destugues   When the device node your device belongs to is going to be removed,
162*a5061eceSAdrien Destugues   you're notified about this in this function.
163*a5061eceSAdrien Destugues-  **open()**
164*a5061eceSAdrien Destugues   Called whenever your device is opened.
165*a5061eceSAdrien Destugues-  **close()**
166*a5061eceSAdrien Destugues-  **free()**
167*a5061eceSAdrien Destugues   Free the private data structure you allocated in **open()**.
168*a5061eceSAdrien Destugues-  **read()**
169*a5061eceSAdrien Destugues-  **write()**
170*a5061eceSAdrien Destugues-  **io()**
171*a5061eceSAdrien Destugues   This is a replacement for the **read()**, and **write()** calls, and
172*a5061eceSAdrien Destugues   allows, among other things, for asynchronous I/O. This functionality
173*a5061eceSAdrien Destugues   has not yet been implemented, though (see below).
174*a5061eceSAdrien Destugues-  **control()**
175*a5061eceSAdrien Destugues-  **select()**
176*a5061eceSAdrien Destugues-  **deselect()**
177*a5061eceSAdrien Destugues
178*a5061eceSAdrien Destugues5. Writing a Bus Driver
179*a5061eceSAdrien Destugues-----------------------
180*a5061eceSAdrien Destugues
181*a5061eceSAdrien DestuguesA bus driver is a driver that represents a bus where one or more
182*a5061eceSAdrien Destuguesarbitrary devices can be attached to.
183*a5061eceSAdrien Destugues
184*a5061eceSAdrien DestuguesThere are two basic types of busses: intelligent busses like PCI or USB
185*a5061eceSAdrien Destuguesthat know a lot about the devices attached to it, like a generic device
186*a5061eceSAdrien Destuguestype, as well as device and vendor ID information, and simple
187*a5061eceSAdrien Destuguesuntyped/generic busses that either have not all the information (like
188*a5061eceSAdrien Destuguesdevice type) or don't even know what and if any devices are attached.
189*a5061eceSAdrien DestuguesThe device manager has been written in such a way that device
190*a5061eceSAdrien Destuguesexploration makes use of additional information the bus can provide in
191*a5061eceSAdrien Destuguesorder to find a responsible device driver faster, and with less
192*a5061eceSAdrien Destuguesoverhead.
193*a5061eceSAdrien Destugues
194*a5061eceSAdrien Destugues5.1. Writing an Intelligent Bus Driver
195*a5061eceSAdrien Destugues^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
196*a5061eceSAdrien Destugues
197*a5061eceSAdrien DestuguesIf your bus knows what type of device is attached to, and also has
198*a5061eceSAdrien Destuguesvendor and device ID information about that device, it is considered to
199*a5061eceSAdrien Destuguesbe an intelligent bus. The bus driver is supposed to have one parent
200*a5061eceSAdrien Destuguesnode representing the bus, and to create a child node for each device
201*a5061eceSAdrien Destuguesattached to the bus.
202*a5061eceSAdrien Destugues
203*a5061eceSAdrien DestuguesThe additional information you have about the devices are attached to
204*a5061eceSAdrien Destuguesthe device node in the following attributes:
205*a5061eceSAdrien Destugues
206*a5061eceSAdrien Destugues-  **B_DEVICE_VENDOR_ID**
207*a5061eceSAdrien Destugues   The vendor ID - this ID has only to be valid in the namespace of your
208*a5061eceSAdrien Destugues   bus.
209*a5061eceSAdrien Destugues-  **B_DEVICE_ID**
210*a5061eceSAdrien Destugues   The device ID.
211*a5061eceSAdrien Destugues-  **B_DEVICE_TYPE**
212*a5061eceSAdrien Destugues   The device type as defined by the PCI class base information.
213*a5061eceSAdrien Destugues-  **B_DEVICE_SUB_TYPE**
214*a5061eceSAdrien Destugues   The device sub type as defined by the PCI sub class information.
215*a5061eceSAdrien Destugues-  **B_DEVICE_INTERFACE**
216*a5061eceSAdrien Destugues   The device interface type as defined by the PCI class API
217*a5061eceSAdrien Destugues   information.
218*a5061eceSAdrien Destugues
219*a5061eceSAdrien DestuguesYou can use the **B_DEVICE_FLAGS** attribute to define how the device
220*a5061eceSAdrien Destuguesmanager finds the children of the devices you exported. For this kind of
221*a5061eceSAdrien Destuguesbus drivers, you will usually only want to specify
222*a5061eceSAdrien Destugues**B_FIND_CHILD_ON_DEMAND** here, which causes the driver only to be
223*a5061eceSAdrien Destuguessearched when the system asks for it.
224*a5061eceSAdrien Destugues
225*a5061eceSAdrien Destugues5.2. Writing a Simple Bus Driver
226*a5061eceSAdrien Destugues^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
227*a5061eceSAdrien Destugues
228*a5061eceSAdrien DestuguesA bus can be simple in a number of ways:
229*a5061eceSAdrien Destugues
230*a5061eceSAdrien Destugues#. It may not know how many or if any devices are attached to it
231*a5061eceSAdrien Destugues#. It cannot retrieve any type information about the devices it has, but
232*a5061eceSAdrien Destugues   knows all devices that are attached to it
233*a5061eceSAdrien Destugues
234*a5061eceSAdrien DestuguesAn example of the latter would be the Zorro bus of the Amiga - it only
235*a5061eceSAdrien Destugueshas information about the vendor and device ID, but no type information.
236*a5061eceSAdrien DestuguesIt should be implemented like an intelligent bus, though, with the type
237*a5061eceSAdrien Destuguesinformation simply omitted.
238*a5061eceSAdrien Destugues
239*a5061eceSAdrien DestuguesTherefore, this section is about the former case, that is, a simple bus
240*a5061eceSAdrien Destugueslike the ISA bus. Since it doesn't know anything about its children, it
241*a5061eceSAdrien Destuguesdoes not publish any child nodes, instead, it will just specify the
242*a5061eceSAdrien DestuguesB_FIND_MULTIPLE_CHILDREN and B_FIND_CHILD_ON_DEMAND flags for its device
243*a5061eceSAdrien Destuguesnode. Since there is no additional information about this bus, the
244*a5061eceSAdrien Destuguesdevice manager will assume a simple bus, and will try to find drivers on
245*a5061eceSAdrien Destuguesdemand only.
246*a5061eceSAdrien Destugues
247*a5061eceSAdrien DestuguesThe generic bus
248*a5061eceSAdrien Destugues---------------
249*a5061eceSAdrien Destugues
250*a5061eceSAdrien DestuguesSome devices are not tied to a specific bus. This is the case for all
251*a5061eceSAdrien Destuguesdrivers that do not relate to a physical device: /dev/null, /dev/zero,
252*a5061eceSAdrien Destugues/dev/random, etc. A "generic" bus has been added, and these drivers can
253*a5061eceSAdrien Destuguesattach to it.
254*a5061eceSAdrien Destugues
255*a5061eceSAdrien Destugues6. Open Issues
256*a5061eceSAdrien Destugues--------------
257*a5061eceSAdrien Destugues
258*a5061eceSAdrien DestuguesWhile most of the new device manager is fledged out, there are some
259*a5061eceSAdrien Destuguesareas that could use improvements or are problematic under certain
260*a5061eceSAdrien Destuguesrequirements. Also, some parts just haven't been written yet.
261*a5061eceSAdrien Destugues
262*a5061eceSAdrien Destugues6.1. generic/simple busses
263*a5061eceSAdrien Destugues^^^^^^^^^^^^^^^^^^^^^^^^^^
264*a5061eceSAdrien Destugues
265*a5061eceSAdrien Destugues6.2. Unpublishing
266*a5061eceSAdrien Destugues^^^^^^^^^^^^^^^^^
267*a5061eceSAdrien Destugues
268*a5061eceSAdrien Destugues6.4. Versioning
269*a5061eceSAdrien Destugues^^^^^^^^^^^^^^^
270*a5061eceSAdrien Destugues
271*a5061eceSAdrien DestuguesThe way the device manager works, it makes versioning of modules (which
272*a5061eceSAdrien Destuguesare supposed to be one of the strong points of the module system) much
273*a5061eceSAdrien Destuguesharder or even impossible. While the device manager could introduce a
274*a5061eceSAdrien Destuguesnew API and could translate between a "driver_v1", and a "driver_v2" API
275*a5061eceSAdrien Destugueson the fly, it's not yet possible for a PCI sub module to do the same
276*a5061eceSAdrien Destuguesthing.
277*a5061eceSAdrien Destugues
278*a5061eceSAdrien Destugues**Proposed Solution:** Add attribute **B_DEVICE_ALTERNATE_VERSION** that
279*a5061eceSAdrien Destuguesspecifies alternate versions of the module API this device node
280*a5061eceSAdrien Destuguessupports. We would then need a **request_version()** or
281*a5061eceSAdrien Destugues**set_version()** function (to be called from **supports_device()**)
282*a5061eceSAdrien Destuguesthat allows to specify the version of the parent node this device node
283*a5061eceSAdrien Destugueswants to talk to.
284*a5061eceSAdrien Destugues
285*a5061eceSAdrien Destugues6.5. Unregistering Nodes
286*a5061eceSAdrien Destugues^^^^^^^^^^^^^^^^^^^^^^^^
287*a5061eceSAdrien Destugues
288*a5061eceSAdrien Destugues6.6. Support for generic drivers is missing
289*a5061eceSAdrien Destugues^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
290*a5061eceSAdrien Destugues
291*a5061eceSAdrien DestuguesThis should probably be done by simply adding a simple bus driver named
292*a5061eceSAdrien Destugues"generic" that generic drivers need to ask for.
293*a5061eceSAdrien Destugues
294*a5061eceSAdrien Destugues6.7. Mappings, And Other Optimizations
295*a5061eceSAdrien Destugues^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
296*a5061eceSAdrien Destugues
297*a5061eceSAdrien DestuguesDue to the way the device tree is built, the device manager could
298*a5061eceSAdrien Destuguesremember which driver served a given device node. That way, it wouldn't
299*a5061eceSAdrien Destuguesneed to search for a driver anymore, but could just pick it up.
300*a5061eceSAdrien DestuguesPractically, the device manager should cache the type (and/or
301*a5061eceSAdrien Destuguesvendor/device) information of a node, and assign one or more drivers
302*a5061eceSAdrien Destugues(via module name) to this information. It should also remember negative
303*a5061eceSAdrien Destuguesoutcome, that is if there is no driver supporting the hardware.
304*a5061eceSAdrien Destugues
305*a5061eceSAdrien DestuguesThis way, only the first boot would require an actual search for
306*a5061eceSAdrien Destuguesdrivers, as subsequent boots would reuse the type-driver assignments. If
307*a5061eceSAdrien Destuguesa new driver is installed, the cached assignments would need to be
308*a5061eceSAdrien Destuguesupdated immediately. If a driver has been installed outside of the
309*a5061eceSAdrien Destuguesrunning system, the device manager might want to create a hash per
310*a5061eceSAdrien Destuguesmodule directory to see if anything changed to flush the cache.
311*a5061eceSAdrien DestuguesAlternatively or additionally, the boot loader could have a menu causing
312*a5061eceSAdrien Destuguesthe cache to be ignored.
313*a5061eceSAdrien Destugues
314*a5061eceSAdrien DestuguesIt would be nice to find a way for generic and simple busses to reduce
315*a5061eceSAdrien Destuguesthe amount of searching necessary for them. One way would be to remember
316*a5061eceSAdrien Destugueswhich driver supports which bus - but this information is currently only
317*a5061eceSAdrien Destuguesaccessible derived from what the driver does, and is therefore not
318*a5061eceSAdrien Destuguesreliable or complete. A separately exported information would be
319*a5061eceSAdrien Destuguesnecessary for this.
320*a5061eceSAdrien Destugues
321*a5061eceSAdrien DestuguesAlso, when looking for a generic or simple bus driver, actual
322*a5061eceSAdrien Destuguesdirectories could be omitted; currently, driver search is always
323*a5061eceSAdrien Destuguesrecursive, as that's how the module mechanism is working. Eventually, we
324*a5061eceSAdrien Destuguesmight want to extend the open_module_list_etc() call a bit more to
325*a5061eceSAdrien Destuguesaccomplish that.
326