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.

1004 lines
29 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. dispatch.c
  5. Abstract:
  6. IRP dispatching routines for the common AGPLIB library
  7. Author:
  8. John Vert (jvert) 10/25/1997
  9. Revision History:
  10. Elliot Shmukler (elliots) 3/24/1999 - Added support for "favored" memory
  11. ranges for AGP physical memory allocation,
  12. fixed some bugs.
  13. --*/
  14. #include "agplib.h"
  15. //
  16. // Two flavors of each dispatch routine, one for the target (AGP bridge) filter and
  17. // one for the master (video card) filter.
  18. //
  19. NTSTATUS
  20. AgpTargetDispatchPnp(
  21. IN PDEVICE_OBJECT DeviceObject,
  22. IN OUT PIRP Irp,
  23. IN PTARGET_EXTENSION Extension
  24. );
  25. NTSTATUS
  26. AgpMasterDispatchPnp(
  27. IN PDEVICE_OBJECT DeviceObject,
  28. IN OUT PIRP Irp,
  29. IN PMASTER_EXTENSION Extension
  30. );
  31. NTSTATUS
  32. AgpTargetDispatchPower(
  33. IN PDEVICE_OBJECT DeviceObject,
  34. IN OUT PIRP Irp,
  35. IN PTARGET_EXTENSION Extension
  36. );
  37. NTSTATUS
  38. AgpMasterDispatchPower(
  39. IN PDEVICE_OBJECT DeviceObject,
  40. IN OUT PIRP Irp,
  41. IN PMASTER_EXTENSION Extension
  42. );
  43. NTSTATUS
  44. AgpCancelMasterRemove(
  45. IN PDEVICE_OBJECT DeviceObject,
  46. IN PIRP Irp,
  47. IN PMASTER_EXTENSION Extension
  48. );
  49. NTSTATUS
  50. AgpMasterPowerUpCompletion(
  51. IN PDEVICE_OBJECT DeviceObject,
  52. IN PIRP Irp,
  53. IN PMASTER_EXTENSION Extension
  54. );
  55. NTSTATUS
  56. AgpTargetPowerUpCompletion(
  57. IN PDEVICE_OBJECT DeviceObject,
  58. IN PIRP Irp,
  59. IN PTARGET_EXTENSION Extension
  60. );
  61. #ifdef ALLOC_PRAGMA
  62. #pragma alloc_text(PAGE, AgpDispatchPnp)
  63. #pragma alloc_text(PAGE, AgpDispatchDeviceControl)
  64. #pragma alloc_text(PAGE, AgpDispatchWmi)
  65. #pragma alloc_text(PAGE, AgpTargetDispatchPnp)
  66. #pragma alloc_text(PAGE, AgpMasterDispatchPnp)
  67. #pragma alloc_text(PAGE, AgpCancelMasterRemove)
  68. #endif
  69. NTSTATUS
  70. AgpDispatchPnp(
  71. IN PDEVICE_OBJECT DeviceObject,
  72. IN OUT PIRP Irp
  73. )
  74. /*++
  75. Routine Description:
  76. Main dispatch routine for PNP irps sent to the AGP bus filter driver
  77. Arguments:
  78. DeviceObject - Supplies the AGP device object
  79. Irp - Supplies the PNP Irp.
  80. Return Value:
  81. NTSTATUS
  82. --*/
  83. {
  84. PCOMMON_EXTENSION Extension = DeviceObject->DeviceExtension;
  85. PAGED_CODE();
  86. //
  87. // We're deleted, fail the irp
  88. //
  89. if (Extension->Deleted == TRUE) {
  90. Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  91. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  92. return STATUS_DELETE_PENDING;
  93. }
  94. ASSERT(Extension->AttachedDevice != NULL);
  95. if (Extension->Type == AgpTargetFilter) {
  96. return(AgpTargetDispatchPnp(DeviceObject,
  97. Irp,
  98. DeviceObject->DeviceExtension));
  99. } else {
  100. ASSERT(Extension->Type == AgpMasterFilter);
  101. return(AgpMasterDispatchPnp(DeviceObject,
  102. Irp,
  103. DeviceObject->DeviceExtension));
  104. }
  105. }
  106. NTSTATUS
  107. AgpDispatchPower(
  108. IN PDEVICE_OBJECT DeviceObject,
  109. IN OUT PIRP Irp
  110. )
  111. /*++
  112. Routine Description:
  113. Main dispatch routine for power irps sent to the AGP bus filter driver
  114. Arguments:
  115. DeviceObject - Supplies the AGP device object
  116. Irp - Supplies the power Irp.
  117. Return Value:
  118. NTSTATUS
  119. --*/
  120. {
  121. PCOMMON_EXTENSION Extension = DeviceObject->DeviceExtension;
  122. //
  123. // We're deleted, fail the irp
  124. //
  125. if (Extension->Deleted == TRUE) {
  126. Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  127. PoStartNextPowerIrp(Irp);
  128. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  129. return STATUS_DELETE_PENDING;
  130. }
  131. ASSERT(Extension->AttachedDevice != NULL);
  132. if (Extension->Type == AgpTargetFilter) {
  133. return(AgpTargetDispatchPower(DeviceObject,
  134. Irp,
  135. DeviceObject->DeviceExtension));
  136. } else {
  137. ASSERT(Extension->Type == AgpMasterFilter);
  138. return(AgpMasterDispatchPower(DeviceObject,
  139. Irp,
  140. DeviceObject->DeviceExtension));
  141. }
  142. }
  143. NTSTATUS
  144. AgpTargetDispatchPnp(
  145. IN PDEVICE_OBJECT DeviceObject,
  146. IN OUT PIRP Irp,
  147. IN PTARGET_EXTENSION Extension
  148. )
  149. /*++
  150. Routine Description:
  151. Dispatch routine for PNP irps sent to the AGP bus filter driver
  152. attached to the target (AGP bridge) PDO.
  153. Arguments:
  154. DeviceObject - Supplies the AGP target device object
  155. Irp - Supplies the PNP Irp.
  156. Extension - Supplies the AGP target device extension
  157. Return Value:
  158. NTSTATUS
  159. --*/
  160. {
  161. NTSTATUS Status = STATUS_NOT_SUPPORTED;
  162. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  163. PAGED_CODE();
  164. AGPLOG(AGP_IRPTRACE,
  165. ("AgpTargetDispatchPnp: IRP 0x%x\n", irpStack->MinorFunction));
  166. switch (irpStack->MinorFunction) {
  167. case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
  168. AGPLOG(AGP_NOISE,
  169. ("AgpTargetDispatchPnp: IRP_MN_FILTER_RESOURCE_REQUIREMENTS to %08lx\n",
  170. DeviceObject));
  171. Status = AgpFilterResourceRequirements(DeviceObject, Irp, Extension);
  172. break;
  173. case IRP_MN_QUERY_RESOURCES:
  174. AGPLOG(AGP_NOISE,
  175. ("AgpTargetDispatchPnp: IRP_MN_QUERY_RESOURCES to %08lx\n",
  176. DeviceObject));
  177. //
  178. // We must handle this IRP on the way back so we can add the AGP
  179. // resources on to it. Set a completion routine.
  180. //
  181. IoCopyCurrentIrpStackLocationToNext(Irp);
  182. IoSetCompletionRoutine(Irp,
  183. AgpQueryResources,
  184. Extension,
  185. TRUE,
  186. FALSE,
  187. FALSE);
  188. Status = IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);
  189. return Status ;
  190. case IRP_MN_QUERY_DEVICE_RELATIONS:
  191. if (irpStack->Parameters.QueryDeviceRelations.Type == BusRelations) {
  192. KEVENT event;
  193. KeInitializeEvent(&event, NotificationEvent, FALSE);
  194. //
  195. // We must handle this IRP on the way back so that we can attach
  196. // a filter to any child PDOs of our PCI-PCI bridge.
  197. //
  198. IoCopyCurrentIrpStackLocationToNext(Irp);
  199. IoSetCompletionRoutine(Irp,
  200. AgpSetEventCompletion,
  201. &event,
  202. TRUE,
  203. TRUE,
  204. TRUE);
  205. Status = IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);
  206. //
  207. // If we did things asynchronously then wait on our event
  208. //
  209. if (Status == STATUS_PENDING) {
  210. //
  211. // We do a KernelMode wait so that our stack where the
  212. // event is doesn't get paged out!
  213. //
  214. KeWaitForSingleObject(&event,
  215. Executive,
  216. KernelMode,
  217. FALSE,
  218. NULL);
  219. Status = Irp->IoStatus.Status;
  220. }
  221. if (NT_SUCCESS(Status)) {
  222. Status = AgpAttachDeviceRelations(DeviceObject,
  223. Irp,
  224. Extension);
  225. Irp->IoStatus.Status = Status;
  226. }
  227. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  228. return Status;
  229. } else {
  230. break;
  231. }
  232. case IRP_MN_START_DEVICE:
  233. //
  234. // We need to hook this in order to filter out any AGP
  235. // resources that have been added.
  236. //
  237. return(AgpStartTarget(Irp, Extension));
  238. case IRP_MN_QUERY_REMOVE_DEVICE:
  239. case IRP_MN_QUERY_STOP_DEVICE:
  240. case IRP_MN_CANCEL_REMOVE_DEVICE:
  241. //
  242. // We can always succeed this.
  243. //
  244. Status = STATUS_SUCCESS;
  245. break;
  246. case IRP_MN_REMOVE_DEVICE:
  247. AgpDisableAperture(GET_AGP_CONTEXT(Extension));
  248. //
  249. // Pass the irp down
  250. //
  251. IoSkipCurrentIrpStackLocation(Irp);
  252. Status = IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);
  253. //
  254. // Clean up and delete ourselves
  255. //
  256. AgpWmiDeRegistration(Extension);
  257. Extension->CommonExtension.Deleted = TRUE;
  258. IoDetachDevice(Extension->CommonExtension.AttachedDevice);
  259. Extension->CommonExtension.AttachedDevice = NULL;
  260. RELEASE_BUS_INTERFACE(Extension);
  261. if (Extension->FavoredMemory.Ranges) {
  262. ExFreePool(Extension->FavoredMemory.Ranges);
  263. }
  264. if (Extension->Resources) {
  265. ExFreePool(Extension->Resources);
  266. }
  267. if (Extension->ResourcesTranslated) {
  268. ExFreePool(Extension->ResourcesTranslated);
  269. }
  270. ExFreePool(Extension->Lock);;
  271. IoDeleteDevice(DeviceObject);
  272. return(Status);
  273. case IRP_MN_STOP_DEVICE:
  274. AgpDisableAperture(GET_AGP_CONTEXT(Extension));
  275. Status = STATUS_SUCCESS;
  276. break; // forward irp down the stack
  277. }
  278. ASSERT(Status != STATUS_PENDING);
  279. if (Status != STATUS_NOT_SUPPORTED) {
  280. Irp->IoStatus.Status = Status;
  281. }
  282. if (NT_SUCCESS(Status) || (Status == STATUS_NOT_SUPPORTED)) {
  283. //
  284. // Forward IRP to PCI driver
  285. //
  286. IoSkipCurrentIrpStackLocation(Irp);
  287. return(IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
  288. } else {
  289. Status = Irp->IoStatus.Status;
  290. IoCompleteRequest(Irp, IO_NO_INCREMENT) ;
  291. return Status ;
  292. }
  293. }
  294. NTSTATUS
  295. AgpDispatchDeviceControl(
  296. IN PDEVICE_OBJECT DeviceObject,
  297. IN OUT PIRP Irp
  298. )
  299. /*++
  300. Routine Description:
  301. Main dispatch routine for device control irps sent to the AGP bus filter driver
  302. AGP currently does not support any device controls. So we just pass everything
  303. down and hope the PDO knows what to do with it.
  304. Arguments:
  305. DeviceObject - Supplies the AGP device object
  306. Irp - Supplies the power Irp.
  307. Return Value:
  308. NTSTATUS
  309. --*/
  310. {
  311. PCOMMON_EXTENSION Extension = DeviceObject->DeviceExtension;
  312. PAGED_CODE();
  313. //
  314. // We're deleted, fail the irp
  315. //
  316. if (Extension->Deleted == TRUE) {
  317. Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  318. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  319. return STATUS_DELETE_PENDING;
  320. }
  321. ASSERT(Extension->AttachedDevice != NULL);
  322. IoSkipCurrentIrpStackLocation(Irp);
  323. return(IoCallDriver(Extension->AttachedDevice, Irp));
  324. }
  325. NTSTATUS
  326. AgpDispatchWmi(
  327. IN PDEVICE_OBJECT DeviceObject,
  328. IN OUT PIRP Irp
  329. )
  330. /*++
  331. Routine Description:
  332. Main dispatch routine for system control irps sent to the AGP bus filter
  333. driver.
  334. AGP currently does not support any WMI IRPs, so we just pass everything
  335. down and hope the PDO knows what to do with it.
  336. Arguments:
  337. DeviceObject - Supplies the AGP device object
  338. Irp - Supplies the power Irp.
  339. Return Value:
  340. NTSTATUS
  341. --*/
  342. {
  343. PCOMMON_EXTENSION Extension = DeviceObject->DeviceExtension;
  344. PAGED_CODE();
  345. //
  346. // We're deleted, fail the irp
  347. //
  348. if (Extension->Deleted == TRUE) {
  349. Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  350. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  351. return STATUS_DELETE_PENDING;
  352. }
  353. ASSERT(Extension->AttachedDevice != NULL);
  354. //
  355. // Return AGP info for target device
  356. //
  357. if (Extension->Type == AgpTargetFilter) {
  358. return AgpSystemControl(DeviceObject, Irp);
  359. }
  360. IoSkipCurrentIrpStackLocation(Irp);
  361. return(IoCallDriver(Extension->AttachedDevice, Irp));
  362. }
  363. NTSTATUS
  364. AgpTargetDispatchPower(
  365. IN PDEVICE_OBJECT DeviceObject,
  366. IN OUT PIRP Irp,
  367. IN PTARGET_EXTENSION Extension
  368. )
  369. {
  370. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  371. AGPLOG(AGP_IRPTRACE,
  372. ("AgpTargetDispatchPower: IRP 0x%x\n", irpStack->MinorFunction));
  373. //
  374. // All we keep track of are Dx states. PCI is responsible for mapping
  375. // S-states into D states.
  376. //
  377. if ((irpStack->MinorFunction == IRP_MN_SET_POWER) &&
  378. (irpStack->Parameters.Power.Type == DevicePowerState) &&
  379. (irpStack->Parameters.Power.State.DeviceState == PowerDeviceD0)) {
  380. NTSTATUS Status;
  381. //
  382. // We need to reinitialize the target when this IRP has been completed
  383. // by the lower drivers. Set up our completion handler to finish this.
  384. //
  385. IoCopyCurrentIrpStackLocationToNext(Irp);
  386. IoSetCompletionRoutine(Irp,
  387. AgpTargetPowerUpCompletion,
  388. Extension,
  389. TRUE,
  390. FALSE,
  391. FALSE);
  392. IoMarkIrpPending(Irp);
  393. PoStartNextPowerIrp(Irp);
  394. Status = PoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);
  395. return STATUS_PENDING;
  396. }
  397. //
  398. // Just forward to target device
  399. //
  400. PoStartNextPowerIrp(Irp);
  401. IoSkipCurrentIrpStackLocation(Irp);
  402. return(PoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
  403. }
  404. NTSTATUS
  405. AgpMasterDispatchPnp(
  406. IN PDEVICE_OBJECT DeviceObject,
  407. IN OUT PIRP Irp,
  408. IN PMASTER_EXTENSION Extension
  409. )
  410. /*++
  411. Routine Description:
  412. Dispatch routine for PNP irps sent to the AGP bus filter driver
  413. attached to the device PDOs.
  414. Arguments:
  415. DeviceObject - Supplies the AGP device object
  416. Irp - Supplies the PNP Irp.
  417. Extension - Supplies the AGP bridge device extension
  418. Return Value:
  419. NTSTATUS
  420. --*/
  421. {
  422. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  423. PAGP_BUS_INTERFACE_STANDARD Interface;
  424. NTSTATUS Status;
  425. PAGED_CODE();
  426. AGPLOG(AGP_IRPTRACE,
  427. ("AgpMasterDispatchPnp: IRP 0x%x\n", irpStack->MinorFunction));
  428. switch (irpStack->MinorFunction) {
  429. case IRP_MN_QUERY_INTERFACE:
  430. #if 0
  431. AGPLOG(AGP_IRPTRACE,
  432. ("\tSize=0x%x, Version=%d\n"
  433. "\tGUID=0x%08x-0x%04x-0x%04x-0x%02x-"
  434. "0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x\n",
  435. irpStack->Parameters.QueryInterface.Size,
  436. irpStack->Parameters.QueryInterface.Version,
  437. *(PULONG)irpStack->Parameters.QueryInterface.InterfaceType,
  438. *((PUSHORT)irpStack->Parameters.QueryInterface.InterfaceType + 2),
  439. *((PUSHORT)irpStack->Parameters.QueryInterface.InterfaceType + 3),
  440. *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 8),
  441. *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 9),
  442. *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 10),
  443. *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 11),
  444. *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 12),
  445. *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 13),
  446. *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 14),
  447. *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 15)));
  448. #endif
  449. //
  450. // The only IRP we look for here is IRP_MN_QUERY_INTERFACE for
  451. // GUID_AGP_BUS_INTERFACE_STANDARD.
  452. //
  453. if ((RtlEqualMemory(
  454. irpStack->Parameters.QueryInterface.InterfaceType,
  455. &GUID_AGP_BUS_INTERFACE_STANDARD,
  456. sizeof(GUID))) &&
  457. (((irpStack->Parameters.QueryInterface.Size >=
  458. sizeof(AGP_BUS_INTERFACE_STANDARD)) &&
  459. (irpStack->Parameters.QueryInterface.Version ==
  460. AGP_BUS_INTERFACE_V2)) ||
  461. ((irpStack->Parameters.QueryInterface.Size >=
  462. AGP_BUS_INTERFACE_V1_SIZE) &&
  463. (irpStack->Parameters.QueryInterface.Version ==
  464. AGP_BUS_INTERFACE_V1)))) {
  465. Interface = (PAGP_BUS_INTERFACE_STANDARD)irpStack->Parameters.QueryInterface.Interface;
  466. Interface->Version =
  467. irpStack->Parameters.QueryInterface.Version;
  468. Interface->AgpContext = Extension;
  469. Interface->InterfaceReference = AgpInterfaceReference;
  470. Interface->InterfaceDereference = AgpInterfaceDereference;
  471. Interface->ReserveMemory = AgpInterfaceReserveMemory;
  472. Interface->ReleaseMemory = AgpInterfaceReleaseMemory;
  473. Interface->CommitMemory = AgpInterfaceCommitMemory;
  474. Interface->FreeMemory = AgpInterfaceFreeMemory;
  475. Interface->GetMappedPages = AgpInterfaceGetMappedPages;
  476. if (Interface->Version < AGP_BUS_INTERFACE_V2) {
  477. Interface->Size = AGP_BUS_INTERFACE_V1_SIZE;
  478. } else {
  479. Interface->Size = sizeof(AGP_BUS_INTERFACE_STANDARD);
  480. Interface->SetRate = AgpInterfaceSetRate;
  481. }
  482. Interface->Capabilities = Extension->Capabilities;
  483. //
  484. // Complete the IRP successfully
  485. //
  486. Irp->IoStatus.Status = STATUS_SUCCESS;
  487. // AGPLOG(AGP_IRPTRACE, ("\tOK.\n"));
  488. } // else { AGPLOG(AGP_IRPTRACE, ("\tNO!\n")); }
  489. break;
  490. case IRP_MN_QUERY_REMOVE_DEVICE:
  491. case IRP_MN_QUERY_STOP_DEVICE:
  492. if (irpStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE) {
  493. Extension->RemovePending = TRUE;
  494. } else {
  495. Extension->StopPending = TRUE;
  496. }
  497. //
  498. // If we have given out any interfaces or there are some reserved
  499. // pages, we cannot stop.
  500. //
  501. if ((Extension->InterfaceCount > 0) ||
  502. (Extension->ReservedPages > 0)) {
  503. AGPLOG(AGP_NOISE,
  504. ("AgpMasterDispatchPnp: failing %s due to outstanding interfaces\n",
  505. (irpStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE)
  506. ? "IRP_MN_QUERY_REMOVE_DEVICE"
  507. : "IRP_MN_QUERY_STOP_DEVICE"
  508. ));
  509. Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
  510. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  511. return(STATUS_UNSUCCESSFUL);
  512. } else {
  513. //
  514. // We can succeed this, mark our extension as being in limbo so we do
  515. // not give out any interfaces or anything until we get removed or
  516. // get a cancel.
  517. //
  518. InterlockedIncrement(&Extension->DisableCount);
  519. break; // forward irp down the stack
  520. }
  521. case IRP_MN_CANCEL_REMOVE_DEVICE:
  522. //
  523. // This IRP must be handled on the way back up the stack.
  524. // Set a completion routine to reenable the device.
  525. //
  526. if (Extension->RemovePending) {
  527. Extension->RemovePending = FALSE;
  528. IoCopyCurrentIrpStackLocationToNext(Irp);
  529. IoSetCompletionRoutine(Irp,
  530. AgpCancelMasterRemove,
  531. Extension,
  532. TRUE,
  533. FALSE,
  534. FALSE);
  535. return(IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
  536. } else {
  537. //
  538. // This is a cancel-remove for a query-remove IRP we never saw.
  539. // Ignore it.
  540. //
  541. break;
  542. }
  543. case IRP_MN_CANCEL_STOP_DEVICE:
  544. //
  545. // This IRP must be handled on the way back up the stack.
  546. // Set a completion routine to reenable the device.
  547. //
  548. if (Extension->StopPending) {
  549. Extension->StopPending = FALSE;
  550. IoCopyCurrentIrpStackLocationToNext(Irp);
  551. IoSetCompletionRoutine(Irp,
  552. AgpCancelMasterRemove,
  553. Extension,
  554. TRUE,
  555. FALSE,
  556. FALSE);
  557. return(IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
  558. } else {
  559. //
  560. // This is a cancel-stop for a query-stop IRP we never saw.
  561. // Ignore it.
  562. //
  563. break;
  564. }
  565. case IRP_MN_REMOVE_DEVICE:
  566. AGPLOG(AGP_NOISE,
  567. ("AgpMasterDispatchPnp: removing device due to IRP_MN_REMOVE_DEVICE\n"));
  568. //
  569. // PNP is supposed to send us a QUERY_REMOVE before any REMOVE. That is
  570. // when we check that we are actually in a state where we can be removed.
  571. // Like all PNP rules, there is an exception - if the START is failed
  572. // after we have succeeded it, then we get a REMOVE without a QUERY_REMOVE.
  573. // Obviously this is totally fatal if we have given out interfaces or
  574. // have pages mapped in the GART. Not much we can do about it then.
  575. //
  576. ASSERT(Extension->InterfaceCount == 0);
  577. ASSERT(Extension->ReservedPages == 0);
  578. //
  579. // Pass the IRP down.
  580. //
  581. IoSkipCurrentIrpStackLocation(Irp);
  582. Status = IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);
  583. //
  584. // Clean up and delete ourselves
  585. //
  586. Extension->Target->ChildDevice = NULL;
  587. Extension->CommonExtension.Deleted = TRUE;
  588. IoDetachDevice(Extension->CommonExtension.AttachedDevice);
  589. Extension->CommonExtension.AttachedDevice = NULL;
  590. RELEASE_BUS_INTERFACE(Extension);
  591. IoDeleteDevice(DeviceObject);
  592. return(Status);
  593. case IRP_MN_STOP_DEVICE:
  594. AGPLOG(AGP_NOISE,
  595. ("AgpMasterDispatchPnp: stopping device due to IRP_MN_STOP_DEVICE\n"));
  596. ASSERT(Extension->DisableCount);
  597. //
  598. // Just pass the IRP on down
  599. //
  600. break;
  601. case IRP_MN_START_DEVICE:
  602. AGPLOG(AGP_NOISE,
  603. ("AgpMasterDispatchPnp: starting device due to IRP_MN_START_DEVICE\n"));
  604. ASSERT(Extension->DisableCount);
  605. InterlockedDecrement(&Extension->DisableCount);
  606. break; // forward IRP down the stack
  607. }
  608. //
  609. // Just forward to target device
  610. //
  611. IoSkipCurrentIrpStackLocation(Irp);
  612. return(IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
  613. }
  614. NTSTATUS
  615. AgpMasterDispatchPower(
  616. IN PDEVICE_OBJECT DeviceObject,
  617. IN OUT PIRP Irp,
  618. IN PMASTER_EXTENSION Extension
  619. )
  620. {
  621. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  622. AGPLOG(AGP_IRPTRACE,
  623. ("AgpMasterDispatchPower: IRP 0x%x\n", irpStack->MinorFunction));
  624. //
  625. // All we keep track of are Dx states. Videoport is responsible for mapping
  626. // S-states into D states.
  627. //
  628. if ((irpStack->MinorFunction == IRP_MN_SET_POWER) &&
  629. (irpStack->Parameters.Power.Type == DevicePowerState) &&
  630. (irpStack->Parameters.Power.State.DeviceState == PowerDeviceD0)) {
  631. NTSTATUS Status;
  632. //
  633. // We need to reinitialize the master when this IRP has been completed
  634. // by the lower drivers. Set up a completion routine.
  635. //
  636. IoCopyCurrentIrpStackLocationToNext(Irp);
  637. IoSetCompletionRoutine(Irp,
  638. AgpMasterPowerUpCompletion,
  639. Extension,
  640. TRUE,
  641. FALSE,
  642. FALSE);
  643. IoMarkIrpPending(Irp);
  644. PoStartNextPowerIrp(Irp);
  645. Status = PoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);
  646. return STATUS_PENDING;
  647. }
  648. //
  649. // Just forward to target device
  650. //
  651. PoStartNextPowerIrp(Irp);
  652. IoSkipCurrentIrpStackLocation(Irp);
  653. return(PoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
  654. }
  655. NTSTATUS
  656. AgpMasterPowerUpCompletion(
  657. IN PDEVICE_OBJECT DeviceObject,
  658. IN PIRP Irp,
  659. IN PMASTER_EXTENSION Extension
  660. )
  661. /*++
  662. Routine Description:
  663. Powerup completion routine for the master device. It reinitializes the
  664. master registers.
  665. Arguments:
  666. DeviceObject - supplies the master device object.
  667. Irp - Supplies the IRP_MN_SET_POWER irp.
  668. Extension - Supplies the master extension
  669. Return Value:
  670. Status
  671. --*/
  672. {
  673. NTSTATUS Status;
  674. ULONG CurrentCapabilities;
  675. if (Irp->PendingReturned) {
  676. IoMarkIrpPending(Irp);
  677. }
  678. Status = AgpInitializeMaster(GET_AGP_CONTEXT_FROM_MASTER(Extension),
  679. &CurrentCapabilities);
  680. ASSERT(CurrentCapabilities == Extension->Capabilities);
  681. if (!NT_SUCCESS(Status)) {
  682. Irp->IoStatus.Status = Status;
  683. }
  684. return STATUS_SUCCESS;
  685. }
  686. NTSTATUS
  687. AgpTargetPowerUpCompletion(
  688. IN PDEVICE_OBJECT DeviceObject,
  689. IN PIRP Irp,
  690. IN PTARGET_EXTENSION Extension
  691. )
  692. /*++
  693. Routine Description:
  694. Powerup completion routine for the target device. It reinitializes the
  695. GART aperture
  696. Arguments:
  697. DeviceObject - supplies the master device object.
  698. Irp - Supplies the IRP_MN_SET_POWER irp.
  699. Extension - Supplies the target extension
  700. Return Value:
  701. Status
  702. --*/
  703. {
  704. NTSTATUS Status;
  705. if (Irp->PendingReturned) {
  706. IoMarkIrpPending(Irp);
  707. }
  708. //
  709. // Now it is safe to reinitialize the target. All we do here
  710. // is reset the aperture
  711. //
  712. if (Extension->GartLengthInPages != 0) {
  713. Status = AgpSetAperture(GET_AGP_CONTEXT(Extension),
  714. Extension->GartBase,
  715. Extension->GartLengthInPages);
  716. if (!NT_SUCCESS(Status)) {
  717. Irp->IoStatus.Status = Status;
  718. }
  719. }
  720. return STATUS_SUCCESS;
  721. }
  722. NTSTATUS
  723. AgpCancelMasterRemove(
  724. IN PDEVICE_OBJECT DeviceObject,
  725. IN PIRP Irp,
  726. IN PMASTER_EXTENSION Extension
  727. )
  728. /*++
  729. Routine Description:
  730. Completion routine for IRP_MN_CANCEL_REMOVE_DEVICE. This is required
  731. since we cannot reenable AGP until the lower levels have completed their
  732. CANCEL_REMOVE processing.
  733. Arguments:
  734. DeviceObject - Supplies the device object
  735. Irp - Supplies the IRP
  736. Extension - Supplies the master extension
  737. Return Value:
  738. NTSTATUS
  739. --*/
  740. {
  741. if (Irp->PendingReturned) {
  742. IoMarkIrpPending(Irp);
  743. }
  744. ASSERT(Extension->DisableCount > 0);
  745. InterlockedDecrement(&Extension->DisableCount);
  746. return(STATUS_SUCCESS);
  747. }
  748. NTSTATUS
  749. AgpSetEventCompletion(
  750. IN PDEVICE_OBJECT DeviceObject,
  751. IN PIRP Irp,
  752. IN PKEVENT Event
  753. )
  754. /*++
  755. Routine Description:
  756. This routine is used as a completion routine when an IRP is passed
  757. down the stack but more processing must be done on the way back up.
  758. The effect of using this as a completion routine is that the IRP
  759. will not be destroyed in IoCompleteRequest as called by the lower
  760. level object. The event which is a KEVENT is signaled to allow
  761. processing to continue
  762. Arguments:
  763. DeviceObject - Supplies the device object
  764. Irp - The IRP we are processing
  765. Event - Supplies the event to be signaled
  766. Return Value:
  767. STATUS_MORE_PROCESSING_REQUIRED
  768. --*/
  769. {
  770. ASSERT(Event);
  771. //
  772. // This can be called at DISPATCH_LEVEL so must not be paged
  773. //
  774. KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
  775. return STATUS_MORE_PROCESSING_REQUIRED;
  776. }