Использование точечной и сборной DMA

Драйверы, выполняющие системную или главную шину, DMA на основе пакетов могут использовать подпрограммы поддержки, предназначенные специально для точечной или сборной DMA. Вместо вызова последовательности подпрограмм, описанных в разделе Using Packet-Based System DMA иPacket-Based Bus-Master DMA, драйвер может использовать GetScatterGatherList и PutScatterGatherList.

Устройству не требуется встроенная поддержка scatter/gather, чтобы его драйвер мог использовать эти подпрограммы.

Драйверы, использующие пакетную DMA, вызывают следующую последовательность вспомогательных процедур для операций scatter/gather:

  1. MmGetMdlVirtualAddress для получения индекса в MDL, необходимого в качестве параметра в вызове GetScatterGatherList

  2. GetScatterGatherList, когда драйвер готов программировать свое устройство для DMA и нуждается в системном контроллере DMA или адаптере шины с главным устройством.

    GetScatterGatherList выделяет системный контроллер DMA или главный адаптер шины, определяет, сколько регистров карт требуется, и распределяет их, заполняет список scatter/gather и вызывает подпрограмму AdapterListControl драйвера, когда доступны контроллер или адаптер DMA, а также регистры карт.

  3. PutScatterGatherList сразу после передачи всех запрошенных данных или если драйвер завершает IRP с ошибкой из-за ошибки ввода-вывода устройства

    PutScatterGatherList очищает буферы адаптера, освобождает регистры отображения и освобождает список scatter/gather. Драйвер должен вызвать PutScatterGatherList , прежде чем он сможет получить доступ к данным в буфере.

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

Подпрограмма GetScatterGatherList включает вызовы в AllocateAdapterChannel и MapTransfer, поэтому драйверу не нужно выполнять эти вызовы. Подпрограмма принимает следующие параметры:

  • Указатель на структуру DMA_ADAPTER , возвращаемую IoGetDmaAdapter

  • Указатель на целевой объект устройства для операции DMA

  • Указатель на MDL, описывающий буфер в Irp-MdlAddress>

  • Указатель на текущий виртуальный адрес в буфере, описанном Mdl

  • Количество байтов для сопоставления

  • Указатель на подпрограмму AdapterListControl , которая выполняет передачу

  • Указатель на определяемую драйвером область контекста, передаваемую в подпрограмму AdapterListControl

  • Логическое значение: TRUE для передачи на устройство; FALSE в противном случае

Определив необходимое количество регистров карты, распределив канал адаптера и регистры карты, заполнив точечный/сборный список и подготовившись к передаче, GetScatterGatherList вызывает подпрограмму AdapterListControl, предоставляемую драйвером. Подпрограмма AdapterListControl выполняется в произвольном контексте потока в IRQL = DISPATCH_LEVEL.

Процедура AdapterListControl, предоставляемая драйвером в вызовах GetScatterGatherList, отличается от процедуры AdapterControl, передаваемой в AllocateAdapterChannel, в следующих важных аспектах:

  • Подпрограмма AdapterListControl не имеет возвращаемого значения, а подпрограмма AdapterControl возвращает IO_ALLOCATION_ACTION.

  • Вместо указателя на MapRegisterBase для регистров карты, выделенных системой, третий параметр подпрограммы AdapterListControl указывает на структуру SCATTER_GATHER_LIST , с помощью которой драйвер может выполнять DMA.

  • Подпрограмма AdapterListControl выполняет подмножество задач, необходимых в подпрограмме AdapterControl .

    Подпрограмма AdapterListControl не вызывает AllocateAdapterChannel или MapTransfer. Ее единственными обязанностями являются сохранение указателя на scatter/gather list, настройка устройства и использование scatter/gather list для выполнения DMA.

Структура списка scatter/gather включает массив SCATTER_GATHER_ELEMENT и количество элементов в массиве. Каждый элемент массива предоставляет длину и начальный физический адрес физически смежного scatter/gather региона. Драйвер использует длину и адрес при передаче данных.

Драйвер может использовать GetScatterGatherList независимо от того, поддерживает ли его устройство точечную или сборную DMA. Для устройства, которое не поддерживает scatter/gather DMA, список scatter/gather будет содержать только один элемент.

Использование механизмов разброса/сбора может улучшить производительность по сравнению с вызовом AllocateAdapterChannel (как описано ранее в Using Packet-Based System DMA и Using Packet-Based Bus-Master DMA). В отличие от вызовов AllocateAdapterChannel, несколько вызовов GetScatterGatherList могут быть поставлены в очередь для объекта устройства в любой момент времени. Драйвер может снова вызвать GetScatterGatherList для другой операции DMA в одном объекте драйвера до завершения выполнения подпрограммы AdapterListControl .

При возвращении из подпрограммы AdapterListControl , предоставленной драйвером, GetScatterGatherList сохраняет регистры карты, но освобождает структуру адаптера DMA.

Если драйвер выполнил текущий запрос на передачу IRP или должен завершить IRP с ошибкой из-за ошибки ввода-вывода устройства или шины, он должен вызвать PutScatterGatherList прежде чем он сможет получить доступ к передаваемым данным в буфере. PutScatterGatherList очищает буферы адаптера и освобождает регистры карты и список точечной и сборной.