WdfDmaTransactionExecute 함수(wdfdmatransaction.h)

[KMDF에만 적용]

WdfDmaTransactionExecute 메서드는 지정된 DMA 트랜잭션의 실행을 시작합니다.

구문

NTSTATUS WdfDmaTransactionExecute(
  [in]           WDFDMATRANSACTION DmaTransaction,
  [in, optional] WDFCONTEXT        Context
);

매개 변수

[in] DmaTransaction

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

[in, optional] Context

드라이버 정의 컨텍스트 정보입니다. 프레임워크는 포인터가 될 수 있는 Context에 지정된 값을 드라이버의 EvtProgramDma 이벤트 콜백 함수에 전달합니다. 이 매개 변수는 선택 사항이며 NULL일 수 있습니다.

반환 값

WdfDmaTransactionExecute 는 작업이 성공하면 STATUS_SUCCESS 반환합니다. 그렇지 않으면 메서드는 다음 값 중 하나를 반환할 수 있습니다.

반환 코드 설명
STATUS_INSUFFICIENT_RESOURCES
이전에 WdfDmaTransactionSetImmediateExecution 이라는 드라이버와 요청에 필요한 리소스를 사용할 수 없습니다.
STATUS_INVALID_DEVICE_REQUEST
WdfDmaTransactionExecute에 대한 호출 앞에 WdfDmaTransactionInitialize 또는 WdfDmaTransactionInitializeUsingRequest를 호출하지 않았습니다.
STATUS_WDF_BUSY
디바이스는 단일 패킷 전송을 수행하고 다른 트랜잭션이 실행되는 동안 WdfDmaTransactionExecute 라는 드라이버를 수행합니다.
STATUS_WDF_TOO_FRAGMENTED
운영 체제에서 지정된 전송 크기를 처리하는 데 필요한 분산/수집 요소 수가 드라이버가 WdfDmaEnablerSetMaximumScatterGatherElements 를 호출한 값보다 큽니다. 자세한 내용은 아래 설명 부분을 참조하십시오.
 

이 메서드는 다른 NTSTATUS 값을 반환할 수도 있습니다.

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

설명

WdfDmaTransactionExecute 메서드는 지정된 DMA 트랜잭션과 연결된 첫 번째 DMA 전송에 대한 트랜잭션의 분산/수집 목록을 초기화합니다. (단일 패킷 전송의 경우 분산/수집 목록에는 단일 요소가 포함됩니다.) 그런 다음, 메서드는 드라이버의 EvtProgramDma 이벤트 콜백 함수를 호출하고 콜백 함수는 디바이스를 프로그래밍하여 전송을 시작할 수 있습니다.

프레임워크 기반 드라이버는 일반적으로 I/O 큐 이벤트 콜백 함수 내에서 WdfDmaTransactionExecute를 호출합니다.

드라이버가 WdfDmaTransactionInitialize 또는 WdfDmaTransactionInitializeUsingRequest를 호출하여 DMA 트랜잭션을 초기화한 후 드라이버는 DMA 트랜잭션을 완료하기 전에 WdfDmaTransactionExecute를 한 번만 호출해야 합니다.

WdfDmaTransactionInitializeXxx가 성공을 반환하지만 WdfDmaTransactionExecute가 오류 값을 반환하는 경우 드라이버는 WdfDmaTransactionRelease를 호출해야 합니다.

1.11 이전 프레임워크 버전에서 디바이스가 단일 패킷 전송을 수행하는 경우 운영 체제는 한 번에 하나의 DMA 트랜잭션만 실행할 수 있습니다. 이 경우 WdfDmaTransactionExecute 는 다른 트랜잭션이 실행되는 경우 STATUS_WDF_BUSY 반환합니다.

프레임워크 버전 1.11 이상에서 드라이버가 DMA 버전 3을 사용하여 단일 패킷 전송을 수행하는 경우 운영 체제는 내부 큐에 여러 DMA 트랜잭션을 저장할 수 있습니다. 이 경우 드라이버는 다른 트랜잭션이 실행되는 동안 WdfDmaTransactionExecute 를 호출할 수 있습니다. DMA 버전 3을 선택하려면 WDF_DMA_ENABLER_CONFIGWdmDmaVersionOverride 멤버를 3으로 설정합니다.

디바이스가 분산/수집 전송을 수행하는 경우 운영 체제는 여러 DMA 트랜잭션을 동시에 실행할 수 있습니다. 이 경우 드라이버는 다른 트랜잭션이 실행되는 동안 WdfDmaTransactionExecute 를 호출할 수 있습니다.

드라이버가 WdfDmaTransactionDmaCompletedWithLength를 호출하여 부분 전송을 보고하고 드라이버가 함께 연결된 MDL을 사용하여 DMA 트랜잭션의 데이터 버퍼를 지정한 경우(MDL 구조의 다음 멤버 사용) WdfDmaTransactionExecute는 프레임워크가 조각의 수와 크기를 다시 계산하고 허용되는 조각 수를 초과할 수 있으므로 STATUS_WDF_TOO_FRAGMENTED 반환할 수 있습니다.

트랜잭션이 성공적으로 시작되면 WdfDmaTransactionExecute 는 STATUS_SUCCESS 반환합니다. 프레임워크가 모든 트랜잭션 전송을 드라이버의 EvtProgramDma 콜백 함수로 성공적으로 보냈는지 확인하려면 드라이버가 WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompletedWithLength 또는 WdfDmaTransactionDmaCompletedFinal을 호출해야 합니다.

Context 매개 변수가 제공하는 값이 포인터 또는 핸들인 경우 참조하는 메모리는 IRQL = DISPATCH_LEVEL 드라이버의 EvtProgramDma 이벤트 콜백 함수에서 액세스할 수 있어야 합니다. 프레임워크 개체 컨텍스트를 사용하여 이 요구 사항을 충족할 수 있습니다.

드라이버는 이전에 WdfDmaTransactionSetImmediateExecution 을 호출한 경우 비차단 방식으로 WdfDmaTransactionExecute를 호출할 수 있습니다.

DMA 트랜잭션에 대한 자세한 내용은 DMA 트랜잭션 시작을 참조하세요.

예제

다음 코드 예제는 PCIDRV 샘플 드라이버에서 가져옵니다. 이 예제에서는 DMA 전송을 만들고 초기화하고 실행을 시작합니다.

NTSTATUS
NICInitiateDmaTransfer(
    IN PFDO_DATA  FdoData,
    IN WDFREQUEST  Request
    )
{
    WDFDMATRANSACTION  dmaTransaction;
    NTSTATUS  status;
    BOOLEAN  bCreated = FALSE;
 
    do {
        status = WdfDmaTransactionCreate(
                                         FdoData->WdfDmaEnabler,
                                         WDF_NO_OBJECT_ATTRIBUTES,
                                         &dmaTransaction
                                         );
        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, 
                        "WdfDmaTransactionCreate failed %X\n", status);
            break;
        }

        bCreated = TRUE;

        status = WdfDmaTransactionInitializeUsingRequest( 
                                     dmaTransaction,
                                     Request,
                                     NICEvtProgramDmaFunction,
                                     WdfDmaDirectionWriteToDevice
                                     );
        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionInitalizeUsingRequest failed %X\n", 
                        status
                        );
            break;
        }

        status = WdfDmaTransactionExecute(
                                          dmaTransaction,
                                          dmaTransaction
                                          );

        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionExecute failed %X\n",
                        status
                        );
            break;
        }
    } while (FALSE);

    if(!NT_SUCCESS(status)){
 
        if(bCreated) {
            WdfObjectDelete(dmaTransaction);
        }
    }
    return status;
}

요구 사항

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

추가 정보

EvtProgramDma

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransaction만들기

WdfDmaTransactionDmaCompleted

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionInitialize

WdfDmaTransactionInitializeUsingRequest

WdfDmaTransactionSetImmediateExecution