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


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

[Относится только к KMDF]

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

Синтаксис

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

Параметры

[in] DmaTransaction

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

[out] Status

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

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

WdfDmaTransactionDmaCompleted возвращает значение FALSE , а status получает 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 , а значение СостоянияSTATUS_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 (включая 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