This appendix contains reference pages for the following:
The include file reference pages can include the following sections:
Lists the name of the include file along with a summary description of its contents.
Presents the pathname for the include file. The pathname makes it easier for you to locate specific include files.
Briefly describes the contents of the include file.
Explains when to include an include file for block and character drivers.
Lists specific structures, macros, constant values, and so forth that are of interest to device driver writers.
Lists related kernel interfaces, structures, system calls, and so forth.
Table A-1 lists the include file related to EISA/ISA bus device drivers, along with a short description of its contents. Device drivers should include include files that use the relative pathname instead of the explicit pathname. For example, although buf.h resides in /usr/sys/include/sys/buf.h, device drivers should include it as:
<sys/buf.h>
Include File | Contents |
eisa.h | Contains definitions for EISA/ISA bus support. |
Contains definitions for EISA/ISA bus support
/usr/sys/include/io/dec/eisa/eisa.h
The eisa.h file contains definitions specific to the EISA/ISA bus.
You include this file in block and character device drivers that connect to EISA/ISA buses.
This file defines data structures referenced by EISA/ISA bus device drivers and by the bus configuration code.
bus_mem, dma, eisa_option, e_port, irq
The kernel interface reference pages can include the following sections:
Lists the name of the kernel interface, along with a summary description of its purpose. In general, there is one interface described for each reference page. However, in some cases it makes sense to describe more than one interface on the same page if the interfaces are related. When this occurs, this section lists the names of all the interfaces it describes.
Shows the kernel interface function definition. The style used is that of the function definition, not the function call. This book assumes that you understand how to interpret the function definition and how to write an appropriate call for a specific interface. The following example shows these conventions:
int copyin
(user_src,
kernel_dest,
bcount)
caddr_t
user_src;
caddr_t
kernel_dest;
u_int
bcount;
The kernel interface function definition gives you the following information:
The data type of the return value, if the kernel interface returns data. If the kernel interface does not return a value, the void data type is used.
The kernel interface name, for example, copyin. Some kernel interfaces are in uppercase.
The name of each kernel interface argument name. In the example, the argument names are user_src, kernel_dest, and bcount.
The types for each of the arguments. In the example, these types are caddr_t and u_int.
This book uses the word kernel ``interface'' instead of kernel ``routine'' or kernel ``macro'' because, from the driver writer's point of view, it does not matter whether the interface is a routine or a macro.
Describes the arguments associated with a given kernel interface. In most cases, argument descriptions begin with the word specifies to indicate that you pass the argument (with some specified value) to the kernel interface. If the type of the argument appears as a void *, the argument description states that you must define the type.
Explains the tasks performed by the kernel interface.
Discusses information that falls into the following categories:
Some kernel interfaces behave differently depending on the architecture of the hardware.
Some kernel interfaces behave differently depending on the implementation of the operating system.
Some kernel interfaces require specific information important to the device driver writer.
Provides information of particular importance when you use the kernel interface. In many cases, the text in this section alerts you to anything that might cause a panic.
Provides the possible error constants a given kernel interface can return, along with a short description of the error.
Describes special processing performed by the kernel interface. For example, the Side Effects section for the uiomove kernel interface describes the members of the uio structure that it can update.
Describes the return values that a given kernel interface can return. In most cases, if the kernel interface returns an error value, this value is described in the Return Values section.
Lists related kernel interfaces, structures, system calls, and so forth.
Table A-2 lists the kernel interface specific to EISA/ISA bus device drivers, along with a short description of its purpose.
Note
Device drivers use the following include files most frequently:
<sys/types.h> <sys/errno.h> <io/common/devdriver.h> <sys/uio.h> <machine/cpu.h>
Kernel Interface | Summary Description |
isa_slot_to_name | Gets the isa_option table function entry. |
Gets the isa_option table function entry
char * isa_slot_to_name
(slot)
uint_t
slot;
The isa_slot_to_name interface returns a pointer to the isacfg handle for the device in the specified ISA slot. The isacfg handle is the string that the ISA bus code uses to match with the function field of the isa_option data table. Appendages to the isacfg handle can communicate various information to the driver through this interface.
You should call the isa_slot_to_name interface only when you are certain that the driver's associated device is operating on the ISA bus. You can check which bus the device is operating on as follows:
.
.
.
struct controller *ctlr;
.
.
.
if ctlr->bus_hd->bus_type == BUS_ISA
.
.
.
The BUS_ISA constant is defined in /usr/sys/include/io/common/devdriver.h.
Upon successful completion, isa_slot_to_name returns a pointer to the isacfg handle. Otherwise, isa_slot_to_name returns the value -1.
The data structure reference pages can include the following sections:
Lists the name of the structure along with a summary description of its purpose.
Lists the include file, including the path, where the structure is defined.
Describes the format of the structure, as follows:
Provides a short description of each member of the structure.
Gives more details about the purpose of the structure.
Lists related kernel interfaces, structures, system calls, and so forth.
Table A-3 lists the data structures specific to EISA bus device drivers, along with short descriptions of their contents.
Data Structure | Contents |
bus_mem | Describes EISA/ISA bus memory characteristics. |
controller | Represents an instance of a controller entity. |
dma | Contains DMA channel information. |
eisa_option | Contains EISA bus options. |
e_port | Contains I/O port information. |
irq | Contains EISA/ISA bus interrupt channel characteristics. |
Describes EISA/ISA bus memory characteristics
/usr/sys/include/io/dec/eisa/eisa.h
Member Name | Data Type |
isram | int |
decode | int |
unit_size | int |
size | long |
start_addr | io_handle_t |
Value | Meaning |
0 | The memory associated with the EISA bus expansion board is ROM (that is, read only). |
1 | The memory associated with the EISA bus expansion board is RAM (that is, read/write). |
Value | Meaning |
0 | The number of address lines decoded by an EISA bus expansion board equals 20. |
1 | The number of address lines decoded by an EISA bus expansion board equals 24. |
2 | The number of address lines decoded by an EISA bus expansion board equals 32. |
Value | Meaning |
0 | There is one byte (8 bits) in the I/O port associated with this EISA/ISA bus expansion board. |
1 | There is one word (16 bits) in the I/O port associated with this EISA/ISA bus expansion board. |
2 | There is one longword (32 bits) in the I/O port associated with this EISA bus expansion board. |
The bus_mem structure describes memory characteristics for an EISA bus expansion board. The bus configuration code initializes the members of the bus_mem structure during device autoconfiguration. Device drivers call the get_config interface to obtain information stored in the members of the bus_mem data structure.
Represents an instance of a controller entity
/usr/sys/include/io/common/devdriver.h
Member Name | Data Type |
slot | int |
physaddr | caddr_t |
slot 1
The autoconfiguration software uses the syntax following the slot keyword in the system configuration file or the stanza.static file fragment to obtain this value. The bus configuration code obtains this value from the autoconfiguration software and uses it to initialize the slot member of the controller structure associated with this EISA/ISA bus device.
The controller structure represents an instance of a controller entity, one that connects logically to a bus. A controller can control devices that are directly connected or can perform some other controlling operation, such as a network interface or terminal controller operation.
Contains DMA channel information
/usr/sys/include/io/dec/eisa/eisa.h
Member Name | Data Type |
channel | uint_t |
is_shared | uint_t |
xfer_size | uint_t |
timing | uint_t |
mode | uint_t |
Value | Meaning |
0 | The devices cannot share the DMA channel number. |
1 | The devices can share the DMA channel number. |
Value | Meaning |
00 | The DMA device data transfer size is 8 bits (byte). |
01 | The DMA device data transfer size is 16 bits (word). |
10 | The DMA device data transfer size is 32 bits (longword). |
Value | Meaning |
00 | The bus cycle type is Default. This bus cycle type is compatible with ISA DMA devices. |
01 | The bus cycle type is Type A. This bus cycle type is used with higher-performance ISA DMA devices to achieve faster data transfers. |
10 | The bus cycle type is Type B. Like bus cycle Type A, this type is used with higher-performance ISA DMA devices to achieve faster data transfers. |
11 | The bus cycle type is Type C (burst). This bus cycle type is used with DMA devices that support EISA/ISA bus cycles to achieve the fastest data transfers. |
The dma structure describes information related to the DMA channel. The bus configuration code initializes the members of the dma structure during device autoconfiguration. Device drivers call the get_config interface to obtain information stored in the members of the dma data structure.
Contains EISA bus options
/usr/sys/include/io/dec/eisa/eisa.h
Member Name | Data Type |
board_id | char [EISA_IDNAMELEN + 1] |
function | char [EISA_FUNCLEN + 1] |
driver_name | char [EISA_NAMELEN + 1] |
intr_b4_probe | int |
intr_aft_attach | int |
type | char |
adpt_config | int (*adpt_config) () |
ISA bus device drivers do not use this member. The ISA bus does not require such an ID register. Typically, ISA device driver writers set this member to the null string () in the eisa_option structure defined in /usr/sys/data/isa_option_data.c.
For the ISA bus, this member specifies a string that matches the ISA configuration (ISACFG) handle.
The eisa_option structure contains EISA/ISA bus option information such as the name of the controlling device driver. An array of eisa_option structures is declared in the file /usr/sys/data/eisa_option_data.c for EISA device drivers and /usr/sys/data/isa_option_data.c for ISA device drivers.
Contains I/O port information
/usr/sys/include/io/dec/eisa/eisa.h
Member Name | Data Type |
base_address | vm_offset_t |
numb_of_ports | uint_t |
is_shared | uint_t |
Value | Meaning |
0 | The device cannot share the I/O port. |
1 | The device can share the I/O port. |
The e_port structure describes bus I/O port information. The bus configuration code initializes the members of the e_port structure during device autoconfiguration. Device drivers call the get_config interface to obtain information stored in the members of the e_port data structure.
Contains EISA/ISA bus interrupt channel characteristics
/usr/sys/include/io/dec/eisa/eisa.h
Member Name | Data Type |
channel | uint_t |
trigger | uint_t |
is_shared | uint_t |
Value | Meaning |
0 | The EISA bus expansion board initializes the interrupt controller to edge-triggered. |
1 | The EISA bus expansion board initializes the interrupt controller to level-triggered. |
The ISA bus does not use this member.
Value | Meaning |
0 | The EISA bus expansion board cannot share this interrupt. |
1 | The EISA bus expansion board can share this interrupt. |
The ISA bus does not use this member.
The irq data structure specifies EISA bus interrupt channel characteristics assigned to a device. The bus configuration code initializes the members of the irq structure during device autoconfiguration. Device drivers call the get_config interface to obtain information stored in the members of the irq data structure.
The device driver interface reference pages can include the following sections:
Lists the name of the driver interface along with a summary description of its purpose. In general, there is one interface described for each reference page. However, in some cases it makes sense to describe more than one interface on the same page if the interfaces are related. When this occurs, this section lists the names of all the interfaces it describes.
Lists the structure or file where you specify the entry for the device driver interface.
Shows the device driver interface function definition.
The style used is that of the function definition, not the
function call.
This book assumes that you understand how to interpret
the function definition and how to write an appropriate call for a specific
interface.
The presentation shown in the following example is of the function
definition:
int xxprobe
(ctlr)
struct controller
*ctlr;
The previous interface function definition gives you the following information:
Gives the data type of the return value, if the interface returns data. If the interface does not return a value, the function definition shows a void data type.
Gives the driver interface name. In the example, xxprobe is the name of the driver interface. The prefix xx indicates that this part of the name is variable. Replace it with the character prefix that represents the name of the device for which the driver is being written.
Gives the name of each driver interface argument. In the example, the argument name is ctlr.
Gives the types for each of the arguments. If you must define the type of the argument, a void * is used. In the example, this type is struct controller *. The term driver interface is used instead of driver routine to establish consistent terminology with that used for the kernel interfaces.
Describes the arguments associated with a given driver interface. In most cases, argument descriptions begin with the word specifies to indicate that the driver writer passes the argument (with some specified value) to the driver interface.
Explains the tasks performed by the driver interface.
Contains information about the driver interface pertinent to the device driver writer.
Describes the values that a given driver interface can return.
Lists related kernel interfaces, structures, system calls, and so forth.
Table A-4 lists the device driver interfaces specific to EISA/ISA bus device drivers, along with short descriptions of their contents.
Driver Interface | Contents |
xxprobe | Determines whether the device exists. |
xxslave | Checks that the device is valid for this controller. |
Determines whether the device exists
The driver structure
int xxprobe
(bus_io_handle,
ctlr)
io_handle_t
bus_io_handle;
struct controller
*ctlr;
An EISA/ISA bus device driver's xxprobe interface performs the tasks necessary to determine if the device exists and is functional on a given system. At system startup time, the EISA bus configuration code reads the configuration information saved by the EISA Configuration Utility (ECU) and performs checks to determine if the device is present before calling xxprobe for statically configured drivers. The EISA bus configuration code calls the xxprobe interface for each device that is defined according to specific rules discussed in Chapter 6.
The ISA bus configuration code reads the data saved by the console firmware's isacfg utility and attempts to match the data to a configured device driver. The matching occurs by using the ISACFG handle and the strings stored in the function member of the isa_option data table that resides in /usr/sys/data/isa_option_data.c.
EISA bus devices must have an ID register that the EISA bus configuration code uses to ensure that the device is present on the system before calling the driver's probe interface. ISA bus devices have no such requirement. Thus drivers for ISA bus devices, whether on either the EISA or ISA bus, should attempt to determine the actual presence of the device in the probe interface probe routine. The methodology to accomplish this is unique to each device. Some predictable device register manipulation is one such method.
The xxprobe interface typically checks some device control status register (CSR) to determine whether the physical device is present. If the device is not present, the device is not initialized and not available for use. In previous versions of the operating system, you defined the device interrupt handlers for static device drivers in the system configuration file or the stanza.static file fragment. At system configuration time, the config program registered the defined device interrupt handlers. For this version of Digital UNIX, Digital recommends that you register the device interrupt handlers for static device drivers in the same way that you register them for loadable device drivers: by calling the handler_add and handler_enable interfaces.
The Synopsis section shows the arguments associated with a probe interface for device drivers that operate on the EISA bus.
Device drivers pass the I/O handle to the following categories of interfaces, which are discussed in Writing Device Drivers: Tutorial. These interfaces can process the I/O handle to access bus address space.
The read_io_port and write_io_port interfaces allow device drivers to read from and write to device registers. Using these interfaces to read data from and write data to a device register makes the device driver more portable across different bus architectures, different CPU architectures, and different CPU types within the same CPU architecture.
The io_copyin, io_copyio, io_copyout, and io_zero interfaces allow device drivers to perform I/O copy operations. Using these interfaces to perform the copy operation makes the device driver more portable across different CPU architectures and different CPU types within the same architecture.
The xxprobe interface returns a nonzero value if the probe operation is successful. It returns the value zero (0) to indicate that the driver did not complete the probe operation.
Checks that the device is valid for this controller
The driver structure
int xxslave
(device,
bus_io_handle)
struct device
*device;
io_handle_t
bus_io_handle;
A device driver's xxslave interface is called only for a controller that has slave devices connected to it. This interface is called once for each slave attached to the controller. You (or the system manager) specify the attachments of these slave devices for static device drivers in the system configuration file or stanza.static file fragment.
The arguments you pass to the slave interface differ according to the bus on which the driver operates. The Synopsis section shows the arguments associated with a slave interface for an EISA bus.
Device drivers pass the I/O handle to the following categories of interfaces, which are discussed in Writing Device Drivers: Tutorial. These interfaces can process the I/O handle to access bus address space.
The read_io_port and write_io_port interfaces allow device drivers to read from and write to device registers. Using these interfaces to read data from and write data to a device register makes the device driver more portable across different bus architectures, different CPU architectures, and different CPU types within the same CPU architecture.
The io_copyin, io_copyio, io_copyout, and io_zero interfaces allow device drivers to perform I/O copy operations. Using these interfaces to perform the copy operation makes the device driver more portable across different CPU architectures and different CPU types within the same architecture.
The xxslave interface returns a nonzero value if the device is present.