编写适用于 Oracle® Solaris 11.2 的设备驱动程序

退出打印视图

更新时间: 2014 年 9 月
 
 

生成命令

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 资源的同时创建了一个新包。为 Group 0(6 字节)命令分配了 SCSI CDB。pkt_flags 字段被设置为零,但没有为 pkt_private 字段分配空间。由于设置了 SLEEP_FUNC 参数,对 scsi_init_pkt(9F) 的调用将会在当前没有可用资源的情况下无限期等待资源。

下一步是使用 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;

该示例将生成 Group 0 命令描述符块。该示例按如下所示填充 pkt_cdbp 字段:

  • 该命令本身位于第 0 个字节中。该命令通过 SCMD_READ 参数进行设置。

  • 地址字段位于第 1 个字节的 0-4 位以及第 2 个字节和第 3 个字节中。地址通过 bp->b_blkno 进行设置。

  • 计数字段位于第 4 个字节中。计数通过最后一个参数进行设置。在本例中,count 设置为 bp->b_bcount >> DEV_BSHIFT,其中 DEV_BSHIFT 是已转换为块数的传输字节计数。


注 - scsi_setup_cdb(9F) 不支持在 SCSI 命令块的第 1 个字节的 5-7 位中设置目标设备的逻辑单元号 (logical unit number, LUN)。此要求由 SCSI-1 定义。对于需要在命令块中设置 LUN 位的 SCSI-1 设备,请使用 makecom_g0(9F) 或某些等效函数,而不是使用 scsi_setup_cdb(9F)

初始化 SCSI CDB 之后,应初始化包中的三个其他字段,并在状态结构中存储为指向包的指针。

pkt->pkt_private = (opaque_t)bp;
pkt->pkt_comp = xxcallback;
pkt->pkt_time = 30;
xsp->pkt = pkt;

buf(9S) 指针保存在 pkt_private 字段中,以备将来在完成例程中使用。