Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Чтобы выполнить передачу DMA, которая использует подпрограммы в интерфейсе операций DMA версии 3, драйвер должен выполнить действия, описанные в следующем списке. Эти действия являются общими как для подчиненных устройств, так и для основных устройств шины. Версия 3 этого интерфейса доступна начиная с Windows 8. Дополнительные сведения о подпрограммах в этом интерфейсе см. в DMA_OPERATIONS.
Шаг 1. Получение объекта адаптера DMA
При подготовке к передаче DMA драйвер вызывает подпрограмму IoGetDmaAdapter для получения объекта адаптера DMA. Объект адаптера DMA — это программный объект, представляющий либо главное устройство шины, либо строку запроса на контроллер DMA системы. Этот объект содержит интерфейс операций DMA для шины, которая используется для передачи данных на устройство или с устройства. Кроме того, этот объект синхронизирует доступ драйвера к общим ресурсам, необходимым для выполнения передачи. Дополнительные сведения см. в разделе "Общие сведения о объектах адаптера".
Шаг 2. Получение описания необходимых ресурсов DMA
Драйвер вызывает подпрограмму GetDmaTransferInfo , чтобы получить описание ресурсов DMA, необходимых для передачи.
Входные параметры для этого вызова описывают буфер памяти, используемый для передачи, и направление (чтение или запись) передачи.
Требования к ресурсам, полученные из этого вызова, включают количество регистров отображения и размер списка scatter/gather, необходимого для описания буфера данных для передачи. При последующем вызове подпрограммы AllocateAdapterChannelEx (см. шаг 3), драйвер предоставляет счетчик регистров карты в качестве входного параметра.
Шаг 3. Запрос необходимых ресурсов DMA
Драйвер вызывает подпрограмму AllocateAdapterChannelEx , чтобы выделить ресурсы для назначения объекту адаптера DMA. Эти ресурсы включают канал DMA и регистры карт.
Вызов AllocateAdapterChannelEx может быть асинхронным или синхронным.
Если флаг DMA_SYNCHRONOUS_CALLBACK не задан, вызов является асинхронным. В этом случае параметр ExecutionRoutine указывает на подпрограмму выполнения, предоставляемую вызывающим, которая вызывается при наличии запрошенных ресурсов. В случае успешного выполнения асинхронный вызов AllocateAdapterChannelEx возвращает STATUS_SUCCESS без ожидания выполнения подпрограммы выполнения.
Если установлен флаг DMA_SYNCHRONOUS_CALLBACK, вызов AllocateAdapterChannelEx синхронен. В этом случае параметр ExecutionRoutine в вызове является необязательным, а Свойство AllocateAdapterChannelEx ведет себя следующим образом:
Если ExecutionRoutine не имеет значения NULL, а ресурсы DMA можно выделить немедленно, AllocateAdapterChannelEx вызывает подпрограмму выполнения в контексте вызывающего потока. После завершения выполнения рутины AllocateAdapterChannelEx возвращает STATUS_SUCCESS. Если ресурсы не сразу доступны, Функция AllocateAdapterChannelEx завершается ошибкой и возвращает код состояния ошибки STATUS_INSUFFICIENT_RESOURCES.
Если ExecutionRoutine имеет значение NULL, и AllocateAdapterChannelEx может немедленно выделить ресурсы DMA, Функция AllocateAdapterChannelEx возвращает STATUS_SUCCESS. Если все ресурсы недоступны сразу, вызов завершается ошибкой с кодом состояния ошибки STATUS_INSUFFICIENT_RESOURCES.
Для синхронных вызовов, возвращающих STATUS_SUCCESS, если параметр MapRegisterBase для AllocateAdapterChannelEx не имеет значения NULL, AllocateAdapterChannelEx записывает базовый адрес выделенных регистров карты в адрес, на который указывает параметр MapRegisterBase . Если Значение ExecutionRoutine равно NULL, MapRegisterBase должно быть не равно NULL. Если ExecutionRoutine не имеет значения NULL, параметр MapRegisterBase для AllocateAdapterChannelEx необязателен, а подпрограмма выполнения получает базовый адрес регистра карты в качестве входного параметра.
Для асинхронных вызовов AllocateAdapterChannelExExecutionRoutine должно быть ненулевой, а подпрограмма выполнения получает базовый адрес регистра карты в качестве входного параметра.
В последующих вызовах подпрограммы MapTransferEx (см. шаг 5), драйвер предоставляет базовый адрес карты в качестве входного параметра.
Если ExecutionRoutine не имеет значения NULL, подпрограмма выполнения возвращает значение состояния, указывающее на ликвидацию выделенных ресурсов. Для передачи данных системы DMA это возвращаемое значение должно быть KeepObject. Это значение сообщает операционной системе, что объект адаптера (и все выделенные ресурсы) используется и не должен быть освобожден. Если подпрограмма выполнения не указана, драйвер должен вместо этого вызвать подпрограмму FreeAdapterObject и указать KeepObject в качестве параметра AllocationOption .
Шаг 4. При необходимости отмените ожидающий запрос ресурса
После вызова AllocateAdapterChannelEx очередь адаптера DMA ожидает ресурсов DMA, и драйвер может при необходимости вызвать подпрограмму CancelAdapterChannel чтобы отменить ожидающий запрос ресурса.
Если CancelAdapterChannel возвращает значение TRUE, запрос ресурса успешно отменен. Если подпрограмма выполнения была предоставлена в вызове AllocateAdapterChannelEx , эта подпрограмма не выполняется.
Если CancelAdapterChannel возвращает ЗНАЧЕНИЕ FALSE, запрос ресурса не может быть отменен, так как он уже предоставлен. Если подпрограмма выполнения была предоставлена в вызове AllocateAdapterChannelEx , эта подпрограмма будет вызвана.
Шаг 5. Инициализация ресурсов DMA и запуск передачи DMA
Драйвер вызывает MapTransferEx для инициализации ресурсов DMA и запуска передачи DMA. Этот вызов может возникать в том же потоке драйвера, который вызывает AllocateAdapterChannelEx, или может произойти в подпрограмме выполнения, которую драйвер предоставляет в AllocateAdapterChannelEx. Если для передачи всего буфера данных DMA требуется несколько вызовов MapTransferEx, в подпрограмме завершения для предыдущего вызова MapTransferEx может возникнуть более поздний вызов MapTransferEx.
MapTransferEx поддерживает цепочки многомерных выражений в качестве входных параметров. Каждый MDL описывает область буфера DMA, который является смежным в виртуальной памяти. Когда MapTransferEx создает список рассеивания/сборки, он автоматически обрабатывает переходы из одной виртуально смежной буферной области к следующей без вмешательства драйвера. Дополнительные сведения см. в разделе "Использование подпрограммы MapTransferEx".
Для системной передачи DMA указатель на подпрограмму завершения DMA можно передать в MapTransferEx в необязательном параметре DmaCompletionRoutine. Эта подпрограмма запланирована для выполнения на уровне диспетчера в ответ на прерывание от контроллера системы DMA, указывающее на завершение передачи DMA.
Если MapTransferEx не удается сопоставить весь запрошенный размер передачи, он установит параметр вывода *Length на длину, сопоставленную, и возвращает STATUS_SUCCESS.
Шаг 6. При необходимости выполните операции, связанные с оборудованием
MapTransferEx возвращает STATUS_SUCCESS, чтобы указать, что передача DMA успешно инициирована. На некоторых платформах драйвер может предпринять некоторые дополнительные действия за пределами вызова MapTransferEx , чтобы начать передачу, но этот тип отложенного запуска не требуется для всех платформ. Драйверы не должны зависеть от таких задержек при принятии решений об использовании и освобождении выделенных ресурсов.
Подпрограммы в интерфейсе операций DMA поддерживают когерентность кэша для передачи DMA таким образом, который является прозрачным для драйверов, использующих эти подпрограммы. На платформах, которые не применяют когерентность кэша в оборудовании, MapTransferEx гарантирует, что кэши данных процессора сбрасываются перед передачей данных (память на устройство). Для передачи данных чтения (устройства в память) кэши недействительны во время вызова подпрограммы FlushAdapterBuffersEx (см. шаг 8), который следует каждому вызову MapTransferEx .
Шаг 7. Получение уведомления о завершении передачи DMA
После завершения передачи DMA драйвер уведомляется одним из следующих двух способов:
- Прерывание драйвера устройства для ведущего устройства шины
- Выполнение подпрограммы завершения, предоставленной драйвером, для подчиненного устройства, использующего системный контроллер DMA
Для передачи DMA в системе драйвер может предоставить функцию завершения MapTransferEx в качестве входного параметра.
Шаг 8. Очистка всех данных, остающихся в кэше
После завершения передачи DMA драйвер должен вызвать подпрограмму FlushAdapterBuffersEx , чтобы очистить все данные, остающиеся в кэше. Драйвер должен вызывать FlushAdapterBuffersEx после каждого вызова MapTransferEx .
Если вызов MapTransferEx сопоставляет только часть буфера данных DMA, драйвер должен снова вызвать MapTransferEx , чтобы сопоставить оставшиеся данные. Для сложной передачи может потребоваться несколько вызовов MapTransferEx . Для каждого дополнительного вызова MapTransferEx повторите шаги 5–8.
Шаг 9. Освобождение канала DMA и регистров карт
После успешного сопоставления всего буфера данных DMA и завершения окончательной передачи драйвер должен вызвать подпрограмму FreeAdapterChannel , чтобы освободить канал DMA и все ранее выделенные регистры карт.
Шаг 10. Выпуск объекта адаптера DMA
После завершения передачи DMA и освобождения всех ранее выделенных регистров карты драйвер вызывает подпрограмму PutDmaAdapter для освобождения объекта адаптера.