Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Para executar uma transferência DMA que usa as rotinas na versão 3 da interface de operações DMA, seu driver deve seguir as etapas descritas na lista a seguir. Essas etapas são comuns a dispositivos subordinados e dispositivos bus-master. A versão 3 desta 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 de adaptador DMA
Em preparação para uma transferência DMA, o driver chama a rotina IoGetDmaAdapter para obter um objeto de adaptador DMA. Um objeto de adaptador DMA é um objeto de software que representa um dispositivo bus-master ou uma linha de pedido num controlador DMA do sistema. Este objeto contém a interface de operações DMA para o barramento utilizado na transferência de dados para o dispositivo ou a partir dele. 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 DMA necessários
O driver chama a rotina GetDmaTransferInfo para obter uma descrição dos recursos DMA necessários para executar a transferência.
Os parâmetros de entrada para esta 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 recursos obtidos nesta chamada incluem o número de registros de mapa e o tamanho da lista de dispersão/coleta necessária para descrever o buffer de dados para a transferência. Na chamada subsequente para a rotina AllocateAdapterChannelEx (consulte a etapa 3), o controlador do dispositivo fornece o número de registos de mapa como parâmetro de entrada.
Etapa 3: Solicitar os recursos DMA necessários
O driver chama a rotina AllocateAdapterChannelEx para alocar recursos a serem atribuídos ao objeto do adaptador DMA. Esses recursos incluem um canal DMA e registros de mapas.
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 for bem-sucedida, uma chamada assíncrona AllocateAdapterChannelEx retornará STATUS_SUCCESS sem aguardar a execução da rotina de execução.
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 for não-NULL e os recursos 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 termina de ser executada, AllocateAdapterChannelEx retorna STATUS_SUCCESS. Se os recursos não estiverem imediatamente disponíveis, AllocateAdapterChannelEx falhará e retornará o código de status de erro STATUS_INSUFFICIENT_RESOURCES.
Se ExecutionRoutine for NULL e AllocateAdapterChannelEx puder alocar imediatamente os recursos DMA, AllocateAdapterChannelEx retorna STATUS_SUCCESS. Se todos os recursos não estiverem imediatamente disponíveis, 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 for não-NULL, AllocateAdapterChannelEx grava o endereço base dos registros de mapa alocados no endereço apontado pelo parâmetro MapRegisterBase . Se ExecutionRoutine for nulo, MapRegisterBase deverá ser não nulo. Se ExecutionRoutine não estiver definido (não-NULL), o parâmetro MapRegisterBase para AllocateAdapterChannelEx torna-se opcional, e a rotina de execução recebe o endereço base do registro de mapa como 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 de mapa como um parâmetro de entrada.
Em chamadas subsequentes para a rotina MapTransferEx (veja a etapa 5), o driver fornece o endereço base do registro de mapa como um parâmetro de entrada.
Se ExecutionRoutine for não-NULL, a rotina de execução retornará um valor de status para indicar a disposição dos recursos alocados. Para transferências DMA do sistema, esse valor de retorno 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 deve, em vez disso, 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 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 já foi concedida. Se uma rotina de execução foi fornecida na chamada AllocateAdapterChannelEx , essa rotina será chamada.
Etapa 5: Inicializar os recursos do DMA e começar a transferência de dados.
O driver chama MapTransferEx para inicializar os recursos DMA e iniciar a transferência DMA. Essa chamada pode ocorrer no mesmo thread de driver que chama AllocateAdapterChannelEx, ou pode ocorrer na rotina de execução que o driver fornece a 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 suporta MDLs encadeadas como parâmetros de entrada. Cada MDL descreve uma região do buffer DMA que é contígua na memória virtual. Quando MapTransferEx cria a lista de dispersão/coleta, ele lida automaticamente com transições de uma região de buffer praticamente contígua para a próxima sem intervenção do driver. Para obter mais informações, consulte Usando a rotina MapTransferEx.
Para uma transferência 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á programada para ser executada no nível de despacho em resposta a uma interrupção do controlador DMA do sistema que indica que a transferência 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 *Length para o comprimento que foi 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 DMA foi iniciada com êxito. Em algumas plataformas, o driver pode ter que tomar 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 condutores não devem depender desses atrasos para tomarem decisões sobre a utilização e libertação dos recursos atribuídos.
As rotinas na interface de operações DMA mantêm a coerência de cache para transferências DMA de forma transparente para os drivers que usam essas rotinas. Em plataformas que não impõem a coerência de cache no hardware, MapTransferEx garante que os caches de dados do processador sejam esvaziados antes das transferências de gravação (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) após cada chamada de MapTransferEx.
Etapa 7: Receber notificação quando a transferência DMA terminar
Quando uma transferência DMA é concluída, o driver é notificado de uma destas duas maneiras:
- Uma interrupção para o driver do dispositivo, para um controlador de barramento
- Execução da rotina de conclusão fornecida pelo motorista, para um dispositivo subordinado que usa um controlador DMA do sistema
Para uma transferência DMA do sistema, um driver pode fornecer 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 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 mapeia apenas uma parte do buffer de dados DMA, o driver deve 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 5 a 8.
Passo 9: Liberte o canal DMA e os registos de mapas
Depois que todo o buffer de dados DMA for mapeado com êxito e a transferência final for concluída, o driver deve chamar a rotina FreeAdapterChannel para liberar o canal DMA e quaisquer registros de mapa alocados anteriormente.
Etapa 10: Solte o objeto do adaptador DMA
Depois que todas as transferências DMA forem concluídas e todos os registros de mapa alocados anteriormente forem liberados, o driver chama a rotina PutDmaAdapter para liberar o objeto do adaptador.