01signal.com

Linux での USB デバイスのリセット (およびその電源の制御)

序章

完璧な世界では、 USB デバイスと hubs は適切に動作し、遭遇した問題を解決することができます。実際には、あらゆる種類の奇妙なことが起こり、それを何とかする必要があります。一般的な解決策は、 USB プラグを抜いて、デバイスを再度接続することです。しかし、これが自動的に行われる必要がある場合はどうでしょうか?

最も劇的な解決策は、 別の Web ページで紹介されています。 USB hubの driversのシャットダウンと再起動が発生します。この効果は、コンピューター上のすべての USB デバイスを切断して再接続するのとほぼ同じです。それは最も重いハンマーであり、時には必要です。

このページでは、1 つの特定の USB デバイスをリセットする 2 つの方法を紹介します。まず、いくつかの最小限の説明を加えて、各方法を実行する方法を紹介します。この後、多くの技術的な詳細に入ります。

ここで紹介する 2 番目の方法はおそらく他のプラットフォームでも可能ですが、ここでは説明全体を Linux に限定します。

ここでの多くの情報は、 Universal Serial Bus Specification Revision 2.0から取得されます。このドキュメントのファイル名は通常 usb_20.pdfです。

方法 #1: Linux kernel にデバイスのリセットを依頼する

これを行うために使用できるツールがいくつかあります。最も高度なツールは usbutilsの一部です。 usbreset.c をダウンロードし、その compilationに gcc を使用します。

$ gcc -O3 -Wall -g usbreset.c -o usbreset

その後:

$ ./usbreset
Usage:
  usbreset PPPP:VVVV - reset by product and vendor id
  usbreset BBB/DDD   - reset by bus and device number
  usbreset "Product" - reset by product name

Devices:
  Number 001/004  ID 045e:07b2  Microsoft® Nano Transceiver v1.0
  Number 001/002  ID 04f3:0103
$ ./usbreset 001/004
Resetting Microsoft® Nano Transceiver v1.0 ... can't open [Permission denied]
$ sudo ./usbreset 001/004
Resetting Microsoft® Nano Transceiver v1.0 ... ok
$ sudo ./usbreset 045e:07b2
Resetting Microsoft® Nano Transceiver v1.0 ... ok

リセットに応じて、 kernel logに次のように表示されます。

usb 1-6: reset full-speed USB device number 4 using xhci_hcd

このセッションの内容:

では、 usbreset は何をするのでしょうか? USB デバイスの device fileでは、次のコマンドに要約されます。

ioctl(fd, USBDEVFS_RESET, 0)

これは、デバイスをリセットするだけでなく、 kernelの usb_reset_device()への関数呼び出しで終わります。アイデアは、プロセス全体をスムーズにすることです。 この関数は、要求があった場合、デバイスの driver にリセットの前後に通知します。リセット前に driver のバインドを解除し、後でバインドし直します。デバイスの configuration もリセット後にロードされます。これがないと、デバイスは bus address を認識できず、データ交換の準備ができません。

つまり、デバイスを再接続するのとほぼ同じですが、(情報が既にわかっているため) デバイス自体の識別を求めたり、新しいアドレスを割り当てたりする必要はありません。

USB 3.xの場合、これは hot resetであり、効率の低いタイプです。 hot reset の詳細については、以下をご覧ください。

方法 #2: USB portの power state を切り替えます

この目的のためのツールもいくつかあります。この方法を hubpowerでデモンストレーションします。 hubpower.cをダウンロードし、 compilationを実行します。

$ gcc -O3 -Wall -g hubpower.c -o hubpower

コマンドが USB デバイス自体に送信されないため、このツールを使用するのはやや複雑です。代わりに、 USB デバイスが接続されている USB hub に要求が送信されます。

したがって、最初のステップは、これがどの hub であるかを把握することです。まず、 USB デバイスのアドレスを見つけてみましょう。

$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 045e:07b2 Microsoft Corp.
Bus 001 Device 002: ID 04f3:0103 Elan Microelectronics Corp. ActiveJet K-2024 Multimedia Keyboard
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

