USB 帯域幅の割り当て

この記事では、USB 帯域幅の慎重な管理に関するガイダンスを提供します。 すべての USB クライアント ドライバーは、使用する USB 帯域幅を最小限に抑え、未使用の帯域幅をできるだけ早く空き帯域幅プールに戻す責任があります。

USB ドライバーが帯域幅エラーから抜け出す理由

USB バス上の帯域幅をめぐる競争は、ハードウェアとソフトウェアの両方の複数のソースから発生します。 USB クライアント ドライバーが利用できる帯域幅を正確に予測することは困難です。 USB ホスト コントローラーは、その動作のために一定量の帯域幅を必要とします。 必要な量はコントローラーが高速かどうかによって異なります。 システムによって異なります。 高速で動作する USB ハブは、高速アップストリーム ポートとLow-Speed デバイス間のトランザクションをダウンストリームに変換する必要がある場合があり、この変換プロセスは帯域幅を消費します。 ただし、トランザクション変換に帯域幅が必要かどうかは、接続されているデバイスの種類とデバイス ツリーのトポロジによって異なります。

帯域幅リソースに対する最も深刻な負担は、通常、帯域幅を独占する USB クライアント ドライバーによって発生します。 システムは帯域幅を先着順で割り当てます。 最初に読み込まれた USB ドライバーが利用可能なすべての帯域幅を要求した場合、後で読み込まれる USB ドライバーはそのデバイスの帯域幅を許可されません。 システムはデバイスを構成できず、列挙に失敗します。 列挙が失敗した理由が明らかではないため、ユーザーは不快な経験をすることになります。

場合によっては、クライアント ドライバーは、高速割り込み転送で使用可能な帯域幅を使い果たします。 しかし、最も一般的なケースは、クライアント ドライバーがアイソクロナス転送に過剰な帯域幅を割り当て、適時に帯域幅を解放できないケースです。 システムは、割り当てられた帯域幅を、要求したドライバーが (別のエンドポイントを開くことによって) エンドポイントを閉じるか、帯域幅が割り当てられていたデバイスが削除されるまで、予約します。 システムはバルク転送に保証された帯域幅を割り当てないため、バルク転送が列挙エラーの原因になることはありません。 ただし、バルク転送デバイスのパフォーマンスは、定期的な アイソクロナスおよび割り込み) 転送を行うデバイスに割り当てられる帯域幅の量によって異なります。

USB 2.0 仕様では、既定のインターフェイス設定で帯域幅がゼロのエンドポイントを持つアイソクロナス デバイスが必要です。 これにより、関数ドライバーが既定以外のインターフェイスを開くまでデバイスの帯域幅が予約されなくなり、デバイス構成中の過剰な帯域幅要求によって引き起こされる列挙エラーを防ぐことができます。 これは、クライアント ドライバーがデバイスの構成後に過剰な帯域幅を割り当てて、他のデバイスが適切に機能しなくなることを防ぐものではありません。

適切な帯域幅管理の鍵は、アイソクロナス転送を行うシステム内のすべての USB デバイスが、アイソクロナス エンドポイントを含むインターフェイスごとに複数の代替 (Alt) 設定を提供する必要があり、クライアント ドライバーがこれらの Alt 設定を賢明に使用する必要があることです。 クライアント ドライバーは、最も高い帯域幅を備えたインターフェイス設定を要求することから始める必要があります。 要求が失敗した場合、クライアント ドライバーは、要求が成功するまで、帯域幅を徐々に小さくしてインターフェイス設定を要求する必要があります。

たとえば、Web カメラ デバイスに次のインターフェイスがあるとします。

インターフェイス 0 (既定のインターフェイス設定: 既定の設定では、0 以外のアイソクロナス帯域幅を持つエンドポイントがありません)

アイソクロナス エンドポイント 1: 最大パケット サイズ = 0 バイト

アイソクロナス エンドポイント 2: 最大パケット サイズ = 0 バイト

インターフェイス 0 Alt 設定 1

アイソクロナス エンドポイント 1: 最大パケット サイズ = 256 バイト

アイソクロナス エンドポイント 2: 最大パケット サイズ = 256 バイト

インターフェイス 0 Alt 設定 2

アイソクロナス エンドポイント 1: 最大パケット サイズ = 512 バイト

アイソクロナス エンドポイント 2: 最大パケット サイズ = 512 バイト

Web カメラのドライバーは、初期化時に既定のインターフェイス設定を使用するように Web カメラを構成します。 既定の設定にはアイソクロナス帯域幅がないため、初期化中に既定の設定を使用すると、アイソクロナス帯域幅の要求が失敗したために Web カメラが列挙に失敗する危険が回避されます。

