PMAP_TRANSFER_EX funzione di callback (wdm.h)

La routine MapTransferEx configura i registri mappa per eseguire il mapping degli indirizzi fisici in un elenco a dispersione/raccolta agli indirizzi logici necessari per eseguire un trasferimento DMA.

Sintassi

PMAP_TRANSFER_EX PmapTransferEx;

NTSTATUS PmapTransferEx(
  [in]            PDMA_ADAPTER DmaAdapter,
  [in]            PMDL Mdl,
  [in]            PVOID MapRegisterBase,
  [in]            ULONGLONG Offset,
  [in]            ULONG DeviceOffset,
  [in, out]       PULONG Length,
  [in]            BOOLEAN WriteToDevice,
  [out, optional] PSCATTER_GATHER_LIST ScatterGatherBuffer,
  [in]            ULONG ScatterGatherBufferLength,
  [in, optional]  PDMA_COMPLETION_ROUTINE DmaCompletionRoutine,
  [in, optional]  PVOID CompletionContext
)
{...}

Parametri

[in] DmaAdapter

Puntatore a una struttura DMA_ADAPTER . Questa struttura è l'oggetto adapter che rappresenta il dispositivo DMA master del driver o il canale DMA del sistema. Il chiamante ha ottenuto questo puntatore da una chiamata precedente alla routine IoGetDmaAdapter .

[in] Mdl

Puntatore a una catena MDL che descrive il layout di pagina fisico per una raccolta di buffer bloccati in memoria virtuale. L'elenco di dispersione/raccolta per il trasferimento DMA userà l'area di questa memoria specificata dai parametri Offset e Length . Per altre informazioni sulle catene MDL, vedere Uso di MDLs.

[in] MapRegisterBase

Handle per i registri della mappa allocati per l'oggetto adapter. Il chiamante ha ottenuto in precedenza questo handle dalla routine AllocateAdapterChannelEx .

[in] Offset

Offset di byte dall'inizio della memoria descritta dalla catena MDL. Questo offset specifica l'inizio del buffer di dati di I/O usato per il trasferimento DMA. Se al chiamante viene fornito un elenco di dispersione/raccolta, questo offset determina l'indirizzo iniziale del primo frammento di buffer nell'elenco. Se gli MDLs nella catena MDL descrivono un totale di N byte di memoria, i valori validi di Offset si trovano nell'intervallo da 0 a N-1. Per altre informazioni, vedere la sezione Osservazioni.

[in] DeviceOffset

Offset di byte del registro dei dati del dispositivo di destinazione o FIFO dall'indirizzo di base del dispositivo. Questo parametro si applica ai dispositivi con più FIFO a cui è possibile accedere da un controller DMA di sistema. Questo parametro viene usato solo per i trasferimenti DMA di sistema. Per i trasferimenti bus-master, impostare questo parametro su zero.

[in, out] Length

Puntatore a una variabile che contiene la lunghezza, in byte, del buffer di dati di I/O usato per il trasferimento DMA. Nella voce questa variabile contiene la lunghezza richiesta dal driver chiamante. Prima di restituire, la routine scrive la lunghezza effettiva del buffer mappato in questa variabile. Il valore *Length on return from MapTransferEx indica il numero di byte mappati. Se il numero di registri mappa e le dimensioni del buffer a dispersione/raccolta sono sufficienti per eseguire il mapping dell'intera lunghezza richiesta dal chiamante, i valori di input e output di *Length sono identici. Se gli MDLs nella catena MDL descrivono un totale di N byte di memoria, i valori validi di *Length si trovano nell'intervallo da 0 a N-Offset.

[in] WriteToDevice

Direzione del trasferimento DMA. Impostare questo parametro su TRUE per un'operazione di scrittura, che trasferisce i dati al dispositivo dalla memoria. Impostare questo parametro su FALSE per un'operazione di lettura, che trasferisce i dati dal dispositivo alla memoria.

[out, optional] ScatterGatherBuffer

Puntatore a un buffer allocato dal chiamante in cui la routine scrive l'elenco di dispersione/raccolta per il trasferimento DMA. Questo elenco inizia con una struttura SCATTER_GATHER_LIST , che viene immediatamente seguita da una matrice di SCATTER_GATHER_ELEMENT . Per un driver che usa un dispositivo DMA master del bus, ScatterGatherBuffer è un parametro obbligatorio. Per un driver che usa un controller DMA di sistema, il parametro ScatterGatherBuffer è facoltativo e può essere NULL. Per altre informazioni, vedere la sezione Osservazioni.

