打开、初始化和关闭 SD 卡总线接口

安全数字 (SD) 设备驱动程序必须打开并初始化 SD 总线接口,以与其管理的设备或主机控制器进行交互。 这需要对 SD 总线库进行两次调用:调用 SdBusOpenInterface ,然后调用由初始化接口的总线驱动程序提供的例程。 SdBusOpenInterface 返回指向例程的指针,该例程初始化 SDBUS_INTERFACE_STANDARD 结构的 InterfaceReference 成员中的接口。 设备驱动程序必须调用此初始化例程,以便为总线驱动程序提供指向中断通知回调例程的指针。 总线驱动程序使用此回调通知设备驱动程序硬件中断。 有关初始化 SD 总线接口的例程的详细信息,请参阅 PSDBUS_INITIALIZE_INTERFACE_ROUTINE。 设备驱动程序通常会从其 AddDevice 例程中打开并初始化 SD 总线接口。

下面的代码示例演示了打开并初始化 SD 总线接口的调用序列:

  status = SdBusOpenInterface (pDevExt->UnderlyingPDO,
    &pDevExt->BusInterface,
    sizeof(SDBUS_INTERFACE_STANDARD),
    SDBUS_INTERFACE_VERSION);

  if (NT_SUCCESS(status)) {
    SDBUS_INTERFACE_PARAMETERS interfaceParameters = {0};
    interfaceParameters.Size = 
      sizeof(SDBUS_INTERFACE_PARAMETERS);
    interfaceParameters.TargetObject = 
      DeviceExtension->TargetObject;
    interfaceParameters.DeviceGeneratesInterrupts = TRUE;
    interfaceParameters.CallbackRoutine = pMyDriverCallback;
    status = STATUS_UNSUCCESSFUL;
    if (DeviceExtension->BusInterface.InitializeInterface) {
      status = (pDevExt->BusInterface.InitializeInterface)
        (pDevExt->BusInterface.Context, &interfaceParameters);
    }
      }

在此代码示例中,设备驱动程序调用 SdBusOpenInterface 以打开接口,总线驱动程序将指向初始化例程的指针存储在设备扩展 (DeviceExtension-BusInterface.InitializeInterface>) 。 SdBusOpenInterface 返回后,驱动程序将从设备扩展检索此指针。 接下来,驱动程序将指向其自己的中断回调例程 pMyDriverCallback 的指针放在 SDBUS_INTERFACE_PARAMETERS 结构中,并将此结构传递给初始化例程。

设备驱动程序还必须检索 SdBusOpenInterface 在 SDBUS_INTERFACE_STANDARD 结构的 Context 成员中返回的 上下文 信息。 每当驱动程序调用 SD 总线接口例程时,它都必须传入此上下文数据。

关闭 SD 接口

若要关闭 SD 接口,驱动程序必须通过调用 SDBUS_INTERFACE_STANDARD 结构的 InterfaceDereference 成员中的例程来取消引用接口,这将释放 SdBusOpenInterface 例程分配的所有资源。 接收以下任一 IRP 时,SD 设备驱动程序应关闭所有打开的 SD 接口:

IRP_MN_QUERY_REMOVE_DEVICE

IRP_MN_REMOVE_DEVICE

IRP_MN_SURPRISE_REMOVAL

以下代码示例演示了驱动程序如何取消引用 SD 卡总线接口:

if (pDevExt->BusInterface.InterfaceDereference) {
    (pDevExt->BusInterface.InterfaceDereference) (pDevExt->BusInterface.Context);
    RtlZeroMemory(&pDevExt->BusInterface, sizeof(SDBUS_INTERFACE_STANDARD));
}

SdBusOpenInterface 调用将指向接口取消引用例程的指针存储在 SDBUS_INTERFACE_STANDARD 结构中。 但是,在尝试调用例程之前,驱动程序应验证指针是否为 NULL