こうした転送方式の違いは、様々な転送に影響してくる。まずはControl Transfer。Control TransferはApplicationとかDriverなどのSoftwareと、USB Device内のFunction(特定の機能)の間でConfiguration/Command/Statusといったメッセージを取り交わすための転送である。全てのDeviceはこのControl Transferをサポートする事が義務付けられている。
USB 2.0ではHost→DeviceやDevice→HostのControl Transferにおけるデータの転送やその取り扱い方式が事細かに決められているが、これらについてはUSB 3.0でも基本的には変わっていない。ただし幾つかの相違点は当然あり、
- USB 2.0においては、Control TransferのBandwidthについて、これをDeviceあるいはSoftwareが明示的に指定するといった事は出来なかった。USB 3.0についてもこれは同じだが、Bandwidthに関してはBest effortを提供できるような仕組みが入った。これに伴い、Control TransferのData Payload sizeの最大値は512Byte固定となり、また全てのDeviceはDevice DescriptorのbMaxPacketSizeに09Hを入れる事が必須となった
- 複数のEndpointで、Control/Bulk Transferが待機状態にある場合、Host ControllerはFair access policyに従ってControl Transferから優先的に処理する(ただしこの際のpolicyの実装はHost Controllerの実装に依存
となっている。
2番目の項目が意味不明かもしれないが、USB 2.0まではそもそもHost ControllerがRound Robin方式に全Endpointを一定のTime Slot間隔でサーチして、そこで順次処理をするという方式だったから、そもそもControl/Bulk TransferのPendingという事態そのものが発生しなかった訳で、非同期にEndpoint→HostにNotificationを送れるUSB 3.0ならではの追加とも言える。
またBulk Transferについても変更がある。Bulk Transferは大量のデータ転送(HDDの接続などその好例だろう)とかStreaming(USB Speakerとか、最近だとUSB TV Tunerなどがこれにあたるだろう)に向いた転送方式で、USB 3.0でもこの方式を当然サポートしている訳だが、基本的な特徴である、
- Bandwidth-available basis(転送の中で最もPriorityが低いので、帯域が余って居れば高速に転送できるが保障されない)
- データの転送そのものは保障されるが、BandwidthやLatencyは一切保障なし
はそのまま継承している。
では何が変わったかというと、まずUSB 2.0ではBus Errorなどの場合にProtocol LevelでTransfer Retryがサポートされていたが、USB 3.0ではProtocol LevelではError Freeが保障される形になった。これはLink LayerでError DetectionとかRetryがサポートされるので、Protocolでは考える必要がなくなったということだ。
また大きな追加点として、Protocol LevelでMulti-stream modelをサポートするようになった事が挙げられよう。これまでは、複数のStream Deviceを1つのHost Controllerにぶら下げる場合、素性が悪いデバイスだと2つ目のDeviceを繋いだ瞬間に転送がまともに行われなくなったりするケースがあったが、USB 3.0ではこうした問題への解決に一歩前進した形だ。
Photo01はこのMulti-streamの模式図である。HostとDeviceは、Stream TransferのHandshakeを行うが、この際にStream IDと呼ばれるUnique IDをそのHandshake毎に割り当てる形になる。FunctionあるいはEndpointは、従来と同様にStream PIPEに対してデータを送出あるいはStream PIPEからデータを受け取る形になるが、これまではStream PIPEがController Domain全体で一つだったのが、今度は仮想的に複数持てるようになった、という事だ。
実体としては、Stream PIPEの前後にMUX/DEMUXを配して、
MUX : パケットにStreamIDで紐付けする
DEMUX : パケットのStreamIDを元に分配する
という事になる。このMUX/DEMUXは、共通のCStreamID(Current StreamID)を持ち、これで現在どのStreamIDのパケットを処理するか管理する、というわけだ。
(続く)