Handling Power Requests to Storage Peripherals
A storage class driver is responsible for issuing device-specific commands to handle power requests. Most commonly, a storage class driver:
Blocks I/O to its device in response to a query-power request (IRP_MJ_POWER with IRP_MN_QUERY_POWER) if handling such I/O might prevent the driver from succeeding a set-power request in a reasonable amount of time
Sets the power state of its device in response to a set-power request (IRP_MJ_POWER with IRP_MN_SET_POWER)
Restarts I/O to its device in response to a set-power request to power up the device
Forwards power requests to the next-lower driver.
Note that a driver must call PoStartNextPowerIrp and PoCallDriver, not IoCallDriver, to send power requests.
Unless the storage class driver has a StartIo routine, it should lock the storage port driver's LU-specific queue (IRP_MJ_SCSI with SRB_FUNCTION_LOCK_QUEUE) before setting the device's power state, to block unsynchronized operations until the power operation (which may involve several steps) is complete. Any SRBs issued to handle the power operation should set SRB_FLAGS_BYPASS_LOCKED_QUEUE to make sure they reach the port driver. After the driver finishes setting the power state, it should unlock the queue (IRP_MJ_SCSI with SRB_FUNCTION_UNLOCK_QUEUE and SRB_FLAGS_BYPASS_LOCKED_QUEUE) so that the port driver can resume sending queued IRPs to the device once it has been powered up.
If a storage class driver has a StartIo routine, that routine handles synchronization so the class driver does not have to explicitly lock and unlock the port driver's LU-specific queue.
A class driver should not attempt to bypass a queue locked by another driver.