Forth Lesson 11

From OLPC
Revision as of 07:49, 22 April 2007 by Wmb@firmworks.com (talk | contribs) (Forth lesson 11)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Review

In the previous lesson, we learned:

  • That a device node can have executable "methods" that are its device driver
  • The names of a few standard methods
  • That some nodes are "support packages" used by other drivers
  • That some nodes contain information about OFW in general

Device Instances

A device driver - the set of methods in the device node - can maintain private data expressing the current state of the device. It is possible for several instances of a given driver to be active simultaneously. The private data can be either per-instance or per-driver.

Before you can use the driver, you have to open it. The opening process allocates and initializes storage for the per-instance data and then calls the node's "open" method, which does whatever device-specific work is necessary. An "instance handle" is thereby created. The instance handle is a reference number that is subsequently used to call the node's other methods. It lets the system establish the correct context in which those methods execute, e.g. so they can get to the private data.

Instance Chains

A device driver usually needs help from other devices, particularly those bus bridges that attach it to the system. For example, a USB mass storage driver needs help from the USB host bridge, while the USB host bridge in turn needs help from a PCI bridge to which it is attached.

The device tree structure is designed so that these dependencies "flow up the tree". A device driver can request services from its direct parent, which can request services from the grandparent, and so on. Each node is responsible for providing all the services its children need, thus isolating an individual driver from global system knowledge. This makes drivers very portable across OFW systems.

In the example above, the mass storage driver needs help from the USB host bridge, so you can't open the former until the latter is open. Similarly, the PCI bridge driver must be opened before the USB host bridge driver is open, and so on until you reach the driver at the root of the tree, which must be self-sufficient.

So the overall process of opening a device driver must start at the root of the device tree, opening each path component in order, until the final device is open. At each step, the next device can call the methods of its parent, which is already open. During the process, OFW creates an "instance chain", whereby each device instance is linked to an open instance of its parent. The final instance handle refers to the final device, but that is implicitly linked to the rest of the chain.

Closing a device proceeds in reverse order, calling first the "close" method of the final device, deallocating its per-instance data, then proceeding up the chain.

Instance Arguments

So far we have seen that a pathname can look like:

  /pci/usb@f,5/scsi/disk@1

But there in an addition wrinkle that can be added - arguments:

  /pci/usb@f,5:debug/scsi/disk@1:\tmp\log

In this example, "debug" is an argument to the "usb" node and "\tmp\log" is an argument to the "disk" node. Arguments can be arbitrary text strings, except that they cannot contain '/', which would interfere with the overall parsing of the pathname. (Now you know why OFW file pathnames must use '\' instead of '/'.) The argument string is made available to the node's methods, which can interpret it any way they want to.

Arguments work with devaliases too. If you have

  devalias com1 /pci/isa/uart@i3f8

and you write

  com1:38400

that is expanded to

  /pci/isa/uart@i3f8:38400

If you want to attach an argument to an interior component of an existing devalias, you would have to either use the pathname or make a new devalias, such as:

  devalias newcom /pci:debug/isa/uart@i3f8

Thus endeth the lesson