ScsiPortNotification 函数 (srb.h)

ScsiPortNotification 例程将特定事件通知操作系统特定的端口驱动程序,例如,当微型端口驱动程序完成请求或准备启动另一个 SRB 时,以及主机总线适配器 (HBA) 指示操作期间发生的某些 SCSI 错误情况时。

注意

SCSI 端口驱动程序和 SCSI 微型端口驱动程序模型将来可能会更改或不可用。 相反,我们建议使用 Storport 驱动程序Storport 微型端口 驱动程序模型。

语法

SCSIPORT_API VOID ScsiPortNotification(
  SCSI_NOTIFICATION_TYPE NotificationType,
  PVOID                  HwDeviceExtension,
  ...                    
);

参数

NotificationType

指定通知的类型。 请参阅“备注”。

HwDeviceExtension

指向硬件设备扩展的指针。 这是端口驱动程序代表微型端口驱动程序分配和初始化的每个 HBA 存储区域。 微型端口驱动程序通常在此扩展中存储特定于 HBA 的信息,例如 HBA 的状态和 HBA 的映射访问范围。 在微型端口驱动程序调用 ScsiPortInitialize 后,HBA 的设备对象的 DeviceExtension-HwDeviceExtension> 成员中,此区域可供微型端口驱动程序使用。 端口驱动程序在移除设备时释放此内存。

...

此例程的可变参数。 参数的数量和类型取决于 NotificationType。 请参阅“备注”。

返回值

备注

