JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
デバイスドライバの記述     Oracle Solaris 11.1 Information Library (日本語)
このドキュメントの評価
search filter icon
search icon

ドキュメントの情報

はじめに

パート I Oracle Solaris プラットフォーム用デバイスドライバの設計

1.  Oracle Solaris デバイスドライバの概要

2.  Oracle Solaris カーネルとデバイスツリー

3.  マルチスレッド

4.  プロパティー

デバイスプロパティー

デバイスプロパティー名

プロパティーの作成と更新

プロパティーの検索

driver.conf ファイルへの変更

prop_op() エントリポイント

5.  イベントの管理とタスクのキュー

6.  ドライバの自動構成

7.  デバイスアクセス: プログラム式入出力

8.  割り込みハンドラ

9.  ダイレクトメモリーアクセス (DMA)

10.  デバイスメモリーおよびカーネルメモリーのマッピング

11.  デバイスコンテキスト管理

12.  電源管理

13.  Oracle Solaris ドライバの強化

14.  階層化ドライバインタフェース (LDI)

パート II 特定の種類のデバイスドライバの設計

15.  文字デバイスのドライバ

16.  ブロックデバイスのドライバ

17.  SCSI ターゲットドライバ

18.  SCSI ホストバスアダプタドライバ

19.  ネットワークデバイスのドライバ

20.  USB ドライバ

21.  SR-IOV ドライバ

パート III デバイスドライバの構築

22.  ドライバのコンパイル、ロード、パッケージ化、およびテスト

23.  デバイスドライバのデバッグ、テスト、およびチューニング

24.  推奨されるコーティング方法

パート IV 付録

A.  ハードウェアの概要

B.  Oracle Solaris DDI/DKI サービスのサマリー

C.  64 ビットデバイスドライバの準備

D.  コンソールフレームバッファードライバ

E.  pci.conf ファイル

索引

ドキュメントの品質向上のためのご意見をください
簡潔すぎた
読みづらかった、または難し過ぎた
重要な情報が欠けていた
内容が間違っていた
翻訳版が必要
その他
Your rating has been updated
貴重なご意見を有り難うございました!

あなたの貴重なご意見はより良いドキュメント作成の手助けとなります 内容の品質向上と追加コメントのためのアンケートに参加されますか?

デバイスプロパティー

デバイス属性情報は、プロパティーと呼ばれる名前-値ペアの表記で表すことができます。

たとえば、デバイスレジスタとオンボードメモリーは reg プロパティーで表すことができます。reg プロパティーは、デバイスハードウェアレジスタを記述するソフトウェアの抽象化です。reg プロパティーの値により、デバイスレジスタのアドレス位置とサイズがエンコードされます。ドライバは、reg プロパティーを使用してデバイスレジスタにアクセスします。

別の例として interrupt プロパティーがあります。interrupt プロパティーは、デバイス割り込みを表します。interrupt プロパティーの値により、デバイス割り込み PIN がエンコードされます。

プロパティーには次の 5 つの型の値を割り当てることができます。

値を持たないプロパティーは、boolean プロパティーとみなされます。boolean プロパティーが存在する場合は真 (true) です。boolean プロパティーが存在しない場合は偽 (false) です。

デバイスプロパティー名

厳密に言えば、DDI/DKI ソフトウェアのプロパティー名には制限がありません。ただし、推奨される使い方がいくつかあります。IEEE 1275-1994「Standard for Boot Firmware」では、プロパティーは次のように定義されています。

プロパティーとは、1 から 31 文字までのプリント可能文字で構成される、人間が読めるテキスト文字列のことです。プロパティー名には、大文字や「/」、「\」、「:」、「[」、「]」、「@」の文字を含めることはできません。「+」文字で始まるプロパティー名は、将来のバージョンの IEEE 1275-1994 用に予約されています。

通常、下線はプロパティー名に使用しません。代わりにハイフン (-) を使用します。通常、疑問符 (?) で終わるプロパティー名には、文字列の値 (一般には TRUE または FALSE) を指定します (例: auto-boot?)。

ドライバ構成ファイルへのプロパティーの追加については、driver.conf(4) のマニュアルページを参照してください。pm(9P)pm-components(9P) のマニュアルページには、電源管理におけるプロパティーの使用方法が記載されています。デバイスドライバのマニュアルページにプロパティーがどのように文書化されているかの例として、sd(7D) のマニュアルページをお読みください。

プロパティーの作成と更新

