The Discover Hardware Detection System

G. Branden Robinson

John R. Daily

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.

Linux is a registered trademark of Linus Torvalds.

$Progeny$

Table of Contents
What Is Discover?
I. Data Structure
1. Overview of the Discover Data Format
2. Master List
3. Busclass Lists
3.1. The busclass_list element
3.1.1. The bus attribute
3.2. The busclass element
3.2.1. The id attribute
3.2.2. The name attribute
4. Vendor Lists
4.1. The vendor_list element
4.1.1. The bus attribute
4.2. The vendor element
4.2.1. The id attribute
4.2.2. The name attribute
5. Device Lists
5.1. The device_list element
5.1.1. The bus attribute
5.2. The device element
5.3. The data element
5.3.1. The class attribute
5.3.2. The version attribute
5.4. Accessing the Device Data
II. Recommended Data Content Conventions
6. Data Hierarchy
6.1. Linux Kernel Modules
6.2. XFree86 X Servers
6.3. Locally-Defined Interfaces
7. Why Order Matters
8. Using Data Versioning
8.1. Specifying a Range
8.2. How the Discover Library Matches a Range
III. Command-Line Tools
9. discover Manual Page
discover -- hardware detection utility
10. discover.conf Manual Page
discover.conf -- configuration file format for discover(1)
11. discover-modprobe Manual Page
discover-modprobe -- kernel module loading using discover(1)
12. discover-modprobe.conf Manual Page
discover-modprobe.conf -- configuration file for discover-modprobe(5)
IV. Library
13. The Discover Library
13.1. Library Design Principles
13.2. Discover Data Sources
13.3. The Bus Map
13.4. Scanning the System
13.5. Using discover_device_t Structures
14. System Dependencies
14.1. API
A. Discover API Reference
B. Discover DTD
C. Discover Configuration File DTD
D. Licensing Issue on the Linux Sysdeps
List of Figures
6-1. Linux interface
6-2. XFree86 interface
List of Examples
3-1. The busclass_list element
4-1. The vendor_list element
5-1. Sample device data
6-1. Defining an interface
6-2. Using the linux interface
6-3. Using the xfree86 interface
7-1. Matching device elements
8-1. Using the version attribute of the data element
9-1. Scan the local buses
9-2. View PCI video cards
9-3. Query for the driver module for XFree86 server version 4.2.0
9-4. Get model and vendor information by type
10-1. Establishing default buses to scan
10-2. A more complex example
14-1. Linux PCI sysdep code

What Is Discover?

Discover 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:

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.


Chapter 1. Overview of the Discover Data Format

Most 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.


Chapter 2. Master List

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.


Chapter 3. Busclass Lists

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.


3.1. The busclass_list element

A busclass_list element possesses a bus attribute and contains one or more busclass elements.


3.1.1. The bus attribute

The 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.


3.2. The busclass element

A busclass element possesses two attributes, id and name, and contains no elements.


3.2.1. The id attribute

The id attribute is set to a bus-specific device class identifier.


3.2.2. The name attribute

The 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.


Chapter 4. Vendor Lists

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.


4.1. The vendor_list element

A vendor_list element possesses a bus attribute and contains one or more vendor elements.


4.1.1. The bus attribute

The 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


4.2. The vendor element

A vendor element possesses two attributes, id and name, and contains no elements.


4.2.1. The id attribute

The id attribute is set to a bus-specific vendor identifier.


4.2.2. The name attribute

The 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.


Chapter 5. Device Lists

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.

Note

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.


5.1. The device_list element

A device_list element possesses a bus attribute and contains one or more device elements.


5.1.1. The bus attribute

The 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


5.2. The device element

A 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.


5.3. The data element

A 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.


5.3.1. The class attribute

A 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.


5.3.2. The version attribute

Data 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.


5.4. Accessing the Device Data

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":

<data class="foo">
  <data class="bar">quux</data>
</data>

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.

II. Recommended Data Content Conventions

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.


Chapter 6. Data Hierarchy

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.


6.1. Linux Kernel Modules

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.

Figure 6-1. Linux interface

/linux
    |
    |-/module
          |
          |-/name
          |
          |-/options

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.


6.2. XFree86 X Servers

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>

6.3. Locally-Defined Interfaces

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.)


Chapter 7. Why Order Matters

When searching device elements, the first exact match will be selected. Subsequent matches are ignored.

Specifically, three comparisons are made:

  1. 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.

  2. The class attributes of child data elements must match the data path as given to the library for searching.

  3. 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.


<device busclass="0000" vendor="102f" model="5555" model_name="100VG ethernet">
  <data class="linux" version="[2.4, inf)">(1)
    <data class="modules">
        <data class="name">vg100</data>
    </data>
  </data>
  <data class="linux" version="[2.0, 2.2)">(2)
    <data class="module">
        <data class="name">vg100</data>
        <data class="options">io=0x300</data>
    </data>
  </data>
</device>

