こうした動機を実現すべく、xHCIはどんな構造を取るようになったか、であるがこれをEHCIと比較しながら御紹介したいと思う。Phot01はEHCIの構造の模式図であるが、EHCI自身はごらんの様に、あくまでUSB 2.0の制御のみに関わっている。一応当時の設計について弁護しておけば、当時のプロセス(CPUなどの先端プロセスは130nmが利用可能になり、90nmも射程に入っていたが、チップセットなどではまだ180nm世代が一般的だった)では、あまり多ポートのUSB Controllerを統合するのは無理だった。またUSB 1.1の世代ではUHCIとOHCIが混在していた。こうした状況を勘案すると、EHCIで全部を包括させるよりも、既存のOHCI/UHCIコントローラはそのまま存続させ、そこにEHCIを足す形でUSB 2.0をサポートさせるほうがインプリメントは楽だ、と判断したのも無理ないことではある。

もっともこの結果として、USBD(Universal Bus Driver)には無駄な負荷がかかることになった。あるDeviceが接続される場合、それがUSB 2.0に対応するものならばUHCI/OHCI側に「USB 1.1では接続しないように」という指示を出してEHCIに「USB 2.0で接続するように」というリクエストを出すという作業が、USBDに任されることになってしまったからだ。Photo01ではEHCIの一部がUHCI/OHCIに跨っているが、これはUSBDの指示に応じて実際に物理層の制御を行う部分を指しており、UHCI/OHCIの処理の一部がEHCIに含まれるという意味ではない。

Photo01: EHCI Specification for Universal Serial Bus Revision 1.0のFigure 1-1より抜粋

このあたりを明確にしめしたのがPhoto02である。EHCIとUHCI/OHCIは論理的に分離しており、共通なのはPort Routing Logicのみである。このPort Routing Logicにはポート毎に「このPortはUSB 1.1なのか、2.0なのか」をPort Owner Controlという形で制御しており、このControlがEHCIから出ているというあたりが、(Photo01に示すように)UHCI/OHCIまで一部EHCIの管理が及んでいるという部分だと理解すれば良い。

Photo02: EHCI Specification for Universal Serial Bus Revision 1.0のFigure 1-2より抜粋

この結果として、USBDは当然包括的に配下にぶら下がるDeviceのListを管理するが、EHCDとUHCD/OHCD(Photo02ではCompanion Host Controller Driverとされているところ)は、それぞれ個別に配下のDevice Listを管理するという形になっている。特にUHCI/OHCIの場合、物理的に複数のControllerが存在しており、このController管理までUHCD/OHCDは管理する必要がある。

ではxHCIでは? というのがPhoto03である。これまで説明したとおり、今度はUSB 1.1~3.0の全てをまとめてxHCIで管理するようになった結果、内部は一つのComplexとして表現される形となり、動くドライバもxHCDのみに集約されることになった。少なくともEHCIとUHCI/OHCIが混在するという従来のモデルよりもずっとすっきりした形だ。んではそのComplexの内部は? というのがこちら(Photo04)である。xHCIの場合、内部に複数のBus Instanceを保持しており、これを使って管理することになる。このBus Instanceとは何か? という話であるが、Specificationでは「あくまでもインプリメント次第だが」と断った上で、Bus Instanceは内部に帯域やDevice Accessibilityをなどを保持するリソースであるとしている。このInstanceは、基本的には転送するDevice毎に出現する。ちょっと後の章であるが、例えば8ポートのxHCIコントローラがあり、ここにUSB 3.0 Deviceが1個、USB 2.0 Deviceが2つ、USB 1.1 Deviceが4つぶら下がっている状態では、xHCI内部にはSS BI(SuperSpeed Bus Instance)が1つ、HS BI(HighSpeed Bus Instance)が2つ、LS/FS BI(Low Speed/High Speed Bus Instance)が4つで合計7つのUSB BIが保持されており、内部の管理(例えば物理的なポートのマッピングとか帯域管理など)はこのUSB BI単位で行う事になっている。ちなみに誤解を招かないように書いておけば、BIはDevice単位ではない。例えばあるポートにUSB Hub経由で複数Deviceを接続した場合、そのHub(とHubにぶら下がる全てのDevice)は1つのBIで管理されることになる(*1)。

Photo03: xHCI Interface for USB Revision 1.0のFigure 1より抜粋

Photo04: xHCI Interface for USB Revision 1.0のFigure 2より抜粋

ちなみにSpecificationにも但し書きとしてPhoto02は実際のxHCIのインプリメントを示したものではないが、xHCIの機能を判りやすく示すのには有用であるとの注意書きがある。実際、物理的にこんなInstanceを内部にレジスタの様な形で実装しているとは限らない。

(*1)例えばUSB 3.0ポートにUSB 3.0のHubをぶら下げ、その下にUSB 3.0 DeviceとUSB 2.0 Deviceを混在した場合にどうなるか? というのはなかなか興味深い。この場合、理論上はそのポートはSS BIとHS BIが1つづつ割り当てられる形になる。これは例えばUSB 2.0 Hubをぶら下げ、そこにUSB 2.0 DeviceとUSB 1.1 Deviceをぶら下げた場合も同じである。つまりポートとBIは1:1対応するわけでもない事になる。