ドライバのプロパティーを作成したり、既存のプロパティーを更新したりするには、適切なプロパティー型を持つ DDI ドライバ更新インタフェース (ddi_prop_update_int(9F)ddi_prop_update_string(9F) など) の 1 つを使用します。使用できるプロパティーインタフェースの一覧については、表 4-1 を参照してください。これらのインタフェースは通常、ドライバの attach(9E) エントリポイントから呼び出されます。次の例では、ddi_prop_update_string() は、needs-suspend-resume という値を使って pm-hardware-state という文字列プロパティーを作成します。

/* The following code is to tell cpr that this device
 * needs to be suspended and resumed.
 */
(void) ddi_prop_update_string(device, dip,
    "pm-hardware-state", "needs-suspend-resume");

ほとんどの場合、プロパティーの更新には ddi_prop_update() ルーチンを使用すれば十分です。ただし、頻繁に値が変わるプロパティーの場合は更新によるオーバーヘッドが原因で、パフォーマンスに関する問題が発生することがあります。ddi_prop_update() の使用を避けるためにプロパティー値のローカルインスタンスを使用する方法については、prop_op() エントリポイント」を参照してください。

プロパティーの検索

ドライバは、その親にプロパティーを要求できます。そしてその親は、さらにその親に要求できます。ドライバは、要求をその親よりも上位に対して行えるかどうかを制御できます。

たとえば、次の例の esp ドライバは、ターゲットごとに targetx-sync-speed という整数プロパティーを保持します。targetx-sync-speed 内の x はターゲット番号を表します。prtconf(1M) コマンドは、ドライバのプロパティーを冗長モードで表示します。次の例は、esp ドライバの部分的なリストを示しています。

% prtconf -v
...
       esp, instance #0
            Driver software properties:
                name <target2-sync-speed> length <4>
                    value <0x00000fa0>.
...

次の表に、プロパティーインタフェースのサマリーを示します。

表 4-1 プロパティーインタフェースの使い方

ファミリ
プロパティーインタフェース
説明
ddi_prop_lookup
プロパティーを検索し、そのプロパティーが存在する場合は正常に復帰します。プロパティーが存在しない場合は失敗します。
整数プロパティーを検索し、それを返します。
64 ビットの整数プロパティーを検索し、それを返します。
整数配列プロパティーを検索し、それを返します。
64 ビットの整数配列プロパティーを検索し、それを返します。
文字列プロパティーを検索し、それを返します。
文字列配列プロパティーを検索し、それを返します。
バイト配列プロパティーを検索し、それを返します。
ddi_prop_update
整数プロパティーを更新または作成します。
単一の 64 ビットの整数プロパティーを更新または作成します。
整数配列プロパティーを更新または作成します。
文字列プロパティーを更新または作成します。
文字列配列プロパティーを更新または作成します。
64 ビットの整数配列プロパティーを更新または作成します。
バイト配列プロパティーを更新または作成します。
ddi_prop_remove
プロパティーを削除します。
デバイスに関連付けられているすべてのプロパティーを削除します。

int プロパティーインタフェースを使用するときは、できるだけ ddi_prop_update_int64(9F) などの 32 ビットバージョンではなく、ddi_prop_update_int(9F) などの 64 ビットバージョンを使用してください。

driver.conf ファイルへの変更

Oracle Solaris OS が稼働するシステムをアップグレードすると、新しいバージョンのドライバがインストールされる可能性があります。そのアップグレードプロセスの間、システム上の driver.conf ファイルも更新されます。driver.conf ファイルのカスタマイズは、ベンダーとシステム管理者の両方によって行われます。システムのアップグレード時には、システムの以前の構成が引き続き、新しいドライバ、ベンダーの driver.conf ファイル、および管理者の driver.conf ファイルとともに動作するようにしてください。

Oracle Solaris 11 リリースでは、ベンダー提供のドライバデータを含む driver.conf ファイルを別途提供するオプションがドライバの開発者に用意されています。新しい driver.conf ファイルは /etc/driver/drv ディレクトリに格納されます。これによりシステムは、このファイルに対して行われた管理変更をすべて保持できます。ドライバが両方の構成ファイル内で見つかった場合、システムはそれらのファイルをマージし、すべてのプロパティーを含むファイルを提供します。ベンダーの driver.conf ファイルの形式は、管理者のドライバ構成ファイルと同じです。

ベンダー構成データと管理構成データは、新しいインタフェース経由でドライバから明示的に使用できるようになりました。このため、ドライバ開発者は、すべてのマージロジックのエンコードを、クラスアクションスクリプト内やインストール前およびインストール後スクリプト内ではなく、ドライバ内で直接行えます。管理ファイルに対して行われたカスタマイズは保持されるため、ドライバ内で新しい値と古い値の関係について判定を行うことができます。