ScsiPortNotification 例程具有一组与每个 NotificationType 关联的不同可选参数。 下面列出了 NotificationType 的可能值,以及每个值的说明。

  • NotificationType = RequestComplete

    指示给定 的 Srb 已完成。 如果设置了此值, ScsiPortNotification 需要一个附加参数:SRB 的地址。 在此通知之后,特定于操作系统的端口驱动程序拥有该请求。 微型端口驱动程序不得访问 Srb,并且不得将 Srb 传递给其他例程 (,例如 ScsiPortLogError) 。

    语法:

    VOID ScsiPortNotification(
      _In_     SCSI_NOTIFICATION_TYPE NotificationType,   // RequestComplete
      _In_     PVOID                  HwDeviceExtension,
      _In_opt_ PSCSI_REQUEST_BLOCK    Srb
    );
    
  • NotificationType = NextRequest

    指示微型端口驱动程序已准备好向当前不忙的目标发出另一个请求。 当微型端口驱动程序准备好接受另一个请求时,应立即发送此通知。 通常,此通知是从 HwScsiStartIo 例程发送的,但有时来自 HwScsiInterrupt (或 HwScsiEnableInterruptsCallback) 例程。

  • NotificationType = NextLuRequest

    指示 HBA 已准备好针对指定逻辑单元的另一个请求。 如果设置了此值, ScsiPortNotification 需要三个附加参数: (1) 路径 ID, (2) 目标 ID, (3) 逻辑单元号。 仅当 HBA 可以将多个请求排队并支持自动请求感知或标记队列时,才应使用此值。

    语法:

    VOID ScsiPortNotification(
      _In_     SCSI_NOTIFICATION_TYPE NotificationType,   // NextLuRequest
      _In_     PVOID                  HwDeviceExtension,
      _In_opt_                        PathId,
      _In_opt_                        TargetId,
      _In_opt_                        Lun
    );
    
  • NotificationType = ResetDetected

    指示 HBA 在 SCSI 总线上检测到重置。 在此通知之后,微型端口驱动程序仍负责完成任何活动请求。 SCSI 端口驱动程序将管理所有必需的总线重置延迟。

  • NotificationType = CallEnableInterrupts

    指示微型端口驱动程序需要特定于操作系统的端口驱动程序来调用微型端口驱动程序的 HwScsiEnableInterruptsCallback 例程。 如果设置了此值, ScsiPortNotification 需要一个附加参数: HwScsiEnableInterruptsCallback 的入口点。 微型端口驱动程序的 HwScsiInterrupt 例程在 HBA 上禁用中断 发出此调用,以在 HBA 需要在 ISR 中轮询或停止时延迟某些中断驱动的 I/O 处理。 在回调运行时,系统中断保持启用状态,但不会调用微型端口驱动程序的 HwScsiInterrupt 例程。 HwScsiEnableInterruptsCallback 负责完成延迟 I/O 处理,并使用 CallDisableInterrupts 和微型端口驱动程序的 HwScsiDisableInterruptsCallback 入口点再次调用 ScsiPortNotification

    语法:

    VOID ScsiPortNotification(
      _In_     SCSI_NOTIFICATION_TYPE NotificationType,           // CallEnableInterrupts
      _In_     PVOID                  HwDeviceExtension,
      _In_opt_ PHW_INTERRUPT          HwScsiXxxInterruptsCallback
    );
    
  • NotificationType = CallDisableInterrupts

    指示微型端口驱动程序需要特定于操作系统的端口驱动程序来调用微型端口驱动程序的 HwScsiDisableInterruptsCallback 例程。 如果设置了此值, ScsiPortNotification 需要一个附加参数: HwScsiDisableInterruptsCallback 的入口点。 当此回调运行时,它不能被中断抢占,除非来自优先级高于 HBA 的设备中断。 在此回调中,微型端口驱动程序在 HBA 上重新启用中断。

    语法:

    VOID ScsiPortNotification(
      _In_     SCSI_NOTIFICATION_TYPE NotificationType,          // CallDisableInterrupts
      _In_     PVOID                  HwDeviceExtension,
      _In_opt_ PHW_INTERRUPT          HwScsiXxxInterruptsCallback
    );
    
  • NotificationType = RequestTimerCall

    指示微型端口驱动程序要求操作系统特定的端口驱动程序以请求的微秒数调用微型端口驱动程序的 HwScsiTimer 例程。 如果设置了此值, ScsiPortNotification 需要两个附加参数: (1) 微型端口驱动程序 的 HwScsiTimer 例程的入口点; (2) MiniportTimerValue 间隔(以微秒为单位)。 请注意,系统计时器的分辨率约为 10 毫秒。

    语法:

    VOID ScsiPortNotification(
      _In_     SCSI_NOTIFICATION_TYPE NotificationType,    // RequestTimerCall
      _In_     PVOID                  HwDeviceExtension,
      _In_opt_ PHW_TIMER              HwScsiTimer,
      _In_opt_ ULONG                  MiniportTimerValue
    );
    
  • NotificationType = BusChangeDetected

    指示目标设备可能已从动态总线添加或删除。 如果设置了此值, ScsiPortNotification 需要一个附加参数:检测到更改的总线的路径 ID。 在此通知之后,端口驱动程序通过发出 INQUIRY 命令来重新运行总线。 总线枚举非常耗时且与总线关联,因此微型端口驱动程序不应不必要地发送此通知。

    语法:

    VOID ScsiPortNotification(
      _In_     SCSI_NOTIFICATION_TYPE NotificationType,    // BusChangeDetected
      _In_     PVOID                  HwDeviceExtension,
      _In_opt_ UCHAR                  PathId
    );
    
  • NotificationType = WMIEvent

    指示微型端口驱动程序已检测到为其注册了一个或多个 WMI 数据使用者的事件。 如果设置了此值, ScsiPortNotification 至少需要三个附加参数: (1) 指向 WMI 事件结构的指针, (2) 事件结构的大小;如果事件源自设备,则 (3) 目标设备的路径 ID;如果事件源自适配器,则0xFF。 如果 (3) 是路径 ID, 则 ScsiPortNotification 需要两个附加参数: (4) 目标 ID, (5) 目标设备的逻辑单元号 (LUN) 。

    PathId != 0xFF 的语法

    VOID ScsiPortNotification(
      _In_     SCSI_NOTIFICATION_TYPE NotificationType,    // WMIEvent
      _In_     PVOID                  HwDeviceExtension,
      _In_opt_ PVOID                  WMIEvent,
      _In_opt_ UCHAR                  PathId,              // != 0xFF
      _In_opt_ UCHAR                  TargetId,
      _In_opt_ UCHAR                  Lun
    );
    

    PathId = 0xFF 的语法

    VOID ScsiPortNotification(
      _In_     SCSI_NOTIFICATION_TYPE NotificationType,    // WMIEvent
      _In_     PVOID                  HwDeviceExtension,
      _In_opt_ PVOID                  WMIEvent,
      _In_opt_ UCHAR                  PathId               // 0xFF
    );
    
  • NotificationType = WMIReregister

    指示微型端口驱动程序已更改之前通过调用 IoWMIRegistrationControl 注册的给定数据块的数据项或实例数。 如果设置了 WMIReregister则 ScsiPortNotification 至少需要两个附加参数: (1) 目标设备的路径 ID 来重新注册该设备,或0xFF重新注册适配器。 如果 (1) 是路径 ID, 则 ScsiPortNotification 需要另外两个参数: (2) 目标 ID, (3) 目标设备的逻辑单元号 (LUN) 。

    PathId != 0xFF 的语法

    VOID ScsiPortNotification(
      _In_     SCSI_NOTIFICATION_TYPE NotificationType,    // WMIReregister
      _In_     PVOID                  HwDeviceExtension,
      _In_opt_ UCHAR                  PathId,             // != 0xFF
      _In_opt_ UCHAR                  TargetId,
      _In_opt_ UCHAR                  Lun
    );
    

    PathId = 0xFF 的语法

    VOID ScsiPortNotification(
      _In_     SCSI_NOTIFICATION_TYPE NotificationType,   // WMIReregister
      _In_     PVOID                  HwDeviceExtension,
      _In_opt_ UCHAR                  PathId              // 0xFF
    );
    

