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.

1212 lines
30 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. dispatch.c
  5. Abstract:
  6. This module contains the dispatch code for the ACPI driver, NT version
  7. Author:
  8. Stephane Plante (splante)
  9. Environment:
  10. NT Kernel Model Driver only
  11. Revision History:
  12. Eric F. Nelson (enelson) October, '98 - Add GUID_ACPI_REGS_INTERFACE_...
  13. --*/
  14. #include "pch.h"
  15. extern KEVENT ACPITerminateEvent;
  16. extern PETHREAD ACPIThread;
  17. //
  18. // Local procedure to query HAL for ACPI register access routines
  19. //
  20. NTSTATUS
  21. ACPIGetRegisterInterfaces(
  22. IN PDEVICE_OBJECT PciPdo
  23. );
  24. //
  25. // Local procedure to query HAL for port range rountines.
  26. //
  27. NTSTATUS
  28. ACPIGetPortRangeInterfaces(
  29. IN PDEVICE_OBJECT Pdo
  30. );
  31. NTSTATUS
  32. ACPIDispatchAddDevice(
  33. IN PDRIVER_OBJECT DriverObject,
  34. IN PDEVICE_OBJECT PhysicalDeviceObject
  35. )
  36. /*++
  37. Routine Description:
  38. This function contains code that is remarkably similar to the ACPIBuildNewXXX
  39. routines. However there are certain core differences (and thus why this routine
  40. is not named ACPIBuildNewFDO). The first difference is that at this time we do
  41. not yet know the address of the ACPI _SB object. The second is that none of the
  42. names need to be generated.
  43. Arguments:
  44. DriverObject - Represents this device driver
  45. PhysicalDeviceObject- This is 1/2 of the Win9X dev node
  46. Return Value:
  47. Are we successfull or what?
  48. --*/
  49. {
  50. KIRQL oldIrql;
  51. NTSTATUS status;
  52. PACPI_POWER_INFO powerInfo;
  53. PDEVICE_EXTENSION deviceExtension = NULL;
  54. PDEVICE_OBJECT newDeviceObject = NULL;
  55. PDEVICE_OBJECT tempDeviceObject = NULL;
  56. PUCHAR buffer = NULL;
  57. PUCHAR deviceID = NULL;
  58. PUCHAR instanceID = NULL;
  59. //
  60. // Note: This code isn't actually pagable --- it must be called
  61. // PASSIVE_LEVEL
  62. //
  63. PAGED_CODE();
  64. //
  65. // Generate a Device ID (fake)
  66. //
  67. deviceID = ExAllocatePoolWithTag( NonPagedPool, 14, ACPI_STRING_POOLTAG);
  68. if (deviceID == NULL) {
  69. ACPIPrint( (
  70. ACPI_PRINT_FAILURE,
  71. "ACPIDispatchAddDevice: Could not allocate %#08lx bytes\n",
  72. 14
  73. ) );
  74. status = STATUS_INSUFFICIENT_RESOURCES;
  75. goto ACPIDispatchAddDeviceExit;
  76. }
  77. strcpy( deviceID, "ACPI\\PNP0C08" );
  78. //
  79. // Generate an Instance ID (Fake)
  80. //
  81. instanceID = ExAllocatePoolWithTag( NonPagedPool, 11, ACPI_STRING_POOLTAG);
  82. if (instanceID == NULL) {
  83. ACPIPrint( (
  84. ACPI_PRINT_FAILURE,
  85. "ACPIDispatchAddDevice: Could not allocate %#08lx bytes\n",
  86. 11
  87. ) );
  88. status = STATUS_INSUFFICIENT_RESOURCES;
  89. goto ACPIDispatchAddDeviceExit;
  90. }
  91. strcpy( instanceID, "0x5F534750" );
  92. //
  93. // Create a new object for the device
  94. //
  95. status = IoCreateDevice(
  96. DriverObject,
  97. 0,
  98. NULL,
  99. FILE_DEVICE_ACPI,
  100. 0,
  101. FALSE,
  102. &newDeviceObject
  103. );
  104. //
  105. // Did we make the device object?
  106. //
  107. if (!NT_SUCCESS(status)) {
  108. //
  109. // Let the world know we failed
  110. //
  111. ACPIPrint( (
  112. ACPI_PRINT_FAILURE,
  113. "ACPIDispatchAddDevice: %s - %#08lx\n",
  114. deviceID, status
  115. ) );
  116. goto ACPIDispatchAddDeviceExit;
  117. }
  118. //
  119. // Attempt to attach to the PDO
  120. //
  121. tempDeviceObject = IoAttachDeviceToDeviceStack(
  122. newDeviceObject,
  123. PhysicalDeviceObject
  124. );
  125. if (tempDeviceObject == NULL) {
  126. //
  127. // An error occured while referencing the device...
  128. //
  129. ACPIPrint( (
  130. ACPI_PRINT_CRITICAL,
  131. "ACPIDispatchAddDevice: IoAttachDeviceToDeviceStack(%#08lx,%#08lx) "
  132. "== NULL\n",
  133. newDeviceObject, PhysicalDeviceObject
  134. ) );
  135. //
  136. // No such device
  137. //
  138. status = STATUS_NO_SUCH_DEVICE;
  139. goto ACPIDispatchAddDeviceExit;
  140. }
  141. //
  142. // At this point, we can attempt to create the device extension.
  143. //
  144. deviceExtension = ExAllocateFromNPagedLookasideList(
  145. &DeviceExtensionLookAsideList
  146. );
  147. if (deviceExtension == NULL) {
  148. ACPIPrint( (
  149. ACPI_PRINT_CRITICAL,
  150. "ACPIDispatchAddDevice: Could not allocate memory for extension\n"
  151. ) );
  152. //
  153. // Memory failure
  154. //
  155. status = STATUS_INSUFFICIENT_RESOURCES;
  156. goto ACPIDispatchAddDeviceExit;
  157. }
  158. //
  159. // First, lets begin with a clean extension
  160. //
  161. RtlZeroMemory( deviceExtension, sizeof(DEVICE_EXTENSION) );
  162. //
  163. // Initialize the reference count mechanism.
  164. //
  165. InterlockedIncrement( &(deviceExtension->ReferenceCount) );
  166. InterlockedIncrement( &(deviceExtension->OutstandingIrpCount) );
  167. //
  168. // Initialize the link fields
  169. //
  170. newDeviceObject->DeviceExtension = deviceExtension;
  171. deviceExtension->DeviceObject = newDeviceObject;
  172. deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
  173. deviceExtension->TargetDeviceObject = tempDeviceObject;
  174. //
  175. // Initialize the data fields
  176. //
  177. deviceExtension->Signature = ACPI_SIGNATURE;
  178. deviceExtension->DispatchTable = &AcpiFdoIrpDispatch;
  179. deviceExtension->DeviceID = deviceID;
  180. deviceExtension->InstanceID = instanceID;
  181. //
  182. // Initialize the power info
  183. //
  184. powerInfo = &(deviceExtension->PowerInfo);
  185. powerInfo->DevicePowerMatrix[PowerSystemUnspecified] =
  186. PowerDeviceUnspecified;
  187. powerInfo->DevicePowerMatrix[PowerSystemWorking] = PowerDeviceD0;
  188. powerInfo->DevicePowerMatrix[PowerSystemSleeping1] = PowerDeviceD0;
  189. powerInfo->DevicePowerMatrix[PowerSystemSleeping2] = PowerDeviceD0;
  190. powerInfo->DevicePowerMatrix[PowerSystemSleeping3] = PowerDeviceD0;
  191. powerInfo->DevicePowerMatrix[PowerSystemHibernate] = PowerDeviceD3;
  192. powerInfo->DevicePowerMatrix[PowerSystemShutdown] = PowerDeviceD3;
  193. powerInfo->SystemWakeLevel = PowerSystemUnspecified;
  194. powerInfo->DeviceWakeLevel = PowerDeviceUnspecified;
  195. //
  196. // Initialize the flags
  197. //
  198. ACPIInternalUpdateFlags(
  199. &(deviceExtension->Flags),
  200. DEV_TYPE_FDO | DEV_CAP_NO_STOP | DEV_PROP_UID | DEV_PROP_HID |
  201. DEV_PROP_FIXED_HID | DEV_PROP_FIXED_UID,
  202. FALSE
  203. );
  204. //
  205. // Initialize the list entry fields
  206. //
  207. InitializeListHead( &(deviceExtension->ChildDeviceList) );
  208. InitializeListHead( &(deviceExtension->SiblingDeviceList) );
  209. InitializeListHead( &(deviceExtension->EjectDeviceHead) );
  210. InitializeListHead( &(deviceExtension->EjectDeviceList) );
  211. //
  212. // Initialize the queue for power requests
  213. //
  214. InitializeListHead( &(deviceExtension->PowerInfo.PowerRequestListEntry) );
  215. //
  216. // Yes! Now, setup the root device extension. We need a spinlock for this
  217. //
  218. KeAcquireSpinLock( &AcpiDeviceTreeLock, &oldIrql );
  219. RootDeviceExtension = deviceExtension;
  220. KeReleaseSpinLock( &AcpiDeviceTreeLock, oldIrql );
  221. //
  222. // Query for ACPI register interfaces
  223. //
  224. ACPIGetRegisterInterfaces(PhysicalDeviceObject);
  225. //
  226. // Query for HAL port range interfaces.
  227. //
  228. ACPIGetPortRangeInterfaces(PhysicalDeviceObject);
  229. #ifdef WMI_TRACING
  230. //
  231. // Initialize WMI Loging.
  232. //
  233. ACPIWmiInitLog(newDeviceObject);
  234. //
  235. // Enable WMI Logging for boot.
  236. //
  237. ACPIGetWmiLogGlobalHandle();
  238. #endif //WMI_TRACING
  239. //
  240. // Clear the Initialization Flag
  241. //
  242. newDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  243. ACPIDispatchAddDeviceExit:
  244. //
  245. // Free things if the status is not success
  246. //
  247. if (!NT_SUCCESS(status)) {
  248. if (deviceID != NULL) {
  249. ExFreePool( deviceID );
  250. }
  251. if (instanceID != NULL) {
  252. ExFreePool( instanceID );
  253. }
  254. if (tempDeviceObject != NULL) {
  255. IoDetachDevice( tempDeviceObject );
  256. }
  257. if (newDeviceObject != NULL) {
  258. IoDeleteDevice( newDeviceObject );
  259. }
  260. if (deviceExtension != NULL) {
  261. ExFreeToNPagedLookasideList(
  262. &DeviceExtensionLookAsideList,
  263. deviceExtension
  264. );
  265. }
  266. }
  267. //
  268. // Done
  269. //
  270. ACPIDevPrint( (
  271. ACPI_PRINT_LOADING,
  272. deviceExtension,
  273. "ACPIDispatchAddDevice: %08lx\n",
  274. status
  275. ) );
  276. return status;
  277. }
  278. NTSTATUS
  279. ACPIDispatchForwardIrp(
  280. IN PDEVICE_OBJECT DeviceObject,
  281. IN PIRP Irp
  282. )
  283. /*++
  284. Routine Description:
  285. This routine is called when the driver doesn't want to handle the
  286. irp explicitly, but rather pass it along
  287. Arguments:
  288. DeviceObject - The target for the request
  289. Irp - The request
  290. Return Value:
  291. NTSTATUS
  292. --*/
  293. {
  294. PDEVICE_EXTENSION deviceExtension;
  295. NTSTATUS status;
  296. deviceExtension = ACPIInternalGetDeviceExtension(DeviceObject);
  297. if (deviceExtension->TargetDeviceObject) {
  298. //
  299. // Forward to target device
  300. //
  301. IoSkipCurrentIrpStackLocation (Irp);
  302. status = IoCallDriver (deviceExtension->TargetDeviceObject, Irp);
  303. } else {
  304. //
  305. // Don't touch the IRP
  306. //
  307. #if DBG
  308. UCHAR majorFunction;
  309. majorFunction = IoGetCurrentIrpStackLocation(Irp)->MajorFunction;
  310. ASSERT((majorFunction == IRP_MJ_PNP) ||
  311. (majorFunction == IRP_MJ_DEVICE_CONTROL) ||
  312. (majorFunction == IRP_MJ_SYSTEM_CONTROL));
  313. #endif
  314. status = Irp->IoStatus.Status;
  315. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  316. }
  317. return status;
  318. }
  319. NTSTATUS
  320. ACPIDispatchForwardOrFailPowerIrp(
  321. IN PDEVICE_OBJECT DeviceObject,
  322. IN PIRP Irp
  323. )
  324. /*++
  325. Routine Description:
  326. This routine is called when the driver doesn't want to handle the Power
  327. Irp any longer
  328. Arguments:
  329. DeviceObject - The target of the power request
  330. Irp - The power Request
  331. Return Value:
  332. NTSTATUS
  333. --*/
  334. {
  335. NTSTATUS status;
  336. PDEVICE_EXTENSION deviceExtension;
  337. PoStartNextPowerIrp( Irp );
  338. deviceExtension = ACPIInternalGetDeviceExtension(DeviceObject);
  339. //
  340. // Forward the irp along, *unless* we are a PDO. In the later case,
  341. // the irp is at the bottom of its stack (even if there is a target
  342. // device object)
  343. //
  344. if ( !(deviceExtension->Flags & DEV_TYPE_PDO) &&
  345. deviceExtension->TargetDeviceObject ) {
  346. //
  347. // Forward power irp to target device
  348. //
  349. IoCopyCurrentIrpStackLocationToNext ( Irp );
  350. status = PoCallDriver (deviceExtension->TargetDeviceObject, Irp);
  351. } else {
  352. //
  353. // Complate/fail the irp with the not implemented code
  354. //
  355. status = Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
  356. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  357. }
  358. return status;
  359. }
  360. NTSTATUS
  361. ACPIDispatchForwardPowerIrp(
  362. IN PDEVICE_OBJECT DeviceObject,
  363. IN PIRP Irp
  364. )
  365. /*++
  366. Routine Description:
  367. This routine is called when the driver doesn't want to handle the Power
  368. Irp any longer.
  369. Arguments:
  370. DeviceObject - The target of the power request
  371. Irp - The power Request
  372. Return Value:
  373. NTSTATUS
  374. --*/
  375. {
  376. NTSTATUS status;
  377. PDEVICE_EXTENSION deviceExtension;
  378. PoStartNextPowerIrp( Irp );
  379. deviceExtension = ACPIInternalGetDeviceExtension(DeviceObject);
  380. //
  381. // Forward the irp along, *unless* we are a PDO. In the later case,
  382. // the irp is at the bottom of its stack (even if there is a target
  383. // device object)
  384. //
  385. if (deviceExtension->TargetDeviceObject &&
  386. !(deviceExtension->Flags & DEV_TYPE_PDO)
  387. ) {
  388. //
  389. // Forward power irp to target device
  390. //
  391. IoSkipCurrentIrpStackLocation( Irp );
  392. status = PoCallDriver (deviceExtension->TargetDeviceObject, Irp);
  393. } else {
  394. //
  395. // Complate/fail the irp with it's current status code
  396. //
  397. status = Irp->IoStatus.Status;
  398. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  399. }
  400. return status;
  401. }
  402. NTSTATUS
  403. ACPIDispatchPowerIrpUnhandled(
  404. IN PDEVICE_OBJECT DeviceObject,
  405. IN PIRP Irp
  406. )
  407. /*++
  408. Routine Description:
  409. This routine is called when an unhandled power IRP is received by an ACPI
  410. enumerated PDO.
  411. Arguments:
  412. DeviceObject - The target of the power request
  413. Irp - The power Request
  414. Return Value:
  415. NTSTATUS
  416. --*/
  417. {
  418. NTSTATUS status;
  419. #if DBG
  420. PDEVICE_EXTENSION deviceExtension;
  421. deviceExtension = ACPIInternalGetDeviceExtension(DeviceObject);
  422. ASSERT(deviceExtension->Flags & DEV_TYPE_PDO);
  423. #endif
  424. PoStartNextPowerIrp( Irp );
  425. //
  426. // Complate/fail the irp with it's current status code
  427. //
  428. status = Irp->IoStatus.Status;
  429. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  430. return status;
  431. }
  432. NTSTATUS
  433. ACPIDispatchIrp (
  434. IN PDEVICE_OBJECT DeviceObject,
  435. IN PIRP Irp
  436. )
  437. {
  438. KIRQL oldIrql;
  439. LONG oldReferenceCount;
  440. NTSTATUS status;
  441. PDEVICE_EXTENSION deviceExtension;
  442. PIO_STACK_LOCATION irpSp;
  443. PIRP_DISPATCH_TABLE dispatchTable;
  444. PDRIVER_DISPATCH dispatch;
  445. BOOLEAN remove;
  446. KEVENT removeEvent;
  447. UCHAR minorFunction;
  448. //
  449. // We need the IrpStack no matter what happens
  450. //
  451. irpSp = IoGetCurrentIrpStackLocation(Irp);
  452. //
  453. // This is evil. But we have to do this is we are to remain in
  454. // sync with the surprise removal code path. Note that we specifically
  455. // do not call the ACPIInternalGetDeviceExtension() function here
  456. // because that would ignore the surprise removed extension, which we
  457. // want to know about here.
  458. //
  459. status = ACPIInternalGetDispatchTable(
  460. DeviceObject,
  461. &deviceExtension,
  462. &dispatchTable
  463. );
  464. //
  465. // We have the device extension. Now see if it exists. If it does not,
  466. // then it is because we have deleted the object, but the system hasn't
  467. // gotten around to destroying it
  468. //
  469. if (deviceExtension == NULL ||
  470. deviceExtension->Flags & DEV_TYPE_REMOVED ||
  471. deviceExtension->Signature != ACPI_SIGNATURE
  472. ) {
  473. //
  474. // Let the world know
  475. //
  476. ACPIPrint( (
  477. ACPI_PRINT_WARNING,
  478. "ACPIDispatchIrp: Deleted Device 0x%08lx got Irp 0x%08lx\n",
  479. DeviceObject,
  480. Irp
  481. ) );
  482. //
  483. // Is this a power irp?
  484. //
  485. if (irpSp->MajorFunction == IRP_MJ_POWER) {
  486. return ACPIDispatchPowerIrpSurpriseRemoved( DeviceObject, Irp );
  487. } else {
  488. return ACPIDispatchIrpSurpriseRemoved( DeviceObject, Irp );
  489. }
  490. }
  491. //
  492. // Get the dispatch table that we will be using and the minor code as well,
  493. // so that we can look it when required
  494. //
  495. minorFunction = irpSp->MinorFunction;
  496. //
  497. // Should be true because no IRPs should be received while we are removing
  498. // ourselves. Anyone sending such an IRP missed a broadcast somewhere, and
  499. // is thus in error.
  500. //
  501. ASSERT(deviceExtension->RemoveEvent == NULL) ;
  502. //
  503. // Handle the irp differently based on the major code that we are seeing
  504. //
  505. switch (irpSp->MajorFunction) {
  506. case IRP_MJ_POWER:
  507. if (minorFunction < (ACPIDispatchPowerTableSize-1) ) {
  508. //
  509. // Obtain the function pointer from the dispatch table
  510. //
  511. dispatch = dispatchTable->Power[ minorFunction ];
  512. } else {
  513. //
  514. // Use the default dispatch point from the table
  515. //
  516. dispatch = dispatchTable->Power[ ACPIDispatchPowerTableSize -1 ];
  517. }
  518. //
  519. // Reference the device
  520. //
  521. InterlockedIncrement(&deviceExtension->OutstandingIrpCount);
  522. //
  523. // Dispatch to handler, then remove our reference
  524. //
  525. status = dispatch (DeviceObject, Irp);
  526. //
  527. // Remove our reference, if the count goes to zero then signal
  528. // for remove complete
  529. //
  530. ACPIInternalDecrementIrpReferenceCount( deviceExtension );
  531. break;
  532. case IRP_MJ_PNP:
  533. if (minorFunction == IRP_MN_START_DEVICE) {
  534. //
  535. // Dispatch to start device handler
  536. //
  537. dispatch = dispatchTable->PnpStartDevice;
  538. } else if (minorFunction < (ACPIDispatchPnpTableSize-1)) {
  539. //
  540. // Dispatch based on minor function. Not that we don't store
  541. // IRP_MN_START_DEVICE (0x0) in this table, so we have to
  542. // sub one from the minor code
  543. //
  544. dispatch = dispatchTable->Pnp[minorFunction];
  545. } else {
  546. //
  547. // Out of dispatch tables range
  548. //
  549. dispatch = dispatchTable->Pnp[ACPIDispatchPnpTableSize-1];
  550. }
  551. //
  552. // If this is a PnP remove device event, then perform special
  553. // remove processing
  554. //
  555. if ((minorFunction == IRP_MN_REMOVE_DEVICE)||
  556. (minorFunction == IRP_MN_SURPRISE_REMOVAL)) {
  557. //
  558. // Mark the device as removed (ie: block new irps from entering)
  559. // and remember what the target event is
  560. //
  561. KeInitializeEvent (
  562. &removeEvent,
  563. SynchronizationEvent,
  564. FALSE);
  565. deviceExtension->RemoveEvent = &removeEvent;
  566. //
  567. // There may be some wake requests pending on this device. Lets
  568. // cancel those irps now
  569. //
  570. ACPIWakeEmptyRequestQueue (deviceExtension );
  571. //
  572. // Are we the last irp to go through the device?
  573. //
  574. oldReferenceCount =
  575. InterlockedDecrement(&deviceExtension->OutstandingIrpCount) ;
  576. ASSERT(oldReferenceCount >= 0) ;
  577. if ( oldReferenceCount != 0 ) {
  578. //
  579. // Wait for other irps to terminate
  580. //
  581. KeWaitForSingleObject (
  582. &removeEvent,
  583. Executive,
  584. KernelMode,
  585. FALSE,
  586. NULL
  587. );
  588. }
  589. //
  590. // Increment the outstanding IRP count. We do this because the
  591. // device may not actually go away, in which case this needs to
  592. // be at one after the IRP returns. Therefore the remove dispatch
  593. // routine must not drop the IRP reference count of course...
  594. //
  595. InterlockedIncrement(&deviceExtension->OutstandingIrpCount);
  596. //
  597. // Dispatch to remove handler
  598. //
  599. deviceExtension->RemoveEvent = NULL;
  600. status = dispatch (DeviceObject, Irp);
  601. } else {
  602. //
  603. // Increment the reference count on the device
  604. //
  605. InterlockedIncrement( &(deviceExtension->OutstandingIrpCount) );
  606. //
  607. // Dispatch to handler, then remove our reference
  608. //
  609. status = dispatch (DeviceObject, Irp);
  610. //
  611. // Decrement the reference count on the device
  612. //
  613. ACPIInternalDecrementIrpReferenceCount(
  614. deviceExtension
  615. );
  616. }
  617. break;
  618. default:
  619. //
  620. // These cases are similar
  621. //
  622. if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL) {
  623. dispatch = dispatchTable->DeviceControl;
  624. } else if (irpSp->MajorFunction == IRP_MJ_CREATE ||
  625. minorFunction == IRP_MJ_CLOSE) {
  626. dispatch = dispatchTable->CreateClose;
  627. } else if (irpSp->MajorFunction == IRP_MJ_SYSTEM_CONTROL) {
  628. dispatch = dispatchTable->SystemControl;
  629. } else {
  630. dispatch = dispatchTable->Other;
  631. }
  632. //
  633. // Reference the device
  634. //
  635. InterlockedIncrement(&deviceExtension->OutstandingIrpCount);
  636. //
  637. // Dispatch to handler
  638. //
  639. status = dispatch (DeviceObject, Irp);
  640. //
  641. // Remove our reference
  642. //
  643. ACPIInternalDecrementIrpReferenceCount( deviceExtension );
  644. break;
  645. }
  646. //
  647. // Done
  648. //
  649. return status;
  650. }
  651. NTSTATUS
  652. ACPIDispatchIrpInvalid (
  653. IN PDEVICE_OBJECT DeviceObject,
  654. IN PIRP Irp
  655. )
  656. {
  657. //
  658. // Fail the Irp as something that we don't support
  659. //
  660. Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
  661. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  662. return STATUS_NOT_IMPLEMENTED;
  663. }
  664. NTSTATUS
  665. ACPIDispatchIrpSuccess (
  666. IN PDEVICE_OBJECT DeviceObject,
  667. IN PIRP Irp
  668. )
  669. {
  670. Irp->IoStatus.Status = STATUS_SUCCESS;
  671. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  672. return STATUS_SUCCESS;
  673. }
  674. NTSTATUS
  675. ACPIDispatchIrpSurpriseRemoved(
  676. IN PDEVICE_OBJECT DeviceObject,
  677. IN PIRP Irp
  678. )
  679. {
  680. Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
  681. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  682. return STATUS_NO_SUCH_DEVICE;
  683. }
  684. NTSTATUS
  685. ACPIDispatchPowerIrpFailure(
  686. IN PDEVICE_OBJECT DeviceObject,
  687. IN PIRP Irp
  688. )
  689. {
  690. PoStartNextPowerIrp( Irp );
  691. Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
  692. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  693. return STATUS_UNSUCCESSFUL;
  694. }
  695. NTSTATUS
  696. ACPIDispatchPowerIrpInvalid (
  697. IN PDEVICE_OBJECT DeviceObject,
  698. IN PIRP Irp
  699. )
  700. {
  701. PoStartNextPowerIrp( Irp );
  702. Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
  703. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  704. return STATUS_NOT_IMPLEMENTED;
  705. }
  706. NTSTATUS
  707. ACPIDispatchPowerIrpSuccess (
  708. IN PDEVICE_OBJECT DeviceObject,
  709. IN PIRP Irp
  710. )
  711. {
  712. PoStartNextPowerIrp( Irp );
  713. Irp->IoStatus.Status = STATUS_SUCCESS;
  714. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  715. return STATUS_SUCCESS;
  716. }
  717. NTSTATUS
  718. ACPIDispatchPowerIrpSurpriseRemoved (
  719. IN PDEVICE_OBJECT DeviceObject,
  720. IN PIRP Irp
  721. )
  722. {
  723. PoStartNextPowerIrp( Irp );
  724. Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE ;
  725. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  726. return STATUS_NO_SUCH_DEVICE;
  727. }
  728. VOID
  729. ACPIUnload(
  730. IN PDRIVER_OBJECT DriverObject
  731. )
  732. /*++
  733. Routine Description:
  734. This routine is called when the driver is supposed to unload
  735. Since this is a PnP driver, I'm not to sure what I need to do here.
  736. Lets just assume that the system is responsible for sending me removes
  737. for all my device objects, and I can just clean up the rest
  738. Arguments:
  739. DriverObject - The pointer to ourselves
  740. Return Value:
  741. NONE
  742. --*/
  743. {
  744. UNREFERENCED_PARAMETER(DriverObject);
  745. //
  746. // Signal termination to the worker thread.
  747. //
  748. KeSetEvent(&ACPITerminateEvent, 0, FALSE);
  749. //
  750. // And wait for the worker thread to die.
  751. //
  752. KeWaitForSingleObject(ACPIThread, Executive, KernelMode, FALSE, 0);
  753. ObDereferenceObject (ACPIThread);
  754. //
  755. // Make ourselves clean up
  756. //
  757. ACPICleanUp();
  758. //
  759. // Free Memory
  760. //
  761. ExDeleteNPagedLookasideList(&BuildRequestLookAsideList);
  762. ExDeleteNPagedLookasideList(&RequestLookAsideList);
  763. ExDeleteNPagedLookasideList(&DeviceExtensionLookAsideList);
  764. ExDeleteNPagedLookasideList(&ObjectDataLookAsideList);
  765. ExDeleteNPagedLookasideList(&PswContextLookAsideList);
  766. if (AcpiRegistryPath.Buffer != NULL) {
  767. ExFreePool( AcpiRegistryPath.Buffer );
  768. }
  769. if (AcpiProcessorString.Buffer != NULL) {
  770. ExFreePool( AcpiProcessorString.Buffer );
  771. }
  772. //
  773. // Done
  774. //
  775. ACPIPrint( (
  776. ACPI_PRINT_WARNING,
  777. "ACPIUnload: Called --- unloading ACPI driver\n"
  778. ) );
  779. ASSERT( DriverObject->DeviceObject == NULL );
  780. }
  781. NTSTATUS
  782. ACPIGetRegisterInterfaces(
  783. IN PDEVICE_OBJECT PciPdo
  784. )
  785. /*++
  786. Routine Description:
  787. This function queries the PCI bus for interfaces used to access
  788. the ACPI registers
  789. Arguments:
  790. PciPdo - PDO for the PCI bus
  791. Return Value:
  792. --*/
  793. {
  794. NTSTATUS status;
  795. PDEVICE_OBJECT topDeviceInStack;
  796. KEVENT irpCompleted;
  797. PIRP irp;
  798. IO_STATUS_BLOCK statusBlock;
  799. PIO_STACK_LOCATION irpStack;
  800. extern PREAD_ACPI_REGISTER AcpiReadRegisterRoutine;
  801. extern PWRITE_ACPI_REGISTER AcpiWriteRegisterRoutine;
  802. ACPI_REGS_INTERFACE_STANDARD AcpiRegsInterfaceStd;
  803. PAGED_CODE();
  804. KeInitializeEvent(&irpCompleted, SynchronizationEvent, FALSE);
  805. //
  806. // Send an IRP to the PCI bus to get ACPI register interfaces.
  807. //
  808. topDeviceInStack = IoGetAttachedDeviceReference(PciPdo);
  809. if (!topDeviceInStack) {
  810. return STATUS_NO_SUCH_DEVICE;
  811. }
  812. irp = IoBuildSynchronousFsdRequest(
  813. IRP_MJ_PNP,
  814. topDeviceInStack,
  815. NULL, // Buffer
  816. 0, // Length
  817. 0, // StartingOffset
  818. &irpCompleted,
  819. &statusBlock
  820. );
  821. if (!irp) {
  822. ObDereferenceObject( topDeviceInStack );
  823. return STATUS_UNSUCCESSFUL;
  824. }
  825. irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  826. irp->IoStatus.Information = 0;
  827. irpStack = IoGetNextIrpStackLocation(irp);
  828. //
  829. // Set the function codes and parameters.
  830. //
  831. irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
  832. irpStack->Parameters.QueryInterface.InterfaceType =
  833. &GUID_ACPI_REGS_INTERFACE_STANDARD;
  834. irpStack->Parameters.QueryInterface.Size =
  835. sizeof(ACPI_REGS_INTERFACE_STANDARD);
  836. irpStack->Parameters.QueryInterface.Version = 1;
  837. irpStack->Parameters.QueryInterface.Interface =
  838. (PINTERFACE)&AcpiRegsInterfaceStd;
  839. irpStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
  840. //
  841. // Call the driver and wait for completion
  842. //
  843. status = IoCallDriver(topDeviceInStack, irp);
  844. if (status == STATUS_PENDING) {
  845. KeWaitForSingleObject(
  846. &irpCompleted,
  847. Executive,
  848. KernelMode,
  849. FALSE,
  850. NULL
  851. );
  852. status = statusBlock.Status;
  853. }
  854. //
  855. // Done with object reference...
  856. //
  857. ObDereferenceObject( topDeviceInStack );
  858. //
  859. // Did we get some interfaces?
  860. //
  861. if (NT_SUCCESS(status)) {
  862. AcpiReadRegisterRoutine = AcpiRegsInterfaceStd.ReadAcpiRegister;
  863. AcpiWriteRegisterRoutine = AcpiRegsInterfaceStd.WriteAcpiRegister;
  864. }
  865. return status;
  866. }
  867. NTSTATUS
  868. ACPIGetPortRangeInterfaces(
  869. IN PDEVICE_OBJECT Pdo
  870. )
  871. /*++
  872. Routine Description:
  873. This function queries the HAL for interfaces used to manage
  874. the port ranges registers
  875. --*/
  876. {
  877. NTSTATUS Status;
  878. PDEVICE_OBJECT topDeviceInStack;
  879. KEVENT irpCompleted;
  880. PIRP irp;
  881. IO_STATUS_BLOCK StatusBlock;
  882. PIO_STACK_LOCATION irpStack;
  883. PAGED_CODE();
  884. KeInitializeEvent(&irpCompleted, SynchronizationEvent, FALSE);
  885. //
  886. // Send an IRP to the PCI bus to get ACPI register interfaces.
  887. //
  888. topDeviceInStack = IoGetAttachedDeviceReference(Pdo);
  889. if (!topDeviceInStack) {
  890. return STATUS_NO_SUCH_DEVICE;
  891. }
  892. irp = IoBuildSynchronousFsdRequest(
  893. IRP_MJ_PNP,
  894. topDeviceInStack,
  895. NULL, // Buffer
  896. 0, // Length
  897. 0, // StartingOffset
  898. &irpCompleted,
  899. &StatusBlock
  900. );
  901. if (!irp) {
  902. ObDereferenceObject( topDeviceInStack );
  903. return STATUS_UNSUCCESSFUL;
  904. }
  905. irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  906. irp->IoStatus.Information = 0;
  907. irpStack = IoGetNextIrpStackLocation(irp);
  908. //
  909. // Set the function codes and parameters.
  910. //
  911. irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
  912. irpStack->Parameters.QueryInterface.InterfaceType =
  913. &GUID_ACPI_PORT_RANGES_INTERFACE_STANDARD;
  914. irpStack->Parameters.QueryInterface.Size =
  915. sizeof(HAL_PORT_RANGE_INTERFACE);
  916. irpStack->Parameters.QueryInterface.Version = 0;
  917. irpStack->Parameters.QueryInterface.Interface =
  918. (PINTERFACE)&HalPortRangeInterface;
  919. irpStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
  920. //
  921. // Call the driver and wait for completion
  922. //
  923. Status = IoCallDriver(topDeviceInStack, irp);
  924. if (Status == STATUS_PENDING) {
  925. KeWaitForSingleObject(
  926. &irpCompleted,
  927. Executive,
  928. KernelMode,
  929. FALSE,
  930. NULL
  931. );
  932. Status = StatusBlock.Status;
  933. }
  934. //
  935. // Done with object reference...
  936. //
  937. ObDereferenceObject( topDeviceInStack );
  938. //
  939. // Did we get some interfaces?
  940. //
  941. if (NT_SUCCESS(Status)) {
  942. // XXX
  943. }
  944. return Status;
  945. }