Control de irP de Power-Down de dispositivos
Un IRP de apagado de dispositivo especifica el código de función secundario IRP_MN_SET_POWER y un estado de alimentación del dispositivo (PowerDeviceD0, PowerDeviceD1, PowerDeviceD2 o PowerDeviceD3) que es menos alimentado o igual que el estado de alimentación del dispositivo actual. Los controladores deben controlar el IRP de encendido a medida que irP viaja por la pila del dispositivo. Los controladores de nivel superior deben controlar el IRP antes de los controladores de nivel inferior. Los controladores que no tienen tareas específicas del dispositivo que se deben realizar deben pasar rápidamente el IRP al controlador inferior siguiente.
En la ilustración siguiente se muestran los pasos implicados en el control de este tipo de IRP.
Si IRP especifica PowerDeviceD3, el controlador de función normalmente debe realizar las siguientes tareas:
Llame a IoAcquireRemoveLock, pasando el IRP actual, para asegurarse de que el controlador no recibe una solicitud de IRP_MN_REMOVE_DEVICE PnP mientras controla el IRP de energía.
Si IoAcquireRemoveLock devuelve un estado de error, el controlador no debe seguir procesando el IRP. En su lugar, a partir de Windows Vista, el controlador debe llamar a IoCompleteRequest para completar el IRP y, a continuación, devolver el estado de error. En Windows Server 2003, Windows XP y Windows 2000, el controlador debe llamar a IoCompleteRequest para completar el IRP y, a continuación, llamar a PoStartNextPowerIrp para iniciar el siguiente IRP de energía y, a continuación, devolver el estado del error.
Realice las tareas específicas del dispositivo que se deben realizar antes de quitar la alimentación del dispositivo, como cerrar el dispositivo, completar o vaciar cualquier E/S pendiente, deshabilitar interrupciones, poner en cola los IRP entrantes posteriores y guardar el contexto del dispositivo desde el que restaurar o reinicializar el dispositivo.
El controlador no debe provocar un retraso largo (por ejemplo, un retraso que un usuario podría encontrar irrazonable para este tipo de dispositivo) al controlar el IRP.
El controlador debe poner en cola las solicitudes de E/S entrantes hasta que el dispositivo haya vuelto al estado de funcionamiento.
Posiblemente compruebe el valor en Parameters.Power.ShutdownType. Si un IRP de configuración del sistema está activo, ShutdownType proporciona información sobre el IRP del sistema. Para obtener más información sobre este valor, vea Acciones de energía del sistema.
Los controladores de los dispositivos en la ruta de acceso de hibernación deben inspeccionar este valor. Si ShutdownType es PowerActionHibernate, el controlador debe guardar cualquier contexto necesario para restaurar el dispositivo, pero no debe apagar el dispositivo.
Cambie el estado de alimentación física del dispositivo si el controlador es capaz de hacerlo y si el cambio es adecuado.
Llame a PoSetPowerState para notificar al administrador de energía el nuevo estado de alimentación del dispositivo.
Llame a IoCopyCurrentIrpStackLocationToNext para configurar la ubicación de la pila para el controlador inferior siguiente.
Establezca una rutina de IoCompletion que llame a PoStartNextPowerIrp que indica que el controlador está listo para controlar el siguiente IRP de energía. Este paso no es necesario en Windows 7 y Windows Vista.
Llama a IoCallDriver (en Windows 7 y Windows Vista) o llama a PoCallDriver (en Windows Server 2003, Windows XP y Windows 2000) para pasar el IRP al controlador inferior siguiente. El IRP debe pasarse hasta el conductor del autobús, que completa el IRP.
Llame a IoReleaseRemoveLock para liberar el bloqueo adquirido anteriormente.
Devuelve STATUS_PENDING.
Los controladores deben guardar cualquier información de contexto del dispositivo y establecer el nuevo estado de energía antes de reenviar el IRP. La información de contexto debe contener, como mínimo, el nuevo estado de energía solicitado. También debe incluir cualquier información adicional que el controlador necesite al encenderse. Una vez completado el IRP y el dispositivo se ha apagado, el controlador ya no puede acceder al dispositivo y el contexto del dispositivo no está disponible.
Cada controlador debe pasar el IRP al controlador inferior siguiente. Cuando el IRP llega al controlador de autobús, el controlador de autobús apaga el dispositivo (si es capaz de esto), llama a PoSetPowerState para informar al administrador de energía y completa el IRP.
Sin embargo, si el controlador de bus atiende el dispositivo de hibernación, debe comprobar si el valor de ShutdownType en irP es PowerSystemHibernate. Si es así, el controlador de bus debe llamar a PoSetPowerState para notificar PowerDeviceD3, pero no debe apagar el dispositivo. El dispositivo se apagará después de guardar el archivo de hibernación, junto con el resto del sistema.
Después de que todos sus dispositivos secundarios apaguen, un conductor de autobús también podría optar por apagar su bus. Este comportamiento depende del dispositivo.
Si el IRP especifica cualquier otro estado (D0, D1 o D2), las acciones de controlador necesarias dependen del dispositivo. Normalmente, los dispositivos que admiten estos estados pueden volver rápidamente al estado de trabajo cuando llega una solicitud de E/S. Un controlador para este tipo de dispositivo debe completar las solicitudes de E/S pendientes, poner en cola todas las solicitudes nuevas y guardar todo el contexto necesario antes de reenviar el IRP al controlador inferior siguiente. Cuando el IRP llega al controlador de bus, establece el hardware en el estado solicitado. Un controlador no puede acceder al dispositivo mientras está dormido.
En algunas circunstancias, una función o un controlador de filtro pueden recibir un IRP de alimentación del dispositivo que especifica PowerDeviceD0 cuando el dispositivo ya está en estado D0. El controlador debe controlar este IRP como lo haría con cualquier otro IRP de potencia establecida: completar solicitudes de E/S pendientes, poner en cola las solicitudes de E/S entrantes, establecer una rutina de IoCompletion y pasar el IRP al controlador inferior siguiente. Sin embargo, un controlador no debe cambiar la configuración de hardware del dispositivo. Cuando el controlador de autobús recibe el IRP, simplemente debe completar el IRP. Cuando se completa el IRP, los controladores de función y filtro pueden controlar las solicitudes en cola. La E/S de puesta en cola hasta que el IRP se completa elimina cualquier posibilidad de que los controladores inferiores intenten cambiar los registros de dispositivos mientras un controlador superior intenta E/S.