Condividi tramite


Uso di DMA a dispersione/raccolta

I driver che eseguono DMA basati su sistema o bus-master possono usare routine di supporto progettate appositamente per DMA a dispersione/raccolta. Anziché chiamare la sequenza di routine descritte in Using Packet-Based System DMA and Packet-Based Bus-Master DMA, un driver può usare GetScatterGatherList e PutScatterGatherList.

Non è necessario che un dispositivo disponga del supporto predefinito di dispersione/raccolta per il driver per l'uso di queste routine.

I driver che usano DMA basato su pacchetti chiamano la sequenza generale seguente di routine di supporto per le operazioni a dispersione/raccolta:

  1. MmGetMdlVirtualAddress per ottenere un indice nel file MDL, obbligatorio come parametro nella chiamata a GetScatterGatherList

  2. GetScatterGatherList quando il driver è pronto per programmare il dispositivo per DMA e richiede il controller DMA di sistema o l'adattatore bus-master

    GetScatterGatherList alloca il controller DMA di sistema o l'adattatore bus-master, determina il numero di registri mappa necessari e li alloca, compila l'elenco a dispersione/raccolta e chiama la routine AdapterListControl del driver quando sono disponibili il controller DMA o l'adattatore e i registri mappa.

  3. PutScatterGatherList non appena tutti i dati richiesti sono stati trasferiti o il driver ha esito negativo a causa di un errore di I/O del dispositivo

    PutScatterGatherList scarica i buffer dell'adattatore, libera i registri della mappa e libera l'elenco di dispersione/raccolta. Il driver deve chiamare PutScatterGatherList prima di poter accedere ai dati nel buffer.

Il puntatore a oggetti dell'adattatore restituito da IoGetDmaAdapter è un parametro obbligatorio per ognuna di queste routine, ad eccezione di MmGetMdlVirtualAddress, che richiede un puntatore a MDL in Irp-MdlAddress>.

La routine GetScatterGatherList include chiamate a AllocateAdapterChannel e MapTransfer, quindi il driver non deve effettuare queste chiamate. La routine accetta quanto segue come parametri:

  • Puntatore alla struttura DMA_ADAPTERrestituita da IoGetDmaAdapter

  • Puntatore all'oggetto dispositivo di destinazione per l'operazione DMA

  • Puntatore al file MDL che descrive il buffer in Irp-MdlAddress>

  • Puntatore all'indirizzo virtuale corrente nel buffer descritto da Mdl

  • Numero di byte di cui eseguire il mapping

  • Puntatore a una routine AdapterListControl che esegue il trasferimento

  • Puntatore a un'area di contesto definita dal driver da passare alla routine AdapterListControl

  • Valore booleano: TRUE per un trasferimento al dispositivo; FALSE in caso contrario

Dopo aver determinato il numero di registri mappa necessari, allocare il canale dell'adattatore e i registri delle mappe, compilare l'elenco di dispersione/raccolta e prepararsi per il trasferimento, GetScatterGatherList chiama la routine AdapterListControl fornita dal driver. La routine AdapterListControl viene eseguita in un contesto di thread arbitrario in IRQL = DISPATCH_LEVEL.

La routine AdapterListControl fornita da un driver nelle chiamate a GetScatterGatherList differisce dalla routine AdapterControl passata a AllocateAdapterChannel nei seguenti aspetti importanti:

  • La routine AdapterListControl non ha alcun valore restituito, mentre la routine AdapterControl restituisce un IO_ALLOCATION_ACTION.

  • Anziché un puntatore a MapRegisterBase per i registri mappa allocati dal sistema, il terzo parametro di una routine AdapterListControl punta invece a una struttura SCATTER_GATHER_LIST tramite cui il driver può eseguire DMA.

  • La routine AdapterListControl esegue un subset delle attività necessarie in una routine AdapterControl .

    La routine AdapterListControl non chiama AllocateAdapterChannel o MapTransfer. Le sue uniche responsabilità sono salvare il puntatore elenco a dispersione/raccolta di input, configurare il dispositivo e usare l'elenco di dispersione/raccolta per eseguire DMA.

La struttura di elenco a dispersione/raccolta include una matrice SCATTER_GATHER_ELEMENT e il numero di elementi nella matrice. Ogni elemento della matrice fornisce la lunghezza e l'indirizzo fisico iniziale di un'area a dispersione/raccolta fisicamente contigua. Un driver usa la lunghezza e l'indirizzo nei trasferimenti di dati.

Un driver può usare GetScatterGatherList indipendentemente dal fatto che il dispositivo supporti DMA a dispersione/raccolta. Per un dispositivo che non supporta DMA a dispersione/raccolta, l'elenco di dispersione/raccolta conterrà un solo elemento.

L'uso delle routine a dispersione/raccolta può migliorare le prestazioni rispetto alla chiamata di AllocateAdapterChannel (come descritto in precedenza in Uso di DMA di sistema Packet-Based e uso di Packet-Based Bus-Master DMA). A differenza delle chiamate a AllocateAdapterChannel, è possibile accodare più chiamate a GetScatterGatherList per un oggetto dispositivo in qualsiasi momento. Un driver può chiamare nuovamente GetScatterGatherList per un'altra operazione DMA sullo stesso oggetto driver prima che la routine AdapterListControl abbia completato l'esecuzione.

Al ritorno dalla routine AdapterListControl fornita dal driver, GetScatterGatherList mantiene i registri della mappa, ma libera la struttura dell'adattatore DMA.

Quando il driver ha soddisfatto la richiesta di trasferimento di IRP corrente o deve non riuscire l'IRP a causa di un errore di I/O del dispositivo o del bus, deve chiamare PutScatterGatherList prima di poter accedere ai dati trasferiti nel buffer. PutScatterGatherList scarica i buffer dell'adattatore e libera i registri della mappa e l'elenco a dispersione/raccolta.