New Driver should to implement IOCTL_POWER_SET to drop PowerUp() & PowerDown()

Suspend path on an implement power management device for WinCE 4.2 and Later

  1. Power Manager disable all Power-manageable none-block drivers.
  2. Power Manager calls the IOCTL_HAL_PRESUSPEND input/output control code. (to call OEMIoControl())
  3. Power Manager notifies file systems.
  4. Power Manager disable all Power-manageable block drivers.
  5. The operating system transitions to singnal threaded mode
  6. Power Manager calls all legcy XXX_PowerDown() callback function. In the state can not to calls any system call, because they will make the drivers non-pageable. The OS output the following event to the kernal debug port when to use any system call."!Unrecoverable Error: Exception or calling API inside Power Handler" or"ERROR : Power Handler function yield to low priority thread.
  7. Power Manager calls the OEMPowerOff(), which is the OEM code that suspends the CPU.
So when need write a new driver should to implement IOCTL_POWER_SET not to use PowerUP() and PowerDown() handle power state transition.The keypoint IOCTL_POWER_SET is pageable but PowerUp & PowerDown are non-pageable.
an example code:
FOO_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn,
        DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)
{
	BOOL fRet = FALSE;
	switch(dwCode) {
	..... // Others IoControl Handle
	case IOCTL_POWER_CAPABILITIES:
		if (pBufOut && pdwActualOut && (dwLenOut >= sizeof (POWER_CAPABILITIES)))
		{
    			PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES) pBufOut;

			memset(ppc, 0, sizeof(*ppc));
			// Add support power states that need handling
			// D0=0x01, D1=0x02, D2=0x04, D3=0x08, D4=0x10
			ppc->DeviceDx = (0x01 | 0x10); // D0, D4
			//  Setup other power capabilietes here
			*pdwActualOut = sizeof(POWER_CAPABILITIES);
			fRet = TRUE;
		}
		else 
		{
			SetLastError(ERROR_INVALID_PARAMETER);
		}
		break;
	case IOCTL_POWER_GET:
		........
		break;
	case IOCTL_POWER_SET:
		if (pBufOut && pdwActualOut && (dwLenOut >= sizeof (CEDEVICE_POWER_STATE)))
		{
			CEDEVICE_POWER_STATE NewDx = *(PCEDEVICE_POWER_STATE) pBufOut;

			//  Other IOCTL_POWER_SET code here
			switch(NewDx) {
			case D0:
				//  PowerUp() code moved here so we can page
        			break;
			case D1:
			case D2:
        			//  Other power states can be handled here
				break;
			case D3:
			case D4:
        			//  PowerDown() code moved here so we can page
        			break;
			}
		}
		else
		{
			SetLastError(ERROR_INVALID_PARAMETER);
		}
		break;
	}
}

Write a IClas interface of Power Mangeable value to registry of the driver let ActivateDeviceEx() automation notify Power Manager have a Power-manageable driver add when Driver Manager call.

Power manageable interface of IClass type

  • “{A32942B7-920C-486b-B0E6-92A702A99B35}" for Power-manageable non-block driver, generic driver
  • “{8DD679CE-8AB4-43c8-A14A-EA4963FAA715}" for Power-manageable block driver
  • “{98C5250D-C29A-4985-AE5F-AFE5367E5006}" for Power-manageable NDIS minport driver

Ref.

Line 880 into PlatformSetSystemPowerState() in PUBLICCOMMONOAKDRIVERSPMPDDPDAplatform.cpp

PowerHandlerGuardThrd() in PRIVATEWINCEOSCOREOSNKKERNELschedule.c

SC_PowerOffSystem() in PRIVATEWINCEOSCOREOSNKKERNELkwin32.c, system funciton PowerOffSystem() implement
Technorati tags: , ,
廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

%d 位部落客按了讚: