窓辺の小石 第152回 Surfin′ USB
いまでは、何も考えることなく、USBコネクタを接続すれば、ほとんどの周辺機器はそのまま動く。1980年台、IBM PCが登場した頃、コンピュータにデバイスを接続するのは、簡単なことではなかった。というのも、インターフェースが利用するアドレスや割り込み番号などの「資源」をユーザーがすべて管理しなければならなかった。8 bit時代は、周辺機器は原則、メーカー純正品とその互換品しかなく、メーカーが資源の割り当てを管理していたが、IBM PCでは、多数のサードパーティが拡張ボードを販売し、純正品には存在しないものも多数あった。このため、資源の割り当ては誰も管理しておらず、インターフェースボード側で選択を行い、衝突を避ける必要があった。
ここに目を付けたのかどうかは、分からないが、この頃インテルはCPUという部品を提供するメーカーからPC互換機というプラットフォームを提供する半導体メーカーに変貌する。そのための技術が、PCI(1991年)とUSB(1996年)であり、これらを組み込んだ自社開発のチップセットである。
USBは、1995年にCompaq、DEC、IBM、Microsoft、NEC、NortelとIntelによって開発が始まった、とWikipediaなどに記載があるが、実際には、それ以前からインテル内部で開発が行われていて、最初のデバイスが完成していた。最初のUSB仕様は、翌1996年に公開されたが、仕様書の改版履歴を見ると、業界団体(USB-IF)の結成以前である1994年の段階でRevision 0.7となっていて、これ以前から仕様書の作成が行われていたことがわかる(写真01)。
写真01: USB 1.0の仕様書にある改版履歴。USB 1.0のリリースは写真にあるように1996年1月だが、すでに1994年11月にリビジョン0.7が0.6eの後継として作成されている。つまり、仕様書自体1994年11月以前から作成されていたわけで、1995年のUSB-IFの成立以前から開発が進んでいたことを示す
WindowsのUSB対応は、1996年のWindows 95 OSR 2(OEM Service Release Ver.2)からだが、当時、USBデバイスも少なければ、限られたUSBデバイスもちゃんと動かなかった。まともに動くようになったのは1999年のWindows 98 SE(Second Edition)あたりからだ。一説には、IntelとMicrosoftがUSBコントローラーの仕様で対立したせいだともいう。
このUSBだが、かつては、デバイスマネージャーを使わないと、接続しているデバイスを調べることもできなかったが、現在では、PowerShellなどで、簡単に情報を取得できる。
USBデバイスを調べる方法としては、
WMIのWin32_PNPEntityクラス
PowerShellのGet-PNPDevice、Get-PnpDevicePropertyコマンド
レジストリのHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum
がある。WMIのWin32_PNPEntityクラスとGet-PNPDeviceコマンドはほとんど同じ。デバイスマネージャーと同じくUSB以外のデバイスを含む。特定の種類のデバイスを取り出すにはClassプロパティを使う。クラスの定義は、レジストリ「HKLM:\SYSTEM\CurrentControlSet\Control\Class」以下にある。キーがClassGUID(重複あり)で、その下のClassにクラス名がある。
Windowsでは、USBデバイスのうちいくつかを別扱いしている。USBとHID(Human Interface Class)はクラスが異なり、キーボード、マウス(ポインティングデバイス)はHIDとも別扱いだ。HIDが別扱いなのは、USBだけでなくBluetoothやデバイスバス(I2CやSPI、GPIOなど)といった「HIDトランスポート」(バス)上でも使われるからだ。キーボード、マウス、ストレージがHIDとはさらに別になっているのは、USB登場以前から存在したデバイスの管理機構のそれぞれでUSBデバイスを扱わせたからである。
すべてのUSBデバイスのDeviceIDは、ホストコントローラーとデバイスの親子関係を示すWMIのWin32_USBControllerDeviceで列挙できる。ただし、ここにはDeviceIDしか情報がないため、前述のコマンドなどでデバイスの情報を取り出す。
まずは、Win32_USBControllerDeviceからDeviceIDのリストを作る(1行目)。ただし、Bluetoothコントローラーの下にあるソフトウェアデバイスなども含まれてしまうため、DeviceIDの先頭が「BTH」になっているものを落とす。
$USB=(Get-CimInstance Win32_USBControllerDevice).Dependent.DeviceID | ? {$_ -notlike 'BTH*' }
簡易には、Get-PnpDeviceコマンドを使って以下のように情報を得ることができる。
$USB | %{ Get-PnpDevice -InstanceId $_ } | select * |Out-GridView
Get-PnpDevicePropertyでは、さらに詳細な情報を得ることもできる。ただ、このコマンドの出力はプロパティごとにオブジェクトになっており、1つのデバイスについて多数のオブジェクトを生成する。なので、デバイスごとにPSCustomObjectを作り、プロパティを追加していく。
$USB | %{ $id=$_ ; $r=[pscustomobject]@{deviceid=$id}; Get-PnpDeviceProperty -InstanceId $id | %{$r | Add-Member -NotePropertyName $_.keyname -NotePropertyValue $_.data}; $r} | Out-GridView
Linuxには、「lshw」、「lsusb」、「lspci」などのコマンドがあり、元になる情報が/proc、/sys、/devファイルシステムにある。ただ、WSLやChromebookのLinux環境は仮想マシンなので、実機にインストールされたLinuxで実行しないと面白みがない。
今回のタイトルネタは、The Beach Boysのアルバム名でありタイトル曲の「Surfin' U.S.A.」(1963年)である。日本で若大将がハワイに行ってサーフィンするのが、この曲が流行った頃。筆者は、ネットサーフィンならやったことはあるが、ホントのサーフィンなんぞ、やったこともない。しかし、自分とはまったく無関係の遠い世界の物事のようには感じないのは、この音楽のせいかもしれない。