ドライバで前述のモデルが正しく機能するようにするために、ドライバ開発者は次を考慮すべきです。

例 4-1 ドライバはローカルで構成されたタイムアウト値をチェックする

     * Has the timeout been locally configured using the
+     * prior option of timeout in units of seconds?
+     */
+    if (ddi_prop_lookup_int(DDI_DEV_T_ANY, dip,
+        DDI_PROP_ADMIN, "timeout",&ivalues,&n) ==
+        DDI_PROP_SUCCESS) {
+        if (n != 1) {
+            ddi_prop_free(ivalues);
+            return (EINVAL);
+        }
+        /* yes - convert our working timeout accordingly */
+        dip->ms_timeout = 1000 * ivalues[0];
+        /* record the new parameter setting for confirmation */
+        (void) ddi_prop_update_int(DDI_DEV_T_NONE,
+            dip, "ms-timeout", dip->ms_timeout);
+        ddi_prop_free(ivalues);
+    }

prtconf(1M) コマンドではドライバのプロパティーが表示されますが、新しい -u オプションを使うと、元のプロパティー値と変更後のプロパティー値を表示できます。

prop_op() エントリポイント

prop_op(9E) エントリポイントは通常、デバイスプロパティーまたはドライバプロパティーの値をシステムに報告するために必要です。ドライバが専用のプロパティーを作成または管理する必要がない場合は、ddi_prop_op(9F) 関数をこのエントリポイントに使用できます。

ddi_prop_op() がデバイスドライバの cb_ops(9S) 構造体で定義されている場合は、ddi_prop_op(9F) をそのドライバの prop_op(9E) エントリポイントとして使用できます。ddi_prop_op() を使用すると、リーフデバイスでプロパティー値を検索して、それをデバイスのプロパティーリストから取得できます。

頻繁に値が変わるプロパティーをドライバで保持する必要がある場合は、ddi_prop_op() を呼び出すのではなく、cb_ops 構造体の中にドライバ固有の prop_op() ルーチンを定義します。この手法により、ddi_prop_update() を繰り返し使用するという非効率性を解消できます。ドライバは、そのソフト状態構造体の中またはドライバ変数でプロパティー値のコピーを保持します。

prop_op(9E) エントリポイントは、特定のドライバプロパティーやデバイスプロパティーの値をシステムに報告します。多くの場合、ddi_prop_op(9F) ルーチンは、cb_ops(9S) 構造体でドライバの prop_op() エントリポイントとして使用できます。ddi_prop_op() は、必要なすべての処理を実行します。デバイスプロパティーリクエストの処理時に特別な処理を必要としないドライバには、ddi_prop_op() で十分です。

ただし、ドライバが prop_op() エントリポイントを提供することが必要な場合があります。たとえば、頻繁に値が変わるプロパティーをドライバで保持する場合、変更のたびに ddi_prop_update(9F) を使用してプロパティーを更新することは効率的ではありません。代わりに、ドライバはインスタンスのソフト状態によってプロパティーのシャドウコピーを保持します。ドライバは、プロパティーの値が変わると、ddi_prop_update() ルーチンを一切使わずにシャドウコピーを更新します。prop_op() エントリポイントは、ddi_prop_op() にリクエストを渡してプロパティーリクエストを処理する前に、このプロパティーのリクエストを遮断し、いずれかの ddi_prop_update() ルーチンを使用してプロパティーの値を更新する必要があります。

次の例では、prop_op()temperature プロパティーの要求を遮断しています。ドライバは、プロパティーが変わるたびに状態構造体で変数を更新します。ただし、プロパティーが更新されるのは、要求が出されたときだけです。その際、ドライバは ddi_prop_op() を使用してプロパティーリクエストを処理します。プロパティー要求がデバイスに固有のものでない場合、ドライバはその要求を遮断しません。このような状況は、dev パラメータの値が DDI_DEV_T_ANY (ワイルドカードのデバイス番号) である場合に示されます。

例 4-2 prop_op() ルーチン

static int
xx_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
    int flags, char *name, caddr_t valuep, int *lengthp)
{
        minor_t instance;
        struct xxstate *xsp;
        if (dev != DDI_DEV_T_ANY) {
                return (ddi_prop_op(dev, dip, prop_op, flags, name,
                    valuep, lengthp));
        }

        instance = getminor(dev);
        xsp = ddi_get_soft_state(statep, instance);
        if (xsp == NULL)
                return (DDI_PROP_NOTFOUND);
        if (strcmp(name, "temperature") == 0) {
                ddi_prop_update_int(dev, dip, name, temperature);
        }

        /* other cases */    
}