IEEE 1394 and Linux

The FireWire Serial Bus and its Implementation

Introduction

In the mid 1980s, Apple Computer began development of a new
serial bus architecture called FireWire.It was designed to address several issues related to current and
upcoming technology:

Parallel
buses are expensive.Apple chose
to instead create a serial bus that has massive bandwidth capabilities.

There
was expected to be an increased market in consumer electronics, and Apple
wanted a standardized interconnection mechanism for them.

They
wanted the devices on the bus to be self-configurable (Plug and Play)
immediately upon connection to the bus.

Operation
of the entire bus should be independent of the host system, eliminating
the host processor and memory bottleneck.

They
also wanted support for reserved bus bandwidth (termed “isochronous” by
the standard)

FireWire devices are generally multimedia based; examples
are Digital Cameras and Camcorders, Digital VCRs, and Pro-audio equipment like
DAT stations and other multi-track recorders.However, they can also be general PC peripherals like Hard Disk Drives,
CD-ROM/DVD Drives, and Laser Printers.

Apple’s work caught the eyes of other vendors and an IEEE
committee was formed to create a formal standard.This paper explains the concepts created by the resulting IEEE
1394-1995 specification and also explains the data structures and algorithms
used by the FireWire subsystem in the 2.3.99-pre6 Linux kernel.

Terminology

The 1394 specification creates a light amount of terminology
that must be discussed before jumping into the technical details.A module is one physical device
attached to the bus, containing at least one node.Generally physical devices are multimedia based; examples are
digital cameras, digital camcorders, digital VCRs, and pro-audio equipment like
DAT stations and other multi-track recorders.However, they can also be general PC peripherals like hard disk drives,
CD-ROM/DVD drives, and laser printers.A node is a logical entity within a module.Devices on the bus are addressed at the node
level.A unit is a functional
subcomponent of a node that can identify processing, memory, or I/O
functionality.Units of a node generally
operate independently (they have their own drivers) but may share registers
with each other.Figure 1 shows the
internal architecture of a module.A port
is a point of I/O within a node (where the node plugs into the bus).As shown in the Figure 2, nodes can be
single or multi-ported.Packets are
transferred in a peer-to-peer fashion, so when a multiport node receives a
packet, it is retransmitted over its other ports.Each time a device is plugged into or unplugged from the bus, the
entire bus topology is reconfigured.Each bus can be viewed as a tree of devices with one and only one
root.The device at the root of the
tree is the root node.

Bus Transfers

In Isochronous
Transfer Mode best-effort delivery is used to deliver data across the
bus at a constant rate

The transfer type is dependent on the nature of the data
being moved around.For example, if you
wanted to stream video from a digital camera to the Internet, you would use an
isochronous transfer because the necessary bandwidth is known a priori and the
data needs to be sent at constant intervals.However, if you were simply copying the data from a CD-ROM to a hard
drive you would use the asynchronous transfer mode because you don’t want to
lose any information during the copy.These two transfer types have direct analogs in the socket-programming
world; isochronous transfers are analogous to communication over a datagram
socket and asynchronous transfers are analogous to communication over a stream
socket.

Bus Arbitration

When a node wishes to transmit a packet on the bus it needs
to request permission to do so.The
procedure for determining which node gets control of the bus is known as arbitration.There are two different kinds of arbitration
depending on what kinds of nodes are on the bus: arbitration with only
asynchronous devices and arbitration with isochronous devices.If isochronous devices are present,
arbitration is handled the same whether or not any asynchronous devices are
present.

Asynchronous-only
arbitration is based on fair scheduling with priorities.After a 20μs gap (bus idle time) a new
“arbitration round” starts.If a node
wishes to transmit, it sends an arbitration request, which propagates up to the
root node.If multiple nodes request
arbitration at the same time, the node closest to the root node wins
arbitration.If the nodes requesting
arbitration are the same distance from the root node, then the node connecting
to the lowest numbered root port wins arbitration.Each node can speak at most once during a given arbitration
round.After a 10μs gap the
remaining nodes arbitrate for their turn to use the bus; this continues until
all nodes that wish to use the bus during that round have used it.Following another 20μs gap a new round
starts over.

