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.
[Aplica-se somente ao KMDF]
Este tópico descreve a funcionalidade que um driver KMDF para um dispositivo DMA mestre de barramento normalmente fornece em sua função de retorno de chamada de evento EvtProgramDma . Se o driver usar o suporte de DMA da estrutura, você deverá fornecer esse retorno de chamada. Essas informações também se aplicam a um driver KMDF para um dispositivo DMA no modo sistema que tem uma interrupção de hardware.
A função de retorno de chamada EvtProgramDma, chamada em IRQL = DISPATCH_LEVEL, programa o dispositivo para iniciar uma transferência de DMA. Os parâmetros de entrada para essa função de retorno de chamada fornecem a direção da transferência (entrada ou saída) e uma lista de dispersão/coleta. Se a transferência consistir em um único pacote, a lista de dispersão/coleta conterá um único elemento.
A função de retorno de chamada EvtProgramDma programa o dispositivo usando os recursos de hardware que a função de retorno de chamada EvtDevicePrepareHardware do driver recebeu. Se a função de retorno de chamada EvtProgramDma programar com êxito o hardware, ela retornará TRUE.
Depois que o hardware conclui a transferência de DMA, ele normalmente emite uma interrupção e o sistema chama a função de retorno de chamada EvtInterruptIsr do driver. A função de retorno de chamada EvtInterruptIsr do driver geralmente:
Limpa a interrupção de hardware.
Salva as informações de contexto da interrupção se forem necessárias. Essas informações podem ser perdidas após o retorno da função de retorno de chamada e o sistema reduz o IRQL (porque a redução do IRQL permite que ocorram interrupções adicionais).
Chama WdfInterruptQueueDpcForIsr para agendar uma função de retorno de chamada EvtInterruptDpc.
A função de retorno de chamada EvtInterruptDpcconclui a transferência de DMA usando informações de contexto salvas pela função de retorno de chamada EvtInterruptIsr .
Se a função de retorno de chamada EvtProgramDma detectar um erro, o driver poderá interromper a transação.
Para interromper uma transação quando o driver detecta um erro, a função de retorno de chamada EvtProgramDma deve:
Chame WdfObjectDelete para excluir o objeto de transação DMA ou chame WdfDmaTransactionRelease para liberar e reutilizar o objeto de transação DMA.
Requeue a solicitação de E/S ou conclua a solicitação de E/S, se a transação estiver associada a um objeto de solicitação de estrutura. Para recuperar um identificador para a solicitação, o driver pode chamar WdfDmaTransactionGetRequest.
Retorne FALSE.
As etapas 1 e 4 são ilustradas no exemplo de código a seguir, extraído da função de retorno de chamada EvtProgramDma do exemplo PLX9x5x para solicitações de leitura no arquivo Read.c.
// If errors occur in the EvtProgramDma callback,
// release the DMA transaction object and complete the request.
if (errors) {
NTSTATUS status;
//
// Must abort the transaction before deleting.
//
(VOID) WdfDmaTransactionDmaCompletedFinal(Transaction, 0, &status);
ASSERT(NT_SUCCESS(status));
PLxReadRequestComplete( Transaction, STATUS_INVALID_DEVICE_STATE );
TraceEvents(TRACE_LEVEL_ERROR, DBG_READ,
"<-- PLxEvtProgramReadDma: errors ****");
return FALSE;
}
O exemplo chama a função PLxReadRequestComplete para executar as etapas 2 e 3:
VOID
PLxReadRequestComplete(
IN WDFDMATRANSACTION DmaTransaction,
IN NTSTATUS Status
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
WDFREQUEST request;
size_t bytesTransferred;
//
// Get the associated request from the transaction.
//
request = WdfDmaTransactionGetRequest(DmaTransaction);
ASSERT(request);
//
// Get the final bytes transferred count.
//
bytesTransferred = WdfDmaTransactionGetBytesTransferred( DmaTransaction );
TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC,
"PLxReadRequestComplete: Request %p, Status %!STATUS!, "
"bytes transferred %d\n",
request, Status, (int) bytesTransferred );
WdfDmaTransactionRelease(DmaTransaction);
//
// Complete this Request.
//
WdfRequestCompleteWithInformation( request, Status, bytesTransferred);
}