したがって、デバイスは bus number 1 と device number 4にあります。 USB デバイスが列挙されるたびに device number が変更されることに注意してください。

では、 USB デバイスはどの hub に接続されているのでしょうか?そして、どの portに?

$ lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/6p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 480M
    |__ Port 6: Dev 4, If 0, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 6: Dev 4, If 1, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 6: Dev 4, If 2, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 11: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
    |__ Port 11: Dev 2, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M

したがって、デバイス番号 4 は port #6に接続されます。 hubの bus number は 1 で、その device number は 1 です ( root hubとして機能する motherboardの USB controllerです)。

hubpower がこれについて何と言っているか見てみましょう:

$ sudo ./hubpower 1:1 status
Port  1 status: 0100  Power-On
Port  2 status: 0100  Power-On
Port  3 status: 0100  Power-On
Port  4 status: 0100  Power-On
Port  5 status: 0100  Power-On
Port  6 status: 0103  Power-On Enabled Connected
Port  7 status: 0100  Power-On
Port  8 status: 0100  Power-On
Port  9 status: 0100  Power-On
Port 10 status: 0100  Power-On
Port 11 status: 0303  Low-Speed Power-On Enabled Connected
Port 12 status: 0100  Power-On

「1:1」の部分は hubの bus addressであることに注意してください。これが外部 hubの場合、この address は、 hub がコンピューターに接続されるたびに変更されます。

ただし、 ports の番号は変更されません (デバイスが同じ物理 portに接続されている限り)。

デバイスの port numberがわかったら、リセットします。

$ sudo ./hubpower 1:1 power 6 off
Port  6 status: 0000  Power-Off
$ sudo ./hubpower 1:1 power 6 on
Port  6 status: 0100  Power-On

最初のコマンドの後、 kernel logでデバイスが切断されたと報告されます。

usb 1-6: USB disconnect, device number 4

2 番目のコマンドの後、コンピューターはデバイスが物理的に接続されているかのように動作します。

usb 1-6: new full-speed USB device number 5 using xhci_hcd
usb 1-6: New USB device found, idVendor=045e, idProduct=07b2, bcd Device= 7.04
usb 1-6: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-6: Product: Microsoft® Nano Transceiver v1.0
usb 1-6: Manufacturer: Microsoft
[ ... ]

この re-enumerationのため、新しい bus address がデバイスに割り当てられます。

$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 045e:07b2 Microsoft Corp.
Bus 001 Device 002: ID 04f3:0103 Elan Microelectronics Corp. ActiveJet K-2024 Multimedia Keyboard
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

これは USB デバイスを物理的に切断して接続し直すようなものですか?答えは多分: ほとんどの場合、 hubpower コマンドは実際には USB デバイスの電源をオフにしません。したがって、デバイスは引き続き VBUS voltage (5V) を受け取ります。実際に電源をオフにする USB hubs はほとんどありません。これについては、以下で詳しく説明します。

hubsの大部分では、最初のコマンド (「電源オフ」) は port をデバイスを無視する状態にするだけです。2 番目のコマンド (「電源オン」) は port を自然な状態に戻します。デバイスが検出され、その初期化手順が開始されます. とりわけ、デバイスがリセットされて列挙され、その driver がデバイスを初期化します.

そのため、特にデバイスが USB plugから電源供給を受けている場合は、通常、これらのコマンドよりも物理的な切断の方が効果的です。しかし、 hub が実際に VBUSをシャットダウンする場合、 hubpower は効果的です。

この例では、コマンドが motherboardの USB controller ( root hub) に送信されていることに注意してください。その理由は、 USB デバイスがコンピューターに直接接続されていたためです。このデバイスが外部 hubを介してコンピュータに接続されている場合、コマンドはこの外部 hubに送信される必要があります。どちらの場合も、 hubpower は同じように使用されます。

残念ながら、hubpower は USB 3.0 (SuperSpeed) をサポートしていません。詳細については、以下をご覧ください。

2 つの方法の違い

