Device-enumerator manager
You must be root to start this manager. |
enum-devices options
Neutrino
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.
This description of enum-devices includes the following sections;
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.
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. |
Matching behavior for enum-devices is based on the “number of matches” in the enum-devices configuration file device statement. A secondary device statement may be created by placing a period (“.”) in front of the match field.
This method for matching devices with entries in the enum-devices configuration file can sometimes result in “ambiguities”: a specified device that matches more than one entry in the enum-devices configuration file, rendering it impossible for the enumerator to select the preferred driver for the device.
For example, with a device fully specified as:
ven=1922,dev=1234,busno=0,devno=1, rev=100,msven=fe,mscomp=MTP,mssubcomp=0
and with the following in the enum-devices configuration file:
device(usb, ven=1922,dev=1234) device(usb, class=08,proto=00)
the specified device matches both the entries in the configuration file.
This ambiguity can be removed by either extending the match criteria for the preferred driver:
device(usb, ven=1922,dev=1234,class=08)
or by making one of the matching fields secondary; that is, by giving it a lower precedence that the other fields:
device(usb, .class=08,proto=00)
A “catch all” (an action that matches any device) is produced by simply entering the bus type for the device. For example:
device(usb) echo("No match found for device ven=$(ven), dev=$(dev), class=$(class), busno=$(busno), devno=$(devno), cfg=$(cfg), iface=$(iface), msven=$(msven), mscomp=$(mscomp), mssubcomp=$(mssubcomp)" )
Configuration files in the etc/system/enum/ directory include:
Configuration files in the etc/system/enum/devices/ directory contain device definitions; these files include:
Configuration files in the etc/system/enum/devices/usb/ directory include:
Configuration files in the etc/system/enum/include/ directory contain macro definitions; they include:
The order of precedence for enum-devices configuration files is determined by one or both of the following criteria:
If files are added to an enumeration directory after the enumeration utility has been started, the enumerator picks up these files and assigns them a higher precedence than currently existing files.
Given the complexity associated with adding and removing files and directories during processing, QNX recommends that you:
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.
The enum-devices configuration file is typically takes the following format:
/enum common /devices default net mass char /include usb-class /overrides mass
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:
The clauses are described in the sections that follow.
The start clause takes this form:
start[/wait] (system_command [, system_args] )
It runs the command and arguments specified by system_command. If you specify the /wait option, the enumerator pauses until the command terminates.
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.)
The requires clause can be one of two forms:
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-pkt*:
requires($(IOPKT_CMD),)
If you specify the /wait option in either form, the enumerator pauses until the command terminates.
The driver clause looks like this:
driver[/wait] (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.
If you specify the /wait option, the enumerator pauses until the command terminates.
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.
The enumerator clause takes this form:
enumerator (enumerator_type)
It starts a new bus enumerator named enumerator_type.
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.
The append clause looks like this:
append (macro_name, macro_definition)
This clause appends macro_definition to the definition of macro_name.
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)")
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.
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.
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.
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.
The use clause looks like this:
use (device_list)
When enum-devices encounters this clause, it:
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:
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:
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"
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.
apid { macro=definition }
If another bus enumerator reports the device, its driver shouldn't be started since it's already running.
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.
Bpid { macro=definition }
It has the same syntax and requirements as ENUMER_CODE_DEV_PERM.
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.
Epid error_message_text
The enum-devices manager displays the error_message_text displayed to the user.
#pid comment_text
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-pkt-v4, -d speedo pci=$(index) ) # Start a network driver (with mount support) device(cardbus,1234,5678) requires( io-pkt-v4 ) 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" )
|
Controlling How Neutrino Starts in the Neutrino User's Guide