Data-in、Data-outと続き、その後は? というとData-inとData-outが混在したケースの話になる。いわゆるBi-directional Transferである。これがどの程度の頻度で発生するか、というのは想像するしかないが、アプリケーションからはともかくOSレベルだと、あるサービスが設定ファイルやら中間ファイルやらを読みつつ、別のサービスがログを書き出しなんてことは普通にありそうではある。

さてUSB 2.0の場合(Photo01)、最初のシーケンスはこれまでと全く同じである。Commandを受け取ったUAS DriverはITr(Stat)とOTr(CIU)を発行、EHCI Controllerはこれを分解してまずIN(Stat)を発行、NAK(Stat)を受け取った後でOUT(Cmd)とDATA(CUI)を発行し、DeviceからまずCmdのACKを受け取った後に、今度はDATAでWRIUを受け取る。最終的にこのシーケンスで戻ってくるのがWRIUなのは、Photo01ではまずData-outを実施し、その後でData-inを実施するというシーケンスになっているからである。

Photo01: USB Attached SCSI Protocol(UASP) Revision 1.0のFigure 5から抜粋

次いでITr(Stat)と、今度はOTr(Data-Out)をUAS Driverは発行する。これをEHCI ControllerはIN(Stat)の後にOUT(Data-out)をまず発行、次いでDATA(Data-out)でデータそのものを送り出す。Deviceはこの2つを正しく受信したらACK(Data-out)を送り返して、正しく受信できたことをECHI Controllerに通知する。以後データが続く限りこのシーケンスが繰り返されるわけだ。

このデータを送信している「最中に」、ECHI ControllerはIN(Stat)を送り出し、これに対してSIUが返されたら、EHCI ControllerはこれをITc(RRIU)としてUAS Driverに返す。これを受けてUAS Driverは今度はITr(Stat)とITr(Data-In)を発行する。これを受けてEHCI ControllerはまずIN(Stat)、次いでIN(Data-in)を順次発行、これを受けてDeviceはIN(Data-in)の返答という形でDATA(Data-in)を順次送り出し、EHCI ControllerはACK(Data-in)を返す。以後データが続く限り、IN(Data-in)とACK(Data-in)のハンドシェイクが続き、必要なデータを送り終わったあとでもう一度EHCI ControllerがIN(Stat)を送ると、今度はSIUが返される形だ。

結果としてハンドシェイクの後半は、Data-inとData-outが混在して発生することになる。実際にはData-inとData-outでは利用するPipeが異なる(Data-in pipeとData-out pipeの両方が使われる)からハンドシェイクそのものに混乱をきたすことはないが、そうは言ってもEHCIとDevice、両方のControllerは相当忙しいことになる。実際にはこうした状況になるか否か、はEHCI Controllerが定期的に送り出すIN(Stat)のリクエストに対して、DeviceがどのタイミングでDATA(RRIU)を送り返すか、にかかっている。処理能力にゆとりがないDeviceの場合は、Data-outのトランザクションが終わるまではDATA(RRIU)を送り返さない様にインプリメントすれば、単に「Data-out→Data-in」をシーケンシャルに実行しているのと変わらないし、逆に処理能力にゆとりがあれば、早めにDATA(RRIU)を送り返すことでData-outとData-inをオーバーラップさせることが出来る。USB 2.0の場合は共通のデータバスを使うから、USB 3.0の様にData-outとData-inを並行して行うといった形でのスループット向上は望みにくいが、(いくら相対的に遅い)USB 2.0といっても、Data-inなりData-outなりのトランザクション1つだけでバスの使用率が100%になることは難しいので、2つのトランザクションをオーバーラップさせることでバスの使用率をギリギリまで追い込むという形でオーバーヘッドを若干減らすことが可能になるだろう。

話をプロトコルに戻すと、最終的にData-outとData-in、それぞれの転送が終わったタイミングでEHCI ControllerはOTc(Data-out)とITC(Data-in)をそれぞれUAS Driverに返す。更に両方の転送が終わったタイミングでEHCI ControllerはDeviceにIN(Stat)を発行、これに対してDATA(SIU)が返ってきたタイミングで、UAS DriverにITc(SIU)を返す。このITc(SIU)までが返ってきたタイミングでUAS Driverは上位アプリケーションに制御を戻す、という形だ。

プロトコル上で見ると、単にData-outとData-inをシーケンシャルに行った場合と比較して、最初の問い合わせが1回省ける点がやや節約になる。更に上に書いたように、理論上は若干バスの利用率を上げることでオーバーヘッドを更に減らせる可能性があるのが利点となる。