では、2 番目の方法 ( hubpowerを使用) と最初の方法 ( usbresetを使用) はどう違うのでしょうか?デバイスの問題を解決するために、どちらの方法も本質的に同じことを行います。 彼らはリセットコマンドを送信します。これが発生する方法は劇的に異なりますが、おそらく問題を解決するのはおそらくこのリセットコマンドです.

ただし、いくつかの重要な違いがあります。

電装品の制御(?)

このページの主なトピックは USB デバイスの問題を修正する方法ですが、興味深い副作用もあります。 USB portの 5V power supplyを制御できる場合があります。つまり、シンプルで安価な USB hub を使用して、 2.5 Wattsを処理できる power supply のオンとオフを切り替えることができます。

これは、 electromechanical relayを制御するには十分すぎるほどです。したがって、 110V / 220Vで動作する電化製品を制御するために追加する必要があるコンポーネントは 1 つだけです。 USB hub を損傷から保護するために、単純なダイオードも追加することをお勧めします。しかし、それだけです。

残念ながら、 power supply を制御する機能はオプションです。 USB 2.0 仕様のセクション 11.11 によると、 hub には、 port が Powered-Off 状態にあるときに、 5V power supply を port にオフにする power switches がある場合があります。あるいは、 power switch を使用して複数の ports (「ganged power switching」) の電源を制御することもできます。電源を制御する主な目的は、過剰な電流を消費する USB デバイスを遮断して、残りの ports が引き続き正常に動作できるようにすることです。

ただし、既に述べたように、物理的な電力制御はオプションです。 hubpower が実際に行うことは、 portの PORT_POWER 属性の値を変更することです ( USB specificationsでは「feature」と呼ばれます)。この変更は、 hubの portの 2 つの異なる側面に関連しています。

PORT_POWER については、以下で詳しく説明します。

hub は電圧を制御しますか?

hub が実際に電圧をオフにするかどうかは、どうすればわかりますか?確実に知る唯一の方法は、テストすることです。 USB デバイスではなく、 USB portから電力を消費するものを接続します。実際の USB デバイスは混乱を招く可能性があります。たとえば、光学式マウスは通常、 5V 電圧が残っている場合でも、電源オフ コマンドに応答して LED をオフにします。

各 hub は、"lsusb -v" で表示される情報 (仕様のセクション 11.23.2.1 で定義されている Hub Descriptor内) で、電圧を制御するかどうか、およびどのような精度で制御するかを宣言します。 hub は、電圧を制御しないこと、または ports のグループ ("gangs") で電圧を制御すること、または各 port の電圧を個別に制御することを宣言できます。 USB 2.0 仕様のセクション11.11によれば、「a hub with power switches can switch power to all ports as a group/gang, to each port individually, or have an arbitrary number of gangs of one or more ports」。

ただし、この情報は信頼できません。電圧を制御すると宣言している hubs をいくつか見かけましたが、実際に制御しているものはありませんでした。

たとえば、これは「lsusb -v」の出力の

Bus 001 Device 073: ID 0bda:5411 Realtek Semiconductor Corp.
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.10
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         2 TT per port
  bMaxPacketSize0        64
  idVendor           0x0bda Realtek Semiconductor Corp.
  idProduct          0x5411
  bcdDevice            1.23
  iManufacturer           1 Generic
  iProduct                2 4-Port USB 2.0 Hub
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:

[ ... ]

Hub Descriptor:
  bLength               9
  bDescriptorType      41
  nNbrPorts             4
  wHubCharacteristic 0x00a9
    Per-port power switching
    Per-port overcurrent protection
    TT think time 16 FS bits
    Port indicators
  bPwrOn2PwrGood        0 * 2 milli seconds
  bHubContrCurrent    100 milli Ampere
  DeviceRemovable    0x00
  PortPwrCtrlMask    0xff
 Hub Port Status:
   Port 1: 0000.0503 highspeed power enable connect
   Port 2: 0000.0503 highspeed power enable connect
   Port 3: 0000.0100 power
   Port 4: 0000.0100 power

楽観的ですね。実際、この hub は電圧をまったく制御しません。

