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.  文字デバイスのドライバ

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

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

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

ホストバスアダプタドライバの概要

SCSI インタフェース

SCSA HBA インタフェース

SCSA HBA エントリポイントのサマリー

SCSA HBA データ構造体

scsi_hba_tran() 構造体

scsi_address 構造体

scsi_device 構造体

scsi_pkt 構造体 (HBA)

ターゲットインスタンスごとのデータ

トランスポート構造体の複製

SCSA HBA 関数

HBA ドライバの依存性と構成に関する問題

宣言と構造体

コマンド別構造体

モジュール初期化用のエントリポイント

_init() エントリポイント (SCSI HBA ドライバ)

_fini() エントリポイント (SCSI HBA ドライバ)

自動構成のエントリポイント

attach() エントリポイント (SCSI HBA ドライバ)

detach() エントリポイント (SCSI HBA ドライバ)

SCSA HBA ドライバのエントリポイント

ターゲットドライバインスタンスの初期化

tran_tgt_init() エントリポイント

tran_tgt_probe() エントリポイント

tran_tgt_free() エントリポイント

資源割り当て

tran_init_pkt() エントリポイント

scsi_pkt(9S) 構造体の割り当てと初期化

DMA 資源の割り当て

データ転送のための DMA 資源の再割り当て

tran_destroy_pkt() エントリポイント

tran_sync_pkt() エントリポイント

tran_dmafree() エントリポイント

コマンドのトランスポート

tran_start() エントリポイント

割り込みハンドラとコマンドの完了

タイムアウトハンドラ

機能管理

tran_getcap() エントリポイント

tran_setcap() エントリポイント

中止およびリセット管理

tran_abort() エントリポイント

tran_reset() エントリポイント

tran_bus_reset() エントリポイント

tran_reset_notify() エントリポイント

動的再構成 (DR)

SCSI HBA ドライバに固有の問題

HBA ドライバのインストール

HBA の構成プロパティー

scsi-reset-delay プロパティー

scsi-options プロパティー

ターゲットごとの scsi-options

x86 ターゲットドライバの構成プロパティー

キューイングのサポート

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

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

SCSA HBA インタフェース

SCSA HBA インタフェースには、HBA エントリポイント、HBA データ構造体、および HBA フレームワークが含まれています。

SCSA HBA エントリポイントのサマリー

SCSA では、HBA ドライバのエントリポイントをいくつか定義しています。次の表に、これらのエントリポイントを示します。このエントリポイントは、HBA ドライバに接続されたターゲットドライバインスタンスが構成されるときにシステムから呼び出されます。また、ターゲットドライバが SCSA 要求を出したときにも呼び出されます。詳細については、「SCSA HBA ドライバのエントリポイント」を参照してください。

表 18-1 SCSA HBA エントリポイントのサマリー

関数名
呼び出される原因となる操作
ターゲットドライバによる scsi_abort(9F) の呼び出し
システムによるバスのリセット
ターゲットドライバによる scsi_destroy_pkt(9F) の呼び出し
ターゲットドライバによる scsi_dmafree(9F) の呼び出し
ターゲットドライバによる scsi_ifgetcap(9F) の呼び出し
ターゲットドライバによる scsi_init_pkt(9F) の呼び出し
システムによるバスの休止
ターゲットドライバによる scsi_reset(9F) の呼び出し
ターゲットドライバによる scsi_reset_notify(9F) の呼び出し
ターゲットドライバによる scsi_ifsetcap(9F) の呼び出し
ターゲットドライバによる scsi_transport(9F) の呼び出し
ターゲットドライバによる scsi_sync_pkt(9F) の呼び出し
tran_tgt_free(9E)
システムによるターゲットデバイスインスタンスの切り離し
tran_tgt_init(9E)
システムによるターゲットデバイスインスタンスの接続
tran_tgt_probe(9E)
ターゲットドライバによる scsi_probe(9F) の呼び出し
システムによるバス上の動作の再開

SCSA HBA データ構造体

SCSA では、データ構造体を定義して、ターゲットドライバと HBA ドライバ間で情報交換ができるようにしています。含まれているデータ構造体は次のとおりです。

scsi_hba_tran() 構造体

HBA ドライバの各インスタンスでは、scsi_hba_tran(9S) エントリポイントで scsi_hba_tran_alloc(9F) 関数を使用して attach(9E) 構造体を割り当てる必要があります。scsi_hba_tran_alloc() 関数は、scsi_hba_tran 構造体を初期化します。HBA ドライバは、HBA ドライバ内のエントリポイントを指すように、トランスポート構造体にある特定のベクトルを初期化する必要があります。scsi_hba_tran 構造体が初期化されたあとで、HBA ドライバは scsi_hba_attach_setup(9F) 関数を呼び出して、このトランスポート構造体を SCSA にエクスポートします。


