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

退出打印视图

更新时间: 2014 年 9 月
 
 

自动请求检测模式

如果使用排队(无论是标记排队还是无标记排队),则最好使用自动请求检测模式。任何后续命令都会清除应急处理状态 (contingent allegiance condition),并因此导致检测数据丢失。大多数 HBA 驱动程序会在执行目标驱动程序回调之前开始下一条命令。其他 HBA 驱动程序可以使用单独的、较低优先级的线程执行回调。采用该方法时,如果存在检查状况,那么向目标驱动程序通知包已完成所需的时间可能会增加。在这种情况下,目标驱动程序可能无法及时提交请求检测命令以检索检测数据。

为了避免检测数据丢失,HBA 驱动程序或控制器应在检测到检查条件时发出请求检测命令。该模式称为自动请求检测模式。请注意,并非所有 HBA 驱动程序都可以使用自动请求检测模式,而某些驱动程序只能在启用了自动请求检测模式时运行。

目标驱动程序使用 scsi_ifsetcap(9F) 来启用自动请求检测模式。以下示例说明了如何启用自动请求检测。

示例 17-6  启用自动请求检测模式
static int
xxattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
    struct xxstate *xsp;
    struct scsi_device *sdp = (struct scsi_device *)
    ddi_get_driver_private(dip);
    /*
     * Enable auto-request-sense. An auto-request-sense command might
     * fail due to a BUSY condition or transport error. Therefore,
     * it is recommended to allocate a separate request sense
     * packet as well.
     * Note that scsi_ifsetcap(9F) can return -1, 0, or 1
     */
    xsp->sdp_arq_enabled =
    ((scsi_ifsetcap(ROUTE, "auto-rqsense", 1, 1) == 1) ? 1 : 0);
    /*
     * If the HBA driver supports auto request sense then the
     * status blocks should be sizeof (struct scsi_arq_status).
     * Else, one byte is sufficient.
     */
    xsp->sdp_cmd_stat_size =  (xsp->sdp_arq_enabled ?
    sizeof (struct scsi_arq_status) : 1);
    /* ... */
}

如果使用 scsi_init_pkt(9F) 分配了一个包并且该包需要自动请求检测,则需要增加空间。目标驱动程序必须为状态块请求此空间,以便存储自动请求检测结构。请求检测命令中使用的检测长度即 struct scsi_extended_sense 中的 sizeof。通过为状态块分配 struct scsi_status 中的 sizeof,可以针对各个包禁用自动请求检测。

可像往常一样使用 scsi_transport(9F) 提交包。当该包中出现检查条件时,主机适配器驱动程序将执行以下步骤:

  • 发出请求检测命令(如果控制器没有自动请求检测功能)

  • 获取检测数据

  • 在包的状态块中填充 scsi_arq_status 信息

  • 在包的 pkt_state 字段中设置 STATE_ARQ_DONE

  • 调用包的回调处理程序 (pkt_comp())

目标驱动程序的回调例程应通过检查 pkt_state 中的 STATE_ARQ_DONE 位,来验证检测数据是否可用。STATE_ARQ_DONE 表明出现了检查条件,并且已执行请求检测。如果包中暂时禁用了自动请求检测,则无法保证对检测数据的后续检索。

然后,目标驱动程序应验证自动请求检测命令是否已成功完成,并对检测数据进行解码。