Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

480 lines
12 KiB

  1. /*++
  2. Module Name:
  3. POWER.C
  4. Abstract:
  5. This module contains contains the plugplay power calls
  6. for a serial port bus enumerator PNP / WDM driver.
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. Revision History:
  11. --*/
  12. #include <ntddk.h>
  13. #include <ntddser.h>
  14. #include "mxenum.h"
  15. #include "mxlog.h"
  16. static const PHYSICAL_ADDRESS SerialPhysicalZero = {0};
  17. #ifdef ALLOC_PRAGMA
  18. #pragma alloc_text (PAGE, MxenumPowerDispatch)
  19. #pragma alloc_text (PAGE, MxenumFdoPowerDispatch)
  20. #pragma alloc_text (PAGE, MxenumPdoPowerDispatch)
  21. #endif
  22. NTSTATUS
  23. MxenumPowerDispatch (
  24. IN PDEVICE_OBJECT DeviceObject,
  25. IN PIRP Irp
  26. )
  27. /*++
  28. --*/
  29. {
  30. PIO_STACK_LOCATION irpStack;
  31. NTSTATUS status;
  32. PCOMMON_DEVICE_DATA commonData;
  33. PAGED_CODE ();
  34. status = STATUS_SUCCESS;
  35. irpStack = IoGetCurrentIrpStackLocation (Irp);
  36. // ASSERT (IRP_MJ_POWER == irpStack->MajorFunction);
  37. commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
  38. if (commonData->IsFDO) {
  39. status =
  40. MxenumFdoPowerDispatch ((PFDO_DEVICE_DATA) DeviceObject->DeviceExtension,
  41. Irp);
  42. } else {
  43. status =
  44. MxenumPdoPowerDispatch ((PPDO_DEVICE_DATA) DeviceObject->DeviceExtension,
  45. Irp);
  46. }
  47. return status;
  48. }
  49. NTSTATUS
  50. MxenumFdoPowerComplete (
  51. IN PDEVICE_OBJECT DeviceObject,
  52. IN PIRP Irp,
  53. IN PVOID Context
  54. );
  55. NTSTATUS
  56. MxenumFdoPowerDispatch(
  57. PFDO_DEVICE_DATA Data,
  58. PIRP Irp
  59. )
  60. /*++
  61. --*/
  62. {
  63. NTSTATUS status;
  64. BOOLEAN hookit = FALSE;
  65. POWER_STATE powerState;
  66. POWER_STATE_TYPE powerType;
  67. PIO_STACK_LOCATION stack;
  68. UCHAR minorFunction;
  69. stack = IoGetCurrentIrpStackLocation (Irp);
  70. minorFunction = stack->MinorFunction;
  71. powerType = stack->Parameters.Power.Type;
  72. powerState = stack->Parameters.Power.State;
  73. PAGED_CODE ();
  74. status = MxenumIncIoCount (Data);
  75. if (!NT_SUCCESS (status)) {
  76. PoStartNextPowerIrp (Irp);
  77. Irp->IoStatus.Information = 0;
  78. Irp->IoStatus.Status = status;
  79. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  80. return status;
  81. }
  82. status = Irp->IoStatus.Status;
  83. switch (minorFunction) {
  84. case IRP_MN_SET_POWER:
  85. MxenumKdPrint( MXENUM_DBG_TRACE,
  86. ("Serenum-PnP Setting %s state to %d\n",
  87. ((powerType == SystemPowerState) ? "System" : "Device"),
  88. powerState.SystemState));
  89. switch (powerType) {
  90. case DevicePowerState:
  91. status = Irp->IoStatus.Status = STATUS_SUCCESS;
  92. if (Data->DeviceState < powerState.DeviceState) {
  93. //
  94. // Powering down
  95. PoSetPowerState (Data->Self, powerType, powerState);
  96. Data->DeviceState = powerState.DeviceState;
  97. } else if (Data->DeviceState > powerState.DeviceState) {
  98. //
  99. // Powering Up
  100. //
  101. hookit = TRUE;
  102. }
  103. break;
  104. case SystemPowerState:
  105. MxenumKdPrint (MXENUM_DBG_TRACE,
  106. ("In SystemPowerState\n"
  107. " Current System state = %d\n"
  108. " Device started = %d\n"
  109. " System state to be set = %d\n"
  110. " Irql = %x\n",
  111. Data->SystemState,
  112. Data->Started,
  113. powerState.SystemState,
  114. KeGetCurrentIrql()));
  115. /* 3-22-01 by William
  116. if ((Data->SystemState == PowerSystemHibernate)&&
  117. */
  118. if ((Data->SystemState != PowerSystemWorking)&&
  119. // (Data->Started == TRUE)&&
  120. (powerState.SystemState == PowerSystemWorking)){
  121. ULONG i;
  122. MxenumKdPrint (MXENUM_DBG_TRACE,("Hook it\n"));
  123. // hookit = TRUE;
  124. MxenumKdPrint (MXENUM_DBG_TRACE,
  125. ("Start Device: Start to download\n"));
  126. i = 0;
  127. while (BoardDesc[Data->BoardType-1][i])
  128. i++;
  129. i <<= 1;
  130. status = MxenumDownloadFirmware(Data,TRUE);
  131. MxenumKdPrint (MXENUM_DBG_TRACE,
  132. ("BoardDesc(%d)->%ws\n",i,BoardDesc[Data->BoardType-1]));
  133. if (status != 0) {
  134. ULONG j;
  135. j = 0;
  136. while (DownloadErrMsg[status-1][j])
  137. j++;
  138. j <<= 1;
  139. MxenumKdPrint (MXENUM_DBG_TRACE,
  140. ("Start Device: Device started failure\n"));
  141. #if 0
  142. MxenumLogError(
  143. DeviceObject->DriverObject,
  144. NULL,
  145. SerialPhysicalZero,
  146. SerialPhysicalZero,
  147. 0,
  148. 0,
  149. 0,
  150. 19,
  151. STATUS_SUCCESS,
  152. MXENUM_DOWNLOAD_FAIL,
  153. i + sizeof (WCHAR),
  154. BoardDesc[Data->BoardType -1],
  155. j + sizeof (WCHAR),
  156. DownloadErrMsg[status -1]
  157. );
  158. #endif
  159. Data->Started = FALSE;
  160. }
  161. else {
  162. MxenumKdPrint (MXENUM_DBG_TRACE,
  163. ("Start Device: Device started successfully\n"));
  164. Data->Started = TRUE;
  165. }
  166. }
  167. status = STATUS_SUCCESS; // return SUCCESS anyway
  168. break;
  169. default:
  170. break;
  171. }
  172. //
  173. // Power IRPS come synchronously; drivers must call
  174. // PoStartNextPowerIrp, when they are ready for the next power
  175. // irp. This can be called here, or in the completetion
  176. // routine, but never the less must be called.
  177. //
  178. Irp->IoStatus.Status = status;
  179. Data->SystemState = powerState.SystemState;
  180. IoCopyCurrentIrpStackLocationToNext (Irp);
  181. PoStartNextPowerIrp (Irp);
  182. PoCallDriver (Data->TopOfStack, Irp);
  183. MxenumDecIoCount (Data);
  184. return status;
  185. case IRP_MN_QUERY_POWER:
  186. //
  187. Data->PowerQueryLock = TRUE;
  188. status = Irp->IoStatus.Status = STATUS_SUCCESS;
  189. break;
  190. default:
  191. break;
  192. }
  193. IoCopyCurrentIrpStackLocationToNext (Irp);
  194. if (hookit) {
  195. status = MxenumIncIoCount (Data);
  196. // ASSERT (STATUS_SUCCESS == status);
  197. IoSetCompletionRoutine (Irp,
  198. MxenumFdoPowerComplete,
  199. NULL,
  200. TRUE,
  201. TRUE,
  202. TRUE);
  203. PoCallDriver (Data->TopOfStack, Irp);
  204. } else {
  205. //
  206. // Power IRPS come synchronously; drivers must call
  207. // PoStartNextPowerIrp, when they are ready for the next power
  208. // irp. This can be called here, or in the completetion
  209. // routine, but never the less must be called.
  210. //
  211. PoStartNextPowerIrp (Irp);
  212. PoCallDriver (Data->TopOfStack, Irp);
  213. }
  214. #if 0
  215. if ((minorFunction == IRP_MN_SET_POWER)&&
  216. (powerType == SystemPowerState)) {
  217. Data->SystemState = powerState.SystemState;
  218. }
  219. #endif
  220. MxenumDecIoCount (Data);
  221. return status;
  222. }
  223. NTSTATUS
  224. MxenumFdoPowerComplete (
  225. IN PDEVICE_OBJECT DeviceObject,
  226. IN PIRP Irp,
  227. IN PVOID Context
  228. )
  229. /*++
  230. --*/
  231. {
  232. POWER_STATE powerState;
  233. POWER_STATE_TYPE powerType;
  234. PIO_STACK_LOCATION stack;
  235. PFDO_DEVICE_DATA data;
  236. NTSTATUS status = STATUS_SUCCESS;
  237. UNREFERENCED_PARAMETER (Context);
  238. data = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;
  239. stack = IoGetCurrentIrpStackLocation (Irp);
  240. powerType = stack->Parameters.Power.Type;
  241. powerState = stack->Parameters.Power.State;
  242. MxenumKdPrint (MXENUM_DBG_TRACE,
  243. ("MxenumFdoPowerComplete,irql=%x\n",KeGetCurrentIrql()));
  244. switch (stack->MinorFunction) {
  245. case IRP_MN_SET_POWER:
  246. switch (powerType) {
  247. case DevicePowerState:
  248. //
  249. // Powering Up
  250. //
  251. // ASSERT (powerState.DeviceState < data->DeviceState);
  252. data->DeviceState = powerState.DeviceState;
  253. PoSetPowerState (data->Self, powerType, powerState);
  254. break;
  255. case SystemPowerState:
  256. {
  257. ULONG i;
  258. MxenumKdPrint (MXENUM_DBG_TRACE,
  259. ("Start Device: Start to download\n"));
  260. i = 0;
  261. while (BoardDesc[data->BoardType-1][i])
  262. i++;
  263. i <<= 1;
  264. status = MxenumDownloadFirmware(data,TRUE);
  265. MxenumKdPrint (MXENUM_DBG_TRACE,
  266. ("BoardDesc(%d)->%ws\n",i,BoardDesc[data->BoardType-1]));
  267. if (status != 0) {
  268. ULONG j;
  269. j = 0;
  270. while (DownloadErrMsg[status-1][j])
  271. j++;
  272. j <<= 1;
  273. MxenumKdPrint (MXENUM_DBG_TRACE,
  274. ("Start Device: Device started failure\n"));
  275. MxenumLogError(
  276. DeviceObject->DriverObject,
  277. NULL,
  278. SerialPhysicalZero,
  279. SerialPhysicalZero,
  280. 0,
  281. 0,
  282. 0,
  283. 19,
  284. STATUS_SUCCESS,
  285. MXENUM_DOWNLOAD_FAIL,
  286. i + sizeof (WCHAR),
  287. BoardDesc[data->BoardType -1],
  288. j + sizeof (WCHAR),
  289. DownloadErrMsg[status -1]
  290. );
  291. data->Started = FALSE;
  292. status = STATUS_UNSUCCESSFUL;
  293. }
  294. else {
  295. MxenumKdPrint (MXENUM_DBG_TRACE,
  296. ("Start Device: Device started successfully\n"));
  297. data->Started = TRUE;
  298. }
  299. break;
  300. }
  301. default:
  302. break;
  303. }
  304. break;
  305. case IRP_MN_QUERY_POWER:
  306. // ASSERT (IRP_MN_QUERY_POWER != stack->MinorFunction);
  307. break;
  308. default:
  309. // ASSERT (0xBADBAD == IRP_MN_QUERY_POWER);
  310. break;
  311. }
  312. PoStartNextPowerIrp (Irp);
  313. MxenumDecIoCount (data);
  314. return status;
  315. }
  316. VOID
  317. MxenumPdoPowerComplete (
  318. IN PDEVICE_OBJECT DeviceObject,
  319. IN UCHAR MinorFunction,
  320. IN POWER_STATE PowerState,
  321. IN PVOID Irp,
  322. IN PIO_STATUS_BLOCK IoStatus
  323. );
  324. NTSTATUS
  325. MxenumPdoPowerDispatch (
  326. PPDO_DEVICE_DATA PdoData,
  327. PIRP Irp
  328. )
  329. /*++
  330. --*/
  331. {
  332. NTSTATUS status = STATUS_SUCCESS;
  333. PIO_STACK_LOCATION stack;
  334. POWER_STATE powerState;
  335. POWER_STATE_TYPE powerType;
  336. PAGED_CODE();
  337. status = Irp->IoStatus.Status;
  338. stack = IoGetCurrentIrpStackLocation (Irp);
  339. powerType = stack->Parameters.Power.Type;
  340. powerState = stack->Parameters.Power.State;
  341. switch (stack->MinorFunction) {
  342. case IRP_MN_SET_POWER:
  343. switch (powerType) {
  344. case DevicePowerState:
  345. if (PdoData->DeviceState > powerState.DeviceState) {
  346. PoSetPowerState (PdoData->Self, powerType, powerState);
  347. PdoData->DeviceState = powerState.DeviceState;
  348. } else if (PdoData->DeviceState < powerState.DeviceState) {
  349. //
  350. // Powering down.
  351. //
  352. PoSetPowerState (PdoData->Self, powerType, powerState);
  353. PdoData->DeviceState = powerState.DeviceState;
  354. }
  355. break;
  356. case SystemPowerState:
  357. status = STATUS_SUCCESS;
  358. break;
  359. default:
  360. // status = STATUS_NOT_IMPLEMENTED;
  361. break;
  362. }
  363. break;
  364. case IRP_MN_QUERY_POWER:
  365. PdoData->PowerQueryLock = TRUE;
  366. status = STATUS_SUCCESS;
  367. break;
  368. case IRP_MN_WAIT_WAKE:
  369. case IRP_MN_POWER_SEQUENCE:
  370. default:
  371. // status = STATUS_NOT_IMPLEMENTED;
  372. break;
  373. }
  374. Irp->IoStatus.Status = status;
  375. PoStartNextPowerIrp (Irp);
  376. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  377. return status;
  378. }