USB UMDF ドライバーでのセレクティブサスペンド

重要な API

このトピックでは、UMDF 関数ドライバーが USB のセレクティブサスペンドをサポートするしくみについて説明します。

UMDF 関数ドライバーでは、次の2つの方法のいずれかで、USB のセレクティブサスペンドをサポートできます。

  • 電源ポリシーの所有権を要求し、デバイスのアイドル電力を処理し、再開します。
  • Microsoft が提供する WinUSB.sys ドライバーを使用して、選択的中断を処理します。 WinUSB.sys は、UMDF USB ドライバーのインストール時に、カーネルモードのデバイススタックの一部としてインストールされます。 WinUSB.sys は、USB デバイス操作を中断および再開するための基になるメカニズムを実装します。

どちらの方法でも、少量のコードしか必要ありません。 WDK に用意されている IdleWake サンプルは、UMDF USB ドライバーでのセレクティブサスペンドをサポートする方法を示しています。 このサンプルは、%WinDDK%\BuildNumber\Src\Usb\OsrUsbFx2\ UMDF \ Fx2_Driver \IdleWake. で見つけることができます。 このフォルダーには、サンプルの PPO と non PPO の両方のバージョンが含まれています。

セレクティブサスペンドをサポートする UMDF ドライバーは、次のガイドラインに従う必要があります。

  • UMDF ドライバーは、デバイススタックの電源ポリシーの所有権を要求できますが、そのためには必要ありません。 既定では、基になる WinUSB.sys ドライバーは電源ポリシーを所有しています。
  • 選択的中断をサポートする UMDF ドライバー。 PPO では、電源管理キューまたは電源管理されていないキューを使用できます。 選択的中断をサポートするが、PPO ではない UMDF ドライバーは、電源管理キューを使用しないようにする必要があります。

UMDF USB ドライバーの電源ポリシーの所有権

既定では、WinUSB.sys は、UMDF USB ドライバーを含むデバイススタックの PPO です。 WDF 1.9 以降では、UMDF ベースの USB ドライバーが電源ポリシーの所有権を要求することができます。 PPO にできるのは、各デバイススタック内のドライバー1つだけであるため、PPO である UMDF USB ドライバーは、WinUSB.sys で電源ポリシーの所有権を明示的に無効にする必要があります。

UMDF USB ドライバーで電源ポリシーの所有権を要求するには

  1. Iwdfdeviceinitialize:: SetPowerPolicyOwnershipを呼び出し、通常は、ドライバーコールバックオブジェクトのIdriverentry:: ondeviceaddメソッドからTRUEを渡します。 次に例を示します。

    FxDeviceInit->SetPowerPolicyOwnership(TRUE);
    
  2. WinUSB で電源ポリシーの所有権を無効にします。 ドライバーの INF ファイルに、レジストリのWinUsbPowerPolicyOwnershipDisabled値を0以外の値に設定するAddRegディレクティブを含めます。 AddRegディレクティブは、DDINSTALL. HW セクションに記述する必要があります。 次に例を示します。

    [MyDriver_Install.NT.hw]
    AddReg=MyDriver_AddReg
    
    [MyDriver_AddReg]
    HKR,,"WinUsbPowerPolicyOwnershipDisabled",0x00010001,1
    

セレクティブサスペンドをサポートし、1.9 より前の WDF バージョンでビルドされた UMDF USB ドライバーは、電源ポリシーの所有権を要求しません。 これらの以前のバージョンの WDF では、WinUSB.sys が PPO の場合にのみ、USB 選択的中断が正常に機能します。

UMDF USB ドライバーの i/o キュー

選択的中断をサポートする UMDF ドライバーの場合、そのデバイスの電源ポリシーが UMDF ドライバーによって所有されているかどうかによって、使用できる i/o キューの種類が決まります。 選択的中断および PPOs をサポートする UMDF ドライバーでは、電源管理されているキューか、電源管理されていないキューを使用できます。 選択的中断をサポートするが、PPO ではない UMDF USB ドライバーは、電源管理の i/o キューを使用しないようにする必要があります。

デバイスが中断されている間に、電源管理キューに i/o 要求が到着した場合、ドライバーが PPO でない限り、フレームワークは要求を提示しません。これは、 USB ドライバーのセレクティブサスペンドのイメージに示されています。 UMDF ドライバーがデバイスの PPO でない場合、フレームワークはデバイスの代わりにデバイスの電源をオンにすることはできません。 その結果、要求は、電源管理キューでスタックされたままになります。 要求が WinUSB に到達しないため、WinUSB はデバイスの電源をオンにできません。 その結果、デバイススタックが停止する可能性があります。

