Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье описываются возможности цепочек MDL в стеке драйверов USB и то, как клиентский драйвер может отправлять буфер передачи в виде цепочки структур MDL.
Большинству контроллеров USB-узла требуется, чтобы буфер передачи был практически смежным. Практически непрерывно означает, что буфер может начинаться и заканчиваться в любом месте страницы, но остальная часть буфера должна начинаться и заканчиваться на границе страницы. Многие драйверы USB-клиента могут соответствовать этим требованиям. Однако для некоторых клиентских драйверов, особенно тех, которые должны добавлять или удалять дополнительные данные в буфер или из буфера, выделение практически непрерывной памяти для буфера передачи не предпочтительнее.
Например, рассмотрим сетевой стек из трех драйверов, драйвер сетевого протокола, промежуточный драйвер и минипорт-драйвер. Драйвер протокола инициирует передачу и отправляет пакет следующему драйверу в стеке: промежуточный драйвер. Промежуточный драйвер хочет добавить в пакет пользовательский заголовок (содержащийся в отдельном блоке памяти). Промежуточный драйвер отправляет этот заголовок и полученный пакет в следующий драйвер в стеке: минипорт-драйвер. Минипорт драйвер взаимодействует со стеком USB-драйверов, и поэтому должен подготовить виртуально непрерывный буфер передачи. Чтобы создать такой буфер, драйвер минипорта выделяет большой буфер, добавляет кастомизированный заголовок, а затем копирует полезные данные. Так как полезные данные обычно большие, копирование всей полезных данных может оказать значительное влияние на производительность.
Драйвер клиента может преодолеть это влияние на производительность, отправив буфер передачи в виде цепочки списка дескрипторов памяти (MDLs). Новый стек USB-драйверов в Windows 8 может принимать цепочки MDL (см. MDL) из драйвера клиента. Предоставляя связанную MDL, драйвер клиента может ссылаться на несмежные страницы в памяти вместо выполнения дополнительных операций копирования. Возможность удаляет ограничения на количество, размер и выравнивание буферов, что позволяет сегментировать буфер передачи в физической памяти.
Чтобы использовать цепочки MDL, драйвер клиента должен определить, поддерживает ли базовый стек USB-драйверов, загруженный Windows, эту возможность, а затем создать цепочку MDL в правильном порядке.
Перед началом работы
Поддержка возможности сцепленного MDL предоставляется только для массовых, изохронных и прерываемых передач. Прежде чем запрашивать возможность MDL в цепочке, убедитесь, что драйвер клиента имеет USBD-дескриптор регистрации драйвера в стеке USB-драйверов. Чтобы создать дескриптор USBD, вызовите USBD_CreateHandle. Как правило, драйвер клиента создает дескриптор USBD в своей подпрограмме AddDevice .
Вы можете запросить возможность использования цепочки MDL в обработчике IRP_MN_START_DEVICE драйвера клиента или в любой момент позже. Драйвер клиента не должен запрашивать эту возможность в подпрограмме AddDevice .
Инструкции
Вызовите подпрограмму USBD_QueryUsbCapability, чтобы выяснить, поддерживает ли стек драйверов USB возможность цепочки MDL. Чтобы запросить эту возможность, укажите UsbCapabilityChainedMdls в качестве GUID. Задайте для параметра OutputBuffer значение NULL и OutputBufferSize значение 0.
Проверьте значение NTSTATUS, возвращаемое USBD_QueryUsbCapability , и оцените результат. Если подпрограмма успешно завершена, поддерживается возможность сетевых многомерных выражений. Любое другое значение указывает, что возможность не поддерживается.
Создайте цепочку многомерных выражений. Каждый MDL имеет указатель next , указывающий на другой MDL.
Драйвер может создать цепочку MDL, вручную задав указатель Next.
В предыдущем примере драйвер протокола отправляет пакет в виде MDL. Промежуточный драйвер может создать другой MDL, который ссылается на блок памяти с данными заголовка. Чтобы создать цепочку, промежуточный драйвер может указать указатель заголовка MDL следующего указателя на MDL, полученный от драйвера протокола. Затем промежуточный драйвер может перенаправить цепочку двух многомерных выражений на минипорт-драйвер, который предоставляет ссылку на цепочки MDL в URB для запроса и отправляет запрос в стек USB-драйверов. Дополнительные сведения см. в разделе Использование MDLs.
При создании URB для запроса ввода-вывода, использующего цепочки многомерных выражений, задайте элемент TransferBufferMDL связанной структуры URB (например, _URB_BULK_OR_INTERRUPT_TRANSFER или _URB_ISOCH_TRANSFER) первым MDL в цепочке и задайте для TransferBufferLength общее количество байтов для передачи. Данные могут охватывать несколько записей MDL в цепочке MDL.
В Windows 8 добавлены два новых типа функций URB, которые позволяют драйверу клиента использовать цепочки многомерных выражений для передачи данных. Если вы хотите использовать эту возможность, убедитесь, что для элемента функции заголовка URB задано одно из следующих функций URB:
- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER_USING_CHAINED_MDL
- URB_FUNCTION_ISOCH_TRANSFER_USING_CHAINED_MDL
Сведения об этих функциях URB см. в _URB_HEADER.
Замечания
Пример кода, который запрашивает базовый стек USB-драйверов, чтобы определить, может ли стек драйверов принимать связанные MDL, см. USBD_QueryUsbCapability.