存储类驱动程序通常需要一个或多个 IoCompletion 例程,除非驱动程序在发送到端口驱动程序的每个 IRP 完成时能够同步等待,并根据需要重试请求,然后在调度或 BuildRequest 例程中释放 SRB 的内存。 请注意,同步处理每个 IRP 会降低类驱动程序的性能。 此外,可能保存系统页文件的设备的存储类驱动程序必须异步处理所有传输请求,因此必须具有用于读/写请求的 IoCompletion 例程。
如 存储类驱动程序的 BuildRequest 例程中所述,存储类驱动程序负责释放其为 SRB 分配的内存,无论是返回到后备列表还是非分页池。 与任何其他更高级别的内核模式驱动程序一样,它们还负责释放分配的任何 IRP,例如 IRP 来拆分传输请求,如 存储类驱动程序的 SplitTransferRequest 例程中所述。
类驱动程序的 IoCompletion 例程最终负责确保设置 I/O 状态块并完成原始 IRP。 请注意,完成 IRP 可以包括将 SRB 的 ScsiStatus 成员或 SenseInfoBuffer 成员返回的错误转换为 NTSTATUS 类型值和/或记录错误,如在 Dispatch 例程中完成 IRP 中所述。
处理请求时发生某些类型的错误时,存储端口驱动程序会冻结目标逻辑单元(LU)的内部队列,并在请求完成时设置SRB_STATUS_QUEUE_FROZEN。 因此,类驱动程序通常具有内部例程来更改其设备 I/O 请求的队列状态。 有关详细信息,请参阅 存储类驱动程序的 ReleaseQueue 例程。
如果驱动程序的 BuildRequest 例程请求端口驱动程序为请求返回请求感知信息,则其 IoCompletion 例程会调用内部 InterpretRequestSense 例程或实现相同的内联功能。 有关详细信息,请参阅 存储类驱动程序的 InterpretRequestSense 例程。
存储类驱动程序负责重试由于目标控制器错误、总线重置或请求超时而失败的请求。 当端口驱动程序返回特定请求并将其 SrbStatus 设置为指示此类错误时,类驱动程序可以从其 IoCompletion 例程或可能从其 InterpretRequestSense 例程调用 RetryRequest 例程。 有关详细信息,请参阅 存储类驱动程序的 RetryRequest 例程。
有关 IoCompletion 例程的一般信息,请参阅 “完成 IRP”。