対照的に、これは単純なマザーボードの hubです。

Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         1 Single TT
  bMaxPacketSize0        64
  idVendor           0x1d6b Linux Foundation
  idProduct          0x0002 2.0 root hub
  bcdDevice            4.15
  iManufacturer           3 Linux 4.15.0-20-generic xhci-hcd
  iProduct                2 xHCI Host Controller
  iSerial                 1 0000:06:00.0
  bNumConfigurations      1
  Configuration Descriptor:

[ ... ]

Hub Descriptor:
  bLength               9
  bDescriptorType      41
  nNbrPorts             2
  wHubCharacteristic 0x000a
    No power switching (usb 1.0)
    Per-port overcurrent protection
    TT think time 8 FS bits
  bPwrOn2PwrGood       10 * 2 milli seconds
  bHubContrCurrent      0 milli Ampere
  DeviceRemovable    0x00
  PortPwrCtrlMask    0xff
 Hub Port Status:
   Port 1: 0000.0100 power
   Port 2: 0000.0100 power
Device Status:     0x0001
  Self Powered

したがって、この hub は、電圧制御をサポートしていないことを認めています。

電源切り替えに関する情報に加えて、各 port に関するステータス情報も「Hub Port Status」としてあることに注意してください。これらの status bits は、 USB 2.0 仕様の表 11-21 (セクション 11.24.2.7.1) で定義されています。これは、 hubpowerによって取得される情報と同じです。

uhubctl ツール

USB hub で relay を制御するというアイデアは、多くのイニシアチブの動機です。主に、このプロジェクトは電圧を制御する USB hubs のリストを維持しているため、 uhubctlを見る価値があります。

このツールは明らかに電圧制御のみを目的としており、 USB デバイスの問題を解決するためのものではありません。たとえば、デフォルトでは、 uhubctl は、 portごとに個別に電圧を制御する機能を宣言していない hubs を無視します。

これらのコマンドは、上記の hubpower コマンドと同等です。

$ sudo ./uhubctl -f -l 1 -p 6 -a 0
Current status for hub 1 [1d6b:0002 Linux 5.16.0 xhci-hcd xHCI Host Controller 0000:00:14.0, USB 2.00, 12 ports, nops]
  Port 6: 0103 power enable connect [045e:07b2 Microsoft Microsoft? Nano Transceiver v1.0]
Sent power off request
New status for hub 1 [1d6b:0002 Linux 5.16.0 xhci-hcd xHCI Host Controller 0000:00:14.0, USB 2.00, 12 ports, nops]
  Port 6: 0000 off
$ sudo ./uhubctl -f -l 1 -p 6 -a 1
Current status for hub 1 [1d6b:0002 Linux 5.16.0 xhci-hcd xHCI Host Controller 0000:00:14.0, USB 2.00, 12 ports, nops]
  Port 6: 0000 off
Sent power on request
New status for hub 1 [1d6b:0002 Linux 5.16.0 xhci-hcd xHCI Host Controller 0000:00:14.0, USB 2.00, 12 ports, nops]
  Port 6: 0100 power

コマンド構文はあまり便利ではありません。以下に簡単に説明します。

uhubctl は libusbに基づいているため、このツールは他のオペレーティング システムでも動作します。対照的に、 hubpower は /dev/bus/usb/ (または /proc/bus/usb/) 内の hubの device file に直接アクセスし、 Linuxでのみ動作します。

uhubctl は USB 3.x もサポートします ( git commitそのフォローアップを参照)。ただし、実際の USB デバイスが hubに接続されたときに何が起こるかは、誰も気にしていないようです。 SuperSpeed デバイスをリセットしようとすると、奇妙な結果になりました。 power が返されたとき、デバイスは Polling 状態のままであり、列挙されませんでした。また、 power がオフの間、「lsusb -v」がスタックしていました。それで、そこで何か悪いことが起こりました。

これらは、 SuperSpeed portで電源をオフにしてから再度オンにするコマンドです。 SuperSpeed の詳細については、以下をご覧ください。

# ./uhubctl -f -e -l 2 -p 4 -a 0
# ./uhubctl -f -e -l 2 -p 4 -a 1

PORT_POWER の説明

