다음을 통해 공유


WdfDmaTransactionDmaCompleted 함수(wdfdmatransaction.h)

[KMDF에만 적용]

WdfDmaTransactionDmaCompleted 메서드는 디바이스의 DMA 전송 작업이 완료되었음을 프레임워크에 알 수 있습니다.

구문

BOOLEAN WdfDmaTransactionDmaCompleted(
  [in]  WDFDMATRANSACTION DmaTransaction,
  [out] NTSTATUS          *Status
);

매개 변수

[in] DmaTransaction

드라이버가 WdfDmaTransactionCreate에 대한 이전 호출에서 가져온 DMA 트랜잭션 개체에 대한 핸들입니다.

[out] Status

DMA 전송의 상태 수신하는 위치에 대한 포인터입니다. 자세한 내용은 아래 설명 부분을 참조하십시오.

반환 값

WdfDmaTransactionDmaCompletedFALSE 를 반환하고 DMA 트랜잭션을 완료하기 위해 추가 전송이 필요한 경우 상태가 STATUS_MORE_PROCESSING_REQUIRED 받습니다. 메서드는 추가 전송이 필요하지 않은 경우 TRUE 를 반환합니다.

드라이버가 잘못된 개체 핸들을 제공하는 경우 버그 검사 발생합니다.

설명

프레임워크 기반 드라이버는 DMA 전송 이 완료 될 때마다 다음 방법 중 하나를 호출해야 합니다.

일반적으로 드라이버는 디바이스 인터럽트가 DMA 전송 작업의 완료를 나타낸 후 EvtInterruptDpc 이벤트 콜백 함수 내에서 이러한 메서드를 호출합니다. 시스템 모드 DMA 디바이스의 드라이버는 EvtDmaTransactionDmaTransferComplete 이벤트 콜백 함수 내에서 이러한 메서드를 호출할 수 있습니다.

프레임워크는 DMA 트랜잭션을 여러 DMA 전송 작업으로 나눌 수 있습니다. 따라서 드라이버는 메서드의 반환 값을 검사하여 추가 전송이 필요한지 확인해야 합니다.

메서드가 FALSE를 반환하는 경우 상태 위치는 STATUS_MORE_PROCESSING_REQUIRED 받고 트랜잭션을 완료하려면 추가 DMA 작업이 필요합니다. 일반적으로 EvtInterruptDpc 이벤트 콜백 함수는 이 시점에서 다른 작업을 수행하지 않습니다. 대신 프레임워크는 드라이버의 EvtProgramDma 이벤트 콜백 함수를 호출하므로 콜백 함수는 다음 전송을 시작할 수 있습니다.

메서드가 TRUE를 반환하는 경우 지정된 트랜잭션에 대해 더 이상 전송되지 않습니다. 이 경우 STATUS_SUCCESS 상태 값은 프레임워크에 오류가 발생하지 않고 DMA 트랜잭션이 완료됨을 의미합니다.

드라이버가 WdfDmaTransactionDmaCompleted를 호출하기 전에 WdfDmaTransactionStopSystemTransfer를 호출하면 WdfDmaTransactionDmaCompletedTRUE를 반환하고 상태 값은 STATUS_CANCELLED.

단일 전송에 대해 설정된 트랜잭션의 경우 WdfDmaTransactionDmaCompleted는 초기화에 성공했음에도 불구하고 하드웨어가 단일 전송에서 트랜잭션을 완료하지 못하면 TRUEstatus 값 STATUS_WDF_TOO_MANY_TRANSFERS 반환합니다. 이는 각 DMA 작업에 대한 잔여 전송을 보고하는 하드웨어에서 발생할 수 있습니다. 예를 들어 드라이버는 64KB를 작성하도록 디바이스를 프로그래밍하지만 디바이스는 60KB만 씁니다. 이 경우 드라이버는 DMA 작업을 반복하거나 디바이스를 다시 설정할 수 있습니다.

