Chapter 16 Common Driver Design Issues

This chapter contains the following information:

16.1 Managing Hardware Priorities

16.2 Using Spin Locks

16.2.1 Providing Storage for Spin Locks and Protected Data

16.2.2 Initializing Spin Locks

16.2.3 Calling Support Routines That Use Spin Locks

16.2.4 Releasing Spin Locks Promptly

16.2.5 Preventing Errors or Deadlocks While Using Spin Locks

16.3 Polling a Device

16.4 Managing Memory Usage

16.4.1 Using System Memory

16.4.1.1 NT Driver Access to User-Space Memory

16.4.1.2 Setting up MDLs for Partial Transfer Requests

16.4.1.3 Allocating System-Space Memory

16.4.1.4 Remapping Bus-Relative Memory-Space Addresses to Logical Addresses

16.4.2 Using the Kernel Stack

16.4.3 Using Zone Buffers

16.5 Maintaining Cache Coherency for DMA and PIO

16.5.1 Flushing Cached Data during DMA Operations

16.5.2 Flushing Cached Data during PIO Operations

16.6 Error Logging and NTSTATUS Values

16.6.1 Calling IoAllocateErrorLogEntry

16.6.2 Filling in an Error Log Packet

16.6.3 Setting NTSTATUS Values in Error Log Packets

16.6.4 Calling IoWriteErrorLogEntry

16.6.5 Defining New IO_ERR_XXX

16.6.6 Defining Private NTSTATUS Constants

16.7 Handling Removable Media

16.8 Using the Registry

16.8.1 Registry Paths Supplied to NT Drivers

16.8.1.1 RegistryPath, DriverName, and Device Object Names

16.8.1.2 Load-control Sets for NT Drivers

16.8.1.3 HardwareDatabase and the System DeviceMap

16.8.2 Getting Device Hardware Configuration Information

16.8.2.1 Calling IoQueryDeviceDescription

16.8.2.2 Calling HalGetBusData or HalGetBusDataByOffset

16.8.3 Claiming Hardware Resources

16.8.3.1 Calling IoReportResourceUsage

16.8.3.2 Calling IoAssignResources or HalAssignSlotResources

16.8.4 Setting Up Driver-specific, User-visible Error Logging

16.8.5 Using the RegistryPath Parameters

16.9 Setting Up Symbolic Links

16.9.1 Making a Named Device Object Visible to User-mode Applications

16.9.2 Creating Symbolic Links between Devices and ARC Names

This chapter contains some information of general interest to all NT driver writers, including the following:

·A summary of the default hardware priorities (IRQLs) at which standard NT driver routines run and some guidelines for calling support routines at appropriate IRQLs

·General guidelines about using spin locks to synchronize access to data or resources shared by driver routines

·General guidelines about allocating system-space memory, using the kernel stack, and using zone buffers

·How NT drivers should handle I/O errors and how NTSTATUS values are defined

·How NT drivers use the registry to initialize themselves in a manner that keeps them portable and configurable across Windows NT® platforms

·How to create a symbolic link between a driver's named device object and a Win32®-visible name (such as LPT1) for the same device

This chapter also discusses design issues that are device-type-specific or design-specific, including the following:

·For NT device driver designers, whether to have the driver poll the device or set up a thread that waits on a Kernel-defined dispatcher object, such as an event or semaphore

·For NT DMA or PIO device driver designers, how to maintain cache coherency and data integrity during transfer operations

·For NT removable-media device driver designers, how to handle user-induced errors, such as supplying the wrong media or removing the media on which a file is open

·For NT floppy and CD-ROM device driver designers, how to set up a symbolic link between the driver's name for a device object that can represent a boot-from device and the corresponding ARC name for the device