Writing Device Drivers

Character Device Autoconfiguration

The attach(9E) routine should perform the common initialization tasks that all devices require. Typically, these tasks include:

See The attach() Entry Point for code examples of these tasks.

Character device drivers create minor nodes of type S_IFCHR. This causes a character special file representing the node to eventually appear in the /devices hierarchy.

Example 10–1 shows a sample attach(9E) routine. It is common to declare any properties associated with the device in an attach() routine; in this example, it is the predefined Size property. Size is the equivalent of the Nblocks property used 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—the 32–bit version is size—you must use a 64–bit property interface, in this case ddi_prop_updtate_int64(9E) See Device Properties for more on properties.


Example 10–1 Character Driver attach(9E) 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:
        For information, see Chapter 9, Power Management   
default:
        return (DDI_FAILURE);
      }
}