Using KMDF in Miniport Drivers Eliyas Yakub Vishal Manan Principal SDE Lead SDE 2 Device and Storage Technologies Device and Storage Technologies [email protected] [email protected].

Download Report

Transcript Using KMDF in Miniport Drivers Eliyas Yakub Vishal Manan Principal SDE Lead SDE 2 Device and Storage Technologies Device and Storage Technologies [email protected] [email protected].

Using KMDF in Miniport Drivers
Eliyas Yakub
Vishal Manan
Principal SDE Lead
SDE 2
Device and Storage Technologies Device and Storage Technologies
[email protected]
[email protected]
Agenda
• Basics of framework and miniports — Dispatch table override
• Code snippets specific to NDIS miniport and AvStream minidrivers
using the framework
• Why should you use KMDF for writing your miniport drivers?
• What features of KMDF can’t you use in your miniport drivers?
How does a WDM driver work?
DriverObject
DriverObject
I/O
Manager
IRP_MJ_xxx
IopInvalidDeviceRequest
AddDevice
NULL
DriverUnload
NULL
DriverEntry
IRP_MJ_xxx
DriverDispatchxxx()
AddDevice
DeviceAdd()
DriverUnload
Unload()
What happens in a miniport (For eg: NDIS)?
I/O
Manager
DriverObject
DriverObject
IRP_MJ_xxx
IopInvalidDeviceRequest
IRP_MJ_xxx
ndisDummyIrpHandler
AddDevice
NULL
AddDevice
ndisPnPAddDevice()
DriverUnload
NULL
DriverUnload
ndisMUnloadEx()
NdisMRegisterMiniportDriver
Initialize()
Halt()
Send()
Receive()
What happens in the framework?
I/O
Manager
DriverObject
DriverObject
IRP_MJ_xxx
IopInvalidDeviceRequest
IRP_MJ_xxx
FxDevice::Dispatch()
AddDevice
NULL
AddDevice
FxDriver::AddDevice()
DriverUnload
NULL
DriverUnload
FxStubDriverUnload()
WdfDriverCreate
EvtDeviceXxx()
EvtIoXxx()
How do you make a miniport and WDF work together?
DriverObject
DriverObject
IRP_MJ_xxx
IopInvalidDeviceRequest
IRP_MJ_xxx
ndisIrpHandler
AddDevice
NULL
AddDevice
ndisPnPAddDevice()
DriverUnload
NULL
DriverUnload
ndisMUnloadEx()
NdisMRegisterMiniportDriver()
WdfDriverCreate (WdfDriverInitNoDispatchOverride)
Initialize()
Halt()
Send()
Receive()
IRP flow in NDIS miniport
NDIS Port Library
I/O
Manager
IRP
Miniport Driver
USB target
NdisCloseIrpHandler
NdisCreateIrpHandle
r
NdisDeviceControlIrp
Handler
MpDriverUnload
NdisPnPDispatch
MpDevicePnpEvent
NdisWMIDispatch
NdisPowerDispatch
NdisMUnloadEx
Framework
IO target
MpOIDRequest
WorkItems
Timer
Utility
Objects
How does the framework communicate with the
lower device stack?
Driver calls WdfDeviceMiniportCreate (…,FDO, AttachedDeviceObject, PDO …)
Frameworks creates an I/O target object to communicate with the lower
device stack using the passed-in AttachedDeviceObject
NDIS Miniport Code Snippets
Overriding the dispatch table
NTSTATUS
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
)
{
WDFDRIVER
hDriver; //vm control
WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK);
config.DriverInitFlags |= WdfDriverInitNoDispatchOverride;
ntStatus = WdfDriverCreate(DriverObject,
RegistryPath,
WDF_NO_OBJECT_ATTRIBUTES,
&config,
&hDriver);
Status = NdisMRegisterMiniportDriver(DriverObject,
RegistryPath,
PNDIS_HANDLE)GlobalDriverContext,
&MPChar,
&NdisMiniportDriverHandle);
}
Creating the miniport device object
NDIS_STATUS
MPInitialize(
IN NDIS_HANDLE MiniportAdapterHandle,
…
)
{
PADAPTER
pAdapter;
NdisMGetDeviceProperty(MiniportAdapterHandle,
&pAdapter->Pdo,
&pAdapter->Fdo,
&pAdapter->NextDeviceObject,
NULL,
NULL);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, WDF_DEVICE_INFO);
ntStatus = WdfDeviceMiniportCreate(WdfGetDriver(),
&attributes,
pAdapter->Fdo,
pAdapter->NextDeviceObject,
pAdapter->Pdo,
&pAdapter->WdfDevice);
…
}
Deleting the miniport device object
VOID
MPHalt(
IN NDIS_HANDLE
MiniportAdapterContext,
IN NDIS_HALT_ACTION
HaltAction
)
{
PADAPTER pAdapter = (PADAPTER)MiniportAdapterContext;
if (pAdapter->WdfDevice != NULL){
WdfObjectDelete(pAdapter->WdfDevice);
}
…
}
NOTE: Don’t forget to free the WdfDeviceObject allocated in WdfDeviceMiniportCreate
Unbinding and freeing the framework driver
resources
•
The framework does not override the driver’s unload routine, so
WdfDriverMiniportUnload allows the miniport driver to unbind as a
client driver from the framework.
•
As a result the framework can free resources that it allocated for the
miniport driver.
VOID
MpDriverUnload(
IN PDRIVER_OBJECT DriverObject
)
{
…
WdfDriverMiniportUnload(WdfGetDriver());
…
}
KMDF NDIS miniport sample in WDK
• NDIS 6.0 sample for USB WiFi device
• Based on the current RTLNWiFi PCI
sample
• Takes advantage of NDIS-WDM
• Conforms to the Microsoft Native
Wi-Fi miniport driver specification
• Abstracts bus dependent and
independent parts
NDIS
802.11 Intermediate
Driver
802.11 Miniport Driver
• Easily adaptable for other buses
• Uses KMDF USB I/O target
• Continuous reader reads packets
from input endpoint and indicates
packets to NDIS
• Location in WDK:
src\network\ndis\usbnwifi
KMDF USB Targets
Core USB Stack
Avstream Minidriver Code Snippets
Overriding the dispatch table
KSDEVICE_DISPATCH
KsDeviceDispatchTable = {
DeviceCreate,
DeviceStart,
DeviceStop,
DeviceRemove,
DeviceQueryCapabilities,
DeviceSurpriseRemoval,
DeviceSetPowerState
};
KSDEVICE_DESCRIPTOR KsDeviceDescriptor = {&KsDeviceDispatchTable, 0, NULL, KSDEVICE_DESCRIPTOR_VERSION};
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPathName )
{
config.DriverInitFlags |= WdfDriverInitNoDispatchOverride;
ntStatus = WdfDriverCreate(DriverObject,
RegistryPathName,
WDF_NO_OBJECT_ATTRIBUTES,
&config,
NULL);
ntStatus = KsInitializeDriver( DriverObject,
RegistryPathName,
&KsDeviceDescriptor );
}
Creating the miniport device object
NTSTATUS
DeviceCreate(
IN PKSDEVICE pKsDevice )
{
PEXTBUS_DEVICE_EXTENSION pEBHwExt = pKsDevice->Context;
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
ntStatus = WdfDeviceMiniportCreate(WdfGetDriver(),
&attributes,
pKsDevice->FunctionalDeviceObject,
pKsDevice->NextDeviceObject,
pKsDevice->PhysicalDeviceObject ,
&pEBHwExt->WdfDevice);
}
Deleting the miniport device object
VOID
DeviceRemove(
IN PKSDEVICE pKsDevice,
IN PIRP pIrp )
{
PEXTBUS_DEVICE_EXTENSION pEBHwExt = pKsDevice->Context;
if (pEBHwExt->WdfDeviceObject != NULL) {
WdfObjectDelete(pEBHwExt->WdfDeviceObject)
}
…
}
NOTE: Don’t forget to free the WdfDeviceObject allocated in WdfDeviceMiniportCreate
Unbinding and freeing the framework driver
resources
void
MiniDriverUnload(
IN PDRIVER_OBJECT DriverObject )
{
…
WdfDriverMiniportUnload(WdfGetDriver());
…
}
Framework features that miniport drivers can use
•
•
•
•
Framework objects benefit from lifetime management -- parenting,
reference counts, context and cleanup in a race free manner
IoTargets / USB Targets
DMA
Deferred Processing Objects
• Timers / Workitems / DPC’s
•
Utility Objects
•
•
•
•
•
•
Framework General Object (a.k.a WDFOBJECT )
Memory
Collections
Registry
WaitLocks
Debugging/Diagnosing
• Tracing / WDF Verifier/ Debug extensions
Benefits of Framework I/O Targets
• Coordinate and synchronize the cancellation of sent requests with
the request completion at the same time
• Format requests before they are sent
• Track and free I/O packets and associated memory only after they
have been completed back to the sending device
• Provide state management for I/O target objects
• Stop can either cancel all sent I/O or leave it
• Will pend incoming requests (as cancellable) when stopped
• Will resend pended requests when restarted
• Time out sent requests asynchronously
• Support for both synchronous and asynchronous communications
Benefits of Framework USB Targets
•
•
•
•
All the benefits of I/O targets described earlier, plus more
Ease of configuring a USB device
USB bus-specific formatting DDI
Continuous reader
• Ping-pong model for having outstanding USB URB’s, allocation of
memory, error handling, event callback to driver to indicate success or
failure
Code snippet showing USB target usage in a
miniport
Creating and Initializing the
WDFUSBTARGETDEVICE
NDIS Miniport
NDIS_STATUS
MPInitialize(
NDIS_HANDLE
MiniportDriverContext,
…
)
{
ntStatus =
WdfUsbTargetDeviceCreate(
Adapter->WdfDevice,
&attributes,
&Nic->UsbDevice);
//SelectConfig(Nic->UsbDevice);
//GetFrameworkPipeHandles(Nic>UsbDevice);
…
}
AvStream Minidriver
NTSTATUS
DeviceStart(
IN PKSDEVICE pKsDevice,
… )
{
PEXTBUS_DEVICE_EXTENSION pEBHwExt =
pKsDevice->Context;
ntStatus = WdfUsbTargetDeviceCreate(
pEBHwExt->WdfDevice,
&attributes,
&pEBHwExt->UsbDevice);
//SelectConfig(
pEBHwExt->UsbDevice);
//GetFrameworkPipeHandles(pEBHwExt>UsbDevice);
…
}
Benefits of using Framework DMA
•
•
Transaction-based model
Simple to use – Driver specifies DMA profile based on the capabilities
of PCI device(32 vs 64, common buffer vs packet based, SG supported)
• Framework uses the profile to manage mixed-mode DMA addressing (ex.
32-bit DMA engine on 64-bit platform without special code in driver)
• Drivers don’t need to know bus addressing capability(64-bit capable or
not)
• Framework insures that drivers receive data buffer physical addresses
that are within the addressing capabilities of their device irrespective of total
memory on the system
•
•
Extension of IO Request processing into the DMA domain.
NOTE: Some port libraries provide their own DMA model and the driver
needs to abide by that. For eg: NDIS
Benefits of using framework deferred processing
objects – Workitems, Timers, DPC’s
•
•
Can reference a parent object to ensure that reference counts are properly
maintained as long as the callback is outstanding
Workitems
•
•
•
Can flush them to make sure no callback is outstanding after the call returns
Passive Timer support (added in version 1.9)– Allows timer callbacks at IRQL
PASSIVE_LEVEL
Timers
•
•
Coalescable Timers in Windows 7
• This feature allows to set a timer whose expiration is coalescable with other
timers in the system.
• It uses the tolerable delay parameter to adjust the timer’s due time so that the
timer expires at a point convenient to the system.
Has start /stop semantics
• The Stop can be synchronous (only callable at IRQL PASSIVE_LEVEL) to make
sure that the Timer callback has been delivered if the Wait flag passed in is set to
TRUE
Utility objects
•
Framework general Object
•
•
•
Memory
•
•
•
•
Self describing, length is embedded
Provides consistent interface to different types of memory (MDL, buffers)
Referenced memory handle(can be parented to WDFREQUEST) allows driver writers
to mitigate the common mistake of freeing memory before async. I/O has completed
Collection
•
•
•
Useful to represent any abstraction in the driver which can be modeled as an object
Lifetime management -- Benefits from framework parenting, reference counts, context
and cleanup
Insert /Delete/ Retrieve semantics
Convenient for storing heterogeneous framework objects
Registry / Wait Lock
•
Simplified parameter passing
Diagnosing and debugging support
• Trace logs
• WDF verifier
• Framework Debug extensions
Framework features which miniport drivers can’t
use
• Since the port library takes over the dispatch table of the driver, the
following framework features can’t be used
• Pnp
• Interrupts – Closely tied to the framework Pnp state machine
• Power
• IoQueues
• WMI
• Framework doesn’t support partial override of dispatch table
Call to Action
•
•
•
•
Read the WDF Book.
Test your UMDF and KMDF drivers with 1.9 immediately.
Start using the new samples and debugging tools.
Write your next driver with UMDF or KMDF.
• Keep telling us what stops you from doing that.
• Your input does affect our future plans.
• Send us your feedback:
• [email protected]
Additional Resources
• Web Resources
• White papers: http://go.microsoft.com/fwlink/?LinkID=79335
• Presentations: Writing KMDF HID Minidrivers
• Blogs
• http://blogs.msdn.com/doronh/default.aspx (A Hole In My Head)
• http://blogs.msdn.com/peterwie/default.aspx (Pointless Blathering)
• http://blogs.msdn.com/iliast/default.aspx (driver writing != bus driving)
• Newsgroups and Lists
• Microsoft.public.device.development.drivers
• OSR NTDev Mailing List
• Book: Developing Drivers with the Windows Driver Foundation
• http://www.microsoft.com/MSPress/books/10512.aspx
WDF DDC 2008 Sessions
Session
Day / Time
Shared Secrets about Windows Driver Framework: Part 1
Mon. 11-12 and
Wed. 8:30-9:30
Shared Secrets about Windows Driver Framework: Part 2
Mon. 4-5 and
Wed. 9:45-10:45
Getting a Logo for your Windows Driver Foundation Driver
Mon. 4-5
Tues. 2:45-3:45
Using WinDBG to Debug Kernel-Mode Windows Driver Framework Drivers
Mon. 2:45-3:45
Wed. 11-12
Packaging and Deploying KMDF and UMDF Drivers
Tues. 4-5
Wed. 8:30-9:30
Exploring a KMDF Storage Driver: Parts 1 and 2
Tues. 9:45-12:00
What’s New in Windows Driver Framework
Mon. 8:30-9:30
Wed. 9:45-10:45
• Ask the Experts Table,
• Panel Disccussion
Discussion: Windows Driver Framework
Wed. 1:30-2:30
Ask the Experts Table
Tues. evening