Implementar redistribuição de PnP para drivers de áudio PortCls

A redistribuição PnP é usada em determinados cenários PCI em que os recursos de memória precisam ser realocados.

A redistribuição pode ser acionada em dois cenários principais:

  1. Hotplug PCI: um usuário conecta um dispositivo e o barramento PCI não tem recursos suficientes para carregar o driver para o novo dispositivo. Alguns exemplos de dispositivos que se enquadram nesta categoria incluem Thunderbolt, USB-C e NVME Storage. Nesse cenário, os recursos de memória precisam ser reorganizados e consolidados (redistribuídos) para oferecer suporte aos dispositivos adicionais que estão sendo adicionados.
  2. BARs redimensionáveis PCI: depois que um driver para um dispositivo é carregado com êxito na memória, ele solicita recursos adicionais. Alguns exemplos de dispositivos incluem placas gráficas de alta tecnologia e dispositivos de armazenamento. Para obter mais informações sobre o suporte a drivers de vídeo, consulte Suporte a BAR redimensionável. Este tópico descreve o que precisa ser feito para implementar a redistribuição PnP para drivers de áudio PortCls.

A redistribuição PnP está disponível no Windows 10, versão 1511 e versões posteriores do Windows.

Requisitos de redistribuição

Os drivers de áudio Portcls oferecerão suporte à redistribuição se as seguintes condições forem atendidas:

Para oferecer suporte à redistribuição quando há fluxos de áudio ativos, os drivers de áudio portcls precisam atender a um desses dois requisitos adicionais.

OR

Comportamento de fluxo de áudio durante redistribuição

Se a redistribuição for acionada, quando houver fluxos de áudio ativos e o driver fornecer suporte à redistribuição para fluxos de áudio ativos, todos os fluxos de áudio ativos serão interrompidos e não serão reiniciados automaticamente.

Interface COM IPortClsPnp

IPortClsPnp é a interface de gerenciamento PnP que o driver de classe de porta (PortCls) expõe ao adaptador.

IPortClsPnp herda de IUnknown e também suporta os seguintes métodos:

Os drivers de miniporta de áudio podem registrar uma interface de notificação PNP usando exportações Portcls ou através da interface COM IPortClsPnp exposta no objeto de porta WaveRT. Use IPortClsPnp::RegisterAdapterPnpManagement e IPortClsPnp::UnregisterAdapterPnpManagement para registrar e cancelar o registro.

DDIs de exportação de PortCls necessárias

IAdapterPnpManagement é uma interface que os adaptadores deverão implementar e registrar se quiserem receber mensagens de gerenciamento PnP. Registre essa interface com PortCls usando PcRegisterAdapterPnpManagement. Cancele o registro dessa interface com PortCls usando PcUnregisterAdapterPnpManagement.

DDIs de driver necessárias

As seguintes DDIs IAdapterPnpManagement devem ser implementadas para dar suporte à redistribuição.

  • IAdapterPnpManagement::GetSupportedRebalanceType é chamado por Portcls durante o processamento do QueryStop. A miniporta retorna o tipo de redistribuição suportado, conforme definido no enum PC_REBALANCE_TYPE.

    Observação O Portcls adquire o bloqueio global do dispositivo antes de fazer essa chamada, portanto, a miniporta deve executar essa chamada o mais rápido possível.

  • IAdapterPnpManagement::PnpQueryStop é invocado por portcls pouco antes de suceder o IRP QueryStop. Essa é apenas uma notificação, e a chamada não retorna um valor.

    Observação O Portcls adquire o bloqueio global do dispositivo antes de fazer essa chamada, portanto, a miniporta deve executar essa chamada o mais rápido possível. Enquanto uma parada estiver pendente, o Portcls bloqueará (manterá) quaisquer novas solicitações de criação.

  • IAdapterPnpManagement::PnpCancelStop é invocado por portcls durante o processamento do IRP CanceStop. Essa é apenas uma notificação. É possível que a miniporta receba PnpCancelStop mesmo sem receber anteriormente uma notificação PnpQueryStop. A miniporta deve ser gravada para acomodar esse comportamento. Por exemplo, esse é o caso quando a lógica QueryStop falha o IRP antes que o Portcls tenha a oportunidade de encaminhar essa notificação para a miniporta. Nesse cenário, o gerenciador PnP ainda invoca uma parada de cancelamento de PnP.

    Observação O Portcls adquire o bloqueio global do dispositivo antes de fazer essa chamada, portanto, a miniporta deve executar essa chamada o mais rápido possível. Enquanto uma parada estiver pendente, o Portcls bloqueará (manterá) quaisquer novas solicitações de criação. O PortCls reinicia todas as solicitações de criação pendentes quando uma parada pendente é cancelada.

  • IAdapterPnpManagement::PnpStop é invocado por Portcls depois de parar todas as operações Ioctl e mover fluxos ativos do estado [run|pause|acquire] para o estado [stop]. Essa chamada não é feita enquanto mantém pressionado o bloqueio global do dispositivo. Assim, a miniporta tem a oportunidade de aguardar suas operações assíncronas (itens de trabalho, dpc, threads assíncronos) e cancelar o registro de seus subdispositivos de áudio. Antes de retornar dessa chamada, a miniporta deve garantir que todos os recursos h/w tenham sido liberados.

    Observação A miniporta não deve esperar que os objetos de miniporta/fluxo atuais sejam excluídos, pois não está claro quando os clientes de áudio existentes liberarão os identificadores atuais. O thread PnpStop não pode bloquear para sempre sem travar o sistema, ou seja, este é um thread PnP/Power.

IMiniportPnpNotify

IMiniportPnpNotify é uma interface opcional para permitir que objetos de miniporta (subdispositivos de áudio) recebam notificações de alteração de estado PnP.

As miniportas têm a oportunidade de receber uma notificação PnP Stop para cada subdispositivo de áudio que registraram. Para receber essa notificação, o subdispositivo deve oferecer suporte a IMiniportPnpNotify. Somente a notificação IMiniportPnpNotify::PnpStop é definida nessa interface.

A interface IMiniportPnpNotify disponível está no WaveRT e na Topologia.

Observação Como o Portcls adquire o bloqueio global do dispositivo antes de fazer essa chamada, a miniporta deve executar essa chamada o mais rápido possível. A miniporta não deve aguardar outra atividade durante o processamento dessa chamada para evitar o deadlock quando outros threads/itens de trabalho estiverem aguardando o bloqueio global do dispositivo. Se necessário, a miniporta pode aguardar na chamada IAdapterPnpManagement::PnpStop.