Usando o DMA de Dispersão/Coleta
Os drivers que executam O AMD baseado em pacotes ou sistema ou master barramento podem usar rotinas de suporte projetadas especialmente para DMA de dispersão/coleta. Em vez de chamar a sequência de rotinas descrita em Usando o DMA do sistema Packet-Based e o DMA Bus-Master baseado em pacotes, um driver pode usar GetScatterGatherList e PutScatterGatherList.
Um dispositivo não precisa ter suporte interno de dispersão/coleta para que seu driver use essas rotinas.
Os drivers que usam DMA baseado em pacotes chamam a seguinte sequência geral de rotinas de suporte para operações de dispersão/coleta:
MmGetMdlVirtualAddress para obter um índice no MDL, necessário como um parâmetro na chamada para GetScatterGatherList
GetScatterGatherList quando o driver estiver pronto para programar seu dispositivo para DMA e precisar do controlador de DMA do sistema ou adaptador de barramento master
GetScatterGatherList aloca o controlador de DMA do sistema ou o adaptador master de barramento, determina quantos registros de mapa são necessários e os aloca, preenche a lista de dispersão/coleta e chama a rotina AdapterListControl do driver quando o controlador de DMA ou o adaptador e os registros de mapa estão disponíveis.
PutScatterGatherList assim que todos os dados solicitados forem transferidos ou o driver falhar o IRP devido a um erro de E/S do dispositivo
PutScatterGatherList libera os buffers do adaptador, libera os registros de mapa e libera a lista de dispersão/coleta. O driver deve chamar PutScatterGatherList antes de poder acessar os dados no buffer.
O ponteiro do objeto do adaptador retornado por IoGetDmaAdapter é um parâmetro necessário para cada uma dessas rotinas, exceto MmGetMdlVirtualAddress, que requer um ponteiro para o MDL em Irp-MdlAddress>.
A rotina GetScatterGatherList inclui chamadas para AllocateAdapterChannel e MapTransfer, para que o driver não precise fazer essas chamadas. A rotina usa o seguinte como parâmetros:
Um ponteiro para a estrutura DMA_ADAPTERretornada por IoGetDmaAdapter
Um ponteiro para o objeto de dispositivo de destino para a operação de DMA
Um ponteiro para o MDL que descreve o buffer em Irp-MdlAddress>
Um ponteiro para o endereço virtual atual no buffer descrito pelo Mdl
O número de bytes a serem mapeados
Um ponteiro para uma rotina AdapterListControl que executa a transferência
Um ponteiro para uma área de contexto definida pelo driver a ser passada para a rotina AdapterListControl
Um valor booliano: TRUE para uma transferência para o dispositivo; Caso contrário, FALSE
Depois de determinar o número de registros de mapa necessários, alocar o canal do adaptador e os registros de mapa, preencher a lista de dispersão/coleta e preparar-se para a transferência, GetScatterGatherList chama a rotina AdapterListControl fornecida pelo driver. A rotina AdapterListControl é executada em um contexto de thread arbitrário em IRQL = DISPATCH_LEVEL.
A rotina AdapterListControl que um driver fornece em chamadas para GetScatterGatherList difere da rotina AdapterControl passada para AllocateAdapterChannel nos seguintes aspectos importantes:
A rotina AdapterListControl não tem valor retornado, enquanto a rotina AdapterControl retorna um IO_ALLOCATION_ACTION.
Em vez de um ponteiro para MapRegisterBase para os registros de mapa alocados pelo sistema, o terceiro parâmetro para uma rotina AdapterListControl , em vez disso, aponta para uma estrutura SCATTER_GATHER_LIST por meio da qual o driver pode executar DMA.
A rotina AdapterListControl executa um subconjunto das tarefas necessárias em uma rotina AdapterControl .
A rotina AdapterListControl não chama AllocateAdapterChannel ou MapTransfer. Suas únicas responsabilidades são salvar o ponteiro de lista de dispersão/coleta de entrada, configurar seu dispositivo e usar a lista de dispersão/coleta para executar o AMD.
A estrutura de lista de dispersão/coleta inclui uma matriz SCATTER_GATHER_ELEMENT e o número de elementos na matriz. Cada elemento da matriz fornece o comprimento e o endereço físico inicial de uma região de dispersão/coleta fisicamente contígua. Um driver usa o comprimento e o endereço em transferências de dados.
Um driver pode usar GetScatterGatherList independentemente de seu dispositivo dar suporte a DMA de dispersão/coleta. Para um dispositivo que não dá suporte ao DMA de dispersão/coleta, a lista de dispersão/coleta conterá apenas um elemento.
O uso das rotinas de dispersão/coleta pode melhorar o desempenho ao chamar AllocateAdapterChannel (conforme descrito anteriormente em Usando Packet-Based DMA do sistema e usando Packet-Based Bus-Master DMA). Ao contrário das chamadas para AllocateAdapterChannel, mais de uma chamada para GetScatterGatherList pode ser enfileirada para um objeto de dispositivo a qualquer momento. Um driver pode chamar GetScatterGatherList novamente para outra operação de DMA no mesmo objeto de driver antes que sua rotina AdapterListControl tenha concluído a execução.
No retorno da rotina AdapterListControl fornecida pelo driver, GetScatterGatherList mantém os registros de mapa, mas libera a estrutura do adaptador DMA.
Quando o driver atende à solicitação de transferência do IRP atual ou deve falhar o IRP devido a um erro de E/S de dispositivo ou barramento, ele deve chamar PutScatterGatherList antes de poder acessar os dados transferidos no buffer. PutScatterGatherList libera os buffers do adaptador e libera os registros de mapa e a lista de dispersão/coleta.