Alocando o objeto do adaptador Bus-Master

Para se preparar para o DMA bus-master baseado em pacotes, um driver chama KeFlushIoBuffers e AllocateAdapterChannel na sequência de receber um IRP_MJ_READ ou IRP_MJ_WRITE. Antes de o condutor chamar estas rotinas, a sua rotina de expedição deve verificar a validade dos parâmetros do IRP. Ele também pode enfileirar o IRP para outra rotina de driver para processamento posterior. A solicitação de transferência é o IRP atual que requer uma operação de E/S do dispositivo.

A rotina do driver que chama AllocateAdapterChannel deve ser executada em IRQL = DISPATCH_LEVEL. Junto com um ponteiro para o objeto do adaptador retornado por IoGetDmaAdapter, um driver deve fornecer o seguinte ao chamar AllocateAdapterChannel:

  • Um ponteiro para o objeto de dispositivo alvo do IRP (Pedido de E/S) atual

  • O ponto de entrada para a rotina AdapterControl

  • Um ponteiro para qualquer informação de contexto determinada pelo driver que a rotina AdapterControl utilizará.

AllocateAdapterChannel enfileira a rotina de do AdapterControl do driver, que é executada quando o objeto do adaptador está livre e um conjunto de registros de mapa foi alocado para as operações DMA do driver de ou para o dispositivo de destino.

Na entrada, uma rotina de AdapterControl recebe o DeviceObject e ponteiros de de contexto passados na chamada para AllocateAdapterChannel , bem como um identificador (MapRegisterBase) para os registros de mapa alocados.

A rotina AdapterControl também recebe um ponteiro para o DeviceObject->CurrentIrp se o driver tiver uma rotina StartIo. Se o driver gere o seu próprio enfileiramento de IRPs em vez de ter uma rotina StartIo, o driver deve incluir um ponteiro para o IRP atual como parte do contexto que ele fornece ao chamar AllocateAdapterChannel.

Para o driver de um dispositivo DMA bus-master sem capacidades de dispersão e coleta, a rotina AdapterControl geralmente realiza o seguinte:

  1. Salva ou inicializa qualquer contexto que o driver mantenha sobre as operações DMA. O contexto pode incluir a entrada MapRegisterBase manipulador que o controlador deve passar para MapTransfer e FlushAdapterBuffers, o Comprimento em bytes da transferência solicitada a partir da sua localização de pilha de E/S no IRP, entre outros.

  2. As chamadas MmGetMdlVirtualAddress, seguidas por MapTransfer (descrito em Setting Up a Transfer Operation, a seguir), são usadas para obter o endereço lógico que o dispositivo pode usar para iniciar a operação de transferência.

  3. Configura o adaptador bus-master para iniciar a operação de transferência.

  4. Retorna o valor DeallocateObjectKeepRegisters.

Para o driver de um dispositivo de mestre de barramento com capacidades de dispersão/coleta, a rotina AdapterControl geralmente executa o seguinte:

  1. Salva ou inicializa qualquer estado que o driver mantenha sobre operações DMA, como salvar o MapRegisterBase manipulador que o driver deve passar para MapTransfer e FlushAdapterBuffers, o de comprimento de em bytes da transferência solicitada de seu local de pilha de E/S no IRP e assim por diante.

  2. Chama MmGetMdlVirtualAddress seguida por MapTransfer (descrito na próxima subseção) para obter o endereço lógico que o seu dispositivo pode usar para iniciar a operação de transferência.

    A rotina AdapterControl chama MapTransfer repetidamente até que tenha usado todos os registos de mapa disponíveis para construir uma lista de dispersão/recolha para o adaptador bus-master.

  3. Configura o adaptador bus-master para iniciar a operação de transferência.

  4. Retorna o valor DeallocateObjectKeepRegisters.

Para obter informações adicionais, consulte Writing AdapterControl Routines.

Observe que os drivers que efetuam o DMA de bus-master podem utilizar as rotinas GetScatterGatherList e PutScatterGatherList, independentemente de os seus dispositivos suportarem DMA de dispersão/coleta. A utilização destas rotinas altera os requisitos para a rotina AdapterControl do controlador; consulte Utilização do DMA de dispersão e recolha para obter detalhes.

Uma rotina AdapterControl deve retornar um valor definido pelo sistema do tipo IO_ALLOCATION_ACTION. Para drivers que usam o DMA bus-master, a rotina AdapterControl normalmente deve retornar o valor DeallocateObjectKeepRegisters, que permite que o driver mantenha os registros de mapa alocados para o objeto de dispositivo de destino até que tenha transferido todos os dados solicitados para o IRP atual. Depois que a transferência for concluída, a rotina do DPC deve chamar FreeMapRegisters para liberar os registros de mapa alocados. Nos casos em que o dispositivo não suporta enfileiramento de comandos, a rotina AdapterControl pode, no entanto, retornar KeepObject quando a transferência para o IRP atual estiver concluída, e a rotina DPC pode, em vez disso, chamar FreeAdapterChannel.

Uma rotina AdapterControl não pode esperar que o adaptador mestre de barramento conclua uma operação DMA.

Independentemente de o adaptador bus-master suportar dispersão e recolha, a rotina AdapterControl deve fazer pelo menos o seguinte:

  1. Salve as informações de contexto necessárias, particularmente o identificador de MapRegisterBase, na extensão do dispositivo do driver, na extensão do controlador ou em outra área de armazenamento residente acessível pelo driver (pool não paginado, alocado pelo driver). O driver deve passar esta alça quando invocar MapTransfer e FlushAdapterBuffers.

  2. Retornar DeallocateObjectKeepRegisters.

Outra rotina de driver (provavelmente a rotina DpcForIsr) deve chamar FlushAdapterBuffers quando cada operação de transferência DMA é concluída. Esta rotina também deve configurar quaisquer operações DMA adicionais necessárias para satisfazer o IRP atual.

Quando o driver atendeu à solicitação de transferência do IRP atual ou deve cancelar o IRP devido a um erro de E/S de dispositivo ou barramento, ele deve chamar FreeMapRegisters. Esta chamada deve ocorrer imediatamente após a última chamada para FlushAdapterBuffers para o IRP atual, de modo que o driver possa atender outras solicitações de DMA, possivelmente para outros dispositivos no barramento de dados.