Status에 대한 다른 값은 프레임워크에서 오류를 감지했으며 DMA 트랜잭션이 완료되지 않았을 수 있음을 의미합니다.

WdfDmaTransactionDmaCompletedTRUE를 반환하는 경우 드라이버는 일반적으로 다음을 수행합니다.

DMA 전송을 완료하는 방법에 대한 자세한 내용은 DMA 전송 완료를 참조하세요.

예제

다음 코드 예제는 AMCC5933 샘플 드라이버에서 가져옵니다. 이 예제에서는 EvtInterruptDpc 콜백 함수를 보여줍니다. 이 예제는 프레임워크에 DMA 전송이 완료되었음을 알 수 있습니다. 프레임워크에서 이 전송이 DMA 트랜잭션의 마지막 전송임을 나타내는 경우 코드는 DMA 트랜잭션 개체를 삭제하고 연결된 I/O 요청을 완료합니다.

VOID
AmccPciEvtInterruptDpc(
    IN WDFINTERRUPT  WdfInterrupt,
    IN WDFOBJECT  WdfDevice
    )
{
    PAMCC_DEVICE_EXTENSION  devExt;
    WDFREQUEST  request;
    REQUEST_CONTEXT  *transfer;
    NTSTATUS  status;
    size_t  transferred;
    BOOLEAN  transactionComplete;

    UNREFERENCED_PARAMETER( WdfInterrupt );

    //
    // Retrieve request and transfer.
    //
    devExt = AmccPciGetDevExt(WdfDevice);
    request  = devExt->CurrentRequest;
    transfer = GetRequestContext(request);

    //
    // Check to see if the request has been canceled. 
    //
    if (WdfRequestIsCanceled(request)) {
        TraceEvents(
                    TRACE_LEVEL_ERROR,
                    AMCC_TRACE_IO,
                    "Aborted DMA transaction 0x%p",
                    request
                    );
        WdfObjectDelete( transfer->DmaTransaction );
        devExt->CurrentRequest = NULL;
        WdfRequestComplete(
                           request,
                           STATUS_CANCELLED
                           );
        return;
    }
 
    //
    // Notify the framework that a DMA transfer has completed.
    //
    transactionComplete = WdfDmaTransactionDmaCompleted(
                                                    transfer->DmaTransaction,
                                                    &status
                                                    );
    if (transactionComplete) {
        ASSERT(status != STATUS_MORE_PROCESSING_REQUIRED);

        //
        // No more data. The request is complete.
        //
        TraceEvents(
                    TRACE_LEVEL_INFORMATION,
                    AMCC_TRACE_IO,
                    "Request %p completed: status %X",  
                    request,
                    status
                    );

        //
        // Get the byte count.
        //
        transferred =
                WdfDmaTransactionGetBytesTransferred(transfer->DmaTransaction);

        TraceEvents(
                    TRACE_LEVEL_INFORMATION,
                    AMCC_TRACE_IO,
                    "Bytes transferred %d",
                    (int) transferred
                    );

        //
        // Delete this DmaTransaction object.
        //
        WdfObjectDelete(transfer->DmaTransaction);

        //
        // Clean up the device context for this request.
        //
        devExt->CurrentRequest = NULL;

        //
        // Complete this I/O request.
        //
        WdfRequestCompleteWithInformation(
                                          request, 
                                          status,
                                          (NT_SUCCESS(status)) ? transferred : 0
                                          );
    }
}

요구 사항

요구 사항
대상 플랫폼 유니버설
최소 KMDF 버전 1.0
머리글 wdfdmatransaction.h(Wdf.h 포함)
라이브러리 Wdf01000.sys(프레임워크 라이브러리 버전 관리 참조)
IRQL <=DISPATCH_LEVEL
DDI 규정 준수 규칙 DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

추가 정보

EvtInterruptDpc

EvtProgramDma

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionRelease

WdfObjectDelete

WdfRequestComplete

WdfRequestCompleteWithInformation