Writing Device Drivers

Properties

Properties define arbitrary characteristics of the device or device driver. Properties may be defined by the FCode of a self-identifying device, by a hardware configuration file (see driver.conf(4)), or by the driver itself using the ddi_prop_update(9F) family of routines.

A property is a name-value pair. The name is a string that identifies the property with an associated value. Examples of properties are the height and width of a frame buffer, the number of blocks in a partition of a block device, or the name of a device. The value of a property can be one of five types:

A property that has no value is known as a Boolean property. It is considered to be true if it exists and false if it doesn't exist.


Note -

Strictly speaking, DDI/DKI software property names are not restricted in any way; however, there are certain recommended uses. As defined in IEEE 1275-1994 (the Standard for Boot Firmware), a property "is a human readable text string consisting of one to thirty-one printable characters. Property names shall not 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. Also by convention, property names ending with the question mark character (auto-boot?) contain values that are strings, typically true or false.


A driver can request a property from its parent, which in turn might ask its parent. The driver can control whether the request can go higher than its parent.

For example, the "esp" driver maintains an integer property for each target called target x-sync-speed, where "x" is the target number. The prtconf(1M) command in its verbose mode displays driver properties. The following example shows a partial listing for the "esp" driver.

test% prtconf -v
...
       esp, instance #0
            Driver software properties:
                name <target2-sync-speed> length <4>
                    value <0x00000fa0>.
...

Table 3-2 provides information on the property interfaces.

Table 3-2 Property Interface Uses

Family 

Property Interfaces 

Description 

ddi_prop_lookup 

ddi_prop_exists(9F)

Looks up property and returns success if one exists. Returns failure if one does not exist.  

 

ddi_prop_get_int(9F)

Looks up and returns an integer property. 

 

ddi_prop_lookup_int_array(9F)

Looks up and returns an integer array property. 

 

ddi_prop_lookup_string(9F)

Looks up and returns a string property. 

 

ddi_prop_lookup_string_array(9F)

Looks up and returns a string array property. 

 

ddi_prop_lookup_byte_array(9F)

Looks up and returns a byte array property. 

ddi_prop_update 

ddi_prop_update_int(9F)

Updates an integer property. 

 

ddi_prop_update_int_array(9F)

Updates an integer array property. 

 

ddi_prop_update_string(9F)

Updates a string property. 

 

ddi_prop_update_string_array(9F)

Updates an string array property. 

 

ddi_prop_update_byte_array(9F)

Updates a byte array property. 

ddi_prop_remove 

ddi_prop_remove(9F)

Removes a property. 

 

ddi_prop_remove_all(9F)

Removes all properties associated with a device.  

prop_op(9E)

The prop_op(9E) entry point reports the values of device properties to the system. In many cases, the ddi_prop_op(9F) routine may be used as the driver's prop_op(9E) entry point in the cb_ops(9S) structure. ddi_prop_op(9F) performs all of the required processing and is sufficient for drivers that do not need to perform any special processing when handling a device property request.

However, there are cases when it is necessary for the driver to provide a prop_op(9E) entry point. For example, if a driver maintains a property whose value changes frequently, updating the property with ddi_prop_update(9F) each time it changes may not be efficient. Instead, the driver can maintain a local copy of the property in a C variable. The driver updates the C variable when the value of the property changes and does not call one of the ddi_prop_update(9F) routines. In this case, the prop_op(9E) entry point would need to intercept requests for this property and call one of the ddi_prop_update(9F) routines to update the value of the property before passing the request to ddi_prop_op(9F) to process the property request. See Example 3-4.

Here is the prop_op(9E) prototype:

int xxprop_op(dev_t dev, dev_info_t *dip,
 	ddi_prop_op_t  prop_op, int flags, char *name,
 	caddr_t valuep, int *lengthp);

Example 3-4 shows a simple implementation of the prop_op(9E) routine. This routine intercepts property requests and then uses the existing software property routines to update property values. For a complete description of all the parameters to (9E), see the manual page.

In Example 3-4, prop_op(9E) intercepts requests for the temperature property. The driver updates a variable in the state structure whenever the property changes but only updates the property when a request is made. It then uses the system routine ddi_prop_op(9F) to process the property request. If the property request is not specific to a device, the driver does not intercept the request. This is indicated when the value of the dev parameter is equal to DDI_DEV_T_ANY (the wildcard device number).

This example adds the following field to the state structure. See "Software State Structure" for more information.

	int		temperature; /* current device temperature */

Example 3-4 prop_op(9E) Routine

static int
xxprop_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 */	
}