struct scsi_pkt { opaque_t pkt_ha_private; /* private data for host adapter */ struct scsi_address pkt_address; /* destination packet is for */ 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 */ };
其中:
scsi_init_pkt(9F) 设置的目标设备的地址。
用于存储目标驱动程序的专用数据的位置。pkt_private 通常用于保存命令的 buf(9S) 指针。
完成例程的地址。主机总线适配器驱动程序将在传输命令后调用此例程。传输命令并不表示命令已成功。目标可能处于繁忙状态。另一种可能性是在经过超时时间段之前目标未响应。请参见 pkt_time 字段的说明。目标驱动程序必须在该字段中提供有效值。如果不需要通知驱动程序,则该值可以为 NULL。
有两种不同的 SCSI 回调例程。pkt_comp 字段标识完成回调例程,该例程将在主机总线适配器完成其处理时调用。此外,还提供了资源回调例程,该例程将在当前尚不可用资源可能可用时调用。请参见 scsi_init_pkt(9F) 手册页。
提供其他控制信息,例如,在没有断开连接权限的情况下传输命令 (FLAG_NODISCON),或禁用回调 (FLAG_NOINTR)。有关详细信息,请参见 scsi_pkt(9S) 手册页。
超时值(以秒为单位)。如果命令在该时间内未完成,则主机总线适配器将调用完成例程,并将 pkt_reason 设置为 CMD_TIMEOUT。目标驱动程序应将该字段设置为大于命令可能需要的最长时间。如果超时值为零,则不请求超时。超时从在 SCSI 总线上传输命令时开始。
指向 SCSI 状态完成块的指针。该字段由主机总线适配器驱动程序填充。
指向 SCSI 命令描述符块(要发送到目标设备的实际命令)的指针。主机总线适配器驱动程序不会解释该字段。目标驱动程序必须使用目标设备可以处理的命令填充该字段。
剩余操作。pkt_resid 字段有两种不同的用途,具体取决于如何使用 pkt_resid。使用 pkt_resid 为命令 scsi_init_pkt(9F) 分配 DMA 资源时,pkt_resid 指示不可分配的字节数。由于 DMA 硬件具有分散/集中限制或其他设备限制,因此可能无法分配 DMA 资源。传输命令后,pkt_resid 指示不可传输的数据字节数。该字段由主机总线适配器驱动程序在调用完成例程之前填充。
指示命令的状态。主机总线适配器驱动程序在命令执行过程中填充该字段。该字段的每一位分别根据以下五种命令状态设置:
STATE_GOT_BUS-已获取总线
STATE_GOT_TARGET-已选定目标
STATE_SENT_CMD-已发送命令
STATE_XFERRED_DATA-已传输数据(如果适用)
STATE_GOT_STATUS-已从设备接收状态
包含与传输相关的统计信息(由主机总线适配器驱动程序设置)。
提供调用完成例程的原因。完成例程会对该字段进行解码。然后,执行相应的操作。如果命令完成(即未发生传输错误),则该字段将设置为 CMD_CMPLT。如果该字段中存在其他值,则指示发生了错误。完成命令后,目标驱动程序应检查 pkt_scbp 字段以查看条件状态。有关更多信息,请参见 scsi_pkt(9S) 手册页。