注意

注意 - SCSA ではトランスポート構造体を指すポインタを devinfo ノード上のドライバの非公開フィールドに保持するため、HBA ドライバは ddi_set_driver_private(9F) を使用してはいけません。ただし、ddi_get_driver_private(9F) を使用して、トランスポート構造体を指すポインタを検出することはできます。


SCSA インタフェースでは、HBA ドライバは scsi_hba_tran 構造体を介して呼び出し可能ないくつかのエントリポイントを提供する必要があります。詳細については、「SCSA HBA ドライバのエントリポイント」を参照してください。

scsi_hba_tran 構造体には、次のフィールドがあります。

struct scsi_hba_tran {
    dev_info_t          *tran_hba_dip;          /* HBAs dev_info pointer */
    void                *tran_hba_private;      /* HBA softstate */
    void                *tran_tgt_private;      /* HBA target private pointer */
    struct scsi_device  *tran_sd;               /* scsi_device */
    int                 (*tran_tgt_init)();     /* Transport target */
                                                /* Initialization */
    int                 (*tran_tgt_probe)();    /* Transport target probe */
    void                (*tran_tgt_free)();     /* Transport target free */
    int                 (*tran_start)();        /* Transport start */
    int                 (*tran_reset)();        /* Transport reset */
    int                 (*tran_abort)();        /* Transport abort */
    int                 (*tran_getcap)();       /* Capability retrieval */
    int                 (*tran_setcap)();       /* Capability establishment */
    struct scsi_pkt     *(*tran_init_pkt)();    /* Packet and DMA allocation */
    void                (*tran_destroy_pkt)();  /* Packet and DMA */
                                                /* Deallocation */
    void                (*tran_dmafree)();      /* DMA deallocation */
    void                (*tran_sync_pkt)();     /* Sync DMA */
    void                (*tran_reset_notify)(); /* Bus reset notification */
    int                 (*tran_bus_reset)();    /* Reset bus only */
    int                 (*tran_quiesce)();      /* Quiesce a bus */
    int                 (*tran_unquiesce)();    /* Unquiesce a bus */
    int                 tran_interconnect_type; /* transport interconnect */
};

次に、scsi_hba_tran 構造体の各フィールドについて詳しく説明します。

tran_hba_dip

HBA デバイスインスタンスの dev_info 構造体を指すポインタです。このフィールドは、scsi_hba_attach_setup(9F) 関数によって設定されます。

tran_hba_private

HBA ドライバによって保持される非公開データを指すポインタです。通常、tran_hba_private には、HBA ドライバの状態構造体を指すポインタが入ります。

tran_tgt_private

複製の使用時に HBA ドライバによって保持される非公開データを指すポインタです。scsi_hba_attach_setup(9F) の呼び出し時に SCSI_HBA_TRAN_CLONE を指定することにより、scsi_hba_tran(9S) 構造体が 1 つのターゲットにつき 1 度だけ複製されます。この方法により、HBA は tran_tgt_init(9E) エントリポイントでターゲットインスタンスごとのデータ構造体を指すようにこのフィールドを初期化できます。SCSI_HBA_TRAN_CLONE を指定しない場合、tran_tgt_privateNULL となり、tran_tgt_private が参照されることはありません。詳細については、「トランスポート構造体の複製」を参照してください。

tran_sd

複製時に使用されるターゲットインスタンスごとの scsi_device(9S) 構造体を指すポインタです。SCSI_HBA_TRAN_CLONEscsi_hba_attach_setup(9F) に渡された場合、tran_sd はターゲットごとの scsi_device 構造体を指すように初期化されます。この初期化は、そのターゲットに代わって HBA 関数が呼び出される前に行われます。SCSI_HBA_TRAN_CLONE を指定しない場合、tran_sdNULL となり、tran_sd が参照されることはありません。詳細については、「トランスポート構造体の複製」を参照してください。

tran_tgt_init

ターゲットデバイスインスタンスの初期化時に呼び出される HBA ドライバのエントリポイントを指すポインタです。ターゲットごとの初期化が必要ない場合、HBA は tran_tgt_initNULL に設定しておくことができます。

tran_tgt_probe

