JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Writing Device Drivers
search filter icon
search icon

Document Information

Preface

Part I Designing Device Drivers for the Solaris Platform

1.  Overview of Solaris Device Drivers

2.  Solaris Kernel and Device Tree

3.  Multithreading

4.  Properties

5.  Managing Events and Queueing Tasks

6.  Driver Autoconfiguration

7.  Device Access: Programmed I/O

8.  Interrupt Handlers

9.  Direct Memory Access (DMA)

10.  Mapping Device and Kernel Memory

11.  Device Context Management

12.  Power Management

13.  Hardening Solaris Drivers

14.  Layered Driver Interface (LDI)

Part II Designing Specific Kinds of Device Drivers

15.  Drivers for Character Devices

16.  Drivers for Block Devices

Block Driver Structure Overview

File I/O

Block Device Autoconfiguration

Controlling Device Access

open() Entry Point (Block Drivers)

close() Entry Point (Block Drivers)

strategy() Entry Point

buf Structure

bp_mapin Structure

Synchronous Data Transfers (Block Drivers)

Asynchronous Data Transfers (Block Drivers)

Checking for Invalid buf Requests

Enqueuing the Request

Starting the First Transfer

Handling the Interrupting Device

dump() and print() Entry Points

dump() Entry Point (Block Drivers)

print() Entry Point (Block Drivers)

Disk Device Drivers

Disk ioctls

Disk Performance

17.  SCSI Target Drivers

18.  SCSI Host Bus Adapter Drivers

19.  Drivers for Network Devices

20.  USB Drivers

Part III Building a Device Driver

21.  Compiling, Loading, Packaging, and Testing Drivers

22.  Debugging, Testing, and Tuning Device Drivers

23.  Recommended Coding Practices

Part IV Appendixes

A.  Hardware Overview

B.  Summary of Solaris DDI/DKI Services

C.  Making a Device Driver 64-Bit Ready

D.  Console Frame Buffer Drivers

Index

Disk Device Drivers

Disk devices represent an important class of block device drivers.

Disk ioctls

Solaris disk drivers need to support a minimum set of ioctl commands specific to Solaris disk drivers. These I/O controls are specified in the dkio(7I) manual page. Disk I/O controls transfer disk information to or from the device driver. A Solaris disk device is supported by disk utility commands such as format(1M) and newfs(1M). The mandatory Sun disk I/O controls are as follows:

DKIOCINFO

Returns information that describes the disk controller

DKIOCGAPART

Returns a disk's partition map

DKIOCSAPART

Sets a disk's partition map

DKIOCGGEOM

Returns a disk's geometry

DKIOCSGEOM

Sets a disk's geometry

DKIOCGVTOC

Returns a disk's Volume Table of Contents

DKIOCSVTOC

Sets a disk's Volume Table of Contents

Disk Performance

The Solaris DDI/DKI provides facilities to optimize I/O transfers for improved file system performance. A mechanism manages the list of I/O requests so as to optimize disk access for a file system. See Asynchronous Data Transfers (Block Drivers) for a description of enqueuing an I/O request.

The diskhd structure is used to manage a linked list of I/O requests.

struct diskhd {
    long     b_flags;         /* not used, needed for consistency*/
    struct   buf *b_forw,    *b_back;       /* queue of unit queues */
    struct   buf *av_forw,    *av_back;    /* queue of bufs for this unit */
    long     b_bcount;            /* active flag */
};

The diskhd data structure has two buf pointers that the driver can manipulate. The av_forw pointer points to the first active I/O request. The second pointer, av_back, points to the last active request on the list.

A pointer to this structure is passed as an argument to disksort(9F), along with a pointer to the current buf structure being processed. The disksort() routine sorts the buf requests to optimize disk seek. The routine then inserts the buf pointer into the diskhd list. The disksort() program uses the value that is in b_resid of the buf structure as a sort key. The driver is responsible for setting this value. Most Sun disk drivers use the cylinder group as the sort key. This approach optimizes the file system read-ahead accesses.

When data has been added to the diskhd list, the device needs to transfer the data. If the device is not busy processing a request, the xxstart() routine pulls the first buf structure off the diskhd list and starts a transfer.

If the device is busy, the driver should return from the xxstrategy() entry point. When the hardware is done with the data transfer, an interrupt is generated. The driver's interrupt routine is then called to service the device. After servicing the interrupt, the driver can then call the start() routine to process the next buf structure in the diskhd list.