About This Book 1 Review of Device Driver Concepts Part 2 Device Drivers and Symmetric Multiprocessing 2 Overview of the Symmetric Multiprocessing Environment 3 Using Simple Lock Interfaces 4 Using Complex Lock Interfaces 5 Using Funnels Part 3 Device Drivers and Kernel Threads 6 Device Drivers and Multithreaded Programming 7 Using Kernel Threads-Related Interfaces 8 Writing a Disk Device Driver A Summary Tables
Table of Contents
Audience
New and Changed Features
Changes to Chapter 5: Using Funnels
Changes to Chapter 7: Using Kernel Threads-Related Interfaces
Chapter 8: Writing a Disk Device Driver
Appendix B: Example Disk Device Driver
Scope of the Book
Organization
Related Documentation
Hardware Documentation
Bus-Specific Device Driver Documentation
Operating System Overview Documentation
Programming Tools Documentation
System Management Documentation
Porting Documentation
Reference Pages
Reader's Comments
Conventions
1.1 Gathering Information
1.2 Designing a Device Driver
1.3 Allocating Data Structures
1.4 Writing Portable Device Drivers
1.5 Reviewing the Device Driver Kits Delivery Process
1.6 Identifying the Method for Registering Device Interrupt Handlers
2.1 Understanding Hardware Issues Related to Synchronization
2.1.1 Atomicity
2.1.2 Alignment
2.1.3 Granularity
2.2 Understanding the Need for Locking in a Symmetric Multiprocessing Environment
2.3 Comparing Simple Locks, Complex Locks, and Funnels
2.3.1 Simple Locks
2.3.2 Complex Locks
2.3.3 Funnels
2.4 Choosing a Locking Method
2.4.1 Who Has Access to a Particular Resource
2.4.2 Prevention of Access to a Resource While a Kernel Thread Sleeps
2.4.3 Length of Time the Lock Is Held
2.4.4 Execution Speed
2.4.5 Size of Code Blocks
2.4.6 Summary of Locking Methods
2.5 Choosing the Resources to Lock in the Driver
2.5.1 Read-Only Resources
2.5.2 Device Control Status Register Addresses
2.5.3 Driver-Specific Global Resources
2.5.4 System-Specific Global Resources
2.5.5 Example Analysis of a Device Driver to Determine Resources to Lock
3.1 Declaring a Simple Lock Structure
3.2 Initializing a Simple Lock
3.3 Asserting Exclusive Access on a Resource
3.4 Releasing a Previously Asserted Simple Lock
3.5 Trying to Obtain a Simple Lock
3.6 Terminating a Simple Lock
3.7 Using the spl Interfaces with Simple Locks
4.1 Declaring a Complex Lock Data Structure
4.2 Initializing a Complex Lock
4.3 Performing Access Operations on a Complex Lock
4.3.1 Asserting a Complex Lock
4.3.1.1 Asserting a Complex Lock with Read-Only Access
4.3.1.2 Asserting a Complex Lock with Write Access
4.3.2 Releasing a Previously Asserted Complex Lock
4.3.3 Trying to Assert a Complex Lock
4.3.3.1 Trying to Assert a Complex Lock with Read-Only Access
4.3.3.2 Trying to Assert a Complex Lock with Write Access
4.4 Terminating a Complex Lock
5.1 Ensuring That the Funnel Does Not Require Any Locks
5.2 Initializing the Device Switch Tables
6.1 Advantages of Using Kernel Threads in Device Drivers
6.2 Kernel Threads Execution
6.3 Issues Related to Using Kernel Threads
6.4 Kernel Threads Operations
7.1 Data Structures That Kernel Thread Interfaces Use
7.2 Starting a Kernel Thread
7.2.1 Starting a Kernel Thread at a Specified Entry Point
7.2.2 Starting a Fixed Priority Kernel Thread Dedicated to Interrupt Service
7.3 Blocking (Putting to Sleep) a Kernel Thread
7.3.1 Asserting That the Current Kernel Thread Is About to Block Until the Specified Event Occurs
7.3.2 Using the Symmetric Multiprocessor Sleep Interface
7.4 Unblocking (Awakening) Kernel Threads
7.5 Terminating a Kernel Thread
7.6 Setting a Timer for the Current Kernel Thread
8.1 Disk Device Names
8.2 Disk Layout
8.2.1 Disk Geometry
8.2.2 Disk Partitions
8.2.3 Locating the Partition for a Request
8.3 Device-Specific Structure
8.4 Opening and Closing a Device
8.4.1 The open Interface
8.4.2 The read_label Subroutine
8.4.3 The close Interface
8.5 Reading and Writing Data
8.5.1 The read and write Interfaces
8.5.2 The strategy Interface
8.5.3 The minphys Interface
8.6 The ioctl Interface
8.6.1 DIOCGDINFO ioctl Command
8.6.2 DIOCGPART ioctl Command
8.6.3 DIOCSDINFO ioctl Command
8.6.4 DIOCWLABEL ioctl Command
8.6.5 DIOCWDINFO ioctl Command
8.6.6 DIOCGDEFPT ioctl Command
8.6.7 DIOCGCURPT ioctl Command
8.6.8 DEVGETINFO ioctl Command
8.6.9 DEVGETGEOM ioctl Command
8.7 The size Interface
8.8 The dump Interface
A.1 List of Header Files
A.2 List of Kernel Support Interfaces
A.3 ioctl Commands
A.4 List of Global Variables
A.5 List of Data Structures
A.6 List of Device Driver Interfaces
A.7 List of Bus Configuration Interfaces
Figures
2-1 Why Locking Is Needed in an SMP Environment
2-2 Simple Locks Are Spin Locks
2-3 Complex Locks Are Blocking Locks
2-4 A Funnel Forces Execution onto a Single CPU
3-1 Two Instances of the /dev/xx Device Driver Asserting an Exclusive Lock
3-2 One Instance of the /dev/xx Device Driver Releasing an Exclusive Lock
3-3 The /dev/xx Device Driver Trying to Assert an Exclusive Lock
4-1 Three Instances of the if_fta Driver Asserting a Read-Only Complex Lock
4-2 Three Instances of the if_fta Driver Asserting a Write Complex Lock
4-3 One Instance of the if_fta Device Driver Releasing a Complex Write Lock
4-4 The if_fta Driver Trying to Assert a Complex Read-Only Lock
4-5 The if_fta Driver Trying to Assert a Complex Write Lock
6-1 Example Use of Kernel Threads in a Device Driver
8-1 Form for Device Special Files
8-2 Disk Device Minor Number
8-3 Device Information Structure