MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_NextPart_01CC4DF5.1FA44F90" This document is a Single File Web Page, also known as a Web Archive file. If you are seeing this message, your browser or editor doesn't support Web Archive files. Please download a browser that supports Web Archive, such as Windows® Internet Explorer®. ------=_NextPart_01CC4DF5.1FA44F90 Content-Location: file:///C:/EEB34A10/WdfMultiComp.htm Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset="us-ascii"
This sample demonstrates how a K=
MDF
driver can implement F-state-based power management for a device that has an
arbitrary number of components that can be individually power-managed.
The sample driver statically lin=
ks
to a helper library (WdfPoFx.lib) that encapsulates all of the generic code=
to
interact with the power framework. The device-specific code is implemented =
in
the driver itself, outside of the helper library. The idea behind this
organizing the code in this manner is make the helper library reusable by o=
ther
drivers. The directory structure for the sample is as follows:
-
The helper library is implemente=
d in
the ‘lib’ subdirectory
-
The interface between the helper
library and the rest of the driver code is defined in the ‘inc’ subdirectory
-
The driver is implemented in the
‘driver’ subdirectory
The
driver can be installed on a root-enumerated device using the devcon.exe to=
ol.
1.
Obtain
the devcon.exe tool from the WDK
2.
Copy
the driver binary, INF file and the KMDF coinstaller=
span>
to a directory on your test machine.
3.
Run
the command “devcon.exe install WdfMultiComp.inf WDF\WdfMultiComp”
Use
the PowerFxApp.exe application to send I/O requests to the driver. Running =
the
command “PowerFxApp.exe /?” displays detailed usage information=
.
The
driver controls a device that has more than one component. It needs to acce=
ss
one of those components for processing each I/O request that it receives. T=
he
specific component that it needs to access depends on the I/O request that =
it
receives.
In
order to support this, the driver creates one top-level, power-managed queu=
e to
receive all its requests. It also creates one secondary, power-managed queue
for each of its components. These secondary queues are called component que=
ues.
This is shown in the diagram below.

When
the driver’s dispatch routine for the top-level queue is invoked, it
examines the request to determine which component it needs to access in ord=
er
to process the request. Then, it forwards the request to the component queue
for the component that it needs to access for that request. When the
driver’s dispatch routine for the component queue is invoked, it acce=
sses
the component hardware to process the request.
The
driver’s top-level queue and component queues are all power-managed so
KMDF ensures that the device is in D0 while the queues are in a dispatching
state. The key point to note is that the driver is designed to maintain a c=
omponent
queue in a dispatching state only when the component is active. In order to
achieve this, the driver stops the component queue when the component becom=
es
idle and starts the component queue when the component becomes active. (To =
be
precise, this mechanism of stopping and starting queues is encapsulated in =
the
power framework helper library used by the driver). Thus, the driver is abl=
e to
ensure that when the component queue is in a dispatching state, not only is=
the
device in D0 but the component corresponding to that queue is also active. =
Thus
it is safe to access the component hardware when the component queue’s
dispatch routine is invoked.
The
driver uses the power framework helper library to manage most of its
interactions with the power framework. In order to achieve this, during dev=
ice
initialization, the driver performs the following tasks in its EvtDriverDeviceAdd callback:
-
Enables
the helper library to register its own KMDF callbacks for PNP and
power-management of the device.
-
Provides
the helper library with power-framework-related information about the devic=
e.
-
Provides
the helper library with information about the component queues.
During
I/O request processing, the driver uses routines provided by helper library=
to
forward requests to component queues and also to complete requests.
The
main tasks performed by the power framework helper library on behalf of the
driver are:
-
Registration
and unregistration with the power framework.
-
Stopping
component queues when the corresponding components become idle and starting
them when the corresponding components become active.
-
Notifying
the power framework when the device returns to its working state (D0) in
response to the system returning from a low-power state to the working state
(S0).
The
power framework helper library does not have any hardware-specific informat=
ion,
so any tasks that are specific to the device’s hardware are performed=
by
the driver. In this sample, the device hardware is represented by a very si=
mple
simulation. The notable hardware-specific tasks in this sample are:
-
Accessing
component hardware to process I/O requests.
-
Accessing
component hardware to change the component’s F-state.
As
mentioned earlier, the hardware access shown is this sample is entirely
simulated in software. This sample does not work with a real device –=
it
installs on a root-enumerated software device.
The
power framework helper library implements support for S0-idle power managem=
ent
for the device. Note that this is different from the component power manage=
ment
support that is enabled by the power framework. Component power management
enables individual components of the device to be power-managed by putting =
them
in different F-states while the device is in a working state (D0). S0-idle
power management for the device enables the device as a whole to be
power-managed by putting it into different D-states while the system is in a
working state (S0).
The
code to implement S0-idle power management support for the device is
conditionally compiled based on the value of the PFH_S0IDLE_SUPPORTED compiler switc=
h. If
the switch is set to a non-zero value, the code to implement S0-idle power
management support is included. If set to zero, the code is omitted thereby
resulting in a smaller binary size. Thus, a driver that requires S0-idle po=
wer
management for the device can use the power framework helper library’s
support for it but a driver that does not require it can reduce its binary =
size
by omitting the code that is specific to S0-idle power management.