NRDYの場合はこれでいいが、STALLはどうなるか? というと、これはPhoto01の様にそこでTransactionが終了し、後に続かない。この場合、Deviceが何らかの手段で障害から回復(それはWatchdogを使ってのシステムリセットかもしれないし、あるいはもっと他の方法もあるだろう)したら、再びUSB Deviceとしての初期化を経て通信可能状態(U0 State)に入ることで、再びInterrupt INのTransactionを受けられるようになる。

Photo01: Universal Serial Bus 3.0 SpecificationのFigure 8-38から抜粋

最後が再送である。連載320回で、「通信エラーがあってもRetryは行わない」と書いたが、厳密にはRetryが発生するケースがある。例えばHostとDeviceの間にHubが挟まっていて、このHubに起因する問題が発生した場合である。この場合、HostからDeviceに送られたACK TPにはDeferred bitが立っている事になる。で、これを受けたDeviceが、自身もHostに送るべきデータを持ち合わせている場合、DeviceはHostに対してDPではなくERDY TPを送り返す。これを受け取ったHostは、まだ同じService Intervalの中にいる場合は、Retry bit付きで同じSequence NumberでACK TPを送りなおす。ここでまたDeferred bitが付いていたら繰り返しになるのだが、Hubが無事復調していれば今度はDeferred bitが付かずにDeviceに送られる形になり、これを受けてDeviceはDPを送りなおす、という仕組みだ(Photo02)。勿論ここでRetlyが頻発して、Service Intervalをはみ出してしまう場合はそこで再送は中断。Deviceはそのデータを(必要なら)保持しておき、次のService Intervalに改めて送るという形になる。

Photo02: Universal Serial Bus 3.0 SpecificationのFigure 8-39から抜粋

では逆にInterrupt OUTの場合を見てみたい。実はこれにあたるデバイスが意外と思いつかないのだが(AudioなんかはIsochronousで転送するほうが確実である。もっともこれもデータ量次第だが)。強いて言えば、例えばジョイスティックなどのForce Feedback機能だろうか? あれなどはInterrupt OUT向けではある。

まぁ用途はともかくとしてシーケンスそのものはInterrupt INの場合に良く似ている。Interrupt OUT Transactionが必要とHostが判断した場合、HostはいきなりDPをDeviceに送信する。これが正常に受信できたら、DeviceはACK TPを送って完了となる。ちなみにPhoto03ではあくまでもDPは1つだが、最大3つまでDPを転送することが出来るので、その場合はDP→ACK TPが3セット続いて終了という形になる。

Photo03: Universal Serial Bus 3.0 SpecificationのFigure 8-40から抜粋

また、Host→DeviceのData転送は無事に終わったものの、受け取ったDataの処理に時間が掛かっている、あるいはその他の理由でとにかくこれ以上Dataを受け取れないとか、という場合、DeviceはDPに対してNRDY TPを送り返す(Photo04)というあたりもInterrupt INと共通である。これを受けたHostは、以後そのDeviceに対するInterrupt OUTのTransactionを中止することになる。これが再開されるのは、Deviceが再びデータ受信可能状態になり、それをERDY TPを使ってHostに通知してからとなる(Photo05)。HostはERDY TPを受け取ってから一定期間後に、Interrupt OUTのTransactionを再開するというあたりもInterrupt INと同じである。

Photo04: Universal Serial Bus 3.0 SpecificationのFigure 8-41から抜粋

Photo05: Universal Serial Bus 3.0 SpecificationのFigure 8-42から抜粋

またHostからのDPにDeferred bitが立っていた(理由はInterrupt INの場合同様、Hubの問題などのケースが一番考えやすいだろう)ケースで、しかもDeviceがそのデータを必要としている場合は、DeviceはRetry bitをセットしてACK TPを送り返す(Photo06)。同じService Interval内の場合、Hostは再び同じDPを再送する形となる。Deviceがこれを正常に受信できれば、ACK TPを返して無事終了となるわけだ。ちなみにHubのトラブルが長期化してService Interval内でRetryが終了しなかった場合、そのRetry Transactionはそこで終了であり、次のService Intervalでは新しいInterrupt OUTのTransactionが始まる形となる。

Photo06: Universal Serial Bus 3.0 SpecificationのFigure 8-43から抜粋

また、Device側に(先のNRDY TPの場合よりも)もっと本格的にトラブルが出た場合、DeviceはSTALL TPを送り返すあたりもInterrupt INと同じである。Hostの対処も同じで、以後はそのDeviceに対してInterrupt OUTのサービスを中止することになる。これが再開されるのは、Deviceが障害から回復し、再びUSB Deviceとして通信ができるようになってからであるというのも、Interrupt INと同じである。

Photo07: Universal Serial Bus 3.0 SpecificationのFigure 8-44から抜粋

(続く)