Device Properties
Device attribute information can be represented by a name-value pair notation called a
property.
For example, device registers and onboard memory can be represented by the reg
property. The reg property is a software abstraction that describes device hardware registers.
The value of the reg property encodes the device register address location and size.
Drivers use the reg property to access device registers.
Another example is the interrupt property. An interrupt property represents the device
interrupt. The value of the interrupt property encodes the device-interrupt PIN.
Five types of values can be assigned to properties:
Byte array – Series of bytes of an arbitrary length
Integer property – An integer value
Integer array property – An array of integers
String property – A null-terminated string
String array property – A list of null-terminated strings
A property that has no value is considered to be a Boolean
property. A Boolean property that exists is true. A Boolean value that does
not exist is false.
Device Property Names
Strictly speaking, DDI/DKI software property names have no restrictions. Certain uses are recommended,
however. The IEEE 1275-1994 Standard for Boot Firmware defines properties as follows:
A property is a human readable text string consisting of from 1 to
31 printable characters. Property names cannot contain upper case characters or the characters
“/”, “\”, “:”, “[“, “]” and “@”. Property names beginning with the character
“+” are reserved for use by future revisions of IEEE 1275-1994.
By convention, underscores are not used in property names. Use a hyphen (-)
instead. By convention, property names ending with the question mark character (?) contain
values that are strings, typically TRUE or FALSE, for example auto-boot?.
Predefined property names are listed in publications of the IEEE 1275 Working Group.
See https://playground.sun.com/1275/ for information about how to obtain these publications. For a discussion
of adding properties in driver configuration files, see the driver.conf(4) man page. The
pm(9P) and pm-components(9P) man pages show how properties are used in power
management. Read the sd(7D) man page as an example of how properties should be
documented in device driver man pages.
Creating and Updating Properties
To create a property for a driver, or to update an existing
property, use an interface from the DDI driver update interfaces such as ddi_prop_update_int(9F)
or ddi_prop_update_string(9F) with the appropriate property type. See Table 4-1 for a list of
available property interfaces. These interfaces are typically called from the driver's attach(9E) entry
point. In the following example, ddi_prop_update_string()creates a string property called pm-hardware-state with a value
of needs-suspend-resume.
/* The following code is to tell cpr that this device
* needs to be suspended and resumed.
*/
(void) ddi_prop_update_string(device, dip,
"pm-hardware-state", "needs-suspend-resume");
In most cases, using a ddi_prop_update() routine is sufficient for updating a property.
Sometimes, however, the overhead of updating a property value that is subject to
frequent change can cause performance problems. See prop_op() Entry Point for a description of using a
local instance of a property value to avoid using ddi_prop_update().
Looking Up Properties
A driver can request a property from its parent, which in turn
can ask its parent. The driver can control whether the request can go
higher than its parent.
For example, the esp driver in the following example maintains an integer
property called targetx-sync-speed for each target. The x in targetx-sync-speed represents the target
number. The prtconf(1M) command displays driver properties in verbose mode. The following example
shows a partial listing for the esp driver.
% prtconf -v
...
esp, instance #0
Driver software properties:
name <target2-sync-speed> length <4>
value <0x00000fa0>.
...
The following table provides a summary of the property interfaces.
Table 4-1 Property Interface Uses
Whenever possible, use 64-bit versions of int property interfaces such as ddi_prop_update_int64(9F) instead
of 32-bit versions such as ddi_prop_update_int(9F)).
prop_op() Entry Point
The prop_op(9E) entry point is generally required for reporting device properties or driver
properties to the system. If the driver does not need to create or
manage its own properties, then the ddi_prop_op(9F) function can be used for this
entry point.
ddi_prop_op(9F) can be used as the prop_op(9E) entry point for a device driver
when ddi_prop_op() is defined in the driver's cb_ops(9S) structure. ddi_prop_op() enables a
leaf device to search for and obtain property values from the device's property
list.
If the driver has to maintain a property whose value changes frequently, you
should define a driver-specific prop_op() routine within the cb_ops structure instead of calling
ddi_prop_op(). This technique avoids the inefficiency of using ddi_prop_update() repeatedly. The driver
should then maintain a copy of the property value either within its soft-state
structure or in a driver variable.
The prop_op(9E) entry point reports the values of specific driver properties and device
properties to the system. In many cases, the ddi_prop_op(9F) routine can be used
as the driver's prop_op() entry point in the cb_ops(9S) structure. ddi_prop_op() performs all
of the required processing. ddi_prop_op() is sufficient for drivers that do not
require special processing when handling device property requests.
However, sometimes the driver must provide a prop_op() entry point. For example, if
a driver maintains a property whose value changes frequently, updating the property with
ddi_prop_update(9F) for each change is not efficient. Instead, the driver should maintain a
shadow copy of the property in the instance's soft state. The driver would
then update the shadow copy when the value changes without using any of
the ddi_prop_update() routines. The prop_op() entry point must intercept requests for this
property and use one of the ddi_prop_update() routines to update the value of the
property before passing the request to ddi_prop_op() to process the property request.
In the following example, prop_op() intercepts requests for the temperature property. The driver
updates a variable in the state structure whenever the property changes. However, the
property is updated only when a request is made. The driver then uses
ddi_prop_op() to process the property request. If the property request is not specific
to a device, the driver does not intercept the request. This situation is
indicated when the value of the dev parameter is equal to DDI_DEV_T_ANY, the
wildcard device number.
Example 4-1 prop_op() Routine
static int
xx_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
int flags, char *name, caddr_t valuep, int *lengthp)
{
minor_t instance;
struct xxstate *xsp;
if (dev != DDI_DEV_T_ANY) {
return (ddi_prop_op(dev, dip, prop_op, flags, name,
valuep, lengthp));
}
instance = getminor(dev);
xsp = ddi_get_soft_state(statep, instance);
if (xsp == NULL)
return (DDI_PROP_NOTFOUND);
if (strcmp(name, "temperature") == 0) {
ddi_prop_update_int(dev, dip, name, temperature);
}
/* other cases */
}