Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Para executar uma transferência de DMA que usa as rotinas na versão 3 da interface de operações de DMA, o driver deve seguir as etapas descritas na lista a seguir. Essas etapas são comuns a dispositivos subordinados e dispositivos mestres de barramento. A versão 3 dessa interface está disponível a partir do Windows 8. Para obter mais informações sobre as rotinas nessa interface, consulte DMA_OPERATIONS.
Etapa 1: Obter um objeto do adaptador DMA
Em preparação para uma transferência de DMA, o driver chama a rotina IoGetDmaAdapter para obter um objeto do adaptador DMA. Um objeto do adaptador DMA é um objeto de software que representa um dispositivo mestre de barramento ou uma linha de solicitação em um controlador DMA do sistema. Esse objeto contém a interface de operações de DMA para o barramento que é usado para transferir dados de ou para o dispositivo. Além disso, esse objeto sincroniza o acesso do driver aos recursos compartilhados necessários para executar a transferência. Para obter mais informações, consulte Introdução aos objetos do adaptador.
Etapa 2: obter uma descrição dos recursos de DMA necessários
O driver chama a rotina GetDmaTransferInfo para obter uma descrição dos recursos de DMA necessários para executar a transferência.
Os parâmetros de entrada para essa chamada descrevem o buffer de memória a ser usado para a transferência e a direção (leitura ou gravação) da transferência.
Os requisitos de recurso obtidos dessa chamada incluem o número de registros de mapa e o tamanho da lista de scatter/gather necessários para descrever o buffer de dados destinado à transferência. Na chamada subsequente para a rotina AllocateAdapterChannelEx (consulte a etapa 3), o driver fornece a contagem de registros do mapa como um parâmetro de entrada.
Etapa 3: Solicitar os recursos de DMA necessários
O driver chama a rotina AllocateAdapterChannelEx para alocar recursos para atribuir ao objeto do adaptador DMA. Esses recursos incluem um canal DMA e registros de mapa.
Uma chamada AllocateAdapterChannelEx pode ser assíncrona ou síncrona.
Se o sinalizador DMA_SYNCHRONOUS_CALLBACK não estiver definido, a chamada será assíncrona. Nesse caso, o parâmetro ExecutionRoutine aponta para uma rotina de execução fornecida pelo chamador que é chamada quando os recursos solicitados estão disponíveis. Se bem-sucedida, uma chamada assíncrona AllocateAdapterChannelEx retornará STATUS_SUCCESS sem esperar a execução da rotina.
Se o sinalizador DMA_SYNCHRONOUS_CALLBACK estiver definido, a chamada AllocateAdapterChannelEx será síncrona. Nesse caso, o parâmetro ExecutionRoutine na chamada é opcional e AllocateAdapterChannelEx se comporta da seguinte maneira:
Se ExecutionRoutine não for NULL e os recursos de DMA puderem ser alocados imediatamente, AllocateAdapterChannelEx chamará a rotina de execução no contexto do thread de chamada. Depois que a rotina de execução terminar de ser executada, AllocateAdapterChannelEx retornará STATUS_SUCCESS. Se os recursos não estiverem disponíveis imediatamente, AllocateAdapterChannelEx falhará e retornará o código de status de erro STATUS_INSUFFICIENT_RESOURCES.
Se ExecutionRoutine for nula e AllocateAdapterChannelEx puder alocar imediatamente os recursos de DMA, AllocateAdapterChannelEx retornará STATUS_SUCCESS. Se todos os recursos não estiverem disponíveis imediatamente, a chamada falhará com o código de status de erro STATUS_INSUFFICIENT_RESOURCES.
Para chamadas síncronas que retornam STATUS_SUCCESS, se o parâmetro MapRegisterBase para AllocateAdapterChannelEx não for NULL, AllocateAdapterChannelEx grava o endereço base dos registros de mapa alocados no endereço apontado pelo parâmetro MapRegisterBase. Se ExecutionRoutine for NULL, MapRegisterBase deverá ser não NULL. Se ExecutionRoutine não for NULL, o parâmetro MapRegisterBase para AllocateAdapterChannelEx será opcional e a rotina de execução receberá o endereço base do registro do mapa como um parâmetro de entrada.
Para chamadas assíncronas AllocateAdapterChannelEx , ExecutionRoutine deve ser não NULL e a rotina de execução recebe o endereço base do registro do mapa como um parâmetro de entrada.
Em chamadas subsequentes para a rotina MapTransferEx (consulte a etapa 5), o driver fornece o endereço base do registro do mapa como um parâmetro de entrada.
Se ExecutionRoutine não for NULL, a rotina de execução retornará um valor de status para indicar a disposição dos recursos alocados. Para transferências de DMA do sistema, esse valor retornado deve ser KeepObject. Esse valor informa ao sistema operacional que o objeto do adaptador (e todos os seus recursos alocados) está em uso e não deve ser liberado. Se nenhuma rotina de execução for fornecida, o driver deverá chamar a rotina FreeAdapterObject e fornecer KeepObject como o parâmetro AllocationOption .
Etapa 4: se necessário, cancele a solicitação de recurso pendente
Depois que uma chamada AllocateAdapterChannelEx enfileira um adaptador DMA para aguardar recursos de DMA, o driver pode, se necessário, chamar a rotina CancelAdapterChannel para cancelar a solicitação de recurso pendente.
Se CancelAdapterChannel retornar TRUE, a solicitação de recurso será cancelada com êxito. Se uma rotina de execução foi fornecida na chamada AllocateAdapterChannelEx , essa rotina não é executada.
Se CancelAdapterChannel retornar FALSE, a solicitação de recurso não poderá ser cancelada porque ela já foi concedida. Se uma rotina de execução tiver sido fornecida na chamada AllocateAdapterChannelEx , essa rotina será chamada.
Etapa 5: Inicializar os recursos de DMA e iniciar a transferência de DMA.
O driver chama MapTransferEx para inicializar os recursos de DMA e iniciar a transferência de DMA. Essa chamada pode ocorrer no mesmo thread de driver que chama AllocateAdapterChannelEx ou pode ocorrer na rotina de execução fornecida pelo driver para AllocateAdapterChannelEx. Se mais de uma chamada MapTransferEx for necessária para transferir todo o buffer de dados DMA, uma chamada MapTransferEx posterior poderá ocorrer na rotina de conclusão da chamada mapTransferEx anterior.
MapTransferEx dá suporte a MDLs encadeados como parâmetros de entrada. Cada MDL descreve uma região do buffer de DMA contígua na memória virtual. Quando MapTransferEx compila a lista de dispersão/coleta, ele manipula automaticamente as transições de uma região de buffer virtualmente contígua para a próxima sem intervenção do driver. Para obter mais informações, consulte Como usar a rotina MapTransferEx.
Para uma transferência de DMA do sistema, um ponteiro para uma rotina de conclusão de DMA pode ser passado para MapTransferEx no parâmetro DmaCompletionRoutine opcional. Essa rotina está agendada para ser executada no nível de expedição em resposta a uma interrupção do controlador DMA do sistema que indica que a transferência de DMA está concluída.
Se MapTransferEx não conseguir mapear todo o tamanho de transferência solicitado, ele definirá o parâmetro de saída *Comprimento para o comprimento mapeado e retornará STATUS_SUCCESS.
Etapa 6: se necessário, execute operações específicas de hardware
MapTransferEx retorna STATUS_SUCCESS para indicar que a transferência de DMA foi iniciada com êxito. Em algumas plataformas, o driver pode ter que executar alguma ação adicional, fora da chamada MapTransferEx , para iniciar a transferência, mas esse tipo de início atrasado não é necessário para todas as plataformas. Os drivers não devem depender desses atrasos para tomar decisões sobre o uso e liberação de recursos alocados.
As rotinas na interface de operações de DMA mantêm a coerência de cache para transferências de DMA de forma transparente para os drivers que usam essas rotinas. Em plataformas que não impõem coerência de cache no hardware, MapTransferEx garante que os caches de dados do processador sejam esvaziados antes das transferências de escrita (memória para dispositivo). Para transferências de leitura (dispositivo para memória), os caches são invalidados durante a chamada para a rotina FlushAdapterBuffersEx (consulte a etapa 8), que segue cada chamada MapTransferEx.
Etapa 7: Receber notificação quando a transferência de DMA for concluída
Quando uma transferência de DMA é concluída, o driver é notificado de uma destas duas maneiras:
- Uma interrupção no driver do dispositivo para um dispositivo mestre de barramento
- Execução da rotina de conclusão fornecida pelo driver para um dispositivo subordinado que usa um controlador DMA do sistema
Para uma transferência de DMA do sistema, um driver pode inserir uma rotina de conclusão para MapTransferEx como parâmetro de entrada.
Etapa 8: Liberar todos os dados que permanecem no cache
Após a conclusão da transferência de DMA, o driver deve chamar a rotina FlushAdapterBuffersEx para liberar todos os dados que permanecem no cache. O driver deve chamar FlushAdapterBuffersEx após cada chamada MapTransferEx.
Se uma chamada MapTransferEx mapear apenas uma parte do buffer de dados DMA, o driver deverá chamar MapTransferEx novamente para mapear os dados restantes. Uma transferência complexa pode exigir várias chamadas MapTransferEx . Para cada chamada mapTransferEx adicional, repita as etapas de 5 a 8.
Etapa 9: Liberar o canal DMA e os registros de mapa
Depois que todo o buffer de dados DMA for mapeado com êxito e a transferência final for concluída, o driver deverá chamar a rotina FreeAdapterChannel para liberar o canal DMA e quaisquer registros de mapa alocados anteriormente.
Etapa 10: Liberar o objeto do adaptador DMA
Depois que todas as transferências de DMA forem concluídas e todos os registros de mapa alocados anteriormente forem liberados, o driver chamará a rotina PutDmaAdapter para liberar o objeto do adaptador.