Freigeben über


BuildRequest-Routine des Speicherklassentreibers

Wie alle Höheren Kernelmodustreiber muss ein Speicherklassentreiber beim Verarbeiten von Anforderungen an Speicherperipheriegeräte den I/O-Stapelspeicherort für den nächstniedrigen Treiber einrichten. In IRPs, die der Klassentreiber mit SRBs für den vom System bereitgestellten Porttreiber einrichtet, wird der E/A-Stapelspeicherort des Porttreibers wie folgt festgelegt:

  • MajorFunction enthält IRP_MJ_SCSI

  • Parameters.Scsi.Srb enthält einen Zeiger auf den SRB.

Jeder Klassentreiber ist für die Zuweisung von Arbeitsspeicher für SRBs sowie für deren Einrichtung mit CDBs für den zugrunde liegenden Speicherporttreiber verantwortlich. Der Klassentreiber kann entweder eine Suchliste für seine SRBs mit ExInitializeNPageLookasideList einrichten oder ExAllocatePool für nicht ausseitigen Arbeitsspeicher aufrufen. Weitere Informationen zur Verwendung von Lookaside-Listen und nicht ausseitigem Pool finden Sie unter Verwenden von Lookaside-Listen .

Unabhängig davon, ob Speicher aus einem Pool oder aus einer vom Treiber erstellten Lookaside-Liste zugeordnet wird, ist jeder Speicherklassentreiber für die Freigabe des speicherbezogenen Speichers für SRBs verantwortlich. Die IoCompletion-Routinen von Speicherklassentreibern, die unter IoCompletion-Routinen des Speicherklassentreibers beschrieben werden, geben in der Regel den für SRBs zugeordneten Arbeitsspeicher in eine Nachschlageliste zurück.

Die BuildRequest-Routine eines Klassentreibers muss geeignete Werte in den SRB-Membern festlegen, einschließlich der Länge des CDB, der für die Kommunikation mit dem Gerät eingerichtet wurde. Für Anforderungen, die Informationen zur Anforderungsoptimierung zurückgeben und/oder die der Treiber möglicherweise wiederholen muss, wird im IRP eine IoCompletion-Routine festgelegt. Bei Lese- oder Schreibanforderungen werden die SrbFlags mit der entsprechenden Übertragungsrichtung, SRB_FLAGS_DATA_IN bzw. SRB_FLAGS_DATA_OUT, angegeben.

Eine BuildRequest-Routine kann die Verantwortung für das Einrichten eines SRB mit einem Paar von SendSrbSynchronous - und SendSrbAsynchronous-Routinen teilen. Das heißt, die BuildRequest-Routine könnte die SRB-Member einrichten, die üblicherweise für alle Anforderungen eingerichtet werden, während SendSrbXxx jeden Satz von SRB-Werten nur für jeden Anforderungstyp routinet. Wenn ein IRP von einer SendSrbAsynchronous-Routine an den Porttreiber übergeben wird, muss der IRP mit einer vom Treiber bereitgestellten IoCompletion-Routine eingerichtet werden.

Nachdem der Klassentreiber geladen wurde, richtet er die meisten SRBs ein, wobei der Function-Member auf SRB_FUNCTION_EXECUTE_SCSI festgelegt ist, was eine Geräte-E/A-Anforderung angibt, die über den Bus gesendet werden soll.

Weitere Informationen zu den systemdefinierten SRB-Membern und ihren Werten finden Sie unter SCSI_REQUEST_BLOCK.

Einrichten von SRBs für die Anforderungsoptimierung

Ein Klassentreiber kann anfordern, dass der Porttreiber die SCSI-Anforderungsoptimierung oder entsprechende Informationen zurückgibt, wenn der Zielcontroller eine Überprüfungsbedingung zurückgibt. Dazu richtet der Klassentreiber den SenseInfoBuffer-Zeiger und SenseInfoBufferLength im SRB ein, damit der Porttreiber die Anforderungs-Sense-Informationen zurückgeben kann, wenn eine Überprüfungsbedingung auftritt. Der Porttreiber gibt an, dass er Informationen zur Anforderungsoptimierung zurückgegeben hat, indem er den SrbStatus-Member auf SRB_STATUS_AUTOSENSE_VALID festlegt, wenn er den IRP zurückgibt. Weitere Informationen zu InterpretSenseInfo-Routinen finden Sie unter InterpretRequestSense-Routine des Speicherklassentreibers.

Wiederholungen

Speicherklassentreiber sind für Wiederholungsanforderungen verantwortlich, die aufgrund von Ziel-/Controllerfehlern, Busrücksetzungen oder Anforderungstimeouts fehlschlagen. Daher behalten viele Klassentreiber eine Wiederholungsanzahl an ihrem eigenen E/A-Stapelspeicherort des IRP bei. Eine solche BuildRequest-Routine eines Klassentreibers kann auch das Wiederholungslimit für eine bestimmte Anforderung initialisieren, bevor die IoCompletion-Routine eingerichtet und der IRP an den Porttreiber gesendet wird. Weitere Informationen zu RetryRequest-Routinen finden Sie unter RetryRequest-Routine des Speicherklassentreibers.