Packet Levelより上位の制御に使われるのがLink Commandである。こちらは文字通りLink Layer同士の制御を行うための専用Packetである。Packet FormatはPhoto01の左側の様に、先頭4Bytesに固定シンボルが入り、その後2BytesにLink Command Wordが2つ入るという仕組みだ。一方Link Command Wordの内部は? というとPhoto01の右側の様に、11bitのLink Command Informationに5bitのCRCが付加される形になっている。このLink Command Wordは同じものを2回送ることになっており、これが一致していなければ無効パケットと判断することになる。
さて、Link Command Informationだが、大きく4つの役割に分かれる。
- (1) パケットの転送に成功したことの通知
- (2) Link Flow Controlの制御
- (3) Link Power Managementの制御
- (4) UPSに対して自身がU0であることの通知(Link Up)
この4種類のコマンドは、Link Command Informationの先頭2bitでまず区分けされ、更にその下位2bitで場合分けされ、最後に最下位の4bitで細かなステータスを伝える事になっている(なぜか4~6bit目はReserved扱い)。
例えば転送成功の場合、7~8bit目は00(LGOOD_n)を示し、0~2bit目がシーケンスナンバーを示す(3bit目はReservedで0)。これにより、シーケンスナンバー0~7のどのパケットが正常に転送されたかを通知できるわけだ。またLink Flow Controlでは、7~8bit目が01(LCRD_x)を示し、0~1bitでHeader Buffer Credit(_A~_D)を示す。7~8bit目が10だと再送(LRTY)、11だとヘッダパケットが不正(LBAD)の意味となる。
もう少しこれの意味を補足しておけば、データが複数パケットに分割されて伝送される事があるので、正常に転送という場合は「何パケット目が転送されたか」まで伝えないと、後で再構成の際に欠落パケットがあってもわかりにくい事になる。そこでパケット転送時には、シーケンス番号にあわせた転送通知が用意されることになる。1パケットのみの転送であれば、したがってシーケンス番号00のLGOOD_0が通知される形だ。
次にFlow Control。ここで(PCI ExpressのFlow Controlを覚えておられる読者には)おなじみのCreditが登場している。詳しくは次回以降で説明するが、USB 3.0では4つのHeader Bufferが用意されており、それぞれHeader Buffer A, B, C, Dと名前が付けられている。受信時にはこのBufferをA, B, C, D, A, B, C, ...とリングバッファの様に使うことになっている。要するにUSB 3.0でもPCI Express同様に、「相手が受信できる(相手の受信バッファに空きがある)」事を確認してから送信する(逆に言えば相手の受信バッファがFullの時には送信しない)という形のFlow Controlを行っている。ただPCI Expressと異なりBufferの数は固定だし、パケットサイズも一定である。またFlow制御はLink Layerで行っている。これは要するに、例えばTransactionレベルの優先パケットといった配慮はUSB 3.0では一切行えないことも意味している。まぁUSB 3.0ではそこまでの配慮は不要だ、と考えたのであろう。
LBADは受信したパケットヘッダのCRCに異常があるなどのケースでの返答、LRTYは実際に再送要求を送る意味となる。このあたりは両者の使い分けがちゃんと規定されている(これも次回以降でもう少し細かく説明する)。
次にPower Managementだが、こちらはLGO_Ux(U1~U3)とLAU/LUX/LPMAという4つのステータスが7~8bit目で定義され、更にLGO_Uxに関しては0~1bit目でどれにあたるかが指定される。LGO_U1~U3は、相手のポートの状態をU1~U3に遷移させる(というか、正確に言えば自分のポートをU1~U3に遷移させることを通知することで、相手側ポートにも遷移してもらう)コマンドとなる。LAUはこのLGO_Uxの受諾通知、LXUはこのLGO_Uxの拒否通知となる。ちなみにDSPからのLGO_U3は受け入れねばならない(LXUを返してはいけない)と定められており、なのでLXUを返せるのはLGO_U1/U2を受け取った場合のみである。LPMAは「状態遷移中」を示すコマンドである。相手側から例えばLGO_U2を受け取った場合、最終的には自身がU2に遷移し終わった時点でUAXを返すことになるが、U0/U1からU2に遷移する間はLPMAを発行し続けることになる。これにより相手側に、自分が現在遷移中であることを知らせる訳だ。
最後のLink Up(LUP)だが、これはUPSがほかに何も送るべきパケットが無い場合、10μs毎に送出することが定められている。いわばHello Messageのようなものである。
(続く)