Поделиться через


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

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

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

  1. Hotplug PCI: пользователь подключается к устройству и шине PCI недостаточно ресурсов для загрузки драйвера для нового устройства. Некоторые примеры устройств, которые попадают в эту категорию, включают Thunderbolt, USB-C и хранилище NVME. В этом сценарии ресурсы памяти должны быть переупорядочены и консолидированы (перебалансированы) для поддержки дополнительных устройств, добавляемых.
  2. PCI resizable BARs: после успешной загрузки драйвера устройства в память он запрашивает дополнительные системные ресурсы. Некоторые примеры устройств включают высокопроизводительные графические карты и устройства хранения. Дополнительные сведения о поддержке видеодрайверов см. в разделе «Поддержка Resizable 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 или через IPortClsPnp COM-интерфейс IPortClsPnp, предоставляемый в объекте порта WaveRT. Используйте IPortClsPnp::RegisterAdapterPnpManagement и IPortClsPnp::UnregisterAdapterPnpManagement для регистрации и отмены регистрации.

обязательные идентификаторы DDI для экспорта PortCls

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

обязательные идентификаторы драйвера DDIs

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

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

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

  • IAdapterPnpManagement::PnpQueryStop вызывается PortCls незадолго до завершения обработки IRP QueryStop. Это просто уведомление, и вызов не возвращает значение.

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

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

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

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

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

IMiniportPnpNotify

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

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

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

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