Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Как описано в разделе Использование Bus-Master DMA, некоторые драйверы для устройств DMA на основе шины используют общий буфер DMA исключительно, а некоторые используют общую буферную DMA в сочетании с DMA на основе пакетов.
Используйте общий буфер DMA экономически. Настройка общего буфера может связать некоторые (или все, в зависимости от размера запрошенного буфера) регистров карты, связанных с объектом адаптера, который представляет адаптер шины master.
Настройка общих буферных областей экономично, например, с помощью блоков PAGE_SIZE или одного выделения, оставляет больше регистров карты свободными для операций DMA на основе пакетов. Он также оставляет больше системной памяти бесплатно для других целей, что обеспечивает лучшую общую производительность драйвера и системы.
Чтобы настроить общий буфер для ведущего устройства шины DMA, драйвер устройства DMA шины должен вызвать AllocateCommonBuffer с указателем объекта адаптера, возвращенным IoGetDmaAdapter. Как правило, драйвер выполняет этот вызов из подпрограммы DispatchPnP для запросов IRP_MN_START_DEVICE. Драйвер должен выделять общий буфер только в том случае, если он будет многократно использовать этот буфер для операций DMA, пока драйвер остается загруженным. На следующей диаграмме показан такой вызов AllocateCommonBuffer.
Запрошенный размер буфера, показанный на предыдущей схеме в формате LengthForBuffer, определяет, сколько регистров карт необходимо использовать для предоставления виртуального логического сопоставления для общего буфера. Используйте макрос BYTES_TO_PAGES для определения максимального количества необходимых страниц (BYTES_TO_PAGES (LengthForBuffer)). Это значение не может быть больше NumberOfMapRegisters, возвращаемых IoGetDmaAdapter.
Кроме того, вызывающий объект должен указать следующее:
Логическое значение, указывающее, следует ли включить кэширование
Примечание Это значение игнорируется. Операционная система определяет, следует ли включить кэшированную память в общем буфере, который должен быть выделен. Это решение основано на архитектуре процессора и шине устройства.
На компьютерах с процессорами на базе x86, x64 и Itanium кэшированная память включена.
На компьютерах с процессорами Arm или Arm 64 операционная система не включает кэшированную память для всех устройств. Система использует метод ACPI_CCA для каждого устройства, чтобы определить, является ли устройство кэшно-согласованным.
Указатель на определяемую драйвером переменную, содержащую базовый логический адрес устройства буфера (BufferLogicalAddress на предыдущей схеме) при возврате из AllocateCommonBuffer
Если вызов выполнен успешно, AllocateCommonBuffer возвращает базовый виртуальный адрес, доступный драйверу для буфера (BufferVirtualAddress на предыдущей схеме), который драйвер должен сохранить в своем расширении устройства, расширении контроллера или другой области хранилища с доступом к драйверу (непагированный пул, выделенный драйвером).
AllocateCommonBuffer возвращает NULL, если он не может выделить память для буфера. Если возвращенный базовый виртуальный адрес NULL, драйвер либо должен использовать исключительно поддержку системы DMA на основе пакетов, либо драйвер должен отклонить запрос IRP_MN_START_DEVICE, возвращая STATUS_INSUFFICIENT_RESOURCES.
В противном случае драйвер может использовать выделенный общий буфер в качестве области хранилища, доступной для драйверов и адаптеров, для передачи DMA.
Когда диспетчер PnP отправляет IRP, который останавливает или удаляет устройство, драйвер должен вызвать FreeCommonBuffer, чтобы освободить каждый общий буфер, который он выделил.