ターゲットドライバインスタンスが scsi_probe(9F) を呼び出したときに呼び出される HBA ドライバのエントリポイントを指すポインタです。このルーチンは、ターゲットデバイスの存在を調べるために呼び出されます。この HBA にターゲットのプローブカスタマイズが必要ない場合、HBA は tran_tgt_probescsi_hba_probe(9F) に設定します。

tran_tgt_free

ターゲットデバイスのインスタンスが破棄されるときに呼び出される HBA ドライバのエントリポイントを指すポインタです。ターゲットごとの解放が必要ない場合、HBA は tran_tgt_freeNULL に設定しておくことができます。

tran_start

ターゲットドライバが scsi_transport(9F) を呼び出したときに呼び出される HBA ドライバのエントリポイントを指すポインタです。

tran_reset

ターゲットドライバが scsi_reset(9F) を呼び出したときに呼び出される HBA ドライバのエントリポイントを指すポインタです。

tran_abort

ターゲットドライバが scsi_abort(9F) を呼び出したときに呼び出される HBA ドライバのエントリポイントを指すポインタです。

tran_getcap

ターゲットドライバが scsi_ifgetcap(9F) を呼び出したときに呼び出される HBA ドライバのエントリポイントを指すポインタです。

tran_setcap

ターゲットドライバが scsi_ifsetcap(9F) を呼び出したときに呼び出される HBA ドライバのエントリポイントを指すポインタです。

tran_init_pkt

ターゲットドライバが scsi_init_pkt(9F) を呼び出したときに呼び出される HBA ドライバのエントリポイントを指すポインタです。

tran_destroy_pkt

ターゲットドライバが scsi_destroy_pkt(9F) を呼び出したときに呼び出される HBA ドライバのエントリポイントを指すポインタです。

tran_dmafree

ターゲットドライバが scsi_dmafree(9F) を呼び出したときに呼び出される HBA ドライバのエントリポイントを指すポインタです。

tran_sync_pkt

ターゲットドライバが scsi_sync_pkt(9F) を呼び出したときに呼び出される HBA ドライバのエントリポイントを指すポインタです。

tran_reset_notify

ターゲットドライバが tran_reset_notify(9E) を呼び出したときに呼び出される HBA ドライバのエントリポイントを指すポインタです。

tran_bus_reset

ターゲットをリセットしないで SCSI バスをリセットする関数エントリです。

tran_quiesce

未処理のコマンドが完了するのを待ち、発行されたすべての入出力要求をブロックする (またはキューに入れる) 関数エントリです。

tran_unquiesce

入出力動作が SCSI バス上で再開できるようにする関数エントリです。

tran_interconnect_type

services.h ヘッダーファイルに定義されたとおりにトランスポートの相互接続タイプを示す整数値です。

scsi_address 構造体

scsi_address(9S) 構造体は、ターゲットドライバのインスタンスによって割り当てられ、トランスポートされる各 SCSI コマンドのトランスポートとアドレス指定の情報を提供します。

scsi_address 構造体には、次のフィールドがあります。

struct scsi_address {
    struct scsi_hba_tran    *a_hba_tran;    /* Transport vectors */
    ushort_t                a_target;       /* Target identifier */
    uchar_t                 a_lun;          /* LUN on that target */
    uchar_t                 a_sublun;       /* Sub LUN on that LUN */
                                            /* Not used */
};
a_hba_tran

HBA ドライバによって割り当てられ、初期化されたときの scsi_hba_tran(9S) 構造体を指すポインタです。scsi_hba_attach_setup(9F) のフラグとして SCSI_HBA_TRAN_CLONE を指定した場合、a_hba_tran はその構造体のコピーを指します。

a_target

SCSI バス上の SCSI ターゲットを識別します。

a_lun

SCSI ターゲット上の SCSI 論理ユニットを識別します。

scsi_device 構造体

HBA フレームワークでは、ターゲットデバイスのインスタンスごとに scsi_device(9S) 構造体を割り当て、初期化します。この割り当てと初期化は、フレームワークで HBA ドライバの tran_tgt_init(9E) エントリポイントを呼び出す前に行われます。この構造体には、一般的な情報とデバイス固有の情報を含む情報領域を指すポインタなど、各 SCSI 論理ユニットに関する情報が格納されます。システムに接続されているターゲットデバイスインスタンスごとに 1 つの scsi_device(9S) 構造体が存在します。

ターゲットごとの初期化が正常に行われると、HBA フレームワークは ddi_set_driver_private(9F) を使用して、ターゲットドライバのインスタンスごとの非公開データが scsi_device(9S) 構造体を指すように設定します。初期化が正常に行われるのは、tran_tgt_init() が成功を返した場合またはベクトルが null の場合です。

