Share via


DMA 트랜잭션 시작

[KMDF에만 적용]

드라이버가 DMA 트랜잭션을 만들고 초기화한 후 드라이버는 WdfDmaTransactionExecute 메서드를 호출하여 트랜잭션을 시작할 수 있습니다. 이 메서드는 트랜잭션과 연결된 첫 번째 DMA 전송 에 대한 분산/수집 목록을 작성합니다. 다음으로, 메서드는 드라이버가 트랜잭션에 등록한 EvtProgramDma 콜백 함수를 호출합니다. 콜백 함수는 DMA 하드웨어를 프로그래밍 하여 전송을 시작합니다.

드라이버가 WdfDmaTransactionExecute를 호출하기 전에 드라이버가 트랜잭션과 연결된 각 DMA 전송을 완료할 때 나중에 검색할 수 있도록 DMA 트랜잭션 핸들을 저장해야 합니다. 트랜잭션 핸들을 저장하는 좋은 위치는 프레임워크 개체(일반적으로 디바이스의 프레임워크 디바이스 개체)의 컨텍스트 메모리에 있습니다. 개체 컨텍스트 메모리 사용에 대한 자세한 내용은 Framework 개체 컨텍스트 공간을 참조하세요.

PLX9x5x 샘플의 다음 코드 예제에서는 DMA 트랜잭션을 초기화한 다음 실행하는 방법을 보여 있습니다. 이 코드는 Read.c 파일에 나타납니다.

VOID PLxEvtIoRead(
    IN WDFQUEUE         Queue,
    IN WDFREQUEST       Request,
    IN size_t           Length
    )
{
    NTSTATUS            status = STATUS_UNSUCCESSFUL;
    PDEVICE_EXTENSION   devExt;
    // Get the DevExt from the queue handle
    devExt = PLxGetDeviceContext(WdfIoQueueGetDevice(Queue));
    do {
        // Validate the Length parameter.
        if (Length > PCI9656_SRAM_SIZE)  {
            status = STATUS_INVALID_BUFFER_SIZE;
            break;
        }
        // Initialize the DmaTransaction.
        status = 
           WdfDmaTransactionInitializeUsingRequest(
                 devExt->ReadDmaTransaction,
                 Request, 
                 PLxEvtProgramReadDma, 
                 WdfDmaDirectionReadFromDevice 
           );
        if(!NT_SUCCESS(status)) {
            . . . //Error-handling code omitted
            break; 
        }
        // Execute this DmaTransaction.
        status = WdfDmaTransactionExecute( devExt->ReadDmaTransaction, 
                                           WDF_NO_CONTEXT);
        if(!NT_SUCCESS(status)) {
            . . . //Error-handling code omitted
            break; 
        }
        // Indicate that the DMA transaction started successfully.
        // The DPC routine will complete the request when the DMA
        // transaction is complete.
        status = STATUS_SUCCESS;
    } while (0);
    // If there are errors, clean up and complete the request.
    if (!NT_SUCCESS(status )) {
        WdfDmaTransactionRelease(devExt->ReadDmaTransaction); 
        WdfRequestComplete(Request, status);
    }
    return;
}