Использование Packet-Based System DMA

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

  • KeFlushIoBuffers за некоторое время до попытки выделить системный контроллер DMA (дополнительные сведения см. в разделе Поддержание когерентности кэша)

  • AllocateAdapterChannel, когда драйвер готов программировать своё устройство для работы с DMA и ему необходим системный контроллер DMA

    AllocateAdapterChannel, в свою очередь, вызывает подпрограмму AdapterControl драйвера.

  • MmGetMdlVirtualAddress для получения индекса в MDL, который требуется в качестве параметра в первоначальном вызове функции MapTransfer

  • MapTransfer для программирования системного контроллера DMA для операции передачи

    Драйверу может потребоваться вызвать MapTransfer более одного раза для передачи всех запрошенных данных, как описано в Подразделение запросов на передачу.

  • FlushAdapterBuffers сразу после каждой операции передачи DMA в/из подчиненного устройства

    Если драйвер должен вызывать MapTransfer более одного раза для передачи всех запрошенных данных, он должен вызывать FlushAdapterBuffers столько раз, сколько он вызывает MapTransfer.

  • FreeAdapterChannel либо сразу после передачи всех запрошенных данных, либо если драйвер отклоняет IRP из-за ошибки ввода-вывода устройства

Указатель объекта адаптера, возвращаемый IoGetDmaAdapter, является обязательным параметром для каждой из этих процедур, за исключением KeFlushIoBuffers и MmGetMdlVirtualAddress, для которых требуется указатель на MDL, который передан в Irp->MdlAddress.

Отдельные драйверы вызывают эту последовательность подпрограмм поддержки в разных точках в зависимости от того, как каждый драйвер реализуется для обслуживания своего устройства. Например, один драйвер может сделать вызов StartIo к AllocateAdapterChannel, другой драйвер может сделать этот вызов из рутины, которая удаляет IRP из созданной драйвером взаимоблокируемой очереди, а еще один драйвер может сделать этот вызов, когда его подчиненное устройство DMA указывает, что оно готово передавать данные.