Control de IRP_MN_SET_POWER para estados de energía del dispositivo
Un IRP de conjunto de dispositivos solicita un cambio de estado para un único dispositivo y se envía a todos los controladores de la pila del dispositivo. Este tipo de IRP especifica DevicePowerState en el miembro Power.Type de la ubicación de pila de E/S.
Los controladores controlan los IRP de encendido a medida que se desplazan por la pila. En el caso de los IRP de encendido, los controladores establecen rutinas de IoCompletion a medida que los IRP viajan por la pila y, a continuación, controlan los IRP en las rutinas de IoCompletion a medida que los IRP se desplazan hacia arriba en la pila. Los controladores de una pila de dispositivos típica controlan un IRP de conjunto de dispositivos de la siguiente manera:
La mayoría de los controladores de filtro simplemente deben llamar a IoMarkIrpPending, pasar irP al controlador inferior siguiente (consulte Pasar IRP de Power) y devolver STATUS_PENDING de la rutina DispatchPower . Sin embargo, es posible que algunos controladores de filtro tengan que realizar tareas específicas del dispositivo, como poner en cola los IRP entrantes o guardar el estado de energía del dispositivo.
Un controlador de función llama a IoMarkIrpPending, realiza tareas específicas del dispositivo (como completar solicitudes de E/S pendientes, poner en cola las solicitudes de E/S entrantes, guardar el contexto del dispositivo o cambiar la energía del dispositivo), establece una rutina de IoCompletion si es necesario y pasa el IRP de energía del dispositivo al controlador inferior siguiente (consulte Pasar IRP de Power). Devuelve STATUS_PENDING de su rutina DispatchPower .
El controlador de bus cambia la energía del dispositivo si es capaz de hacerlo y, a continuación, llama a PoSetPowerState para notificar al administrador de energía del nuevo estado de alimentación del dispositivo. En Windows Server 2003, Windows XP y Windows 2000 solo, el controlador también debe llamar a PoStartNextPowerIrp para iniciar el siguiente IRP de energía después de establecer el estado de energía. A continuación, el controlador completa el IRP, especificando IO_NO_INCREMENT. Si el controlador no puede completar el IRP inmediatamente, llama a IoMarkIrpPending, devuelve STATUS_PENDING de su rutina DispatchPower y completa el IRP más adelante.
Incluso si el dispositivo de destino ya está en estado de alimentación solicitado, cada función o controlador de filtro debe pasar el IRP hacia abajo al controlador inferior siguiente. Cada IRP de energía establecida debe viajar hasta la pila del dispositivo al controlador de autobús, que lo completa.
Los controladores de función y filtro que se encuentran encima de un controlador de bus no deben producir un error en un IRP de alimentación del conjunto de dispositivos. El controlador de bus puede producir un error en un IRP de encendido del dispositivo si el dispositivo se quita o en el proceso de eliminación.
Cada controlador (función, filtro y controlador de autobús) de una pila de controladores debe llamar a PoSetPowerState para informar al administrador de energía de un cambio en el estado de alimentación de su objeto de dispositivo correspondiente.
Al igual que otras tareas de controlador asociadas al encendido y apagado del dispositivo, la llamada a PoSetPowerState debe producirse después de encender el dispositivo (si el nuevo estado es D0) o antes de que el dispositivo se apague (si el nuevo estado es cualquier otro estado).
Cada controlador debe realizar un seguimiento del estado de alimentación de su dispositivo. El administrador de energía no proporciona esta información a los conductores.
Al controlar una solicitud de IRP_MN_SET_POWER para un estado de alimentación del dispositivo, un controlador debe volver de la rutina DispatchPower lo antes posible. Un controlador no debe esperar en su rutina DispatchPower para un evento de kernel señalado por código que controla el mismo IRP. Dado que los IRP de energía se sincronizan en todo el sistema, puede producirse un interbloqueo.
Para garantizar el mayor nivel de rendimiento del sistema, especialmente para las aplicaciones multimedia, un controlador debe realizar operaciones que consumen mucho tiempo en un nivel de solicitud de interrupción (IRQL) igual a PASSIVE_LEVEL. Para realizar operaciones en IRQL= PASSIVE_LEVEL, un controlador puede usar un subproceso dedicado o un subproceso de trabajo del sistema. Para obtener instrucciones sobre cómo optimizar el rendimiento de los controladores para plataformas multimedia, consulte la Guía de diseño de dispositivos multimedia de streaming.
Los pasos exactos que debe seguir un controlador para controlar un IRP de alimentación dependen de si el dispositivo está encendido o inactivo, como se describe en las secciones siguientes: