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.

382 lines
11 KiB

  1. /*++
  2. Copyright (c) 2002 Microsoft Corporation
  3. Module Name:
  4. dispatch.c
  5. Abstract:
  6. This module contains the global dispatch related
  7. routines for the sd controller & it's child devices
  8. Author:
  9. Neil Sandlin (neilsa) Jan 1 2002
  10. Environment:
  11. Kernel mode
  12. Revision History :
  13. --*/
  14. #include "pch.h"
  15. NTSTATUS
  16. SdbusDispatch(
  17. IN PDEVICE_OBJECT DeviceObject,
  18. IN PIRP Irp
  19. );
  20. NTSTATUS
  21. SdbusFdoPowerDispatch(
  22. IN PDEVICE_OBJECT Fdo,
  23. IN PIRP Irp
  24. );
  25. NTSTATUS
  26. SdbusPdoPowerDispatch(
  27. IN PDEVICE_OBJECT Pdo,
  28. IN PIRP Irp
  29. );
  30. #ifdef ALLOC_PRAGMA
  31. #pragma alloc_text(PAGE, SdbusInitDeviceDispatchTable)
  32. #endif
  33. //
  34. // Dispatch table array for FDOs/PDOs
  35. //
  36. PDRIVER_DISPATCH DeviceObjectDispatch[sizeof(DEVICE_OBJECT_TYPE)][IRP_MJ_MAXIMUM_FUNCTION + 1];
  37. VOID
  38. SdbusInitDeviceDispatchTable(
  39. IN PDRIVER_OBJECT DriverObject
  40. )
  41. /*++
  42. Routine Description:
  43. Initializes the IRP dispatch tables for Pdo's & Fdo's
  44. Arguments:
  45. None
  46. Return value:
  47. None
  48. --*/
  49. {
  50. ULONG i;
  51. PAGED_CODE();
  52. //
  53. // Init the controller (FDO) dispatch table
  54. //
  55. DeviceObjectDispatch[FDO][IRP_MJ_CREATE] = SdbusOpenCloseDispatch;
  56. DeviceObjectDispatch[FDO][IRP_MJ_CLOSE] = SdbusOpenCloseDispatch;
  57. DeviceObjectDispatch[FDO][IRP_MJ_CLEANUP] = SdbusCleanupDispatch;
  58. DeviceObjectDispatch[FDO][IRP_MJ_DEVICE_CONTROL] = SdbusFdoDeviceControl;
  59. DeviceObjectDispatch[FDO][IRP_MJ_SYSTEM_CONTROL] = SdbusFdoSystemControl;
  60. DeviceObjectDispatch[FDO][IRP_MJ_PNP] = SdbusFdoPnpDispatch;
  61. DeviceObjectDispatch[FDO][IRP_MJ_POWER] = SdbusFdoPowerDispatch;
  62. //
  63. // Init the PDO dispatch table
  64. //
  65. DeviceObjectDispatch[PDO][IRP_MJ_DEVICE_CONTROL] = SdbusPdoDeviceControl;
  66. DeviceObjectDispatch[PDO][IRP_MJ_INTERNAL_DEVICE_CONTROL] = SdbusPdoInternalDeviceControl;
  67. DeviceObjectDispatch[PDO][IRP_MJ_SYSTEM_CONTROL] = SdbusPdoSystemControl;
  68. DeviceObjectDispatch[PDO][IRP_MJ_PNP] = SdbusPdoPnpDispatch;
  69. DeviceObjectDispatch[PDO][IRP_MJ_POWER] = SdbusPdoPowerDispatch;
  70. //
  71. // Set the global dispatch table
  72. DriverObject->MajorFunction[IRP_MJ_CREATE] = SdbusDispatch;
  73. DriverObject->MajorFunction[IRP_MJ_CLOSE] = SdbusDispatch;
  74. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = SdbusDispatch;
  75. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SdbusDispatch;
  76. DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = SdbusDispatch;
  77. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = SdbusDispatch;
  78. DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = SdbusDispatch;
  79. DriverObject->MajorFunction[IRP_MJ_PNP] = SdbusDispatch;
  80. DriverObject->MajorFunction[IRP_MJ_POWER] = SdbusDispatch;
  81. }
  82. NTSTATUS
  83. SdbusDispatch(
  84. IN PDEVICE_OBJECT DeviceObject,
  85. IN PIRP Irp
  86. )
  87. /*++
  88. Routine Description:
  89. Dispatch routine for all IRPs handled by this driver. This dispatch would then
  90. call the appropriate real dispatch routine which corresponds to the device object
  91. type (physical or functional).
  92. Arguments:
  93. DeviceObject - Pointer to the device object this dispatch is intended for
  94. Irp - Pointer to the IRP to be handled
  95. Return value:
  96. Returns the status from the 'real' dispatch routine which handles this IRP
  97. --*/
  98. {
  99. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  100. NTSTATUS status;
  101. DEVICE_OBJECT_TYPE devtype = IS_PDO(DeviceObject) ? PDO : FDO;
  102. UCHAR MajorFunction = irpStack->MajorFunction;
  103. if ((MajorFunction > IRP_MJ_MAXIMUM_FUNCTION) ||
  104. (DeviceObjectDispatch[devtype][MajorFunction] == NULL)) {
  105. DebugPrint((SDBUS_DEBUG_INFO, "SDBUS: Dispatch skipping unimplemented Irp MJ function %x\n", MajorFunction));
  106. status = Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  107. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  108. } else if (((devtype == PDO) && IsDeviceDeleted((PPDO_EXTENSION)DeviceObject->DeviceExtension)) ||
  109. ((devtype == FDO) && IsDeviceDeleted((PFDO_EXTENSION)DeviceObject->DeviceExtension))) {
  110. //
  111. // This do was supposed to have been already deleted
  112. // so we don't support any IRPs on it
  113. //
  114. DebugPrint((SDBUS_DEBUG_INFO, "SDBUS: Dispatch skipping Irp on deleted DO %08x MJ function %x\n", DeviceObject, MajorFunction));
  115. if (MajorFunction == IRP_MJ_POWER) {
  116. PoStartNextPowerIrp(Irp);
  117. }
  118. status = Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  119. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  120. } else {
  121. //
  122. // Dispatch the irp
  123. //
  124. status = ((*DeviceObjectDispatch[devtype][MajorFunction])(DeviceObject, Irp));
  125. }
  126. return status;
  127. }
  128. NTSTATUS
  129. SdbusFdoPowerDispatch(
  130. IN PDEVICE_OBJECT Fdo,
  131. IN PIRP Irp
  132. )
  133. /*++
  134. Routine Description:
  135. This routine handles power requests
  136. for the PDOs.
  137. Arguments:
  138. Pdo - pointer to the physical device object
  139. Irp - pointer to the io request packet
  140. Return Value:
  141. status
  142. --*/
  143. {
  144. PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
  145. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  146. NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
  147. switch (irpStack->MinorFunction) {
  148. case IRP_MN_SET_POWER:
  149. DebugPrint((SDBUS_DEBUG_POWER, "fdo %08x irp %08x --> IRP_MN_SET_POWER\n", Fdo, Irp));
  150. DebugPrint((SDBUS_DEBUG_POWER, " (%s%x context %x)\n",
  151. (irpStack->Parameters.Power.Type == SystemPowerState) ?
  152. "S":
  153. ((irpStack->Parameters.Power.Type == DevicePowerState) ?
  154. "D" :
  155. "Unknown"),
  156. irpStack->Parameters.Power.State,
  157. irpStack->Parameters.Power.SystemContext
  158. ));
  159. status = SdbusSetFdoPowerState(Fdo, Irp);
  160. break;
  161. case IRP_MN_QUERY_POWER:
  162. DebugPrint((SDBUS_DEBUG_POWER, "fdo %08x irp %08x --> IRP_MN_QUERY_POWER\n", Fdo, Irp));
  163. DebugPrint((SDBUS_DEBUG_POWER, " (%s%x context %x)\n",
  164. (irpStack->Parameters.Power.Type == SystemPowerState) ?
  165. "S":
  166. ((irpStack->Parameters.Power.Type == DevicePowerState) ?
  167. "D" :
  168. "Unknown"),
  169. irpStack->Parameters.Power.State,
  170. irpStack->Parameters.Power.SystemContext
  171. ));
  172. //
  173. // Let the pdo handle it
  174. //
  175. PoStartNextPowerIrp(Irp);
  176. IoSkipCurrentIrpStackLocation(Irp);
  177. status = PoCallDriver(fdoExtension->LowerDevice, Irp);
  178. break;
  179. case IRP_MN_WAIT_WAKE:
  180. DebugPrint((SDBUS_DEBUG_POWER, "fdo %08x irp %08x --> IRP_MN_WAIT_WAKE\n", Fdo, Irp));
  181. status = SdbusFdoWaitWake(Fdo, Irp);
  182. break;
  183. default:
  184. DebugPrint((SDBUS_DEBUG_POWER, "FdoPowerDispatch: Unhandled Irp %x received for 0x%08x\n",
  185. Irp,
  186. Fdo));
  187. PoStartNextPowerIrp(Irp);
  188. IoSkipCurrentIrpStackLocation(Irp);
  189. status = PoCallDriver(fdoExtension->LowerDevice, Irp);
  190. break;
  191. }
  192. DebugPrint((SDBUS_DEBUG_POWER, "fdo %08x irp %08x <-- %08x\n", Fdo, Irp, status));
  193. return status;
  194. }
  195. NTSTATUS
  196. SdbusPdoPowerDispatch(
  197. IN PDEVICE_OBJECT Pdo,
  198. IN PIRP Irp
  199. )
  200. /*++
  201. Routine Description:
  202. This routine handles power requests
  203. for the PDOs.
  204. Arguments:
  205. Pdo - pointer to the physical device object
  206. Irp - pointer to the io request packet
  207. Return Value:
  208. status
  209. --*/
  210. {
  211. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  212. NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
  213. PPDO_EXTENSION pdoExtension = Pdo->DeviceExtension;
  214. if(IsDevicePhysicallyRemoved(pdoExtension) || IsDeviceDeleted(pdoExtension)) {
  215. // couldn't aquire RemoveLock - we're in the process of being removed - abort
  216. status = STATUS_NO_SUCH_DEVICE;
  217. PoStartNextPowerIrp( Irp );
  218. Irp->IoStatus.Status = status;
  219. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  220. return status;
  221. }
  222. InterlockedIncrement(&pdoExtension->DeletionLock);
  223. switch (irpStack->MinorFunction) {
  224. case IRP_MN_SET_POWER:
  225. DebugPrint((SDBUS_DEBUG_POWER, "pdo %08x irp %08x --> IRP_MN_SET_POWER\n", Pdo, Irp));
  226. DebugPrint((SDBUS_DEBUG_POWER, " (%s%x, context %x)\n",
  227. (irpStack->Parameters.Power.Type == SystemPowerState) ?
  228. "S":
  229. ((irpStack->Parameters.Power.Type == DevicePowerState) ?
  230. "D" :
  231. "Unknown"),
  232. irpStack->Parameters.Power.State,
  233. irpStack->Parameters.Power.SystemContext
  234. ));
  235. status = SdbusSetPdoPowerState(Pdo, Irp);
  236. break;
  237. case IRP_MN_QUERY_POWER:
  238. DebugPrint((SDBUS_DEBUG_POWER, "pdo %08x irp %08x --> IRP_MN_QUERY_POWER\n", Pdo, Irp));
  239. DebugPrint((SDBUS_DEBUG_POWER, " (%s%x, context %x)\n",
  240. (irpStack->Parameters.Power.Type == SystemPowerState) ?
  241. "S":
  242. ((irpStack->Parameters.Power.Type == DevicePowerState) ?
  243. "D" :
  244. "Unknown"),
  245. irpStack->Parameters.Power.State,
  246. irpStack->Parameters.Power.SystemContext
  247. ));
  248. InterlockedDecrement(&pdoExtension->DeletionLock);
  249. status = Irp->IoStatus.Status = STATUS_SUCCESS;
  250. PoStartNextPowerIrp(Irp);
  251. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  252. break;
  253. case IRP_MN_WAIT_WAKE: {
  254. BOOLEAN completeIrp;
  255. DebugPrint((SDBUS_DEBUG_POWER, "pdo %08x irp %08x --> IRP_MN_WAIT_WAKE\n", Pdo, Irp));
  256. //
  257. // Should not have a wake pending already
  258. //
  259. ASSERT (!(((PPDO_EXTENSION)Pdo->DeviceExtension)->Flags & SDBUS_DEVICE_WAKE_PENDING));
  260. status = SdbusPdoWaitWake(Pdo, Irp, &completeIrp);
  261. if (completeIrp) {
  262. InterlockedDecrement(&pdoExtension->DeletionLock);
  263. PoStartNextPowerIrp(Irp);
  264. Irp->IoStatus.Status = status;
  265. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  266. }
  267. break;
  268. }
  269. default:
  270. //
  271. // Unhandled minor function
  272. //
  273. InterlockedDecrement(&pdoExtension->DeletionLock);
  274. status = Irp->IoStatus.Status;
  275. PoStartNextPowerIrp(Irp);
  276. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  277. }
  278. DebugPrint((SDBUS_DEBUG_POWER, "pdo %08x irp %08x <-- %08x\n", Pdo, Irp, status));
  279. return status;
  280. }