キューが電源管理されていない場合、デバイスの電源がオフになっている場合でも、フレームワークは UMDF ドライバーに i/o 要求を提示します。 UMDF ドライバーは、要求をフォーマットし、通常の方法でデバイススタックから既定の i/o ターゲットに転送します。 特別なコードは必要ありません。 要求が PPO (WinUSB.sys) に到達すると、WinUSB.sys はデバイスの電源を入れ、必要な i/o 操作を実行します。

%Winddk%\buildnumber\src\usb\osrusbfx2\umdf\ Fx2_Driver \idlewakeのサンプルドライバーは、ppo 以外のバージョンのドライバーをビルドするときに _NOT_POWER_POLICY_OWNER_ 定数を定義します。 ドライバーは、読み取り要求と書き込み要求のキューを作成するときに、定数をチェックすることによって、電源管理キューを作成するかどうかを決定します。

キューを作成するには、ドライバーによって定義された CMyQueue:: Initialize メソッドを呼び出します。このメソッドは、次の3つのパラメーターを受け取ります。

  • DispatchTypeは、キューが要求をディスパッチする方法を示す WDF_IO_QUEUE_DISPATCH_TYPE 列挙値です。
  • 既定値は、キューが既定のキューであるかどうかを示すブール値です。
  • Powermanaged。キューが電源管理されているかどうかを示すブール値です。

次のコードスニペットは、読み取り/書き込みキューの作成の一部として、ドライバーの CMyQueue:: Initialize メソッドの呼び出しを示しています。

#if defined(_NOT_POWER_POLICY_OWNER_)
    powerManaged = false;
#else
    powerManaged = true;
#endif  
hr = __super::Initialize(WdfIoQueueDispatchParallel,
                         true,
                         powerManaged,
                         );

CMyQueue:: Initialize は、次のように、 Iwdfdevice:: CreateIoQueue を呼び出してキューを作成します。

hr = m_FxDevice->CreateIoQueue(
                               callback,
                               Default,
                               DispatchType,
                               PowerManaged,
                               FALSE,
                               &fxQueue
                               );

このコードシーケンスは、要求を並列でディスパッチする既定のキューになります。 ドライバーが PPO の場合、キューは電源管理され、ドライバーが PPO でない場合、キューは電源管理されません。

UMDF PPO での USB 選択的中断のサポート

セレクティブサスペンドをサポートするために、デバイススタックの PPO である UMDF USB ドライバーは、次の操作を行う必要があります。

  1. 前に説明したように、ドライバーコールバックオブジェクトの Idriverentry:: OnDeviceAdd メソッドで、デバイススタックの電源ポリシーの所有権を要求します。
  2. フレームワークデバイスオブジェクトで IWDFDevice2:: AssignS0IdleSettings メソッドを呼び出して、選択的中断を有効にします。

PPO から USB のセレクティブサスペンドを有効にするには

  • IWDFDevice2:: AssignS0IdleSettingsを呼び出します。通常は、デバイスコールバックオブジェクトの代わっ hardwareメソッドから呼び出します。 次のように、パラメーターを AssignS0IdleSettings に設定します。
    • IdleCapsIdleUsbSelectiveSuspend.
    • Dxstate は、フレームワークがアイドル状態のデバイスを遷移するデバイスのスリープ状態になります。 USB のセレクティブサスペンドの場合は、 PowerDeviceMaximumを指定します。これは、バスドライバーで指定された値をフレームワークが使用する必要があることを示します。
    • フレームワークがDxstateに遷移する前に、デバイスがアイドル状態である必要があるミリ秒数にIdleTimeoutします。
    • UserControlOfIdleSettings は、ユーザーがアイドル設定を管理できる場合はIdleAllowUserControl 、それ以外の場合はId Onotallowusercontrolに設定します。
    • 既定でセレクティブサスペンドを有効にし、ユーザー設定で既定値をオーバーライドできるようにするために、 Wdfusedefaultに対して有効にします。

次の例は、IdleWake_PPO ドライバーが内部 CMyDevice:: SetPowerManagement メソッドでこのメソッドを呼び出す方法を示しています。

hr = m_FxDevice->AssignS0IdleSettings( IdleUsbSelectiveSuspend,
                                PowerDeviceMaximum,
                                IDLE_TIMEOUT_IN_MSEC,
                                IdleAllowUserControl,
                                WdfUseDefault);                                                                                                   

デバイスハードウェアがウェイクアップ信号を生成できる場合、UMDF ドライバーは S1、S2、または S3 からのシステムウェイクもサポートできます。 詳細については、「 UMDF ドライバーでのシステムのスリープ解除」を参照してください。

