|
|
<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>
|