scsi_device(9S) 構造体には、次のフィールドがあります。

struct scsi_device {
    struct scsi_address           sd_address;    /* routing information */
    dev_info_t                    *sd_dev;       /* device dev_info node */
    kmutex_t                      sd_mutex;      /* mutex used by device */
    void                          *sd_reserved;
    struct scsi_inquiry           *sd_inq;
    struct scsi_extended_sense    *sd_sense;
    caddr_t                       sd_private;    /* for driver's use */
};

各表記の意味は次のとおりです。

sd_address

SCSI 資源の割り当てのためのルーチンに渡されるデータ構造体です。

sd_dev

ターゲットの dev_info 構造体を指すポインタです。

sd_mutex

ターゲットドライバが使用する mutex です。この mutex は、HBA フレームワークによって初期化されます。ターゲットドライバは、この mutex をデバイスごとの mutex として使用できます。この mutex は、scsi_transport(9F) または scsi_poll(9F) が呼び出されると保持されません。mutex の詳細については、第 3 章マルチスレッドを参照してください。

sd_inq

ターゲットデバイスの SCSI 照会データへのポインタです。scsi_probe(9F) ルーチンは、バッファーを割り当て、そのバッファーを満たして、このフィールドに追加します。

sd_sense

デバイスから送られた要求検知データを収めるバッファーを指すポインタです。ターゲットドライバは、このバッファーそのものを割り当てて管理する必要があります。詳細については、attach() エントリポイント」 に記載されたターゲットドライバの attach(9E) ルーチンを参照してください。

sd_private

ターゲットドライバが使用するポインタフィールドです。このフィールドは、ターゲットドライバの非公開の状態構造体を指すポインタの格納によく使われます。

scsi_pkt 構造体 (HBA)

SCSI コマンドを実行するには、ターゲットドライバはまずそのコマンドに scsi_pkt(9S) 構造体を割り当てる必要があります。次に、そのターゲットドライバ専用の非公開データ領域の大きさ、コマンドのステータス、およびコマンドの長さを指定する必要があります。HBA ドライバは、tran_init_pkt(9E) エントリポイントでパケット割り当てを実装します。また、その tran_destroy_pkt(9E) エントリポイントでパケットの解放を行います。詳細については、scsi_pkt 構造体 (ターゲットドライバ)」を参照してください。

scsi_pkt(9S) 構造体には、次のフィールドがあります。

struct scsi_pkt {
    opaque_t pkt_ha_private;             /* private data for host adapter */
    struct scsi_address pkt_address;     /* destination address */
    opaque_t pkt_private;                /* private data for target driver */
    void (*pkt_comp)(struct scsi_pkt *); /* completion routine */
    uint_t  pkt_flags;                   /* flags */
    int     pkt_time;                    /* time allotted to complete command */
    uchar_t *pkt_scbp;                   /* pointer to status block */
    uchar_t *pkt_cdbp;                   /* pointer to command block */
    ssize_t pkt_resid;                   /* data bytes not transferred */
    uint_t  pkt_state;                   /* state of command */
    uint_t  pkt_statistics;              /* statistics */
    uchar_t pkt_reason;                  /* reason completion called */
};

各表記の意味は次のとおりです。

pkt_ha_private

コマンドごとの HBA ドライバの非公開データを指すポインタです。

pkt_address

このコマンドのアドレス情報を提供する scsi_address(9S) 構造体を指すポインタです。

pkt_private

パケットごとのターゲットドライバの非公開データを指すポインタです。

pkt_comp

トランスポート層でこのコマンドが実行されたときに HBA ドライバによって呼び出されるターゲットドライバ完了ルーチンを指すポインタです。

pkt_flags

コマンドのフラグです。

pkt_time

コマンドの完了タイムアウトを秒単位で指定します。

pkt_scbp

コマンドのステータス完了ブロックを指すポインタです。

pkt_cdbp

コマンドのコマンド記述子ブロック (CDB) を指すポインタです。

pkt_resid

コマンドが完了したときに転送されなかったデータバイト数です。このフィールドを使用すると、資源が割り当てられなかったデータの量も指定できます。HBA は、トランスポート時にこのフィールドを変更する必要があります。

pkt_state

コマンドの状態です。HBA は、トランスポート時にこのフィールドを変更する必要があります。

pkt_statistics