The
arbitration mechanism gets more complicated when isochronous devices are
connected on the bus, because those devices have already been guaranteed
bandwidth.Each arbitration round is
approximately 125μs long, so bandwidth is allocated as a portion of the
125μs interval.The root node
broadcasts (sends a message to node 63, the broadcast address) a cycle start
packet, which begins the arbitration round.All interested nodes send an arbitration request as before, and
the winning node is still the node closest to the root.After .04μs of bus idle time, the
remaining nodes arbitrate for control of the bus.Once each isochronous node has completed its transaction the time
remaining in the 125μs interval is used for asynchronous
transactions.Up to 80% of the bus
bandwidth may be allocated to isochronous transactions and the remaining 20% is
left available for asynchronous transactions.

Linux Background

Support for IEEE 1394 began with Linux kernel version 2.3.99
as part of the mainstream kernel, though patches are available for version
2.2.14.The project is still under
development, though the current implementation is fairly complete and
stable.The general subsystem is
maintained by Andreas Bombe while others maintain the individual device drivers
for supported PCI cards.

Host Data Structures and Architecture

Two main data structures define the Linux host architecture:
hpsb_host and hpsb_host_template.The hpsb_host_template structure is filled in and
registered with Linux by each host device driver.There is exactly one instance of a host template per host type
(i.e. PCI Lynx, Adaptec 5800, etc.).This structure holds function pointers for dealing with hosts on the
system, such as detecting hosts, initializing them, releasing them,
transmitting packets, etc.The hpsb_host
structure serves to store information about a particular host.The most important field is a pointer to the
hpsb_host_template that represents the type of host the structure is
representing.Other fields stored in hpsb_host
include the host’s node id, the bus manager’s id, a list of pending packets,
etc.Figure 4 shows how these
structures interact with one another in the system.

Figure 4.Interaction of Host Related Data Structures

High Level Callbacks

The IEEE 1394 subsystem provides a callback mechanism for
interaction with the bus.Two important
data structures exist that allow users to register callback functions with the
system to be called when certain events occur: hpsb_highlevel_ops and hpsb_address_ops.The first of these structures contains
functions for host-level operations.These functions are called by the system when, for example, a host is
added or removed, or when an isochronous packet is received.The second structure allows users to provide
operations related to a specific address range.The functions provided include read, write, and lock.When a device on the bus attempts to read or
write an address in the range specified for a particular hpsb_address_ops,
the function in that structure is called by the system.

High Level Operations

The high level callbacks are provided for when the bus
wishes to interact with the system.When the system wishes to interact with the bus, however, it must use
the high level operations provided by the IEEE 1394 subsystem.Many of the high level operations provided
by the Linux subsystem mirror those of the high level callbacks. For example, there are functions to read,
write, add a host, remove a host, listen on an isochronous channel, etc.

RAW1394

The IEEE 1394 subsystem in Linux provides a convenient
interface to the bus in the form of the raw1394 module.The raw1394 module is both a hpsb_highlevel_ops
and a character device.Being an hpsb_highlevel_ops
allows the module to know about all hosts that exist on the system so that
users can access all buses available on the system.As a character device, raw1394 provides the standard fops
functions that allow reading, writing, etc.Reading and writing are accomplished in a slightly different manner than
is traditionally used for character devices.There is a data structure, raw1394_request, which has data
members for all important information regarding an IEEE 1394 transaction
including type, address, and buffers for the actual data.An instance of this structure is passed to
the read and write methods instead of actual buffers of data as is
traditionally done.

Summary and Conclusion

The IEEE 1394 subsystem allows high speed devices to be
interconnected independent of the host system, processor, memory, etc.It provides for both guaranteed bandwidth
and guaranteed delivery type transactions via a simple, fairness based arbitration
system.The Linux implementation
supports all of the features of the IEEE 1394 subsystem in a simple to use
manner that is consistent with current support for other subsystems and
architectures.
References