다음을 통해 공유


DMA 전송 완료

[KMDF에만 적용]

일반적으로 드라이버의 EvtInterruptDpc 콜백 함수는 각 DMA 전송 처리를 완료합니다.

첫째, 여러 DMA 트랜잭션이 동시에 진행될 수 있으므로 EvtInterruptDpc 콜백 함수는 완료된 전송이 연결된 DMA 트랜잭션을 결정해야 합니다. 콜백 함수는 드라이버가 DMA 트랜잭션 시작할 때 저장한 트랜잭션 핸들을 검색하여 이 작업을 수행할 수 있습니다. 디바이스 확장을 검색하기 위해 PLX9x5x 샘플은 Private.h 헤더 파일에서 PLxGetDeviceContext 함수를 정의합니다.

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_EXTENSION, PLxGetDeviceContext)

그런 다음 드라이버의 EvtInterruptDpc 콜백에서 다음을 수행합니다.

WDFDMATRANSACTION   dmaTransaction;
PDEVICE_EXTENSION   devExt;
...
devExt  = PLxGetDeviceContext(WdfInterruptGetDevice(Interrupt));
...
dmaTransaction = devExt->WriteDmaTransaction;

다음으로, EvtInterruptDpc 콜백 함수는 다음 전송 완료 방법 중 하나를 호출하여 전송이 완료되었다는 것을 프레임워크에 알려야 합니다.

  • WdfDmaTransactionDmaCompleted. 전송이 성공적으로 완료되고 하드웨어에서 전송된 바이트 수를 보고하지 않는 경우

  • WdfDmaTransactionDmaCompletedWithLength, 전송이 성공적으로 완료되고 하드웨어가 전송된 바이트 수(또는 전송되지 않은 바이트 수)를 보고하거나 드라이버가 오류를 감지하고 전송을 다시 시도할 0의 전송 수를 지정하는 경우입니다. 드라이버가 전송 횟수 0을 지정하는 경우 프레임워크는 남아 있는 바이트 수에서 0을 빼서 EvtProgramDma 콜백 함수로 동일한 전송을 보냅니다.

  • 하드웨어가 언더런 또는 실패 조건을 보고하는 경우 WdfDmaTransactionDmaCompletedFinal.

드라이버는 WdfDmaTransactionGetCurrentDmaTransferLength 호출하여 완료된 전송의 원래 길이를 가져올 수 있습니다. 이 호출은 드라이버가 원래 전송 길이에서 전송되지 않은 바이트 수를 빼고 WdfDmaTransactionGetCurrentDmaTransferLength 호출하여 실제 전송 크기를 보고할 수 있으므로 디바이스에서 전송되지 않은 바이트 수를 보고하는 경우에 유용합니다.

위의 각 전송 완료 방법은 단일 DMA 전송(전체 DMA 트랜잭션아님)이 완료되었다는 것을 프레임워크에 알릴 수 있습니다. 드라이버가 이러한 메서드 중 하나를 호출한 후 드라이버는 메서드의 반환 값을 확인하여 트랜잭션에 더 많은 전송이 필요한지 확인합니다.

  • 완료 메서드의 반환 값이 FALSE 경우 프레임워크는 DMA 트랜잭션 처리를 완료하기 위해 추가 DMA 전송이 필요하다고 결정했습니다.

    일반적으로 드라이버의 EvtInterruptDpc 콜백 함수는 그냥 반환합니다. 프레임워크는 드라이버의 EvtProgramDma 콜백 함수를 다시 호출하고 콜백 함수는 다음 전송을 위해 하드웨어를 프로그래밍할 수 있습니다.

    전송 완료 메서드는 상태 값을 STATUS_MORE_PROCESSING_REQUIRED로 제공하며 이 경우 항상 그렇습니다.

  • 반환 값이 TRUE인 경우, DMA 트랜잭션에 대해 더 이상의 전송은 발생하지 않습니다.

    전송 완료 메서드는 상태 값을 제공합니다. 상태 값이 STATUS_SUCCESS일 경우, DMA 트랜잭션에 대한 모든 전송이 완료되며 드라이버는 DMA 트랜잭션을완료해야 합니다. 상태 값이 다른 경우 오류가 발생하고 DMA 트랜잭션이 완료되지 않았을 수 있습니다.

EvtInterruptDpc 콜백 함수가 일반적으로 타이머 만료 또는 전송 오류를 알리는 하드웨어 인터럽트로 인해 오류를 감지하는 경우 드라이버는 트랜잭션의 현재 전송을 다시 시작할 수 있습니다.

트랜잭션의 현재 전송을 다시 시작하기 위해 드라이버의 EvtInterruptDpc 콜백 함수는 TransferedLength 매개 변수가 0으로 설정된 WdfDmaTransactionDmaCompletedWithLength 호출할 수 있습니다.