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.  プロパティー

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

6.  ドライバの自動構成

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

8.  割り込みハンドラ

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

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

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

12.  電源管理

13.  Oracle Solaris ドライバの強化

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

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

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

文字ドライバの構造の概要

文字デバイスの自動構成

デバイスアクセス (文字ドライバ)

open() エントリポイント (文字ドライバ)

close() エントリポイント (文字ドライバ)

入出力要求の処理

ユーザーアドレス

ベクトル化された入出力

同期入出力と非同期入出力の違い

データ転送方法

プログラム式入出力転送

DMA 転送 (同期)

DMA 転送 (非同期)

minphys() エントリポイント

strategy() エントリポイント

デバイスメモリーのマッピング

ファイル記述子に対する入出力の多重化

その他の入出力制御

ioctl() エントリポイント (文字ドライバ)

64 ビットに対応したデバイスドライバに対する入出力制御のサポート

copyout() のオーバーフローの処理

32 ビットと 64 ビットのデータ構造体マクロ

構造体マクロの動作のしくみ

構造体マクロを使用する場合

構造体ハンドルの宣言と初期化

構造体ハンドルに対する操作

その他の操作

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
貴重なご意見を有り難うございました!

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

ファイル記述子に対する入出力の多重化

スレッドは、時には複数のファイル記述子に対する入出力を処理することが必要になります。1 つの例として、温度検知デバイスから温度を読み取ったあと、その温度を対話型ディスプレイに報告する必要があるアプリケーションプログラムがあります。使用可能なデータがない状態で読み取り要求を行うプログラムは、ユーザーとふたたび対話する前の、温度の待機中にブロックされるべきではありません。

poll(2) システムコールはユーザーに、開かれたファイルを参照する一連のファイル記述子に対する入出力を多重化するためのメカニズムを提供します。poll(2) は、プログラムがブロックを使用せずにデータを送受信できるファイル記述子、または特定のイベントが発生したファイル記述子を識別します。

プログラムが文字ドライバをポーリングできるようにするには、そのドライバが chpoll(9E) エントリポイントを実装する必要があります。システムは、ユーザープロセスが、デバイスに関連付けられたファイル記述子に対する poll(2) システムコールを発行したときに chpoll(9E ) を呼び出します。chpoll(9E) エントリポイントのルーチンは、ポーリングをサポートする必要のある、STREAMS 以外の文字デバイスドライバによって使用されます。

chpoll(9E) 関数は、次の構文を使用します。

int xxchpoll(dev_t dev, short events, int anyyet, short *reventsp,
     struct pollhead **phpp);

chpoll(9E) エントリポイントでは、ドライバは次の規則に従う必要があります。

例 15-10例 15-11 は、ポーリング手法の実装方法および pollwakeup(9F) の使用方法を示しています。

次の例は、POLLIN イベントと POLLERR イベントを処理する方法を示しています。ドライバはまず、デバイスの現在のステータスを判定するために、ステータスレジスタを読み取ります。パラメータ events は、ドライバがチェックする条件を指定します。該当する条件が発生した場合、ドライバは *reventsp 内のそのビットを設定します。どの条件も発生せず、かつ anyyet が設定されていない場合は、pollhead 構造体のアドレスが *phpp で返されます。

例 15-10 chpoll(9E) ルーチン

static int
xxchpoll(dev_t dev, short events, int anyyet,
    short *reventsp, struct pollhead **phpp)
{
     uint8_t status;
     short revent;
     struct xxstate *xsp;

     xsp = ddi_get_soft_state(statep, getminor(dev));
     if (xsp == NULL)
         return (ENXIO);
     revent = 0;
     /*
      * Valid events are:
      * POLLIN | POLLOUT | POLLPRI | POLLHUP | POLLERR
      * This example checks only for POLLIN and POLLERR.
      */
     status = ddi_get8(xsp->data_access_handle, &xsp->regp->csr);
     if ((events & POLLIN) && data available to read) {
        revent |= POLLIN;
     }
     if (status & DEVICE_ERROR) {
        revent |= POLLERR;
     }
     /* if nothing has occurred */
     if (revent == 0) {
        if (!anyyet) {
        *phpp = &xsp->pollhead;
        }
     }
       *reventsp = revent;
     return (0);
}

次の例は、pollwakeup(9F) 関数の使用方法を示しています。pollwakeup(9F) 関数は通常、サポートされている条件が発生したときに割り込みルーチンで呼び出されます。割り込みルーチンはステータスレジスタからステータスを読み取り、これらの条件をチェックします。次に、ポーリングスレッドにもう一度チェックすることを通知するために、イベントごとに pollwakeup(9F) を呼び出します。何らかのロックが保持された状態で pollwakeup(9F) を呼び出すと、別のルーチンが chpoll(9E) に入り、同じロックをつかもうとしてデッドロックが発生する可能性があるため、これを行うべきではないことに注意してください。

例 15-11 chpoll(9E) をサポートしている割り込みルーチン

static u_int
xxintr(caddr_t arg)
{
     struct xxstate *xsp = (struct xxstate *)arg;
     uint8_t    status;
     /* normal interrupt processing */
     /* ... */
     status = ddi_get8(xsp->data_access_handle, &xsp->regp->csr);
     if (status & DEVICE_ERROR) {
        pollwakeup(&xsp->pollhead, POLLERR);
     }
     if ( /* just completed a read */ ) {
        pollwakeup(&xsp->pollhead, POLLIN);
     }
     /* ... */
     return (DDI_INTR_CLAIMED);
}