Oracle® Solaris 11.2 デバイスドライバの記述

印刷ビューの終了

更新: 2014 年 9 月
 
 

GLDv2 のサービスルーチン

このセクションでは、GLDv2 のサービスルーチンの構文および説明を示します。

gld_mac_alloc() 関数

gld_mac_info_t *gld_mac_alloc(dev_info_t *dip);

gld_mac_alloc() は新しい gld_mac_info(9S) 構造体を割り当て、その構造体へのポインタを返します。構造体の GLDv2 専用要素の一部は、gld_mac_alloc() が戻る前に初期化される可能性があります。ほかのすべての要素は 0 に初期化されます。デバイスドライバは、gld_mac_info 構造体へのポインタを gld_register() に渡す前に、gld_mac_info(9S) のマニュアルページの説明に従って一部の構造体メンバーを初期化する必要があります。

gld_mac_free() 関数

void gld_mac_free(gld_mac_info_t *macinfo);

gld_mac_free() は、以前に gld_mac_alloc() によって割り当てられた gld_mac_info(9S) 構造体を解放します。

gld_register() 関数

int gld_register(dev_info_t *dip, char *name, gld_mac_info_t *macinfo);

gld_register() は、デバイスドライバの attach (9E) ルーチンから呼び出されます。gld_register() は、GLDv2 ベースのデバイスドライバを GLDv2 フレームワークとリンクします。gld_register() を呼び出す前に、デバイスドライバの attach (9E) ルーチンは gld_mac_alloc() を使用して gld_mac_info(9S ) 構造体を割り当ててから、いくつかの構造体要素を初期化します。詳細は、gld_mac_info (9S) を参照してください。gld_register() の呼び出しが成功すると、次の処理が実行されます。

  • デバイス固有ドライバを GLDv2 システムとリンクする

  • ddi_set_driver_private(9F) を使用して、デバイス固有ドライバの非公開データポインタが macinfo 構造体を指し示すように設定する

  • マイナーデバイスノードを作成する

  • DDI_SUCCESS を返す

gld_register() に渡されるデバイスインタフェース名は、ファイルシステムに存在するドライバモジュールの名前と完全一致する必要があります。

gld_register() が成功した場合、ドライバの attach (9E) ルーチンは DDI_SUCCESS を返します。gld_register()DDI_SUCCESS を返さない場合、attach(9E) ルーチンは gld_register() を呼び出す前に、割り当て済みのリソースをすべて解放してから DDI_FAILURE を返します。

gld_unregister() 関数

int gld_unregister(gld_mac_info_t *macinfo);

gld_unregister() はデバイスドライバの detach (9E) 関数によって呼び出され、成功した場合に次のタスクを実行します。

  • 必要であればドライバの gldm_stop() ルーチンを呼び出して、デバイスの割り込みを確実に中止させる

  • マイナーデバイスノードを削除する

  • デバイス固有ドライバを GLDv2 システムからリンク解除する

  • DDI_SUCCESS を返す

gld_unregister()DDI_SUCCESS を返す場合、detach(9E) ルーチンは、attach(9E) ルーチンで割り当てられたデータ構造体があればすべて解放し (gld_mac_free() を使用して macinfo 構造体を解放)、DDI_SUCCESS を返します。gld_unregister()DDI_SUCCESS を返さない場合、ドライバの detach(9E) ルーチンは、デバイスを動作状態にしたまま DDI_FAILURE を返す必要があります。

gld_recv() Function

void gld_recv(gld_mac_info_t *macinfo, mblk_t *mp);

gld_recv() はドライバの割り込みハンドラによって呼び出され、受信したパケットをアップストリームに渡します。ドライバは raw パケットが格納された M_DATA 型の STREAMS メッセージを作成して渡す必要があります。gld_recv () は、どの STREAMS キューがパケットのコピーを受信するかを調べ、必要に応じてパケットを複製します。gld_recv() はその後、必要に応じて DL_UNITDATA_IND メッセージをフォーマットし、データをすべての該当するストリームに渡します。

ドライバでは、gld_recv() の呼び出し中に mutex ロックまたはまたはその他のロックを保持しないようにしてください。特に、転送スレッドが使用する可能性のあるロックが、gld_recv() の呼び出し中に保持されていてはなりません。場合によっては、gld_recv() を呼び出す割り込みスレッドが、発信パケットの送信を含む処理を実行します。パケット転送の結果として、ドライバの gldm_send() ルーチンが呼び出されてしまいます。gld_recv() の呼び出し時に gldm_intr() によって保持されている mutex を gldm_send() が取得しようとすると、mutex エントリの再帰性が原因でパニックが発生します。gld_recv() の呼び出しでドライバが保持する mutex をほかのドライバのエントリポイントが取得しようとすると、デッドロックに陥る可能性があります。

gld_sched() 関数

void gld_sched(gld_mac_info_t *macinfo);

gld_sched() はデバイスドライバによって呼び出され、停止されていたアウトバウンドパケットを再スケジューリングします。ドライバの gldm_send() ルーチンが GLD_NORESOURCES を返すたびに、ドライバは gld_sched() を呼び出して、以前に送信できなかったパケットを再試行するよう GLDv2 フレームワークに通知する必要があります。 リソースが利用可能になると、GLDv2 がドライバの gldm_send() ルーチンに発信パケットを渡す処理を再開するよう、ただちに gld_sched() が呼び出されます (ドライバの gldm_stop() ルーチンが呼び出される場合、gldm_send() から GLD_NORESOURCES が返されるまでの間、ドライバは再試行する必要はありません。ただし、gld_sched() を余分に呼び出しても、誤った動作になることはありません)。

gld_intr() 関数

uint_t gld_intr(caddr_t);

gld_intr() は GLDv2 のメイン割り込みハンドラです。gld_intr() は通常、デバイスドライバの ddi_add_intr (9F) 呼び出しで割り込みルーチンとして指定されます。割り込みハンドラへの引数は、ddi_add_intr(9F) の呼び出しで int_handler_arg として指定されます。この引数は gld_mac_info(9S) 構造体へのポインタである必要があります。gld_intr() は、該当する場合、デバイスドライバの gldm_intr() 関数を呼び出し、gld_mac_info (9S) 構造体にそのポインタを渡します。ただし、高レベル割り込みを使用する場合、ドライバは独自の上位割り込みハンドラを提供し、その中からソフト割り込みをトリガーする必要があります。この場合、gld_intr() は通常、ddi_add_softintr() の呼び出しでソフト割り込みハンドラとして指定されます。gld_intr() は、割り込みハンドラに適した値を返します。