Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Writing Device Drivers
Previous Next

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);
  }
}
Previous Next

 
 
  Published under the terms fo the Public Documentation License Version 1.01. Design by Interspire