FireWire Trademark
Overview of the Linux IEEE-1394 Subsystem
Google
Linux1394 Web  
Written December 1999 by Søren Thing Andersen, soeren@thing.dk.

When I first started looking at the GNU/Linux IEEE-1394 Subsystem it took me quite a while to figure out how it all fits together. So I decided to write this text, in the hope that it might make it easier for others to find their way through the code.

1.1 The driver hierarchy

In figure 1 I have sketched the driver hierarchy as it appears in my PC. The core of the entire 1394 subsystem is the module ieee1394. It manages all high- and low-level drivers in the subsystem, handles transactions, and provides a mechanism for event triggering.


Figure 1: The driver hierarchy in a simple setup.

Below the ieee1394 module are the low-level (hardware) driver modules. There are three low-level drivers to choose from:

aic5800 Adaptec AIC-5800 PCI-IEEE1394 chip driver
pcilynx Texas Instruments PCILynx driver
ohci1394 1394 Open Host Controller Interface driver

As I have an OHCI compliant card, I use the ohci1394 module to interface the 1394 card. It is possible to have all three low-level driver modules loaded and active at the same time. All the low-level drivers can control more than one card (the default maximum is four per low-level driver).

Above the ieee1394 module are the high-level driver modules1. One such high-level driver is ``raw1394'', that provides an interface for userspace applications to access the raw 1394 bus. Another high-level driver is the SBP2 driver that Mark Hatle has started working on.

To access the raw 1394 bus from userspace, you should link your applications with libraw1394, which handles the communication with the raw1394 high-level driver.

1.2 All those files....

This section lists the files in the src/linux/drivers/ieee1394 directory, and gives a short description of their content.

The raw1394 module
  raw1394.* The high-level driver ``raw1394''.
The ieee1394 module
  csr.* High-level driver handling read/write/locks for the local CSRs.
  highlevel.* Registration and management of the high-level drivers.
  ieee1394_core.* The core! All packets come through here, handling of timeouts.
  ieee1394_transactions.* Generic blocking read/write/lock functions, utility functions.
  events.* Functions to register event-handlers and dispatch events.
  hosts.* Registration and management of the low-level drivers.
The low-level driver modules
  ohci1394.* 1394 Open Host Controller Interface driver.
  aic5800.* Adaptec AIC-5800 PCI-IEEE1394 chip driver.
  pcilynx.* Texas Instruments PCILynx driver.
Miscellaneous files
  ieee1394.h Generic IEEE-1394 definitions (eg. transaction codes).
  ieee1394_types.h Includes various linux headerfiles, more defines (eg. quadlet_t).
  ieee1394_syms.c Exports symbols for module usage.
  Makefile  
  Config.in  

Many functions and structures in these files have the prefix ``hpsb_''. I took me a while to figure out that it was short for High Performance Serial Bus.

The event-framework from event.* is currently unused.

1.3 What is a high-level driver?

In the GNU/Linux IEEE-1394 Subsystem high-level drivers are routines that register themselves to the ieee1394 module by calling the function hpsb_register_highlevel. This call passes a structure containing pointers to four functions (*add_host, *remove_host, *host_reset and *iso_receive) provided by the registering high-level driver. These functions are then called when the appropriate event occurs in the underlying system, eg. *add_host is called every time a new host (a 1394 interface card) is detected and initialized, and *iso_receive is called every time isochronous data is received from the low-level drivers.

When hpsb_register_highlevel is called, *add_host is immediately called for every host already known by the ieee1394 module.

High-level drivers can also register themselves as responsible for handling read/write/lock transactions for areas of the 1394 address space on the local hosts. To do so, they must call the function hpsb_register_addrspace. This call passes a structure containing the address range and four pointers (*read, *write, *lock and *lock64) provided by the registering high-level driver. These functions are then called when the appropriate event occurs in the underlying system, eg. *read is called when the system receives a read request for an address in the specified range.

If the subsystem receives a request for an address, for which no high-level driver has registered itself, a response code of resp_address_error is returned.

When calling the two mentioned registration functions, it is allowed to let some of the pointers be null pointers. If for example only *read was non-null in a hpsp_register_addrspace call, the address range in question will be ``read only'' from the 1394 bus. Likewise, letting eg. the *iso_receive pointer in a hpsb_register_highlevel call be null will prevent the high-level driver from being called upon reception of isochronous data.

The 1394 standard uses a 64 bit address space, where the upper 16 bits represents the node-ID. High-level drivers register for the lower 48 bits of the address space. This means that a high-level driver will be called for request for the specified addresses on all the local hosts. The High-level driver can differentiate the handling of the hosts if required, as a reference to the host in question is passed along with the call.

1.4 Initializing

This section describes what happens when the modules are insmod'ed.

1.4.1 insmod ieee1394.o

The initialization function for this module is init_module in ieee1394_core.c. It only calls two functions, namely init_hpsb_highlevel and init_scr.

init_hpsb_highlevel is in highlevel.c. It prepares two standard linux doubly linked lists, hl_drivers and addr_space, that are used to handle the high-level drivers. hl_drivers is a list of the drivers that have registered themselves using hpsb_register_highlevel. addr_space is a list of the address ranges, for which high-level drivers have been registered. An address can only be handled by one high-level driver. Initially both these lists are empty.

init_csr from csr.c is called after the high-level handling has been set up. init_csr registers a high-level driver ``standard registers'' that handles the standard command and status registers, the config-ROM, the topology map and the speed map. This registration is done using hpsb_register_highlevel and hpsb_registeraddrspace.

1.4.2 insmod <lowleveldriver>

When a low-level driver is inserted, it calls hpsb_register_lowlevel from its init_module routine. Along with the call it passes a structure containing (amongst others) pointers to functions that are used for detecting, initializing and releasing hosts and for transmitting packets. hpsb_register_lowlevel is a function from hosts.c. It adds the low-level driver to its list of drivers (the list is called templates), and then detects, registers and initializes all hosts (1394 adapters) the low-level driver knows about.

After this, the subsystem is up and running. You should be able to see some messages from syslogd now (on my machine it is /var/log/messages). But to access the raw bus from userspace we still need one more module.

1.4.3 insmod raw1394

raw1394 registers itself as a high-level driver using hpsb_register_highlevel when inserted (hpsb_register_addrspace is not called, as raw1394 does not handle any portion of the 1394 address space). Then it calls register_chrdev to connect to /dev/raw1394, the character device used by libraw1394 to connect to raw1394 fra userspace.

Now the GNU/Linux IEEE-1394 Subsystem is ready to be used by applications using the libraw1394 interface, eg. gscanbus or Gnome1394.

1.5 How packets are send and received

This section is yet to be written.


Footnotes

1 Actually there is also a high-level driver inside the ieee1394 module, namely ``standard registers'' from the file csr.c.