The libdevinfo library contains a set of interfaces for accessing device configuration data.
Device configuration data is organized as a tree of device nodes, defined as di_node_t in the libdevinfo interfaces. Each di_node_t represents a physical or logical (pseudo) device. Three types of data are associated with device nodes:
- data defined for all device nodes (attributes)
- properties specific to each device
- minor node data
All device nodes have a set of common attributes, such as a node name, an instance number, and a driver binding name. Common device node attributes are accessed by calling interfaces listed on the di_binding_name(3DEVINFO) man page. Each device node also has a physical path, which is accessed by calling di_devfs_path(3DEVINFO).
Properties provide device specific information for device configuration and usage. Properties may be defined by software (di_prop_t) or by firmware (di_prom_prop_t). One way to access each di_prop_t is to make successive calls to di_prop_next(3DEVINFO) until DI_PROP_NIL is returned. For each di_prop_t, use interfaces on the di_prop_bytes(3DEVINFO) man page to obtain property names and values. Another way to access these properties is to call di_prop_lookup_bytes(3DEVINFO) to find the value of a property with a given name. Accessing a di_prom_prop_t is similar to accessing a di_prop_t, except that the interface names start with di_prom_prop and additional calls
to di_prom_init(3DEVINFO) and di_prom_fini(3DEVINFO)
are required.
Minor nodes contain information exported by the device for creating special files for the device. Each device node has 0 or more minor nodes associated with it. A list minor nodes (di_minor_t) may be obtained by making successive calls to di_minor_next(3DEVINFO) until DI_MINOR_NIL is returned. For each minor node, di_minor_devt(3DEVINFO) and related interfaces are called to get minor node data.
Using libdevinfo involves three steps:
- Creating a snapshot of the device tree
- Traversing the device tree to get information of interest
- Destroying the snapshot of the device tree
A snapshot of the device tree is created by calling di_init(3DEVINFO) and destroyed by calling di_fini(3DEVINFO). An application can specify the data to be included in the snapshot (full or partial tree, include or exclude properties and minor nodes) and get a handle to the root of the device tree. See di_init(3DEVINFO) for details. The application then traverses the device tree in the snapshot to obtain device configuration data.
The device tree is normally traversed through parent-child-sibling linkage. Each device node contains references to its parent, its next sibling, and the first of its children. Given the di_node_t returned from di_init(3DEVINFO), one can find all children by first calling di_child_node(3DEVINFO), followed by successive calls to di_sibling_node(3DEVINFO), until DI_NODE_NIL is returned. By following this procedure recursively, an application can visit all device nodes contained in
the snapshot. Two interfaces, di_walk_node(3DEVINFO) and di_walk_minor(3DEVINFO), are provided to facilitate device tree traversal. The di_walk_node(3DEVINFO) interface visits all device nodes and executes a user-supplied callback function
for each node visited. The di_walk_minor(3DEVINFO) does the same for each minor node in the device tree.
An alternative way to traverse the device tree is through the per-driver device node linkage. Device nodes contain a reference to the next device node bound to the same driver. Given the di_node_t returned from di_init(3DEVINFO), an application can find all device nodes bound to a driver by first calling di_drv_first_node(3DEVINFO),
followed by successive calls to di_drv_next_node(3DEVINFO) until DI_NODE_NIL is returned. Note that traversing the per-driver device node list works
only when the snapshot includes all device nodes.
See libdevinfo(3LIB) for a complete list of libdevinfo interfaces. See di_init(3DEVINFO) for examples of libdevinfo usage. See Writing Device Drivers for details of Solaris device configuration.
|