PPO 以外の UMDF ドライバーでの USB 選択的中断のサポート

PPO 以外の UMDF 関数ドライバーは、基になる WinUSB.sys ドライバーの機能を使用して、選択的中断をサポートできます。 UMDF ドライバーは、デバイスとドライバーが選択的中断をサポートしていること、および INF ファイルで選択的な中断を有効にするか、USB ターゲットデバイスオブジェクトの電源ポリシーを設定する必要があることを WinUSB に通知する必要があります。

UMDF 関数ドライバーで選択的中断が有効になっている場合、基になる WinUSB.sys ドライバーは、デバイスがアイドル状態であることを判断します。 WinUSB は、保留中の転送がない場合、または保留中の転送のみが割り込みまたは一括エンドポイントで転送される場合に、アイドルタイムアウトカウンターを開始します。 既定では、アイドルタイムアウトは5秒ですが、UMDF ドライバーはこの既定値を変更できます。

WinUSB.sys がデバイスがアイドル状態であると判断した場合は、デバイスを中断する要求をカーネルモードのデバイススタックに送信します。 バスドライバーは、ハードウェアの状態を必要に応じて変更します。 ポートのすべてのデバイス機能が中断されている場合は、USB のセレクティブサスペンドの状態になります。

デバイスが中断されている間に WinUSB.sys に i/o 要求が到着した場合、要求を処理するためにデバイスの電源をオンにする必要がある場合、WinUSB.sys はデバイスの操作を再開します。 UMDF ドライバーでは、システムが S0 を受けている間にデバイスを再開するコードは必要ありません。 デバイスハードウェアがウェイクアップ信号を生成できる場合、UMDF ドライバーは S1、S2、または S3 からのシステムウェイクもサポートできます。 詳細については、「 UMDF ドライバーでのシステムのスリープ解除」を参照してください。

PPO 以外の UMDF ドライバーは、次の2つの手順を実行することで、選択的中断をサポートできます。

  1. デバイスとドライバーが選択的中断をサポートしていることを WinUSB.sys に通知します。
  2. USB セレクティブサスペンドを有効にしています。

また、ドライバーは必要に応じて次のことができます。

  • デバイスのタイムアウト値を設定します。
  • ユーザーが選択的中断を有効または無効にすることを許可します。

PPO 以外の UMDF USB 関数ドライバーで USB セレクティブサスペンドを実装する方法の例については、WDK の Fx2_Driver サンプルを参照してください。 このサンプルは 、%winddk%\buildnumber\src\usb\osrusbfx2\umdf\ Fx2_Driver \ IdleWake_Nonにあります。

セレクティブサスペンドのサポートについて WinUSB に通知するには

デバイスで USB セレクティブサスペンドをサポートできることを WinUSB.sys 通知するには、デバイスの INF で、デバイスのハードウェアキーに DeviceIdleEnabled 値を追加し、値を1に設定する必要があります。 次の例では、Fx2_Driver のサンプルで WUDFOsrUsbFx2_IdleWakeNon Inx ファイルにこの値を追加して設定する方法を示します。

[OsrUsb_Device_AddReg]
...
HKR,,"DeviceIdleEnabled",0x00010001,1

USB のセレクティブサスペンドを有効にするには

UMDF USB ドライバーは、実行時または INF でのインストール中に、USB のセレクティブサスペンドを有効にすることができます。

  • 実行時にサポートを有効にするには、関数ドライバーによって IWDFUsbTargetDevice::SetPowerPolicy が呼び出され、PolicyType パラメーターが AUTO_SUSPEND に設定され、Value パラメーターが TRUE または 1 に設定されます。 次の例は、deviceNonPpo.cpp ファイルFx2_Driverサンプルで選択的中断を有効にする方法を示しています。

    BOOL AutoSuspend = TRUE;
    hr = m_pIUsbTargetDevice->SetPowerPolicy( AUTO_SUSPEND,
                                              sizeof(BOOL),
                                             (PVOID) &AutoSuspend );
    
  • インストール中にサポートを有効にするには、INF に AddReg ディレクティブが含まれています。このディレクティブは、DefaultIdleState 値をデバイスのハードウェア キーに追加し、値を 1 に設定します。 次に例を示します。

    HKR,,"DefaultIdleState",0x00010001,1
    

アイドルタイムアウト値を設定するには