[in] ScatterGatherBufferLength

Dimensioni, in byte, del buffer a cui punta il parametro ScatterGatherBuffer . Le dimensioni del buffer allocato devono essere sufficienti per contenere l'elenco di dispersione/raccolta, oltre ai dati interni archiviati dal sistema operativo in questo buffer. Per determinare le dimensioni del buffer necessarie, chiamare la routine GetDmaTransferInfo o CalculateScatterGatherList . Se ScatterGatherBuffer è NULL, impostare ScatterGatherBufferLength su zero.

[in, optional] DmaCompletionRoutine

Puntatore a una routine DmaCompletionRoutine fornita dal chiamante da chiamare al completamento del trasferimento DMA. Questa routine viene chiamata se il dispositivo di destinazione usa un controller DMA di sistema che genera un interruzione di completamento DMA. La routine DmaCompletionRoutine viene chiamata in DISPATCH_LEVEL dopo il completamento del trasferimento DMA. Per un adattatore DMA di sistema, questo parametro è facoltativo e può essere NULL. Per un adattatore bus-master, impostare questo parametro su NULL.

[in, optional] CompletionContext

Contesto determinato dal driver per la routine DmaCompletionRoutine . Questo contesto viene fornito come parametro CompletionContext alla routine DmaCompletionRoutine . Se il parametro DmaCompletionRoutine è NULL, impostare CompletionContext su NULL.

Valore restituito

MapTransferEx restituisce STATUS_SUCCESS se la chiamata ha esito positivo. I valori restituiti degli errori possibili includono i codici di stato seguenti.

Codice restituito Descrizione
STATUS_INVALID_PARAMETERS
La routine non è riuscita a causa di valori di parametro non validi passati dal chiamante.
STATUS_BUFFER_TOO_SMALL
Il buffer fornito dal chiamante in ScatterGatherBuffer è troppo piccolo per contenere l'elenco di dispersione/raccolta.
STATUS_INSUFFICIENT_RESOURCES
La routine non è riuscita ad allocare le risorse necessarie per il trasferimento DMA.
STATUS_CANCELLED
Questo trasferimento è stato annullato.

Commenti

MapTransferEx non è una routine di sistema che può essere chiamata direttamente per nome. Questa routine può essere chiamata solo dal puntatore dall'indirizzo restituito in una struttura DMA_OPERATIONS. I driver ottengono l'indirizzo di questa routine chiamando IoGetDmaAdapter con il membro Version del parametro DeviceDescription impostato su DEVICE_DESCRIPTION_VERSION3. Se IoGetDmaAdapter restituisce NULL, la routine non è disponibile nella piattaforma.

Per un trasferimento che usa un controller DMA di sistema, il chiamante può, come opzione, fornire una routine di callback DmaCompletionRoutine chiamata al termine del trasferimento. Il sistema operativo pianifica questo callback in risposta all'interruzione del completamento DMA dal controller DMA di sistema.

Il numero di registri mappa che possono essere configurati da MapTransferEx non può superare il massimo ottenuto dal driver IoGetDmaAdapter.

I parametri Mdl, Offset e Length descrivono il buffer dei dati di I/O per il trasferimento DMA richiesto. Il numero di registri mappa allocati potrebbe non essere sufficiente per eseguire il mapping di tutta la memoria in questo buffer o il buffer di dispersione/raccolta puntato da ScatterGatherBuffer potrebbe non essere abbastanza grande per descrivere l'intero buffer. MapTransferEx scrive un valore di output in *Length per indicare al driver la quantità di memoria del buffer per il trasferimento DMA richiesto mappato dalla routine. La routine scrive un elenco di dispersione/raccolta nel buffer a cui fa riferimento ScatterGatherBuffer. Questo elenco descrive i frammenti di buffer mappati correttamente dalla routine.

Se una chiamata a MapTransferEx ha esito positivo, MapTransferEx scrive il valore di output *Length prima che venga restituito. Se il chiamante specifica un DmaCompletionRoutine, il valore di output *Length aggiornato viene sempre scritto prima dell'esecuzione di DmaCompletionRoutine . Per altre informazioni, vedere Più chiamate a MapTransferEx.

