diff --git a/en_US.ISO8859-1/books/arch-handbook/newbus/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/newbus/chapter.sgml
index 8458aec35d..3a4528b32b 100644
--- a/en_US.ISO8859-1/books/arch-handbook/newbus/chapter.sgml
+++ b/en_US.ISO8859-1/books/arch-handbook/newbus/chapter.sgml
@@ -1,363 +1,362 @@
JeroenRuigrok van der Wervenasmodai@FreeBSD.orgWritten by HitenPandyahiten@uk.FreeBSD.orgNewbusSpecial thanks to Mathew N. Dodd, Warner Losh, Bill Paul.
Daug Rabson, Mike Smith, Peter Wemm and Scott Long.This chapter explains the Newbus device framework in detail.Device DriversPurpose of a Device DriverA device driver is a software component which provides the
interface between the kernel's generic view of a peripheral
(e.g. disk, network adapter) and the actual implementation of the
peripheral. The device driver interface (DDI) is
the defined interface between the kernel and the device driver component.
Types of Device DriversThere used to be days in &unix;, and thus FreeBSD, in which there
were four types of devices defined:block device driverscharacter device driversnetwork device driverspseudo-device driversBlock devices performed in way that used
fixed size blocks [of data]. This type of driver depended on the
so called buffer cache, which had the purpose
to cache accessed blocks of data in a dedicated part of the memory.
Often this buffer cache was based on write-behind, which meant that when
data was modified in memory it got synced to disk whenever the system
did its periodical disk flushing, thus optimizing writes.Character devicesHowever, in the versions of FreeBSD 4.0 and onward the
distinction between block and character devices became non-existent.
Overview of NewbusNewbus is the implementation of a new bus
architecture based on abstraction layers which saw its introduction in
FreeBSD 3.0 when the Alpha port was imported into the source tree. It was
not until 4.0 before it became the default system to use for device
drivers. Its goals are to provide a more object oriented means of
interconnecting the various busses and devices which a host system
provides to the Operating System.Its main features include amongst others:dynamic attachingeasy modularization of driverspseudo-bussesOne of the most prominent changes is the migration from the flat and
ad-hoc system to a device tree lay-out.At the top level resides the root
device which is the parent to hang all other devices on. For each
architecture, there is typically a single child of root
which has such things as host-to-PCI bridges, etc.
attached to it. For x86, this root device is the
nexus device and for Alpha, various
different different models of Alpha have different top-level devices
corresponding to the different hardware chipsets, including
lca, apecs,
cia and tsunami.A device in the Newbus context represents a single hardware entity
in the system. For instance each PCI device is represented by a Newbus
device. Any device in the system can have children; a device which has
children is often called a bus.
Examples of common busses in the system are ISA and PCI which manage lists
of devices attached to ISA and PCI busses respectively.Often, a connection between different kinds of bus is represented by
a bridge device which normally has one
child for the attached bus. An example of this is a
PCI-to-PCI bridge which is represented by a device
pcibN on the parent PCI bus
and has a child pciN for the
attached bus. This layout simplifies the implementation of the PCI bus
tree, allowing common code to be used for both top-level and bridged
busses.Each device in the Newbus architecture asks its parent to map its
resources. The parent then asks its own parent until the nexus is
reached. So, basically the nexus is the only part of the Newbus system
which knows about all resources.An ISA device might want to map its IO port at
- 0x23c, so it asks its parent, in this case the ISA
+ 0x230, so it asks its parent, in this case the ISA
bus. The ISA bus hands it over to the PCI-to-ISA bridge which in its turn
asks the PCI bus, which reaches the host-to-PCI bridge and finally the
nexus. The beauty of this transition upwards is that there is room to
- translate the requests. For example, the 0x23c IO port
- request might become memory-mapped at 0xb000023c on a
+ translate the requests. For example, the 0x230 IO port
+ request might become memory-mapped at 0xb0000230 on a
MIPS box by the PCI bridge.Resource allocation can be controlled at any place in the device
tree. For instance on many Alpha platforms, ISA interrupts are managed
separately from PCI interrupts and resource allocations for ISA interrupts
are managed by the Alpha's ISA bus device. On IA-32, ISA and PCI
interrupts are both managed by the top-level nexus device. For both
ports, memory and port address space is managed by a single entity - nexus
for IA-32 and the relevant chipset driver on Alpha (e.g. CIA or tsunami).
In order to normalize access to memory and port mapped resources,
Newbus integrates the bus_space APIs from NetBSD.
These provide a single API to replace inb/outb and direct memory
reads/writes. The advantage of this is that a single driver can easily
use either memory-mapped registers or port-mapped registers
(some hardware supports both).This support is integrated into the resource allocation mechanism.
When a resource is allocated, a driver can retrieve the associated
bus_space_tag_t and
bus_space_handle_t from the resource.Newbus also allows for definitions of interface methods in files
dedicated to this purpose. These are the .m files
that are found under the src/sys hierarchy.The core of the Newbus system is an extensible
object-based programming model. Each device in the system
has a table of methods which it supports. The system and other devices
uses those methods to control the device and request services. The
different methods supported by a device are defined by a number of
interfaces. An interface is simply a group
of related methods which can be implemented by a device.In the Newbus system, the methods for a device are provided by the
various device drivers in the system. When a device is attached to a
driver during auto-configuration, it uses the method
table declared by the driver. A device can later
detach from its driver and
re-attach to a new driver with a new method table.
This allows dynamic replacement of drivers which can be useful for driver
development.The interfaces are described by an interface definition language
similar to the language used to define vnode operations for file systems.
The interface would be stored in a methods file (which would normally named
foo_if.m).Newbus Methods
# Foo subsystem/driver (a comment...)
INTERFACE foo
METHOD int doit {
device_t dev;
};
# DEFAULT is the method that will be used, if a method was not
# provided via: DEVMETHOD()
METHOD void doit_to_child {
device_t dev;
driver_t child;
} DEFAULT doit_generic_to_child;
When this interface is compiled, it generates a header file
foo_if.h which contains function
declarations:
int FOO_DOIT(device_t dev);
int FOO_DOIT_TO_CHILD(device_t dev, device_t child);
A source file, foo_if.c is
also created to accompany the automatically generated header file; it
contains implementations of those functions which look up the location
of the relevant functions in the object's method table and call that
function.The system defines two main interfaces. The first fundamental
interface is called device and
includes methods which are relevant to all devices. Methods in the
device interface include
probe,
attach and
detach to control detection of
hardware and shutdown,
suspend and
resume for critical event
notification.The second, more complex interface is
bus. This interface contains
methods suitable for devices which have children, including methods to
access bus specific per-device information
&man.bus.generic.read.ivar.9; and
&man.bus.generic.write.ivar.9;, event notification
(child_detached,
driver_added) and resource
management (alloc_resource,
activate_resource,
deactivate_resource,
release_resource).
Many methods in the bus interface are performing
services for some child of the bus device. These methods would normally
use the first two arguments to specify the bus providing the service
and the child device which is requesting the service. To simplify
driver code, many of these methods have accessor functions which
lookup the parent and call a method on the parent. For instance the
method
BUS_TEARDOWN_INTR(device_t dev, device_t child, ...)
can be called using the function
bus_teardown_intr(device_t child, ...).Some bus types in the system define additional interfaces to
provide access to bus-specific functionality. For instance, the PCI
bus driver defines the pci interface which has two
methods read_config and
write_config for accessing the
configuration registers of a PCI device.Newbus APIAs the Newbus API is huge, this section makes some effort at
documenting it. More information to come in the next revision of this
document.Important locations in the source hierarchysrc/sys/[arch]/[arch] - Kernel code for a
specific machine architecture resides in this directory. for example,
the i386 architecture, or the
SPARC64 architecture.src/sys/dev/[bus] - device support for a
specific [bus] resides in this directory.src/sys/dev/pci - PCI bus support code
resides in this directory.src/sys/[isa|pci] - PCI/ISA device drivers
reside in this directory. The PCI/ISA bus support code used to exist
in this directory in FreeBSD version 4.0.Important structures and type definitionsdevclass_t - This is a type definition of a
pointer to a struct devclass.device_method_t - This is same as
kobj_method_t (see
src/sys/kobj.h).device_t - This is a type definition of a
pointer to a struct device.
device_t represents a device in the system. It is
a kernel object. See src/sys/sys/bus_private.h
for implementation details.driver_t - This is a type definition which,
references struct driver. The
driver struct is a class of the
device kernel object; it also holds data private
to for the driver.A device_state_t type, which is
an enumeration, device_state. It contains
the possible states of a Newbus device before and after the
autoconfiguration process.
diff --git a/en_US.ISO8859-1/books/developers-handbook/newbus/chapter.sgml b/en_US.ISO8859-1/books/developers-handbook/newbus/chapter.sgml
index 8458aec35d..3a4528b32b 100644
--- a/en_US.ISO8859-1/books/developers-handbook/newbus/chapter.sgml
+++ b/en_US.ISO8859-1/books/developers-handbook/newbus/chapter.sgml
@@ -1,363 +1,362 @@
JeroenRuigrok van der Wervenasmodai@FreeBSD.orgWritten by HitenPandyahiten@uk.FreeBSD.orgNewbusSpecial thanks to Mathew N. Dodd, Warner Losh, Bill Paul.
Daug Rabson, Mike Smith, Peter Wemm and Scott Long.This chapter explains the Newbus device framework in detail.Device DriversPurpose of a Device DriverA device driver is a software component which provides the
interface between the kernel's generic view of a peripheral
(e.g. disk, network adapter) and the actual implementation of the
peripheral. The device driver interface (DDI) is
the defined interface between the kernel and the device driver component.
Types of Device DriversThere used to be days in &unix;, and thus FreeBSD, in which there
were four types of devices defined:block device driverscharacter device driversnetwork device driverspseudo-device driversBlock devices performed in way that used
fixed size blocks [of data]. This type of driver depended on the
so called buffer cache, which had the purpose
to cache accessed blocks of data in a dedicated part of the memory.
Often this buffer cache was based on write-behind, which meant that when
data was modified in memory it got synced to disk whenever the system
did its periodical disk flushing, thus optimizing writes.Character devicesHowever, in the versions of FreeBSD 4.0 and onward the
distinction between block and character devices became non-existent.
Overview of NewbusNewbus is the implementation of a new bus
architecture based on abstraction layers which saw its introduction in
FreeBSD 3.0 when the Alpha port was imported into the source tree. It was
not until 4.0 before it became the default system to use for device
drivers. Its goals are to provide a more object oriented means of
interconnecting the various busses and devices which a host system
provides to the Operating System.Its main features include amongst others:dynamic attachingeasy modularization of driverspseudo-bussesOne of the most prominent changes is the migration from the flat and
ad-hoc system to a device tree lay-out.At the top level resides the root
device which is the parent to hang all other devices on. For each
architecture, there is typically a single child of root
which has such things as host-to-PCI bridges, etc.
attached to it. For x86, this root device is the
nexus device and for Alpha, various
different different models of Alpha have different top-level devices
corresponding to the different hardware chipsets, including
lca, apecs,
cia and tsunami.A device in the Newbus context represents a single hardware entity
in the system. For instance each PCI device is represented by a Newbus
device. Any device in the system can have children; a device which has
children is often called a bus.
Examples of common busses in the system are ISA and PCI which manage lists
of devices attached to ISA and PCI busses respectively.Often, a connection between different kinds of bus is represented by
a bridge device which normally has one
child for the attached bus. An example of this is a
PCI-to-PCI bridge which is represented by a device
pcibN on the parent PCI bus
and has a child pciN for the
attached bus. This layout simplifies the implementation of the PCI bus
tree, allowing common code to be used for both top-level and bridged
busses.Each device in the Newbus architecture asks its parent to map its
resources. The parent then asks its own parent until the nexus is
reached. So, basically the nexus is the only part of the Newbus system
which knows about all resources.An ISA device might want to map its IO port at
- 0x23c, so it asks its parent, in this case the ISA
+ 0x230, so it asks its parent, in this case the ISA
bus. The ISA bus hands it over to the PCI-to-ISA bridge which in its turn
asks the PCI bus, which reaches the host-to-PCI bridge and finally the
nexus. The beauty of this transition upwards is that there is room to
- translate the requests. For example, the 0x23c IO port
- request might become memory-mapped at 0xb000023c on a
+ translate the requests. For example, the 0x230 IO port
+ request might become memory-mapped at 0xb0000230 on a
MIPS box by the PCI bridge.Resource allocation can be controlled at any place in the device
tree. For instance on many Alpha platforms, ISA interrupts are managed
separately from PCI interrupts and resource allocations for ISA interrupts
are managed by the Alpha's ISA bus device. On IA-32, ISA and PCI
interrupts are both managed by the top-level nexus device. For both
ports, memory and port address space is managed by a single entity - nexus
for IA-32 and the relevant chipset driver on Alpha (e.g. CIA or tsunami).
In order to normalize access to memory and port mapped resources,
Newbus integrates the bus_space APIs from NetBSD.
These provide a single API to replace inb/outb and direct memory
reads/writes. The advantage of this is that a single driver can easily
use either memory-mapped registers or port-mapped registers
(some hardware supports both).This support is integrated into the resource allocation mechanism.
When a resource is allocated, a driver can retrieve the associated
bus_space_tag_t and
bus_space_handle_t from the resource.Newbus also allows for definitions of interface methods in files
dedicated to this purpose. These are the .m files
that are found under the src/sys hierarchy.The core of the Newbus system is an extensible
object-based programming model. Each device in the system
has a table of methods which it supports. The system and other devices
uses those methods to control the device and request services. The
different methods supported by a device are defined by a number of
interfaces. An interface is simply a group
of related methods which can be implemented by a device.In the Newbus system, the methods for a device are provided by the
various device drivers in the system. When a device is attached to a
driver during auto-configuration, it uses the method
table declared by the driver. A device can later
detach from its driver and
re-attach to a new driver with a new method table.
This allows dynamic replacement of drivers which can be useful for driver
development.The interfaces are described by an interface definition language
similar to the language used to define vnode operations for file systems.
The interface would be stored in a methods file (which would normally named
foo_if.m).Newbus Methods
# Foo subsystem/driver (a comment...)
INTERFACE foo
METHOD int doit {
device_t dev;
};
# DEFAULT is the method that will be used, if a method was not
# provided via: DEVMETHOD()
METHOD void doit_to_child {
device_t dev;
driver_t child;
} DEFAULT doit_generic_to_child;
When this interface is compiled, it generates a header file
foo_if.h which contains function
declarations:
int FOO_DOIT(device_t dev);
int FOO_DOIT_TO_CHILD(device_t dev, device_t child);
A source file, foo_if.c is
also created to accompany the automatically generated header file; it
contains implementations of those functions which look up the location
of the relevant functions in the object's method table and call that
function.The system defines two main interfaces. The first fundamental
interface is called device and
includes methods which are relevant to all devices. Methods in the
device interface include
probe,
attach and
detach to control detection of
hardware and shutdown,
suspend and
resume for critical event
notification.The second, more complex interface is
bus. This interface contains
methods suitable for devices which have children, including methods to
access bus specific per-device information
&man.bus.generic.read.ivar.9; and
&man.bus.generic.write.ivar.9;, event notification
(child_detached,
driver_added) and resource
management (alloc_resource,
activate_resource,
deactivate_resource,
release_resource).
Many methods in the bus interface are performing
services for some child of the bus device. These methods would normally
use the first two arguments to specify the bus providing the service
and the child device which is requesting the service. To simplify
driver code, many of these methods have accessor functions which
lookup the parent and call a method on the parent. For instance the
method
BUS_TEARDOWN_INTR(device_t dev, device_t child, ...)
can be called using the function
bus_teardown_intr(device_t child, ...).Some bus types in the system define additional interfaces to
provide access to bus-specific functionality. For instance, the PCI
bus driver defines the pci interface which has two
methods read_config and
write_config for accessing the
configuration registers of a PCI device.Newbus APIAs the Newbus API is huge, this section makes some effort at
documenting it. More information to come in the next revision of this
document.Important locations in the source hierarchysrc/sys/[arch]/[arch] - Kernel code for a
specific machine architecture resides in this directory. for example,
the i386 architecture, or the
SPARC64 architecture.src/sys/dev/[bus] - device support for a
specific [bus] resides in this directory.src/sys/dev/pci - PCI bus support code
resides in this directory.src/sys/[isa|pci] - PCI/ISA device drivers
reside in this directory. The PCI/ISA bus support code used to exist
in this directory in FreeBSD version 4.0.Important structures and type definitionsdevclass_t - This is a type definition of a
pointer to a struct devclass.device_method_t - This is same as
kobj_method_t (see
src/sys/kobj.h).device_t - This is a type definition of a
pointer to a struct device.
device_t represents a device in the system. It is
a kernel object. See src/sys/sys/bus_private.h
for implementation details.driver_t - This is a type definition which,
references struct driver. The
driver struct is a class of the
device kernel object; it also holds data private
to for the driver.A device_state_t type, which is
an enumeration, device_state. It contains
the possible states of a Newbus device before and after the
autoconfiguration process.