Character Device Autoconfiguration
The attach(9E) routine should perform the common initialization tasks that all devices
require, such as:
Allocating per-instance state structures
Registering device interrupts
Mapping the device's registers
Initializing mutex variables and condition variables
Creating power-manageable components
Creating minor nodes
See attach() Entry Point for code examples of these tasks.
Character device drivers create minor nodes of type S_IFCHR. A minor node of
S_IFCHR causes a character special file that represents the node to eventually appear
in the /devices hierarchy.
The following example shows a typical attach(9E) routine for character drivers. Properties that
are associated with the device are commonly declared in an attach() routine.
This example uses a predefined Size property. Size is the equivalent of
the Nblocks property for getting the size of partition in a block
device. If, for example, you are doing character I/O on a disk device,
you might use Size to get the size of a partition. Since Size
is a 64-bit property, you must use a 64-bit property interface. In this
case, you use ddi_prop_update_int64(9F). See Device Properties for more information about properties.
Example 15-1 Character Driver attach() Routine
static int
xxattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
int instance = ddi_get_instance(dip);
switch (cmd) {
case DDI_ATTACH:
/*
* Allocate a state structure and initialize it.
* Map the device's registers.
* Add the device driver's interrupt handler(s).
* Initialize any mutexes and condition variables.
* Create power manageable components.
*
* Create the device's minor node. Note that the node_type
* argument is set to DDI_NT_TAPE.
*/
if (ddi_create_minor_node(dip, minor_name, S_IFCHR,
instance, DDI_NT_TAPE, 0) == DDI_FAILURE)
{
/* Free resources allocated so far. */
/* Remove any previously allocated minor nodes. */
ddi_remove_minor_node(dip, NULL);
return (DDI_FAILURE);
}
/*
* Create driver properties like "Size." Use "Size"
* instead of "size" to ensure the property works
* for large bytecounts.
*/
xsp->Size = size_of_device_in_bytes;
maj_number = ddi_driver_major(dip);
if (ddi_prop_update_int64(makedevice(maj_number, instance),
dip, "Size", xsp->Size) != DDI_PROP_SUCCESS) {
cmn_err(CE_CONT, "%s: cannot create Size property\n",
ddi_get_name(dip));
/* Free resources allocated so far. */
return (DDI_FAILURE);
}
/* ... */
return (DDI_SUCCESS);
case DDI_RESUME:
/* See the "Power Management" chapter in this book. */
default:
return (DDI_FAILURE);
}
}