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.

442 lines
9.6 KiB

  1. /*++
  2. Copyright (c) 1990-2000 Microsoft Corporation
  3. Module Name:
  4. dispatch.c
  5. Abstract:
  6. This file contains the dispatch logic for ISAPNP
  7. Author:
  8. Shie-Lin Tzong (shielint)
  9. Environment:
  10. Kernel Mode Driver.
  11. --*/
  12. #include "busp.h"
  13. #include "pnpisa.h"
  14. #include <initguid.h>
  15. #include <wdmguid.h>
  16. #include "halpnpp.h"
  17. //
  18. // Prototype
  19. //
  20. VOID
  21. PipCompleteRequest(
  22. IN OUT PIRP Irp,
  23. IN NTSTATUS Status,
  24. IN PVOID Information
  25. );
  26. NTSTATUS
  27. PipPassIrp(
  28. PDEVICE_OBJECT pDeviceObject,
  29. PIRP pIrp
  30. );
  31. #ifdef ALLOC_PRAGMA
  32. #pragma alloc_text(PAGE, PiUnload)
  33. #pragma alloc_text(PAGE, PiDispatchPnp)
  34. #pragma alloc_text(PAGE, PiDispatchDevCtl)
  35. #pragma alloc_text(PAGE, PiDispatchCreate)
  36. #pragma alloc_text(PAGE, PiDispatchClose)
  37. #pragma alloc_text(PAGE, PiAddDevice)
  38. #pragma alloc_text(PAGE, PipPassIrp)
  39. #endif
  40. VOID
  41. PiUnload(
  42. IN PDRIVER_OBJECT DriverObject
  43. )
  44. /*++
  45. Routine Description:
  46. This routine checks if there is any pnpisa card in the machine. If non, it returns
  47. STATUS_NO_SUCH_DEVICE.
  48. Arguments:
  49. DriverObject - Pointer to our pseudo driver object.
  50. DeviceObject - Pointer to the device object for which this requestapplies.
  51. Return Value:
  52. NT status.
  53. --*/
  54. {
  55. PAGED_CODE();
  56. // We can not be unload.
  57. // ASSERT(0);
  58. }
  59. NTSTATUS
  60. PiAddDevice(
  61. IN PDRIVER_OBJECT DriverObject,
  62. IN PDEVICE_OBJECT DeviceObject
  63. )
  64. /*++
  65. Routine Description:
  66. This routine checks if there is any pnpisa card in the machine. If non, it returns
  67. STATUS_NO_SUCH_DEVICE.
  68. (Not any more, fix this)
  69. Arguments:
  70. DriverObject - Pointer to our pseudo driver object.
  71. DeviceObject - Pointer to the device object for which this requestapplies.
  72. Return Value:
  73. NT status.
  74. --*/
  75. {
  76. NTSTATUS status;
  77. PDEVICE_OBJECT busFdo;
  78. PPI_BUS_EXTENSION busExtension;
  79. UNICODE_STRING interfaceName;
  80. ULONG busNumber;
  81. PAGED_CODE();
  82. KeWaitForSingleObject( &IsaBusNumberLock,
  83. Executive,
  84. KernelMode,
  85. FALSE,
  86. NULL );
  87. ActiveIsaCount++;
  88. //
  89. // We are creating the first instance of the ISA bus.
  90. //
  91. RtlInitUnicodeString(&interfaceName, NULL);
  92. //
  93. // Create an FDO to attatch to the PDO
  94. //
  95. status = IoCreateDevice( DriverObject,
  96. sizeof(PI_BUS_EXTENSION), // Extension Size
  97. NULL, // DeviceName
  98. FILE_DEVICE_BUS_EXTENDER,
  99. FILE_DEVICE_SECURE_OPEN,
  100. FALSE,
  101. &busFdo);
  102. if (NT_SUCCESS(status)) {
  103. busExtension = (PPI_BUS_EXTENSION) busFdo->DeviceExtension;
  104. busExtension->Flags = DF_BUS;
  105. busExtension->FunctionalBusDevice = busFdo;
  106. busExtension->AttachedDevice = IoAttachDeviceToDeviceStack(busFdo, DeviceObject);
  107. busExtension->PhysicalBusDevice = DeviceObject;
  108. if (PiNeedDeferISABridge(DriverObject,DeviceObject)) {
  109. busNumber = RtlFindClearBitsAndSet (BusNumBM,1,1);
  110. ASSERT (busNumber != 0);
  111. } else {
  112. busNumber = RtlFindClearBitsAndSet (BusNumBM,1,0);
  113. }
  114. ASSERT (busNumber != 0xFFFFFFFF);
  115. if (ActiveIsaCount == 1) {
  116. if (PipFirstInit) {
  117. #if ISOLATE_CARDS
  118. PipResetGlobals();
  119. #endif
  120. }
  121. PipDriverObject = DriverObject;
  122. busExtension->ReadDataPort = NULL;
  123. ASSERT (PipBusExtension == NULL);
  124. //
  125. //bus extension can get touched in pipdeletedevice
  126. //
  127. PipBusExtension = (PBUS_EXTENSION_LIST)ExAllocatePool (NonPagedPool,sizeof (BUS_EXTENSION_LIST));
  128. if (!PipBusExtension) {
  129. return STATUS_INSUFFICIENT_RESOURCES;
  130. }
  131. PipBusExtension->BusExtension = busExtension;
  132. PipBusExtension->Next=NULL;
  133. PipFirstInit = TRUE;
  134. } else {
  135. PBUS_EXTENSION_LIST busList;
  136. ASSERT (PipDriverObject);
  137. busExtension->ReadDataPort = NULL;
  138. ASSERT (PipBusExtension);
  139. busList = PipBusExtension;
  140. while (busList->Next) {
  141. busList = (PBUS_EXTENSION_LIST)busList->Next;
  142. }
  143. busList->Next = (PBUS_EXTENSION_LIST)ExAllocatePool (NonPagedPool,sizeof (BUS_EXTENSION_LIST));
  144. if (!busList->Next) {
  145. return STATUS_INSUFFICIENT_RESOURCES;
  146. }
  147. busList=busList->Next;
  148. busList->BusExtension = busExtension;
  149. busList->Next=NULL;
  150. }
  151. busExtension->BusNumber = busNumber;
  152. busFdo->Flags &= ~DO_DEVICE_INITIALIZING;
  153. }
  154. KeSetEvent( &IsaBusNumberLock,
  155. 0,
  156. FALSE );
  157. return status;
  158. }
  159. NTSTATUS
  160. PiDispatchPnp(
  161. IN PDEVICE_OBJECT DeviceObject,
  162. IN OUT PIRP Irp
  163. )
  164. /*++
  165. Routine Description:
  166. This routine handles all IRP_MJ_PNP_POWER IRPs.
  167. Arguments:
  168. DeviceObject - Pointer to the device object for which this IRP applies.
  169. Irp - Pointer to the IRP_MJ_PNP_POWER IRP to dispatch.
  170. Return Value:
  171. NT status.
  172. --*/
  173. {
  174. PIO_STACK_LOCATION irpSp;
  175. NTSTATUS status;
  176. ULONG length;
  177. PVOID information = NULL;
  178. PWCHAR requestId, ids;
  179. PIO_RESOURCE_REQUIREMENTS_LIST ioResources;
  180. PCM_RESOURCE_LIST cmResources;
  181. PDEVICE_INFORMATION deviceInfo;
  182. PDEVICE_CAPABILITIES deviceCapabilities;
  183. PPNP_BUS_INFORMATION busInfo;
  184. PPI_BUS_EXTENSION busExtension;
  185. PDEVICE_INFORMATION deviceExtension = NULL;
  186. UNICODE_STRING unicodeString;
  187. PAGED_CODE();
  188. //
  189. // Get a pointer to our stack location and take appropriate action based
  190. // on the minor function.
  191. //
  192. irpSp = IoGetCurrentIrpStackLocation(Irp);
  193. busExtension = DeviceObject->DeviceExtension;
  194. if (busExtension->Flags & DF_BUS) {
  195. if (busExtension->AttachedDevice == NULL) {
  196. status = STATUS_NO_SUCH_DEVICE;
  197. PipCompleteRequest(Irp, status, information);
  198. goto exit;
  199. }
  200. } else {
  201. busExtension = NULL;
  202. deviceExtension = DeviceObject->DeviceExtension;
  203. if (deviceExtension->Flags & DF_DELETED) {
  204. if (irpSp->MinorFunction == IRP_MN_REMOVE_DEVICE) {
  205. status = STATUS_SUCCESS;
  206. } else {
  207. status = STATUS_NO_SUCH_DEVICE;
  208. }
  209. PipCompleteRequest(Irp, status, information);
  210. goto exit;
  211. }
  212. }
  213. //
  214. // Dispatch IRPs bound for the FDO
  215. //
  216. if (busExtension) {
  217. status = PiDispatchPnpFdo(
  218. DeviceObject,
  219. Irp
  220. );
  221. //return status;
  222. } else {
  223. #if ISOLATE_CARDS
  224. //
  225. // Dispatch IRPs bound for the PDO
  226. //
  227. status = PiDispatchPnpPdo(
  228. DeviceObject,
  229. Irp
  230. );
  231. //return status;
  232. #endif
  233. }
  234. exit:
  235. //
  236. // Complete the Irp and return.
  237. //
  238. // PipCompleteRequest(Irp, status, information);
  239. return status;
  240. } // PiDispatchPnp
  241. VOID
  242. PipCompleteRequest(
  243. IN OUT PIRP Irp,
  244. IN NTSTATUS Status,
  245. IN PVOID Information
  246. )
  247. /*++
  248. Routine Description:
  249. This routine completes PnP irps for our pseudo driver.
  250. Arguments:
  251. Irp - Supplies a pointer to the irp to be completed.
  252. Status - completion status.
  253. Information - completion information to be passed back.
  254. Return Value:
  255. None.
  256. --*/
  257. {
  258. //
  259. // Complete the IRP. First update the status...
  260. //
  261. Irp->IoStatus.Status = Status;
  262. Irp->IoStatus.Information = (ULONG_PTR)Information;
  263. //
  264. // ... and complete it.
  265. //
  266. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  267. }
  268. NTSTATUS
  269. PipPassIrp(
  270. PDEVICE_OBJECT DeviceObject,
  271. PIRP Irp
  272. )
  273. /*++
  274. Description:
  275. This function pass the Irp to lower level driver.
  276. Arguments:
  277. DeviceObject - the Fdo or Pdo
  278. Irp - the request
  279. Return:
  280. STATUS_PENDING
  281. --*/
  282. {
  283. PIO_STACK_LOCATION ioStackLocation; // our stack location
  284. PIO_STACK_LOCATION nextIoStackLocation; // next guy's
  285. PPI_BUS_EXTENSION busExtension = (PPI_BUS_EXTENSION) DeviceObject->DeviceExtension;
  286. IoSkipCurrentIrpStackLocation(Irp);
  287. //
  288. // Io call next driver, we pass it to root hub's parent no matter which tier we are at.
  289. //
  290. return IoCallDriver( busExtension->AttachedDevice, Irp );
  291. }
  292. NTSTATUS
  293. PiDispatchDevCtl(
  294. IN PDEVICE_OBJECT DeviceObject,
  295. IN OUT PIRP Irp
  296. )
  297. /*++
  298. Description:
  299. This function passes the Device Control Irp to lower level driver.
  300. Arguments:
  301. DeviceObject - the Fdo or Pdo
  302. Irp - the request
  303. Return:
  304. STATUS_PENDING
  305. --*/
  306. {
  307. PPI_BUS_EXTENSION busExtension = (PPI_BUS_EXTENSION) DeviceObject->DeviceExtension;
  308. NTSTATUS status;
  309. PAGED_CODE();
  310. if (busExtension->Flags & DF_BUS) {
  311. IoSkipCurrentIrpStackLocation (Irp);
  312. return IoCallDriver( busExtension->AttachedDevice, Irp );
  313. } else {
  314. //
  315. //We're at the bottom
  316. //
  317. status = Irp->IoStatus.Status;
  318. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  319. return status;
  320. }
  321. }