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

ドキュメントの情報

はじめに

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

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

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

3.  マルチスレッド

4.  プロパティー

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

6.  ドライバの自動設定

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

デバイスメモリー

デバイスとホストのエンディアンの違いの管理

データ順序付け要件の管理

ddi_device_acc_attr 構造体

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

マッピングの設定例

デバイスアクセス関数

代替のデバイスアクセスインタフェース

メモリー空間アクセス

入出力空間アクセス

PCI 構成空間アクセス

8.  割り込みハンドラ

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

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

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

12.  電源管理

13.  Solaris ドライバの強化

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

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

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

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

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

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

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

20.  USB ドライバ

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

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

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

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

パート IV 付録

A.  ハードウェアの概要

B.  Solaris DDI/DKI サービスの概要

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

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

索引

デバイスアクセス関数

ドライバは、ddi_get8(9F) および ddi_put8(9F) ルーチンファミリと、ddi_regs_map_setup(9F) から返されたハンドルとを組み合わせて使用することで、デバイス間でデータを転送します。DDI フレームワークは、ホストまたはデバイスのエンディアン形式に合わせるために必要なすべてのバイトスワップを自動的に処理するとともに、デバイスで発生する可能性のあるすべての格納順序付け制約を適用します。

DDI には、8 ビット、16 ビット、32 ビット、64 ビットの各サイズでデータを転送するためのインタフェースが用意されているほか、複数の値を繰り返し転送するためのインタフェースも用意されています。ddi_get8(9F)ddi_put8(9F)ddi_rep_get8(9F)、および ddi_rep_put8(9F) ルーチンファミリのマニュアルページで、一覧表やこれらのインタフェースの説明を参照してください。

次の例は、ドライバ内でデバイスの CSR レジスタとデータレジスタのマッピングを行った例 7-1 に基づいたものです。このドライバの write(9E) エントリポイントは、呼び出し時にデータバッファーを一度に 1 バイトずつデバイスに書き込みます。

例 7-2 マッピングの設定: バッファー

static  int
pio_write(dev_t dev, struct uio *uiop, cred_t *credp)
{
    int  retval;
    int  error = OK;
    Pio *pio_p = ddi_get_soft_state(pio_softstate, getminor(dev));
    if (pio_p == NULL)
    return (ENXIO);
    mutex_enter(&pio_p->mutex);
    /*
     * enable interrupts from the device by setting the Interrupt
     * Enable bit in the devices CSR register
     */
    ddi_put8(pio_p->csr_handle, pio_p->csr,
      (ddi_get8(pio_p->csr_handle, pio_p->csr) | PIO_INTR_ENABLE));
    while (uiop->uio_resid > 0) {
    /*
     * This device issues an IDLE interrupt when it is ready
     * to accept a character; the interrupt can be cleared
     * by setting PIO_INTR_CLEAR.  The interrupt is reasserted
     * after the next character is written or the next time
     * PIO_INTR_ENABLE is toggled on.
     *
     * wait for interrupt (see pio_intr)
     */
     cv_wait(&pio_p->cv, &pio_p->mutex);
     /*
      * get a character from the user's write request
      * fail the write request if any errors are encountered
      */
     if ((retval = uwritec(uiop)) == -1) {
         error = retval;
         break;
     }
     /*
      * pass the character to the device by writing it to
      * the device's data register
      */
     ddi_put8(pio_p->data_handle, pio_p->data, (uchar_t)retval);
    }
    /*
     * disable interrupts by clearing the Interrupt Enable bit
     * in the CSR
     */
    ddi_put8(pio_p->csr_handle, pio_p->csr,
      (ddi_get8(pio_p->csr_handle, pio_p->csr) & ~PIO_INTR_ENABLE));
    mutex_exit(&pio_p->mutex);
    return (error);
}

代替のデバイスアクセスインタフェース

Solaris OS には、ddi_get8(9F) および ddi_put8(9F) インタフェースファミリ経由ですべてのデバイスアクセスを実装する方法だけでなく、特定のバス実装に固有のインタフェースも用意されています。これらの関数は一部のプラットフォームで効率が高くなる可能性もありますが、これらのルーチンを使用すると、デバイスのさまざまなバスバージョンでのドライバの移植性が低下する可能性があります。

メモリー空間アクセス

メモリーマップアクセスでは、デバイスレジスタがメモリーアドレス空間に現れます。ddi_getX および ddi_putX ルーチンファミリが、標準のデバイスアクセスインタフェースの代替手段としてドライバから使用可能となっています。

入出力空間アクセス

入出力空間アクセスでは、デバイスレジスタが入出力空間に現れます。このとき、アドレス指定可能な各要素は入出力ポートと呼ばれます。ddi_io_get8(9F) および ddi_io_put8(9F) ルーチンが、標準のデバイスアクセスインタフェースの代替手段としてドライバから使用可能となっています。

PCI 構成空間アクセス

通常のデバイスアクセスインタフェースを使用しないで PCI 構成空間にアクセスするには、ドライバ内で、PCI 構成空間をマップするために、ddi_regs_map_setup(9F) の代わりに pci_config_setup(9F) を呼び出す必要があります。その後ドライバ内で、pci_config_get8(9F) および pci_config_put8(9F) インタフェースファミリを呼び出して PCI 構成空間にアクセスできます。