クライアント ドライバーがアイソクロナス転送を実行する準備ができたら、Alt 設定 2 のパケット サイズが最大であるため、Alt 設定 2 の使用を試行する必要があります。 要求が失敗した場合、ドライバーは Alt 設定 1 を使用して 2 回目の試行を行うことができます。 Alt 設定 1 では必要な帯域幅が少ないため、最初の要求が失敗した場合でも、この要求は成功する可能性があります。 複数の Alt 設定を使用すると、ドライバーは諦めるまでに何度か試行することができます。

Web カメラがアイドル状態になった後、既定の設定を再度選択することで、割り当てられた帯域幅を空き帯域幅プールに戻すことができます。

ユーザーは、Windows デバイス マネージャーでコントローラーのプロパティを確認することで、USB コントローラーに割り当てられた帯域幅を確認できます。 コントローラーのプロパティを選択し、[詳細設定] タブを確認します。 この読み取り値は、USB ハブがトランザクション変換に割り当てた帯域幅の量を示すものではありません。

USB コントローラーの帯域幅使用状況を報告するデバイス マネージャ機能は、Windows XP では正しく動作しません。

USB 転送とパケット サイズ

この記事では、Windows オペレーティング システムのさまざまなバージョンで許可される USB 転送サイズについて説明します。

最大転送サイズ

最大転送サイズは、USB ドライバー スタックのハードコーディングされた制限を指定します。 システム リソースの制限により、これらの制限を下回る転送サイズが失敗する可能性があります。 このような種類の障害を回避し、Windows のすべてのバージョン間での互換性を確保するには、USB 転送に大きな転送サイズを使用しないようにしてください。

Note

USBD_PIPE_INFORMATION 構造体の MaximumTransferSize メンバーは廃止されました。 USB ドライバー スタックは、複合デバイスと非複合デバイスの両方の MaximumTransferSize の値を無視します。

Windows 2000 では、USB ドライバー スタックは MaximumTransferSize を USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE に初期化します。 クライアント ドライバーは、デバイスの構成中に小さい値を設定できます。 複合デバイスの場合、各関数のクライアント ドライバーは、既定以外のインターフェイス設定のパイプの MaximumTransferSize のみを変更できます。

USB 転送サイズには、次の制限があります。

転送パイプ Windows 8.1、Windows 8 Windows 7、Windows Vista Windows XP、Windows Server 2003 Windows 2000
コントロール SuperSpeed および High-Speed 用64K (xHCI)

Full-Speed および Low-Speed 用の 4K (xHCI、EHCI、UHCI、OHCI)

UHCI の場合、既定のエンドポイントで 4K、既定以外のコントロール パイプでは 64K
High-Speed 用 64K (EHCI)

Full-Speed および Low-Speed 用の 4K (EHCI、UHCI、OHCI)

UHCI の場合、既定のエンドポイントで 4K、既定以外のコントロール パイプでは 64K (UHCI)
High-Speed 用 64K (EHCI)

Full-Speed および Low-Speed 用の 4K (EHCI、UHCI、OHCI)

UHCI の場合、既定のエンドポイントで 4K、既定以外のコントロール パイプでは 64K (UHCI)
既定のエンドポイントでは 4K、既定以外の制御パイプ (OHCI) で 64K
割り込み 4 MB (メガバイト) SuperSpeed、High-Speed、Full-Speed、Low-Speed (xHCI、EHCI、UHCI、OHCI) Full-Speed および Low-Speed 用の 4MB (EHCI、UHCI、OHCI) 無制限 不明 (OHCI)
一括 SuperSpeed 用の 32 MB (xHCI)

High-Speed および Full-Speed 用の 4 MB (xHCI)

High-Speed および Full-Speed 用の 4 MB (EHCI および UHCI)

Full-Speed 用の 256K (OHCI)
High-Speed および Full-Speed 用の 4 MB (EHCI、UHCI)

Full-Speed 用の 256K (OHCI)
High-Speed および Full-Speed 用の 3MB (EHCI)

不明 (UHCI)

Full-Speed 用の 256K (OHCI)
不明 (OHCI)
アイソクロナス SuperSpeed (xHCI) 用の 1024 * wBytesPerInterval
(USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR を参照)

High-Speed 用の 1024 * MaximumPacketSize (xHCI、EHCI)

Full-Speed 用の 256 * MaximumPacketSize (xHCI、EHCI)

Full-Speed 用の 64K (UHCI、OHCI)
High-Speed 用の 1024 * MaximumPacketSize (EHCI)

Full-Speed 用の 256 * MaximumPacketSize (EHCI)

Full-Speed 用の 64K (UHCI、OHCI)
High-Speed 用の 1024 * MaximumPacketSize (EHCI)

Full-Speed 用の 256 * MaximumPacketSize (EHCI)

