Compartir a través de


Cancelación de transacciones de DMA

[Solo se aplica a KMDF]

Si el controlador se ha compilado con la versión 1.11 o una versión posterior de KMDF y se ejecuta en Windows 8 o posterior mediante acceso directo a memoria (DMA) versión 3, el controlador puede intentar cancelar una transacción DMA pendiente llamando al método WdfDmaTransactionCancel.

Al llamar a WdfDmaTransactionCancel, el controlador debe asegurarse de que la transacción DMA especificada no se haya completado durante la llamada. El controlador puede usar la técnica siguiente para cancelar de forma segura una transacción, ya sea antes de la asignación del canal DMA o después de que ya se haya completado algún número de operaciones de transferencia:

  1. En uno de los controladores de solicitud del controlador, el controlador llama a WdfRequestMarkCancelableEx y proporciona una función de devolución de llamada EvtRequestCancel para la solicitud de E/S. A continuación, el controlador de solicitudes llama a WdfDmaTransactionExecute.

  2. La función de devolución de llamada EvtRequestCancel del controlador (que puede empezar a ejecutarse en un subproceso independiente inmediatamente después de la llamada a WdfRequestMarkCancelableEx) llama a WdfDmaTransactionCancel.

  3. Si la llamada a WdfDmaTransactionCancel se produce después de la llamada a WdfDmaTransactionExecute, pero antes de que el método WdfDmaTransactionExecute haya iniciado la asignación de DMA, la cancelación de transacciones se realiza correctamente y WdfDmaTransactionCancel devuelve TRUE. En este caso, la función de devolución de llamada EvtRequestCancel del controlador debe completar la transacción DMA. WdfDmaTransactionExecute devuelve un valor de error.

  4. Si el controlador llama a WdfDmaTransactionCancel después de que el método WdfDmaTransactionExecute haya iniciado la asignación de DMA, se producirá un error en el intento de cancelar la transacción y WdfDmaTransactionCancel devolverá FALSE. En este caso, WdfDmaTransactionExecute devuelve STATUS_SUCCESS y el controlador de solicitudes del controlador debe completar la transacción DMA.

    En este momento, si el controlador usa DMA en modo sistema, la función de devolución de llamada EvtRequestCancel podría llamar a WdfDmaTransactionStopSystemTransfer para intentar detener la transferencia DMA en curso del modo sistema. Para obtener un ejemplo de código que muestra cómo hacerlo, vea WdfDmaTransactionStopSystemTransfer.

  5. Una vez que el método WdfDmaTransactionExecute finaliza la asignación de DMA, el marco llama a la función de devolución de llamada EvtProgramDma del controlador (que puede empezar a ejecutarse en un subproceso independiente inmediatamente después de la llamada a WdfDmaTransactionExecute). En este momento, una llamada al método WdfDmaTransactionCancel devolvería FALSE.

    En EvtProgramDma, el controlador puede llamar a WdfRequestUnmarkCancelable para finalizar la posibilidad de cancelación de la solicitud. Si WdfRequestUnmarkCancelable devuelve STATUS_SUCCESS, la función de devolución de llamada debe programar el hardware para iniciar la transferencia. Si WdfRequestUnmarkCancelable devuelve STATUS_CANCELLED, se ha cancelado la solicitud. En este caso, EvtProgramDma debe llamar a WdfDmaTransactionDmaCompletedFinal para completar la transacción DMA.

    El controlador puede usar la misma técnica para cancelar una transacción DMA después de que ya se hayan completado algunas operaciones de transferencia. En este caso, el controlador llama a WdfDmaTransactionCancel después de llamar a WdfDmaTransactionDmaCompleted, pero antes de que el marco llame a EvtProgramDma para programar la siguiente operación de transferencia. Si el controlador llama a WdfDmaTransactionCancel antes de llamar a WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompleted devuelve TRUE, lo que indica que se ha completado la transacción DMA.