トランスポート層に存在している間に、コマンドが検出したイベントの履歴を提供します。HBA は、トランスポート時にこのフィールドを変更する必要があります。

pkt_reason

コマンド完了の理由です。HBA は、トランスポート時にこのフィールドを変更する必要があります。

ターゲットインスタンスごとのデータ

HBA ドライバは、attach(9E) の実行中に scsi_hba_tran(9S) 構造体を割り当てる必要があります。次に、HBA ドライバは、HBA ドライバの必須のエントリポイントを指すように、このトランスポート構造体にあるベクトルを初期化する必要があります。その後、この scsi_hba_tran 構造体は scsi_hba_attach_setup(9F) に渡されます。

scsi_hba_tran 構造体には tran_hba_private フィールドがあり、HBA ドライバのインスタンスごとの状態を参照するために使用できます。

scsi_address(9S) 構造体には、scsi_hba_tran 構造体を指すポインタが含まれています。また、scsi_address 構造体には、特定のターゲットデバイスのターゲット (a_target) と論理ユニット (a_lun) のアドレスもあります。HBA ドライバの各エントリポイントには、scsi_address 構造体を指すポインタが直接渡されるか、scsi_device(9S) 構造体を経由して間接的に渡されます。その結果、HBA ドライバは自身の状態を参照できます。HBA ドライバは、アドレス指定されているターゲットデバイスを識別することもできます。

次の図は、トランスポート操作のための HBA データ構造体を示しています。

図 18-3 HBA トランスポート構造体

image:図では、HBA トランスポート層に含まれる構造体の関係を示しています。

トランスポート構造体の複製

HBA ドライバが scsi_hba_tran(9S) 構造体でターゲットごとの非公開データを保持する必要がある場合は、クローニングが役立つことがあります。複製は、scsi_address(9S) 構造体で提供されるアドレスよりも複雑なアドレスを保持するためにも使用できます。

複製プロセスでは、HBA ドライバは引き続き attach(9E) の実行時に scsi_hba_tran 構造体を割り当てる必要があります。また、HBA ドライバの tran_hba_private ソフト状態ポインタとエントリポイントベクトルを初期化する必要もあります。違いが生じるのは、フレームワークがターゲットドライバのインスタンスを HBA ドライバに接続開始するときです。HBA ドライバの tran_tgt_init(9E) エントリポイントを呼び出す前に、フレームワークでは HBA のそのインスタンスに関連付けられている scsi_hba_tran 構造体を複製します。その結果、特定のターゲットデバイスインスタンスに割り当てられ、初期化された各 scsi_address 構造体は、scsi_hba_tran 構造体のターゲットインスタンスごとのコピーを指します。scsi_address 構造体は、attach() の実行時に HBA ドライバによって割り当てられた scsi_hba_tran 構造体を指しません。

複製の指定時には、HBA ドライバは 2 つの重要なポインタを使用できます。これらのポインタは、scsi_hba_tran 構造体に含まれています。最初のポインタは tran_tgt_private フィールドであり、ドライバがターゲットごとの HBA 非公開データを指すために使用できます。 tran_tgt_private ポインタは、HBA ドライバが a_targeta_lun で提供されるアドレスよりも複雑なアドレスを保持する必要がある場合などに役立ちします。2 番目のポインタは tran_sd フィールドであり、これは特定のターゲットデバイスを参照する scsi_device(9S) 構造体を指すポインタです。

複製の指定時は、HBA ドライバはターゲットごとのデータを割り当て、初期化する必要があります。次に、HBA ドライバは、その tran_tgt_init(9E) エントリポイントの実行中にこのデータを指すように tran_tgt_private フィールドを初期化する必要があります。HBA ドライバは、その tran_tgt_free(9E) エントリポイントの実行中に、このターゲットごとのデータを解放する必要があります。

複製時にフレームワークでは、HBA ドライバの tran_tgt_init() エントリポイントが呼び出される前に、scsi_device 構造体を指すように tran_sd フィールドを初期化します。ドライバが複製を要求するときは、SCSI_HBA_TRAN_CLONE フラグを scsi_hba_attach_setup(9F) に渡します。次の図は、トランスポート操作を複製するための HBA データ構造体を示しています。

図 18-4 トランスポート操作の複製

image:図は、複製された HBA 構造体の例を示しています。

SCSA HBA 関数

SCSA では、いくつかの関数も提供しています。これらの関数は次の表に一覧表示されており、HBA ドライバで使用されます。

表 18-2 SCSA HBA 関数

関数名
呼び出し元のドライバエントリポイント