• Compliance Mode

Stateの最後はこのCompliance Modeである。これはPolling stateからのみ遷移できるもので、Substateも一切持たない。

Compliance Modeは、Polling.LFPSで最初のLFPSのハンドシェイクがTimeoutした場合に遷移する。LPFSのハンドシェイクに失敗した、という場合は例えば相手が突然ダウンしたとかケーブルが抜けたとかの可能性も勿論あるわけだが、そもそもPolling.LFPSはこちらの遷移図でも判るとおり、まずRx.Detectで相手と通信可能な状態であることを確認の上で、それではLFPSを使ってハンドシェイクを始めようという状態だから、Rx.Detect.ActiveからPolling.LFPSに移るわずかな間に相手あるいはLinkに異常が発生する可能性は0ではないにせよ、非常に乏しい。むしろありそうなのは、電圧が合っていないとかタイミングがずれているといった可能性である。

そこでCompliance Modeでは、

  • まず受信電圧が規定値に入るのを待つ
  • 規定値に入ったのを確認後、Compliance Test Patternとして定義されているシンボル列をお互いに送りあう
  • これに成功したらPing.LFPSのパターンを相互に送りあう

という処理を行う。相互にPing.LFPSの送受信に成功したら、そのままWarm Resetに入り、再びRx.Detectに戻る形になる。要するにRx.Detectからもう一度仕切りなおす訳だ。

ということで、ここまでLTSSMの説明を延々と行ってきたが、これはLink Layerの仕事の一番下位、初期化やエラー処理などの、Linkという論理構造を保持するための作業になる。で、通常の通信時は? というとLTSSM的にはU0に入ったままということになるが、Link LayerはこのU0の中でも色々な処理を行っている。その概略は293回にも書いたとおりであるが、今回からはこのあたりをもう少し説明してゆきたい。

USB 3.0ではPCI Expressとかと同じように、フロー制御を含む制御コマンド類をすべてPacket化して送受信することになる。このため、Link制御に関しても、やはり独自のコマンド((Link Command)を定義して、これを使って管理するほか、より詳細な管理に関しては専用パケットも用意される。ただ、すべての管理を別パケットにしていると都合が悪い(というか、オーバーヘッドが馬鹿にならない)事も多い。そこで、

  • Link Control Word:各PacketのPacket Header中に存在。Packet単位の管理
  • Link Command(LC):Linkの下位レベルの制御
  • Link Management Packet(LMP):Linkの上位レベルの制御

という3種類が用意され、これらを組み合わせることで制御を行っている。

Photo01はPacket HeaderとLink Control Wordの構造である。USB 3.0では基本的に全ての通信がPacket化されるわけだが、上に示したLMP以外にTransaction Layerの制御のためのTP(Transaction Packet)、USB Hostから時間同期のために使われるITP(Isochronous Timestamp Packet)、それとデータの転送に使われるDP(Data Packet)の合計4種類のPacketが存在する。これらのすべてのPacketには、Photo01右側に示される20BytesのFormatのHeaderが付加される。

Photo01: これはSuperSpeed USB Developer ConferenceにおけるSue Vining氏のプレゼンテーションより。Specificationと同じ図なのだが、2つの図が1ページにまとまっているので判りやすい。

ちなみにここで、

SHP : Start Header Packet
EPF : End Packet Framing

で、これはあらかじめ定められたシンボルである。LSBの方から先に送信されるので、要するにSHPが3回続き、EPFがこれに続く事で、ここがPacket Headerであることが確認できるというものだ。これに続く12BytesはHeader Information、その後に2BytesのCRCを挟み、最後にLink Control Wordが付加される形だ。このHeader Informationなどの詳細は後回しにするとして、最後の2byteを占めるのが、Link Control Wordである。これは例えば長大なデータ転送を行う場合、それが複数Packetに分割される場合が当然ありえるし、間にHubなどを介するとそれが正しい順に到着するという保障はない(このあたりはTCP/IPのPacketと考え方は一緒である)。

そこで連番を付けることで順序を明確にしようというのがHeader Sequenceである。Delayedは、Packetの再送が行われたか、もしくは転送がDelayしていることを示すもの。Hub DepthとかDeferredは、いずれもUSB Hubが入る事が前提のFieldである。Deferredは、Hubの先に繋がったDeviceがLow Power stateに入っている場合にHubが付加するもので、Hub Depthはその際のHubの深さを示すものとなっている。ちなみにHub Depthは0~4までしか値を取れないことになっている。

こうしたレベルの制御はやはりPacket単位となるから、いちいち別Packetを用意すると無駄が多すぎるということで、Packet Headerの中に含めるようにしたようだ。

(続く)