ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
デバイスドライバの記述 Oracle Solaris 10 8/11 Information Library (日本語) |
パート I Solaris プラットフォーム用デバイスドライバの設計
Sun Common SCSI Architecture の概要
probe() エントリポイント (SCSI ターゲットドライバ)
attach() エントリポイント (SCSI ターゲットドライバ)
detach() エントリポイント (SCSI ターゲットドライバ)
getinfo() エントリポイント (SCSI ターゲットドライバ)
21. ドライバのコンパイル、ロード、パッケージ化、およびテスト
SCSI コマンドをデバイスに送信するには、ターゲットドライバで scsi_pkt(9S) 構造体を作成して初期化する必要があります。次に、この構造体をホストバスアダプタドライバに渡す必要があります。
scsi_init_pkt(9F) ルーチンは scsi_pkt(9S) 構造体を割り当てて 0 に設定します。 scsi_init_pkt() は、pkt_private、 *pkt_scbp、および *pkt_cdbp へのポインタも設定します。さらに、scsi_init_pkt () は資源を使用できない場合を処理するコールバック機構を提供します。この関数の構文は次のとおりです。
struct scsi_pkt *scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pktp, struct buf *bp, int cmdlen, int statuslen, int privatelen, int flags, int (*callback)(caddr_t), caddr_t arg)
各表記の意味は次のとおりです。
scsi_address 構造体へのポインタです。ap は、デバイスの scsi_device(9S) 構造体の sd_address フィールドです。
初期化する scsi_pkt(9S) 構造体へのポインタです。このポインタが NULL に設定されている場合、新しいパケットが割り当てられます。
buf(9S) 構造対へのポインタです。このポインタが NULL ではなく、有効なバイトカウントがある場合、DMA 資源が割り当てられます。
SCSI コマンド記述子ブロックの長さ (バイト単位) です。
SCSI ステータス完了ブロックの必要な長さ (バイト単位) です。
pkt_private フィールドのために割り当てるバイト数です。
フラグのセットです。
PKT_CONSISTENT – scsi_alloc_consistent_buf(9F) を使用して DMA バッファーが割り当てられた場合は、このビットを設定する必要があります。この場合、ホストバスアダプタドライバによって、ターゲットドライバのコマンド完了コールバックを実行する前にデータ転送が適切に同期されることが保証されます。
PKT_DMA_PARTIAL – ドライバが部分的な DMA マッピングを受け入れる場合、このビットを設定できます。設定されている場合、scsi_init_pkt(9F) は DDI_DMA_PARTIAL フラグを設定して、DMA 資源を割り当てます。scsi_pkt(9S) 構造体の pkt_resid フィールドは、ゼロ以外の未処理の内容を格納して復帰できます。ゼロ以外の値は、scsi_init_pkt(9F) が DMA 資源を割り当てることができなかったバイト数を示します。
資源を使用できない場合に実行する処理を指定します。NULL_FUNC に設定されている場合、scsi_init_pkt(9F) はすぐに値 NULL を返します。SLEEP_FUNC に設定されている場合、資源が使用可能になるまで scsi_init_pkt() は復帰しません。その他すべての有効なカーネルアドレスは、資源が使用可能になる可能性が高いときに呼び出される関数のアドレスとして解釈されます。
コールバック関数に渡されるパラメータです。
scsi_init_pkt() ルーチンはトランスポート前にデータを同期します。トランスポート後にドライバがデータにアクセスする必要がある場合は、ドライバで scsi_sync_pkt(9F) を呼び出して、中間キャッシュをすべてフラッシュする必要があります。scsi_sync_pkt () ルーチンを使用すると、キャッシュされているすべてのデータを同期できます。
ターゲットドライバが、データの変更後にパケットを再送信する必要がある場合は、scsi_transport(9F) を呼び出す前に scsi_sync_pkt(9F) を呼び出す必要があります。ただし、ターゲットドライバがデータにアクセスする必要がない場合は、トランスポート後に scsi_sync_pkt() を呼び出す必要はありません。
scsi_destroy_pkt(9F) ルーチンは、必要な場合、パケットに関連付けられている、残りすべてのキャッシュデータを同期します。このルーチンは次に、パケットと、関連付けられているコマンド、ステータス、およびターゲットのドライバの非公開データ領域を解放します。このルーチンは、コマンド完了ルーチンで呼び出す必要があります。
ほとんどの入出力要求で、ドライバのエントリポイントに渡されるデータバッファーは、ドライバから直接アクセスされることはありません。バッファーは scsi_init_pkt(9F) に渡されるのみです。ドライバがSCSI コマンドを送信し、その操作対象がドライバ自体が調べているバッファーである場合、バッファーの DMA に整合性が必要です。SCSI 要求検知コマンドがその良い例です。scsi_alloc_consistent_buf(9F) ルーチンは buf(9S) 構造体と、DMA が一定である操作に適したデータバッファーを割り当てます。HBA は、コマンド完了コールバックを実行する前に、必要なバッファーの同期をすべて実行します。
注 - scsi_alloc_consistent_buf(9F) は不足しているシステム資源を使用します。そのため、 scsi_alloc_consistent_buf() は慎重に使用してください。
scsi_free_consistent_buf(9F) は、buf(9S) 構造体と、scsi_alloc_consistent_buf(9F)によって割り当てられた、関連付けられているデータバッファーを解放します。例については、「attach() エントリポイント (SCSI ターゲットドライバ)」と「detach() エントリポイント (SCSI ターゲットドライバ)」を参照してください。