Oracle® Solaris 11.2 デバイスドライバの記述

印刷ビューの終了

更新: 2014 年 9 月
 
 

SCSA HBA データ構造体

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

scsi_hba_tran() 構造体

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


Caution

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


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

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 つのターゲットにつき一度だけクローニングされます。この方法により、HBA はtran_tgt_init (9E) エントリポイントでターゲットインスタンスごとのデータ構造体を指すようにこのフィールドを初期化できます。SCSI_HBA_TRAN_CLONE を指定しない場合、tran_tgt_private は NULL となり、tran_tgt_private が参照されることがあってはなりません。詳細については、Transport Structure Cloningを参照してください。

tran_sd

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

tran_tgt_init

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

tran_tgt_probe

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

tran_tgt_free

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

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 の詳細については、Chapter 3, Multithreadingを参照してください。

sd_inq

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

sd_sense

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

sd_private

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

scsi_pkt 構造体 (HBA)

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

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 は、トランスポート時にこのフィールドを変更する必要があります。