[Previous] [Contents] [Index] [Next]

enum-devices

Device-enumerator manager


Note: You must be root to start this manager.

Syntax:

enum-devices options

Options:

-c path
Specify one or more configuration files. The path can either be a single file, or the name of a directory:

You can repeat this option to specify multiple configuration files and directories; you can also use a config clause in a configuration file to include other files and directories (see below).

Before it starts processing, enum-devices concatenates the contents of all the configuration files that you tell it to read.

-D
Dump the device-lookup table.
-E enumerator
Start the second-pass enumerator program.
-e enumerator
Start the given enumerator command:
-i prefix
Ignore any configuration files in directories whose names start with prefix.
-I suffix
Ignore any configuration files in directories whose names end with suffix.
-n
Write the commands for starting the drivers to standard output rather than executing them.
-v[v...]
Operate verbosely. The more v characters, the more verbose the output is.

Description:

The enum-devices manager enumerates the devices present on your computer. This manager first reads the configuration files specified by any -c command-line options.

Next, the configuration manager queries its various enumerators to discover what devices are on the system. It then matches these devices against the device IDs listed in the configuration files. If the device matches, enum-devices executes the action clauses associated with the device.


Note: Programs that are spawned by any start and requires clauses aren't actually started until all processing is completed, so that any built-up command lines are finished. If you want to perform an action regardless of what devices are present, use the all device ID.

Configuration file contents

A configuration file consists of statements for one or more devices. Each statement contains clauses that you want to execute if enum-devices finds those devices on your system.

