Whitespace-only changes to fix indentation, remove trailing whitespace,
and wrap long lines. Translators: none of these changes affect content, and can be ignored for translation purposes. Approved by: gjb (mentor)
This commit is contained in:
parent
f232f53d9b
commit
3cb17c52b0
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=38148
1 changed files with 283 additions and 244 deletions
|
@ -6,94 +6,105 @@
|
|||
Date: newbus-draft.txt,v 1.8 2001/01/25 08:01:08
|
||||
Copyright (c) 2000 Jeroen Ruigrok van der Warven (asmodai@wxs.nl)
|
||||
Copyright (c) 2002 Hiten Mahesh Pandya (hiten@uk.FreeBSD.org)
|
||||
|
||||
|
||||
Future Additions:
|
||||
|
||||
|
||||
o Expand the information about device_t
|
||||
o Add information about the bus_* functions.
|
||||
o Add information about bus specific (e.g. PCI) functions.
|
||||
o Add a reference section for additional information.
|
||||
o Add more newbus related structures and typedefs.
|
||||
o Add a 'Terminology' section.
|
||||
o Add information on resource manager functions, busspace
|
||||
o Add information on resource manager functions, busspace
|
||||
manager functions, newbus events related functions.
|
||||
o More cleanup ... !
|
||||
|
||||
|
||||
Provided under the FreeBSD Documentation License.
|
||||
-->
|
||||
<chapter id="newbus">
|
||||
<chapterinfo>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Jeroen</firstname>
|
||||
<surname>Ruigrok van der Werven (asmodai)</surname>
|
||||
<affiliation><address><email>asmodai@FreeBSD.org</email></address>
|
||||
</affiliation>
|
||||
<contrib>Written by </contrib>
|
||||
<firstname>Jeroen</firstname>
|
||||
<surname>Ruigrok van der Werven (asmodai)</surname>
|
||||
<affiliation>
|
||||
<address><email>asmodai@FreeBSD.org</email></address>
|
||||
</affiliation>
|
||||
<contrib>Written by </contrib>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Hiten</firstname>
|
||||
<firstname>Hiten</firstname>
|
||||
<surname>Pandya</surname>
|
||||
<affiliation><address><email>hiten@uk.FreeBSD.org</email></address>
|
||||
<affiliation>
|
||||
<address><email>hiten@uk.FreeBSD.org</email></address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
</chapterinfo>
|
||||
<title>Newbus</title>
|
||||
|
||||
<para><emphasis>Special thanks to Matthew N. Dodd, Warner Losh, Bill Paul,
|
||||
Doug Rabson, Mike Smith, Peter Wemm and Scott Long</emphasis>.</para>
|
||||
<para><emphasis>Special thanks to Matthew N. Dodd, Warner Losh, Bill
|
||||
Paul, Doug Rabson, Mike Smith, Peter Wemm and Scott
|
||||
Long</emphasis>.</para>
|
||||
|
||||
<para>This chapter explains the Newbus device framework in
|
||||
detail.</para>
|
||||
|
||||
<para>This chapter explains the Newbus device framework in detail.</para>
|
||||
<sect1 id="newbus-devdrivers">
|
||||
<title>Device Drivers</title>
|
||||
|
||||
<sect2>
|
||||
<title>Purpose of a Device Driver</title>
|
||||
|
||||
<indexterm><primary>device driver</primary></indexterm>
|
||||
<indexterm><primary>device driver</primary><secondary>introduction</secondary></indexterm>
|
||||
<para>A 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 <emphasis>device driver interface (DDI)</emphasis> is
|
||||
the defined interface between the kernel and the device driver component.
|
||||
</para>
|
||||
|
||||
<indexterm><primary>device
|
||||
driver</primary><secondary>introduction</secondary></indexterm>
|
||||
|
||||
<para>A 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 <emphasis>device driver interface
|
||||
(DDI)</emphasis> is the defined interface between the kernel
|
||||
and the device driver component.</para>
|
||||
</sect2>
|
||||
|
||||
|
||||
<sect2>
|
||||
<title>Types of Device Drivers</title>
|
||||
<para>There used to be days in &unix;, and thus FreeBSD, in which there
|
||||
were four types of devices defined:</para>
|
||||
|
||||
|
||||
<para>There used to be days in &unix;, and thus FreeBSD, in
|
||||
which there were four types of devices defined:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>block device drivers</para></listitem>
|
||||
<listitem><para>character device drivers</para></listitem>
|
||||
<listitem><para>network device drivers</para></listitem>
|
||||
<listitem><para>pseudo-device drivers</para></listitem>
|
||||
<listitem><para>block device drivers</para></listitem>
|
||||
<listitem><para>character device drivers</para></listitem>
|
||||
<listitem><para>network device drivers</para></listitem>
|
||||
<listitem><para>pseudo-device drivers</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
<indexterm><primary>block devices</primary></indexterm>
|
||||
|
||||
<para><emphasis>Block devices</emphasis> performed in way that used
|
||||
fixed size blocks [of data]. This type of driver depended on the
|
||||
so called <emphasis>buffer cache</emphasis>, 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.</para>
|
||||
<para><emphasis>Block devices</emphasis> performed in way that
|
||||
used fixed size blocks [of data]. This type of driver
|
||||
depended on the so called <emphasis>buffer cache</emphasis>,
|
||||
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.</para>
|
||||
</sect2>
|
||||
|
||||
|
||||
<sect2>
|
||||
<title>Character devices</title>
|
||||
|
||||
<indexterm><primary>character devices</primary></indexterm>
|
||||
|
||||
<para>However, in the versions of FreeBSD 4.0 and onward the
|
||||
distinction between block and character devices became non-existent.
|
||||
</para>
|
||||
distinction between block and character devices became
|
||||
non-existent.</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="newbus-overview">
|
||||
<!--
|
||||
Real title:
|
||||
|
@ -101,118 +112,133 @@
|
|||
-->
|
||||
<title>Overview of Newbus</title>
|
||||
|
||||
<indexterm><primary>Newbus</primary></indexterm>
|
||||
<indexterm><primary>Newbus</primary></indexterm>
|
||||
|
||||
<para><emphasis>Newbus</emphasis> 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
|
||||
<emphasis>Operating System</emphasis>.</para>
|
||||
|
||||
<para><emphasis>Newbus</emphasis> 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 <emphasis>Operating System</emphasis>.</para>
|
||||
|
||||
<para>Its main features include amongst others:</para>
|
||||
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>dynamic attaching</para></listitem>
|
||||
<listitem><para>easy modularization of drivers</para></listitem>
|
||||
<listitem><para>pseudo-busses</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>One of the most prominent changes is the migration from the flat and
|
||||
ad-hoc system to a device tree lay-out.</para>
|
||||
|
||||
<para>At the top level resides the <emphasis><quote>root</quote></emphasis>
|
||||
device which is the parent to hang all other devices on. For each
|
||||
architecture, there is typically a single child of <quote>root</quote>
|
||||
which has such things as <emphasis>host-to-PCI bridges</emphasis>, etc.
|
||||
attached to it. For x86, this <quote>root</quote> device is the
|
||||
<emphasis><quote>nexus</quote></emphasis> device and for Alpha, various
|
||||
different different models of Alpha have different top-level devices
|
||||
corresponding to the different hardware chipsets, including
|
||||
<emphasis>lca</emphasis>, <emphasis>apecs</emphasis>,
|
||||
<emphasis>cia</emphasis> and <emphasis>tsunami</emphasis>.</para>
|
||||
|
||||
<para>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 <emphasis><quote>bus</quote></emphasis>.
|
||||
Examples of common busses in the system are ISA and PCI which manage lists
|
||||
of devices attached to ISA and PCI busses respectively.</para>
|
||||
|
||||
<para>Often, a connection between different kinds of bus is represented by
|
||||
a <emphasis><quote>bridge</quote></emphasis> device which normally has one
|
||||
child for the attached bus. An example of this is a
|
||||
<emphasis>PCI-to-PCI bridge</emphasis> which is represented by a device
|
||||
<emphasis><devicename>pcibN</devicename></emphasis> on the parent PCI bus
|
||||
and has a child <emphasis><devicename>pciN</devicename></emphasis> 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.</para>
|
||||
|
||||
<para>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.</para>
|
||||
|
||||
<tip><para>An ISA device might want to map its IO port at
|
||||
<literal>0x230</literal>, 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 <literal>0x230</literal> IO port
|
||||
request might become memory-mapped at <literal>0xb0000230</literal> on a
|
||||
<acronym>MIPS</acronym> box by the PCI bridge.</para></tip>
|
||||
|
||||
<para>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).
|
||||
</para>
|
||||
|
||||
<para>In order to normalize access to memory and port mapped resources,
|
||||
Newbus integrates the <literal>bus_space</literal> 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).</para>
|
||||
|
||||
<para>This support is integrated into the resource allocation mechanism.
|
||||
When a resource is allocated, a driver can retrieve the associated
|
||||
<structfield>bus_space_tag_t</structfield> and
|
||||
<structfield>bus_space_handle_t</structfield> from the resource.</para>
|
||||
|
||||
<para>Newbus also allows for definitions of interface methods in files
|
||||
dedicated to this purpose. These are the <filename>.m</filename> files
|
||||
that are found under the <filename>src/sys</filename> hierarchy.</para>
|
||||
|
||||
<para>The core of the Newbus system is an extensible
|
||||
<quote>object-based programming</quote> 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
|
||||
<quote>interfaces</quote>. An <quote>interface</quote> is simply a group
|
||||
of related methods which can be implemented by a device.</para>
|
||||
|
||||
<para>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 <emphasis>auto-configuration</emphasis>, it uses the method
|
||||
table declared by the driver. A device can later
|
||||
<emphasis>detach</emphasis> from its driver and
|
||||
<emphasis>re-attach</emphasis> to a new driver with a new method table.
|
||||
This allows dynamic replacement of drivers which can be useful for driver
|
||||
development.</para>
|
||||
|
||||
<para>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
|
||||
<filename>foo_if.m</filename>).</para>
|
||||
|
||||
|
||||
<para>One of the most prominent changes is the migration from the
|
||||
flat and ad-hoc system to a device tree lay-out.</para>
|
||||
|
||||
<para>At the top level resides the
|
||||
<emphasis><quote>root</quote></emphasis> device which is the
|
||||
parent to hang all other devices on. For each architecture,
|
||||
there is typically a single child of <quote>root</quote> which
|
||||
has such things as <emphasis>host-to-PCI bridges</emphasis>,
|
||||
etc. attached to it. For x86, this <quote>root</quote> device
|
||||
is the <emphasis><quote>nexus</quote></emphasis> device and for
|
||||
Alpha, various different different models of Alpha have
|
||||
different top-level devices corresponding to the different
|
||||
hardware chipsets, including <emphasis>lca</emphasis>,
|
||||
<emphasis>apecs</emphasis>, <emphasis>cia</emphasis> and
|
||||
<emphasis>tsunami</emphasis>.</para>
|
||||
|
||||
<para>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
|
||||
<emphasis><quote>bus</quote></emphasis>. Examples of common
|
||||
busses in the system are ISA and PCI which manage lists of
|
||||
devices attached to ISA and PCI busses respectively.</para>
|
||||
|
||||
<para>Often, a connection between different kinds of bus is
|
||||
represented by a <emphasis><quote>bridge</quote></emphasis>
|
||||
device which normally has one child for the attached bus. An
|
||||
example of this is a <emphasis>PCI-to-PCI bridge</emphasis>
|
||||
which is represented by a device
|
||||
<emphasis><devicename>pcibN</devicename></emphasis> on the
|
||||
parent PCI bus and has a child
|
||||
<emphasis><devicename>pciN</devicename></emphasis> 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.</para>
|
||||
|
||||
<para>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.</para>
|
||||
|
||||
<tip><para>An ISA device might want to map its IO port at
|
||||
<literal>0x230</literal>, 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 <literal>0x230</literal> IO port
|
||||
request might become memory-mapped at
|
||||
<literal>0xb0000230</literal> on a <acronym>MIPS</acronym> box
|
||||
by the PCI bridge.</para></tip>
|
||||
|
||||
<para>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).</para>
|
||||
|
||||
<para>In order to normalize access to memory and port mapped
|
||||
resources, Newbus integrates the <literal>bus_space</literal>
|
||||
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).</para>
|
||||
|
||||
<para>This support is integrated into the resource allocation
|
||||
mechanism. When a resource is allocated, a driver can retrieve
|
||||
the associated <structfield>bus_space_tag_t</structfield> and
|
||||
<structfield>bus_space_handle_t</structfield> from the
|
||||
resource.</para>
|
||||
|
||||
<para>Newbus also allows for definitions of interface methods in
|
||||
files dedicated to this purpose. These are the
|
||||
<filename>.m</filename> files that are found under the
|
||||
<filename>src/sys</filename> hierarchy.</para>
|
||||
|
||||
<para>The core of the Newbus system is an extensible
|
||||
<quote>object-based programming</quote> 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 <quote>interfaces</quote>. An
|
||||
<quote>interface</quote> is simply a group of related methods
|
||||
which can be implemented by a device.</para>
|
||||
|
||||
<para>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
|
||||
<emphasis>auto-configuration</emphasis>, it uses the method
|
||||
table declared by the driver. A device can later
|
||||
<emphasis>detach</emphasis> from its driver and
|
||||
<emphasis>re-attach</emphasis> to a new driver with a new method
|
||||
table. This allows dynamic replacement of drivers which can be
|
||||
useful for driver development.</para>
|
||||
|
||||
<para>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
|
||||
<filename>foo_if.m</filename>).</para>
|
||||
|
||||
<example>
|
||||
<title>Newbus Methods</title>
|
||||
|
||||
<programlisting>
|
||||
# Foo subsystem/driver (a comment...)
|
||||
|
||||
|
@ -231,114 +257,125 @@
|
|||
} DEFAULT doit_generic_to_child;
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>When this interface is compiled, it generates a header file
|
||||
<quote><filename>foo_if.h</filename></quote> which contains function
|
||||
declarations:</para>
|
||||
|
||||
|
||||
<para>When this interface is compiled, it generates a header file
|
||||
<quote><filename>foo_if.h</filename></quote> which contains
|
||||
function declarations:</para>
|
||||
|
||||
<programlisting>
|
||||
int FOO_DOIT(device_t dev);
|
||||
int FOO_DOIT_TO_CHILD(device_t dev, device_t child);
|
||||
</programlisting>
|
||||
|
||||
<para>A source file, <quote><filename>foo_if.c</filename></quote> 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.</para>
|
||||
|
||||
<para>The system defines two main interfaces. The first fundamental
|
||||
interface is called <emphasis><quote>device</quote></emphasis> and
|
||||
includes methods which are relevant to all devices. Methods in the
|
||||
<emphasis><quote>device</quote></emphasis> interface include
|
||||
<emphasis><quote>probe</quote></emphasis>,
|
||||
<emphasis><quote>attach</quote></emphasis> and
|
||||
<emphasis><quote>detach</quote></emphasis> to control detection of
|
||||
hardware and <emphasis><quote>shutdown</quote></emphasis>,
|
||||
<emphasis><quote>suspend</quote></emphasis> and
|
||||
<emphasis><quote>resume</quote></emphasis> for critical event
|
||||
notification.</para>
|
||||
|
||||
<para>The second, more complex interface is
|
||||
<emphasis><quote>bus</quote></emphasis>. This interface contains
|
||||
methods suitable for devices which have children, including methods to
|
||||
access bus specific per-device information
|
||||
<footnote><para>&man.bus.generic.read.ivar.9; and
|
||||
&man.bus.generic.write.ivar.9;</para></footnote>, event notification
|
||||
(<emphasis><literal>child_detached</literal></emphasis>,
|
||||
<emphasis><literal>driver_added</literal></emphasis>) and resource
|
||||
management (<emphasis><literal>alloc_resource</literal></emphasis>,
|
||||
<emphasis><literal>activate_resource</literal></emphasis>,
|
||||
<emphasis><literal>deactivate_resource</literal></emphasis>,
|
||||
<emphasis><literal>release_resource</literal></emphasis>).</para>
|
||||
|
||||
<para>Many methods in the <quote>bus</quote> 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
|
||||
<literal>BUS_TEARDOWN_INTR(device_t dev, device_t child, ...)</literal>
|
||||
can be called using the function
|
||||
<literal>bus_teardown_intr(device_t child, ...)</literal>.</para>
|
||||
|
||||
<para>Some bus types in the system define additional interfaces to
|
||||
provide access to bus-specific functionality. For instance, the PCI
|
||||
bus driver defines the <quote>pci</quote> interface which has two
|
||||
methods <emphasis><literal>read_config</literal></emphasis> and
|
||||
<emphasis><literal>write_config</literal></emphasis> for accessing the
|
||||
configuration registers of a PCI device.</para>
|
||||
|
||||
<para>A source file, <quote><filename>foo_if.c</filename></quote>
|
||||
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.</para>
|
||||
|
||||
<para>The system defines two main interfaces. The first
|
||||
fundamental interface is called
|
||||
<emphasis><quote>device</quote></emphasis> and includes methods
|
||||
which are relevant to all devices. Methods in the
|
||||
<emphasis><quote>device</quote></emphasis> interface include
|
||||
<emphasis><quote>probe</quote></emphasis>,
|
||||
<emphasis><quote>attach</quote></emphasis> and
|
||||
<emphasis><quote>detach</quote></emphasis> to control detection
|
||||
of hardware and <emphasis><quote>shutdown</quote></emphasis>,
|
||||
<emphasis><quote>suspend</quote></emphasis> and
|
||||
<emphasis><quote>resume</quote></emphasis> for critical event
|
||||
notification.</para>
|
||||
|
||||
<para>The second, more complex interface is
|
||||
<emphasis><quote>bus</quote></emphasis>. This interface
|
||||
contains methods suitable for devices which have children,
|
||||
including methods to access bus specific per-device information
|
||||
<footnote><para>&man.bus.generic.read.ivar.9; and
|
||||
&man.bus.generic.write.ivar.9;</para></footnote>, event
|
||||
notification
|
||||
(<emphasis><literal>child_detached</literal></emphasis>,
|
||||
<emphasis><literal>driver_added</literal></emphasis>) and
|
||||
resource management
|
||||
(<emphasis><literal>alloc_resource</literal></emphasis>,
|
||||
<emphasis><literal>activate_resource</literal></emphasis>,
|
||||
<emphasis><literal>deactivate_resource</literal></emphasis>,
|
||||
<emphasis><literal>release_resource</literal></emphasis>).</para>
|
||||
|
||||
<para>Many methods in the <quote>bus</quote> 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
|
||||
<literal>BUS_TEARDOWN_INTR(device_t dev, device_t child,
|
||||
...)</literal> can be called using the function
|
||||
<literal>bus_teardown_intr(device_t child,
|
||||
...)</literal>.</para>
|
||||
|
||||
<para>Some bus types in the system define additional interfaces to
|
||||
provide access to bus-specific functionality. For instance, the
|
||||
PCI bus driver defines the <quote>pci</quote> interface which
|
||||
has two methods
|
||||
<emphasis><literal>read_config</literal></emphasis> and
|
||||
<emphasis><literal>write_config</literal></emphasis> for
|
||||
accessing the configuration registers of a PCI device.</para>
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="newbus-api">
|
||||
<title>Newbus API</title>
|
||||
|
||||
<para>As the Newbus API is huge, this section makes some effort at
|
||||
documenting it. More information to come in the next revision of this
|
||||
document.</para>
|
||||
|
||||
documenting it. More information to come in the next revision
|
||||
of this document.</para>
|
||||
|
||||
<sect2>
|
||||
<title>Important locations in the source hierarchy</title>
|
||||
|
||||
<para><filename>src/sys/[arch]/[arch]</filename> - Kernel code for a
|
||||
specific machine architecture resides in this directory. For example,
|
||||
the <literal>i386</literal> architecture, or the
|
||||
<literal>SPARC64</literal> architecture.</para>
|
||||
|
||||
<para><filename>src/sys/dev/[bus]</filename> - device support for a
|
||||
specific <literal>[bus]</literal> resides in this directory.</para>
|
||||
|
||||
<para><filename>src/sys/dev/pci</filename> - PCI bus support code
|
||||
resides in this directory.</para>
|
||||
|
||||
<para><filename>src/sys/[isa|pci]</filename> - PCI/ISA device drivers
|
||||
reside in this directory. The PCI/ISA bus support code used to exist
|
||||
in this directory in FreeBSD version <literal>4.0</literal>.</para>
|
||||
|
||||
<para><filename>src/sys/[arch]/[arch]</filename> - Kernel code
|
||||
for a specific machine architecture resides in this directory.
|
||||
For example, the <literal>i386</literal> architecture, or the
|
||||
<literal>SPARC64</literal> architecture.</para>
|
||||
|
||||
<para><filename>src/sys/dev/[bus]</filename> - device support
|
||||
for a specific <literal>[bus]</literal> resides in this
|
||||
directory.</para>
|
||||
|
||||
<para><filename>src/sys/dev/pci</filename> - PCI bus support
|
||||
code resides in this directory.</para>
|
||||
|
||||
<para><filename>src/sys/[isa|pci]</filename> - PCI/ISA device
|
||||
drivers reside in this directory. The PCI/ISA bus support
|
||||
code used to exist in this directory in FreeBSD version
|
||||
<literal>4.0</literal>.</para>
|
||||
</sect2>
|
||||
|
||||
|
||||
<sect2>
|
||||
<title>Important structures and type definitions</title>
|
||||
<para><literal>devclass_t</literal> - This is a type definition of a
|
||||
pointer to a <literal>struct devclass</literal>.</para>
|
||||
|
||||
<para><literal>device_method_t</literal> - This is same as
|
||||
<literal>kobj_method_t</literal> (see
|
||||
<filename>src/sys/kobj.h</filename>).</para>
|
||||
|
||||
<para><literal>device_t</literal> - This is a type definition of a
|
||||
pointer to a <literal>struct device</literal>.
|
||||
<literal>device_t</literal> represents a device in the system. It is
|
||||
a kernel object. See <filename>src/sys/sys/bus_private.h</filename>
|
||||
for implementation details.</para>
|
||||
|
||||
<para><literal>driver_t</literal> - This is a type definition which,
|
||||
references <literal>struct driver</literal>. The
|
||||
<literal>driver</literal> struct is a class of the
|
||||
<literal>device</literal> kernel object; it also holds data private
|
||||
to for the driver.</para>
|
||||
|
||||
|
||||
<para><literal>devclass_t</literal> - This is a type definition
|
||||
of a pointer to a <literal>struct devclass</literal>.</para>
|
||||
|
||||
<para><literal>device_method_t</literal> - This is same as
|
||||
<literal>kobj_method_t</literal> (see
|
||||
<filename>src/sys/kobj.h</filename>).</para>
|
||||
|
||||
<para><literal>device_t</literal> - This is a type definition of
|
||||
a pointer to a <literal>struct device</literal>.
|
||||
<literal>device_t</literal> represents a device in the system.
|
||||
It is a kernel object. See
|
||||
<filename>src/sys/sys/bus_private.h</filename> for
|
||||
implementation details.</para>
|
||||
|
||||
<para><literal>driver_t</literal> - This is a type definition
|
||||
which, references <literal>struct driver</literal>. The
|
||||
<literal>driver</literal> struct is a class of the
|
||||
<literal>device</literal> kernel object; it also holds data
|
||||
private to for the driver.</para>
|
||||
|
||||
<figure>
|
||||
<title><emphasis>driver_t</emphasis> implementation</title>
|
||||
<title><emphasis>driver_t</emphasis> implementation</title>
|
||||
|
||||
<programlisting>
|
||||
struct driver {
|
||||
KOBJ_CLASS_FIELDS;
|
||||
|
@ -346,14 +383,16 @@
|
|||
};
|
||||
</programlisting>
|
||||
</figure>
|
||||
|
||||
|
||||
<para>A <literal>device_state_t</literal> type, which is
|
||||
an enumeration, <literal>device_state</literal>. It contains
|
||||
the possible states of a Newbus device before and after the
|
||||
autoconfiguration process.</para>
|
||||
|
||||
an enumeration, <literal>device_state</literal>. It contains
|
||||
the possible states of a Newbus device before and after the
|
||||
autoconfiguration process.</para>
|
||||
|
||||
<figure>
|
||||
<title>Device states<emphasis>device_state_t</emphasis></title>
|
||||
<title>Device
|
||||
states<emphasis>device_state_t</emphasis></title>
|
||||
|
||||
<programlisting>
|
||||
/*
|
||||
* src/sys/sys/bus.h
|
||||
|
|
Loading…
Reference in a new issue