Il parametro Offset specifica l'offset iniziale nella catena MDL che descrive la memoria nel buffer di dati di I/O. Si supponga, ad esempio, che la catena MDL contenga due DLL, MDL₁ e MDL gigabyte e che MDL₁ descrive N₁ byte di memoria e MDL gigabyte descrive i byte N gigabyte. Se Offset = N, dove N₁ N<₁ < + N₂, il buffer contiene nessuno della memoria descritta da MDL₁ e inizia a un offset di N - N - N₁ byte nella memoria descritta da MDL GIGABYTE.

Se il trasferimento usa un controller DMA di sistema, il chiamante può impostare ScatterGatherBuffer = NULL, in questo caso MapTransferEx usa un buffer predefinito allocato internamente per contenere l'elenco di dispersione/raccolta. Il buffer predefinito è garantito essere abbastanza grande per contenere un elenco di dispersione/raccolta di almeno un elemento. Se il buffer predefinito viene usato per un trasferimento a dispersione/raccolta di molti elementi, è possibile che siano necessarie molte chiamate a MapTransferEx per completare il trasferimento. Se l'hardware del controller DMA supporta trasferimenti a dispersione/raccolta, l'uso del buffer predefinito potrebbe ridurre le prestazioni.

Se ScatterGatherBuffer non è NULL e ScatterGatherBufferSize specifica una dimensione troppo piccola per contenere un elenco di dispersione/raccolta di almeno un elemento, MapTransferEx ha esito negativo e restituisce STATUS_INVALID_PARAMETER.

MapTransferEx è una versione estesa della routine MapTransfer . La versione estesa offre questi vantaggi:

  • MapTransferEx può elaborare tutti i frammenti di buffer in una catena MDL in una sola chiamata, ma MapTransfer può elaborare un solo frammento di buffer contiguo fisicamente per chiamata.
  • MapTransferEx può generare un intero elenco di dispersione/raccolta in una chiamata, ma MapTransfer può generare un solo elemento elenco a dispersione/raccolta per chiamata.
  • MapTransferEx può eseguire il mapping di tutti i frammenti di buffer in un elenco a dispersione/raccolta in una sola chiamata, ma MapTransfer può eseguire il mapping di un solo frammento di buffer contiguo fisicamente per ogni chiamata.
  • MapTransferEx richiede solo l'offset iniziale per l'intero elenco di dispersione/raccolta, ma MapTransfer richiede un indirizzo virtuale iniziale per ogni frammento di buffer contiguo fisicamente.
  • Una chiamata MapTransferEx può eseguire il mapping di un buffer che si estende attraverso uno o più MDLs, ma una chiamata MapTransfer può eseguire il mapping di un solo frammento di buffer fisicamente contiguo nella memoria descritta da un MDL.
  • Per un trasferimento DMA di sistema, MapTransferEx consente al chiamante di fornire una routine di callback DmaCompletionRoutine per ricevere una notifica dopo il completamento del trasferimento, ma MapTransfer non fornisce un modo per notificare al chiamante quando viene completato un trasferimento DMA.
Ogni chiamata riuscita a MapTransferEx deve essere seguita da una chiamata corrispondente alla routine FlushAdapterBuffersEx . La chiamata FlushAdapterBuffersEx che segue una chiamata MapTransferEx deve verificarsi prima che si verifichi la chiamata MapTransferEx successiva. La chiamata FlushAdapterBuffersEx è necessaria anche se una chiamata alla routine CancelMappedTransfer riesce ad annullare il trasferimento mappato richiesto dalla chiamata MapTransferEx precedente.

Per altre informazioni, vedere Uso della routine MapTransferEx.

Requisiti

Requisito Valore
Client minimo supportato Disponibile a partire da Windows 8.
Piattaforma di destinazione Desktop
Intestazione wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
IRQL <= DISPATCH_LEVEL

Vedi anche

AllocateAdapterChannelEx

CalculateScatterGatherList

CancelMappedTransfer

DMA_ADAPTER

DMA_OPERATIONS

DmaCompletionRoutine

FlushAdapterBuffersEx

GetDmaTransferInfo

IoGetDmaAdapter

SCATTER_GATHER_LIST