Anything after a number sign (#) until the end of the line is considered a comment.

Each statement is in this form:

device_id...
   action_clause
   ...

The device_id is either the keyword all or any number of identifiers in this form:

device(bus_type[, specification]...)

The bus types include at least the following:

Each clause is a keyword, followed by any required arguments. The clauses include:

start
Start a command.
requires
Start a command if it isn't already running.
driver
Start a command as an individual driver if the device might be removed.
mount
Run the mount utility with the specified arguments.
enumerator
Start a new bus enumerator.
set
Set a macro.
append
Add to a macro definition.
uniq
Set a macro to a value that depends on whether or not a string is found in an internal database.
waitfor
Wait for a given pathname to appear.
echo
Echo a string to a file.
tag
Assign a name to a block of action clauses.
config
Load additional configuration files or directories.
use
Merge macro definitions.

The clauses are described in the sections that follow.

start clause

The start clause takes this form:

start (system_command [, system_args] )

It runs the command and arguments specified by system_command.

If you specify system_args, the manager searches for a start clause with a system_command that's identical to this one, and appends system_args to its command line. This is a useful way to start just one instance of a command, specifying the arguments needed for all of the devices found.

For example, this clause:

start(spooler -d$(path), -P$(pnpstr))

says to start spooler -d$(path), but tells enum-devices that if it's already encountered this command, just append -P$(pnpstr) to it. (The $(...) notation is for macro expansion; see the set clause, below.)

requires clause

The requires clause can be one of two forms:

requires (system_command [, system_args] )
This form is similar to the start clause, but enum-devices checks to make sure that the command isn't already running on the system.
Note: If you specify system_args, don't forget the comma between system_command and system_args; if you omit it, enum-devices doesn't check to see if the command is already running -- it might start the command more than once.

For example, the /etc/system/enum/devices/net enumeration file includes this line for the network devices that need io-net:

requires($(IONET_CMD),)
  
requires (@tag_string)
If you use this form, enum-devices searches all the pending action lines for tag names of tag_name (see the tag clause) and executes them. This can be useful when you need a certain ordering of various components.

driver clause

The driver clause looks like this:

driver (system_command [, system_args] )

It's similar to the start clause, but if the bus-enumerator process indicates that the device might be removed, enum-devices starts an individual driver process for the device (instead of tacking the system_args onto a previously specified driver for the same device). If the bus enumerator indicates that the device has been removed, a SIGTERM signal is sent to the driver process.

mount clause

The mount clause looks like this:

mount (mount_args [, umount_args] )

It spawns the mount command with the given mount_args arguments. If you specify any umount_args, they're passed to umount if or when the device is removed.

enumerator clause

The enumerator clause takes this form:

enumerator (enumerator_type)

It starts a new bus enumerator named enumerator_type.

set clause

The set clause takes this form:

set (macro_name, macro_definition)

This clause sets the definition of macro_name to be macro_definition. Whenever enum-devices finds $(macro_name) in any of the configuration files, it substitutes the macro_definition. For example:

set(DEVB_OPTIONS, cam quiet blk auto=partition)

You can recursively nest macros the way that you can in make.

append clause

The append clause looks like this:

append (macro_name, macro_definition)

This clause appends macro_definition to the definition of macro_name.

uniq clause

The uniq clause is in this form:

uniq (macro_name, uniq_name [, initial] )

This clause makes enum-devices search an internal database for the string uniq_name:

For example, you can use a uniq clause to keep track of how many instances of a device you've found, so you can create a unique path for a device:

uniq(sernum, devc-ser, 1)
driver(devc-ser8250 $(SER_OPTIONS), "-u$(sernum) $(ioport),$(irq)")

waitfor clause

The waitfor clause looks like this:

waitfor (pathname [, timeout] )

This clause makes enum-devices wait for up to timeout tenths of a second for pathname to appear. If you don't specify timeout, enum-devices waits for 10 seconds.

echo clause

The echo clause takes this form:

echo (string [, output_file] )

It echoes string to output_file. If this is the first occurrence of an echo to the file for this invocation of the configuration manager, enum-devices erases output_file before doing the echo. For subsequent occurrences, enum-devices appends to the file. If you don't specify an output_file, the output goes to standard output.

tag clause

The tag clause looks like this:

tag (tag_string)

It gives the name, tag_string, to the subsequent block of action clauses. Use this clause to indicate the commands to run when you use the second form of the requires clause.

config clause

The config clause is in this form:

config (path)

It makes enum-devices load an additional configuration file or directory, as specified by path. This clause works in the same way as the -c command-line option, except that the specified pathname is relative to the configuration file that contains the clause.

use clause

The use clause looks like this:

use (device_list)

When enum-devices encounters this clause, it:

Macros

When invoking an action-clause sequence, a number of of special macros are available for expansion. What they are depends on the bus that the device is present on.

For PCI devices, the macros are:

$(ven)
PCI vendor ID.
$(dev)
PCI device ID.
$(index)
PCI index.
$(busnum)
PCI bus number.
$(function)
PCI function number.

Bus-enumerator protocol

To handle the bus-specific aspects of device enumeration, enum-devices spawns separate bus-enumerator programs. The standard output of these programs is connected to a pipe that enum-devices reads from. As the bus enumerator does its bus scan, it writes lines to standard output describing what it's found. Each line must be written to the pipe atomically. Each line starts with a one-character code (defined in <hw/enumdata.h> in the form ENUMER_CODE_*) and is immediately followed by the process ID of the bus enumerator.

Here are the lines that can be written for each C macro definition:

ENUMER_CODE_DEV_PERM
This line reports a permanently connected device (i.e one that will never be removed while the system is running):
Dpid  { macro=value }
  

A sequence of macro names and values follows the D code and pid. If there's more than one macro, separate them with spaces. These are available for expansion in the action clauses that enum-devices invokes for the device.

You must define the following special macros because enum-devices uses them to identify the device:

#define ENUMER_SYM_BUSTYPE      "bus"
#define ENUMER_SYM_VENDOR       "ven"
#define ENUMER_SYM_SUBVENDOR    "dev"
#define ENUMER_SYM_CLASS        "class"
#define ENUMER_SYM_SUBCLASS     "subclass"
  
ENUMER_CODE_DEV_TEMP
This is similar to ENUMER_CODE_DEV_PERM, except that the device might be removed while the system is running:
dpid  { macro=definition }
  

In addition to the required macro definitions above, be sure to define:

#define ENUMER_SYM_REMOVAL_ID   "removal_id"
  

The macro value should be a simple integer.

ENUMER_CODE_DEV_ACTIVE
This is similar to ENUMER_CODE_DEV_PERM, except that the indicated device is already running on the system:
apid  { macro=definition }
  

If another bus enumerator reports the device, its driver shouldn't be started since it's already running.

ENUMER_CODE_DEV_REMOVED
This line is reported when a device is removed from a running system:
gpid  { macro=definition }
  

The only required macro definition is the ENUMER_SYM_REMOVAL_ID from above. The value should be the same integer that was used when the device was originally reported. The enum-devices program uses it to figure out which driver process to slay or which pathname to unmount.

ENUMER_CODE_BUS
This is used for reporting additional buses that need new enumerators started:
Bpid  { macro=definition }
  

It has the same syntax and requirements as ENUMER_CODE_DEV_PERM.

ENUMER_CODE_SCAN_DONE
Write this line when the bus enumerator has finished scanning its bus:
Fpid
  

When all the bus enumerators started have written this line, enum-devices invokes the required action clauses (note that ENUMER_CODE_BUS actions are invoked immediately). If no devices may be added/deleted from the bus, the bus enumerator should terminate after writing this line. If there are temporary devices, it should remain running and write ENUMER_CODE_DEV_TEMP and/or ENUMER_CODE_DEV_REMOVED events followed by another ENUMER_CODE_SCAN_DONE as devices are inserted or removed.

ENUMER_CODE_ERROR
Write this line when the bus enumerator detects an error of some kind:
Epid    error_message_text
  

The enum-devices manager displays the error_message_text displayed to the user.

ENUMER_CODE_COMMENT
The enum-devices manager ignores this type of line. You can use it to provide additional information when the bus enumerator is run standalone:
#pid    comment_text
  

Examples:

Here's a sample configuration file:

# prefixing generic commands
all
    # so we can say "pci($(ATI), ....) for readability
    set( ATI, 0x1234 )
    echo( "starting configuration" )
    
# Start a hard disk driver
device(pci,1234,5678)
    start( devb-ncr8 ncr8 pci=$(index) )
    
# Start a network driver (currently)
device(pci,0x1234,0x5678)
    start( io-net, -d speedo pci=$(index) )
    
# Start a network driver (with mount support)
device(cardbus,1234,5678)
    requires( io-net )
    start( mount, -T none -o pci=$(index) ne2000 /dev/if0 )
    
# Start a graphics driver (sorta :-)
device(pci,1234,5678)
    echo( $(ven) $(dev) $(bus) $(device) $(function), /etc/devg.$(hostname) )
    
# postfixing generic commands
all
    echo( "Completed configuration" )

See also:

Controlling How Neutrino Starts in the Neutrino User's Guide


[Previous] [Contents] [Index] [Next]