对于每次调用微型端口驱动程序的 HwScsiStartIo 例程,每个微型端口驱动程序都必须调用两次 ScsiPortNotification,该调用具有微型端口驱动程序成功完成的 SRB。 首先,如果微型端口驱动程序支持标记队列或每个 LU 的多个请求,则微型端口驱动程序使用 NextRequestNotificationTypeNextLuRequest 调用 ScsiPortNotification。 然后,微型端口驱动程序使用 RequestCompleteNotificationType 和刚刚满足的请求调用 ScsiPortNotification

微型端口驱动程序的 HwScsiInterrupt 例程最有可能使用 ResetDetectedNotificationType 调用 ScsiPortNotification

如果 HBA 要求微型端口驱动程序使用超过一毫秒的处理中断驱动的 I/O 操作,则其 HwScsiInterrupt 例程应禁用 HBA 上的中断,并使用 CallEnableInterrupts 和驱动程序提供的 HwScsiEnableInterruptsCallback 例程调用 ScsiPortNotification。 此例程反过来会使用 CallDisableInterrupts 和相应的驱动程序提供的 HwScsiDisableInterruptsCallback 调用 ScsiPortNotification

注册为 WMI 数据提供程序的微型端口驱动程序可以使用 WMIEvent 调用 ScsiPortNotification,以发布之前已收到启用请求的事件。 端口驱动程序在微型端口驱动程序的设备扩展的中断数据区域中将事件排队,以便以后在较低的 IRQL 下进行处理。 由于一次只能对有限数量的事件进行排队,因此微型端口驱动程序应使用 WMIEvent 来发出异常情况而不是常规条件的信号,并且它应该为端口驱动程序提供时间以在两次发布之间返回到DISPATCH_LEVEL,以防止事件丢失。

要求

要求
目标平台 通用
标头 srb.h (包括 Miniport.h、Scsi.h)
Library Scsiport.lib;Storport.lib
IRQL (请参阅“备注”部分)

另请参阅

HwScsiDisableInterruptsCallback

HwScsiEnableInterruptsCallback

HwScsiTimer

IoWMIRegistrationControl

ScsiPortCompleteRequest