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.

496 lines
11 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation and Litronic, 1998 - 1999
  6. //
  7. // File: l220powr.c
  8. //
  9. //--------------------------------------------------------------------------
  10. //////////////////////////////////////////////////////////
  11. //
  12. // Power Management
  13. //
  14. //////////////////////////////////////////////////////////
  15. NTSTATUS
  16. Lit220DispatchPower (
  17. IN PDEVICE_OBJECT DeviceObject,
  18. IN PIRP Irp
  19. )
  20. /*++
  21. Routine Description:
  22. The power dispatch routine.
  23. As this is a POWER irp, and therefore a special irp, special power irp
  24. handling is required.
  25. Arguments:
  26. DeviceObject - pointer to a device object.
  27. Irp - pointer to an I/O Request Packet.
  28. Return Value:
  29. NT status code
  30. --*/
  31. {
  32. PIO_STACK_LOCATION stack;
  33. PSMARTCARD_EXTENSION SmartcardExtension = DeviceObject->DeviceExtension;
  34. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  35. NTSTATUS status;
  36. LONG requestCount;
  37. stack = IoGetCurrentIrpStackLocation(Irp);
  38. //
  39. // This IRP was sent to the function driver.
  40. // The behavior is similar with the one of SD_Pass
  41. //
  42. //
  43. // This IRP was sent to the function driver.
  44. // We don't queue power Irps, we'll only check if the
  45. // device was removed, otherwise we'll send it to the next lower
  46. // driver.
  47. //
  48. SmartcardDebug(
  49. DEBUG_TRACE,
  50. ("%s!Lit220DispatchPower: Enter - MinorFunction %X\n",
  51. DRIVER_NAME,
  52. stack->MinorFunction)
  53. );
  54. // Increment the IRP Count
  55. status = Lit220IncIoCount(ReaderExtension);
  56. if (ReaderExtension->IsRemoved) {
  57. status = STATUS_DELETE_PENDING;
  58. PoStartNextPowerIrp (Irp);
  59. Irp->IoStatus.Information = 0;
  60. Irp->IoStatus.Status = status;
  61. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  62. } else {
  63. //
  64. // We always need to start the next power irp with PoStartNextPowerIrp
  65. //
  66. switch (stack->MinorFunction) {
  67. case IRP_MN_WAIT_WAKE :
  68. SmartcardDebug(
  69. DEBUG_DRIVER,
  70. ("%s!Lit220DispatchPower: IRP_MN_WAIT_WAKE\n",
  71. DRIVER_NAME)
  72. );
  73. status = Lit220PassDownToNextPowerDriver(
  74. DeviceObject,
  75. Irp
  76. );
  77. break;
  78. case IRP_MN_POWER_SEQUENCE :
  79. SmartcardDebug(
  80. DEBUG_DRIVER,
  81. ("%s!Lit220DispatchPower: IRP_MN_POWER_SEQUENCE\n",
  82. DRIVER_NAME)
  83. );
  84. status = Lit220PassDownToNextPowerDriver(
  85. DeviceObject,
  86. Irp
  87. );
  88. break;
  89. case IRP_MN_QUERY_POWER :
  90. SmartcardDebug(
  91. DEBUG_DRIVER,
  92. ("%s!Lit220DispatchPower: IRP_MN_QUERY_POWER\n",
  93. DRIVER_NAME)
  94. );
  95. status = Lit220QueryPowerState(
  96. DeviceObject,
  97. Irp
  98. );
  99. break;
  100. case IRP_MN_SET_POWER :
  101. SmartcardDebug(
  102. DEBUG_DRIVER,
  103. ("%s!Lit220DispatchPower: IRP_MN_SET_POWER\n",
  104. DRIVER_NAME)
  105. );
  106. status = Lit220SetPowerState(
  107. DeviceObject,
  108. Irp
  109. );
  110. break;
  111. default:
  112. //
  113. // Pass it down
  114. //
  115. SmartcardDebug(
  116. DEBUG_DRIVER,
  117. ("%s!Lit220DispatchPower: IRP_MN_0x%x\n",
  118. DRIVER_NAME,
  119. stack->MinorFunction)
  120. );
  121. status = Lit220PassDownToNextPowerDriver(
  122. DeviceObject,
  123. Irp
  124. );
  125. break;
  126. }
  127. }
  128. return status;
  129. }
  130. NTSTATUS
  131. Lit220PassDownToNextPowerDriver (
  132. IN PDEVICE_OBJECT DeviceObject,
  133. IN OUT PIRP Irp
  134. )
  135. /*++
  136. Routine Description:
  137. Passes the Irp to the next device in the attchement chain
  138. Arguments:
  139. DeviceObject - pointer to a device object.
  140. Irp - pointer to an I/O Request Packet.
  141. Return Value:
  142. NT status code
  143. --*/
  144. {
  145. NTSTATUS status;
  146. PSMARTCARD_EXTENSION SmartcardExtension = DeviceObject->DeviceExtension;
  147. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  148. IoCopyCurrentIrpStackLocationToNext(Irp);
  149. PoStartNextPowerIrp(Irp);
  150. status = PoCallDriver(
  151. ReaderExtension->BusDeviceObject,
  152. Irp
  153. );
  154. if (!NT_SUCCESS(status)) {
  155. SmartcardDebug(
  156. DEBUG_DRIVER,
  157. ("%s!Lit220PassDownToNextPowerDriver : Lower driver fails a power irp\n",
  158. DRIVER_NAME)
  159. );
  160. }
  161. return status;
  162. }
  163. NTSTATUS
  164. Lit220QueryPowerState (
  165. IN PDEVICE_OBJECT DeviceObject,
  166. IN OUT PIRP Irp
  167. )
  168. /*++
  169. Routine Description:
  170. Completes the power Irp with STATUS_SUCCESS
  171. Arguments:
  172. DeviceObject - pointer to a device object.
  173. Irp - pointer to an I/O Request Packet.
  174. Return Value:
  175. NT status code
  176. --*/
  177. {
  178. Irp->IoStatus.Status = STATUS_SUCCESS;
  179. PoStartNextPowerIrp(Irp);
  180. IoCompleteRequest(
  181. Irp,
  182. IO_NO_INCREMENT
  183. );
  184. //
  185. // Do not send this Irp down.
  186. //
  187. return STATUS_SUCCESS;
  188. }
  189. NTSTATUS
  190. Lit220SetPowerState (
  191. IN PDEVICE_OBJECT DeviceObject,
  192. IN OUT PIRP Irp
  193. )
  194. /*++
  195. Routine Description:
  196. Processes IRP_MN_SET_POWER.
  197. Arguments:
  198. DeviceObject - pointer to a device object.
  199. Irp - pointer to an I/O Request Packet.
  200. Return Value:
  201. NT status code
  202. --*/
  203. {
  204. NTSTATUS status = STATUS_SUCCESS;
  205. PSMARTCARD_EXTENSION SmartcardExtension = DeviceObject->DeviceExtension;
  206. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  207. PIO_STACK_LOCATION stack;
  208. PFDO_POWER_CONTEXT context;
  209. BOOLEAN passItDown;
  210. stack = IoGetCurrentIrpStackLocation (Irp);
  211. SmartcardDebug(
  212. DEBUG_DRIVER,
  213. ("%s!Lit220SetPowerState: Type %X, State %X\n",
  214. DRIVER_NAME,
  215. stack->Parameters.Power.Type,
  216. stack->Parameters.Power.State.SystemState)
  217. );
  218. context = ExAllocatePool(
  219. NonPagedPool,
  220. sizeof(FDO_POWER_CONTEXT)
  221. );
  222. if (context == NULL) {
  223. status = STATUS_NO_MEMORY;
  224. } else {
  225. RtlZeroMemory(
  226. context,
  227. sizeof(FDO_POWER_CONTEXT)
  228. );
  229. stack = IoGetCurrentIrpStackLocation (Irp);
  230. context->newPowerType = stack->Parameters.Power.Type;
  231. context->newPowerState = stack->Parameters.Power.State;
  232. passItDown = TRUE;
  233. if (stack->Parameters.Power.Type == SystemPowerState) {
  234. if (ReaderExtension->SystemPowerState ==
  235. stack->Parameters.Power.State.SystemState)
  236. {
  237. //
  238. // We are already in the given system state
  239. //
  240. passItDown = FALSE;
  241. }
  242. } else if (stack->Parameters.Power.Type == DevicePowerState) {
  243. if (ReaderExtension->DevicePowerState !=
  244. stack->Parameters.Power.State.DeviceState)
  245. {
  246. if (ReaderExtension->DevicePowerState == PowerDeviceD0) {
  247. //
  248. // getting out of D0 state, better call PoSetPowerState now
  249. //
  250. PoSetPowerState (
  251. DeviceObject,
  252. DevicePowerState,
  253. stack->Parameters.Power.State
  254. );
  255. }
  256. } else {
  257. //
  258. // We are already in the given device state
  259. //
  260. passItDown = FALSE;
  261. }
  262. } else {
  263. ASSERT (FALSE);
  264. status = STATUS_NOT_IMPLEMENTED;
  265. }
  266. }
  267. if (NT_SUCCESS(status) && passItDown) {
  268. IoCopyCurrentIrpStackLocationToNext (Irp);
  269. IoSetCompletionRoutine(Irp,
  270. Lit220PowerCompletionRoutine,
  271. context,
  272. TRUE,
  273. TRUE,
  274. TRUE);
  275. return PoCallDriver(
  276. ReaderExtension->BusDeviceObject,
  277. Irp
  278. );
  279. } else {
  280. Irp->IoStatus.Information = 0;
  281. Irp->IoStatus.Status = status;
  282. PoStartNextPowerIrp (Irp);
  283. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  284. //
  285. // Free the memory now
  286. //
  287. if (context) {
  288. ExFreePool (context);
  289. }
  290. return status;
  291. }
  292. }
  293. NTSTATUS
  294. Lit220PowerCompletionRoutine (
  295. IN PDEVICE_OBJECT DeviceObject,
  296. IN PIRP Irp,
  297. IN PVOID Context
  298. )
  299. /*++
  300. Routine Description:
  301. The completion routine for IRP_MN_SET_POWER.
  302. Arguments:
  303. DeviceObject - pointer to a device object.
  304. Irp - pointer to an I/O Request Packet.
  305. Context - a pointer to a structure that contains the new power type and
  306. new power state.
  307. Return Value:
  308. NT status code
  309. --*/
  310. {
  311. PFDO_POWER_CONTEXT context = Context;
  312. BOOLEAN callPoSetPowerState;
  313. PSMARTCARD_EXTENSION SmartcardExtension = DeviceObject->DeviceExtension;
  314. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  315. if (NT_SUCCESS(Irp->IoStatus.Status)) {
  316. callPoSetPowerState = TRUE;
  317. if (context->newPowerType == SystemPowerState) {
  318. ReaderExtension->SystemPowerState = context->newPowerState.SystemState;
  319. } else if (context->newPowerType == DevicePowerState) {
  320. if (ReaderExtension->DevicePowerState == PowerDeviceD0) {
  321. //
  322. // PoSetPowerState is called before we get out of D0
  323. //
  324. callPoSetPowerState = FALSE;
  325. }
  326. //TODO: Send Power command to device
  327. //Also, Not sure if we should do this yet it is
  328. // still TBD
  329. ReaderExtension->DevicePowerState = context->newPowerState.DeviceState;
  330. }
  331. if (callPoSetPowerState) {
  332. PoSetPowerState (
  333. DeviceObject,
  334. context->newPowerType,
  335. context->newPowerState
  336. );
  337. }
  338. }
  339. PoStartNextPowerIrp (Irp);
  340. //
  341. // We can happily free the heap here
  342. //
  343. ExFreePool(context);
  344. return Irp->IoStatus.Status;
  345. }