AUTOCONF(9) NetBSD Kernel Developer's Manual AUTOCONF(9) 名称 autoconf, config_search, config_found_sm, config_found, config_match, config_attach, config_detach, config_activate, config_deactivate, config_defer, config_interrupts, config_pending_incr, config_pending_decr -- 自動コンフィグレーション・フレームワーク 書式 #include #include #include struct cfdata * config_search(cfmatch_t func, struct device *parent, void *aux); struct device * config_found_sm(struct device *parent, void *aux, cfprint_t print, cfmatch_t submatch); struct device * config_found(struct device *parent, void *aux, cfprint_t print); int config_match(struct device *parent, struct cfdata *cf, void *aux); struct device * config_attach(struct device *parent, struct cfdata *cf, void *aux, cfprint_t print); int config_detach(struct device *dev, int flags); int config_activate(struct device *dev); int config_deactivate(struct device *dev); int config_defer(struct device *dev, void (*func)(struct device *)); void config_interrupts(struct device *dev, void (*func)(struct device *)); void config_pending_incr(); void config_pending_decr(); (訳註: void *device_lookup(const struct cfdriver *cfd, int unit); cfmatch_t の宣言は sys/sys/device.h: typedef int (*cfmatch_t)(struct device *, struct cfdata *, void *); cfmatch_t の宣言は sys/sys/device.h: typedef int (*cfprint_t)(void *, const char *); /* XXX const char * */ struct device の宣言は sys/sys/device.h: struct device { enum devclass dv_class; /* this device's classification */ TAILQ_ENTRY(device) dv_list; /* entry on list of all devices */ struct cfdata *dv_cfdata; /* config data that found us (NULL if pseudo-device) */ struct cfdriver *dv_cfdriver; /* our cfdriver */ struct cfattach *dv_cfattach; /* our cfattach */ int dv_unit; /* device unit number */ char dv_xname[16]; /* external name (name + unit) */ struct device *dv_parent; /* pointer to parent device (NULL if pesudo- or root node) */ int dv_flags; /* misc. flags; see below */ int *dv_locators; /* our actual locators (optional) */ }; struct cfdata の宣言は sys/sys/device.h: struct cfdata { const char *cf_name; /* driver name */ const char *cf_atname; /* attachment name */ short cf_unit; /* unit number */ short cf_fstate; /* finding state (below) */ int *cf_loc; /* locators (machine dependent) */ int cf_flags; /* flags from config */ const struct cfparent *cf_pspec;/* parent specification */ const char * const *cf_locnames;/* locator names (machine dependent) */ }; struct cfdriver の宣言は sys/sys/device.h: struct cfdriver { LIST_ENTRY(cfdriver) cd_list; /* link on allcfdrivers */ struct cfattachlist cd_attach; /* list of all attachments */ void **cd_devs; /* devices found */ const char *cd_name; /* device name */ enum devclass cd_class; /* device classification */ int cd_ndevs; /* size of cd_devs array */ const char * const *cd_attrs; /* attributes for this device */ }; 解説 自動コンフィグレーション(autoconfiguration)はハードウェアデバイス に対して、適切なデバイスドライバをマッチさせるプロセスです。多く の場合、自動コンフィグレーションは一つのバスに接続された全てのデ バイス(他のバスも含む)を見つけアタッチ(attach)する過程を、再帰的 に繰り返します。 自動コンフィグレーション・フレームワークは、バスドライバがデバイ スの存在を決定する、direct configuration 方式をサポートします。自 動コンフィグレーション・フレームワークはまた、ドライバがデバイス の存在を確認するためにバスをプローブ(probe)しなければならない、 indirect configuration 方式もサポートします。direct configuration 方式では、適切なドライバが存在しなくてもハードウェアを発見できる ので、より好ましいと言えます。 自動コンフィグレーションのプロセスは、システムのブートストラップ 中に起こり、config(8) が ``機種記述(machine description)'' ファイ ルから作成したテーブルによって駆動されます。config(8) の ``デバイ ス定義(device definition)'' 言語に関する情報は、config(9) を参照 して下さい。 各デバイスは必ず名前を持たねばなりません。名前は英数字から成る文 字列で、最後にユニット番号が付きます。デバイス番号はドライバのイ ンスタンスを識別します。デバイスデータ構造体は自動コンフィグレー ションの間、動的に確保され、各インスタンス毎に異なるアドレスを持 ちます。 関数 config_search(func, parent, aux) 物理デバイスの indirect configuration を行います。 config_search() は存在し得る全ての子に対し、それぞれ関数 func を呼び出すことを繰り返します。もし func が NULL な らば、config_search() は代わりにそれぞれの子の match 関 数を適用します。引数 parent は親の device 構造対へのポイ ンタです。引数 aux は検出されたデバイスを記述するもので、 単純に func の引数として子に渡されます。config_search() はベストマッチした子へのポインタか、マッチする子が無けれ ば NULL を返します。 func の任務は、一つ一つのデバイスに対して match 関数を呼 び出し、正の値を返したデバイスに対しては config_attach() を呼び出すことです。func が NULL ならば、親は config_search() の戻り値を記録し、config_attach() 自身を 呼び出すべきです。 config_found_sm(parent, aux, print, submatch) 物理デバイスの direct configuration を行います。 config_found_sm() は親によって呼び出され、コンフィグレー ションテーブルで決定された match 関数を呼ぶために、順番 に submatch 関数を呼び出します。もし submatch が NULL な らば、ドライバの match 関数が直接呼び出されます。引数 parent は親の device 構造体へのポインタです。引数 aux は 検出されたデバイスを記述します。マッチしたデバイスに対し ては softc 構造体が確保され、適切な attach 関数が呼び出 されます。もしデバイスがマッチした場合、システムは子と親 の名前を表示し、(必要であれば)追加の情報を表示するために print 関数を呼び出します。もしマッチするドライバが見付か らなければ、そのことを報告する為に同じ print 関数が呼び 出されます。print 関数の引数には aux と、マッチが失敗な らば親デバイスのフルネーム(ユニット番号含む)、そうでなけ れば NULL が渡されます。print 関数は整数値を返さなければ なりません。 ドライバが見付からないことを報告する場合、戻り値が UNCONF または UNSUPP ならば、二つの特別な文字列 ``not configured'' と ``unsupported'' が自動的に追加されます。 そうしたくなければ、関数は値 QUIET を返すべきです。 config_found_sm() は、デバイスがアタッチされた場合はアタッ チされたデバイスの softc 構造体へのポインタを返します。 アタッチされない場合は NULL を返します。システムが既に診 断メッセージを表示しているので、ほとんどの場合呼び出し元 はこの値を無視できます。 (訳註: config_found_sm(parent, aux, print, submatch) の中身は if ((cf = config_search(sumbatch, parent, aux) != NULL) return config_attach(parent, cf, aux, print) てな感じ。 ) config_found(parent, aux, print) この関数は config_found_sm(parent, aux, print, NULL) と同等で、 古いドライバとの互換を保つ為に残っています。 config_match(parent, cf, aux) デバイスをマッチします。コンフィグレーションテーブル に従って、ドライバの match 関数を呼び出します。 config_match() 関数は、デバイスをサポートする場合、優先 度に応じ 0 でない整数を返し、ドライバがデバイスをサポー トしない場合は 0 を返します。 config_attach(parent, cf, aux, print) 検出したデバイスをアタッチします。softc 構造体をメモリに 確保し、コンフィグレーションテーブルに従って、ドライバの attach 関数を呼び出します。config_attach() は、成功した 場合は確保した softc へのポインタを返し、失敗した場合は NULL を返します。 config_detach(dev, flags) 子デバイスをデタッチ(detach)する為に、親から呼び出されま す。第 2 引数 flags にはデタッチメントフラグが入っていま す。有効な値は DETACH_FORCE (強制デタッチ(例えばハードウェ アが取り外された)) と DETACH_QUIET (告知を表示しない) で す。config_detach() は、成功の場合 0 を返し、失敗の場合 エラーコードを返します。config_detach() は常にスレッドコ ンテキストから呼び出され、デバイスが自身をデタッチする間 ltsleep(9) 呼び出すことができます。 config_activate(dev) 子デバイス dev をアクティベートする為に、親から呼び出さ れます。資源をアクティベートし、他のカーネルサブシステム (ネットワークサブシステム等)を初期化する為に呼び出されま す。config_activate() は、デバイスがアタッチされた後、割 り込みコンテキストから呼び出されます。 config_deactivate(dev) 子デバイス dev をディアクティベートする為に、親から呼び 出されます。config_activate() は、割り込みコンテキストか ら呼び出され、資源を即座に放棄し、依存するカーネルサブシ ステムに、デバイスがデタッチされることを通知する必要があ ります。その後、デバイスの取り外し処理を終了させる為、 config_detach() が呼び出されます。 config_defer(dev, func) 子によって呼び出され、親の全てのデバイスがアタッチされる まで、残りのコンフィグレーションを延期させます。アタッチ された時点で、関数 func が引数 dev を持って呼び出されま す。 config_interrupts(struct device *dev, void (*func)(struct device *)) 子によって呼び出され、割り込みが有効になるまで、残りのコ ンフィグレーションを延期させます。有効になった時点で、関 数 func が引数 dev を持って呼び出されます。 config_pending_incr() config_pending セマフォを増加させます。ルートファイルシス テムをマウントする前に defer されたコンフィグレーション をカウントする為に使用されます。 config_pending_decr() config_pending セマフォを減少させます。ルートファイルシ ステムをマウントする前に defer されたコンフィグレーショ ンをカウントする為に使用されます。 コードリファレンス このセクションでは、NetBSD ソースツリー内で、実際に自動コンフィグ レーション・フレームワークを使ったコード実装や、使用例の存在する 場所を示します。全てのパス名は /usr/src からの相対パスです。 自動コンフィグレーション・フレームワークそのものの実装は、ファイ ル sys/kern/subr_autoconf.c です。フレームワーク用のデータ構造と 関数プロトタイプはsys/sys/device.h にあります。 関連項目 config(8), config(9), driver(9) 歴史 自動コンフィグレーションは 4.1BSD で登場しました。自動コンフィグ レーション・フレームワークは 4.4BSD で全面的に改修されました。 detach と activeate/deactivate インターフェースは NetBSD 1.5 で登 場しました。 NetBSD 3.1 October 5, 2002 NetBSD 3.1 $Id: autoconf.0,v 1.4 2007/07/12 02:47:45 candy Exp candy $