Documentation Home
> Writing Device Drivers
Writing Device Drivers
Book Information
Preface
Chapter 1 Solaris Kernel and Device Tree
What Is the Kernel?
Multithreaded Execution Environment
Virtual Memory
Special Files
Solaris 8 DDI/DKI
Device Tree
Example Device Tree
Device Drivers
Displaying the Device Tree
libdevinfo(3DEVINFO)
prtconf(1M)
/devices
Binding a Driver to a Device
Generic Device Names
Chapter 2 Overview of Solaris Device Drivers
What Is a Device Driver?
Types of Device Drivers
Block Device Drivers
Character Device Drivers
Byte-Stream I/O
Memory Mapped Devices
STREAMS Drivers
Driver Module Entry Points
Loadable Module Entry Points
Autoconfiguration Entry Points
Character and Block Driver Entry Points
Power Management Entry Point
Driver Context
Interrupt Handling
Callback Functions
Printing Messages
Device IDs
Software State Management
Dynamic Memory Allocation
Programmed I/O Device Access
Direct Memory Access (DMA)
Properties
Driver and Device Statistics
64-Bit Considerations
Kernel Programming Model
Data Model Concepts
ioctl(9E) Considerations
Chapter 3 Multithreading
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
Waiting for the Condition
Signaling the Condition
cv_timedwait(9F)
cv_wait_sig(9F)
cv_timedwait_sig(9F)
Choosing a Locking Scheme
Potential Pitfalls
Chapter 4 Properties
Property Names
Looking up Properties
prop_op(9E)
Chapter 5 Autoconfiguration
Driver Loading and Unloading
Data Structures
modlinkage Structure
modldrv Structure
dev_ops Structure
cb_ops Structure
Loadable Driver Interfaces
_init(9E)
_fini(9E)
_info(9E)
Device Configuration Concepts
Device Instances and Instance Numbers
Minor Nodes and Minor Numbers
probe(9E)
attach(9E)
Driver Soft State Management
Lock and Conditional Variable Initialization
Creating Minor Device Nodes
Deferred Attach
detach(9E)
getinfo(9E)
Device IDs
Registering Device IDs
Registering a Device-Supplied ID
Registering a Fabricated ID
Unregistering Device IDs
Chapter 6 Device Access -- Programmed I/O
Device Memory
Managing Differences in Device and Host Endianness
Managing Data Ordering Requirements
ddi_device_acc_attr(9S)
Mapping Device Memory
Mapping Setup
Device Access Functions
Alternate Device Access Interfaces
Memory Space Access
I/O Space Access
PCI Configuration Space Access
Chapter 7 Interrupt Handlers
Interrupt Handler Overview
Interrupt Specification
Interrupt Number
Interrupt Block Cookies
Device Interrupts
High-Level Interrupts
Normal Interrupts
Software Interrupts
Registering Interrupts
Interrupt Handlers
Handling High-Level Interrupts
High-level Mutexes
High-Level Interrupt Handling Example
Chapter 8 Direct Memory Access (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
ISA Bus Example
Object Locking
Allocating a DMA Handle
Allocating DMA Resources
Device Register Structure
DMA Callback Example
Determining Maximum Burst Sizes
Allocating Private DMA Buffers
Handling Resource Allocation Failures
Programming the DMA Engine
Freeing the DMA Resources
Freeing the DMA Handle
Canceling DMA Callbacks
Synchronizing Memory Objects
Cache
ddi_dma_sync(9F)
DMA Windows
Chapter 9 Power Management
Power Management Framework
Device Power Management
System Power Management
Device Power Management Model
Components
Multiple Components
Idleness
Power Levels
Dependency
Policy
Device Power Management Interfaces
Busy-Idle State Transitions
pm_busy_component(9F)
pm_idle_component(9F)
Device Power State Transitions
pm_raise_power(9F)
pm_lower_power(9F)
pm_power_has_changed(9F)
Entry Points Used by Device Power Management
power(9E)
System Power Management Model
Autoshutdown Threshold
Busy State
Hardware State
Policy
Entry Points Used by System Power Management
detach(9E)
attach(9E)
Device Access
Power Management Flow of Control
Changes to Power Management Interfaces
Chapter 10 Drivers for Character Devices
Character Driver Structure Overview
Entry Points
Autoconfiguration
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(9F)
uwritec(9F) and uread(9F)
DMA Transfers (Synchronous)
DMA Transfers (Asynchronous)
minphys(9F)
strategy(9E)
Mapping Device Memory
segmap(9E)
devmap(9E)
Multiplexing I/O on File Descriptors
chpoll(9E)
Miscellaneous I/O Control
ioctl(9E)
I/O Control Support for 64-Bit Capable Device Drivers
Handling copyout(9F) Overflow
32-bit and 64-bit Data Structure Macros
How Do the Structure Macros Work?
When to Use Structure Macros
Declaring and Initializing Structure Handles
Operations on Structure Handles
Other Operations
Chapter 11 Drivers for Block Devices
Block Driver Structure Overview
Block Driver Device Access
File I/O
Entry Points
Autoconfiguration
Controlling Device Access
open(9E)
close(9E)
strategy(9E)
buf Structure
bp_mapin(9F)
Synchronous Data Transfers
Asynchronous Data Transfers
Miscellaneous Entry Points
dump(9E)
print(9E)
Disk Device Drivers
Disk ioctls
Disk Performance
Chapter 12 Mapping Device or Kernel Memory
Memory Mapping Operations
Exporting the Mapping
devmap(9E)
Associating Device Memory With User Mappings
Associating Kernel Memory With User Mappings
Allocating Kernel Memory for User Access
Exporting Kernel Memory to Applications
Freeing Kernel Memory Exported for User Access
Chapter 13 Device Context Management
What Is a Device Context?
Context Management Model
Multiprocessor Considerations
Context Management Operation
devmap_callback_ctl Structure
Device Context Management Entry Points
devmap_map(9E)
devmap_access(9E)
devmap_contextmgt(9E)
devmap_dup(9E)
devmap_unmap(9E)
Associating User Mappings With Driver Notifications
Managing Mapping Accesses
devmap_load(9F)
devmap_unload(9F)
Chapter 14 SCSI Target Drivers
SCSI Target Driver Overview
Reference Documents
Sun Common SCSI Architecture Overview
General Flow of Control
SCSA Functions
SCSI Target Drivers
Hardware Configuration File
Declarations and Data Structures
scsi_device Structure
scsi_pkt Structure
Autoconfiguration
probe(9E)
attach(9E)
detach(9E)
getinfo(9E)
Resource Allocation
scsi_init_pkt(9F)
scsi_sync_pkt(9F)
scsi_destroy_pkt(9F)
scsi_alloc_consistent_buf(9F)
scsi_free_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)
SCSI Options
Chapter 15 SCSI Host Bus Adapter Drivers
SCSI 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
Declarations and Structures
Per-Command 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
Create Power Manageable Components
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_bus_reset(9E)
tran_reset_notify(9E)
Dynamic Reconfiguration
tran_quiesce(9E) and tran_unquiesce(9E)
SCSI HBA Driver Specific Issues
Installing HBA Drivers
HBA Configuration Properties
scsi-reset-delay Property
scsi-options Property
Per-target scsi-options
IA Target Driver Configuration Properties
Support for Queuing
Tagged Queuing
Untagged Queuing
Chapter 16 Compiling, Loading, Packaging, and Testing Drivers
Driver Code Layout Structure
Header Files
.c Files
driver.conf Files
Preparing for Installation
Module Naming
Compiling and Linking the Driver
Module Dependencies
Writing a Hardware Configuration File
Installing and Removing Drivers
Copying the Driver to a Module Directory
Optionally Editing /etc/devlink.tab
Running add_drv(1M)
Removing the Driver
Loading Drivers
Unloading Drivers
Driver Packaging
Package Postinstall
Package Preremove
Testing
Configuration Testing
Functionality Testing
Error Handling
Testing Loading and Unloading
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
Chapter 17 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 IA Platforms
Preparing for Disasters
Back Up Critical System Files
Prepare and Boot an Alternate Kernel
Prepare Other Back Up Plans
Saving System Crash Dumps
Disaster Recovery
Recommended Coding Practices
Use cmn_err(9F) to Log Driver Activity
Use ASSERT(9F) to Catch Invalid Assumptions
Use mutex_owned(9F) to Validate and Document Locking Requirements
Use Conditional Compilation to Toggle Costly Debugging Features
Runtime Debugging Tools
/etc/system
moddebug
kmem_flags
modload, modunload, and modinfo
The kadb Kernel Debugger
Starting kadb
Exiting
Commands
Register Identifiers
Display and Control Commands
Breakpoints
Conditional Breakpoints
Macros
Output Pager
Example: kadb on a Deadlocked Thread
Post-Mortem Debugging
Getting Started With MDB
Important MDB Commands
Navigating the Device Tree
Retrieving Driver Soft State Information
Detecting Kernel Memory Leaks
Writing Debugger Commands
Appendix A 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
IA Processor Issues
IA Byte Ordering
IA Architecture Manuals
Endianness
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
ISA Bus
ISA Bus Memory and I/O Space
Hardware Configuration Files
Bootable (Realmode) Drivers
Device Issues
Timing-Critical Sections
Delays
Internal Sequencing Logic
Interrupt Issues
PROM on SPARC Machines
Open Boot PROM 3
Help
History
Forth Commands
Walking the PROMs Device Tree
Mapping the Device
Reading and Writing
Appendix B Summary of Solaris 8 DDI/DKI Services
Introduction
Module Functions
Device Information Tree Node (dev_info_t) Functions
Device (dev_t) Functions
Property Functions
Device Software State Functions
Memory Allocation and Deallocation Functions
Kernel Thread Control and Synchronization Functions
Interrupt Functions
Programmed I/O Functions
Direct Memory Access (DMA) Functions
User Space Access Functions
User Process Event Functions
User Process Information Functions
User Application Kernel and Device Access Functions
Time-Related Functions
Power Management Functions
Kernel Statistics Functions
Kernel Logging and Printing Functions
Buffered I/O Functions
Virtual Memory Functions
Device ID Functions
SCSI Functions
Resource Map Management Functions
System Global State
Utility Functions
Appendix C Making a Device Driver 64-Bit Ready
Introduction
General Issues
Driver-Specific Issues
General Conversion Steps
Use Fixed-width Types for Hardware Registers
Use Fixed-width Common Access Functions
Check and Extend Use of Derived Types
Check Changed Fields in DDI Data Structures
buf(9S)
ddi_dma_attr(9S)
ddi_dma_cookie(9S)
scsi_arq_status(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)
Modify Routines That Handle Data Sharing
ioctl(9E)
devmap(9E)
mmap(9E)
Well-known ioctl Interfaces
Device Sizes
Appendix D DDI Interfaces for Cluster-Aware Drivers
Device Classification
Enumerated Devices
Node Specific Devices
Global Devices
Node Bound Devices
Minor Number Space Management
Device Interfaces
Appendix E Hardened Drivers
Overview of the Process
Responsibilities of the Driver Writer
Device Driver Instances
Exclusive Use of DDI Access Handles
Detecting Corrupted Data
Corruption of Device Management and Control Data
Corruption of Received Data
Detecting Faults
Containment of Faults
Handling Stuck Interrupts
DMA Isolation
Thread Interaction
Threats From Top-Down Requests
Adaptive Strategies
Index
Numbers and Symbols
A
B
C
D
E
F
G
H
I
K
L
M
N
O
P
Q
R
S
T
U
V
W
© 2010, Oracle Corporation and/or its affiliates