具体的には、Route Stringと呼ばれるものがこれを管理することになっている(Photo01)。Route Stringは20bitのフィールドで、これが4bitづつ5つに分かれている。

Photo01: 図で、右端にあるフォルダアイコン型のUSBデバイスの場合、Route Stringは0x0003となる。

Photo01の図はちょっと誤解しそうではあるが、最初に接続設定を行う場合、上の2つのHub(Hub Depth=0)にはRoute String=0x0000が渡される。これを受けて、左上のHubは自分のDownstreamに対して、左から0x0001,0x0002,0x0003,...と、右上のHubもやっぱり0x0001,0x0002,0x0003,...とRoute Stringを振って行く。このため、右端のフォルダアイコンに渡されるのは0x0003となるわけだ。

他方、左側のTreeはHub Depth 1でRoute Stringが更新される。左端のものは0x0002が渡されるので、自分のDownstreamに対しては左から0x0012,0x0022,0x0032,...と、その右にあるHubは0x0003を渡されるので、Downstreamに対しては0x0013,0x0023,0x0033,...とRoute Stringを割り振るわけだ。

「あれ? これだとRoute Stringが重なるのでは?」と思われるかもしれないが、実は重ならない。この図がちょっとまずいのは、まるでHost Controllerが1つ(というか、まとめて管理される)に誤解されやすいからで、実際はこんな具合になっている(図1)。

つまりHost Controllerが別々になっており、片方にはHubとUSB Deviceが1つ、もう片方にはHubが3つとUSB Deviceが3つぶら下がっており、この2つは別々のTreeとして管理されることになる。実はこうした、複数のコントローラが搭載されているというケースはUSB 3.0が初めてではない、というか以前から存在した。

Photo02はICH10のUSBコントローラの状態を示したものだ。ICH10はUSBを合計12ポートカバーするが、中身をみるとこんな具合にUSB 2.0のEHCIコントローラが2つとUHCIコントローラが6つ、Root Hubが8つ配されている(それ以外の2つのUSB Composite DeviceはUSBキーボードとUSBマウス、Generic USB Hubは使っているKVMスイッチに内蔵されたHubで、ICH10とは直接関係ない)。

Photo02: これはX58+ICH10のマザーボード(Intel DX58SO)にWindows 7を導入した環境での結果だが、別にWindows 7でなくてもこんな感じで表示されるはずだ。

この中身はどんな具合か? というと、図2の様な構図である。1つのUSBコントローラに全部のデバイスが繋がっている訳ではなく、内部で細かく分割されている訳だ。だから、例えば図2でPort #6とPort #7にそれぞれUSB Deviceを接続した場合、各々は別々に管理されることになる(もっともこの言い方も難しくて、管理構造の最上位であるOSのレベルでは、複数のUSBコントローラとその配下に繋がるUSBデバイスを一つのUSB Classで管理しているから、例えばデバイスマネージャで見ると一緒になっているように見える)。ただ、実際にドライバレベルで見た場合、コントローラ毎にデバイスツリーが分離されているわけだ。

話をUSB 3.0に戻すと、こちらも同じ仕組みで管理される。つまりフォルダアイコン型デバイスはUSB Host #1の0x00003、指型デバイスはHost #2の0x00022という具合に、ユニークなRoute Stringがつく形で管理される。

これを使えば、例えばPCが苺型のデバイスにアクセスしたい場合、USB Host #2の0x00013を指定すれば良い。この場合、まずUSB Host #2からHub Aにパケットが飛ぶが、USB Hub AはRoute Stringを見てポート #3にのみパケットを送り出す。次いでUSB Hub DはやはりRoute Stringを見て、ポート #1にのみパケットを送り出し、最終的に無事苺型デバイスにパケットが届くという仕組みだ。これならば無駄にパケットがデバイスツリー全体に送り出される事もない。

この方式の欠点は、各USB Hostが自分の配下にあるUSB Deviceとそのツリー構造を保持しておく必要があることだ。つまり、USB Deviceの抜き差しが発生するたびに、何がどう変化したか(それもどのHubのどのポートに何が着脱されたか、というレベル)を把握しなければならない事だ。ただ、Ethernetなどの場合は台数が半端じゃないし、N対Nの通信になるから、これを真面目に実装したら大変な事になるが、USB 3.0の場合は所詮1対Nの通信だから、Hostだけが頑張れば済むというあたりでこれが許容されたのだろう。

もう一つの制限は、このRoute Stringが事実上のデバイスの制限になることだ。Route Stringで0はUpstream Portを意味するので、USB HubのDownstream番号は0001~1111までの合計15となる。またHubの段数は最大5段までに制限されることになる。もっとも、これが本当に何らかの制約になるかといえば、まずならないだろう。Hubを5段以上カスケードするというシチュエーションがまず想像しにくいし、最大のDevice数は15^5=759,375個となる。これで不足するというケースもありえないだろう。

(続く)