vfs: check userland buffers before reading them.
[haiku.git] / docs / develop / kernel / device_manager_introduction.html
blob4af29626ee9b2a3e7f068b232806a591f92c1f21
1 <html>
2 <body bgcolor=white>
4 <h1>Introduction to Haiku's Device Driver Architecture</h1>
6 <p>This document tries to give you a short introduction into the new device
7 manager, and how to write drivers for it. Haiku still supports the legacy
8 device driver architecture introduced with BeOS.</p>
10 <p>The new device driver architecture of Haiku is still a moving target,
11 although most of its details are already specificed.</p>
14 <h2>1. The Basics</h2>
16 <p>The device manager functionality builds upon <i>device_node</i> objects.
17 Every driver in the system publishes one or more of such nodes, building a
18 tree of device nodes. This tree is in theory a dynamic representation of the
19 current hardware devices in the system, but in practice will also contain
20 implementation specific details; since every node comes with an API specific
21 to that node, you'll find device nodes that only come with a number of support
22 functions for a certain class of drivers.</p>
24 <p>Structurally, a <i>device_node</i> is a set of a module, attributes,
25 and resources, as well as a parent and children. At a minimum, a node must
26 have a module, all other components are optional.</p>
28 TODO: picture of the device node tree
30 <p>When the system starts, there is only a root node registered. Only primary
31 hardware busses register with the root node, such as PCI, and ISA on x86.
32 Since the PCI bus is an intelligent bus, it knows what hardware is installed,
33 and registers a child node for each device on the bus.</p>
35 <p>Every driver can also publish a device in <i>/dev</i> for communication with
36 userland applications. All drivers and devices are kernel modules.</p>
39 <h2>2. Exploring the Device Tree</h2>
41 <p>So how does it all work? When building the initial device tree, the system only
42 explores a minimum of device drivers only, resulting in a tree that basically
43 only shows the hardware found in the computer.</p>
45 <p>Now, if the system requires disk access, it will scan the device file system
46 for a driver that provides such functionality, in this case, it will look for
47 drivers under "/dev/disk/". The device manager has a set of built-in rules for
48 how to translate a device path into a device node, and vice versa: every node
49 representing a device of an intelligent bus (such as PCI) will also contain
50 device type information following the PCI definitions. In this case, the "disk"
51 sub-path will translate into the <i>PCI_mass_storage</i> type, and hence, the
52 device manager will then completely explore all device nodes of that type.</p>
54 <p>It will also use that path information to only ask drivers that actually
55 are in a matching module directory. In the above example of a disk driver, this
56 would be either in "busses/scsi", "busses/ide", "drivers/disk", ...</p>
58 <p>For untyped or generic busses, it will use the context information gained
59 from the devfs query directly, and will search for drivers in that sub directory
60 only. The only exception to this rule are the devfs directories "disk", "ports",
61 and "bus", which will also allow to search matching drivers in "busses". While
62 this is relatively limited, it is a good way to cut down the number of drivers
63 to be loaded.</p>
66 <h2>3. Writing a Driver</h2>
68 <p>The device manager assumes the following API from a driver module:</p>
69 <ul>
70 <li><b>supports_device()</b><br>
71 Determines wether or not the driver supports a given parent device node,
72 that is the hardware device it represents (if any), and the API the node
73 exports.</li>
74 <li><b>register_device()</b><br>
75 The driver should register its device node here. The parent driver is
76 always initialized at this point. When registering the node, the driver
77 can also attach certain I/O resources (like I/O ports, or memory ranges)
78 to the node -- the device manager will make sure that only one node can
79 claim these resources.</li>
80 <li><b>init_driver()</b><br>
81 Any initialization necessary to get the driver going. For most drivers,
82 this will be reduced to the creation of a private data structure that is
83 going to be used for all of the following functions.</li>
84 <li><b>uninit_driver()</b><br>
85 Uninitializes resources acquired by <b>init_driver()</b>.</li>
86 <li><b>register_child_devices()</b><br>
87 If the driver wants to register any child device nodes or to publish
88 any devices, it should do so here. This function is called only during
89 the initial registration process of the device node.</li>
90 <li><b>rescan_child_devices()</b><br>
91 Is called whenever a manual rescan is triggered.</li>
92 <li><b>device_removed()</b></br>
93 Is called when the device node is about to be unregistered when its
94 device is gone, for example when a USB device is unplugged.</li>
95 <li><b>suspend()</b><br>
96 Enters different sleep modes.</li>
97 <li><b>resume()</b><br>
98 Resumes a device from a previous sleep mode.</li>
99 </ul>
101 <p>To ensure that a module exports this API, it <b>must</b> end its module name
102 with "driver_v1" to denote the version of the API it supports. Note that
103 <b>suspend()</b> and <b>resume()</b> are currently never called, as Haiku has
104 no power management implemented yet.</p>
106 <p>If your driver can give the device it is attached to a nice name that can be
107 presented to the user, it should add the <b>B_DEVICE_PRETTY_NAME</b> attribute
108 to the device node.
110 <p>The <b>B_DEVICE_UNIQUE_ID</b> should be used in case the device has a unique
111 ID that can be used to identify it, and also differentiate it from other devices
112 of the same model and vendor. This information will be added to the file system
113 attributes of all devices published by your driver, so that user applications
114 can identify, say, a USB printer no matter what USB slot it is attached to, and
115 assign it additional data, like paper configuration, or recognize it as the
116 default printer.</p>
118 <p>If your driver implements an API that is used by a support or bus module, you
119 will usually use the <b>B_DEVICE_FIXED_CHILD</b> attribute to specify exactly
120 which child device node you will be talking to. If you support several child
121 nodes, you may want to have a closer look at the section explaining
122 <a href="#bus_driver">how to write a bus driver</a>.</p>
124 <p>In addition to the child nodes a driver registers itself, a driver can either
125 have dynamic children or fixed children, never both. Also, fixed children are
126 registered before <b>register_child_devices()</b> is called, while dynamic
127 children are registered afterwards.</p>
130 <h2>4. Publishing a Device</h2>
132 To publish a device entry in the device file system under <i>/dev</i>, all your
133 driver has to do is to call the
134 <pre>
135 publish_device(device_node *node, const char *path,
136 const char *deviceModuleName);
137 </pre>
138 function the device manager module exports. The <i>path</i> is the path
139 component that follows "/dev", for example "net/ipro1000/0". The
140 <i>deviceModuleName</i> is the module exporting the device functionality.
141 It should end with "device_v1" to show the device manager which protocol it
142 supports. If the device node your device belongs to is removed, your device
143 is removed automatically with it. On the other hand, you are allowed to
144 unpublish the device at any point using the <b>unpublish_device()</b> function
145 the device manager delivers for this.</p>
147 <p>A device module must export the following API:</p>
148 <ul>
149 <li><b>init_device()</b><br>
150 This is called when the open() is called on this device for the first
151 time. You may want to create a private data structure that is passed on
152 to all subsequent calls of the <b>open()</b> function that your device
153 exports.</li>
154 <li><b>uninit_device()</b><br>
155 Is called when the last file descriptor to the device had been closed.</li>
156 <li><b>device_removed()</b><br>
157 When the device node your device belongs to is going to be removed,
158 you're notified about this in this function.</li>
159 <li><b>open()</b><br>
160 Called whenever your device is opened.</li>
161 <li><b>close()</b><br>
162 </li>
163 <li><b>free()</b><br>
164 Free the private data structure you allocated in <b>open()</b>.</li>
165 <li><b>read()</b><br>
166 </li>
167 <li><b>write()</b><br>
168 </li>
169 <li><b>io()</b><br>
170 This is a replacement for the <b>read()</b>, and <b>write()</b> calls,
171 and allows, among other things, for asynchronous I/O. This functionality
172 has not yet been implemented, though (see below).</li>
173 <li><b>control()</b><br>
174 </li>
175 <li><b>select()</b><br>
176 </li>
177 <li><b>deselect()</b><br>
178 </li>
179 </ul>
182 <h2>5. <a name="bus_driver">Writing a Bus Driver</a></h2>
184 <p>A bus driver is a driver that represents a bus where one or more arbitrary
185 devices can be attached to.</p>
187 <p>There are two basic types of busses: intelligent busses like PCI or USB that
188 know a lot about the devices attached to it, like a generic device type, as
189 well as device and vendor ID information, and simple untyped/generic busses that
190 either have not all the information (like device type) or don't even know what
191 and if any devices are attached. The device manager has been written in such a
192 way that device exploration makes use of additional information the bus can
193 provide in order to find a responsible device driver faster, and with less
194 overhead.</p>
196 <h4>5.1. Writing an Intelligent Bus Driver</h4>
198 <p>If your bus knows what type of device is attached to, and also has vendor and
199 device ID information about that device, it is considered to be an intelligent
200 bus. The bus driver is supposed to have one parent node representing the bus,
201 and to create a child node for each device attached to the bus.</p>
203 <p>The additional information you have about the devices are attached to the
204 device node in the following attributes:</p>
205 <ul>
206 <li><b>B_DEVICE_VENDOR_ID</b><br>
207 The vendor ID - this ID has only to be valid in the namespace of your
208 bus.</li>
209 <li><b>B_DEVICE_ID</b><br>
210 The device ID.</li>
211 <li><b>B_DEVICE_TYPE</b><br>
212 The device type as defined by the PCI class base information.</li>
213 <li><b>B_DEVICE_SUB_TYPE</b><br>
214 The device sub type as defined by the PCI sub class information.</li>
215 <li><b>B_DEVICE_INTERFACE</b><br>
216 The device interface type as defined by the PCI class API information.</li>
217 </ul>
219 <p>You can use the <b>B_DEVICE_FLAGS</b> attribute to define how the device
220 manager finds the children of the devices you exported. For this kind of bus
221 drivers, you will usually only want to specify <b>B_FIND_CHILD_ON_DEMAND</b>
222 here, which causes the driver only to be searched when the system asks for it.
223 </p>
225 <h4>5.2. Writing a Simple Bus Driver</h4>
227 <p>A bus can be simple in a number of ways:</p>
228 <ol>
229 <li>It may not know how many or if any devices are attached to it</li>
230 <li>It cannot retrieve any type information about the devices it has, but
231 knows all devices that are attached to it</li>
232 </ol>
234 <p>An example of the latter would be the Zorro bus of the Amiga - it only has
235 information about the vendor and device ID, but no type information. It should
236 be implemented like an intelligent bus, though, with the type information simply
237 omitted.</p>
239 <p>Therefore, this section is about the former case, that is, a simple bus like
240 the ISA bus. Since it doesn't know anything about its children, it does not
241 publish any child nodes, instead, it will just specify the
242 B_FIND_MULTIPLE_CHILDREN and B_FIND_CHILD_ON_DEMAND flags for its device node.
243 Since there are no additional informations about this bus, the device manager
244 will assume a simple bus, and will try to find drivers on demand only.</p>
247 <h2>6. Open Issues</h2>
249 While most of the new device manager is fledged out, there are some areas that
250 could use improvements or are problematic under certain requirements. Also, some
251 parts just haven't been written yet.
253 <h4>6.1. generic/simple busses</h4>
255 <h4>6.2. Unpublishing</h4>
257 <h4>6.3. listdev functionality</h4>
259 The "listdev" command has been removed from the image, and it is currently not
260 functional anymore.
262 <h4>6.4. Versioning</h4>
264 <p>The way the device manager works, it makes versioning of modules (which are
265 supposed to be one of the strong points of the module system) much harder or
266 even impossible. While the device manager could introduce a new API and could
267 translate between a "driver_v1", and a "driver_v2" API on the fly, it's not
268 yet possible for a PCI sub module to do the same thing.</p>
270 <p><b>Proposed Solution:</b> Add attribute <b>B_DEVICE_ALTERNATE_VERSION</b>
271 that specifies alternate versions of the module API this device node supports.
272 We would then need a <b>request_version()</b> or <b>set_version()</b> function
273 (to be called from <b>supports_device()</b>) that allows to specify the version
274 of the parent node this device node wants to talk to.</p>
276 <h4>6.5. Unregistering Nodes</h4>
278 <h4>6.6. Support for generic drivers is missing</h4>
280 <p>This should probably be done by simply adding a simple bus driver named
281 "generic" that generic drivers need to ask for.</p>
283 <h4>6.7. Mappings, And Other Optimizations</h4>
285 <p>Due to the way the device tree is built, the device manager could remember
286 which driver served a given device node. That way, it wouldn't need to search
287 for a driver anymore, but could just pick it up. Practically, the device manager
288 should cache the type (and/or vendor/device) information of a node, and assign
289 one or more drivers (via module name) to this information. It should also
290 remember negative outcome, that is if there is no driver supporting the
291 hardware.</p>
293 <p>This way, only the first boot would require an actual search for drivers, as
294 subsequent boots would reuse the type-driver assignments. If a new driver is
295 installed, the cached assignments would need to be updated immediately. If a
296 driver has been installed outside of the running system, the device manager
297 might want to create a hash per module directory to see if anything changed to
298 flush the cache. Alternatively or additionally, the boot loader could have a
299 menu causing the cache to be ignored.</p>
301 <p>It would be nice to find a way for generic and simple busses to reduce the
302 amount of searching necessary for them. One way would be to remember which
303 driver supports which bus - but this information is currently only accessible
304 derived from what the driver does, and is therefore not reliable or complete.
305 A separately exported information would be necessary for this.</p>
307 <p>Also, when looking for a generic or simple bus driver, actual directories
308 could be omitted; currently, driver search is always recursive, as that's how
309 the module mechanism is working. Eventually, we might want to extend the
310 open_module_list_etc() call a bit more to accomplish that.</p>
312 </body>
313 </html>