ドライバは、次のインタフェースを使用してコールバックサポートを登録する必要があります。
|
ドライバのコールバックハンドラ関数を登録するときは、 ddi_cb_register(9F) 関数を使用します。
int ddi_cb_register (dev_info_t *dip, ddi_cb_flags_t cbflags, ddi_cb_func_t cbfunc, void *arg1, void *arg2, ddi_cb_handle_t *ret_hdlp);
ドライバは、1 つのコールバック関数のみを登録できます。この 1 つのコールバック関数が、個々のすべてのコールバックアクションを処理するために使用されます。cbflags パラメータは、アクションが発生したときにドライバが受信するアクションのタイプを判定します。cbfunc() ルーチンは、関連するアクションをドライバが処理するときに常に呼び出されます。ドライバは、cbfunc() ルーチンを実行するたびに自分に送信する 2 つのプライベート引数 (arg1 と arg2) を指定します。
cbflags() パラメータは、ドライバがサポートするアクションを指定する列挙型です。
typedef enum { DDI_CB_FLAG_INTR } ddi_cb_flags_t;
割り込みリソース管理アクションのサポートを登録するには、ドライバでハンドラを登録して DDI_CB_FLAG_INTR フラグを含める必要があります。コールバックハンドラが正常に登録されると、ret_hdlp パラメータを介して不透明なハンドルが返されます。ドライバでコールバックハンドラの処理が終了すると、ドライバは ret_hdlp パラメータを使用してコールバックハンドラの登録を解除できます。
コールバックハンドラをドライバの attach(9F) エントリポイントで登録します。不透明なハンドルをドライバのソフト状態に保存します。ドライバの detach(9F) エントリポイントでコールバックハンドラの登録を解除します。
ドライバのコールバックハンドラ関数の登録を解除するときは、 ddi_cb_unregister(9F) 関数を使用します。
int ddi_cb_unregister (ddi_cb_handle_t hdl);
この呼び出しは、ドライバの detach(9F) エントリポイントで行います。この呼び出しのあと、ドライバはコールバックアクションを受信しなくなります。
ドライバは、登録されたコールバック処理関数があることによって取得した、システムによる追加サポートも失います。たとえば、ドライバで前に利用できるようになった一部の割り込みベクターは、ドライバがコールバック処理関数の登録を解除するとすぐに元に戻されます。正常に復帰する前に、ddi_cb_unregister() 関数は、システムのサポートを失うことによって発生する、最終的なアクションをドライバに通知します。
コールバックアクションを受信し、処理する各アクションに固有の引数を受信するときは、登録されたコールバック処理関数を使用します。
typedef int (*ddi_cb_func_t)(dev_info_t *dip, ddi_cb_action_t cbaction, void *cbarg, void *arg1, void *arg2);
cbaction パラメータは、ドライバがコールバックを受信するときの処理対象となるアクションを指定します。
typedef enum { DDI_CB_INTR_ADD, DDI_CB_INTR_REMOVE } ddi_cb_action_t;
DDI_CB_INTR_ADD アクションは、ドライバで使用可能な割り込みが増えることを意味します。DDI_CB_INTR_REMOVE アクションは、ドライバで使用可能な割り込みが減ることを意味します。追加または削除された割り込みの数を判定するときは、cbarg パラメータを int にキャストします。cbarg 値は、利用可能な割り込みの数の変化を表します。
たとえば、利用可能な割り込みの数の変化を取得する場合は、次のようになります。
count = (int)(uintptr_t)cbarg;
cbaction が DDI_CB_INTR_ADD である場合は、cbarg 個の割り込みベクターを追加します。cbaction が DDI_CB_INTR_REMOVE である場合は、cbarg 個の割り込みベクターを解放します。
arg1 および arg2 の説明については、ddi_cb_register(9F) を参照してください。
コールバック処理関数は、関数が登録される期間全体を通じて、正しく実行できる必要があります。コールバック関数は、コールバック関数の登録が正常に解除される前に破棄される可能性のあるデータ構造体に依存することはできません。
コールバック処理関数は、次のいずれかの値を返す必要があります。
アクションを正しく処理した場合は DDI_SUCCESS
内部エラーが発生した場合は DDI_FAILURE
認識できないアクションを受信した場合は DDI_ENOTSUP