NTSTATUS NICInitiateDmaTransfer( IN PFDO_DATA FdoData, IN WDFREQUEST Request ) { WDFDMATRANSACTION dmaTransaction; NTSTATUS status; BOOLEAN bCreated = FALSE; do { // // Create a new DmaTransaction. // 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; // // Initialize the new DmaTransaction. // status = WdfDmaTransactionInitializeUsingRequest( dmaTransaction, Request, NICEvtProgramDmaFunction, WdfDmaDirectionWriteToDevice ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "WdfDmaTransactionInitalizeUsingRequest failed %X\n", status); break; } // // Execute this DmaTransaction. // 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; }
VOID AmccPciEvtIoDefault( __in WDFQUEUE Queue, __in WDFREQUEST Request ) /*++ Routine Description: Start the IRP on the device. This driver allows only one I/O to be active on the adapter at any one time. If multiple I/Os are sent to the driver, they will be queued and completed as they complete on the adapter (one IRP per interrupt). Arguments: Queue - Default queue handle Request - Handle to the write request Parameters - Contains current stack location information from the IRP Return Value: None --*/ { PAMCC_DEVICE_EXTENSION devExt; REQUEST_CONTEXT * transfer; NTSTATUS status; size_t length; WDF_DMA_DIRECTION direction; WDFDMATRANSACTION dmaTransaction; WDF_REQUEST_PARAMETERS params; WDF_REQUEST_PARAMETERS_INIT(¶ms); WdfRequestGetParameters( Request, ¶ms ); // // Get the device extension. // devExt = AmccPciGetDevExt(WdfIoQueueGetDevice( Queue )); // // Validate and gather parameters. // switch (params.Type) { case WdfRequestTypeRead: length = params.Parameters.Read.Length; direction = WdfDmaDirectionReadFromDevice; break; case WdfRequestTypeWrite: length = params.Parameters.Write.Length; direction = WdfDmaDirectionWriteToDevice; break; default: TraceEvents(TRACE_LEVEL_WARNING, AMCC_TRACE_IO, "Request type not Read or Write\n"); WdfRequestComplete(Request, STATUS_INVALID_PARAMETER); return; } TraceEvents(TRACE_LEVEL_INFORMATION, AMCC_TRACE_IO, "Request %p: %s %d bytes", Request, (direction)?"Write":"Read", (ULONG)length); // // The length must be non-zero. // if (length == 0) { TraceEvents(TRACE_LEVEL_WARNING, AMCC_TRACE_IO, "Zero transfer length input to read/write"); WdfRequestComplete(Request, STATUS_INVALID_PARAMETER); return; } transfer = GetRequestContext(Request); // // Create new DmaRequst to conduct this DMA transaction. // status = WdfDmaTransactionCreate( devExt->DmaEnabler, WDF_NO_OBJECT_ATTRIBUTES, &dmaTransaction ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, AMCC_TRACE_IO, "WdfDmaRequestCreate failed: %X", status); WdfRequestComplete(Request, status); return; } // // Create new DmaTransaction. // status = WdfDmaTransactionInitializeUsingRequest( dmaTransaction, Request, AmccPciProgramDma, direction ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, AMCC_TRACE_IO, "WdfDmaRequestInitializeWithRequest failed: %X", status); WdfObjectDelete(dmaTransaction); WdfRequestComplete(Request, status); return; } // // Fill transfer context structure // transfer->Request = Request; transfer->DmaTransaction = dmaTransaction; // // Save the current Request as the "in-progress" request. // devExt->CurrentRequest = Request; // // Execute this dmaTransaction transaction. // status = WdfDmaTransactionExecute( dmaTransaction, WDF_NO_CONTEXT); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, AMCC_TRACE_IO, "WdfDmaTransactionExecute failed: %X", status); WdfObjectDelete(dmaTransaction); WdfRequestComplete(Request, status); return; } return; }