[Return to Library]  [TOC]  [PREV]  SECT--  [NEXT]  [INDEX] [Help]

1    Review of Device Driver Concepts

Before writing a driver for a VMEbus device, you must be familiar with driver concepts in general as well as specific tasks you need to perform to successfully code the driver. This book presumes you understand the following concepts:

The following sections review the tasks associated with writing device drivers. Writing Device Drivers: Tutorial discusses these tasks in detail. The chapter concludes with a section that discusses VMEbus porting information. You should read this section if you have written VMEbus device drivers for previous versions of the Digital UNIX operating system.


[Return to Library]  [TOC]  [PREV]  SECT--  [NEXT]  [INDEX] [Help]

1.1    Gathering Information

The first task in writing a device driver is to gather pertinent information about the host system and the device for which you are writing the driver. For example, you need to:


[Return to Library]  [TOC]  [PREV]  --SECT  SECT--  [NEXT]  [INDEX] [Help]

1.2    Designing a Device Driver

After you gather information about the host system and the device, you are ready to design and develop the device driver. You need to specify the driver type and whether the driver you are writing will be statically or dynamically configured into the kernel. During the design of the driver, you also identify device driver entry points and describe the driver states.


[Return to Library]  [TOC]  [PREV]  --SECT  SECT--  [NEXT]  [INDEX] [Help]

1.3    Allocating Data Structures

Data structures are the mechanism used to pass information between the kernel and device driver interfaces. The following table summarizes data structures, which are described in Writing Device Drivers: Tutorial and Writing Device Drivers: Reference:
Assign_table  Defines members used in device special file creation. 
buf  Describes arbitrary I/O. 
bus  Represents an instance of a bus entity to which other buses or controllers are logically attached. 
cfg_attr_t  Contains information for managing the loading and unloading of drivers. 
cfg_subsys_attr_t  Contains attribute information for drivers. 
controller  Contains members that store information about hardware resources and store data for communication between the kernel and the device driver. 
controller_config  Contains information needed to create a controller structure. 
DEVGEOMST  Stores disk device geometry. 
devget  Contains information about a device. 
device  Contains information that identifies the device. There is one device data structure for each device connected to the controller. 
device_config  Contains information needed to create a device structure. 
device_info_t  Is the top-level union that stores bus- and device-type information. 
disklabel  Stores disk device label information. 
driver  Defines driver entry points and other driver-specific information. You initialize this data structure in the device driver. 
dsent  Defines a device driver's entry points and other information. 
handler_intr_info  Contains interrupt handler information. 
ihandler_t  Contains information associated with device driver interrupt handling. 
item_list  Contains hardware platform-specific information. 
lock  Contains complex lock-specific information. 
port  Contains information about a port. 
pt  Stores disk device partition information. 
pt_tbl  Stores a disk partition map. 
sel_queue  Defines a queue of select events. 
sg_entry  Contains bus address/byte count pairs. 
slock  Contains simple lock-specific information. 
task  Contains task-specific information. 
thread  Contains kernel threads-related information. 
uio  Describes I/O, either single vector or multiple vectors. 
v1_bustype_info_t  Stores bus information. 
v1_device_info_t  Is the top-level union that stores bus- and device-type information. 
v1_devtype_info_t  Stores device-type information. 
v1_disk_dev_info_t  Stores disk information. 
v1_tape_dev_info_t  Stores tape information. 

Chapter 4 reviews the members of the controller and driver structures that are specific to the VMEbus.

When designing a device driver, you must decide on the technique you will use for allocating data structures. Generally, there are two techniques you can use: dynamic allocation and static allocation. Dynamic allocation is the recommended method for all new drivers; some existing drivers allocate data structures statically. If you know that the maximum number of devices is greater than five or that the driver uses numerous data structures, plan to use the dynamic allocation method. You should also use the dynamic allocation method for allocating data structures in loadable device drivers.


[Return to Library]  [TOC]  [PREV]  --SECT  SECT--  [NEXT]  [INDEX] [Help]

1.4    Writing Portable Device Drivers

Whenever possible, design your device driver so that it can accommodate peripheral devices that operate on different bus architectures, different CPU architectures, and more than one CPU type within the same architecture. You need to consider the following issues to make your drivers portable across CPU architectures:

You need to consider the following issues to make your drivers portable across bus architectures:

You must consider these issues also if you have an ULTRIX device driver that you want to port to Digital UNIX. See Writing Device Drivers: Tutorial for a discussion of the additional tasks you need to perform to port an ULTRIX device driver to Digital UNIX. Also, see the porting chapter in Writing Device Drivers: Tutorial for a discussion of the issues associated with updating device drivers written for a previous version of Digital UNIX to the current version of the operating system. Although existing device drivers are binary compatible with the current version of Digital UNIX, you might want to make the changes suggested in the porting chapter of the tutorial.


Note

See Writing Device Drivers: Tutorial for information on the CSR I/O access interfaces read_io_port and write_io_port. These interfaces allow you to read from and write to a device's CSR addresses without directly accessing its device registers. Each of these interfaces takes an I/O handle that the bus configuration code passes to the driver's probe interface.

See Writing Device Drivers: Tutorial for information on the I/O copy operation interfaces io_copyin, io_copyio, io_copyout, and io_zero. These are generic interfaces that map to bus- and machine-specific interfaces that actually perform the I/O copy operations. Using these interfaces to perform copy operations makes the device driver more portable across different CPU architectures and different CPU types within the same architecture. Each of these interfaces takes an I/O handle that the bus configuration code passes to the driver's probe interface.



[Return to Library]  [TOC]  [PREV]  --SECT  SECT--  [NEXT]  [INDEX] [Help]

1.5    Reviewing the Device Driver Kits Delivery Process

When you are ready to write your driver, you may want to study the device driver kits delivery process and create an appropriate device driver development environment.

Writing Device Drivers: Tutorial describes the device driver kits delivery process and how to statically and dynamically configure drivers into the kernel. The tutorial discusses how to write device drivers for computer systems running Digital UNIX.


[Return to Library]  [TOC]  [PREV]  --SECT  SECT--  [NEXT]  [INDEX] [Help]

1.6    Identifying the Method for Registering Device Interrupt Handlers

For this version of Digital UNIX, Digital requires that you implement all new VMEbus device drivers to call the handler interfaces and reference the handler-specific data structures to register their device interrupt handlers. (See Writing Device Drivers: Tutorial for more information.)

Section 6.5 provides an example of adding VMEbus interrupt handlers. As described in the tutorial, VMEbus device drivers must use the structure vme_handler_info rather than handler_intr_info when using the interrupt handler handler interfaces. The structure vme_handler_info includes handler_intr_info as a member.


[Return to Library]  [TOC]  [PREV]  --SECT  SECT--  [NEXT]  [INDEX] [Help]

1.7    VMEbus Porting Information

One of the goals of an open systems environment is to provide hardware and software platforms that promote the use of standards. By adhering to a set of standard interfaces, these platforms make it easier for third-party application programmers to write applications that can run on a variety of operating systems and hardware. The Digital UNIX operating system adheres to this philosophy by providing kernel interfaces that device drivers operating on any bus can use. Writing Device Drivers: Tutorial provides examples of how to use many of these interfaces.

Previous versions of the operating system provided VMEbus device driver writers with numerous VMEbus-specific interfaces. To promote the portability of device drivers across different bus and CPU architectures, this version of Digital UNIX eliminates some of the VMEbus-specific interfaces and replaces them with more generic interfaces. Table 1-2 shows the existing VMEbus interfaces and the associated generic interfaces that VMEbus device drivers should call. A None in the second column indicates that the interface is no longer available in this version of the Digital UNIX operating system.


Table 1-2: VMEbus-Specific Interfaces and Associated Generic Interfaces
VMEbus InterfaceGeneric Digital UNIX Interface
log_vme_ctlr_error  None 
log_vme_device_error  None 
vbasetup  dma_map_allocdma_map_loadvba_set_dma_addr(Provides additional functionality not provided by generic interfaces.) 
vballoc  dma_map_allocdma_map_loadvba_set_dma_addr(Provides additional functionality not provided by generic interfaces.) 
vbarelse  dma_map_deallocdma_map_unload 
vme_read_bytevme_read_wordvme_read_longvme_read_quad  read_io_port 
vme_write_bytevme_write_wordvme_write_longvme_write_quad  write_io_port 

The following are VMEbus interfaces that VMEbus device drivers can still call: