WdfDmaTransactionInitialize 함수(wdfdmatransaction.h)

[KMDF에만 적용]

WdfDmaTransactionInitialize 메서드는 지정된 DMA 트랜잭션을 초기화합니다.

구문

NTSTATUS WdfDmaTransactionInitialize(
  [in] WDFDMATRANSACTION   DmaTransaction,
  [in] PFN_WDF_PROGRAM_DMA EvtProgramDmaFunction,
  [in] WDF_DMA_DIRECTION   DmaDirection,
  [in] PMDL                Mdl,
  [in] PVOID               VirtualAddress,
  [in] size_t              Length
);

매개 변수

[in] DmaTransaction

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

[in] EvtProgramDmaFunction

드라이버의 EvtProgramDma 이벤트 콜백 함수에 대한 포인터입니다.

[in] DmaDirection

WDF_DMA_DIRECTION 형식의 값입니다.

[in] Mdl

DMA 트랜잭션에 사용할 버퍼를 설명하는 MDL(메모리 설명자 목록)에 대한 포인터입니다. 설명에서 자세한 내용을 참조 하세요.

[in] VirtualAddress

DMA 트랜잭션에 사용할 버퍼의 가상 주소입니다.

[in] Length

전송할 바이트 수입니다.

반환 값

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

반환 코드 설명
STATUS_INSUFFICIENT_RESOURCES
분산/수집 목록을 할당할 수 없습니다.
STATUS_INVALID_PARAMETER
잘못된 매개 변수가 감지되었습니다.
STATUS_WDF_TOO_FRAGMENTED
트랜잭션을 처리하는 데 필요한 분산/수집 요소 수가 드라이버가 WdfDmaEnablerSetMaximumScatterGatherElements 에 대해 호출한 값보다 큽니다.

단일 전송에 대해 설정된 트랜잭션의 경우 이 문제를 해결하는 한 가지 방법은 데이터를 물리적으로 연속된 버퍼에 복사한 다음 해당 버퍼를 사용하여 트랜잭션을 초기화하는 것입니다. 예를 들어 MmAllocateContiguousMemory를 호출하고 원래 버퍼를 새 버퍼에 복사한 다음 WdfDmaTransactionInitialize 를 다시 호출합니다.

STATUS_WDF_NOT_ENOUGH_MAP_REGISTERS
이 반환 값은 단일 전송에 대해 설정된 트랜잭션에만 적용됩니다.

트랜잭션을 매핑하는 데 필요한 맵 레지스터 수가 DMA 어댑터가 예약한 수보다 큽니다.

이를 해결하기 위해 드라이버는 MDL 체인을 단일 MDL로 결합하여 필요한 맵 레지스터 수를 줄일 수 있습니다.

패킷 및 시스템 DMA를 사용하는 드라이버는 WdfDmaTransactionAllocateResources 를 호출하여 디바이스에 할당된 총 맵 레지스터 수를 예약할 수 있습니다. 드라이버가 총 맵 레지스터 8개 중 4개만 예약했지만 DMA 전송에 6이 필요하다고 가정합니다. 이 경우 WdfDmaTransactionInitialize가 실패합니다. 문제를 해결하려면 WdfDmaTransactionFreeResources를 호출한 다음 WdfDmaTransactionInitialize를 다시 호출합니다.

분산/수집 DMA를 사용하는 드라이버는 지도 레지스터를 예약할 수 없습니다.

STATUS_WDF_TOO_MANY_TRANSFERS
이 반환 값은 단일 전송에 대해 설정된 트랜잭션에만 적용됩니다.

트랜잭션의 총 길이가 디바이스의 최대 전송 크기를 초과합니다.

 

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

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

설명

WdfDmaTransactionInitialize 메서드는 트랜잭션의 분산/수집 목록 할당과 같은 초기화 작업을 수행하여 실행을 위해 DMA 작업을 준비합니다. 드라이버가 WdfDmaTransactionInitialize를 호출한 후 드라이버는 WdfDmaTransactionExecute 를 호출하여 트랜잭션 실행을 시작해야 합니다.

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

프레임워크 요청 개체에 포함된 정보를 기반으로 하는 DMA 트랜잭션을 만드는 경우 드라이버는 WdfDmaTransactionInitializeUsingRequest를 호출해야 합니다. 요청 개체를 기반으로 하지 않는 DMA 트랜잭션을 만드는 경우 WdfDmaTransactionInitialize 또는 WdfDmaTransactionInitializeUsingOffset을 사용합니다.

드라이버는 이 메서드의 Mdl 매개 변수에서 MDL 체인을 지정할 수 있습니다. MDL 체인은 MDL 구조체의 Next 멤버를 사용하여 드라이버가 함께 연결된 MDL 구조의 시퀀스입니다. 1.11 이전 프레임워크 버전에서는 분산/수집 DMA 전송만 MDL 체인을 사용할 수 있습니다. 버전 1.11부터 드라이버가 DMA 버전 3을 사용하는 경우 단일 패킷 전송은 연결된 MDL을 사용할 수도 있습니다.

드라이버가 지정하는 버퍼가 WdfDmaEnablerCreate 또는 WdfDmaTransactionSetMaximumLength를 호출할 때 드라이버가 지정한 최대 전송 길이보다 큰 경우 프레임워크는 트랜잭션을 여러 전송으로 나눕 니다.

DMA 트랜잭션에 대한 자세한 내용은 DMA 트랜잭션 만들기 및 초기화를 참조하세요.

예제

다음 코드 예제는 PLX9x5x 샘플 드라이버에서 가져옵니다. 먼저 WDF_OBJECT_ATTRIBUTES 구조를 초기 화하고 DMA 트랜잭션 개체를 만듭니다. 다음으로 수신된 I/O 요청의 입력 버퍼를 나타내는 MDL을 가져오고 버퍼의 가상 주소와 길이를 가져옵니다. 마지막으로, 이 예제에서는 WdfDmaTransactionInitialize 를 호출하여 트랜잭션을 초기화합니다.

WDF_OBJECT_ATTRIBUTES  attributes;
PMDL  mdl;
PVOID  virtualAddress;
ULONG  length;
NTSTATUS  status;

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
                                        &attributes,
                                        TRANSACTION_CONTEXT
                                        );

status = WdfDmaTransactionCreate(
                                 devExt->DmaEnabler,
                                 &attributes,
                                 &dmaTransaction
                                 );
if(!NT_SUCCESS(status)) {
    goto CleanUp;
}

status = WdfRequestRetrieveInputWdmMdl(
                                       Request,
                                       &mdl
                                       );
if (!NT_SUCCESS(status)) {
    goto CleanUp;
}

virtualAddress = MmGetMdlVirtualAddress(mdl);
length = MmGetMdlByteCount(mdl);

status = WdfDmaTransactionInitialize(
                                     dmaTransaction,
                                     PLxEvtProgramWriteDma,
                                     WdfDmaDirectionWriteToDevice,
                                     mdl,
                                     virtualAddress,
                                     length
                                     );
if(!NT_SUCCESS(status)) {
    goto CleanUp;
}

요구 사항

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

추가 정보

EvtProgramDma

MmGetMdlByteCount

MmGetMdlVirtualAddress

WDF_DMA_DIRECTION

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransaction만들기

WdfDmaTransactionExecute

WdfDmaTransactionInitializeUsingRequest