|
|||
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 14. Layered Driver Interface (LDI) Part II Designing Specific Kinds of Device Drivers 15. Drivers for Character Devices Overview of the Character Driver Structure Character Device Autoconfiguration Multiplexing I/O on File Descriptors 32-bit and 64-bit Data Structure Macros 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 |
Device Access (Character Drivers)Access to a device by one or more application programs is controlled through the open(9E) and close(9E) entry points. An open(2) system call to a special file representing a character device always causes a call to the open(9E) routine for the driver. For a particular minor device, open(9E) can be called many times. The close(9E) routine is called only when the final reference to a device is removed. If the device is accessed through file descriptors, the final call to close(9E) can occur as a result of a close(2) or exit(2) system call. If the device is accessed through memory mapping, the final call to close(9E) can occur as a result of a munmap(2) system call. open() Entry Point (Character Drivers)The primary function of open() is to verify that the open request is allowed. The syntax for open(9E) is as follows: int xxopen(dev_t *devp, int flag, int otyp, cred_t *credp); where:
The following example shows a character driver open(9E) routine. Example 15-2 Character Driver open(9E) Routinestatic int xxopen(dev_t *devp, int flag, int otyp, cred_t *credp) { minor_t instance; if (getminor(*devp) /* if device pointer is invalid */ return (EINVAL); instance = getminor(*devp); /* one-to-one example mapping */ /* Is the instance attached? */ if (ddi_get_soft_state(statep, instance) == NULL) return (ENXIO); /* verify that otyp is appropriate */ if (otyp != OTYP_CHR) return (EINVAL); if ((flag & FWRITE) && drv_priv(credp) == EPERM) return (EPERM); return (0); } close() Entry Point (Character Drivers)The syntax for close(9E) is as follows: int xxclose(dev_t dev, int flag, int otyp, cred_t *credp); close() should perform any cleanup necessary to finish using the minor device, and prepare the device (and driver) to be opened again. For example, the open routine might have been invoked with the exclusive access (FEXCL) flag. A call to close(9E) would allow additional open routines to continue. Other functions that close(9E) might perform are:
A driver that waits for I/O to drain could wait forever if draining stalls due to external conditions such as flow control. See Threads Unable to Receive Signals for information about how to avoid this problem. |
||
|