次の方法で共有


USB UMDF ドライバーにおける選択的一時停止

このトピックでは、UMDF 関数ドライバーが USB 選択的一時停止をサポートする方法について説明します。

重要な API

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 バージョンと PPO 以外のバージョンの両方が含まれています。

選択的一時停止をサポートする UMDF ドライバーは、次のガイドラインに従う必要があります。

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

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

既定では、WinUSB.sys は、UMDF USB ドライバーを含むデバイス スタックの PPO です。 WDF 1.9 以降、UMDF ベースの USB ドライバーは電源ポリシーの所有権を要求できます。 各デバイス スタックに含めることができるドライバーは 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 では、USB 選択的一時停止は、WinUSB.sys が PPO の場合にのみ適切に動作します。

UMDF USB ドライバーの I/O キュー

選択的一時停止をサポートする UMDF ドライバーの場合、UMDF ドライバーがデバイスの電源ポリシーを所有しているかどうかによって、使用できる I/O キューの種類が決まります。 選択的一時停止をサポートし、PPO である UMDF ドライバーは、電源管理されているキューまたは電源管理されていないキューのどちらでも使用できます。 選択的一時停止をサポートするが、PPO ではない UMDF USB ドライバーは、電源管理 I/O キューを使用しないでください。

デバイスの中断中に電源管理キューに対して I/O 要求が到着した場合、 USB ドライバーの選択的一時停止の図に示すように、ドライバーが PPO でない限り、フレームワークは要求を提示しません。 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 を呼び出します。通常は、デバイス コールバック オブジェクトの OnPrepareHardware メソッドから呼び出します。 次のように、パラメーターを AssignS0IdleSettings に設定します。
    • IdleCaps から IdleUsbSelectiveSuspend
    • フレームワークがアイドル状態のデバイスを移行するデバイスのスリープ状態であるDxState。 USB 選択的一時停止の場合は、 PowerDeviceMaximum を指定します。これは、フレームワークでバス ドライバーが指定した値を使用する必要があることを示します。
    • IdleTimeout は、フレームワークが DxState に移行する前にデバイスがアイドル状態である必要があるミリ秒数です。
    • ドライバーでユーザーがアイドル設定を管理できる場合は IdleAllowUserControl に、それ以外の場合は IdleDoNotAllowUserControlUserControlOfIdleSettings
    • EnabledWdfUseDefault に設定して、既定では選択的サスペンドを有効にしますが、ユーザーの設定で既定値を上書きできるようにします。

次の例は、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 は、転送が保留中でない場合、または保留中の転送のみが割り込みまたは一括エンドポイントでの IN 転送である場合に、アイドル タイムアウト カウンターを開始します。 既定では、アイドル タイムアウトは 5 秒ですが、UMDF ドライバーはこの既定値を変更できます。

WinUSB.sys は、デバイスがアイドル状態であると判断すると、カーネル モード デバイス スタックでデバイスを中断する要求を送信します。 バス ドライバーは、必要に応じてハードウェアの状態を変更します。 ポート上のすべてのデバイス機能が中断されている場合、ポートは USB 選択的一時停止状態になります。

デバイスが中断されている間に I/O 要求が WinUSB.sys に到着した場合、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-PPO にあります

選択的一時停止のサポートについて WinUSB に通知するには

デバイスが USB 選択的一時停止をサポートできることを WinUSB.sys に通知するには、デバイス INF はデバイスのハードウェア キーに DeviceIdleEnabled 値を追加し、値を 1 に設定する必要があります。 次の例は、Fx2_Driverサンプルが WUDFOsrUsbFx2_IdleWakeNon-PPO.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 には、デバイスのハードウェア キーに DefaultIdleState 値を追加し、値を 1 に設定する AddReg ディレクティブが含まれています。 例えば次が挙げられます。

    HKR,,"DefaultIdleState",0x00010001,1
    

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

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

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

    HKR,,"DefaultIdleTimeout",0x00010001,7000
    
  • 実行時にアイドル タイムアウトを設定するために、ドライバーは IWDFUsbTargetDevice::SetPowerPolicy を呼び出し、PolicyType を SUSPEND_DELAY に設定し、値をアイドル タイムアウト値 (ミリ秒単位) に設定します。 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 ドライバーが実装するシステム ウェイク サポートを使用できます。

UMDF USB ドライバーが PPO の場合にシステムのウェイクアップをサポートするには

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

  • DxState は、システムがスリープ解除可能な Sx 状態になったときにデバイスが遷移する電源状態です。 USB デバイスの場合は、バス ドライバーが指定した値を使用する PowerDeviceMaximum を指定します。
  • ドライバーでユーザーがウェイク設定を管理できる場合は、UserControlOfWakeSettingsWakeAllowUserControl に切り替えてください。それ以外の場合は WakeDoNotAllowUserControl にしてください。
  • WdfUseDefaultして有効にして、既定でウェイクを有効にしますが、ユーザーの設定で既定値をオーバーライドできるようにします。

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

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

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

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

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

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