From 30f7fc408b9320f9b5b25060abd546d15a80ae16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 2 Jun 2008 15:45:22 +0000 Subject: [PATCH] An early version of an introduction to the new device manager. Will be expanded more over the following days, and published on the website. Comments welcome! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25760 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/device_manager_introduction.html | 249 ++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 docs/develop/kernel/device_manager_introduction.html diff --git a/docs/develop/kernel/device_manager_introduction.html b/docs/develop/kernel/device_manager_introduction.html new file mode 100644 index 0000000000..6fa69c2878 --- /dev/null +++ b/docs/develop/kernel/device_manager_introduction.html @@ -0,0 +1,249 @@ + + + +

Introduction to Haiku's Device Driver Architecture

+ +

This document tries to give you a short introduction into the new device +manager, and how to write drivers for it. Haiku still supports the legacy +device driver architecture introduced with BeOS.

+ +

The new device driver architecture of Haiku is still a moving target, +although most of its details are already specificed.

+ + +

1. The Basics

+ +

The device manager functionality builds upon device_node objects. +Every driver in the system publishes one or more of such nodes, building a +tree of device nodes. This tree is in theory a dynamic representation of the +current hardware devices in the system, but in practice will also contain +implementation specific details; since every node comes with an API specific +to that node, you'll find device nodes that only come with a number of support +functions for a certain class of drivers.

+ +

Structurally, a device_node is a set of a module, attributes, +and resources, as well as a parent and children. At a minimum, a node must +have a module, all other components are optional.

+ +TODO: picture of the device node tree + +

When the system starts, there is only a root node registered. Only primary +hardware busses register with the root node, such as PCI, and ISA on x86. +Since the PCI bus is an intelligent bus, it knows what hardware is installed, +and registers a child node for each device on the bus.

+ +

Every driver can also publish a device in /dev for communication with +userland applications. All drivers and devices are kernel modules.

+ + +

2. Exploring the Device Tree

+ +

So how does it all work? When building the initial device tree, the system only +explores a minimum of device drivers only, resulting in a tree that basically +only shows the hardware found in the computer.

+ +

Now, if the system requires disk access, it will scan the device file system +for a driver that provides such functionality, in this case, it will look for +drivers under "/dev/disk/". The device manager has a set of built-in rules for +how to translate a device path into a device node, and vice versa: every node +representing a device of an intelligent bus (such as PCI) will also contain +device type information following the PCI definitions. In this case, the "disk" +sub-path will translate into the PCI_mass_storage type, and hence, the +device manager will then completely explore all device nodes of that type.

+ +

It will also use that path information to only ask drivers that actually +are in a matching module directory. In the above example of a disk driver, this +would be either in "busses/scsi", "busses/ide", "drivers/disk", ...

+ +TODO: untyped/generic busses are not yet supported! + + +

3. Writing a Driver

+ +

The device manager assumes the following API from a driver module:

+ +

To ensure that a module exports this API, it must end its module name +with "driver_v1" to denote the version of the API it supports. Note that +suspend() and resume() are currently never called, as Haiku has +no power management implemented yet.

+ +

If your driver can give the device it is attached to a nice name that can be +presented to the user, it should add the B_DEVICE_PRETTY_NAME attribute +to the device node. +

The B_DEVICE_UNIQUE_ID should be used in case the device has a unique +ID that can be used to identify it, and also differentiate it from other devices +of the same model and vendor. This information will be added to the file system +attributes of all devices published by your driver, so that user applications +can identify, say, a USB printer no matter what USB slot it is attached to, and +assign it additional data, like paper configuration, or recognize it as the +default printer.

+

If your driver implements an API that is used by a support or bus module, you +will usually use the B_DEVICE_FIXED_CHILD attribute to specify exactly +which child device node you will be talking to. If you support several child +nodes, you may want to have a closer look at the section explaining +how to write a bus driver.

+ + +

4. Publishing a Device

+ +To publish a device entry in the device file system under /dev, all your +driver has to do is to call the +
+	publish_device(device_node *node, const char *path,
+		const char *deviceModuleName);
+
+function the device manager module exports. The path is the path +component that follows "/dev", for example "net/ipro1000/0". The +deviceModuleName is the module exporting the device functionality. +It should end with "device_v1" to show the device manager which protocol it +supports. If the device node your device belongs to is removed, your device +is removed automatically with it. On the other hand, you are allowed to +unpublish the device at any point using the unpublish_device() function +the device manager delivers for this.

+ +

A device module must export the following API:

+ + + +

5. Writing a Bus Driver

+ +

A bus driver is a driver that represents a bus where one or more arbitrary +devices can be attached to.

+ +

There are two basic types of busses: intelligent busses like PCI or USB that +know a lot about the devices attached to it, like a generic device type, as +well as device and vendor ID information, and simple untyped/generic busses that +either have not all the information (like device type) or don't even know what +and if any devices are attached. The device manager has been written in such a +way that device exploration makes use of additional information the bus can +provide in order to find a responsible device driver faster, and with less +overhead.

+ +

5.1. Writing an Intelligent Bus Driver

+ +

If your bus knows what type of device is attached to, and also has vendor and +device ID information about that device, it is considered to be an intelligent +bus. The bus driver is supposed to have one parent node representing the bus, +and to create a child node for each device attached to the bus.

+ +

The additional information you have about the devices are attached to the +device node in the following attributes:

+ + +

You can use the B_DEVICE_FLAGS attribute to define how the device +manager finds the children of the devices you exported. For this kind of bus +drivers, you will usually only want to specify B_FIND_CHILD_ON_DEMAND +here, which causes the driver only to be searched when the system asks for it. +

+ +

5.2. Writing a Simple Bus Driver

+ +TODO: support for these drivers is still missing! + + +

6. Open Issues

+ +While most of the new device manager is fledged out, there are some areas that +could use improvements or are problematic under certain requirements. Also, some +parts just haven't been written yet. + +

6.1. generic/simple busses

+ +

6.2. Unpublishing

+ +

6.3. listdev functionality

+ +The "listdev" command has been removed from the image, and it is currently not +functional anymore. + +

6.4. Versioning

+ +

The way the device manager works, it makes versioning of modules (which are +supposed to be one of the strong points of the module system) much harder or +even impossible. While the device manager could introduce a new API and could +translate between a "driver_v1", and a "driver_v2" API on the fly, it's not +yet possible for a PCI sub module to do the same thing.

+ +

Proposed Solution: Add attribute B_DEVICE_ALTERNATE_VERSION +that specifies alternate versions of the module API this device node supports. +We would then need a request_version() or set_version() function +(to be called from supports_device()) that allows to specify the version +of the parent node this device node wants to talk to.

+ +

6.5. Unregistering Nodes

+ + +