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.
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); } }