イニシエーター(ホスト)とレスポンダー(デバイス)は相互にPTP通信を行う前に、USBバスをStill Image Capture Deviceクラスで使えるようにしておく必要があります。これはUSBで規定されるバスリセットやコントロール転送を使ったデバイスのコンフィグレーションのプロセスを介して行われます。
USBのコンフィグレーションは次のような手順で行われます(Windows XPの例)。
デバイスがバスに接続されると、ホストはバスリセットを行います。
ホストがGetDescriptor(DeviceType)リクエストを送ってデバイス・ディスクリプタを64バイト要求します。USB 2.0ではデバイス ディスクリプタのサイズは18バイト固定なので18バイトを要求しても良さそうですが、今後のUSB仕様では必ずしも18バイトであるとは限らないかも知れません。そこでまずはディスクリプタサイズ(bLength)やUSBバージョン(bcdUSB)などが含まれるであろう適当なサイズとして64バイトを指定していると思われます。USB 2.0デバイスは当然ショート・パケット(18バイト)を返すことになります。
Windows XPの場合、ホストはここで再びバスリセットを行います。
ホストはSetAddress()リクエストを使ってデバイスにデバイスアドレスを設定します。これ以降ホストは、(USB上は)ここで設定したデバイスアドレスを使ってデバイスにアクセスします。
①で知り得たディスクリプタサイズ(bLength=0x12)を使って再度デバイス ディスクリプタを取得します。
コンフィグレーション ディスクリプタとこれに関連するディスクリプタ(インターフェース, エンドポイント・ディスクリプタなど)の総バイト数を取得します。ホストはGetDescriptor(ConfigurationType)リクエストを使って最初の9バイトを(コンフィグレーション ディスクリプタ)を取得します。このリクエストの目的である「総バイト数」は、コンフィグレーション ディスクリプタの先頭から2バイト目(wTotalLengthフィールド)に格納されています。
⑥で知り得た「総バイト数」(wTotalLength)とGetDescriptor(ConfigurationType)リクエストを使って、コンフィグレーション ディスクリプタとこれに関連するディスクリプタを取得します。GetDescriptorリクエストでデバイスは、コンフィグレーション ディスクリプタ、インターフェース ディスクリプタ、エンドポイント ディスクリプタの順にデータを返します。
ベンダー名や製品名などの文字列情報はストリングディスクリプタに格納されます。文字列は複数の言語ごとに用意することができます。デバイスはストリングディスクリプタ内でどのような言語がサポートされるか、USB-IFで定義されるLanguageIDのリストを返すことでホストに示します。これを調べるために、ホストはGetDescriptor()リクエストでディスクリプタタイプ=stringType、 wIndex=0を指定します。
⑧で知り得たLanguageIDとデバイス ディスクリプタやコンフィグレーション ディスクリプタなどに格納されていたストリングディスクリプタへのインデックス値を使って、ストリングディスクリプタからベンダー名や製品名などの文字列を取得します。このためにホストはGetDescriptor()リクエストでディスクリプタタイプ=stringType、 wIndex=文字列へのインデックス値を指定します。
これまでに取得したディスクリプタの情報をもとに、ホストはSetConfiguration()リクエストを使ってデバイスの提供するコンフィグレーショの一つ(Still Image Capture Deviceクラス)を選びます。これ以降、PTP上での通信が可能となります。