host から PORT_POWER をゼロに変更するコマンドが到着すると、 port は無条件に Powered-off 状態に入ります。これは、 hub がデバイスに 5V 電源を供給し続けている場合でも当てはまります。 PORT_POWER がゼロになる理由は他にもあります。特に、 port での overcurrent の状態 (デバイスが大量の電流を消費する) があります。

PORT_POWER を '1' に変更する唯一の方法は、 hostからのコマンドによるものです。これにより、 port が Disconnected 状態になります。何も接続されていない USB ports は、通常、この状態にあります。 portでデバイスが検出されると、少し遅れて状態が Disabled に変わります。デバイスがすでに接続されていて、 PORT_POWER が '1'に変更された場合、これはすぐに発生します。

この状態からデバイスをアクティブ化するための唯一の方法は、 port をリセットすることです ( PORT_RESETの場合、以下を参照)。それができるのは host だけです。したがって、 hub ができる唯一のことは、注意が必要なデバイスが接続されていることを host に通知することです。

これは、 portの status bits の 1 つが登場する場所です。 PORT_CONNECTION. port が Powered-off 状態または Disconnected 状態にある場合、この bit はゼロでなければなりません。 port が Disconnected 状態から Disabled 状態に移行すると、 PORT_CONNECTION は '1' に変化します。 PORT_CONNECTION の変更は hub eventを生成するため、 driver に通知されます (つまり、 kernelの hub.c での port_event() への関数呼び出しは、 USB_PORT_FEAT_C_CONNECTION が有効な状態で行われます)。 driver は、( portの PORT_RESET ビットを '1'に変更することによって) port をリセットし、接続されたデバイスを列挙することで応答します。

これはすべて USB 2.0に関連しています。 USB 2.0 仕様の図 11-10 は、 hubの port がどのように状態を変更するかを示しています。

PORT_RESET と PORT_ENABLE を直接制御する

hubpower には、他の 2 つの属性を直接変更する機能もあります。 PORT_RESET と PORT_ENABLE。実際、私はこのツールの fork にこの機能を追加しました。ただし、これでできることは、故意に USB デバイスを故障させることだけであることに注意してください (したがって、コンピュータにデバイスをリセットさせて修正させます)。より詳細に:

USB 2.0 仕様のセクション 11.5.1.5 に従って port reset を開始するには、 host によってPORT_RESET を '1' に設定する必要があります。 hub は、リセットの完了後に PORT_RESET を '0' に戻します。 hub はそれ自身のイニシアチブで port reset を開始することはなく、 host はこの属性に '0' を書き込むことはできません (セクション 11.24.2.7.1.5)。

port が Powered-off または Disconnected 状態にある場合、この hub は PORT_RESET を無視します。

PORT_ENABLEについて: この属性が '0'に変更されると、 port は Disabled 状態に変更されます。これは、 hostからの要求、 USB デバイスの切断、 port の電源がオフの状態、または reset プロセス中のエラーが原因で発生する可能性があります。

PORT_ENABLE は、 host からの port reset 要求の結果としてのみ '1' に変更できます ( USB 2.0 仕様のセクション 11.24.2.7.1.2)。

したがって、 host は、 PORT_RESET を '0' に変更したり、 PORT_ENABLE を '1'に変更したりすることはできません。これを行おうとすると、 hub からエラー応答が返されます (関連する ioctl() コマンドは error statusを返します)。

hubpower は、 portの PORT_RESET を '1'に変更することにより、直接リセットを要求できます。これにより、 USB デバイスがリセットされ、その結果、デバイスは bus address を忘れます。そのため、デバイスにアクセスできなくなります。

このコマンドは hubに直接送信されるため、 Linux kernel 内の hubの driver はこれが発生したことを知りません。実際、コンピューターは、 USB デバイスにアクセスしようとするまで、何かが変更されたことに気付きません。次に何が起こるかは、デバイスの driverによって異なります。デバイスは、何らかのハードウェア エラーがあるかのように扱われます。したがって、何らかのエラー訂正措置が講じられます。ほとんどの場合、これにはリセットが含まれます。

