Öffnen, Initialisieren und Schließen einer SD-Kartenbusschnittstelle
Sd-Gerätetreiber (Secure Digital) müssen eine SD-Busschnittstelle öffnen und initialisieren, um mit den von ihnen verwalteten Geräten oder dem Hostcontroller zu interagieren. Dazu sind zwei Aufrufe der SD-Busbibliothek erforderlich: ein Aufruf von SdBusOpenInterface gefolgt von einem Aufruf einer Vom Bustreiber bereitgestellten Routine, die die Schnittstelle initialisiert. SdBusOpenInterface gibt einen Zeiger auf die Routine zurück, die die Schnittstelle im InterfaceReference-Member der SDBUS_INTERFACE_STANDARD-Struktur initialisiert. Der Gerätetreiber muss diese Initialisierungsroutine aufrufen, um den Bustreiber mit einem Zeiger auf eine Interruptbenachrichtigungsrückrufroutine zu versorgen. Der Bustreiber verwendet diesen Rückruf, um den Gerätetreiber über einen Hardware-Interrupt zu benachrichtigen. Weitere Informationen zur Routine, die eine SD-Busschnittstelle initialisiert, finden Sie unter PSDBUS_INITIALIZE_INTERFACE_ROUTINE. Der Gerätetreiber öffnet normalerweise eine SD-Busschnittstelle aus seiner AddDevice-Routine und initialisiert diese.
Im folgenden Codebeispiel wird die Reihenfolge der Aufrufe veranschaulicht, die eine SD-Busschnittstelle öffnen und initialisieren:
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);
}
}
In diesem Codebeispiel ruft der Gerätetreiber SdBusOpenInterface auf, um die Schnittstelle zu öffnen, und der Bustreiber speichert einen Zeiger auf die Initialisierungsroutine in der Geräteerweiterung (DeviceExtension-BusInterface.InitializeInterface>). Nachdem SdBusOpenInterface zurückgegeben wurde, ruft der Treiber diesen Zeiger aus der Geräteerweiterung ab. Als Nächstes platziert der Treiber einen Zeiger auf seine eigene Interrupt-Rückrufroutine pMyDriverCallback in der SDBUS_INTERFACE_PARAMETERS-Struktur und übergibt diese Struktur an die Initialisierungsroutine.
Der Gerätetreiber muss auch die Kontextinformationen abrufen, die SdBusOpenInterface im Kontextelement der SDBUS_INTERFACE_STANDARD-Struktur zurückgibt. Wenn der Treiber eine SD-Busschnittstellenroutine aufruft, müssen in diesem Kontext Daten übergeben werden.
Um eine SD-Schnittstelle zu schließen, müssen Treiber die Schnittstelle dereferenzieren, indem sie die Routine im InterfaceDereference-Member der SDBUS_INTERFACE_STANDARD-Struktur aufrufen, wodurch alle Ressourcen freigegeben werden, die von der SdBusOpenInterface-Routine zugeordnet sind. SD-Gerätetreiber sollten alle offenen SD-Schnittstellen schließen, wenn sie eines der folgenden IRPs empfangen:
Im folgenden Codebeispiel wird veranschaulicht, wie ein Treiber eine SD-Karte Busschnittstelle deleiten kann:
if (pDevExt->BusInterface.InterfaceDereference) {
(pDevExt->BusInterface.InterfaceDereference) (pDevExt->BusInterface.Context);
RtlZeroMemory(&pDevExt->BusInterface, sizeof(SDBUS_INTERFACE_STANDARD));
}
Der SdBusOpenInterface-Aufruf speichert einen Zeiger auf die Schnittstellendeferenceroutine in der SDBUS_INTERFACE_STANDARD-Struktur. Treiber sollten jedoch überprüfen, ob der Zeiger nicht NULL ist, bevor sie versuchen, die Routine aufzurufen.