Compartir a través de


Cancelación de un IRP de espera o reactivación

Solo el controlador que envió un IRP de espera o reactivación puede cancelar ese IRP.

Es posible que un controlador tenga que cancelar un IRP de espera/reactivación pendiente en las siguientes circunstancias:

  • El controlador recibe una solicitud PnP IRP_MN_STOP_DEVICE, IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE o IRP_MN_SURPRISE_REMOVAL para el dispositivo. El controlador debe volver a emitir el IRP de espera/reactivación (PoRequestPowerIrp) después de reiniciar el dispositivo.

  • El sistema se va a suspender, pero el dispositivo no debe estar habilitado para reactivar el sistema.

    Por ejemplo, el controlador del concentrador USB podría enviar una solicitud de IRP_MN_WAIT_WAKE en el inicio del dispositivo en caso de que posteriormente coloque uno de sus dispositivos de entrada en un estado de suspensión. Mientras el sistema está en estado de funcionamiento, una señal de reactivación del dispositivo devuelve el dispositivo al estado de trabajo (pero no tiene ningún efecto en el estado de alimentación del sistema). Cuando el sistema se prepara para apagarse, el controlador del concentrador USB cancela este IRP si el dispositivo no debe permitirse despertar el sistema.

  • El sistema entra en un estado de suspensión desde el que el dispositivo no puede despertarlo. Es decir, entra en un estado menos alimentado que el valor de SystemWake especificado en su estructura de DEVICE_CAPABILITIES .

  • El dispositivo entra en un estado de alimentación desde el que no puede responder a una señal de reactivación. Es decir, entra en un estado menos alimentado que el valor DeviceWake especificado en su estructura de DEVICE_CAPABILITIES .

Para cancelar un IRP de espera o reactivación, el controlador que envió el IRP llama a IoCancelIrp, pasando el puntero al IRP que se devolvió anteriormente cuando el controlador llamó a PoRequestPowerIrp.

Un controlador no debe cancelar un IRP de espera o reactivación que no envió.

Cancelar rutinas para IRP de espera o reactivación

Muchos controladores de bus y función deben establecer rutinas de cancelación para IRP de espera/reactivación pendientes; Los siguientes tipos de controladores deben establecer estas rutinas:

  • Controladores que cambian la configuración del dispositivo para habilitar o deshabilitar la reactivación.

  • Controladores que envían IRP_MN_WAIT_WAKE solicitudes a controladores de dispositivos primarios.

Una rutina Cancelar permite a un controlador deshabilitar la reactivación de su dispositivo y limpiar los datos relacionados con el IRP de espera o reactivación pendientes. Los controladores que solicitan IRP de espera/reactivación para los dispositivos primarios también pueden cancelar esos IRP.

En su rutina wait/wake Cancel , un controlador debe seguir estos pasos:

  1. Llame a IoSetCancelRoutine para restablecer la rutina Cancel para irP a NULL.

  2. Llame a IoReleaseCancelSpinLock y pase cancelIRQL especificado en el IRP para liberar el bloqueo de número de cancelación del IRP.

  3. Restablezca los campos pertinentes de la extensión del dispositivo. Por ejemplo, cuando está pendiente un IRP de espera o reactivación, la mayoría de los controladores establecen una marca y mantienen un puntero al IRP en la extensión del dispositivo.

    Tenga en cuenta que es posible que un controlador reciba un IRP de espera o reactivación mientras se cancela otro irP de este tipo. El controlador debe comprobar si ya tiene un IRP bajo protección de bloqueo de giro (o su equivalente). Si es así, el controlador debe sincronizar cuidadosamente su control para asegurarse de que cancela el IRP correcto. Para obtener más información sobre el uso de bloqueos de número en Rutinas de cancelación , vea Cancelar IRP.

  4. Cambie cualquier configuración de dispositivo necesaria. Por ejemplo, un controlador de módem deshabilitaría la configuración de reactivación del dispositivo.

  5. Establezca Irp-IoStatus.Status> en STATUS_CANCELLED.

  6. Llame a IoCompleteRequest para completar el IRP de espera y reactivación, especificando IO_NO_INCREMENT.

  7. Si el controlador solicitó anteriormente un IRP_MN_WAIT_WAKE relacionado para un dispositivo primario, el controlador debe cancelar ese IRP desde su rutina Cancelar . El controlador debe liberar el bloqueo de número de cancelación antes de cancelar el IRP del elemento primario.

    Por ejemplo, un controlador que actúa como controlador de autobús para un dispositivo y posee un controlador de directiva de energía para su elemento primario debe cancelar un IRP de espera/reactivación relacionado que envió anteriormente a su elemento primario. Llamar a IoCancelIrp invocaría la rutina Cancel del elemento primario, etc.