195 lines
9.9 KiB
HTML
195 lines
9.9 KiB
HTML
|
<HTML>
|
||
|
<HEAD>
|
||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-
|
||
|
1252">
|
||
|
<META NAME="Generator" CONTENT="Microsoft FrontPage 5.0">
|
||
|
<TITLE>Selective Suspend</TITLE>
|
||
|
</HEAD>
|
||
|
<BODY LINK="#0000ff">
|
||
|
|
||
|
<p><b><font face="Times New Roman">The Selective Suspend driver</font></b></p>
|
||
|
<ul>
|
||
|
<li><font face="Times New Roman">The selective suspend driver is a generic function driver based on the
|
||
|
Windows Driver Model (WDM).</font></li>
|
||
|
<li><font face="Times New Roman">Supports Plug and Play(PnP), Power
|
||
|
Management(PM), Windows Management Instrumentation (WMI) and the Selective
|
||
|
Suspend (SS) features.</font></li>
|
||
|
<li><font face="Times New Roman">The support for PnP, PM and the WMI feature
|
||
|
is essential for any driver based on the WDM model.</font></li>
|
||
|
<li><font face="Times New Roman">The SS feature, described in detail later, is
|
||
|
a new feature in the core USB stack.</font></li>
|
||
|
</ul>
|
||
|
<p><font face="Times New Roman"><b>Plug and Play</b></font></p>
|
||
|
<ul>
|
||
|
<li><font face="Times New Roman">The Plug and Play system allows for dynamic
|
||
|
recognition of installed hardware and configuration of resources.</font></li>
|
||
|
<li><font face="Times New Roman">The selective suspend driver (function
|
||
|
driver) registers a dispatch routine to receive and process PnP requests
|
||
|
from the PnP manager.</font></li>
|
||
|
<li><font face="Times New Roman">In the dispatch routine, the driver examines
|
||
|
the minor function of the PnP requests and delegates them for further
|
||
|
processing. <br>
|
||
|
Please refer the Windows XP DDK docs and the Toaster sample in the DDK to
|
||
|
understand the kernel-driver responsibilities and handling of PnP requests.</font></li>
|
||
|
<li><font face="Times New Roman">The selective suspend driver has the
|
||
|
following delegate-routines to process the PnP requests.</font></li>
|
||
|
</ul>
|
||
|
<table border="1" width="65%">
|
||
|
<tr>
|
||
|
<td width="46%"><font face="Courier New">IRP_MN_START_DEVICE</font></td>
|
||
|
<td width="54%"><font face="Courier New">HandleStartDevice()</font></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td width="46%"><font face="Courier New">IRP_MN_QUERY_STOP_DEVICE</font></td>
|
||
|
<td width="54%"><font face="Courier New">HandleQueryStopDevice()</font></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td width="46%"><font face="Courier New">IRP_MN_CANCEL_STOP_DEVICE</font></td>
|
||
|
<td width="54%"><font face="Courier New">HandleCancelStopDevice()</font></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td width="46%"><font face="Courier New">IRP_MN_STOP_DEVICE</font></td>
|
||
|
<td width="54%"><font face="Courier New">HandleStopDevice()</font></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td width="46%"><font face="Courier New">IRP_MN_QUERY_REMOVE_DEVICE</font></td>
|
||
|
<td width="54%"><font face="Courier New">HandleQueryRemoveDevice()</font></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td width="46%"><font face="Courier New">IRP_MN_CANCEL_REMOVE_DEVICE</font></td>
|
||
|
<td width="54%"><font face="Courier New">HandleCancelRemoveDevice()</font></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td width="46%"><font face="Courier New">IRP_MN_SURPRISE_REMOVAL</font></td>
|
||
|
<td width="54%"><font face="Courier New">HandleSurpriseRemoval()</font></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td width="46%"><font face="Courier New">IRP_MN_REMOVE_DEVICE</font></td>
|
||
|
<td width="54%"><font face="Courier New">HandleRemoveDevice()</font></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td width="46%"><font face="Courier New">IRP_MN_QUERY_CAPABILITIES</font></td>
|
||
|
<td width="54%"><font face="Courier New">HandleQueryCapabilities()</font></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p><font face="Times New Roman"><b>Power Management</b></font></p>
|
||
|
<ul>
|
||
|
<li>The power manager is the global power-policy owner for the system and the
|
||
|
devices.</li>
|
||
|
<li>The selective suspend driver registers a dispatch routine to receive and
|
||
|
process power requests.</li>
|
||
|
<li>In the dispatch routine, the driver examines the minor function of the
|
||
|
power requests and delegates them for further processing.</li>
|
||
|
<li>Please refer the Windows XP DDK docs and the Toaster sample in the DDK to
|
||
|
understand the kernel-driver responsibilities and handling of power requests.</li>
|
||
|
</ul>
|
||
|
<table border="1" width="64%">
|
||
|
<tr>
|
||
|
<td width="50%"><font face="Courier New">IRP_MN_QUERY_POWER(SystemPowerState)</font></td>
|
||
|
<td width="50%"><font face="Courier New">HandleSystemQueryPower()</font></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td width="50%"><font face="Courier New">IRP_MN_QUERY_POWER(DevicePowerState)</font></td>
|
||
|
<td width="50%"><font face="Courier New">HandleDeviceQueryPower()</font></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td width="50%"><font face="Courier New">IRP_MN_SET_POWER (DevicePowerState)</font></td>
|
||
|
<td width="50%"><font face="Courier New">HandleDeviceSetPower()</font></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td width="50%"><font face="Courier New">IRP_MN_SET_POWER (SystemPowerState)</font></td>
|
||
|
<td width="50%"><font face="Courier New">HandleSystemSetPower()</font></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p><b>Remote Wakeup capability</b></p>
|
||
|
<p>The selective suspend driver supports the remote wakeup capability. The
|
||
|
routines which implement this capability are:<br>
|
||
|
<font face="Courier New">IssueWaitWake()<br>
|
||
|
WaitWakeCallback()<br>
|
||
|
WaitWakeCompletionRoutine()</font></p>
|
||
|
<ul>
|
||
|
<li>After the device is configured and is in a D0 power state, the selective
|
||
|
suspend driver requests an <font face="Courier New">IRP_MN_WAIT_WAKE</font>
|
||
|
request for the device - <font face="Courier New">IssueWaitWake</font>. </li>
|
||
|
<li>A pointer to the callback function in the driver, <font face="Courier New">WaitWakeCallback</font><font face="Times New Roman">,</font>
|
||
|
is passed along this request. </li>
|
||
|
<li>The wait-wake request is sent to the PDO for the driver. </li>
|
||
|
<li>When this request is received by the selective
|
||
|
suspend driver , the dispatch routine sets a completion routine, <font face="Courier New">WaitWakeCompletionRoutine</font><font face="Times New Roman">,
|
||
|
for this request.</font></li>
|
||
|
<li>The request is then passed down the stack.</li>
|
||
|
<li>The request remains pending with the hub driver until completed by the hub
|
||
|
driver.</li>
|
||
|
<li>On resume signaling, the wait wake request is completed and the callback
|
||
|
function is invoked. <br>
|
||
|
The <font face="Courier New">WaitWakeCallback</font> routine powers up the
|
||
|
device and issues a new wait-wake request for the device.</li>
|
||
|
<li>The wait wake request should not be sent when the device is in a low power
|
||
|
state.</li>
|
||
|
</ul>
|
||
|
<p><b>Selective Suspend feature</b></p>
|
||
|
<p>The USB core stack supports a new feature called the selective suspend
|
||
|
feature. This feature allows the driver to power down the device while the
|
||
|
system remains in the S0 power state. </p>
|
||
|
<ul>
|
||
|
<li>The device driver "observes" that the device is idle and sends
|
||
|
an idle request down the stack - <font face="Courier New">SubmitIdleRequestIrp.<br>
|
||
|
</font> <font face="Times New Roman">The exact notion of the device in idle
|
||
|
state is
|
||
|
described in the selective suspend model section.</font></li>
|
||
|
<li>A pointer to the callback function in the driver, <font face="Courier New">IdleNotificationCallback,</font>
|
||
|
is passed along with it.</li>
|
||
|
<li>The driver also sets a completion routine, <font face="Courier New">IdleNotificationRequestComplete
|
||
|
</font><font face="Times New Roman">for this request</font>. </li>
|
||
|
<li>The hub driver pends this idle request for the device.</li>
|
||
|
<li>When the hub "deems it appropriate" to selectively suspend the
|
||
|
device, the callback function <font face="Courier New">IdleNotificationCallback</font>
|
||
|
is invoked.<br>
|
||
|
This function powers down the device. The device is powered down to
|
||
|
the <font face="Courier New">DeviceWake</font>
|
||
|
state (initialized while handling the <font face="Courier New">IRP_MN_QUERY_CAPABILITIES</font>).
|
||
|
<br>
|
||
|
If the <font face="Courier New">DeviceWake</font> state is not known, then
|
||
|
the device should power down to the D2 power state.</li>
|
||
|
</ul>
|
||
|
<p>Notes</p>
|
||
|
<ul>
|
||
|
<li>Since the hub invokes the callback function, <font face="Courier New">IdleNotificationCallback</font>,
|
||
|
only when it deems appropriate, the function driver should never assume that
|
||
|
the device will power down as soon as the idle request is sent down the
|
||
|
stack. </li>
|
||
|
<li>Since it is not appropriate to send requests down the stack when the
|
||
|
device is in low power state,
|
||
|
the function driver should send an idle request only when the device is in D0
|
||
|
power state. </li>
|
||
|
<li>As soon as the device is "not idle", the driver should cancel
|
||
|
the idle request - <font face="Courier New">CancelSelectSuspend</font>.</li>
|
||
|
<li>No assumptions should be made on the completion of idle request. If the
|
||
|
driver needs to pass requests (reads/writes/ioctls) down the stack, then the
|
||
|
driver should wait for the idle request to complete before proceeding to
|
||
|
submit one.</li>
|
||
|
<li>If the idle request completes in error, the <font face="Courier New">IdleNotificationRequestComplete
|
||
|
</font><font face="Times New Roman">powers
|
||
|
up the device.</font></li>
|
||
|
<li>Only one idle request can be pending for the device at any time.</li>
|
||
|
</ul>
|
||
|
<p>Selective Suspend model</p>
|
||
|
<ul>
|
||
|
<li>The selective suspend driver interprets the device as idle when<br>
|
||
|
a) there are no open handles to the device and<br>
|
||
|
b) no PnP requests are being processed. <br>
|
||
|
This is a mere suggestion. A function driver may have a different
|
||
|
interpretation of the idle state.<br>
|
||
|
As an example, an open handle need not violate the idle state of the device
|
||
|
if this does not cause any request to be sent down the stack.</li>
|
||
|
<li>The selective suspend driver initializes a timer to fire at fixed
|
||
|
intervals. </li>
|
||
|
<li>The DPC associated with the timer checks the idle state of the device and
|
||
|
queues a work item to submit an idle request for the device. </li>
|
||
|
<li>The timer is cancelled when the idle request is passed down the stack. </li>
|
||
|
<li>The timer is re-initialized when the idle request completes.</li>
|
||
|
</ul>
|
||
|
<p>Please refer the inline comments in the selSusp sample for implementation of
|
||
|
the above suggestions.</p>
|
||
|
</BODY>
|
||
|
</HTML>
|