Copyright © 2002 Progeny Linux Systems, Inc.
Copyright © 2002 Hewlett-Packard Company
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
busclass_list
elementbus
attributebusclass
elementid
attributename
attributevendor_list
elementbus
attributevendor
elementid
attributename
attributedevice_list
elementbus
attributedevice
elementdata
elementclass
attributeversion
attributebusclass_list
elementvendor_list
elementlinux
interfacexfree86
interfacedevice
elementsversion
attribute of the
data
elementDiscover is a tool that reports information about a system's hardware. It uses operating system-dependent modules (selected at build time) to detect what hardware is actually on the system and provides system-independent interfaces for querying XML data sources about this hardware. These data sources contain specific information required to enable support for various devices via defined software interfaces. The tool can be accessed by linking to the Discover library or by calling discover (which itself links to the Discover library) and parsing its output. In the future, other interfaces (for example, modules for interpreted languages such as Perl and Python) may be included.
Why use Discover? There are at least a few reasons:
Flexibility. Discover is designed from the ground up to be flexible. It is portable to a variety of operating environments, and its modular design supports the addition of arbitrary methods for querying the host operating system (OS) about installed devices. Discover is also designed to be flexible in terms of the types of data that can be retrieved. Discover does not tie the user to retrieving only one type of information, such as the name of the Linux kernel module that should be loaded to support a given device. Instead, Discover supports the association of arbitrary data with hardware devices, typically through specification of an interface to the hardware in question, such as a Linux kernel module or an XFree86 server driver module.
Updatability. Many hardware-autodetection programs suffer from an inherent limitation in that they are restricted to reading hardware lists or databases that are stored on the local filesystem. This is not an efficient approach in the fast-moving world of consumer computer hardware, with new devices constantly being introduced. A couple of months after the latest version of your OS of choice is released, it may fail to recognize that the latest revision of, for instance, a video chipset is compatible with an older one, and can use the same software interfaces. Discover overcomes this problem by supporting the retrieval of hardware information via HTTP[1] ("over the web"). When HTTP access is impossible, Discover falls back to locally stored hardware lists.
Portability. On top of its flexibility in terms of system interfaces to hardware, Discover has been written to be broadly portable to all of today's popular POSIX-compliant systems. Discover is not a Linux-only solution. Discover is intended to provide operating system vendors, computer manufacturers, and third-party vendors of software and peripherals with a powerful tool for describing the hardware they support to the interfaces they care about. Because Discover's data sources can be anywhere on the Internet, the OS vendor need not be the sole provider of hardware catalogs.
Usability. Discover is not an in-house tool designed to solve a narrow class of problems. Discover is designed to be easy to use from the perspectives of the individual system administrator, the applications programmer, and the hardware manufacturer or support staff. Discover's XML database structure, its command-line tools, and its library API are well documented and support extensions to meet diverse demands.
Freely licensed. Discover has a copyright license that is highly adaptable to the needs of the varied audiences to which Discover is targeted. Under the so-called "UCB/BSD" or "MIT/X Consortium" terms, after the names of American universities and some very well known software projects that used these terms, anyone is free to copy, modify, and distribute the software, and to extend (or not) these same freedoms to those who receive the software. Progeny would like to see Discover adopted by a wide variety of existing software products, such the various GNU/Linux distributions; the FreeBSD, NetBSD, and OpenBSD projects; the GNU Project of the Free Software Foundation; the XFree86 Project; system integrators; and the designers and manufacturers of computer hardware. We believe that Discover's design empowers those with the greatest knowledge of hardware and the software interfaces to that hardware to express that knowledge and make it available to the world, thereby ameliorating an entire class of computer configuration problems. Progeny does not want Discover's licensing to stand in the way of realizing that dream, which is why we have chosen these license terms.
We must take a moment to explain what Discover is not: Discover is not a replacement for the service — usually provided by the underlying operating system kernel or a user-space program that interfaces with it — of simply translating bus-specific vendor and model identifiers to human-readable names. Discover performs its own translations of this data as a convenience for generating human-readable reports, but it does not attempt to enumerate all hardware devices that exist for a particular bus architecture. Rather, Discover is intended only to catalog data for which there is some useful information to impart regarding software interfaces. Facilities already exist in modern operating systems for answering the questions "What is the name of this device?" and "Who manufactured it?" Discover's role is to answer questions like "What Linux kernel module do I need to load for this device to work?" More importantly, Discover will enable you to provide answers in the future to questions you don't even expect to ask today.
Discover is not intended to be a comprehensive hardware-management tool. It is an enabling technology, designed to provide data that a tool layered above it can use. Two applications are provided with Discover to demonstrate how the library can be leveraged: the command-line utility discover, and a Linux kernel module loading script, discover-modprobe, designed to be invoked at system boot time.
This manual is divided into four parts. First, we examine the Discover XML data file format, exploring the elements and attributes used to describe hardware and various interfaces to it. This part will enable you to read and understand a Discover XML file. Next, we offer some recommendations for writing your own Discover XML data. Knowing the syntax is valuable, but knowing how best to take advantage of it is even more useful. We then present the reference pages describing Progeny's Discover-based command-line tools and the configuration files used to control their behavior. You may want to use these references as a guide when implementing your own Discover-based applications. The final part describes the Discover library API so that you can develop your own solutions based on Discover. Appendices offer references to the formal descriptions of the Discover API and XML DTDs.
busclass_list
elementbus
attributebusclass
elementid
attributename
attributevendor_list
elementbus
attributevendor
elementid
attributename
attributedevice_list
elementbus
attributedevice
elementdata
elementclass
attributeversion
attributeMost modern computer peripherals contain self-identifying information in a format standardized for the hardware interface (bus). This enables the OS on the host system to query or scan a bus and catalog the devices. In general, the OS stores this information in the same basic format in which it is returned, without translating it more times than necessary for device drivers to communicate with the peripheral. However, this information varies by bus type and is often insufficiently clear for human consumption. Furthermore, many operating systems do not contain a comprehensive database that maps each peripheral to every subsystem running on the OS that may want to communicate with that peripheral. Discover addresses these issues by providing flexible databases stored in XML format.
Extensible Markup Language (XML) is a highly flexible hypertext format. Discover uses XML exclusively to store hardware information externally. Some familiarity with XML syntax is therefore assumed. For more information, see the W3C's XML website.
For a formal description of Discover's XML data format, see the Discover Document Type Definition (DTD) document. The purpose of this document is to present the information in a form digestible by the novice.
Because each hardware bus type, such as PCI or USB, communicates different details about the connected devices (essentially, each one solves the same problem in a different way), Discover has a different set of lists for each bus type. For each bus, up to three lists are stored: a bus class list maps the bus specification's notion of a device type (hereinafter referred to as a "device class" to reduce confusion) to Discover's device types, which are used for running selective queries; a vendor list associates bus-specific vendor identification data with natural-language names for hardware vendors; and a device list contains information specific to individual devices.
When Discover is provided with a URL for the retrieval of hardware information, the data retrieved is expected to be in XML format and to contain further URLs for retrieval.
The root element must be discover-data
, which has no attributes,
and can only contain location
elements.
The location
element is
always empty, and has three required attributes: bus
, type
, and url
.
location
Attributes
type
This attribute can have one of these values: busclass
, device
, or vendor
. See Chapter 3, Chapter 4, and Chapter 5.
url
This must be a valid URL containing one of the three types of data lists.
bus
This is the bus to which the URL applies. See Section 3.2.2 for a list of valid bus names.
As noted in the previous chapter, a busclass list provides a mapping between device classes recognized by the hardware bus and the device type names used by Discover. Because every bus is different, sometimes there is no perfect, one-to-one correspondence between Discover device types and the device classes recognized by a particular bus. This is one reason that the busclass lists, like other types of Discover data lists, are updatable. Revisions in a bus specification may demand updates to the mapping.
The device classes recognized by a bus are typically determined by the specification for the bus as determined by a standards committee or other technical body, and do not change frequently (if at all).
Example 3-1. The
busclass_list
element
<?xml version="1.0"?> <busclass_list bus="usb"> <busclass id="0202" name="modem"/> <busclass id="1030" name="broadband"/> <busclass id="0101" name="printer"/> <busclass id="ffff" name="imaging"/> <busclass id="0206" name="network"/> <busclass id="0300" name="humaninput"/> <busclass id="ff00" name="video"/> <busclass id="0000" name="unknown"/> <busclass id="0804" name="removabledisk"/> </busclass_list> |
In the foregoing example, we can see one possible mapping of the USB bus's numeric device class IDs to Discover's device type names (see Section 3.2.2). The file begins by declaring the version of the XML standard to which it conforms, and then presents data. The format should be fairly familiar to those accustomed to HTML-style structured markup languages.
Not all of Discover's supported device types are listed in the example; for example, display is missing. This is not a problem, since not all buses are used for all hardware applications. USB 1.1 would be a poor choice of bus for VGA-compatible display controllers, for instance, because the available bandwidth on the USB 1.1 bus is insufficient to handle typical data loads for such devices.
Another infelicity in the above example is the association of the ffff device class ID with the Discover device type imaging. In actuality, a device type class of ffff in the USB specification indicates a device of an unknown classification. In practice, most consumer-level devices with this device class are scanners, one of the first applications of USB technology in the consumer marketplace. It is possible that in certain deployments, the association of USB's unknown device class ID with Discover's imaging device type is suboptimal — another reason the busclass lists are not hard-coded into the library.
busclass_list
elementA busclass_list
element possesses a
bus
attribute and contains one or more
busclass
elements.
bus
attributeThe bus
attribute of the
busclass_list
element is set to the name of
the bus being described by the busclass list.
The bus
attribute
presently supports the following values:
ata
pci
pcmcia
scsi
usb
We expect to support more buses in the future; ieee1394 and sbus are possible candidates.
busclass
elementA busclass
element possesses two
attributes, id
and name
, and
contains no elements.
name
attributeThe name
attribute is set to a
Discover device type. Discover's device types are an effort
to balance a few criteria:
Device types ("bus classes" in Discover terminology) defined by the PCI specification
Bus classes defined by the USB specification
Bus classes defined by the SCSI specification
Device types commonly conceived of by the personal computer user
Discover's definitions of device types will not meet with universal agreement; as happens in most categorization problems, some decisions had to be made arbitrarily. Discover does not attempt to solve the general problem of grouping various peripherals into categories; rather, Discover solves the problem for itself and uses bus-specific mappings to translate a device's own notion of its type to Discover's device type.
audio
A device capable of producing an analog or digital sound signal is an audio device. Typically, any device commonly referred to as a "sound card" is classified by Discover as an audio device.
bridge
A device that provides access to devices of a different type, commonly on a different bus, is a bridge device. For instance, consumer PCI chipsets often feature a bridge to ATA (also known as IDE) devices.
broadband
An interface device to a computer communications network implemented on top of a technology not explicitly designed for that purpose is a broadband device. Examples include ISDN terminal adapters as well as DSL and cable "modems"; analog phone-line modems are not included in this classification (see "modem" below).
display
A device controlled by the host machine's CPU and capable of producing an analog or digital video signal for output purposes is a display device. Typically, any device commonly referred to as a "video card" is classified by Discover as a display device.
fixeddisk
A high-speed, fixed magnetic storage device such as a hard disk drive is a fixeddisk device. Removable media devices such as floppy disk drives, CD-ROM drives, magneto-optical devices, tape drives, and Compact Flash card readers are not included in this classification.
humaninput
A device that receives tactile input from a person for the purpose of directing a computer's activity is a humaninput device. Examples include keyboards, mice, trackballs, joysticks, gamepads, digital tablets manipulated with a stylus or finger, and so forth. Input devices that rely upon non-tactile means of determining a person's intent, such as speech-recognition devices or cameras, are not included in this classification.
imaging
A device that captures still images for input purposes is an imaging device. Scanners and digital cameras are examples of imaging devices. Motion-capture devices such as television tuner cards, webcams, and digital video cameras are not included in this classification.
miscellaneous
Any device that cannot logically be classified as another device type is a miscellaneous device.
modem
An analog phone-line modulator/demodulator (modem) is classified by Discover as a modem device. No other kind of device is so classified.
network
An interface device to a conventional computer data communications network that does not require the use of a terminal adapter is a network device. For example, Ethernet and Token Ring network interface cards are network devices. Analog phone-line modems; terminal adapters for technologies such as ISDN and DSL; and "cable modems" are not "network" devices.
optical
An optical-technology storage device, often using read-only media, is an optical device. By far the most common examples of these devices are CD-ROM and DVD-ROM drives, including versions of these drives that can "burn" (write to) optical discs.
printer
A device that renders visual output in a permanent or semi-permanent manner to a physical medium is a printer. Typically, any device colloquially referred to as a "printer" is also classified by Discover as a printer.
removabledisk
Storage devices that feature removable media using just about any technology except that of magnetic tape, CD-ROM, and DVD-ROM drives are removabledisk devices. Examples include floppy disk drives, magneto-optical drives, and Compact Flash card readers.
tape
A sequential-access mass storage device using magnetic tape is a tape device. Commonly used for archival and backup purposes, DAT drives are examples of tape devices.
video
A device that produces a real-time digital video signal for input purposes is a video device. Webcams, digital video cameras, and television tuners are examples of video devices. Note that still digital cameras with "movie" capability are not considered video devices unless they can transmit the live video signal to the host in real time.
Many buses have vendor identification numbers that are registered with that bus's standardization body and programmed into the devices when they are manufactured. These numbers generally are assigned arbitrarily, and typically have little meaning to the end user; therefore, most hardware detection tools provide a way to translate these numeric vendor IDs to human-readable strings. Thus, instead of knowing that your PCI or AGP video card was manufactured by "1002," you can determine that it was manufactured by "ATI Technologies, Inc."
Example 4-1. The vendor_list
element
<?xml version="1.0"?> <vendor_list bus="pci"> <vendor id="0675" name="Dynalink"/> <vendor id="0e11" name="Compaq Computer Corporation"/> <vendor id="1004" name="VLSI Technology Inc"/> <vendor id="1025" name="Acer Incorporated [ALI]"/> <vendor id="102b" name="Matrox Graphics, Inc."/> <vendor id="109e" name="Brooktree Corporation"/> </vendor_list> |
The foregoing example is similar in structure to the busclass list example; a numeric vendor ID maps to a vendor name, which can be used by Discover for queries or reports generated for the user's benefit.
vendor_list
elementA vendor_list
element possesses a
bus
attribute and contains one or more
vendor
elements.
bus
attributeThe bus
attribute of the
vendor_list
element is set to the name of
the bus being described by the vendor list.
The following bus attributes are supported:
ata
pci
pcmcia
scsi
usb
vendor
elementA vendor
element possesses two
attributes, id
and name
, and
contains no elements.
name
attributeThe name
attribute is set to a
human-readable vendor identifier, typically the official name of
the corporation or other business entity that designed or
manufactured that peripheral.
The device lists are the heart of Discover's functionality. They are the most frequently updated lists and contain the information of greatest value.
Discover's device lists not only provide a way to identify individual peripherals by name, but also permit the specification of an arbitrary quantity of organized data for each device, supporting an arbitrary number of software interfaces.
The following is a fictitious example. The information within it is for illustrative purposes only. See Part II in The Discover Hardware Detection System for a discussion of the "real" hardware data as provided by Progeny, and for some suggested conventions on organizing the data namespace. |
Example 5-1. Sample device data
<?xml version="1.0"?> <device_list bus="pci"> <device busclass="1984" model="0101" model_name="Cerebral Reprogrammer" vendor="B16B"> <data class="linux"> <data class="module"> <data class="name">winston</data> <data class="options">base_address=0x300 manual_override=0</data> </data> </data> <data class="win2k"> <data class="hal_driver"> <data class="StrUglyHungarianNotatedDriverName">settlement</data> <data class="flags">NSA_KEY=96b5f3e3283a62c85f6cb6f4017135c2</data> </data> </data> </device> </device_list> |
The example above includes a device_list
element containing device
elements, and a
device
element that defines the device itself,
but reserves any software- or interface-specific details to the
data
elements it contains.
The actual data provided in the example is accessed by means of data paths; see Section 5.4 for further information.
device_list
elementA device_list
element possesses a
bus
attribute and contains one or more
device
elements.
bus
attributeThe bus
attribute of the
device_list
element is set to the name of
the bus described by the device list.
The following bus attributes are supported:
ata
pci
pcmcia
scsi
usb
device
elementA device
element possesses four attributes:
busclass
vendor
model
model_name
All of these attributes must be specified for each
device
element. The busclass
attribute is set to a busclass
identifier, vendor
to a vendor
identifier, model
to a bus-specific
model identifier, and model_name
to a
human-readable vendor identifier, typically the name of the product
under which the device reporting the model
identifier is sold or otherwise distributed.
A device
element contains zero or more
data
elements.
data
elementA data
element possesses a mandatory
class
attribute, an optional
version
attribute, and zero or more
data
elements.
The ability to nest data
elements inside
other data
elements affords interface designers
and device driver authors the ability to specify a hierarchy of
data, instead of being compelled to encapsulate only one piece of
data per device for their interface.
class
attributeA class
attribute is set to an arbitrary
value determined by an interface designer. For
data
elements whose parent element is a
device
element, this should be the name of
the interface being described, such as
freebsd, linux, or
xfree86.
A data
element whose parent element is a
data
element should set this attribute to a
term reflecting the interface designer's intended data hierarchy.
Discover does not mandate any particular hierarchy for
interface designers.
version
attributeData elements have an optional attribute named version
. This indicates a version
range applicable to the data contained
within the element. The purpose of this attribute is to permit
the specification of data that is valid only for a range of
versions of the given interface. For example, the Linux kernel
changed some of the names of its modules between the 2.2 and 2.4
series.
Discover's range syntax, common in mathematical writings, is expressed as an interval; that is, it consists of a pair of endpoints with a comma between them, and brackets or parentheses as qualifiers for inclusion or exclusion of the endpoints' exact values. For example, the version specification [1.0, 2.0) matches any version less than 2.0 and greater than or equal to 1.0. It is the responsibility of the calling environment to specify the version of the interface actually in use. In other words, the Discover library does not take it upon itself to determine the currently running version of the Linux kernel, XFree86 X server, CUPS printing daemon, and so forth.
Due to the lack of consistent standards for version numbers
(in fact, some version numbers aren't numbers at all),
Discover requires simplifications for the version
attribute. The versions that
express the range must be in dotted-decimal form, such as
7.1.0. The version that is supplied to the
Discover library as part of a query (for example, via the
--data-version
argument to discover)
may or may not comply with this requirement, but should
be expressed such that it compares in a desirable way against
version strings that do.
In place of the upper end of the range, inf (infinity) can be used if the information is still relevant and should be for forseeable versions.
Discover data is grouped into hierarchical data
elements. This data can be accessed
via its data path. The data path is the concatenation of the class
attribute values of a data
element and all its parents, separated by slash
(/) characters. In the following example,
quux is accessed via the data path
"foo/bar":
In Example 5-1 above, we would determine the name of the Linux kernel module ("winston") for the "Cerebral Reprogrammer" device by referencing the data path linux/module/name; similarly, the data path win2k/hal_driver/flags returns NSA_KEY=96b5f3e3283a62c85f6cb6f4017135c2.
As discussed in the preface, Discover is not
intended to be a replacement for system utilities such as
lspci on Linux. A
device
element should exist
for a piece of hardware only if there is some interface information
to communicate about the hardware; that is, some
data
elements to house within the
device
element. This part of the
manual contains Progeny's recommendations on how to organize that
information for maximum utility.
As discussed in Section 5.4, the XML structure around the data allows for a hierarchical view.
While Discover does not mandate any particular hierarchy or
namespace organization for data
elements, the XML files provided by Progeny express — and
some applications based on Discover (such as
discover-modprobe) expect — a certain
structure for Linux kernel module and XFree86 configuration
information.
At Progeny, we have often found it convenient to refer to a
top-level data
element's class
attribute value as an
"interface" (see the following example).
Example 6-1. Defining an interface
<device busclass="0300" vendor="de8d" model="90a9" model_name="Stingray"> <data class="xfree86"> <data class="server" version="[3, 4)"> <data class="name">XF86_SVGA</data> </data> </data> <data class="openbsd"> <data class="security_level">untrusted</data> </data> </device> |
In Example 6-1, two interfaces have been defined for the "Stingray" device: xfree86 and openbsd.
A hardware device that requires a particular Linux kernel
module should have nested data
elements to describe that module. The top-level data
element should have a class
attribute with a value of
linux
. Underneath that should
be a data
element with a
class
of module
.
Within that data
element,
there should be one or two more, one with a class
of name
, and an optional one with a
class
of options
. The former has as content the
name of the module; the latter, options to be passed to
modprobe.
In Figure 6-1, each component of
the tree represents a data
element; the label is the value of its class
attribute.
If the kernel version affects the choice of module name or
options, the top-level linux
data
element should have a
version range attribute; see Section 5.3.2.
Example 6-2. Using the linux
interface
<device busclass="0204" model="1702" model_name="IS64PH ISDN Adapter" vendor="0675"> <data class="linux"> <data class="module"> <data class="name">hisax</data> <data class="options">io=0x300 irq=11</data> </data> </data> </device> |
See Example 8-1 for guidance on how to specify different Linux kernel modules for the same device, depending on the version of the Linux kernel in use.
The data hierarchy of a video card device (Discover's
display type) should include a top-level
data
element with a class
attribute of xfree86
(the interface)
and likely with a version
attribute as well; nested within that element will be a server
data
element containing a name
data
element identifying the name of the
server executable. For XFree86 version 4.0 or greater, the
name
will always be XFree86
, and the server
data
element will also contain a device
data
element, which contains one or more
data
elements communicating
information to be stored in the XF86Config
file. The children of the device
data
element are named in correspondence
with the syntax of the XF86Config file's
Device section; see the XF86Config
manual page for further information. In particular, note
that in many cases only a
driver
data
element is necessary.
Figure 6-2. XFree86 interface
/xfree86 | |-/server | |-/name | |-/device | |-/driver | |-/chipid | |-/chipset | |-/ramdac | |-/dacspeed | |-/videoram | |-/options | |-... |
Figure 6-2 illustrates the
xfree86
interface. Example 6-3 shows
how you might write xfree86
interface information for a Discover display
device.
Example 6-3. Using the xfree86
interface
<device busclass="0300" vendor="1002" model="4654" model_name="Mach64 VT [264VT FT]"> <data class="xfree86"> <data class="server" version="[4, inf)"> <data class="name">XFree86</data> <data class="device"> <data class="driver">ati</data> </data> </data> <data class="server" version="(0, 4)"> <data class="name">XF86_Mach64</data> </data> </data> </device> |
Progeny recommends that publicly distributed Discover
XML files avoid using the interface name
local; that is, a
class
attribute value of
local in a top-level
data
element. This
means that data paths such as local/foo/bar
should not be defined in a public Discover XML file, but
both foo/bar/local and
foo/local/bar are okay.
The intention is to reserve this part of the namespace for users' experiments with defining their own — and possibly future, widely adopted — interface definitions for Discover data. An interface definition could thus be "beta tested" by a person or organization to ensure that it is efficiently structured before it is unleashed upon the world elsewhere in the namespace, where people may write tools that expect to be able to resolve the interface definition's data paths.
Likewise, Progeny recommends that authors of applications
that use Discover avoid traversing into a top-level
local data
element, which may impose an undesirable support burden on
the designers of the interface while they are still working out
their design. (The application also may not find the data it
desires, or may not get back what it expects.)
When searching device elements, the first exact match will be selected. Subsequent matches are ignored.
Specifically, three comparisons are made:
The hardware must provide identification that matches
attributes of the device
element. As an
example, a PCI device supplies numeric vendor and model
identifiers, which are used to match the
model
and vendor
attributes.
The class
attributes of child
data
elements must match the data path as
given to the library for searching.
The first version range, if any, associated with the nested
data
elements must encompass any
version provided by the client.
Example 7-1. Matching device
elements
Assume that the path linux/module/name is
provided, along with a version of 2.4.2. The following is sample
data; the device
elements may be from the same
or different data files.
Because multiple versions of a software interface often are
in simultaneous deployment, Progeny recommendeds that the upper
bound of a data
element's
version
attribute be defined
as the first version that is inconsistent with the information
provided within it, and that the upper end of the interval be open
(terminated with a parenthesis). As an example, suppose we know
that the name of the Linux kernel module to drive the RealTek
RTL-8139 Ethernet device was rtl8139 in the 2.2
kernel series and 8139too in the 2.4 series. To
express this, we would say the following:
Example 8-1. Using the
version
attribute of the
data
element
<device_list bus="pci"> <device busclass="0200" model="8139" model_name="RTL-8139" vendor="10ec"> <data class="linux" version="[2.4,inf)"> <data class="module"> <data class="name">8139too</data> </data> </data> <data class="linux" version="[2.2,2.4)"> <data class="module"> <data class="name">rtl8139</data> </data> </data> </device> </device_list> |
In the first data element, for instance, we would not use a version attribute of [2.2.0,2.2.19] because it is needlessly specific. What happens if the Linux kernel developers release Linux kernel 2.2.20? By saying [2.2,2.4), we "catch" everything in the kernel 2.2 series[2] — past, present, and future.
The data files will be searched in order; the first data path that matches the version range or doesn't have a version range will be returned.
Recalling the discussion in Section 5.3.2, if you want the first data element matching the requested data path to also be the "fallback" element if no version range applies, you can duplicate that data element and place it at the end. However, a better practice is to make certain that all reasonable versions will match one of the ranges, and that the first range listed has an open-ended high end, such as [2.4, inf) for Linux kernel modules in Example 8-1. This will have the effect of "assuming" that all unversioned requests for linux data will be for Linux kernel 2.4 or later.
discover [DATA_OPTIONS] [DISPLAY_OPTIONS] [--bus-summary] [bus...]
discover [DATA_OPTIONS] [DISPLAY_OPTIONS] --type-summary [type...]
discover [DATA_OPTIONS] --data-path=path/to/data... [--data-version=version] [--normalize-whitespace] [--format=format string] [type | id...]
-d | --disable-bus=bus
-e | --enable-bus=bus
--insert-url=url
--append-url=url
-v | --verbose
--model | --no-model
--model-id | --no-model-id
--vendor | --no-vendor
--vendor-id | --no-vendor-id
discover provides an extensible hardware detection and reporting interface. Hardware information is stored in an XML data format and can be retrieved across the network.
Fundamental modes of operation:
Display a list of hardware devices based on type of device or
system bus on which the devices reside, via
--type-summary
or
--bus-summary
(the latter of which is the
default behavior).
Query specified data for attached hardware, via
--data-path
.
-h | --help
Display a simple help message.
-v | --verbose
Instruct the tool to provide feedback as it operates. This will affect the output as discover parses certain arguments, so this should appear early in the command line.
-V | --version
Display the tool name and version.
-b | --bus-summary
This is the default behavior: Display basic information regarding all devices on the appropriate buses. See Selecting Buses.
-t | --type-summary
Summarize devices by class of hardware. Examples of valid device types include broadband, fixeddisk, display, and network. See Device Types.
--data-path=path/to/data
Query matching devices for detailed information. Device-specific data is stored in a hierarchical fashion, and the query argument comprises strings naming each level in that hierarchy.
Typically, the top-level component of the data
path will be the "platform" that will need
the information, such as linux or
xfree86. For example, to retrieve
the Linux kernel module name for a piece of hardware,
the --data-path
argument would be
linux/module/name.
If multiple --data-path
arguments are given and no format string (see
--format
) is provided, only the last
path is used.
See also the --data-version
argument.
--data-version=version
Specify a version string for the platform that
will use the information specified by the argument to
--data-path
.
This string must be in dotted-decimal notation in order to be matched against a range of values, and thus may be shorter than the real version.
--format=format string
Dictate the output of the results of the queries
specified by --data-path
arguments.
This format string should follow
printf(3)
specifications, although
only %s and appropriate flags,
precision, and width values are supported (or
make sense); literal text and %%
can also be used. The behavior when the string is
poorly formatted is undefined. See also
--normalize-whitespace
.
-d | --disable-bus=bus
Use this option to override the list of
buses to scan by default as defined in
discover.conf. Use
all as an argument to
disable all buses; this is useful only if
followed by
--enable-bus
(or -e
)
arguments.
-e | --enable-bus=bus
Specify a bus to be scanned.
--insert-url=url
Insert a URL at the head of
the list of network resources to include in the search
for hardware information. Earlier data overrides
later data; to override the local data
sources, insert URLs into the list. See also
--append-url
.
--append-url=url
Append a URL to the end of the
list of network resources to search for
hardware information. See also
--insert-url
.
--model
Include the model description in summary information. This is enabled by default.
--model-id
Include the numeric model identifier in summary information.
--no-model
Do not include the model description in summary information.
--no-model-id
Do not include the numeric model identifier in summary information. This is the default.
--vendor
Include the vendor description in summary information. This is enabled by default.
--vendor-id
Include the numeric vendor identifier in summary information.
--no-vendor
Do not include the vendor description in summary information.
--no-vendor-id
Do not include the numeric vendor identifier in summary information. This is the default.
--normalize-whitespace
Consolidate whitespace in the results of a
--data-path
query. The default is not to do so,
which faithfully reproduces all text in the raw XML data.
With this option enabled, leading and trailing whitespace is removed, and any consecutive internal whitespaces are compressed to a single space character.
discover.conf defines two lists of system buses: one to scan by default (used by the discover command), and one never to scan (used by the Discover library).
You can override and/or extend the list of default buses with
--disable-bus
and --enable-bus
.
The list of buses not to scan cannot be overridden
without changing discover.conf, so that list
should be used only for buses that may be dangerous to probe.
Both arguments take the string "all" as a value.
If a bus summary is being performed, which is indicated
either by the presence of --bus-summary
or
the absence of --type-summary
and
--data-path
, any unattached arguments on the
command line will be interpreted as the only buses to scan.
This is equivalent to using --disable-bus
all
before invoking --enable-bus
for the buses of interest.
The following buses are currently supported by Discover:
ata
pci
pcmcia
scsi
usb
Discover defines its own device types, to which the device types used by each bus are mapped. Discover currently recognizes the following device types:
audio
A device capable of producing an analog or digital sound signal is an audio device. Typically, any device commonly referred to as a "sound card" is classified by Discover as an audio device.
bridge
A device that provides access to devices of a different type, commonly on a different bus, is a bridge device. For instance, consumer PCI chipsets often feature a bridge to ATA (also known as IDE) devices.
broadband
An interface device to a computer communications network implemented on top of a technology not explicitly designed for that purpose is a broadband device. Examples include ISDN terminal adapters as well as DSL and cable "modems"; analog phone-line modems are not included in this classification (see "modem" below).
display
A device controlled by the host machine's CPU and capable of producing an analog or digital video signal for output purposes is a display device. Typically, any device commonly referred to as a "video card" is classified by Discover as a display device.
fixeddisk
A high-speed, fixed magnetic storage device such as a hard disk drive is a fixeddisk device. Removable media devices such as floppy disk drives, CD-ROM drives, magneto-optical devices, tape drives, and Compact Flash card readers are not included in this classification.
humaninput
A device that receives tactile input from a person for the purpose of directing a computer's activity is a humaninput device. Examples include keyboards, mice, trackballs, joysticks, gamepads, digital tablets manipulated with a stylus or finger, and so forth. Input devices that rely upon non-tactile means of determining a person's intent, such as speech-recognition devices or cameras, are not included in this classification.
imaging
A device that captures still images for input purposes is an imaging device. Scanners and digital cameras are examples of imaging devices. Motion-capture devices such as television tuner cards, webcams, and digital video cameras are not included in this classification.
miscellaneous
Any device that cannot logically be classified as another device type is a miscellaneous device.
modem
An analog phone-line modulator/demodulator (modem) is classified by Discover as a modem device. No other kind of device is so classified.
network
An interface device to a conventional computer data communications network that does not require the use of a terminal adapter is a network device. For example, Ethernet and Token Ring network interface cards are network devices. Analog phone-line modems; terminal adapters for technologies such as ISDN and DSL; and "cable modems" are not "network" devices.
optical
An optical-technology storage device, often using read-only media, is an optical device. By far the most common examples of these devices are CD-ROM and DVD-ROM drives, including versions of these drives that can "burn" (write to) optical discs.
printer
A device that renders visual output in a permanent or semi-permanent manner to a physical medium is a printer. Typically, any device colloquially referred to as a "printer" is also classified by Discover as a printer.
removabledisk
Storage devices that feature removable media using just about any technology except that of magnetic tape, CD-ROM, and DVD-ROM drives are removabledisk devices. Examples include floppy disk drives, magneto-optical drives, and Compact Flash card readers.
tape
A sequential-access mass storage device using magnetic tape is a tape device. Commonly used for archival and backup purposes, DAT drives are examples of tape devices.
video
A device that produces a real-time digital video signal for input purposes is a video device. Webcams, digital video cameras, and television tuners are examples of video devices. Note that still digital cameras with "movie" capability are not considered video devices unless they can transmit the live video signal to the host in real time.
Example 9-1. Scan the local buses
# discover Intel Corporation 82815 Chipset Host Bridge and Memory Controller Hub unknown unknown unknown unknown unknown unknown Intel Corporation 82815 Chipset IDE controller Intel Corporation 82815 Chipset USB (A) Intel Corporation 82815 System Management bus controller ATI Technologies, Inc. Rage 128 Pro GL [PF] 3Com Corporation 3c905C-TX [Fast Etherlink] Ensoniq ES1371 [AudioPCI-97] unknown unknown |
Example 9-2. View PCI video cards
# discover -v --type-summary --disable-bus all --enable-bus pci display Disabled pci Disabled pcmcia Disabled scsi Disabled usb Enabled pci Loading XML data... pci Done Scanning buses... pci Done ATI Technologies, Inc. Rage 128 Pro GL [PF] |
The directory containing configuration files that control the default behavior for both the discover tool and the Discover library.
An XML file containing URLs with
hardware information. This list can be extended with
--append-url
and
--extend-url
.
Discover looks for configuration files in a configuration directory, containing a number of files. These define the system buses that should be scanned by default, those that should never be scanned, and the URLs for hardware data files beyond the local copy provided with the software.
The file format is XML; the DTD is provided with the Discover software, and can be used for informational or validation purposes.
Example 10-1. Establishing default buses to scan
<?xml version="1.0"?> <!DOCTYPE conffile SYSTEM "conffile.dtd"> <conffile> <busscan scan="default"> <bus name="ata"/> <bus name="pci"/> <bus name="pcmcia"/> <bus name="scsi"/> <bus name="usb"/> </busscan> </conffile> |
Example 10-2. A more complex example
<?xml version="1.0"?> <!DOCTYPE conffile SYSTEM "conffile.dtd"> <conffile> <busscan scan="default"> <bus name="ata"/> <bus name="pci"/> <bus name="pcmcia"/> <bus name="usb"/> </busscan> <!-- My ancient SCSI card locks up when probed --> <busscan scan="never"> <bus name="scsi"/> </busscan> <data-sources> <data-source url="http://www.example.com/discover/xfree86.xml" label="Updated XFree86 hardware information"> </data-sources> </conffile> |
discover-modprobe loads kernel modules identified by discover. It will typically be invoked automatically at boot time.
This configuration file defines the types of modules to load by default, and specific modules not to load.
A crash file written and erased each time discover-modprobe attempts to load a module. If the file lingers, the computer is assumed to have crashed while loading that module, and the module name is added to discover-modprobe.conf as a module to skip in the future.
discover-modprobe.conf is the configuration file for discover-modprobe, which is responsible for retrieving and loading kernel modules.
This file is a shell script, and as such is subject to a string variable assignment syntax. No space is allowed between the variable name, the equal (=) sign, and the value(s) assigned. If multiple values are to be assigned, the list must be space-delimited with surrounding quotes. |
Two directives can be used in this file: types and skip. Both can be defined multiple times.
This describes the classes of hardware that should be scanned and queried.
These modules should never be loaded. See the "Files" section for details on the mechanism for generating these entries automatically.
Lazy allocation is used throughout Discover. This means that there are no "init" functions, and no functions to scan the bus. Instead, retrieval functions scan or initialize as necessary. Each of these retrieval functions has an equivalent function for freeing the allocated memory. This is valuable to long-lived processes to aid in memory management, but even short-lived processes may want to use them to force reloading of the information.
Discover knows about one data source by default: the local
data from the discover-data package. Additional
sources can be added with the
discover_conf_append_url
and
discover_conf_insert_url
functions. As their
names suggest, they append or insert URLs on the data source
list. Earlier data overrides later data; to override
the local data sources, insert URLs.
Most high-level operations begin at the bus map. Bus maps
(discover_bus_map_t)
are retrieved with calls to
discover_conf_get_bus_map
or
discover_conf_get_bus_map_by_name
.
discover_conf_get_bus_map
returns an array of
maps, one for each supported bus, with the last element being all
0s. discover_conf_get_bus_map_by_name
returns
the map for the named bus. The map contains pointers to all the
functions that operate on the bus, as well as the
scan_default
variable, which determines whether
the bus is scanned by default. There is also a
scan_never
variable, but it is for internal use
only. The name of the bus is stored in the
name
variable.
The following functions are available in the bus map. The "get" functions take a single discover_error_t argument and return a list of discover_device_t structures, while the "free" functions take no arguments and return no value.
get_devices
Retrieve the list of devices found on this bus. Returns NULL if the bus is not present on the system, or if no devices are attached to it.
xml_get_busclasses
Retrieve the list of busclasses for this bus (from the XML data sources).
xml_get_devices
Retrieve the list of devices for this bus (from the XML data sources). Note that this is the list of devices that Discover knows about, not the list of devices present on the system.
xml_get_vendors
Retrieve the list of vendors for this bus (from the XML data sources).
xml_get_busclass_urls
Retrieve the list of URLs from which busclass data is retrieved. This function is probably not useful to most clients.
xml_get_device_urls
Retrieve the list of URLs from which device data is retrieved. This function is probably not useful to most clients.
xml_get_vendor_urls
Retrieve the list of URLs from which vendor data is retrieved. This function is probably not useful to most clients.
free_devices
Free the list of devices.
xml_free_busclasses
Free the list of busclasses.
xml_free_devices
Free the list of devices (the XML data, not the list of devices found on the system).
xml_free_vendors
Free the list of vendors.
xml_free_busclass_urls
Free the list of busclass URLs.
xml_free_device_urls
Free the list of device URLs.
xml_free_vendor_urls
Free the list of vendor URLs.
Discover provides a few ways to scan the system for information.
You can walk the bus map:
for (i = 0; busmap[i].name; i++) { if (busmap[i].scan == DISCOVER_SCAN_DEFAULT) { devices = busmap[i].get_devices(&status); check_status(status); do_something_cool(devices); } } |
You can scan a specific bus:
Perhaps most usefully, you can scan for devices of a specific type:
Now that you have some device structures, what can you
do with them? The most interesting operation is retrieving
data with discover_device_get_data
. Also
available are
discover_device_get_vendor_name
,
discover_device_get_model_name
,
discover_device_get_model_id
, and
discover_device_get_vendor_id
.
discover_device_get_data
takes a
data path and a
version
number and searches for the first data structure that
matches.
discover_device_get_vendor_name
returns the human-readable name for the device's
vendor.
discover_device_get_model_name
returns the human-readable name for the device's model.
discover_device_get_model_id
returns the bus-specific ID for the device model.
discover_device_get_vendor_id
returns the bus-specific ID for the device vendor.
The system-dependent code (sysdeps)
that must be custom-written for each operating system conforms to a
very simple API. Discover invokes
_discover_get_busname_raw()
with no arguments, and expects a linked list of
discover_sysdep_data_t structures in return.
The discover_sysdep_data_t structures should contain as much descriptive information as they can regarding the devices discovered. Specifically, the three pieces of information desired are the busclass (device type), vendor identifier, and model identifier, which is a unique identification string that the vendor has provided for the given piece of hardware.
Example 14-1. Linux PCI sysdep code
#include <config.h> #include <stdio.h> #include <stdlib.h> #include <sysdep.h> discover_sysdep_data_t * _discover_get_pci_raw(void) { FILE *f; char *line = NULL; size_t len = 0; discover_sysdep_data_t *head = NULL, *node, *last = NULL; unsigned int id; if ((f = fopen(PATH_PROC_PCI, "r"))) { while (getline(&line, &len, f) >= 0) { if (line[0] == '\n' || line[0] == '#') { continue; } node = _discover_sysdep_data_new(); sscanf(line, "%*04x\t%08x", &id); node->vendor = (id >> 16); node->model = id & 0xffff; if (head == NULL) { head = node; last = head; } else { last->next = node; last = node; } } free(line); fclose(f); } return head; } |
<!-- $Progeny$ --> <!ELEMENT discover-data (location)*> <!ELEMENT location EMPTY> <!ATTLIST location bus NMTOKEN #REQUIRED type NMTOKEN #REQUIRED url CDATA #REQUIRED> <!ELEMENT busclass_list (busclass)*> <!ATTLIST busclass_list bus NMTOKEN #REQUIRED> <!ELEMENT busclass EMPTY> <!ATTLIST busclass id NMTOKEN #REQUIRED name NMTOKEN #REQUIRED> <!ELEMENT vendor_list (vendor)*> <!ATTLIST vendor_list bus NMTOKEN #REQUIRED> <!ELEMENT vendor EMPTY> <!ATTLIST vendor id CDATA #REQUIRED name CDATA #REQUIRED> <!ELEMENT device_list (device)*> <!ATTLIST device_list bus NMTOKEN #REQUIRED> <!ELEMENT device (data)*> <!ATTLIST device busclass NMTOKEN #REQUIRED model CDATA #DEFAULT default model_name CDATA #REQUIRED vendor CDATA #REQUIRED> <!ELEMENT data (#PCDATA|data)*> <!ATTLIST data class NMTOKEN #REQUIRED version CDATA #IMPLIED> <!-- vim:set ai et sts=8 sw=8 tw=0: --> |
<!-- $Progeny$ --> <!ELEMENT conffile (busscan*,data-sources?)> <!ELEMENT data-sources (data-source)*> <!ELEMENT data-source EMPTY> <!ATTLIST data-source url CDATA #REQUIRED label CDATA #IMPLIED place NMTOKEN #IMPLIED> <!ELEMENT busscan (bus)*> <!-- The attributes will likely be handled by different parts of --> <!-- Discover. If there is a list of buses never to scan, the library --> <!-- should be aware of it. If there is a list of buses to scan by --> <!-- default, that will be of interest to the client tool. --> <!ATTLIST busscan scan (default|never) #REQUIRED> <!ELEMENT bus EMPTY> <!ATTLIST bus name NMTOKEN #REQUIRED> |
It should be noted that the Linux-specific files in the sysdeps/linux directory of the source distribution are derived from code written for the Detect library by MandrakeSoft SA, and are licensed under the GNU Project's General Public License (GPL).
Note that section 2 of the GPL places requirements on derived works that prevent licensees from exercising some of the permissions granted under the license on the rest of Discover. However, not everyone who modifies or distributes Discover will necessarily be subject to the terms of the GPL. If you do not compile, use, or distribute the Linux sysdeps (for instance, if you are building Discover for FreeBSD), then the license terms on them do not attach.
We realize, however, that it is desirable that all of Discover be under the the same license terms. There are a few possible solutions to this problem:
If you do not need the Linux sysdeps, you can delete them from your copy of Discover.
You can rewrite the Linux sysdeps. The resulting code will be your work, so the only limitations on you will be those imposed by Discover's license. If you do so, we encourage you to license your rewrite under the same terms as the rest of Discover — in that event, Progeny will be happy to incorporate your code into a future release of Discover.
You can contact MandrakeSoft SA and negotiate a different license to their code that is used in the Linux sysdeps.
You can contact MandrakeSoft SA and attempt to persuade them to relicense their code that is used in the Linux sydeps under the terms used by the rest of Discover. (MandrakeSoft SA would not have to abandon or assign their copyright.) If you succeed in this effort, please let Progeny know and we will update the license terms on our copy of the MandrakeSoft SA code.
You can wait; eventually Progeny employees, or some volunteer, will rewrite the Linux sysdeps and license them under the terms that the rest of Discover uses.
The foregoing discussing is not legal advice and makes no claim to be such. It is a layperson's understanding of the licensing issues from a software developer's perspective. Progeny makes no warranties or guarantees as to the accuracy of the above analysis in a legal context. If you require a professional legal opinion, consult attorneys specializing in copyright and licensed to practice in the jurisdictions of interest to you or to your organization. |
[1] | Other protocols such as FTP are available but deprecated; Discover uses integrity verification mechanisms such as MD5 checksums in the HTTP protocol. |
[2] | We would say [2.2,2.3) instead, but, like many Free Software projects, the Linux kernel uses odd minor version numbers to denote unstable, development series of the software, and even minor version numbers to denote stable, production series of the software. In the example, then, we arbitrarily treat all 2.3 series kernels the same as 2.2 kernels. |