Реализация повторного балансировки PnP для аудиодрайверов PortCls

Перебалансирование PnP используется в некоторых сценариях PCI, где необходимо перераспределить ресурсы памяти.

Перебалансировать можно в двух main сценариях:

  1. Горячее подключение PCI. Пользователь подключает устройство, и у шины PCI недостаточно ресурсов для загрузки драйвера для нового устройства. Некоторые примеры устройств, которые относятся к этой категории, включают Thunderbolt, USB-C и хранилище NVME. В этом сценарии ресурсы памяти необходимо переупорядочить и консолидировать (повторно сбалансировать) для поддержки добавляемых дополнительных устройств.
  2. BAR с возможностью изменения размера PCI. После успешной загрузки драйвера для устройства в памяти он запрашивает дополнительные ресурсы. Некоторые примеры устройств включают высокопроизводительные графические карты и запоминающий устройства. Дополнительные сведения о поддержке видеодрайвов см. в статье Поддержка bar с возможностью изменения размера. В этом разделе описывается, что необходимо сделать для реализации перераспределения PnP для аудиодрайверов PortCls.

Перебалансирование PnP доступно в Windows 10 версии 1511 и более поздних версиях Windows.

Требования к перераспределению

Аудиодрайверы Portcls могут поддерживать повторную балансировку при выполнении следующих условий:

  • Минипорт должен зарегистрировать интерфейс IAdapterPnpManagement с помощью Portcls.
  • Минипорт должен возвращать pcRebalanceRemoveSubdevices из IAdapterPnpManagement::GetSupportedRebalanceType.
  • Топология и WaveRT — это два поддерживаемых типа портов.

Для поддержки перераспределения при наличии активных аудиопотоков аудиодрайверы portcls должны соответствовать одному из этих двух дополнительных требований.

ИЛИ

Поведение аудиопотока при изменении балансировки

Если перебалансировка активируется при наличии активных аудиопотоков и драйвер поддерживает перебалансировку активных аудиопотоков, то все активные звуковые потоки будут остановлены и не будут перезапущены автоматически.

Интерфейс COM IPortClsPnp

IPortClsPnp — это интерфейс управления PnP, который драйвер класса портов (PortCls) предоставляет адаптеру.

IPortClsPnp наследует от IUnknown , а также поддерживает следующие методы:

Аудиодрайверы минипорта могут зарегистрировать интерфейс уведомлений PNP с помощью экспортов Portcls или через интерфейс COM IPortClsPnp IPortClsPnp, предоставляемый в объекте порта WaveRT. Используйте IPortClsPnp::RegisterAdapterPnpManagement и IPortClsPnp::UnregisterAdapterPnpManagement для регистрации и отмены регистрации.

Обязательные DDIs экспорта PortCls

IAdapterPnpManagement — это интерфейс, который адаптеры должны реализовать и зарегистрировать, если они хотят получать сообщения управления PnP. Зарегистрируйте этот интерфейс с помощью PortCls с помощью PcRegisterAdapterPnpManagement. Отмените регистрацию этого интерфейса с помощью PortCls с помощью PcUnregisterAdapterPnpManagement.

Обязательные DDIs драйвера

Для поддержки перебалансировки необходимо реализовать следующие DDIs IAdapterPnpManagement .

  • IAdapterPnpManagement::GetSupportedRebalanceType вызывается Portcls при обработке QueryStop. Мини-порт возвращает поддерживаемый тип перераспределения, как определено в перечислении PC_REBALANCE_TYPE .

    Примечание Portcls получает глобальную блокировку устройства перед выполнением этого вызова, поэтому мини-порт должен выполнить этот вызов как можно быстрее.

  • IAdapterPnpManagement::P npQueryStop вызывается portcls непосредственно перед выполнением запроса QueryStop IRP. Это просто уведомление, и вызов не возвращает значение.

    Примечание Portcls получает глобальную блокировку устройства перед выполнением этого вызова, поэтому мини-порт должен выполнить этот вызов как можно быстрее. Пока ожидается остановка, portcls блокирует (удерживает) все новые запросы на создание.

  • IAdapterPnpManagement::P npCancelStop вызывается portcls при обработке IRP CanceStop. Это просто уведомление. Мини-порт может получать PnpCancelStop даже без предварительного уведомления PnpQueryStop. Мини-порт должен быть записан в соответствии с этим поведением. Например, это происходит, когда логика QueryStop завершается сбоем IRP до того, как Portcls сможет переслать это уведомление в мини-порт. В этом сценарии диспетчер PnP по-прежнему вызывает остановку отмены PnP.

    Примечание Portcls получает глобальную блокировку устройства перед выполнением этого вызова, поэтому мини-порт должен выполнить этот вызов как можно быстрее. Пока ожидается остановка, portcls блокирует (удерживает) все новые запросы на создание. PortCls перезапускает все выполняемые запросы на создание при отмене ожидающей остановки.

  • IAdapterPnpManagement::P npStop вызывается Portcls после остановки всех операций Ioctl и перемещения активных потоков из состояния [run|pause|acquire] в состояние [stop]. Этот вызов не выполняется при удержании глобальной блокировки устройства. Таким образом, мини-порт имеет возможность ждать асинхронных операций (рабочие элементы, dpc, асинхронные потоки) и отменять регистрацию своих дочерних аудиоустройств. Перед возвращением из этого вызова мини-порт должен убедиться, что все ресурсы h/w освобождены.

    Примечание Минипорт не должен ждать удаления текущих объектов miniport/stream, так как неясно, когда существующие аудиоконференты будут освобождать текущие дескрипторы. Поток PnpStop не может блокироваться навсегда без сбоя системы, т. е. это поток PnP/Power.

IMiniportPnpNotify

IMiniportPnpNotify — это необязательный интерфейс, позволяющий объектам мини-портов (аудиоподделениям) получать уведомления об изменении состояния PnP.

Минипорты имеют возможность получать уведомление об остановке PnP для каждого зарегистрированного звукового подраздела. Чтобы получить это уведомление, вложенная часть должна поддерживать IMiniportPnpNotify. В этом интерфейсе определено только уведомление IMiniportPnpNotify::P npStop .

Интерфейс IMiniportPnpNotify доступен как в WaveRT, так и в топологии.

Примечание Так как portcls получает глобальную блокировку устройства перед выполнением этого вызова, мини-порт должен выполнить этот вызов как можно быстрее. Мини-порт не должен ожидать другого действия при обработке этого вызова, чтобы предотвратить взаимоблокировку, когда другие потоки или рабочие элементы ожидают глобальной блокировки устройства. При необходимости мини-порт может ожидать вызова IAdapterPnpManagement::P npStop .