またData StageあるいはStatus StageでSTALL TPが返された場合、以後に続くDP/TPは、全てSTALL TPが返されることになる。これは、再びHostがSETUP TPを送るまで続けられ、SETUP TPを受信したらDeviceはACK TPを送り返すことになる。要するにもう一度Setup Stageからやり直しになるわけだ。ここでHostはACK TPを受け取る事で、Deviceの(STALLを送る理由になった)問題が解決したと判断して、再度Data Stageに遷移する形となる。

ちなみに、STALL TPが返される場合、一般的な解釈は「渡されたリクエストあるいはパラメータをDeviceが理解できなかった」となる(解釈あるいは処理に時間が掛かっており、まだ次のDPあるいはSTATUS TPを受け取る準備が出来ていない場合、NRDY TPが返されるからだ)。

これを使えば、Control Transferを使ってDeviceとのある種のコミュニケーションが可能である。実際、USB 3.0のSpecificationにも"In general, protocol stall indicates that the request or its parameters are not understood by a device and thus provides a mechanism for extending USB requests."とあり、こうした使い方を想定しているようだ。

ちょっと話が逸れるが、例えば汎用のドライバ(Windowsに付属するSVGAドライバなどその格好の例だろう)の場合、初期化ルーチンの先頭でかなり長いDevice Inquire Sequenceが続く。具体的には「AHレジスタにXX、ALレジスタにXXを入れてInt 21Hをcallしたときに、AXレジスタの戻りがZZZならこれ、AAAならこれ、...」といった具合に、殆ど主要なFunctionを総なめする勢いで機能チェックが行われる。

ある特定のハードウェア専用のドライバといっても、内部的には回路あるいはファームウェアのバージョンが変更になるなんていうのは日常茶飯事だから、ものによっては安全を期すために単にどこかに書き込まれた文字列をチェックするだけではなく、(汎用のSVGAドライバほどではないにせよ)「このFunctionがあるか」「このFeatureはあるか」といった事をDeviceとInteractiveに交信しあって確認する必要がでてくる。

こうした通信は、USB Deviceの初期化が終われば勿論簡単に可能だが、Control Transferが行われている最中はまだ初期化が済んでいない(というか、初期化のためにControl Transferを行っている)訳で、通常の通信はまだ出来ない。そこでSETUP TPとACK/STALLを組み合わせる形で、HostとDeviceの間に(簡単ながら)Communicationを取るための手段が提供されている、と考えればいいだろう。

次は、逆にHostからDeviceにControl Transferを送るパターンだ(Photo01)。こちらも本質的には差はない。最初のSETUP TPの設定は、Control Readの場合と全く同じである。唯一異なるのはSETUP TPのbmRequestTypeのFieldで、この7bit目が1ならばControl Read(Device to Host)、0ならばControl Write(Host to Device)と解釈される。今度はHostからでのデータ転送になるので、Data StageはPhoto01が示すようにHostからはいきなりDPが送られ、これを受け取ったDeviceがAck TPを送るという、これまた普通のハンドシェイクとなる。ただControl Readと異なり、最後にACK TPが余分に1個入ることは無い。

Photo01: DeviceがHostからのControl Transferを受け取る(Write)ケース

最後のStatus StageもControl Readと同じである。

続いてはInterrupt Data Transferである。USB 3.0の場合の特徴は、

  • バスプロトコルはBulk Transferにかなり近い。但し、1回のInterval間に許されるBurst Transferは最大3 Packetまでに制限されている。
  • 基本的にはエラーがあってもRetlyは行わない。但し、一時的に転送が滞る(DeviceからNRDT TPが返ってくるなど)場合は、再開する(NRDY TPが返ってくる)まで待つ。
  • 帯域(Maximum Packet Size×Number of Packets)が保障される。
  • Service Intervalが保障される(Hostは必ずService Interval毎に転送を行う)。

といった点が挙げられる。ちなみにUSB 2.0までは、複数Packetに跨って転送する(USB 1.1ではInterrupt Data Transferで利用できる最大Payloadが64Bytesだったので、1 packetに制限されていたが、USB 2.0ではPacketの最大Payloadが1024Bytesで、かつ最大3 PacketまでのBurst Transferが可能だった)場合、ACKは全てのPacketの転送が終わった後で送られる形になっていたが、USB 3.0では毎Packet毎にACK TPを返すようになったのもちょっと異なる点である。まぁ転送速度がざっくり10倍になっているから、ACK TPを返してもそれほどオーバーヘッドは大きくない事と、DP→ACK TPのシーケンスを崩したくなかったためと思われる。

(続く)