编写设备驱动程序

目标驱动程序实例初始化

以下各节介绍了目标入口点。

tran_tgt_init() 入口点

使用 tran_tgt_init(9E) 入口点,HBA 可以分配和初始化按目标的任何资源。此外,tran_tgt_init() 还允许 HBA 将设备地址限定为该特定 HBA 的有效且可支持的地址。如果返回 DDI_FAILURE,则不会探测或附加该设备的目标驱动程序实例。

无需使用 tran_tgt_init()。如果未提供 tran_tgt_init(),则框架会尝试探测和附加相应目标驱动程序的所有可能实例。

static int
isp_tran_tgt_init(
    dev_info_t            *hba_dip,
    dev_info_t            *tgt_dip,
    scsi_hba_tran_t       *tran,
    struct scsi_device    *sd)
{
    return ((sd->sd_address.a_target < N_ISP_TARGETS_WIDE &&
        sd->sd_address.a_lun < 8) ? DDI_SUCCESS : DDI_FAILURE);
}

tran_tgt_probe() 入口点

使用 tran_tgt_probe(9E) 入口点,HBA 可以自定义 scsi_probe(9F) 的操作(如有必要)。仅当目标驱动程序调用 scsi_probe() 时,才会调用此入口点。

HBA 驱动程序可以通过调用 scsi_hba_probe(9F) 并返回其返回值来保留 scsi_probe () 的正常操作。

无需使用此入口点。如果不需要此入口点,则 HBA 驱动程序应将 scsi_hba_tran(9S) 结构中的 tran_tgt_probe 向量设置为指向 scsi_hba_probe()

scsi_probe() 可用于分配 scsi_inquiry(9S) 结构,并将 scsi_device(9S) 结构的 sd_inq 字段设置为指向 scsi_inquiry 中的数据。scsi_hba_probe() 可自动处理此任务。scsi_unprobe(9F) 随后将释放 scsi_inquiry 数据。

除分配 scsi_inquiry 数据以外,tran_tgt_probe() 必须是无状态的,因为同一 SCSI 设备可能会多次调用 tran_tgt_probe()。通常,scsi_inquiry 数据的分配通过 scsi_hba_probe() 来处理。


注 –

scsi_inquiry(9S) 结构的分配通过 scsi_hba_probe() 自动处理。此信息仅在需要自定义 scsi_probe() 处理时才有意义。


static int
isp_tran_tgt_probe(
    struct scsi_device    *sd,
    int                   (*callback)())
{
    /*
     * Perform any special probe customization needed.
     * Normal probe handling.
     */
    return (scsi_hba_probe(sd, callback));
}

tran_tgt_free() 入口点

使用 tran_tgt_free(9E) 入口点,HBA 可以执行目标实例的所有取消分配或清理过程。此入口点是可选的。

static void
isp_tran_tgt_free(
    dev_info_t            *hba_dip,
    dev_info_t            *tgt_dip,
    scsi_hba_tran_t       *hba_tran,
    struct scsi_device    *sd)
{
    /*
     * Undo any special per-target initialization done
     * earlier in tran_tgt_init(9F) and tran_tgt_probe(9F)
     */
}