既定では、転送が保留中ではない場合、または保留中の転送が割り込みまたは一括エンドポイントでの IN 転送のみである場合、WinUSB は 5 秒後にデバイスを中断します。 UMDF ドライバーは、INF のインストール時または実行時に、このアイドル タイムアウト値を変更できます。

  • インストール時にアイドル タイムアウトを設定するために、INF には、デバイスのハードウェア キーに DefaultIdleTimeout 値を追加し、その値をタイムアウト間隔 (ミリ秒単位) に設定する AddReg ディレクティブが含まれています。 次の例では、タイム アウトを 7 秒に設定します。

    HKR,,"DefaultIdleTimeout",0x00010001,7000
    
  • 実行時にアイドル タイムアウトを設定するために、ドライバーは IWDFUsbTargetDevice::SetPowerPolicy を呼び出し、PolicyType を SUSPEND_DELAY に設定し、Value をアイドル タイムアウト値 (ミリ秒単位) に設定します。 Device.cpp ファイルの次の例では、Fx2_Driverが 10 秒に設定されます。

    HRESULT hr;
    ULONG value;
    value = 10 * 1000;
    hr = m_pIUsbTargetDevice->SetPowerPolicy( SUSPEND_DELAY,
                                              sizeof(ULONG),
                                             (PVOID) &value );
    

USB 選択的中断のユーザー制御を提供するには

WinUSB 選択的中断サポートを使用する UMDF USB ドライバーでは、必要に応じて、ユーザーが選択的中断を有効または無効にできます。 これを行うには、デバイスのハードウェア キーに UserSetDeviceIdleEnabled 値を追加し、値を 1 に設定する AddReg ディレクティブを INF に含める必要があります。 AddReg ディレクティブに使用する文字列を次に示します。

HKR,,"UserSetDeviceIdleEnabled",0x00010001,1

UserSetDeviceIdleEnabled が設定されている場合、デバイスの [プロパティ] ダイアログ ボックスには、ユーザーが USB 選択的中断を有効または無効にできる [電源管理] タブが表示されます。

UMDF ドライバーでのシステム ウェイク

UMDF ドライバーでは、システム ウェイクのサポートは選択的中断のサポートとは独立しています。 UMDF USB ドライバーは、システム ウェイクと選択的中断の両方をサポートできます。システム ウェイクも選択的中断も、システム ウェイクまたは選択的中断もサポートできません。 システム ウェイクをサポートするデバイスは、システムをスリープ状態 (S1、S2、または S3) からウェイクアップできます。

UMDF USB PPO ドライバーは、フレームワークのドライバー オブジェクトのウェイクアップ情報を提供することで、システム ウェイクをサポートできます。 外部イベントによってシステムウェイクがトリガーされると、フレームワークはデバイスを動作状態に戻します。

USB 非 PPO ドライバーでは、デバイス ドライバーが実装するシステム ウェイク WinUSB.sys使用できます。

PPO である UMDF USB ドライバーでシステム ウェイクをサポートするには

次のパラメーターを使用して、フレームワークのデバイス オブジェクトで IWDFDevice2::AssignSxWakeSettings メソッドを呼び出します。

  • DxState は、システムがウェイク可能な Sx 状態に入った場合にデバイスが遷移する電源状態に切り替えられます。 USB デバイスの場合は、バス ドライバーが指定した値を使用する PowerDeviceMaximum を指定します。
  • ドライバーでユーザーがウェイク設定を管理できる場合、または WakeDoNotAllowUserControl を管理できる場合は、UserControlOfWakeSettingsWakeAllowUserControl に設定します。
  • 既定 ではウェイクを有効にし、ユーザーの設定で既定値をオーバーライドするには、 WdfUseDefault に対して有効になります。

次の例は、ドライバーが内部 CMyDevice::SetPowerManagement メソッドでIdleWake_PPOメソッドを呼び出す方法を示しています。

hr = m_FxDevice->AssignSxWakeSettings( PowerDeviceMaximum,
                                       WakeAllowUserControl,
                                       WdfUseDefault);

PPO 以外のドライバーで WinUSB 経由でシステム ウェイクを有効にするには

WinUSB を介したシステム ウェイクを有効にするには、ドライバーの INF によってレジストリ値 SystemWakeEnabled がデバイスのハードウェア キーに追加され、1 に設定されます。 IdleWake_Non-PPO サンプルでは、次のようにシステム ウェイクが有効になります。

[OsrUsb_Device_AddReg]
...
HKR,,"SystemWakeEnabled",0x00010001,1

この値を設定することで、ドライバーは両方ともシステムウェイクを有効にし、ユーザーはデバイスがシステムをスリープ解除する機能を制御できます。 このデバイス マネージャーデバイスの電源管理設定プロパティ ページには、ユーザーがシステム ウェイクを有効または無効にできるチェック ボックスが含まれています。

USB ドライバーにおけるセレクティブ サスペンド (WDF)