|
|||
Part I Designing Device Drivers for the Solaris Platform 1. Overview of Solaris Device Drivers 2. Solaris Kernel and Device Tree 5. Managing Events and Queueing Tasks 7. Device Access: Programmed I/O 10. Mapping Device and Kernel Memory Power Management Flow of Control Changes to Power Management Interfaces 14. Layered Driver Interface (LDI) Part II Designing Specific Kinds of Device Drivers 15. Drivers for Character Devices 18. SCSI Host Bus Adapter Drivers 19. Drivers for Network Devices Part III Building a Device Driver 21. Compiling, Loading, Packaging, and Testing Drivers 22. Debugging, Testing, and Tuning Device Drivers 23. Recommended Coding Practices B. Summary of Solaris DDI/DKI Services C. Making a Device Driver 64-Bit Ready |
Power Management Device Access ExampleIf power management is supported, and detach(9E) and attach(9E) are used as in Example 12-6 and Example 12-7, then access to the device can be made from user context, for example, from read(2), write(2), and ioctl(2). The following example demonstrates this approach. The example assumes that the operation about to be performed requires a component component that is operating at power level level. Example 12-8 Device Accessmutex_enter(&xsp->mu); /* * Block command while device is suspended by DDI_SUSPEND */ while (xsp->xx_suspended) cv_wait(&xsp->xx_suspend_cv, &xsp->mu); /* * Mark component busy so xx_power() will reject attempt to lower power */ xsp->xx_busy[component]++; if (pm_busy_component(dip, component) != DDI_SUCCESS) { xsp->xx_busy[component]--; /* * Log error and abort */ } if (xsp->xx_power_level[component] < level) { mutex_exit(&xsp->mu); if (pm_raise_power(dip, component, level) != DDI_SUCCESS) { /* * Log error and abort */ } mutex_enter(&xsp->mu); } The code fragment in the following example can be used when device operation completes, for example, in the device's interrupt handler. Example 12-9 Device Operation Completion/* * For each command completion, decrement the busy count and unstack * the pm_busy_component() call by calling pm_idle_component(). This * will allow device power to be lowered when all commands complete * (all pm_busy_component() counts are unstacked) */ xsp->xx_busy[component]--; if (pm_idle_component(dip, component) != DDI_SUCCESS) { xsp->xx_busy[component]++; /* * Log error and abort */ } /* * If no more outstanding commands, wake up anyone (like DDI_SUSPEND) * waiting for all commands to be completed */ |
||
|