Full-Speed 用の 64K (UHCI、OHCI)
Full-Speed 用の 64K (OHCI)

MaximumTransferSize で転送サイズを制限しても、デバイスが消費する帯域幅には直接影響しません。 クライアント ドライバーは、インターフェイスの設定を変更するか、USBD_PIPE_INFORMATIONMaximumPacketSize メンバーで設定された最大パケット サイズを制限する必要があります。

最大パケット サイズ

最大パケット サイズは、エンドポイント記述子の wMaxPacketSize フィールドによって定義されます。 クライアント ドライバーは、デバイスへのインターフェイスの選択要求で USB パケット サイズを調整できます。 この値を変更しても、デバイスの wMaxPacketSize は変更されません。

要求の URB には、パイプの USBD_PIPE_INFORMATION 構造があります。 その構造では、

  • USBD_PIPE_INFORMATION 構造体の MaximumPacketSize メンバーを変更します。 現在のインターフェイス設定のデバイス ファームウェアで定義されている wMaxPacketSize の値以下の値に設定します。
  • USBD_PIPE_INFORMATION 構造体の PipeFlags メンバーで、USBD_PF_CHANGE_MAX_PACKET フラグを設定します。

インターフェイス設定の選択については、「USB デバイス用の構成の選択方法」を参照してください。

読み取り転送バッファーの最大パケット サイズ制限

クライアント ドライバーが読み取り要求を行う場合、転送バッファーは最大パケット サイズの倍数である必要があります。 ドライバーが最大パケット サイズより小さいデータを予期している場合でも、パケット全体を要求する必要があります。 デバイスが最大サイズより小さいパケット (短いパケット) を送信すると、転送が完了したことを示します。

古いコントローラーでは、クライアント ドライバーが動作をオーバーライドできます。 データ転送 URBTransferFlags メンバーでは、クライアント ドライバーは、USBD_SHORT_TRANSFER_OK フラグを設定する必要があります。 このフラグにより、デバイスは wMaxPacketSize より小さいパケットを送信できます。

xHCI ホスト コントローラーでは、バルク エンドポイントおよび割り込みエンドポイントに対して USBD_SHORT_TRANSFER_OK が無視されました。 EHCI コントローラーで短いパケットを転送しても、エラー状態にはなりません。

EHCI ホスト コントローラーでは、USBD_SHORT_TRANSFER_OK はバルク エンドポイントおよび割り込みエンドポイントに対して無視されます。

UHCI および OHCI ホスト コントローラーでは、USBD_SHORT_TRANSFER_OK がバルク転送または割り込み転送に設定されていない場合、ショート パケット転送によってエンドポイントが停止し、転送に対してエラー コードが返されます。

書き込み転送を短いパケットで区切る

USB ドライバー スタック ドライバーは、デバイスへの書き込み時に、デバイスからの読み取り時に課すパケット サイズと同じ制限を課しません。 一部のクライアント ドライバーは、デバイスを管理するために少量の制御データを頻繁に送信する必要があります。 このような場合、データ送信を均一サイズのパケットに制限するのは現実的ではありません。 したがって、ドライバー スタックは、データ書き込み中にエンドポイントの最大サイズより小さいサイズのパケットに特別な意味を割り当てません。 これにより、クライアント ドライバーは、デバイスへの大規模な転送を最大値以下の任意のサイズの複数の URB に分割できます。

ドライバーは、最大サイズ未満のパケットで送信を終了するか、長さ 0 のパケットで送信の終わりを区切る必要があります。 ドライバーが wMaxPacketSize より小さいパケットを送信するまで、転送は完了しません。 転送サイズが最大値の正確な倍数である場合、ドライバーは転送を明示的に終了するために長さ 0 の区切りパケットを送信する必要があります

クライアント ドライバーは、USB 仕様の要求に従って、データ送信を長さ 0 のパケットで区切る役割を果たします。 USB ドライバー スタックは、これらのパケットを自動的に生成しません。

wMaxPacketSize より小さいパケットで USB データ転送を区切る

準拠している USB 2.0 および USB 1.1 ドライバーは、最大サイズ (wMaxPacketSize) のパケットを送信し、最大サイズ未満のパケットで送信を終了するか、長さ 0 のパケットで伝送の終了を区切る必要があります。 ドライバーが wMaxPacketSize より小さいパケットを送信するまで、転送は完了しません。 転送サイズが最大値の正確な倍数である場合、ドライバーは転送を明示的に終了するために長さ 0 の区切りパケットを送信する必要があります

デバイス ドライバーは、USB 仕様の要求に従って、データ送信を長さ 0 のパケットで区切る役割を果たします。 システム USB スタックは、これらのパケットを自動的に生成しません。