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:

  1. MmGetMdlVirtualAddress para obter um índice no MDL, necessário como um parâmetro na chamada para GetScatterGatherList

  2. 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.

  3. 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.