したがって、 hubpower を使用して直接リセットを行うと、おそらく望ましい結果が得られますが、不必要なドラマがたくさんあります。 PORT_POWER はこれをよりエレガントに行います。直接の PORT_RESET の唯一の利点は、 driver が「このデバイスに何か問題があるので、根本的な解決策を講じましょう」と言う可能性があることです。そして、それは役立つかもしれません。

PORT_ENABLEの操作に関しては、同じことが起こります。 デバイスが突然消えます。この場合でも、コンピューターは何かが起こったことをすぐには認識しません。 USB 2.0 specificationのセクション 11.24.2.7.2.2 によると、 PORT_ENABLE (つまり C_PORT_ENABLE) の変更通知は、リンク上のエラーが原因で port が無効になった場合にのみトリガーされます。仕様では、この通知は他の理由では行われないと明示的に述べています。

したがって、 PORT_ENABLE をゼロに変更すると、 PORT_RESET を直接変更するのとほぼ同じ効果があります。欠点が 1 つあります。 USB 3.0 仕様のセクション 10.14.2.6.1 によれば、 PORT_ENABLE "is not supported by SuperSpeed hubs"。

SuperSpeed (USB 3.x)

何よりもまず: USB 3.x デバイスに問題があるためにこれを読んでいる場合は、 USB 3.x が提供する data rate が本当に必要かどうか自問してください。答えが否定的な場合は、 USB 3.x をサポートしていない USB hub (または短い USB 2.0 ケーブル) を介してデバイスをコンピューターに接続してみてください。これだけで問題が解決する場合があります。

SuperSpeed USB ( USB 3.xと同じ意味) は USB 2.0と並行して共存します。すべての SuperSpeed デバイスは実質的に 2 つのデバイスで構成されています。 SuperSpeed用の 1 つの別個のデバイスと、 USB 2.0用の別の別個のデバイス。これら 2 つの USB versions のそれぞれは、 USB cableの個別のワイヤに依存しています。それらは、電子的にも概念的にも相互に独立しています。

USB 仕様では、すべての SuperSpeed デバイスがこれら 2 つのデバイスで構成されている必要がありますが、これは実際には必要ありません。つまり、 USB 2.0 をサポートしていない SuperSpeed デバイスは、 SuperSpeed portに接続すると正しく動作します。

SuperSpeed デバイスが SuperSpeed portに接続されている場合、最初の試みは SuperSpeed インターフェイスを介した接続です。それが失敗した場合、 USB 2.0 を介した接続が試行されます。実際には (そして仕様によれば)、 USB デバイスは両方のバージョンを同時に接続することはありません。ただし、これは可能であり、 USB デバイスが 2 つの別個のデバイスであるかのように動作します。

SuperSpeed hub は、並列の 2 つの hubs で構成されます。 USB 2.0 用に 1 つ、 SuperSpeed用に 1 つ。外部 SuperSpeed USB hub をコンピューターに接続すると、2 つの hubs がシステムに追加されます。それらは 2 つの別個のデバイスとして表示されます。プレーンな USB デバイスでは、両方のバージョンを並行して使用することはできませんが、 hub ではこれを行う必要があります。

SuperSpeed hub が USB 2.0 portに接続されている場合、通常の USB 2.0 hubのように動作します。

一般に、これら 2 つの hubs はそれぞれ独立して動作します。各 hub には独自の portsがあり、これらの ports はそれぞれ独立して動作します。特に、これらの並列 hubsの 1 つで port のパラメータが変更された場合、これは他の hubの portsには影響しません。

もう 1 つの結論は、「lsusb -t」がデバイスが SuperSpeed root hubを介してコンピュータに接続されていることを示している場合、そのデバイスは SuperSpeed デバイスとして動作するということです。つまり、そのデータレートは 5 Gbit/s 以上です。同様に、このデバイスが USB 2.0 root hubを介して接続されている場合、そのデータ レートは 480 Mbit/s 以下です。

SuperSpeed および PORT_POWER

hubpower が実際に行ったことは、 portの PORT_POWER 属性を変更することだったことを思い出してください。

