Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este tópico descreve como os drivers de função UMDF dão suporte à suspensão seletiva da USB.
APIs importantes
- IWDFUsbTargetDevice::SetPowerPolicy
- IWDFDevice2::AssignSxWakeSettings
- IWDFDevice2::AssignS0IdleSettings
Os controladores de função UMDF podem suportar a suspensão seletiva USB de duas maneiras:
- Ao reivindicar a propriedade da política de energia e gerenciar o desligamento por inatividade e a retomada do dispositivo.
- Contando com o driver WinUSB.sys, que a Microsoft fornece, para lidar com a suspensão seletiva. WinUSB.sys é instalado como parte da pilha de dispositivos em modo kernel durante a instalação do driver USB do UMDF. WinUSB.sys implementa os mecanismos subjacentes para suspender e retomar a operação do dispositivo USB.
Ambas as abordagens exigem apenas pequenas quantidades de código. O exemplo IdleWake fornecido no WDK mostra como dar suporte à suspensão seletiva em um driver USB UMDF. Você pode encontrar este exemplo em %WinDDK%\BuildNumber\Src\Usb\OsrUsbFx2\ UMDF\Fx2_Driver\IdleWake. A pasta contém versões PPO e não PPO do arquivo de exemplo.
Os drivers UMDF que dão suporte à suspensão seletiva devem seguir estas diretrizes:
- O driver UMDF pode reivindicar a propriedade da política de energia para sua pilha de dispositivos, mas não é necessário fazê-lo. Por padrão, o driver WinUSB.sys subjacente controla a política de energia.
- Um driver UMDF que dá suporte à suspensão seletiva e é o PPO pode usar filas gerenciadas por energia ou filas que não são gerenciadas por energia. Um driver UMDF que dá suporte à suspensão seletiva, mas não é o PPO, não deve usar filas com gerenciamento de energia.
Propriedade de política de energia nos drivers USB do UMDF
Por padrão, WinUSB.sys é o PPO para uma pilha de dispositivos que inclui um driver USB UMDF. A partir do WDF 1.9, os drivers USB baseados em UMDF podem reivindicar a propriedade da política de energia. Como apenas um driver em cada pilha de dispositivos pode ser o PPO, um driver USB UMDF que é o PPO deve desabilitar explicitamente a propriedade da política de energia no WinUSB.sys.
Para assumir a propriedade da política de energia em um driver UMDF USB
Chame IWDFDeviceInitialize::SetPowerPolicyOwnership e passe TRUE, normalmente do método IDriverEntry::OnDeviceAdd no objeto de retorno de chamada do driver. Por exemplo:
FxDeviceInit->SetPowerPolicyOwnership(TRUE);Desativar a gestão de política de energia no WinUSB. No arquivo INF do driver, inclua uma diretiva AddReg que define o valor WinUsbPowerPolicyOwnershipDisabled no registro como um valor diferente de zero. A diretiva AddReg deve aparecer em uma seção DDInstall.HW. Por exemplo:
[MyDriver_Install.NT.hw] AddReg=MyDriver_AddReg [MyDriver_AddReg] HKR,,"WinUsbPowerPolicyOwnershipDisabled",0x00010001,1
Os drivers USB UMDF que dão suporte à suspensão seletiva e são criados com versões do WDF anteriores à 1.9 não devem reivindicar a propriedade da política de energia. Com essas versões anteriores do WDF, a suspensão seletiva de USB funciona corretamente somente se WinUSB.sys for o PPO.
Filas de E/S em drivers USB UMDF
Para um driver UMDF que dá suporte à suspensão seletiva, se o driver UMDF possui a política de energia para seu dispositivo determina o tipo de filas de E/S que ele pode usar. Os drivers UMDF que dão suporte à suspensão seletiva e são PPOs podem usar filas gerenciadas por energia ou não gerenciadas por energia. Drivers USB UMDF que dão suporte à suspensão seletiva, mas não são o PPO, não devem usar filas de E/S gerenciadas por energia.
Se uma solicitação de E/S chegar para uma fila gerenciada por energia enquanto o dispositivo estiver suspenso, o framework não apresentará a solicitação, a menos que o driver seja PPO, conforme mostrado na imagem na suspensão seletiva em drivers USB. Se o driver UMDF não for o PPO para o dispositivo, a estrutura não poderá ativar o dispositivo em seu nome. Como resultado, a solicitação permanece presa na fila gerenciada por energia. A solicitação nunca chega ao WinUSB, portanto, o WinUSB não pode ativar o dispositivo. Consequentemente, a pilha de dispositivos pode parar.
Se a fila não for gerenciada por energia, a estrutura apresentará solicitações de E/S para o driver UMDF mesmo quando o dispositivo for desligado. O driver UMDF formata a solicitação e a encaminha para baixo na pilha do dispositivo para o destino de E/S padrão da maneira usual. Código especial não é necessário. Quando a solicitação atinge o PPO (WinUSB.sys), WinUSB.sys habilita o dispositivo e executa a operação de E/S necessária.
O driver de exemplo em %WinDDK%\BuildNumber\Src\Usb\OsrUsbFx2\umdf\Fx2_Driver\IdleWake define a constante _NOT_POWER_POLICY_OWNER_ quando você compila a versão do driver que não é Power Policy Owner. Quando o driver cria uma fila para solicitações de leitura e gravação, ele determina se deve criar uma fila gerenciada por energia verificando a constante.
Para criar a fila, o driver chama o método CMyQueue::Initialize definido pelo driver, que usa os três parâmetros a seguir:
- DispatchType, um valor de enumeração WDF_IO_QUEUE_DISPATCH_TYPE que indica como a fila envia solicitações.
- Padrão, um booliano que indica se a fila é uma fila padrão.
- PowerManaged, um Booleano que indica se a fila é gerenciada por energia.
O trecho de código a seguir mostra a chamada do driver para o método CMyQueue::Initialize como parte da criação da fila de leitura e escrita.
#if defined(_NOT_POWER_POLICY_OWNER_)
powerManaged = false;
#else
powerManaged = true;
#endif
hr = __super::Initialize(WdfIoQueueDispatchParallel,
true,
powerManaged,
);
CMyQueue::Initialize então chama IWDFDevice::CreateIoQueue para criar a fila da seguinte maneira:
hr = m_FxDevice->CreateIoQueue(
callback,
Default,
DispatchType,
PowerManaged,
FALSE,
&fxQueue
);
Essa sequência de códigos resulta em uma fila padrão que envia solicitações em paralelo. Se o driver for o PPO, a fila será gerenciada por energia e, se o driver não for o PPO, a fila não será gerenciada por energia.
Suporte à suspensão seletiva USB em um PPO UMDF
Para dar suporte à suspensão seletiva, um driver USB UMDF que é o PPO para sua pilha de dispositivos deve fazer o seguinte:
- Declarar a propriedade da política de energia para a pilha de dispositivos, normalmente no método IDriverEntry::OnDeviceAdd em seu objeto de retorno de chamada de driver, conforme descrito anteriormente.
- Habilite a suspensão seletiva chamando o método IWDFDevice2::AssignS0IdleSettings no objeto do dispositivo da estrutura.
Para habilitar a suspensão seletiva USB de um PPO
- Chame IWDFDevice2::AssignS0IdleSettings, normalmente do método OnPrepareHardware no objeto de retorno de chamada do dispositivo. Configure os parâmetros para AssignS0IdleSettings da seguinte forma:
- IdleCaps para IdleUsbSelectiveSuspend.
- DxState para o estado de suspensão do dispositivo ao qual a estrutura transiciona o dispositivo em estado ocioso. Para a suspensão seletiva de USB, especifique PowerDeviceMaximum, que indica que o framework deve usar o valor especificado pelo driver de barramento.
- IdleTimeout para o número de milissegundos que o dispositivo deve estar ocioso antes que a estrutura o transicione para DxState.
- UserControlOfIdleSettings para IdleAllowUserControl se o driver permitir que os usuários gerenciem as configurações de inatividade, caso contrário, utilize IdleDoNotAllowUserControl.
- Habilitado para WdfUseDefault para habilitar a suspensão seletiva por padrão, mas para permitir que a configuração do usuário substitua o padrão.
O exemplo a seguir mostra como o driver IdleWake_PPO chama esse método em seu método CMyDevice::SetPowerManagement interno:
hr = m_FxDevice->AssignS0IdleSettings( IdleUsbSelectiveSuspend,
PowerDeviceMaximum,
IDLE_TIMEOUT_IN_MSEC,
IdleAllowUserControl,
WdfUseDefault);
Se o hardware do dispositivo puder gerar um sinal de ativação, o driver UMDF também poderá dar suporte à ativação do sistema a partir de S1, S2 ou S3. Para obter detalhes, consulte Ativação do Sistema em um Driver UMDF.
Suportando Suspensão Seletiva USB em um Driver UMDF não PPO
Um driver de função UMDF que não é o PPO pode dar suporte à suspensão seletiva usando os recursos do driver de WinUSB.sys subjacente. O driver UMDF deve notificar o WinUSB de que o dispositivo e o driver dão suporte à suspensão seletiva e devem habilitar a suspensão seletiva no arquivo INF ou definindo a política de energia no objeto de dispositivo de destino USB.
Se um driver de função UMDF habilitar a suspensão seletiva, o driver subjacente WinUSB.sys determinará quando o dispositivo está ocioso. O WinUSB inicia um contador de tempo de inatividade quando nenhuma transferência está pendente ou quando as únicas transferências pendentes são transferências IN em um endpoint de interrupção ou em massa. Por padrão, o tempo limite ocioso é de 5 segundos, mas o driver UMDF pode alterar esse padrão.
Quando WinUSB.sys determina que o dispositivo está ocioso, ele envia uma solicitação para suspender o dispositivo na pilha de dispositivos em modo kernel. O motorista do ônibus altera o estado do hardware conforme apropriado. Se todas as funções de dispositivo na porta tiverem sido suspensas, a porta entrará no estado de suspensão seletiva USB.
Se uma solicitação de E/S chegar ao WinUSB.sys enquanto o dispositivo estiver suspenso, WinUSB.sys retomará a operação do dispositivo se o dispositivo precisar ser habilitado para atender à solicitação. O driver UMDF não requer nenhum código para retomar o dispositivo enquanto o sistema permanece no S0. Se o hardware do dispositivo puder gerar um sinal de ativação, o driver UMDF também poderá dar suporte à ativação do sistema de S1, S2 ou S3. Para obter detalhes, consulte System Wake em um Driver UMDF.
Um driver UMDF que não é o PPO pode dar suporte à suspensão seletiva seguindo as duas etapas a seguir:
- Avisando ao WinUSB.sys que o dispositivo e o driver suportam suspensão seletiva.
- Habilitando a suspensão seletiva de USB.
Além disso, o driver pode, opcionalmente:
- Defina um valor de tempo limite para o dispositivo.
- Permitir que o usuário habilite ou desabilite a suspensão seletiva.
Para obter um exemplo de como implementar a suspensão seletiva USB em um driver de função USB UMDF que não seja o PPO, consulte o exemplo Fx2_Driver no WDK. Este exemplo está localizado em %WinDDK%\BuildNumber\Src\Usb\OsrUsbFx2\Umdf\Fx2_Driver\ IdleWake_Non-PPO.
Para notificar o WinUSB sobre o suporte de suspensão seletiva
Para notificar WinUSB.sys que o dispositivo pode dar suporte à suspensão seletiva USB, o INF do dispositivo deve adicionar o valor DeviceIdleEnabled à chave de hardware do dispositivo e definir o valor como 1. O exemplo a seguir mostra como o exemplo de Fx2_Driver adiciona e define esse valor no arquivo WUDFOsrUsbFx2_IdleWakeNon-PPO.Inx:
[OsrUsb_Device_AddReg]
...
HKR,,"DeviceIdleEnabled",0x00010001,1
Para habilitar a suspensão seletiva de USB
Um driver USB UMDF pode habilitar a suspensão seletiva USB em tempo de execução ou durante a instalação no INF.
Para habilitar o suporte em runtime, o driver de função chama IWDFUsbTargetDevice::SetPowerPolicy e define o parâmetro PolicyType como AUTO_SUSPEND e o parâmetro Value como TRUE ou 1. O exemplo a seguir mostra como o exemplo de Fx2_Driver permite a suspensão seletiva no arquivo DeviceNonPpo.cpp:
BOOL AutoSuspend = TRUE; hr = m_pIUsbTargetDevice->SetPowerPolicy( AUTO_SUSPEND, sizeof(BOOL), (PVOID) &AutoSuspend );Para habilitar o suporte durante a instalação, o INF inclui uma diretiva AddReg que adiciona o valor DefaultIdleState à chave de hardware do dispositivo e define o valor como 1. Por exemplo:
HKR,,"DefaultIdleState",0x00010001,1
Para definir um valor de tempo limite ocioso
Por padrão, o WinUSB suspende o dispositivo após 5 segundos se nenhuma transferência estiver pendente ou se as únicas transferências pendentes forem transferências IN em um endpoint de interrupção ou em massa. Um driver UMDF pode alterar esse valor de tempo limite ocioso na instalação no INF ou em runtime.
Para definir um tempo limite ocioso na instalação, o INF inclui uma diretiva AddReg que adiciona o valor DefaultIdleTimeout à chave de hardware do dispositivo e define o valor como o intervalo de tempo limite em milissegundos. O exemplo a seguir define o tempo limite como 7 segundos:
HKR,,"DefaultIdleTimeout",0x00010001,7000Para definir um tempo limite ocioso durante o tempo de execução, o driver chama IWDFUsbTargetDevice::SetPowerPolicy com PolicyType definido como SUSPEND_DELAY e Valor para o valor de tempo limite ocioso, expresso em milissegundos. No exemplo a seguir do arquivo Device.cpp, o exemplo de Fx2_Driver define o tempo limite como 10 segundos:
HRESULT hr; ULONG value; value = 10 * 1000; hr = m_pIUsbTargetDevice->SetPowerPolicy( SUSPEND_DELAY, sizeof(ULONG), (PVOID) &value );
Para permitir o controle do usuário sobre a suspensão seletiva do USB
Os drivers USB UMDF que usam o suporte de suspensão seletiva do WinUSB podem, opcionalmente, permitir que o usuário habilite ou desabilite a suspensão seletiva. Para fazer isso, inclua uma diretiva AddReg no INF que adiciona o valor UserSetDeviceIdleEnabled à chave de hardware do dispositivo e define o valor como 1. O seguinte mostra a cadeia de caracteres a ser usada para a diretiva AddReg:
HKR,,"UserSetDeviceIdleEnabled",0x00010001,1
Se a opção UserSetDeviceIdleEnabled estiver ativada, a caixa de diálogo Propriedades do dispositivo incluirá uma guia Gerenciamento de Energia que permite ao usuário ativar ou desativar a suspensão seletiva USB.
Despertar do sistema em um driver UMDF
Em um driver UMDF (Driver de Modo Usuário do Microsoft Windows), o suporte para despertar do sistema é independente do suporte para suspensão seletiva. Um driver USB UMDF pode dar suporte tanto à ativação do sistema quanto à suspensão seletiva, a nenhuma das duas, ou a uma ou outra dessas funcionalidades. Um dispositivo que suporta o despertar do sistema pode despertá-lo de um estado de suspensão (S1, S2 ou S3).
Um driver UMDF USB PPO pode dar suporte ao acordar do sistema ao fornecer informações de ativação para o objeto de driver do framework. Quando um evento externo dispara a ativação do sistema, o framework retorna o dispositivo para o estado operacional.
Um driver USB não-PPO pode utilizar o suporte de despertar do sistema que o driver WinUSB.sys implementa.
Para dar suporte à ativação do sistema em um driver USB do UMDF (User-Mode Driver Framework) que é o PPO**
Chame o método IWDFDevice2::AssignSxWakeSettings no objeto de dispositivo da estrutura com os seguintes parâmetros:
- DxState para o estado de energia para o qual o dispositivo faz a transição quando o sistema entra em um estado Sx de ativação. Para dispositivos USB, especifique PowerDeviceMaximum para usar o valor especificado pelo driver de ônibus.
- UserControlOfWakeSettings para WakeAllowUserControl se o driver permitir que os usuários gerenciem as configurações de ativação ou, caso contrário, para WakeDoNotAllowUserControl.
- Habilitado para WdfUseDefault para habilitar a ativação por padrão, mas para permitir que a configuração do usuário substitua o padrão.
O exemplo a seguir mostra como o driver IdleWake_PPO chama esse método em seu método CMyDevice::SetPowerManagement interno:
hr = m_FxDevice->AssignSxWakeSettings( PowerDeviceMaximum,
WakeAllowUserControl,
WdfUseDefault);
Para ativar o despertar do sistema via WinUSB em um driver que não seja PPO**
Para habilitar o despertar do sistema por meio do WinUSB, o INF do driver adiciona o valor do registro SystemWakeEnabled à chave de hardware do dispositivo e o define como 1. A amostra IdleWake_Non-PPO permite a ativação do sistema da seguinte maneira:
[OsrUsb_Device_AddReg]
...
HKR,,"SystemWakeEnabled",0x00010001,1
Ao definir esse valor, o driver tanto habilita o acordar do sistema quanto permite que o usuário controle a capacidade do dispositivo de acordar o sistema. No Gerenciador de Dispositivos, a página de propriedades de configurações de gerenciamento de energia do dispositivo inclui uma caixa de seleção, permitindo que o usuário habilite ou desabilite o acordar do sistema.