201 lines
4.7 KiB
C
201 lines
4.7 KiB
C
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
power.c
|
|
|
|
Abstract: ESC/POS (serial) interface for USB Point-of-Sale devices
|
|
|
|
Author:
|
|
|
|
ervinp
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include <WDM.H>
|
|
|
|
#include <usbdi.h>
|
|
#include <usbdlib.h>
|
|
#include <usbioctl.h>
|
|
|
|
#include "escpos.h"
|
|
#include "debug.h"
|
|
|
|
|
|
NTSTATUS FDO_Power(PARENTFDOEXT *parentFdoExt, PIRP irp)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dispatch routine for Power IRPs (MajorFunction == IRP_MJ_Power)
|
|
|
|
Note: We may or may not have set the DO_POWER_PAGABLE bit
|
|
for the filter device object in AddDevice().
|
|
Therefore, we don't know whether or not this function
|
|
can be called at DISPATCH_LEVEL; so the power-handling
|
|
code must be locked.
|
|
|
|
Arguments:
|
|
|
|
parentFdoExt - device extension for targetted device object
|
|
irp - Io Request Packet
|
|
|
|
Return Value:
|
|
|
|
NT status code
|
|
|
|
--*/
|
|
{
|
|
PIO_STACK_LOCATION irpSp;
|
|
NTSTATUS status;
|
|
|
|
irpSp = IoGetCurrentIrpStackLocation(irp);
|
|
|
|
switch (irpSp->MinorFunction){
|
|
|
|
case IRP_MN_SET_POWER:
|
|
|
|
DBGVERBOSE(("IRP_MN_SET_POWER"));
|
|
|
|
switch (irpSp->Parameters.Power.Type) {
|
|
|
|
case SystemPowerState:
|
|
/*
|
|
* For system power states, just pass the IRP down.
|
|
*/
|
|
break;
|
|
|
|
case DevicePowerState:
|
|
|
|
switch (irpSp->Parameters.Power.State.DeviceState) {
|
|
|
|
case PowerDeviceD0:
|
|
/*
|
|
* Resume from APM Suspend
|
|
*
|
|
* Do nothing here;
|
|
* Send down the read IRPs in the completion
|
|
* routine for this (the power) IRP.
|
|
*/
|
|
break;
|
|
|
|
case PowerDeviceD1:
|
|
case PowerDeviceD2:
|
|
case PowerDeviceD3:
|
|
/*
|
|
* Suspend
|
|
*/
|
|
if (parentFdoExt->state == STATE_STARTED){
|
|
parentFdoExt->state = STATE_SUSPENDED;
|
|
}
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DBGVERBOSE(("Power, minorFunc = %d ", (ULONG)irpSp->MinorFunction));
|
|
break;
|
|
}
|
|
|
|
|
|
/*
|
|
* Whether we are completing or relaying this power IRP,
|
|
* we must call PoStartNextPowerIrp.
|
|
*/
|
|
PoStartNextPowerIrp(irp);
|
|
|
|
/*
|
|
* Send the IRP down the driver stack,
|
|
* using PoCallDriver (not IoCallDriver, as for non-power irps).
|
|
*/
|
|
IoCopyCurrentIrpStackLocationToNext(irp);
|
|
IncrementPendingActionCount(parentFdoExt);
|
|
IoSetCompletionRoutine( irp,
|
|
FDO_PowerComplete,
|
|
(PVOID)parentFdoExt, // context
|
|
TRUE,
|
|
TRUE,
|
|
TRUE);
|
|
status = PoCallDriver(parentFdoExt->physicalDevObj, irp);
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS FDO_PowerComplete(
|
|
IN PDEVICE_OBJECT devObj,
|
|
IN PIRP irp,
|
|
IN PVOID context)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Completion routine for Power IRPs (MajorFunction == IRP_MJ_Power)
|
|
|
|
Arguments:
|
|
|
|
devObj - targetted device object
|
|
irp - Io Request Packet
|
|
context - context value passed to IoSetCompletionRoutine by FDO_Power
|
|
|
|
Return Value:
|
|
|
|
NT status code
|
|
|
|
--*/
|
|
{
|
|
PIO_STACK_LOCATION irpSp;
|
|
PARENTFDOEXT *parentFdoExt = (PARENTFDOEXT *)context;
|
|
|
|
ASSERT(parentFdoExt);
|
|
|
|
irpSp = IoGetCurrentIrpStackLocation(irp);
|
|
ASSERT(irpSp->MajorFunction == IRP_MJ_POWER);
|
|
|
|
if (NT_SUCCESS(irp->IoStatus.Status)){
|
|
switch (irpSp->MinorFunction){
|
|
|
|
case IRP_MN_SET_POWER:
|
|
|
|
switch (irpSp->Parameters.Power.Type){
|
|
|
|
case DevicePowerState:
|
|
switch (irpSp->Parameters.Power.State.DeviceState){
|
|
case PowerDeviceD0:
|
|
if (parentFdoExt->state == STATE_SUSPENDED){
|
|
parentFdoExt->state = STATE_STARTED;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* Decrement the pendingActionCount, which we incremented in FDO_Power.
|
|
*/
|
|
DecrementPendingActionCount(parentFdoExt);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
|