Solaris 8 のソフトウェア開発 (追補)

GLD ドライバの要件

GLD ベースのドライバには、ヘッダーファイル <sys/gld.h> が組み込まれていなければなりません。

また、GLD ベースのドライバには次の宣言が含まれていることも必要です。


char _depends_on[] = "misc/gld";

GLD はデバイス固有のドライバのために、open(9E) および close(9E) 関数の他に、要求される STREAMS の put(9E) および srv(9E) 関数を実装します。さらに、ドライバ用に getinfo(9E) 関数も実装します。

module_info(9S) 構造体の mi_idname 要素は、ドライバ名を指定する文字列です。ファイルシステムに存在するドライバモジュールの名前と正確に一致しなければなりません。

読み取り側の qinit(9S) 構造体では、次の要素を指定する必要があります。

qi_putp

NULL

qi_srvp

gld_rsrv

qi_qopen

gld_open

qi_qclose

gld_close

書き込み側の qinit(9S) 構造体では、次の要素を指定する必要があります。

qi_putp

gld_wput

qi_srvp

gld_wsrv

qi_qopen

NULL

qi_qclose

NULL

dev_ops(9S) 構造体の devo_getinfo 要素では、getinfo(9E) ルーチンとして gld_getinfo を指定する必要があります。

ドライバの attach(9E) 関数は、ハードウェア固有のデバイスドライバと GLD 機能を対応付け、デバイスとドライバを使用できるように準備を整える一切の作業を行います。

attach(9E) 関数は、gld_mac_alloc() を使用して gld_mac_info(9S) (macinfo) 構造体を割り当てます。ドライバは通常、1 つのデバイスについて、macinfo 構造体で定義されているより多くの情報を保存しなければならないので、必要な追加分のデータ構造体を割り当て、gld_mac_info(9S) 構造体の gldm_private メンバーにそのデータ構造体へのポインタを保存する必要があります。

attach(9E) ルーチンは、gld_mac_info(9S) に記述されているように macinfo 構造体を初期化し、その後 gld_register() を呼び出して、ドライバと GLD モジュールを結びつけなければなりません。ドライバは必要に応じてレジスタをマップし、完全に初期化して、gld_register() を呼び出す前に割り込みを受け付けるように準備する必要があります。attach(9E) 関数が割り込みを追加することはあっても、デバイスに割り込みを発生させてはなりません。ドライバは、ハードウェアが確実に静止しているように、gld_register() を呼び出す前に、ハードウェアをリセットする必要があります。gld_register() の呼び出し前に、デバイスが起動されたり、割り込みが発生するような状態になったりしてはなりません。これは、gld(9E) に記載されているように、後に GLD がドライバの gldm_start() エントリポイントを呼び出した時点で行います。gld_register() が正常に完了すると、GLD はいつでも gld(9E) エントリポイントを呼び出すことができます。

attach(9E) ルーチンは、gld_register() が正常に完了した場合は、DDI_SUCCESS を返します。gld_register() がエラーになった場合は、DDI_FAILURE を返し、gld_register() を呼び出す前に割り当てられたあらゆるリソースを、attach(9E)ルーチンで割り当て解除する必要があります。そして、DDI_FAILURE を返します。どのような状況でも、エラーの起きた macinfo 構造体を再利用することがあってはなりません。gld_mac_free() を使用して、割り当てを解除する必要があります。

detach(9E) 関数は、GLD からドライバの登録を解除しようとします。これは、gld(9F) に記載されている gld_unregister() を呼び出すことによって行います。detach(9E) ルーチンは、ddi_get_driver_private(9F) を使用することによって、デバイスの専用データから必要な gld_mac_info(9S) 構造体に対するポインタを取得できます。gld_unregister() は、一定の条件をチェックして、ドライバを切り離せないかどうかを調べます。このチェックに失敗すると、gld_unregister()DDI_FAILURE を返します。その場合、ドライバの detach(9E) ルーチンはデバイスを動作状態にしたまま、DDI_FAILURE を返さなければなりません。

チェックが成功すると、gld_unregister() は、(必要に応じてドライバの gldm_stop() ルーチンを呼び出して) デバイスの割り込み中止を確認し、ドライバを GLD フレームワークから切り離し、DDI_SUCCESS を返します。この場合、detach(9E) ルーチンは割り込みを削除し、attach(9E) ルーチンに割り当てられていたすべてのデータ構造を (macinfo 構造体の割り当てを解除する gld_mac_free() を使用して) 割り当て解除したうえで、DDI_SUCCESS を返さなければなりません。gld_mac_free() を呼び出す前に割り込みを削除することが重要です。