Documentation Home
> Writing Device Drivers
Writing Device Drivers
Book Information
Preface
Chapter 1 SunOS Kernel and Device Tree
What Is the Kernel?
Multithreading Considerations
Virtual Memory
Special Files
Dynamic Loading of Kernel Modules
Overview of the Solaris 7 DDI/DKI
Device Tree
Example Device Tree
Device Drivers
Displaying the Device Tree
prtconf(1M)
/devices
Binding a Driver to a Device Node
Generic Device Names
Chapter 2 Hardware Overview
SPARC Processor Issues
SPARC Data Alignment
SPARC Structure Member Alignment
SPARC Byte Ordering
SPARC Register Windows
SPARC Floating-Point Operations
SPARC Multiply and Divide Instructions
SPARC Architecture Manual
x86 Processor Issues
x86 Data Alignment
x86 Structure Member Alignment
x86 Byte Ordering
x86 Floating-Point Operations
x86 Architecture Manuals
Store Buffers
System Memory Model
Total Store Ordering (TSO)
Partial Store Ordering (PSO)
Bus Architectures
Device Identification
Self-Identifying Devices
Non-Self-Identifying Devices
Interrupts
Bus Specifics
PCI Local Bus
PCI Address Domain
PCI Configuration Address Space
PCI Configuration Base Address Registers
PCI Memory Address Space
PCI I/O Address Space
PCI Hardware Configuration Files
SBus
SBus Physical Address Space
Physical SBus Addresses
SBus Hardware Configuration Files
VMEbus
VMEbus Hardware Configuration Files
ISA Bus
ISA Bus Memory and I/O Space
Hardware Configuration Files
EISA Bus
Memory and I/O Space
Hardware Configuration Files
MCA Bus
Memory and I/O Space
Hardware Configuration Files
Device Issues
Timing-Critical Sections
Delays
Internal Sequencing Logic
Interrupt Issues
Byte Ordering
Device Attribute Representations
PROM on SPARC Machines
Open Boot PROM 3.x
Help
History
Forth Commands
Walking the PROMs Device Tree
Mapping the Device
Reading and Writing
Interrupts
Chapter 3 Overview of SunOS Device Drivers
What Is a Device Driver?
Types of Device Drivers
Block Device Drivers
Standard Character Device Drivers
Byte-Stream I/O
I/O Control
Device Memory Mapping
Device Polling
STREAMS Drivers
Bus Address Spaces
Address Mapping Setup
Data Access Functions
Memory Space Access
I/O Space Access
Configuration Space Access
Example Device Registers
Device Register Structure
Structure Padding
Finding Padding
Driver Interfaces
Entry Points
Loadable Module Routines
Autoconfiguration Entry Points
Block Driver Entry Points
Character Driver Entry Points
Power Management Entry Point
Driver Structure Overview
Callback Functions
Interrupt Handling
Device-Interrupt Cookies
Block-Interrupt Cookies
Driver Context
Printing Messages
Dynamic Memory Allocation
Software State Management
Software State Structure
Software State Management Routines
Properties
prop_op(9E)
Driver Layout
Header Files
Source Files
Configuration Files
64-Bit-Safe Device Drivers
C Language and Compiler Modes
Compiler Modes
-Xa (ANSI C Mode)
-Xt (Transition Mode)
Function Prototypes
Keywords
const
volatile
Chapter 4 Multithreading
Threads
User Threads
Kernel Threads
Multiprocessing Changes Since the SunOS 4.1 System
Locking Primitives
Storage Classes of Driver Data
Mutual-Exclusion Locks
Setting Up Mutexes
Using Mutexes
Readers/Writer Locks
Semaphores
Thread Synchronization
Condition Variables
Initializing Condition Variables
Multithreading Additions to the State Structure
Using Condition Variables
cv_timedwait(9F)
cv_wait_sig()
cv_timedwait_sig()
Choosing a Locking Scheme
Chapter 5 Autoconfiguration
Autoconfiguration Overview
Autoconfiguration Additions to the State Structure
Driver Loading and Configuration
Data Structures
modlinkage Structure
modldrv Structure
dev_ops Structure
cb_ops Structure
Loadable Driver Interface
Device Configuration
Instance Numbers
Persistent Instances
identify()
probe()
attach()
Registering Interrupts Overview
Mapping Device Registers
Minor Device Nodes
Deferred Attach
detach()
Callbacks
getinfo()
Chapter 6 Interrupt Handlers
Interrupt Handler Overview
Interrupt Specification
Interrupt Number
Interrupt Block Cookies
Bus Interrupt Levels
High-Level Interrupts
Types of Interrupts
Vectored Interrupts
Polled Interrupts
Software Interrupts
Registering Interrupts
Responsibilities of an Interrupt Handler
Interrupt Handling Additions to the State Structure
Handling High-Level Interrupts
High-level Mutexes
High-Level Interrupt Handling Example
Chapter 7 DMA
DMA Model
Types of Device DMA
Bus-Master DMA
Third-party DMA
First-party DMA
Types of Host Platform DMA
DMA Software Components: Handles, Windows, and Cookies
Scatter-Gather
DMA Operations
Bus-Master DMA
First-Party DMA
Third-Party DMA
DMA Attributes
ddi_dma_attr Structure
SBus--Example One
VMEbus--Example Two
ISAbus--Example Three
Object Locking
Allocating a DMA Handle
Handling Resource Allocation Failures
Allocating DMA Resources
DMA Additions to the State Structure
Device Register Structure
DMA Callback Example
Determining Maximum Burst Sizes
Programming the DMA Engine
Freeing the DMA Resources
Freeing the DMA Handle
Canceling DMA Callbacks
Synchronizing Memory Objects
Cache
ddi_dma_sync()
DMA Windows
State Structure
Allocating Private DMA Buffers
Chapter 8 Power Management
Power Management Overview
Device Power Management
System Power Management
Power Management Additions to the State Structure
Device Power Management Model
Components
Idleness
Power Levels
Dependency
Policy
Device Power Management Interfaces
pm_create_components()
pm_destroy_components()
pm_set_normal_power()
pm_get_normal_power()
Busy-Idle State Transitions
pm_busy_component()
pm_idle_component()
Device Power State Transitions
ddi_dev_is_needed()
Entry Points Used by Device Power Management
power()
detach()
attach()
System Power Management Model
Autoshutdown Threshold
Busy State
Hardware State
Policy
Entry Points Used by System Power Management
detach()
attach()
Device Access
Power Management Flow of Control
Device Power Management Flow of Control for Component Zero
Device Power Manangement Flow of Control for Components Other Than Component Zero
Chapter 9 Drivers for Character Devices
Character Driver Structure Overview
Character Driver Device Access
Entry Points
Autoconfiguration
Controlling Device Access
open(9E)
close(9E)
I/O Request Handling
User Addresses
Vectored I/O
uio Structure
Synchronous Versus Asynchronous I/O
Data Transfer Methods
Programmed I/O Transfers
uiomove( )
uwritec(9F) and ureadc(9F)
DMA Transfers (Synchronous)
DMA Transfers (Asynchronous)
minphys(9F)
strategy(9E)
Mapping Device Memory
segmap(9E)
devmap(9E)
Multiplexing I/O on File Descriptors
Adding Polling to the State Structure
chpoll(9E)
Miscellaneous I/O Control
ioctl(9E)
I/O Control Support for 64-Bit Capable Device Drivers
Chapter 10 Drivers for Block Devices
Block Driver Structure Overview
Block Driver Device Access
File I/O
Block Driver Additions to the State Structure
Entry Points
Autoconfiguration
Controlling Device Access
open(9E)
close(9E)
Data Transfers
strategy(9E)
buf Structure
bp_mapin(9F)
Synchronous Data Transfers
Asynchronous Data Transfers
Miscellaneous Entry Points
dump(9E)
print(9E)
Chapter 11 Mapping Device or Kernel Memory
Memory Mapping Operations
Exporting the Mapping
devmap()()
Associating Device Memory With User Mappings
Associating Kernel Memory With User Mappings
Device Mapping Additions to the State Structure
Allocating Kernel Memory for User Access
Exporting Kernel Memory to Applications
Freeing Kernel Memory Exported for User Access
Chapter 12 Device Context Management
What Is a Device Context?
Context Management Model
Multiprocessor Considerations
Context Management Additions to the State Structure
Context Management Operation
devmap_callback_ctl Structure
Associating User Mappings With Driver Notifications
Managing Mapping Accesses
devmap_load()
devmap_unload()
Device Context Management Entry Points
devmap_map()
devmap_access()
devmap_contextmgt()
devmap_dup()
devmap_unmap()
Chapter 13 SCSI Target Drivers
SCSI Target Driver Overview
Reference Documents
Sun Common SCSI Architecture Overview
General Flow of Control
SCSA Functions
SCSA Compatibility Functions
SCSI Target Drivers
Hardware Configuration File
Declarations and Data Structures
scsi_device Structure
scsi_pkt Structure
SCSI Additions to the State Structure
Autoconfiguration
probe(9E)
attach(9E)
detach(9E)
getinfo(9E)
Resource Allocation
scsi_init_pkt(9F)
scsi_alloc_consistent_buf(9F)
Building and Transporting a Command
Building a Command
Setting Target Capabilities
Transporting a Command
Synchronous scsi_transport(9F)
Command Completion
Reuse of Packets
Auto-Request Sense Mode
Dump Handling
dump(9E)
Chapter 14 SCSI Host Bus Adapter Drivers
SCSI HBA Driver Overview
SCSA Interface
HBA Transport Layer
SCSA HBA Interfaces
SCSA HBA Entry Point Summary
SCSA HBA Data Structures
scsi_hba_tran Structure
scsi_address Structure
scsi_device Structure
scsi_pkt Structure
Per-Target Instance Data
Transport Structure Cloning (optional)
SCSA HBA Functions
HBA Driver Dependency and Configuration Issues
HBA Configuration Properties
scsi-reset-delay Property
scsi-options Property
Per-target scsi-options
Declarations and Structures
Per-Command Structure
HBA Additions to the State Structure
Module Initialization Entry Points
_init(9E)
_fini(9E)
Autoconfiguration Entry Points
attach(9E)
Soft State Structure
DMA
Transport Structure
Attaching an HBA Driver
Register Mapping
Adding an Interrupt Handler
Report Attachment Status
detach(9E)
SCSA HBA Entry Points
Target Driver Instance Initialization
tran_tgt_init(9E)
tran_tgt_probe(9E)
tran_tgt_free(9E)
Resource Allocation
tran_init_pkt(9E)
Allocation and Initialization of a scsi_pkt(9S) Structure
Allocation of DMA Resources
Reallocation of DMA Resources for Next Portion of Data Transfer
tran_destroy_pkt(9E)
tran_sync_pkt(9E)
tran_dmafree(9E)
Command Transport
tran_start(9E)
Interrupt Handler and Command Completion
Timeout Handler
Capability Management
tran_getcap(9E)
tran_setcap(9E)
Abort and Reset Management
tran_abort(9E)
tran_reset(9E)
tran_reset_notify(9E)
Driver Installation
Hardware Configuration File
Installing the Driver
x86 Target Driver Configuration Properties
Chapter 15 Loading and Unloading Drivers
Preparing for Installation
Module Naming
Compiling and Linking the Driver
Writing a Hardware Configuration File
Installing and Removing Drivers
Copying the Driver to a Module Directory
Optionally Editing /etc/devlink.tab
Running add_drvadd_drv(1M)
Removing the Driver
Loading Drivers
Getting the Driver Module's ID
Unloading Drivers
Driver Packaging
Package Postinstall
Package Postremove
Chapter 16 Debugging
Machine Configuration
Setting Up a tip(1) Connection
Setting Up the Host System
Setting Up the Test System for SPARC Platforms
Setting Up the Test System for x86 Platforms
Preparing for Disasters
Critical System Files
Booting an Alternate Kernel
Booting Off the Network or CD-ROM
Re-creating /devices and /dev
Booting Off a Backup Root Partition
Coding Hints
Process Layout for Sun4m, Sun4c, Sun4d, and x86 Platforms
Process Layout for Sun4u Platforms
System Support
cmn_err()()
ASSERT()()
mutex_owned()()
Conditional Compilation and Variables
volatile and _depends_on
Debugging Tools
/etc/system
moddebug
modload and modunload
Saving System Core Dumps
adb and kadb
Starting adb
Starting kadb
Exiting
Commands
Register Identifiers
Display and Control Commands
Breakpoints
Conditional Breakpoints
Macros
Example: adb on a Core Dump
Example: kadb on a Deadlocked Thread
Testing
Configuration Testing
Functionality Testing
Error Handling
Stress, Performance, and Interoperability Testing
DDI/DKI Compliance Testing
Installation and Packaging Testing
Testing Specific Types of Drivers
Tape Drivers
Disk Drivers
Asynchronous Communication Drivers
Network Drivers
Appendix A Converting a SunOS 4.1 Device Driver to SunOS 5.7
Before Starting the Conversion
Review Existing Functionality
Read the Manual
ANSI C Compliance
Development Environment
DDI/DKI
Avoid Using Non-DDI/DKI Interfaces
UNIX System V Release 4
Development Tools
Debugging Tools
ANSI C Features
volatile
Function Prototypes
Header Files
Summary of Changes
Autoconfiguration Changes
Changes to Routines
Instance Numbers
Changes to /devices
Changes to/dev
Multithreading Changes
Locking Changes
Mutual Exclusion Locks
Condition Variables
Catching Signals
cv_timedwait()()
Other Locks
Lock Granularity
Interrupt Changes
DMA Changes
Conversion Notes
identify(9E)
probe(9E)
attach(9E)
getinfo(9E)
open(9E)
psize()
read(9E) and write(9E)
ioctl(9E)
strategy(9E)
mmap(9E)
chpoll(9E)
SunOS 4.1 to SunOS 5.7 Differences
Appendix B Interface Transition List
Appendix C Summary of Solaris 7 DDI/DKI Services
buf(9S) Handling
Copying Data
Device Access
Device Configuration
Device Information
DMA Handling
Flow of Control
Interrupt Handling
Kernel Statistics
Memory Allocation
Memory Space Access
Common Device Access Functions
Polling
Power Management
Printing System Messages
Process Signaling
Properties
Register and Memory Mapping
Device Context Management
PCI Configuration
I/O Port Access
SCSI and SCSA
Soft State Management
String Manipulation
System Information
Thread Synchronization
Timing
uio(9S) Handling
Utility Functions
Appendix D Sample Driver Source Code
Sample Drivers
Appendix E Driver Code Layout Structure
Header Files
xx.c Files
driver .conf Files
Appendix F Making a Device Driver 64-Bit Ready
How 64-Bit Drivers Differ From 32-Bit Drivers
C Language Data Type Models: LP64 and ILP32
Potential Problems to Avoid
Overview of Driver-Specific Issues
General Conversion Steps
Convert Driver Code to Be 64-Bit Clean
Useful Tools to Check Data Model Conversion
Update Data Structures to Preserve 32-Bit Data in Register Layouts
Check Use of Derived Types That Change Size Between 32-Bit and 64-Bit Environments
Change Common Access Functions to Fixed-Width Versions
Modify Routines That Handle Data Sharing
ddi_model_convert_from(9F)
ioctl(9E)
devmap(9E)
mmap(9E)
Check Changed Fields in DDI Data Structures
buf(9S)
ddi_dma_attr(9S)
ddi_dma_cookie(9S)
scsi_pkt(9S)
Check Changed Arguments of DDI Functions
getrbuf(9F)
drv_getparm(9F)
delay(9F) and timeout(9F)
rmallocmap(9F) and rmallocmap_wait(9F)
scsi_alloc_consistent_buf(9F)
uiomove(9F)
cv_timedwait(9F) and cv_timedwait_sig(9F)
ddi_device_copy(9F)
ddi_device_zero(9F)
ddi_dma_mem_alloc(9F)
Convert Well-Known Ioctl Interfaces
Device Sizes
Data Structure Macros
How Structure Macros Work
Declaring and Initializing Structure Handles
Operations on Structure Handles
Other Operations
When to Use Structure Macros
Appendix G Advanced Topics
Multithreading
Lock Granularity
Avoiding Unnecessary Locks
Locking Order
Scope of a Lock
Potential Panics
Sun Disk Device Drivers
Disk I/O Controls
Disk Performance
SCSA
Global Data Definitions
Tagged Queuing
Untagged Queueing
Appendix H Converting Device Drivers to Support Hotplugging
Introduction
Overview of Hotplugging
Hot Removal With No Replacement
Hot Insertion
Hot Removal Followed by Insertion
Solaris Hotplugging Driver Issues
Hot Removal
Hot Insertion
Hotplug-Capable Device Driver Development
D_HOTPLUG Flag
Detach Entry Point
DDI_DETACH Command
DDI_SUSPEND Command
Attach Entry Point
DDI_PM_RESUME Command
DDI_RESUME Command
Special Issues With SCSI HBA Drivers
Device Driver Testing
Unloading
Suspend/Resume Testing
Conclusion
© 2010, Oracle Corporation and/or its affiliates