ではその6種類のLMPの詳細を見てみたい。

Set Link Function(Photo01)

Photo01: SubTypeの後に7bitのSet Link Function Fieldが設けられただけ。

Portの状態をU0に維持しながら、状態を変化させる際にこれを利用する。といっても、現状では機能は一つだけ。USB Hubからのリクエストを受けるかどうか、の設定である。これは後でHubの議論をするときに出てくる話だが、HubはHubで独自に電源管理を行っているわけで、その場合にHubも状態が変わると自分の配下のデバイスに対して電源状態の通知を行うことになる。で、この通知にPortが従うか、従わないかの設定を行うのがこのFunctionとなる。

具体的には7bitもフィールドが用意されていつつ、実際に使っているのはbit 1のみ(他は全てReserved)。機能はForce_LinkPM_AcceptをAssertするか(Value=1)、De-assertするか(Value=0)のみである。この機能、Portの状態がU0のまま設定を変更でき、かつソフトウェアは直ちにこれを処理することが求められている。ただしこの機能はLinkのPerformanceに重大な影響を及ぼすので、あくまでもファンクションの動作確認やテストの目的のみに使うべきだ、という注釈付きである。

なお余談であるが、この動作はHub側のSetPortFeature(FORECE_LINKPM_ACCEPT) commandに関係しているわけで、こちらを参照せよとSpecificationにあるのだが、手持ちのSpecification(Nov 12, 2008版)では「10.4.2.2章および10.4.2.9章を参照」となっている。ところが実際には10.4.2.6章までしかなく、要するにSpecificationのミスである。最新のErrata(May 20, 2009)でもこれは修正されておらず、今後のErrataで修正されるか、もしくは10.4.2.7章~10.4.2.9章が今後追加されるのかもしれない。

U2 Inactivity Timeout(Photo02)

Photo02: SubTypeの後に8bitのU2 Inactivity Timeout Fieldが追加される。こちらは8bitがフルに使われる。

名前の通り、U2 Timeoutの時間を定めるためのField。これは相手がHubの場合に有効である。Hubの場合、U0の状態において、

U1_TIMEOUT=0, U2_TIMEOUT=0
U1_TIMEOUT>0, U2_TIMEOUT=0
U1_TIMEOUT=0, U2_TIMEOUT>0
U1_TIMEOUT>0, U2_TIMEOUT>0

の4つの状態で振る舞いが変わることが定められており、逆に外部からこれを変更を変更することも出来る。ちなみにここではU2_TIMEOUTの時間の変更であるが、機能的にはU1_TIMEOUTの変更も(USB Hub的には)可能である。

これまた余談であるが、このあたりの詳細は10.14.2.10章(Specificationでは10.14.2.9章になっている)に記述されている。まぁ相手がHubで無い限り通常は無関係なコマンドである。

Veder Device Test(Photo03)

Photo03: SubTypeの後に8bitのVendor Device TestFieldが追加され、更にDWORD 1/2もTest用に開放される

これはもう名前の通り、各ベンダーが自由に使ってよいフィールドになっている。Vendor Device Test Fieldは各ベンダーが自由に定義してよく、またDWORD 1/2の8Bytes分も自由に定義できる。

実際の使い方を考えると、各USB DeviceのベンダがフィールドでDevice Testなどをするときにこれは役に立つだろう。要するにHost機能を持った専用のTest Benchの先にDeviceを接続し、テストをするといったシチュエーションで、逆にそれ以外の状況で使われる事はないだろうと思われる。

Port Capability(Photo04)

Photo04: こちらはポートの機能一覧を取得するためのもの。Link Speedとかは現在は5GT/sで固定だが、将来拡張される場合に備えて用意した(PCIeのLink Speed Fieldみたいなものだろう)と考えられる。

こちらはLink TrainingやInitializationが終了し、Linkが確立した後で「どんな状態なのか」を調べるものとなる。実のところ現状では5GT/sの接続一種類しかないから余り意味はないのだが、例えば今後より高速な規格が決まったときに、どんな状態で接続されているかを調べる必要がでてくるからだ。

フィールドは幾つかあるが、現状で定められているのは、

Link Speed(7bit) : 現状はBit 0のみ使われ、これが1だと5GT/sとなる。Bit1~6はReserved。

Num HP Buffer(8bit) : Header Packet Bufferの数。ただし現在は4(0x04)のみとされている。将来はHeader Packet Bufferの数を増減できるオプションも考えられているのだろう。

Direction(2bit) : これはそのPortがUpstream/Downstream Stateのどちらの状態かを示すもの。Bit 0=1ならば、Downstream State、Bit 1=1ならばUpstream Stateということになる。

TieBreaker(20bit) : これはDirectionに関係する。Linkの片方がUpstream、もう片方がDownstreamであれば、これは通信の方向は一意に決まる。あるいは、例えばどちらもDownstreamとかどちらもUpstereamという状況であれば、これは通信できないだけだ(Specificationでも、この状態は"Not Defined"とされている)。問題は両方のポートがUpstream/DownstreamのどちらでもOKとなっている場合で、この場合は両方の状態が平衡状態(Tie)になっている。そこで、ここで平衡状態を崩してやる(Break)ために使われるのがこのフィールドで、要するに毎回20bitの乱数が入る。で、2つのPortのTieBreaker fieldの値を比較し、大きい値を持つPortがDownstreamとなる、という規則がある。ちなみに、希に両方のPortが同じ値になる可能性があるので、その場合はもう一度Port Capability LMPを送りなおすことになっている。

(続く)