[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


4    Porting Digital UNIX Device Drivers

This chapter discusses how you port device drivers from the ULTRIX operating system to the Digital UNIX operating system. The chapter also summarizes the issues you need to consider before you decide to update existing Digital UNIX device drivers to the current version of Digital UNIX.


[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


4.1    Porting ULTRIX Device Drivers to the Digital UNIX Operating System

This section discusses the tasks you need to perform when porting device drivers from the ULTRIX operating system (running on Digital hardware) to the Digital UNIX operating system (also running on Digital hardware). The section does not discuss how to port drivers running on other UNIX operating systems, such as System V, or running on other hardware platforms, such as Sun Microsystems. Specifically, you need to:

These tasks are discussed in the following sections.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.1.1    Writing Test Suites

Porting a device driver requires that you understand the hardware device and the associated driver you want to port. One way to learn about the hardware device and its associated driver is to run a test suite, if it exists, on the machine and the operating system you are porting from (the source machine and the source operating system). If the test suite does not exist, you need to write a full test suite for that device on the source machine and the source operating system. For example, if you port a device driver written for a Digital CPU running the ULTRIX operating system, write the full test suite on that Digital CPU.

Write the test suite so that only minimal changes are necessary when you move it to the Digital CPU running the Digital UNIX operating system you are porting to (the target machine and the target operating system). The test suite represents a cross section of your users, and they should not have to modify their applications to work with the ported driver. You need to have both the source machine and source operating system and the target machine and target operating system on a network or make them accessible through a common interface, such as the Small Computer System Interface (SCSI).

After writing the test suite on the source machine, move the driver and the test suite to the target machine. Move only the .c and the .h files that were created for the driver. Do not copy any header or binary executable files because these files on the source machine will probably not be compatible on the target machine.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.1.2    Checking Header Files

Check the header files in the driver you want to port with those in the Digital UNIX device drivers. Section 5.1 provides information on the header files that Digital UNIX uses. Writing Device Drivers: Reference provides reference page descriptions of the header files that Digital UNIX device drivers use most frequently.

The following example summarizes the differences in the way header files are included in device drivers on Digital UNIX and ULTRIX systems:

/* Header Files Included in Digital UNIX */ [1]
#include <sys/types.h>

/* Header Files Included in ULTRIX */ [1] #include "../h/types.h"

  1. Shows that drivers written for Digital UNIX use left (<) and right (>) angle brackets, instead of the begin (") and end (") quotes used in ULTRIX pathnames. Note also that the location of the file has changed for Digital UNIX. [Return to example]


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.1.3    Reviewing Device Driver Configuration

Digital UNIX supports static and dynamic configuration of device drivers into the kernel. The steps and tools that driver writers use to configure drivers into the kernel are different than those used on ULTRIX systems. The chapters in Part 4 of this book describe device driver configuration on Digital UNIX.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.1.4    Checking Driver Interfaces

You need to compare the driver interfaces that ULTRIX device drivers use with those that Digital UNIX device drivers use. Writing Device Drivers: Reference provides reference page descriptions of the driver interfaces that Digital UNIX device drivers use. Use this information to compare the interface's behavior, number and type of arguments, return values, and so forth with its associated ULTRIX driver interface.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.1.5    Checking Kernel Interfaces

You need to compare the kernel interfaces that ULTRIX device drivers use with those that Digital UNIX device drivers use. Writing Device Drivers: Reference provides reference page descriptions of the kernel interfaces that Digital UNIX device drivers use. Use this information to compare the interface's behavior, number and type of arguments, return values, and so forth with its associated ULTRIX kernel interface. Table 4-1 lists some of these differences.


Table 4-1: Highlights of Differences Between Digital UNIX and ULTRIX Kernel Interfaces

Kernel Interface Remarks
BADADDR You can use BADADDR in device drivers that are statically configured into the kernel on Digital UNIX. However, you cannot use BADADDR if the driver is dynamically configured into the kernel. If you implement the driver to be both statically and dynamically configured, you can declare a variable and use it to control the call to BADADDR. For an example of how noneprobe uses such a variable (called none_is_dynamic), see Section 7.1.8.
bufflush ULTRIX BSD device drivers written for platforms based on MIPS use the bufflush interface. This interface is not used for Alpha platforms. Therefore, delete this interface from your device driver.
KM_ALLOC A previous version of the operating system instructed you to replace calls to KM_ALLOC with calls to kalloc. Digital UNIX supports a new memory allocator. Thus, replace calls to KM_ALLOC with calls to MALLOC.
KM_FREE A previous version of the operating system instructed you to replace calls to KM_FREE with calls to kfree. Digital UNIX supports a new memory allocator. Thus, replace calls to KM_FREE with calls to FREE.
printf interfaces ULTRIX device drivers can call cprintf, mprintf, printf, and uprintf. Digital UNIX device drivers can call printf and uprintf.
selwakeup The selwakeup interface is not used in Digital UNIX. Replace calls to selwakeup with calls to select_wakeup. Note that the formal parameters for the two interfaces are different.
vslock The vslock interface is obsolete on Digital UNIX. Therefore, replace calls to vslock with calls to vm_map_pageable.
vsunlock The vsunlock interface is obsolete on Digital UNIX. Therefore, replace calls to vsunlock with calls to vm_map_pageable.
useracc The useracc interface is obsolete on Digital UNIX. If you called useracc with vslock, replace both interfaces with a call to vm_map_pageable. Typically, the useracc interface was called by the driver's strategy interface. In most cases, the driver's strategy interface would be called indirectly from the physio interface (in response to read and write system calls or file-system access).

In Digital UNIX, the physio interface verifies access permissions to the user buffer and locks down the memory. For this reason, in existing drivers that may have historically called useracc, it is no longer necessary to perform such a check and subsequent locking of memory with vslock. The general rule is that any interface called from the physio interface (that is, the driver's strategy interface) should not call useracc or its replacement vm_map_pageable because the physio interface performs those functions.

If you called useracc prior to accessing user data, replace it with calls to copyin and copyout to access user space. Calling useracc simply verifies access permissions to the specified memory at the time the useracc interface is called. It is possible that immediately after the useracc interface has returned back to the driver that the corresponding memory could be invalid. The memory could be invalid if it was swapped out or otherwise remapped by the virtual memory management portion of the kernel. Therefore, a driver should not assume that the memory region whose access permissions are verified through a call to useracc is persistent.

In Digital UNIX, calls to useracc are either unnecessary (as previously explained) or should be replaced by direct calls to vm_map_pageable. This interface performs functions for both verifying access permissions and for locking down the memory so that it cannot be invalidated until it is unlocked by subsequent calls to vm_map_pageable for this memory region.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.1.6    Checking Data Structures

You need to compare the data structures that ULTRIX device drivers use with those that Digital UNIX device drivers use. Writing Device Drivers: Reference provides reference page descriptions of the data structures that Digital UNIX device drivers use. Use this information to compare the data structure's members with its associated ULTRIX data structure. Table 4-2 lists some of these differences.

Table 4-2: Highlights of Differences Between Digital UNIX and ULTRIX Data Structures

Data Structure Remarks
uba_ctlr Replace references to the uba_ctlr structure and its associated members with references to the controller structure and its associated members.
uba_device Replace references to the uba_device structure and its associated members with references to the device structure and its associated members. Make sure that the reference is to a slave, for example, a disk or tape drive. If the reference is to a controller, reference the controller structure, not the device structure.
uba_driver Replace references to the uba_driver structure and its associated members with references to the driver structure and its associated members.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2    Updating Device Drivers to the Current Version of the Digital UNIX Operating System

This section is for driver writers who have already written device drivers for previous versions of the operating system.

The following list summarizes the issues you need to consider when deciding whether to update device drivers written on previous versions of the operating system to the current version of Digital UNIX. Although existing device drivers are binary compatible with the current version of Digital UNIX, you might want to make these changes to take advantage of the single binary module technology.

The following sections provide details on each of these issues. Section 4.2.14 lists the interfaces that will be retired in a future release of Digital UNIX and the replacement interface, if applicable. Section 4.2.15 lists the data structures that will be retired in a future release of Digital UNIX and the replacement structure, if applicable. Section 4.2.16 lists the fields used in the sysconfigtab file fragment (formerly, the stanza.static and stanza.loadable file fragments) that will be retired in a future release of Digital UNIX.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.1    Method for Registering Interrupt Handlers

In previous versions of the operating system, you could do the following:

Digital recommends that you register interrupt handlers for statically and dynamically configured drivers operating on any Digital-supported bus (EISA, ISA, PCI, and TURBOchannel) by using the ihandler_t and handler_intr_info structures and by calling the handler interfaces. Section 7.1.6 shows how to accomplish this task. You typically register interrupt handlers in the driver's probe interface.

For the VMEbus, you call the handler interfaces, but instead of using the handler_intr_info structure, you use the vme_handler_info structure. One of the members of the vme_handler_info structure is a handler_intr_info structure.

Because the method for registering interrupt handlers is through the handler interfaces, device drivers should no longer be calling the enable_option and disable_option interfaces. The enable_option and disable_option interfaces will be retired in a future release of Digital UNIX.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.2    Method for Registering Character and Block Device Driver Interfaces

In previous versions of the operating system, you could do the following:

To register character and block driver entry points for statically or dynamically configured drivers, you call the devsw_add interface. You no longer specify a static driver's interfaces in the stanza.static file fragment. Section 6.6.5.2 discusses how to register character and block driver interfaces by calling the devsw_add interface. (The stanza.static file fragment is replaced by the sysconfigtab file fragment.)

The call to the devsw_add interface also reserves a major number (both block and character). A device driver is responsible for determining if an open or close call is to the block or character device by examining the format argument.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.3    Use of the Bus-Specific Option Structure and Structure Snippet

In previous versions of the operating system, the buses implemented on Alpha CPUs have an associated bus-specific option data structure defined in the bus-specific header file. The following list identifies the option structures for the EISA, ISA, PCI, and TURBOchannel buses that were supported in a previous version of Digital UNIX:

In a previous version of Digital UNIX, to write portable device drivers (that were statically configured) across multiple bus architectures you needed to add device entries to the bus-specific option structure arrays. When using the traditional model, you used a text editor to directly edit these arrays. When using the third-party model, you did not directly edit the arrays. Instead, you provided the bus-specific option array information in the following files for use with the mkdata utility: eisa_data (for the EISA/ISA bus option structure array), pci_data (for the PCI bus option structure array), and tc_data (for the TURBOchannel bus option structure array). To write portable drivers (that were dynamically configured) across multiple bus architectures in a previous version of Digital UNIX, you needed to declare and initialize bus-specific option structure snippets.

For this version of Digital UNIX, you no longer add entries to the bus-specific option structure arrays (for statically configured drivers) or declare and initialize a bus-specific option structure snippet (for dynamically configured drivers) or add entries to the eisa_data, pci_data, and tc_data files (for the traditional model). You now use the EISA_Option (for EISA buses), ISA_Option (for ISA buses), PCI_Option (for PCI buses), TC_Option (for TURBOchannel buses), and VBA_Option (for the VMEbus) attribute fields to populate a driver's sysconfigtab file fragment. See the bus-specific book for descriptions of the EISA_Option, ISA_Option, PCI_Option, TC_Option, and VBA_Option attribute fields.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.4    Device Driver Object Files

In previous versions of the operating system, third-party driver writers supplied to their customers:

In this version of Digital UNIX it is not necessary to ship files with .o extensions. The reason is that Digital UNIX supports a single binary module (for drivers that are statically or dynamically configured into the kernel). Thus, third-party driver writers supply to their customers a single binary module, which has a .mod extension. Note that the .mod file in this version of Digital UNIX is not the same as the .mod file in previous versions of the operating system. Part 4 contains chapters that describe how to statically and dynamically configure third-party device drivers into the kernel.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.5    Elimination of the stanza.static File Fragment

In previous versions of the operating system, you could specify the following in the stanza.static file fragment:

For this version of Digital UNIX, the stanza.static file fragment is replaced by the sysconfigtab file fragment. You must not specify the I/O services interfaces (and other information) for block and character drivers in the sysconfigtab file fragment. Section 6.6.5.2 discusses how to register character and block driver interfaces by calling the devsw_add interface.

You specify device special file information, bus option, and other information in the sysconfigtab file fragment. Section 14.1.5 describes in detail how to create a driver's sysconfigtab file fragment and what items to place in it.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.6    Elimination of the stanza.loadable File Fragment

In previous versions of the operating system, you could specify the following in the stanza.loadable file fragment:

For this version of Digital UNIX, the stanza.loadable file fragment is replaced by the sysconfigtab file fragment. You must not specify device connectivity information in the sysconfigtab file fragment. Section 6.6.6 shows how to specify device connectivity information by calling the create_controller_struct and create_device_struct interfaces.

You specify device special file, bus option, and other information in the sysconfigtab file fragment. Section 14.1.5 describes in detail how to create a driver's sysconfigtab file fragment and what items to place in it.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.7    Changes to the files File Fragment

The syntax you use to specify information in the files file fragment has changed. The reason for the changes is to accommodate the single binary module. Section 14.1.3 discusses the syntax associated with a files file fragment. Note that the if_dynamic and optional keywords will be retired in a future release of the Digital UNIX operating system.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.8    Elimination of the config.file File Fragment

In previous versions of the operating system, you could specify the following in the config.file file fragment:

For this version of Digital UNIX, the config.file file fragment is no longer used. Section 6.6.6 shows how to specify device connectivity information by calling the create_controller_struct and create_device_struct interfaces.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.9    Method for Configuring and Unconfiguring Controllers

In previous versions of the operating system, you typically called the following kernel support interfaces:

Digital recommends that you replace these interfaces as follows:


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.10    Method for Identifying Bus, Controller, and Device Information

In previous versions of the operating system, you identified bus, controller, and device information as follows:

Digital UNIX provides the create_controller_struct and create_device_struct interfaces. These interfaces create the controller and device structures associated with your device driver. Section 6.6.4.3 shows you how to use these interfaces.

As a result of these changes, you no longer need to supply bus, controller, and device specification information in the sysconfigtab file fragment. (This means that the Module_Config stanza field will not be supported in a future release of Digital UNIX.)


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.11    Use of name_data.c Files

Digital no longer recommends that you use name_data.c files to size the data structures and data structure arrays for drivers that are statically configured into the kernel. All references to name_data.c files have been deleted. Section 2.6.2 describes how to dynamically allocate data structures.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.12    Method for Specifying Device Special File Information

In previous versions of the operating system, you specified device special file information in the stanza.static file fragment for statically configured drivers and in the stanza.loadable file fragment for dynamically configured drivers. You specified device special file informtion by using the device special file-related attribute fields.

For this version of Digital UNIX, the stanza.static and stanza.loadable file fragments are replaced by the sysconfigtab file fragment. You use the device special file-related attribute fields in the sysconfigtab file fragment to identify device special files. Section 13.4 describes the sysconfigtab file fragment and Section 14.1.5 describes the syntax for the attribute fields associated with the sysconfigtab file fragment.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.13    Use of the Device Driver Header File

The device driver header file contains #define statements for as many devices as are configured into the system. This file is generated by the config program during static configuration of the device driver. The config program creates a compile-time variable, which defines how many devices exist on the system. Many existing ULTRIX-based drivers use this compile-time variable in device driver code to refer to the number of this type of device on the system. This usage most frequently occurs in structure array declarations and in condition (for example, if and while) statements. In previous versions of Digital UNIX device drivers could use this device driver header file.

For this version of Digital UNIX, the device driver header file is no longer used.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.14    List of Interfaces to be Retired

Table 4-3 lists the interfaces that will be retired in a future release of Digital UNIX. The table also identifies a replacement for the retired interface (if applicable).

Table 4-3: Interfaces to be Retired in a Future Release of Digital UNIX

Retired Interface Replacement
bdevsw_add devsw_add
bdevsw_del devsw_del
cdevsw_add devsw_add
cdevsw_del devsw_del
disable_option Not applicable
dualdevsw_add devsw_add
dualdevsw_del devsw_del
enable_option Not applicable
kalloc MALLOC
kfree FREE
kget Not applicable
ldbl_ctlr_configure configure_driver
ldbl_ctlr_unconfigure unconfigure_driver
ldbl_stanza_resolver Not applicable
zalloc MALLOC
zchange Not applicable
zfree FREE
zget Not applicable
zinit Not applicable


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


4.2.15    List of Data Structures to be Retired

Table 4-4 lists the data structures that will be retired in a future release of Digital UNIX. The table also identifies a replacement for the retired structure.

Table 4-4: Data Structures to be Retired in a Future Release of Digital UNIX

Retired Structure Replacement
bdevsw dsent
cdevsw dsent
zone Not applicable


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Chapter] [Index] [Help]


4.2.16    List of stanza Fields to be Retired

The following list identifies stanza fields that will be retired in a future release of Digital UNIX: