Documentation Home
> Writing Device Drivers
Writing Device Drivers
Book Information
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
Preface
Chapter 1 Solaris Kernel and Device Tree
What Is the Kernel?
Multithreaded Execution Environment
Virtual Memory
Devices as Special Files
DDI/DKI Interfaces
Overview of the Device Tree
Device Tree Components
Displaying the Device Tree
The libdevinfo Library
The prtconf Command
The /devices Directory
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
Device Driver Design Considerations
DDI/DKI Facilities
Device IDs
Device Properties
Interrupt Handling
Callback Functions
Software State Management
Programmed I/O Device Access
Direct Memory Access (DMA)
Driver and Device Statistics
Driver Context
Returning Errors
Dynamic Memory Allocation
Hotplugging
Driver Layout
Header Files
Source Files
Configuration Files
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 in Thread Synchronization
Initializing Condition Variables
Waiting for the Condition
Signaling the Condition
cv_wait() and cv_timedwait() Functions
cv_wait_sig() Function
cv_timedwait_sig() Function
Choosing a Locking Scheme
Potential Locking Pitfalls
Chapter 4 Properties and Events
Device Properties
Device Property Names
Creating and Updating Properties
Looking up Properties
prop_op() Entry Point
Events
How Drivers Track Events: ddi_log_sysevent()
Event Name-Value Pairs
Kernel Statistics
Chapter 5 Driver Autoconfiguration
Driver Loading and Unloading
Data Structures Required for Drivers
modlinkage Structure
modldrv Structure
dev_ops Structure
cb_ops Structure
Loadable Driver Interfaces
_init() Example
_fini() Example
_info() Example
Device Configuration Concepts
Device Instances and Instance Numbers
Minor Nodes and Minor Numbers
The probe() Entry Point
The attach() Entry Point
Driver Soft State Management
Lock and Conditional Variable Initialization
Creating Minor Device Nodes
Deferred Attach
The detach() Entry Point
The getinfo() Entry Point
Using 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 Structure
Mapping Device Memory
Mapping Setup Example
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 Handler Responsibilities
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
DMA Operations
Performing Bus-Master DMA Transfers
Performing First-Party DMA Transfers
Performing Third-Party DMA Transfers
DMA Attributes
ddi_dma_attr Structure
SBus Example
ISA Bus Example
Managing DMA Resources
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
Power Management Components
Multiple Power Management Components
Power Management States
Power Levels
Power Management Dependencies
Automatic Power Management for Devices
Device Power Management Interfaces
Busy-Idle State Transitions
Device Power State Transitions
power() Entry Point
System Power Management Model
Autoshutdown Threshold
Busy State
Hardware State
Automatic Power Management for Systems
Entry Points Used by System Power Management
detach() Entry Point
attach() Entry Point
Power Management Device Access Example
Power Management Flow of Control
Changes to Power Management Interfaces
Chapter 10 Drivers for Character Devices
Character Driver Structure Overview
Character Device Autoconfiguration
Device Access (Character Drivers)
open() Entry Point (Character Drivers)
close() Entry Point (Character Drivers)
I/O Request Handling
User Addresses
Vectored I/O
Synchronous Versus Asynchronous I/O
Data Transfer Methods
Programmed I/O Transfers
DMA Transfers (Synchronous)
DMA Transfers (Asynchronous)
minphys() Entry Point
strategy() Entry Point
Mapping Device Memory
segmap() Entry Point
devmap() Entry Point
Multiplexing I/O on File Descriptors
Miscellaneous I/O Control
ioctl() Entry Point (Character Drivers)
I/O Control Support for 64-Bit Capable Device Drivers
Handling copyout() 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
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)
Miscellaneous Entry Points
dump() Entry Point (Block Drivers)
print() Entry Point (Block Drivers)
Disk Device Drivers
Disk ioctls
Disk Performance
Chapter 12 Mapping Device and Kernel Memory
Memory Mapping Operation Overview
Exporting the Mapping
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
Introduction to Device Context
What Is a Device Context?
Context Management Model
Context Management Operation
devmap_callback_ctl Structure
Device Context Management Entry Points
devmap() Entry Point
devmap_access() Entry Point
devmap_contextmgt() Entry Point
devmap_dup() Entry Point
devmap_unmap() Entry Point
Associating User Mappings With Driver Notifications
Managing Mapping Accesses
devmap_load() Entry Point
devmap_unload() Entry Point
Chapter 14 SCSI Target Drivers
Introduction to Target Drivers
Sun Common SCSI Architecture Overview
General Flow of Control
SCSA Functions
Hardware Configuration File
Declarations and Data Structures
scsi_device Structure
scsi_pkt Structure
Autoconfiguration for SCSI Target Drivers
probe() Entry Point (SCSI Target Drivers)
attach() Entry Point (SCSI Target Drivers)
detach() Entry Point (SCSI Target Drivers)
getinfo() Entry Point (SCSI Target Drivers)
Resource Allocation
scsi_init_pkt() Function
scsi_sync_pkt() Function
scsi_destroy_pkt() Function
scsi_alloc_consistent_buf() Function
scsi_free_consistent_buf() Function
Building and Transporting a Command
Building a Command
Setting Target Capabilities
Transporting a Command
Synchronous scsi_transport() Function
Command Completion
Reuse of Packets
Auto-Request Sense Mode
Dump Handling
SCSI Options
Chapter 15 SCSI Host Bus Adapter Drivers
Introduction to Host Bus Adapter Drivers
SCSI Interface
SCSA HBA Interfaces
SCSA HBA Entry Point Summary
SCSA HBA Data Structures
scsi_hba_tran(9S) Structure
scsi_address Structure
scsi_device Structure
scsi_pkt Structure
Per-Target Instance Data
Transport Structure Cloning
SCSA HBA Functions
HBA Driver Dependency and Configuration Issues
Declarations and Structures
Per-Command Structure
Module Initialization Entry Points
_init() Entry Point (SCSI HBA Drivers)
_fini() Entry Point (SCSI HBA Drivers)
Autoconfiguration Entry Points
attach() Entry Point (SCSI HBA Drivers)
Soft State Structure
DMA
Transport Structure
Attaching an HBA Driver
Register Mapping
Adding an Interrupt Handler
Create Power Manageable Components
Report Attachment Status
detach() Entry Point (SCSI HBA Drivers)
SCSA HBA Entry Points
Target Driver Instance Initialization
tran_tgt_init() Entry Point
tran_tgt_probe() Entry Point
tran_tgt_free() Entry Point
Resource Allocation
tran_tgt_pkt() Entry Point
Allocation and Initialization of a scsi_pkt(9S) Structure
Allocation of DMA Resources
Reallocation of DMA Resources for Data Transfer
tran_destroy_pkt() Entry Point
tran_sync_pkt() Entry Point
tran_dmafree() Entry Point
Command Transport
tran_start() Entry Point
Interrupt Handler and Command Completion
Timeout Handler
Capability Management
tran_getcap() Entry Point
tran_setcap() Entry Point
Abort and Reset Management
tran_abort() Entry Point
tran_reset() Entry Point
tran_bus_reset() Entry Point
tran_reset_notify() Entry Point
Dynamic Reconfiguration
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
Chapter 16 Drivers for Network Devices
Generic LAN Driver Overview
Type DL_ETHER: Ethernet V2 and ISO 8802-3 (IEEE 802.3)
Types DL_TPR and DL_FDDI: SNAP Processing
Type DL_TPR: Source Routing
Style 1 and Style 2 DLPI Providers
Implemented DLPI Primitives
Implemented ioctl Functions
GLD Driver Requirements
Network Statistics
Declarations and Data Structures
gld_mac_info Structure
gld_stats Structure
GLD Arguments
GLD Entry Points
gldm_reset() Entry Point
gldm_start() Entry Point
gldm_stop() Entry Point
gldm_set_mac_addr() Entry Point
gldm_set_multicast() Entry Point
gldm_set_promiscuous() Entry Point
gldm_send() Entry Point
gldm_intr() Entry Point
gldm_get_stats() Entry Point
gldm_ioctl() Entry Point
GLD Return Values
GLD Service Routines
gld_mac_alloc() Function
gld_mac_free() Function
gld_register() Function
gld_unregister() Function
gld_recv() Function
gld_sched() Function
gld_intr() Function
Chapter 17 Compiling, Loading, Packaging, and Testing Drivers
Driver Code Layout Structure
Header Files
.c Files
driver.conf Files
Preparing for Driver Installation
Compiling and Linking the Driver
Module Dependencies
Writing a Hardware Configuration File
Installing, Updating, and Removing Drivers
Copying the Driver to a Module Directory
Installing Drivers with add_drv()
Updating Driver Information
Removing the Driver
Loading and Unloading Drivers
Driver Packaging
Package Postinstall
Package Preremove
Testing Drivers
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 18 Debugging
Machine Configuration
Setting Up a tip Connection
To Set 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 Backup Plans
Saving System Crash Dumps
Disaster Recovery
Runtime Debugging Tools
/etc/system File
Controlling Module Loading with moddebug
kmem_flags
modload, modunload, and modinfo Commands
The kadb Kernel Debugger
Starting kadb
Exiting kadb
kadb Command Usage
Register Identifiers
Display and Control Commands
Breakpoints
Conditional Breakpoints
kadbMacros
Device Macros
Examples: Use of Device Macros
Thread Macros
kadb Output Pager
Example: kadb on a Deadlocked Thread
Post-Mortem Debugging
Getting Started With the Modular Debugger
Important mdb Commands
Displaying Data Structures with mdb
Navigating the Device Tree with mdb
Retrieving Driver Soft State Information
Detecting Kernel Memory Leaks
Writing Debugger Commands with mdb
Chapter 19 Recommended Coding Practices
Debugging
Use cmn_err() to Log Driver Activity
Use ASSERT() to Catch Invalid Assumptions
Use mutex_owned() to Validate and Document Locking Requirements
Use Conditional Compilation to Toggle Costly Debugging Features
Defensive Programming
Using Separate Device Driver Instances
Exclusive Use of DDI Access Handles
Detecting Corrupted Data
Corruption of Device Management and Control Data
Corruption of Received Data
DMA Isolation
Handling Stuck Interrupts
Additional Programming Considerations
Thread Interaction
Threats From Top-Down Requests
Adaptive Strategies
Declaring a Variable Volatile
Serviceability
Periodic Health Checks
Appendix A Hardware Overview
SPARC Processor Issues
SPARC Data Alignment
SPARC Structure Member Alignment
SPARC Byte Ordering
SPARC Register Windows
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
Supported Interrupt Types
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
Device Issues
Timing-Critical Sections
Delays
Internal Sequencing Logic
Interrupt Issues
PROM on SPARC Machines
Open Boot PROM 3
Forth Commands
Walking the PROMs Device Tree
Mapping the Device
Reading and Writing
Appendix B Summary of Solaris 9 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 to 64–Bit Driver Design
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 Structure Changes
ddi_dma_attr
ddi_dma_cookie Structure Changes
csi_arq_status Structure Changes
scsi_pkt Structure Changes
Check Changed Arguments of DDI Functions
getrbuf() Argument Changes
drv_getparm() Argument Changes
delay() and timeout () Argument Changes
rmallocmap() and rmallocmap_wait() Argument Changes
scsi_alloc_consistent_buf() Argument Changes
uiomove() Argument Changes
cv_timedwait() and cv_timedwait_sig() Argument Changes
ddi_device_copy() Argument Changes
ddi_device_zero() Argument Changes
ddi_dma_mem_alloc() Argument Changes
Modify Routines That Handle Data Sharing
Data Sharing in ioctl()
Data Sharing in devmap()
Data Sharing in mmap()
Well-known ioctl Interfaces
Device Sizes
© 2010, Oracle Corporation and/or its affiliates