EN JA
BUS_SETUP_INTR(9)
BUS_SETUP_INTR(9) FreeBSD Kernel Developer's Manual BUS_SETUP_INTR(9)

名称

BUS_SETUP_INTR, bus_setup_intr, BUS_TEARDOWN_INTR, bus_teardown_intr割り込みハンドラを作成し、アタッチして、取り壊す

書式

#include < sys/param.h>
#include < sys/bus.h>

int
BUS_SETUP_INTR( device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *ithread, void *arg, void **cookiep);

int
bus_setup_intr( device_t dev, struct resource *r, int flags, driver_filter_t filter, driver_intr_t ithread, void *arg, void **cookiep);

int
BUS_TEARDOWN_INTR( device_t dev, device_t child, struct resource *irq, void *cookiep);

int
bus_teardown_intr( device_t dev, struct resource *r, void *cookiep);

解説

BUS_SETUP_INTR() メソッドは、以前にリソース管理の BUS_ALLOC_RESOURCE(9) メソッドによって割り付けられた割り込みへの割り込みハンドラを作成しアタッチします。 flags は、 < sys/bus.h> で見つかり、割り込みの広義のカテゴリを与えます。また flags は、特定のデバイスドライバの特性について割り込みハンドラに伝えます。 INTR_EXCL は、この割り込みのための排他的なハンドラであるとしてハンドラをマークします。 INTR_MPSAFE は、割り込みハンドラがプリエンプティブの環境でうまく振る舞い (``SMP セーフ'')、``ジャイアントロック'' ミューテックによって保護される必要がないことをスケジューラに伝えます。 INTR_ENTROPY は、エントロピのよいソースであるとして割り込みをマークします - エントロピデバイス /dev/random によって、これを使用することができます。

潜在的にブロック操作を実行しない時間にクリティカルなハンドラを定義するには、 filter 引数を使用します。フィルタを書くための情報については、下記の フィルタルーチン セクションを参照してください。そうでなければ、 ithread 引数を使用します。定義されたハンドラは、唯一の引数 arg の値を付けて呼び出されます。割り込みハンドラを書くための詳しい情報については、下記の ithread ルーチン セクションを参照してください。

cookiep 引数は、 BUS_SETUP_INTR() が、割り込みの確立に成功するなら、親のバスの使用のためにクッキーを書き込む void * へのポインタです。ドライバの作者は、このクッキーが 0 でないと仮定することができます。 nexus ドライバは、失敗すれば、 cookiep に 0 を書き込みます。

割り込みハンドラは、 BUS_TEARDOWN_INTR() によってデタッチされます。正しい割り込みハンドラを取り壊すために BUS_TEARDOWN_INTR() にクッキーを渡す必要があります。いったん BUS_TEARDOWN_INTR() が返ると、割り込み関数は、アクティブではなく、もはや呼び出されないことが保証されています。

これらの関数への呼び出しにわたってミューテックを保持することは許されません。

フィルタルーチン

フィルタは、プライマリ割り込みコンテキストを実行します。このようなコンテキストで、通常の mutex を使用できません。 (mutex を初期化するとき、 MTX_SPINmtx_init() に渡すことによって指定される) これらのスピンロックバージョンのみを使用することができます。 wakeup(9) と同様のルーチンを呼び出すことができます。 machine/atomic からの不可分の操作が使用できます。 bus_space(9) を通してハードウェアへの読み込みと書き込むを使用できます。 PCI 設定レジスタは、読み込み書き込みできます。他のすべてのカーネルインタフェースを使用できるというわけではありません。

この制限された環境で、すべての競合 (race) について考慮されなければならないことに注意してください。同様に、競合の慎重な解析が行われるべきです。一般的に、特別の割り込みを取ることは、例えば、スピンロック (spinlock) で変数を保護するよりコストが安いです。ハードウェアレジスタの読み込み、変更、書き込みサイクルは、他のスレッドが同じレジスタにアクセスするなら、慎重に解析される必要があります。

一般的に、フィルタルーチンは、2 つの戦略の 1 つを使用します。最初の戦略は、単にハードウェアの割り込みをマスクして、 ithread ルーチンは、ハードウェアから状態を読み込むことができ、次に割り込みを再有効化します。また、ハードウェアの割り込みソースを再利用可能にする前に、 ithread は、割り込みを承諾します。ほとんどの PCI ハードウェアは、割り込みソースをマスクすることができます。

2 番目の共通のアプローチは、複数の taskqueue(9) タスクがあるフィルタを使用することです。この場合、フィルタは、割り込みを承諾して、適切なタスクキューへ仕事をキューに入れます。ネットワークカードの送信と受信パスのような、割り込みソースの複数の異なった種類があるところで、これは、ロックの競合を削減して、性能を向上させることができます。

利用者は、フィルタの中から malloc(9) するべきではありません。利用者は、通常の mutex を使用するものを呼び出すことができません。目撃者 (witness) は、これらに関してエラーを出すかもしれません。

ithread ルーチン

利用者は、sleep を除いて、ithread ルーチンで必要なことなら何でもできます。 ithread で sleep しないように注意しなければなりません。さらに、競合したロックは、その割り込みで、他のすべての ithread ルーチンに波及 (ripple over) するので、ithread ルーチンのロックの競合を最小にするべきです。

スリーピング (sleeping)

スリーピングは、自発的に利用者のスレッドの制御を放棄します。すべてのスリープルーチンは、 msleep(9) スリープにあります。 condvar(9) で説明された状態変数でウェートすることは、スリーピングです。これらのことのいずれかを行う任意の関数を呼び出すことは、スリーピングです。

戻り値

成功すれば、0 が返され、そうでなければ、適切なエラーが返されます。

作者

このマニュアルページは、 Doug Rabson <dfr@FreeBSD.org>によって書かれた、 BUS_CREATE_INTR() と BUS_CONNECT_INTR() のマニュアルページを基に Jeroen Ruigrok van der Werven <asmodai@FreeBSD.org>によって書かれました。
November 3, 2010 FreeBSD