<device busclass="0000" vendor="102f" model="5555" model_name="100VG ethernet">
  <data class="linux">(3)
    <data class="module">
        <data class="name">vg100new</data>
    </data>
  </data>
  <data class="linux" version="[2.4, inf)">(4)
    <data class="module">
        <data class="name">vg100old</data>
    </data>
  </data>
</device>

(1)
This item is the first one scanned, and would match, except that the requested data path includes "module" as a component, not "modules" as specified here.
(2)
This item doesn't match because the provided range is outside the limits defined by the element. (2.4.2 is not greater than or equal to 2.0 and less than 2.2.)
(3)
This item matches because no range is given, so "vg100new" is the value returned.
(4)
This is the nearest match, but the Discover library will never select it because its previous sibling has no version range, and thus will catch any version provided.

Chapter 8. Using Data Versioning

8.1. Specifying a Range

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.


8.2. How the Discover Library Matches a Range

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.

III. Command-Line Tools

Table of Contents
9. discover Manual Page
discover -- hardware detection utility
10. discover.conf Manual Page
discover.conf -- configuration file format for discover(1)
11. discover-modprobe Manual Page
discover-modprobe -- kernel module loading using discover(1)
12. discover-modprobe.conf Manual Page
discover-modprobe.conf -- configuration file for discover-modprobe(5)

Chapter 9. discover Manual Page

discover

Name

discover -- hardware detection utility

Synopsis

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...]

DATA_OPTIONS

  • -d | --disable-bus=bus

  • -e | --enable-bus=bus

  • --insert-url=url

  • --append-url=url

  • -v | --verbose

DISPLAY_OPTIONS

  • --model | --no-model

  • --model-id | --no-model-id

  • --vendor | --no-vendor

  • --vendor-id | --no-vendor-id

Description

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.

Options

-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.

Selecting Buses

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

Device Types

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.

Examples

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]

Example 9-3. Query for the driver module for XFree86 server version 4.2.0

# discover --data-path=xfree86/server/device/driver --data-version=4.2.0 display
ati

Example 9-4. Get model and vendor information by type

$ discover -t --no-model
Intel Corporation
NVIDIA Corporation
3Com Corporation
$ discover -t --no-vendor
82815 System Management bus controller
Vanta [NV6]
3c905C-TX [Fast Etherlink]

Files

/etc/discover.conf.d

The directory containing configuration files that control the default behavior for both the discover tool and the Discover library.

file:///lib/discover/list.xml

An XML file containing URLs with hardware information. This list can be extended with --append-url and --extend-url.

Authors

Josh Bressers, John R. Daily, and G. Branden Robinson developed the current implementation of Discover for Progeny Linux Systems.

The Linux implementation of the system-dependent interfaces is derived from detect, by MandrakeSoft SA.

See Also

discover.conf(5), discover-modprobe(8)


Chapter 10. discover.conf Manual Page

discover.conf

Name

discover.conf -- configuration file format for discover(1)

Description

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.

Examples

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>

Authors

Josh Bressers, John R. Daily, and G. Branden Robinson developed the current implementation of Discover for Progeny Linux Systems.

The Linux implementation of the system-dependent interfaces is derived from detect, by MandrakeSoft SA.

See Also

discover(1)


Chapter 11. discover-modprobe Manual Page

discover-modprobe

Name

discover-modprobe -- kernel module loading using discover(1)

Synopsis

discover-modprobe [-n] [-v]

Description

discover-modprobe loads kernel modules identified by discover. It will typically be invoked automatically at boot time.

Options

-n

Echo the modprobe invocations instead of running them.

-v

Be verbose.

Files

/etc/discover-modprobe.conf

This configuration file defines the types of modules to load by default, and specific modules not to load.

/var/lib/discover/crash

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.

See Also

discover-modprobe.conf(5), modprobe(8), discover(1)


Chapter 12. discover-modprobe.conf Manual Page

discover-modprobe.conf

Name

discover-modprobe.conf -- configuration file for discover-modprobe(5)

Description

discover-modprobe.conf is the configuration file for discover-modprobe, which is responsible for retrieving and loading kernel modules.

Warning

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.

types

This describes the classes of hardware that should be scanned and queried.

skip

These modules should never be loaded. See the "Files" section for details on the mechanism for generating these entries automatically.

Files

/var/lib/discover/crash

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.

See Also

discover-modprobe(8), modprobe(8), discover(1)


Chapter 13. The Discover Library

13.1. Library Design Principles

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.


13.2. Discover Data Sources

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.


13.3. The Bus Map

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.


13.4. Scanning the System

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:

devices = discover_get_pci_devices(&status);
check_status(status);
do_something_cool(devices);

Perhaps most usefully, you can scan for devices of a specific type:

devices = discover_device_find("video", &status);
check_status(status);
do_something_video(devices);


13.5. Using discover_device_t Structures

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.


Chapter 14. System Dependencies

14.1. API

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;
}

Appendix A. Discover API Reference

The API reference is here.


Appendix B. Discover DTD


<!-- $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: -->

    

Appendix C. Discover Configuration File DTD


<!-- $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>

    

Appendix D. Licensing Issue on the Linux Sysdeps

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:

Note

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.

Notes

[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.