PCIデバイスの自動検出を

いろいろネットで調べていると、どうやら/proc/pciの情報はアテにならないらしい。カーネルのバージョンアップで消されるかもしれないと。
実際、私が使っているカーネルが出力する/proc/pciは、標準的カーネルが出力する/proc/pciと全然違うことが判明した。どうやらMandrivaがカーネルにパッチを当てているらしい。うかつであったがな。


↓これが私が使っているカーネルの/proc/pci。マシンはParallels仮想マシンなので、全部エミュレートされたデバイス。

PCI devices found:
  Bus  0, device   2, function  0:
    Class 0300: PCI device aaaa:1121 (rev 0).
      I/O at 0xff00 [0xff0f].
      Non-prefetchable 32 bit memory at 0xc0000000 [0xffffffff].
  Bus  0, device   3, function  0:
    Class 0680: PCI device aaaa:1112 (rev 0).
      IRQ 9.
      I/O at 0x1040 [0x105f].
  Bus  0, device   5, function  0:
    Class 0200: PCI device 10ec:8029 (rev 0).
      IRQ 10.
      I/O at 0x1080 [0x109f].
  Bus  0, device  30, function  0:
    Class 0600: PCI device 8086:1130 (rev 2).
      Prefetchable 32 bit memory at 0x84000000 [0x87ffffff].
  Bus  0, device  31, function  0:
    Class 0601: PCI device 8086:2440 (rev 8).
  Bus  0, device  31, function  1:
    Class 0101: PCI device 8086:244b (rev 0).
      I/O at 0x10c0 [0x10cf].


http://people.debian.org/~wouter/laptop/node20.html より

PCI devices found:
  Bus  0, device   0, function  0:
    Host bridge: PCI device 10b9:1644 (Acer Laboratories Inc. [ALi]) (rev 1).
      Prefetchable 32 bit memory at 0xf0000000 [0xf3ffffff].
  Bus  0, device   1, function  0:
    PCI bridge: Acer Laboratories Inc. [ALi] M5247 (rev 0).
      Master Capable.  No bursts.  Min Gnt=8.
  Bus  0, device   2, function  0:
    USB Controller: Acer Laboratories Inc. [ALi] M5237 USB (rev 3).
      IRQ 11.
      Master Capable.  Latency=64.  Max Lat=80.
      Non-prefetchable 32 bit memory at 0xf7eff000 [0xf7efffff].
  Bus  0, device   4, function  0:
    IDE interface: Acer Laboratories Inc. [ALi] M5229 IDE (rev 195).
      Master Capable.  Latency=64.  Min Gnt=2.Max Lat=4.
      I/O at 0xeff0 [0xefff].
(以下省略)


普通のカーネルではClassやDevice IDの16進の数値は表示されないで、代わりにそのIDに対応する名前が出てきてしまう。実際に確認。
ということで、数日前に作ったSimpleDetectPCIは、使い物にならないと。なんてこった。


どうする。思いついた選択肢は3つ。

  1. /proc/bus/pciを使う
  2. /sys/bus/pci/devicesと/sys/bus/pci_express/devicesを使う
  3. pciutilsを使う

/proc/bus/pciは、ファイルではなくディレクトリで、中にdevicesというファイルと、( "%02x/%02.%x", バス番号, 良くわからない番号 良くわからない番号2 )(00/1f.1とか)というバイナリなファイルが入っている。devicesにはバス番号とVendor IDとDevice IDと良くわからない番号が並んでいて、それに対応したバイナリなファイルを読み込むと、ClassやSubvendor IDなどもわかるという仕掛けになっている模様。

/sys/bus/pci/devices/ディレクトリ以下には、良くわからない番号:バス番号:良くわからない番号:良くわからない番号というディレクトリが並んでいて、その中にvendor、device、class、subsystem_vendor、subsystem_deviceといったファイルが入っている。

pciutilsを使うなんてのは負けに違いない!


結局、pciutilsは使わないけど、pciutilsと同じく/proc/bus/pciを使うことにする。/sys/bus/pciはファイルをたくさん開かないといけないので面倒っぽい。/proc/bus/pciの方もバイナリファイルがあって面倒だけど。
/proc/bus/pci/devicesを読むと、まずPCIカードが刺さっているバスの情報がわかる模様。


※書きかけ書きかけ