Поделиться через


Функция WdfDmaTransactionDmaCompleted (wdfdmatransaction.h)

[Применимо только к KMDF]

Метод WdfDmaTransactionDmaCompleted уведомляет платформу о завершении операции передачи DMA устройства.

Синтаксис

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

Параметры

[in] DmaTransaction

Дескриптор объекта транзакции DMA, полученный драйвером из предыдущего вызова WdfDmaTransactionCreate.

[out] Status

Указатель на расположение, которое получает состояние передачи DMA. Дополнительные сведения см. в следующем разделе "Примечания".

Возвращаемое значение

WdfDmaTransactionDmaCompleted возвращает false и состояние получает STATUS_MORE_PROCESSING_REQUIRED, если для завершения транзакции DMA требуются дополнительные передачи. Метод возвращает TRUE, если дополнительная передача не требуется.

Ошибка возникает, если драйвер предоставляет недопустимый дескриптор объекта.

Замечания

Драйверы на основе платформы должны вызывать один из следующих методов при завершении передачи DMA:

Как правило, драйверы вызывают эти методы из Функция обратного вызова событий EvtInterruptDpc после прерывания устройства указывает на завершение операции передачи DMA. Драйвер для устройства DMA в системном режиме может вызывать эти методы из функции обратного вызова событий EvtDmaTransactionDmaTransferComplete.

Платформа может разделить транзакцию DMA на несколько операций передачи DMA. Поэтому драйвер должен проверить возвращаемое значение метода, чтобы определить, требуются ли дополнительные передачи.

Если метод возвращает FALSE, то для завершения транзакции требуется расположение STATUS_MORE_PROCESSING_REQUIRED состояния состояния и дополнительные операции DMA. Как правило, функция обратного вызова событий evtInterruptDpc не делает ничего другого. Вместо этого платформа вызывает функцию обратного вызова драйвера EvtProgramDma функцию обратного вызова событий, поэтому функция обратного вызова может начать следующую передачу.

Если метод возвращает TRUE, для указанной транзакции больше не будет выполняться передача. В этом случае значение состояния STATUS_SUCCESS означает, что платформа не столкнулась с ошибками, и транзакция DMA завершена.

Если драйвер вызывает WdfDmaTransactionStopSystemTransfer перед вызовом WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompleted возвращает true и значение statusSTATUS_CANCELLED.

Для транзакций, которые были заданы для одной передачи, WdfDmaTransactionDmaCompleted возвращает значение TRUE и значение состоянияSTATUS_WDF_TOO_MANY_TRANSFERS, если оборудование не сможет завершить транзакцию в одной передаче, даже если инициализация завершилась успешно. Это может произойти для оборудования, которое сообщает остаточные передачи для каждой операции DMA. Например, драйвер программирует устройство для записи 64 КБ, но устройство записывает только 60 КБ. В этом случае драйвер может повторить операцию DMA или сбросить устройство.

Любое другое значение для состояния означает, что платформа обнаружила ошибку и транзакцию DMA, возможно, не была завершена.

Если WdfDmaTransactionDmaCompleted возвращает TRUE, драйвер обычно выполняет следующее:

  • Вызывает WdfObjectDelete или WdfDmaTransactionRelease для удаления или повторного использования объекта транзакции соответственно.
  • Завершает запрос ввода-вывода, если транзакция DMA связана с запросом ввода-вывода. (Драйверы выполняют запросы путем вызова WdfRequestComplete или WdfRequestCompleteWithInformation.)
Дополнительные сведения о завершении передачи DMA см. в разделе Завершение передачи DMA.

Примеры

В следующем примере кода используется пример драйвера AMCC5933. В этом примере показана функция обратного вызова EvtInterruptDpc. В примере сообщается, что передача DMA завершена. Если платформа указывает, что эта передача является последней для транзакции DMA, код удаляет объект транзакции DMA и завершает связанный запрос ввода-вывода.

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 (include 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