ルーチンscsi_init_pkt(9F) は、この例で示すように、SCSI CDB に領域を割り当て、必要な場合には DMA リソースを割り当てて、pkt_flags フィールドを設定します。
pkt = scsi_init_pkt(&sdp->sd_address, NULL, bp, CDB_GROUP0, 1, 0, 0, SLEEP_FUNC, NULL);
この例では、渡された buf(9S) 構造体ポインタで指定されているように DMA リソースを割り当てるとともに、新しいパケットを作成しています。SCSI CDB はグループ 0 (6 バイト) のコマンドに割り当てられています。pkt_flags フィールドは 0 に設定されていますが、pkt_private フィールドに割り当てられた領域はありません。scsi_init_pkt (9F) に対するこの呼び出しは、SLEEP_FUNC パラメータのため、使用できるリソースが現在ない場合はリソースを待機し続けます。
次のステップは、scsi_setup_cdb (9F) 関数を使用して SCSI CDB を初期化することです。
if (scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp, SCMD_READ, bp->b_blkno, bp->b_bcount >> DEV_BSHIFT, 0) == 0) goto failed;
この例では、グループ 0 のコマンド記述子ブロックを構築しています。この例の pkt_cdbp フィールドには次のように値が格納されます。
コマンド自体はバイト 0 に格納されます。コマンドはパラメータ SCMD_READ から設定されます。
アドレスフィールドはバイト 1、バイト 2、およびバイト 3 の 0-4 ビット内です。アドレスは bp->b_blkno から設定されます。
カウントフィールドはバイト 4 内です。カウントは最後のパラメータから設定されます。この場合、count は bp->b_bcount >> DEV_BSHIFT に設定されます。ここで DEV_BSHIFT はブロックの数に変換される転送のバイトカウントです。
SCSI CDB を初期化したら、パケット内にあるほかの 3 つのフィールドを初期化し、パケットへのポインタとして状態構造体内に格納します。
pkt->pkt_private = (opaque_t)bp; pkt->pkt_comp = xxcallback; pkt->pkt_time = 30; xsp->pkt = pkt;
buf(9S) ポインタは、後から完了ルーチンで使用するため、pkt_private フィールドに保存されます。