Windows Driver Model History And Architectural Overview Bob
Windows Driver Model History And Architectural Overview ® Bob Rinne Director Windows Operating System Base Microsoft Corporation
Purpose Of This Talk u The WDM reality Ø Ø u u u Discuss what is covered in WDM It has taken a long time Get an overview of its history and versions Get an overview of the architectures Basic information for navigating through WDM
Technical Outline u u Goals of WDM History of WDM Current state Overview of WDM
Goals Of WDM u u Common development environment for Windows NT® and Windows 9 x family products Method of bringing Plug and Play and Power Management to Windows NT Binary compatibility between products Broad coverage of new technology busses
What Is WDM u NDIS/SCSI Ø u u u Pre-WDM, but satisfies goals System environment Bus support Device class support
History Of WDM u u Introduced after Windows 95 launch First available in Windows 98 Now available in Windows 2000 Is present on Windows ME with enhancements from Windows 98
History Of WDM u Windows 98 versions Ø Ø Started from a device oriented Plug and Play operating system Added portable abstractions and I/O subsystem from Windows NT Provided definition for Plug and Play and power management mapping to Windows NT Work done as a mapper between WDM and Windows 95 core
Windows 98 And Me System VM Applications System services Windows NT I/O Manager Installable file system FSD Device drivers HAL FSD Windows 95 I/O subsystem Device drivers MS-DOS VM Virtual Memory Manager Services Drivers
History Of WDM u Windows NT version Ø Ø Ø Started from non-Plug and Play, “driver”-oriented operating system Made WDM interfaces native Converted to Plug and Play/“device”oriented operating system
Windows NT Daemons Services Other Spooler File server Security Session manager Other Replicator Logon Alerter Event logger LPC Environments Applications Windows LPC LPC Windows NT System I/O manager Security monitor Executive Power Management Memory Management Process support File systems Object management/executive run time Device drivers Kernel Hardware abstraction layer Platform interface I/O devices DMA control Bus mapping Clocks/ timers Cache control Interrupt dispatch Privileged architecture
Current State u u u WDM is real There now is a common development environment Binary compatibility is possible Ø Ø Unfortunately it is harder than we wanted Requires extensive testing on all versions of all operating systems
Current State u Busses covered Ø Ø Still have NDIS and SCSI USB 1394 New ones coming
Current State u Devices covered Ø Ø Ø Ø Input Cameras/Scanners Audio Win. Modem Storage (*) Many more New ones coming
Current State u What’s not there Ø Ø Ø Video Generic storage Super I/O chip
Overview Of WDM u Breakdown the components Ø u What do those first two characters in DDI calls mean? Definition of functionality
Components In WDM u wdm. h Ø Ø Ø u ks. h Ø u Ke Ob Ex Io Mm Ps Rtl Po Pnp Hal (platform support) Zw (magic) Ks Wmi
Ke - Kernel u u Minimal set of items exported here in WDM Synchronization primitives Performance counters and timers Stall and Irq control
Ob - Object Manager u u Very minimal set Used only for object reference count maintenance
Ex - The System Executive u u Memory allocations Interlocked operations List operations Work items Ø There is a better set in the IO manager (Io*)
Io - I/O Manager u I/O Request Packet (IRP) Handling Ø Ø u Device Object Plumbing Ø u u u The routines that pass Irps Global locks The routines that set device relationships Work items Registry access routines System state notifications DMA assistance Interrupt assistance
Mm - Memory Manager u u Virtual to Physical mapping Physical memory commit/locking Driver image memory locking Portable I/O space handling
Ps - Process Service u u System thread support Just creation and deletion
Rtl - Run-Time Library u u u Bulk memory activity support Unicode support Conversion support Ø Ø Ø Unicode to Ansi Integer to Unicode Etc.
Po - Power Manager u u u Power state change support Power Irp handling Device idle detection support
Pn. P - Plug And Play Subsystem u u u There are no Plug and Play decorated routine names Exists as part of the I/O manager Actually implemented as an entity in the system
Hal - Hardware Abstraction Layer u Device manipulation Ø Ø u I/O port access and usage Memory mapped device access and usage Platform abstraction Ø Component owner of interrupts
Zw - Magic u u Kernel mode map to system APIs Registry access Ø Ø Ø u Open/Close keys Create/Delete keys Query values Minimal file access
Ks - Kernel Streaming u u u Separate component on both platforms Definitions of interfaces located in ks. h Provides plumbing for streaming data device connections
WMI - Windows Management Infrastructure u u Similar to Plug and Play as a component of Io GUID support - wmidata. h Structure definitions - wmistr. h Support library definitions - wmilib. h
Conclusion u u Its taken awhile Some of it is simple; Some of it isn’t Develop driver first under Windows 2000 Test, test, on all releases of all supported operating systems
WDM Driver Implementation Guide Adrian J. Oney Software Engineer Windows Core OS Microsoft Corporation
Preview u Writing an Windows NT 4. 0 skeleton driver required mastery of many concepts Ø Ø Ø Scheduling Synchronization Device. Objects, Driver. Objects I/O theory (IRP handling, queuing, asynchronous I/O) Security Debugging
Preview u Writing a WDM driver requires mastery of all of those concepts plus: Ø Ø u Plug and Play Power Management WMI (Windows® Management Interface) Windows 9 x/Windows 2000 differences And don’t forget technology specific issues Ø Ø Device class specific: Audio, Modem, … Bus specific: USB, 1394, PCI, …
Scheduling Basics WDM presents two types of scheduling u Thread-based scheduling Ø Ø Kernel support for semaphores, mutexes, event objects Windows 2000 adds new high-level support for reader/writer operations to WDM l u (For instance Ex. Acquire. Shared. Starve. Exclusive) Interrupt Level-based scheduling Ø Code running at a higher IRQ Level (IRQL) immediately preempts code running at a lower IRQL l Ø The lowest three IRQL’s are scheduling constructs, unrelated to hardware: l Ø Code runs on same thread, no switching! PASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVEL Multiple processors can each run at a different IRQL!
Callbacks u PASSIVE_LEVEL (IRQL 0) Ø “Work Item” l l u APC_LEVEL (IRQL 1) Ø Asynchronous Procedure Call aka “APC” l l l u Queue-able from DISPATCH_LEVEL or lower Two types, Ex-Work. Items and Io-Work. Items Thread specific No WDM function to queue these I/O Manager queues them to get back into correct process during I/O DISPATCH_LEVEL (IRQL 2) Ø Deferred Procedure Call aka “DPC” l Queue-able anytime and anywhere, including ISRs
Scheduling Basics u PASSIVE_LEVEL (IRQL 0) Ø Ø u APC_LEVEL (IRQL 1) Ø Ø Ø u Drivers typically run at this level Drivers can touch pageable memory Drivers can do file I/O Blocking causes a processor to switch threads When switching into a new thread, the processor will run any pending APC’s at APC_LEVEL Blocking lets other threads run at PASSIVE_LEVEL Restriction: Drivers cannot use file functions DISPATCH_LEVEL (IRQL 2) Ø Ø A processor never switches threads when running driver code at DISPATCH_LEVEL Restrictions: A driver cannot touch pagable memory, or use file functions
IRQs And IRQLs On 8259 PIC CLOCK 31 IRQL Hardware Interrupt 0 Hardware Interrupt 1 IDE ISR queues DPC … Hardware Interrupt 14 Hardware Interrupt 15 2 – DISPATCH_LEVEL 1 – APC_LEVEL 0 – PASSIVE_LEVEL DPC executes Thread Switches
IO-APIC Example From an 8 -Way server machine down the hall, other machines will be different! Device IRQL USB Controller SCSI Controller Network Adapter SCSI Controller IDE Controller SCSI Controller Floppy Controller Video Controller Com Port Network Adapter 0 x. B 4 0 x. A 3 0 x. A 4 0 x 93 0 x 94 0 x 83 0 x 72 0 x 73 0 x 62 0 x 63 0 x 51 0 x 53 0 x. A 9 9 8 8 7 6 6 5 5 4 4
Synchronization u PASSIVE_LEVEL (IRQL 0) Ø Ø Ø u APC_LEVEL (IRQL 1) Ø Ø u Fast Mutexes (automatically raises IRQL to APC_LEVEL) Semaphores, Events, Resources (note: none raise IRQL) DISPATCH_LEVEL (IRQL 2) Ø Ø u Semaphores Events Resources (a kind of Mutex) Spinlocks No reentrant primitives (i. e. , mutexes) Hardware levels (IRQL > 2) Ø Ke. Synchronize. Execution
Security Attack u A user mode application may choose to “freeze” a thread. User mode does this by queuing an APC to the appropriate thread. Security is compromised if your driver gets frozen holding a sync object Ø Ø Ø Use synchronization objects that raise to APC_LEVEL or above, or Move such operations into a system thread, or Use Ke. Enter. Critical. Region and Ke. Leave. Critical. Region
Drivers And Devices u u Every driver has a Driver. Object associated with it Driver. Object(s) represent driver-specific information Ø u u Each driver creates one or more Device. Object(s) via Io. Create. Device(…) Device. Object(s) contain per-device information Ø Ø Ø u Dispatch table Device. Extension Name Flags (e. g. , DO_POWER_PAGABLE) A WDM driver is typically unloaded when all it’s Device. Object(s) have been deleted
Drivers And Devices DRIVER_OBJECT Scanner. sys DEVICE_OBJECT (Scanner #3) DEVICE_OBJECT (Scanner #2) DEVICE_OBJECT (Scanner #1) DRIVER_OBJECT Toaster. sys DEVICE_OBJECT (Toaster #1)
Device Stacks u u Doing an operation often requires multiple drivers Device. Objects are arranged into chains called Device Stack DEVICE_OBJECT DRIVER_OBJECT Scanner. sys DEVICE_OBJECT (Scanner #2) DEVICE_OBJECT (Scanner #1) DEVICE_OBJECT
I/O Request Packets u u The OS communicates with drivers by sending I/O Request Packets (IRPs) to a device stack IRPs are WDM’s solution to asynchronous I/O IRP DEVICE_OBJECT (Scanner #2) DEVICE_OBJECT
Asynchronous I/O u Goal: Let applications queue one or more requests without blocking Ø u Two dedicated application threads is not an optimal solution Ø u Example: Decompressing GIF frames from a CD Thread switches are expensive Policy needs to be in the driver stack Ø Only it knows whether a given request should be handled synchronously or asynchronously
Synchronous OS design App User Mode Kernel Mode Driver A Driver B Driver C Instruction Pointer Stack Pointer Thread Stack Param for A Return address to App … Param for B Return address to A … Param for C Return address to B
I/O Request Packets Thread Stack Param for A Return address to App … Param for B Return address to A … Param for C Return address to B IRP Header (Contains Status and Stack Pointer) Param A Callback for Initator Param B Callback for A Param C Callback for B
I/O Request Packets Thread Stack Concept IRP Stack Concept Stack Frame IO_STACK_LOCATION Stack Pointer Io. Get. Current. Irp. Stack. Location (and Io. Get. Next. Irp. Stack. Location) Subroutine call Io. Call. Driver Return from subroutine Io. Complete. Request Return Address/Callback Completion routine (Io. Set. Completion. Routine) Return Value Irp->Io. Status/Information
I/O Request Packets u u Each IRP must be targeted at a specific device stack IRPs typically have just enough stack locations to traverse the device stack Ø You must allocate a new IRP if you need to forward the request to another stack Device A 3 Device B 2 Device C 1 IRP Header (Contains Status and Stack Pointer) Param A Callback for Initiator Param B Callback for A Param C Callback for B
I/O Request Packets IRP Header Thread User. Io. Status User. Event Stack Pointer Io. Status Cancel. Routine Major Code Minor Code Param Completion Routine Completion Context IRP_MJ_ IRP_MN_ … … func(…) PVOID IRP_MJ_CREATE IRP_MJ_CLOSE IRP_MJ_READ DEVICE_OBJECT DRIVER_OBJECT Dispatch Table IRP_MJ_WRITE IRP_MJ_DEVICE_CONTROL IRP_MJ_PNP IRP_MJ_POWER
I/O Request Packets u What do I return from my dispatch routine? Ø Caller on thread stack Callers completion routine status = Io. Call. Driver(. . . ); status = Irp->Io. Status; Return same value completion routine would see, else return STATUS_PENDING
I/O Request Packets u Correct value returned from dispatch handler: Irp->Io. Status = STATUS_UNSUCCESSFUL; Io. Complete. Request( Irp, IO_NO_INCREMENT ); return STATUS_UNSUCCESSFUL; Irp->Io. Status = STATUS_SUCCESS; Io. Skip. Current. Irp. Stack. Location( Irp ); return Io. Call. Driver( device. Beneath. Me, Irp ); u Incorrect value returned from dispatch handler: Irp->Io. Status = STATUS_SUCCESS; Io. Skip. Current. Irp. Stack. Location( Irp ); Io. Call. Driver( device. Beneath. Me, Irp ); return STATUS_SUCCESS; // Be extra careful when changing status in completion routines!
The Two Types Of I/O u Buffered I/O Ø Ø u Driver writes into Irp->Associated. Irp. System. Buffer OS queues an APC in the requesting process context where it performs a copy Direct I/O Ø Ø Doesn’t require a copy Memory pages are locked during the duration of the operation Pages are described by the IRPs Memory Descriptor List (Irp->Mdl. Address) Driver use DMA functions or get a kernel address via Mm. Get. System. Address. For. Mdl. Safe(Irp->Mdl. Address)
WDM Device Stacks u A WDM driver stack can contain several different kinds of device objects: Ø Ø Ø u Functional Device Object ( “FDO” ) Physical Device Object (“PDO”) Filters The stack and the OS data associated with it is called a “Dev. Node” Upper Class Filters Upper Device Filters FDO Functional Device Object Lower Class Filters Lower Device Filters PDO Physical Device Object Device Node (“Dev. Node”)
WDM Device Stacks u I/O IRPs are typically handled by the FDO Ø u Pn. P and Power IRPs traverse the entire stack except if there is an error Ø u Drivers do not modify these IRPs if they do not implement the request WMI IRPs are targeted at specific device objects in the stack Ø Drivers do not modify WMI IRPs if they do not implement WMI IRP Ø Create, Close, Read, Write, etc. Drivers must fail any such IRP explicitly if it’s not handled Upper Class Filters Upper Device Filters FDO Functional Device Object Lower Class Filters Lower Device Filters PDO Physical Device Object Dev. Node
WDM Device Stacks u A PDO is created by the bus driver Ø u Only the PDO has a name! Ø u This is done in response to an OS enumeration request More on this later FDO’s and Filters are created in Add. Device routines Ø Ø Ø Drivers do not find their hardware, rather their hardware finds them Plug and Play passes the PDO to Add. Device Drivers attach new device objects to the stack via Io. Attach. Device. To. Device. Stack Upper Class Filters Upper Device Filters FDO Functional Device Object Lower Class Filters Lower Device Filters PDO Physical Device Object Dev. Node
[Version] Signature = Provider PNP Manager IRP Information 3 IRP_MN_QUERY_ID 4 Search INF Files 5 Call Class Installers and Co-Installers Upper Filters FDO USBFLOP. SYS Registry Lower Filters PDO USBHUB. SYS 6 IRP Information 2 USB Floppy Dev. Node FDO USBHUB. SYS PDO USB Hub Dev. Node Load drivers IRP_MN_QUERY_DEVICE_RELATIONS 1 Io. Invalidate. Device. Relations
Plug And Play u The Plug and Play Manager queries the stack to get a list of all possible resource solutions: Ø Ø u The PDO responds to IRP_MN_QUERY_RESOURCE_REQUIREMENTS The FDO can adjust these requirements by responding to IRP_MN_FILTER_RESOURCE_REQUIREMENTS The Plug and Play Manager sends the best resource settings in IRP_MN_START_DEVICE Ø Ø The card is configured to use the “Raw’ resource set The driver communicates with the card via the “Translated” resource set
Plug And Play u FDO’s must respond to the following Plug and Play events: Ø “Remove” events occur when a device is removed or disabled Ø Ø Ø “Stop” events occur when a device is to be paused for resource rebalancing Ø Ø IRP_MN_REMOVE_DEVICE IRP_MN_SURPRISE_REMOVAL IRP_MN_QUERY_REMOVE_DEVICE IRP_MN_CANCEL_REMOVE_DEVICE IRP_MN_QUERY_STOP_DEVICE IRP_MN_CANCEL_STOP_DEVICE Other Plug and Play events FDO’s typically respond to: Ø Ø IRP_MN_START_DEVICE (We hope) IRP_MN_QUERY_CAPABILITIES
Plug And Play u PDO’s must respond to even more messages: Ø “Who” are you, “What” are you? Ø Ø Ø “Where are you, and where can you go today? ” Ø Ø Ø IRP_MN_QUERY_RESOURCES IRP_MN_QUERY_RESOURCE_REQUIREMENTS Settings, capabilities, and location: Ø Ø Ø IRP_MN_QUERY_ID IRP_MN_QUERY_DEVICE_TEXT IRP_MN_QUERY_CAPABILITIES IRP_MN_QUERY_BUS_INFORMATION Misc. Ø IRP_MN_QUERY_DEVICE_RELATIONS (Target. Relations)
“Finding” Plug And Play Devices u Applications often need a list of devices to manipulate or display to the user Ø u u Using “well known names” (i. e. , Lpt. X) doesn’t work well in a Plug and Play environment Applications often need a list of devices that share a given property, and properties can be hierarchical Ø u Printers, Scanners, etc (E. g. , all storage devices, just CDROMs, just Zip drives, etc. ) WDM drivers expose one or more “Interfaces”, identified via GUID Ø Note: Only started devices can expose interfaces
Interfaces u u u Drivers register support for a given Interface by calling Io. Register. Device. Interface Drivers dynamically enable and disable an interface via Io. Set. Device. Interface. State creates a symbolic link so that user mode applications can communicate with the device Ø u More on this later Applications enumerate devices by passing an interface GUID to various Setup. Api functions
Kernel mode security u u User mode can attempt to open a device with Read, Write, and Execute privileges By default, all users get full access to a WDM device stack Security checks are done at Create/Open time Access to a device can be restricted via INF Ø Search DDK for “INF Add. Reg”, or stay tuned… Upper Class Filters Upper Device Filters FDO Functional Device Object Lower Class Filters Lower Device Filters PDO Physical Device Object
Kernel Mode Security [My. Device. NTx 86] Copy. Files =. . . [My. Device. NTx 86. Services] Add. Service =. . . [My. Device. NTx 86. HW] Add. Reg = My. Device. Security [My. Device. Security] HKR, , Device. Characteristics , 0 x 10001, 0 x 100 HKR, , Device. Characteristics, 0 x 10001, 0 x 100 HKR, , Security , , ”security-descriptor-string” HKR, , Security, , ” "D: P( ; ; A: Allow D: Deny ; ; ; GA: All GR: Read GW: Write ) (. . . )" SY: System LA: Local Administrator PU: Power user WD: World "D: P(A; ; GA; ; ; SY)" Allow All System (Example: System only access)
Security Attacks u u Security constraints are applied to named device objects In a WDM stack, only the PDO should be named Ø u u If another device is named, it might compromise system security A device doesn’t have to expose a symbolic link to be opened! Be sure to pass in FILE_DEVICE_SECURE_OPEN when creating PDO’s Upper Class Filters Upper Device Filters FDO Functional Device Object Lower Class Filters Lower Device Filters PDO Physical Device Object
IOCTL Security 31 15 Device Number u u Access 2 Function Method Drivers encode the security requirements of Device IOCTLs in the 32 bit code itself The Access mask can specify one of four different privilege levels: Ø Ø u 13 Openable Opened with read access Opened with write access Opened with both read and write access The IO Manager prevents applications from forming IOCTL codes their privileges don’t allow
Security Attacks 31 15 Device Number u Ø Function Method Masking out the Access bits lets lower privileged Ioctl’s succeed Do not use the Io. Get. Function. Code. From. Ctl. Code macro Drivers should always check the buffer size of incoming Ioctl’s Ø u Access 2 Drivers should always check the full 32 bit Ioctl code! Ø u 13 Malicious applications can attempt to crash the system via malformed requests Do not implement IOCTLs that allow an application to read or write any piece of virtual or physical memory Ø Ø Don’t ship with debugging IOCTLs enabled Don’t pass back “pointers” as handles
Power Management u To implement power management, a driver needs code to: Ø Ø u Save and restore the state of its hardware Disable and enable the device Queue incoming requests Convert System states to Device states A driver must not touch it’s hardware while it’s device is off Ø Memory and I/O typically return 0 x. FFFF when off, fooling badly written ISR’s
System States u S 0: Working Ø u S 1: Standby Ø u Typically only memory remains powered S 4: Hibernation Ø u Greater power conservation, recovery time more than two seconds S 3: Standby Ø u Processor and bus clocks are off, recovery time typically two seconds S 2: Standby Ø u Machine is fully powered and responsive Machine is off, memory is written to persistent storage S 5: Off
Device States u D 0 Ø u D 1 Ø Ø Ø u Less power consumption than D 0 Transition to fully powered happens quickly Driver cannot access device until powered up D 2 Ø Ø Ø u Hardware is fully powered Less power consumption than D 1 Longer power-up time than D 1 Driver cannot access device until powered up D 3: Off Ø Device is completely off (inaccessable)
Converting S IRPs To D IRPs The WDM Power Manager sends S IRPs: u Ø Ø u Each device stack has a “Power Policy Owner” who converts S IRPs to D IRPs Ø Ø u u IRP_MN_QUERY_POWER IRP_MN_SET_POWER The Power Policy Owner is typically the FDO The mapping comes from the S D array stored in the IRP_MN_QUERY_CAPABILITIES structure Each entry calls out the lightest possible D state for a given S state Mappings can be rounded down (deeper) The Power Policy Owner then uses Po. Request. Power. Irp to request the appropriate D IRP The conversion code is complicated, but most drivers can use the boilerplate code in the WDM DDK
System State S 0 – Working PCI Bus S 0 D 0 Modem D 3 D 2 D 1 D 0 HDD D 3 D 2 D 1 D 0 CDROM Net Card D 3 D 2 D 1 D 0 C 0 PCI. SYS ACPI. SYS IDE Controller S 0 D 0 PCIIDE. SYS ACPI. SYS SCSI Card S 0 D 0 PCI. SYS IDE Channel S 0 D 0 HDD S 0 D 0 ATAPI. SYS PCIIDE. SYS DISK. SYS ATAPI. SYS SCSIPORT. SYS ACPI. SYS PCI. SYS CDROM S 0 D 0 Net Card S 0 D 0 NDIS. SYS ACPI. SYS PCI. SYS CDROM. SYS SCSIPORT. SYS S 0 D 0
System State S 1 – Standby PCI Bus S 1 D 1 Modem D 3 D 2 D 1 D 0 HDD D 3 D 2 D 1 D 0 CDROM Net Card D 3 D 2 D 1 D 0 C 0 PCI. SYS ACPI. SYS IDE Controller S 1 D 1 PCIIDE. SYS ACPI. SYS SCSI Card S 1 D 3 PCI. SYS IDE Channel S 1 D 1 HDD S 1 D 1 ATAPI. SYS PCIIDE. SYS DISK. SYS ATAPI. SYS SCSIPORT. SYS ACPI. SYS PCI. SYS CDROM S 1 D 3 Net Card S 1 D 3 NDIS. SYS ACPI. SYS PCI. SYS CDROM. SYS SCSIPORT. SYS S 1 D?
System State S 3 – Standby PCI Bus S 3 D 3 Modem D 3 D 2 D 1 D 0 HDD D 3 D 2 D 1 D 0 CDROM Net Card D 3 D 2 D 1 D 0 C 0 PCI. SYS ACPI. SYS IDE Controller S 3 D 3 PCIIDE. SYS ACPI. SYS SCSI Card S 3 D 3 PCI. SYS IDE Channel S 3 D 3 HDD S 3 D 3 ATAPI. SYS PCIIDE. SYS DISK. SYS ATAPI. SYS SCSIPORT. SYS ACPI. SYS PCI. SYS CDROM S 3 D 3 Net Card S 3 D 3 NDIS. SYS ACPI. SYS PCI. SYS CDROM. SYS SCSIPORT. SYS S 3 D?
System State S 4 – Hibernate PCI Bus S 4 D 3 Modem D 3 D 2 D 1 D 0 HDD D 3 D 2 D 1 D 0 CDROM Net Card D 3 D 2 D 1 D 0 C 0 PCI. SYS ACPI. SYS IDE Controller S 4 D 3 PCIIDE. SYS ACPI. SYS SCSI Card S 4 D 3 PCI. SYS IDE Channel S 4 D 3 HDD S 4 D 3 ATAPI. SYS PCIIDE. SYS DISK. SYS ATAPI. SYS SCSIPORT. SYS ACPI. SYS PCI. SYS CDROM S 4 D 3 Net Card S 4 D 3 NDIS. SYS ACPI. SYS PCI. SYS CDROM. SYS SCSIPORT. SYS S 4 D 3
System State S 5 – Off PCI Bus S 5 D 3 Modem D 3 D 2 D 1 D 0 HDD D 3 D 2 D 1 D 0 CDROM Net Card D 3 D 2 D 1 D 0 C 0 PCI. SYS ACPI. SYS IDE Controller S 5 D 3 PCIIDE. SYS ACPI. SYS SCSI Card S 5 D 3 PCI. SYS IDE Channel S 5 D 3 HDD S 5 D 3 ATAPI. SYS PCIIDE. SYS DISK. SYS ATAPI. SYS SCSIPORT. SYS ACPI. SYS PCI. SYS CDROM S 5 D 3 Net Card S 5 D 3 NDIS. SYS ACPI. SYS PCI. SYS CDROM. SYS SCSIPORT. SYS S 5 D 3
Converting S IRPs To D IRPs ( Simplified from Toaster Sample in the WDM DDK ) NTSTATUS Toaster. Dispatch. Power( IN PDEVICE_OBJECT Device. Object, IN PIRP Irp) { PIO_STACK_LOCATION stack. Location; // // Not shown: Are we deleted? If so, fail IRP. // Not shown: Are we started? If not, pass on IRP untouched. // stack. Location = Io. Get. Current. Irp. Stack. Location( Irp ); switch(stack. Location ->Minor. Function) ) { switch(stack. Location-> case IRP_MN_QUERY_POWER: return Toaster. Query. Power. State( Device. Object, Irp ); case IRP_MN_SET_POWER: return Toaster. Set. Power. State( Device. Object, Irp ); default: // Not shown: default logic } }
Converting S IRPs To D IRPs NTSTATUS Toaster. Query. Power. State( IN PDEVICE_OBJECT Device. Object, IN PIRP Irp ) { PIO_STACK_LOCATION stack. Location; if (stack. Location ->Parameters. Power. Type == System. Power. State) (stack. Location->Parameters. Power. Type System. Power. State) { S D routine return Handle. System. Power. Irp( Device. Object, Irp ); } return Handle. Device. Query. Power( Device. Object, Irp ); }
Converting S IRPs To D IRPs NTSTATUS Toaster. Set. Power. State( IN PDEVICE_OBJECT Device. Object, IN PIRP Irp ) { PIO_STACK_LOCATION stack. Location; if (stack. Location ->Parameters. Power. Type == System. Power. State) (stack. Location->Parameters. Power. Type System. Power. State) { S D routine return Handle. System. Power. Irp( Device. Object, Irp ); } return Handle. Device. Set. Power( Device. Object, Irp ); }
Converting S IRPs To D IRPs NTSTATUS Handle. System. Power. Irp( IN PDEVICE_OBJECT Device. Object, IN PIRP Irp ) { // // Forward IRP *asynchronously*, catch it on way up // Io. Mark. Irp. Pending( Irp ); S-IRP Io. Copy. Current. Irp. Stack. Location. To. Next( Irp ); Io. Set. Completion. Routine( Irp, (PIO_COMPLETION_ROUTINE) On. Finish. System. Power. Up, NULL, TRUE, TRUE); Po. Call. Driver( Next. Lower. Driver, , Irp ); Po. Call. Driver( fdo. Data->Next. Lower. Driver return STATUS_PENDING; } PPO
Converting S IRPs To D IRPs NTSTATUS On. Finish. System. Power. Up( IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Not. Used ) { NTSTATUS status = Irp-> Io. Status; Irp->Io. Status if (!NT_SUCCESS(status)) { Po. Start. Next. Power. Irp(Irp); return STATUS_SUCCESS; PPO Queue. Corresponding. Device. Irp( Irp, Fdo ); return STATUS_MORE_PROCESSING_REQUIRED; } S-IRP }
Converting S IRPs To D IRPs VOID Queue. Corresponding. Device. Irp( IN PIRP SIrp, IN PDEVICE_OBJECT Device. Object ) { POWER_STATE d. State; PFDO_DATA fdo. Data = (PFDO_DATA) Device. Object-> Device. Extension; ; Device. Object->Device. Extension PIO_STACK_LOCATION stack = Io. Get. Current. Irp. Stack. Location(SIrp); SYSTEM_POWER_STATE s. State = stack->Power. State. System. State ; stack->Power. State. System. State; d. State, On. Power. Request. Complete, SIrp, NULL); } // Not shown: Handle case where Po. Request. Power. Irp fails } PPO S-IRP status = Po. Request. Power. Irp( fdo. Data-> Underlying. PDO, , fdo. Data->Underlying. PDO stack->Minor. Function , stack->Minor. Function, D-IR P if ((s. State ->Armed. For. Wake)) )) { ((s. State == Power. System. Working) || (fdo. Data-> d. State. Device. Caps. . Device. State[ d. State. Device. State = fdo. Data->Device. Caps Device. State[s. State]; } else { d. State. Device. State = Power. Device. D 3; }
Converting S IRPs To D IRPs VOID On. Power. Request. Complete( IN PDEVICE_OBJECT IN UCHAR IN POWER_STATE IN PVOID Device. Object, Minor. Function, State, Power. Context, D-IRP IN PIO_STATUS_BLOCK Io. Status ) { // // Copy status from D IRP to S IRP // s. Irp->Io. Status = Io. Status->Status; Po. Start. Next. Power. Irp( s. Irp ); Io. Complete. Request( s. Irp, IO_NO_INCREMENT ); } PPO S-IRP PIRP s. Irp = (PIRP) Power. Context;
Converting S IRPs To D IRPs // // Copy status from D IRP to S IRP // s. Irp-> Io. Status = Io. Status->Status; s. Irp->Io. Status->Status; Po. Start. Next. Power. Irp( s. Irp ); Io. Complete. Request( s. Irp, IO_NO_INCREMENT ); } S-IRP VOID On. Power. Request. Complete( IN PDEVICE_OBJECT Device. Object, IN UCHAR Minor. Function, IN POWER_STATE State, IN PVOID Power. Context, IN PIO_STATUS_BLOCK Io. Status ) { PIRP s. Irp = (PIRP) Power. Context; PPO
Power Management Gotcha’s u u u Drivers cannot block a thread and wait for a power IRP to complete on Windows 2000 S D state mapping for non-power manageable PCI devices may contain invalid D states on Windows 2000 Drivers cannot safely complete power IRPs at DISPATCH_LEVEL on Windows 9 x Drivers cannot safely do “idle time” power management on Windows 9 x PCI supports two types of D 3 which WDM doesn’t distinguish
WDM And Hardware – DSP Bad design: 1. 2. 3. 4. OS loads DSP driver against “DSP device” Driver uploads software into volatile DSP RAM “DSP device” disappears from bus New device appears in it’s place Problem: What happens when the device is turned off? Correct design: 1. 2. 3. 4. OS loads DSP bus driver against “DSP device” DSP bus driver uploads DSP software into volatile DSP RAM Bus driver exposes new functionality by creating a child device Bus driver reprograms DSP when appropriate
- Slides: 88