ただし、 SuperSpeed hub は 2 つの hubs を並列に接続したものです。これら 2 つの hubs にはそれぞれ、 portごとに独自の独立した PORT_POWER 属性があります。では、いつ hub が VBUS powerをオフにすべきでしょうか?各物理 power switch は、並列 hubsのそれぞれから 1 つずつ、2 つの PORT_POWER 属性に依存します。

USB 3.0 specification の表 10-2 は、 hub が電源を有効にするかどうかの真理値表を示しています。次のように要約できます。 hub が USB 2.0 hub としてのみ動作する場合 (たとえば、 SuperSpeedをサポートしていないコンピューターに接続されている場合)、 USB 2.0の PORT_POWERに従います。 SuperSpeed hub として接続されている (または両方の並列 hubs が接続されている) 場合、 VBUS は、両方の PORT_POWER がゼロの場合にのみオフになります。

複雑に聞こえるかもしれませんが、実際には簡単な部分でした。 hub の SuperSpeed 部分には、異なる内部 state machineがあります。 link training は別の方法で行われるため、これは当然のことです。ただし、この state machine には、 PORT_POWER がゼロの場合に適格な 3 つの異なる状態 ( USB 2.0のような 1 つではなく) があります。

最後の 2 つの状態の目的は、独自の電源を備えた SuperSpeed デバイスが portに接続されている場合、接続が USB 2.0にフォールバックしないようにすることです。これは、デバイスが SuperSpeed portに接続されていることを認識する方法がないために発生します。

では、このことから何を学んだでしょうか。主に、 SuperSpeed hub で PORT_POWER を変更してデバイスをリセットすることは、 USB 2.0 hubの場合ほど単純ではありません。

SuperSpeed: warm reset および hot reset

USB 2.0 には、デバイスをリセットする簡単な方法が 1 つあります。 両方のワイヤは、 hub から ground (SE0) に 10 ミリ秒間接続されます。一方、 SuperSpeed デバイスには、デバイスを reset する 2 つの方法があります。 warm reset と hot reset。これらを、リセットの理由を定義するために使用される用語である PowerOn Reset および Inband Resetと混同しないでください。 Inband Reset は、 hostからの要求によりリセットが発生したことを意味します。これにより、リクエストのタイプに応じて、 warm reset または hot resetが発生する可能性があります (詳細は後述)。

warm reset と hot resetを区別することが重要です。 特に、 warm reset では、 data stream を停止して最初から起動する必要があります。 hot reset は data stream 自体に送信され、この data stream を実行し続けます。したがって、 hot reset ははるかに高速ですが、 data stream を再起動することで解決できる問題がある場合は、 warm reset が必要です。このような問題の例として、 physical layer上に bit errors がある場合があります。 bitstream を停止して最初からやり直すと、おそらく equalizerの最適ではないチューニングを修正できるため、これを修正できる可能性があります。

usbreset は USBDEVFS_RESETで ioctl() を実行することを思い出してください。発生する他のすべてのことの中で、これにより、デバイスの USB バージョン ( Linux kernel v5.16の時点) に関係なく、 PORT_RESET がゼロに変更されます。

USB 3.0 仕様のセクション 7.4.2 によると、 PORT_RESET 要求は Hot Resetになります。これは、 data stream がアクティブな場合、解体されず、この data streamでリセット コマンドが送信されることを意味します。この仕様では、 warm reset を強制する BH_PORT_RESET (feature 番号 28) も定義しています ( port が無効になっていない場合)。このリセットはより基本的なものです。 data streamを停止し、再度起動するための手順を再開します ( LFPS signalingのおかげで)。重要な違いは、 data stream の再起動が必要な場合、 BH_PORT_RESET は再起動しますが、 PORT_RESET は再起動しないことです。

新しい SuperSpeed デバイスの接続には、 Warm Resetが含まれます。したがって、 SuperSpeed portで PORT_POWER を操作できるツールがないように見えるのは残念です。前述のように、 uhubctl は技術的にはこれを行うことができますが、デバイスは厄介な状態になります。


残り物

これらは役立つ可能性のあるランダムな情報ですが、適切なコンテキストはありません。

このページは英語から自動翻訳されています。 不明な点は元のページを参照してください。
Copyright © 2021-2024. All rights reserved. (6f913017)