次のページ 前のページ 目次へ

8. カードサービスクライアントドライバの解剖

Linux PCMCIA パッケージのそれぞれの版は、最初から新規にドライバを書け るように良く文書化された``雛型''のクライアントドライバと一緒に 提供しています。 modules/skeleton.c に置いています。

8.1 モジュールの初期化とリセット

全てのローダブルモジュールは init_module()cleanup_module() 関数 を備えなければいけません。それはモジュールを着脱するときにモジュール を支援するプログラムが必要とするからです。PCMCIA クライアントドライバ の初期化関数は register_pcmcia_driver() 呼び出し経由でドライバサービス によってドライバを登録します。再初期化(cleanup) 関数は unregister_pcmcia_driver() を使用してドライバサービスによって登録解除 します。ドライバによっては、再初期化関数はシャットダウン時に存在する デバイスの構造体を解放する為にも呼ばれるかもしれません。

8.2 *_attach() と *_detach() 関数

*_attach() 関数はドライバの ``実体'' を作成し、1つの PCMCIA カードの 管理に必要なデータ構造体の設定を行なう役目があります。*_attach() 関数 は dev_link_t 構造体の割り当てと初期化を行ない、RegisterClient を呼び 出してカードサービスとの結合を確立します。RegisterClient は新しく出来 た dev_link_t 構造体へのポインタを返し、作成できなかった時は NULL を 返します。

*_detach() 関数は以前に発行した *_attach が作成したドライバの実体を 削除します。また、カードサービスとの結合も DeregisterClient を使って 解除します。

*_attach() 関数は DS_BIND_REQUEST ioctl() で一致するドライバが識別で き、割り付けがうまくいった時にドライバサービスによって呼ばれます。 *_detach() 関数は DS_UNBIND_REQUEST ioctl() を呼ぶことに応答し起動し ます。

8.3 *_config() と *_release() 関数

*_config() 関数はカードに対する入出力の準備の為に呼ばれます。殆んどの ドライバは詳細な情報はカード自身から読み出しますが、どのようにデバイス を設定するかの最小限の知識はドライバに組み込まれています。例えば、 シリアルカードのドライバはカードの CFTABLE_ENTRY タプルから一致する 入出力ポートの基底アドレスと一致する設定指標を読み込みますが、 CIS 内の割り込み情報は無視します。*_config 関数はカードの CIS の関連 する部分を解析します。そして RequestIO, RequestIRQRequestWindow を呼び出せます。それから RequestConfiguration を呼びます。

カードの設定がうまくいったら、*_config() ルーチンが dev_link_t 構造体の dev_name, majorminor 変数に書き込みます。 これらの変数 は DS_GET_DEVICE_INFO ioctl () の応答としてドライバサービスが ユーザプログラムに返します。

*_release() 関数は以前に呼んだ *_config() が割り当てたリソースを 解放し、デバイスの dev_name 変数を空白にします。

*_config()*_release 関数は通常カード状態の変更イベントまたは タイマー割り込みに反応して呼ばれます。この時、これらの関数はスリープ 出来なく、他のカーネル関数から呼ばれないように遮断しておきます。

8.4 PCMCIA イベントハンドラ

*_event() 関数はカードサービスからカード状態次変更イベントを通知 する為に呼ばれます。

8.5 ロックと同期について

設定したソケットは全ての関連したデバイスが閉じられた時にのみ解放 されます。ソケットの解放はソケットのシステム資源を他のデバイスで使用 出来るようにします。解放された資源が元のデバイスで入出力に使用している 場合は、元のドライバは新しいデバイスを使用してします。

ドライバの実体は一致するソケットの構成が解放された後のみ解放されます。 カードサービスは DeregisterClient が成功する為にはクライアントが明らか に割り当てた資源を解放する必要があります。

全てのローダブルモジュールは安全にモジュールを解放する時にシステムが 使用する ``使用回数(use count)'' を持っています。PCMCIA クライアント ドライバの慣習はデバイスをオープンすると使用回数を増加させ、デバイスを クローズすると使用回数を減少させます。従ってドライバを解放するには全て の関連するデバイスは閉じている必要があります。特に、ソケットが接続して いる時にドライバを解放出来ます。モジュール再初期化プログラムは適切な 解放できる既に割当済みの資源を必要とします。これは使用回数がゼロで、 全てのデバイスが閉じていて、つまり全てのソケットが解放できる状態で 全てのデバイスが外せる場合に安全な方法です。

デバイスが開いている状態で *_release() 関数が呼ばれたら、デバイス状態 の DEV_STALE_CONFIG フラグが設定され close() 関数が呼ばれた時に デバイスを解放するように通知します。構成したデバイスを*_detach() 関数で呼び出したら、DEV_STALE_LINK フラグは *_release() 関数が 呼ばれた時に実体が解放されるように通知するように設定されます。

8.6 現有の Linux のドライバで PCMCIA デバイスをアクセスする方法

現在の PCMCIA クライアントドライバは現有の Linux のドライバをデバイス の入出力操作を行ないます。カードサービスクライアントモジュールは カードの構成とカード状態の変更イベントの監視を行ないますが、通常の ISA バスのカードのドライバと互換性のある入出力を行ないます。 いくつかの場合では、普通のドライバを変更無しに使う事が出来ます。 しかしながら、活線抜去やパワーマネージメントのような PCMCIA の機能は すべてはサポートされていませんので、PCMCIA クライアントプログラムと デバイス入出力プログラムの間で通信をする必要があります。

殆んどのドライバはブート時にデバイスを探知するのと着脱出来るデバイスを 扱うように設計されています。ドライバのモジュール化の副作用は通常着脱 可能なデバイスを扱うのにモジュラー化したドライバは簡単に受け入れられる ということです。

重要な事は、適切でない時にデバイスを取り去ってしまいデバイスドライバが 使えなくなる事です。最善の方法はドライバが入出力操作や入出力割り込み を行なう前にデバイスを事前に確認する事です。デバイスの状態の確認の 繰返しは時間切れになってしまい、結局デバイスが応答しない場合は終了 します。


次のページ 前のページ 目次へ