Linux プラグ&プレイ・ドキュメント Adam Belay 最終更新日: 2002 年 10 月 16 日 -------------------------------------------------------------------------------- 概要 ---- プラグ&プレイは、レガシーデバイスまたは設定不可デバイスを検出し、それら 用のリソースをセットする手段を提供します。Linux プラグ&プレイ・レイヤは、 互換ドライバに対して、これらのサービスを提供します。 ユーザインターフェース ---------------------- Linux プラグ&プレイのユーザインターフェースは、Linux プラグ&プレイを サポートしないレガシーデバイスとユーザレベルドライバに、PnP デバイスを アクティベートする手段を提供します。ユーザインターフェースは、driverfs に統合されています。 標準の driverfs ファイルに加えて、次のファイルも、各デバイス用ディレク トリ内に作成されます。 id - サポート EISA ID のリストを表示する options - 可能なリソース設定を表示する resources - 現在割り当てられているリソースの表示、リソースの変更が可能 - デバイスをアクティベートする # echo "auto" > resources これにより、デバイスをアクティベートするために自動リソース設定システムが 起動されます。 - 手動でデバイスをアクティベートする # echo "manual " > resources - 設定番号 - static または dynamic static = 次回のブート用 dynamic = 今すぐ - デバイスを無効化する # echo "disable" > resources 例: フロッピーディスクコントローラをアクティベートする必要があるとします。 1.) 適切なディレクトリに移動します。私の場合は /driver/bus/pnp/devices/00:0f # cd /driver/bus/pnp/devices/00:0f # cat name PC standard floppy disk controller 2.) デバイスが既にアクティブかどうかチェックします。 # cat resources DISABLED - 文字列 "DISABLED" に注目してください。これは、デバイスがアクティブ ではないことを意味します。 3.) デバイスの可能な設定をチェックしてください (任意) # cat options Dependent: 01 - Priority acceptable port 0x3f0-0x3f0, align 0x7, size 0x6, 16-bit address decoding port 0x3f7-0x3f7, align 0x0, size 0x1, 16-bit address decoding irq 6 dma 2 8-bit compatible Dependent: 02 - Priority acceptable port 0x370-0x370, align 0x7, size 0x6, 16-bit address decoding port 0x377-0x377, align 0x0, size 0x1, 16-bit address decoding irq 6 dma 2 8-bit compatible 4.) ここで、デバイスをアクティベートします。 # echo "auto" > resources 5.) 最後に、デバイスがアクティブかどうかチェックします。 # cat resources io 0x3f0-0x3f5 io 0x3f7-0x3f7 irq 6 dma 2 また、一連のカーネルパラメータがあります。 allowdma0 pnp_reserve_irq=irq1[,irq2] .... pnp_reserve_dma=dma1[,dma2] .... pnp_reserve_io=io1,size1[,io2,size2] .... pnp_reserve_mem=mem1,size1[,mem2,size2] .... 統合されたプラグ&プレイ・レイヤ -------------------------------- 全てのプラグ&プレイ・ドライバ、プロトコル、サービスは、プラグ&プレイ・ レイヤと呼ばれる中枢部分で繋がっています。PnP ドライバと PnP プロトコル 間の情報のやりとりは、このレイヤが担当します。そのため、このレイヤは、 コマンドを適切なプロトコルへと転送します。これにより、PnP ドライバを 書くのが非常に簡単になります。 次に挙げる関数群は、プラグ&プレイ・レイヤから提供されます。 pnp_get_protocol - 使用数を一つ増やす。 pnp_put_protocol - 使用数を一つ減らす。 pnp_register_protocol - 新しい PnP プロトコルを登録する際、この関数を使います。 pnp_unregister_protocol - プラグ&プレイ・レイヤから PnP プロトコルを削除する際、この関数を 使います。 pnp_register_driver - プラグ&プレイ・レイヤに PnP ドライバを追加します。 - これにより、ドライバモデルにも統合されます。 (訳注: pnp_register_driver() の中から driver_register() [drivers/base/driver.c] が呼ばれる、ということです) pnp_unregister_driver - プラグ&プレイ・レイヤから PnP ドライバを削除します。 プラグ&プレイ・プロトコル -------------------------- このセクションには、PnP プロトコル開発者向けの情報があります。 コンピューティングの世界には、現在のところ次のプロトコル群があります。 - PNPBIOS シリアルポート、パラレルポート等のシステムデバイスで使用されます。 - ISAPNP ISA バス用の PnP サポートを提供します。 - ACPI 数ある用途の中でも、ACPI は、システムレベルデバイスに関する情報を 提供します。 PNPBIOS は置き換えられる予定になっています。Linux プラグ&プレイではまだ サポートされていませんが、近い将来サポートされる予定です。 Linux PnP プロトコルに対する要求事項: 1.) プロトコルは、EISA ID を使用しなければならない。 2.) プロトコルは、PnP レイヤにデバイス群の現設定を通知しなければならない。 - リソースをセットする機能は任意ですが、推奨されます。 次に挙げるのは、PnP プロトコルに関係する関数群です。 pnp_add_device - PnP レイヤに PnP デバイスを追加する際、この関数を使用します。 - この関数を呼び出すのは、pnp_dev 構造体に要求される値が全てセット された場合のみとしてください。 pnp_init_device - PnP 構造体を初期化するために、この関数を呼び出します。 pnp_remove_device - プラグ&プレイ・レイヤからデバイスを削除するのに、この関数を呼び 出します。 - デバイスが使用中の場合、失敗します。 - 当該デバイスと関連する構造体により使用されていたメモリを自動的に 解放します。 pnp_add_id - 指定したデバイスがサポートする ID のリストに、EISA ID を追加します。 より詳細な情報については、/drivers/pnp/pnpbios/core.c などのプロトコルの ソースコードを参照してください。 Linux プラグ&プレイ・ドライバ ------------------------------ このセクションには、PnP ドライバ開発者向けの情報があります。 新しい方法 .......... 1.) 最初に、サポートする EISA ID のリストを作ります。 例: static const struct pnp_id pnp_dev_table[] = { /* 標準 LPT プリンタポート */ {.id = "PNP0400", .driver_data = 0}, /* ECP プリンタポート */ {.id = "PNP0401", .driver_data = 0}, {.id = ""} }; 文字 'X' は、関数の一部でワイルドカードとして使用できることに注目 してください (末尾の 4 文字)。 例: /* 未知の PnP モデム群 */ { "PNPCXXX", UNKNOWN_DEV }, サポートする PnP カード ID を任意で定義できます。 例: static const struct pnp_id pnp_card_table[] = { { "ANYDEVS", 0 }, { "", 0 } }; 2.) 任意で、probe 関数と remove 関数を定義します。parport_pc ドライバ のように、リソースを検出する確かな手法を既にドライバが持っている 場合には、これらの関数を定義しないというのは、理にかなっています。 例: static int serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struct pnp_id *dev_id) { . . . 例: static void serial_pnp_remove(struct pnp_dev * dev) { . . . より詳細な情報については /drivers/serial/8250_pnp.c を参照して ください。 3.) ドライバ構造体を作成します。 例: static struct pnp_driver serial_pnp_driver = { .name = "serial", .card_id_table = pnp_card_table, .id_table = pnp_dev_table, .probe = serial_pnp_probe, .remove = serial_pnp_remove, }; * name と id_table は NULL にできません。 4.) ドライバを登録します。 例: static int __init serial8250_pnp_init(void) { return pnp_register_driver(&serial_pnp_driver); } 古い方法 ........ ISAPNP ドライバの変換を容易にするため、一連の互換関数が作成されています。 一時的な解決方法としてのみ提供されます。 次のとおりです。 struct pnp_card *pnp_find_card(unsigned short vendor, unsigned short device, struct pnp_card *from) struct pnp_dev *pnp_find_dev(struct pnp_card *card, unsigned short vendor, unsigned short function, struct pnp_dev *from) ------------------------------------------------------------ 翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ > 翻訳日: 2004/05/17 翻訳者: 川崎 貴彦