Copyright (c) 2001, Sun Microsystems, Inc. All Rights Reserved.
Copyright 1989 AT&T
The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
In the past, device drivers did not port easily for one or more of the following reasons:
To enhance functionality, members had been added to kernel data structures accessed by drivers, or the sizes of existing members had been redefined.
The calling or return syntax of kernel functions had changed.
Driver developers did not use existing kernel functions where available, or relied on undocumented side effects that were not maintained in the next release.
Architecture-specific code had been scattered throughout the driver when it could have been isolated.
Operating systems are periodically reissued to customers as a way to improve performance, fix bugs, and add new features. This is probably the most common threat to compatibility encountered by developers responsible for maintaining software. Another common problem is upgrading hardware. As new hardware is developed, customers occasionally decide to upgrade to faster, more capable computers of the same family. Although they may run the same operating system as those being replaced, architecture-specific code may prevent the software from porting.
Device drivers are kernel modules that control data transferred to and received from peripheral devices but are developed independently from the rest of the kernel. If the goal of achieving complete freedom in modifying the kernel is to be reconciled with the goal of binary compatibility with existing drivers, the interaction between drivers and the kernel must be rigorously regulated. This driver/kernel service interface is the most important of the three distinguishable interfaces for a driver, summarized as follows:
Driver-Kernel. I/O System calls result in calls to driver entry point routines. These make up the kernel-to-driver part of the service interface, described in Section 9E. Drivers may call any of the functions described in Section 9F. These are the driver-to-kernel part of the interface.
Driver-Hardware. All drivers (except software drivers) must include code for interrupt handling, and may also perform direct memory access (DMA). These and other hardware-specific interactions make up the driver/hardware interface.
Driver-Boot/Configuration Software. The interaction between the driver and the boot and configuration software is the third interface affecting drivers.
DDI/DKI Architecture Independent - These interfaces are supported on all implementations of System V Release 4.
DKI-only - These interfaces are part of System V Release 4, and may not be supported in future releases of System V. There are only two interfaces in this class, segmap(9E) and hat_getkpfnum(9F)
illumos DDI - These interfaces specific to illumos.
illumos SPARC specific DDI - These interfaces are specific to the SPARC processor, and may not be available on other processors supported by illumos.
illumos x86 specific DDI - These interfaces are specific to the x86 processor, and may not be available on other processors supported by illumos.
To achieve the goal of source and binary compatibility, the functions, routines, and structures specified in the DDI/DKI must be used according to these rules.
Drivers cannot access system state structures (for example, u and sysinfo) directly.
For structures external to the driver that may be accessed directly, only the utility functions provided in Section 9F should be used. More generally, these functions should be used wherever possible.
Driver Entry Points - contains reference pages for all driver entry point routines.
Kernel Functions - contains reference pages for all driver support routines.
Driver Properties - contains reference pages for driver properties.
Data Structures - contains reference pages for driver-related structures.
Kernel functions usable by the driver are described in section 9F.
In this section, reference pages contain the following headings:
NAME describes the routine's purpose.
SYNOPSIS summarizes the routine's calling and return syntax.
INTERFACE LEVEL describes any architecture dependencies. It also indicates whether the use of the entry point is required, optional, or discouraged.
ARGUMENTS describes each of the routine's arguments.
DESCRIPTION provides general information about the routine.
RETURN VALUES describes each of the routine's return values.
SEE ALSO gives sources for further information.
All routines and data should be declared as static.
Every driver MUST include <sys/ddi.h> and <sys/sunddi.h>, in that order, and after all other include files.
The following table summarizes the STREAMS driver entry points described in this section.
Routine Type |
put DDI/DKI |
srv DDI/DKI |
The following table summarizes the driver entry points described in this section.
Routine Type |
_fini illumos DDI |
_info illumos DDI |
_init illumos DDI |
aread illumos DDI |
attach illumos DDI |
awrite illumos DDI |
chpoll DDI/DKI |
close DDI/DKI |
detach illumos DDI |
devmap illumos DDI |
devmap_access illumos DDI |
devmap_contextmgt illumos DDI |
devmap_dup illumos DDI |
devmap_map illumos DDI |
devmap_unmap illumos DDI |
dump illumos DDI |
getinfo illumos DDI |
identify illumos DDI |
ioctl DDI/DKI |
ks_update illumos DDI |
mapdev_access illumos DDI |
mapdev_dup illumos DDI |
mapdev_free illumos DDI |
mmap DKI only |
open DDI/DKI |
power illumos DDI |
print DDI/DKI |
probe illumos DDI |
prop_op illumos DDI |
read DDI/DKI |
segmap DKI only |
strategy DDI/DKI |
tran_abort illumos DDI |
tran_destroy_pkt illumos DDI |
tran_dmafree illumos DDI |
tran_getcap illumos DDI |
tran_init_pkt illumos DDI |
tran_reset illumos DDI |
tran_reset_notify illumos DDI |
tran_setcap illumos DDI |
tran_start illumos DDI |
tran_sync_pkt illumos DDI |
tran_tgt_free illumos DDI |
tran_tgt_init illumos DDI |
tran_tgt_probe illumos DDI |
write DDI/DKI |
The following table lists the error codes returned by a driver routine when it encounters an error. The error values are listed in alphabetic order and are defined in sys/errno.h. In the driver open(9E), close(9E), ioctl(9E), read(9E), and write(9E) routines, errors are passed back to the user by calling bioerror(9F) to set b_flags to the proper error code. In the driver strategy(9E) routine, errors are passed back to the user by setting the b_error member of the buf(9S) structure to the error code. For STREAMS ioctl routines, errors should be sent upstream in an M_IOCNAK message. For STREAMS read() and write() routines, errors should be sent upstream in an M_ERROR message. The driver print routine should not return an error code because the function that it calls, cmn_err(9F), is declared as void (no error is returned).
Error Value Error Description |
EAGAIN |
Kernel resources, such as the buf structure or cache memory, are not available at this time (device may be busy, or the system resource is not available). This is used in open, ioctl, read, write, and strategy. |
EFAULT |
An invalid address has been passed as an argument; memory addressing error. This is used in open, close, ioctl, read, write, and strategy. |
EINTR |
Sleep interrupted by signal. This is used in open, close, ioctl, read, write, and strategy. |
EINVAL |
An invalid argument was passed to the routine. This is used in open, ioctl, read, write, and strategy. |
EIO |
A device error occurred; an error condition was detected in a device status register (the I/O request was valid, but an error occurred on the device). This is used in open, close, ioctl, read, write, and strategy. |
ENXIO |
An attempt was made to access a device or subdevice that does not exist (one that is not configured); an attempt was made to perform an invalid I/O operation; an incorrect minor number was specified. This is used in open, close, ioctl, read, write, and strategy. |
EPERM |
A process attempting an operation did not have required permission. This is used in open, ioctl, read, write, and strategy. |
EROFS |
An attempt was made to open for writing a read-only device. This is used in open. |
The table below cross references error values to the driver routines from which the error values can be returned.
open close ioctl read, write and strategy |
EAGAIN EFAULT EAGAIN EAGAIN |
EFAULT EINTR EFAULT EFAULT |
EINTR EIO EINTR EINTR |
EINVAL ENXIO EINVAL EINVAL |
EIO EIO EIO |
ENXIO ENXIO ENXIO |
EPERM EPERM |
EROFS |