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.

3872 lines
94 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. bus.c
  5. Abstract:
  6. This module contains the bus dispatcher for the ACPI driver, NT version
  7. Author:
  8. Stephane Plante (splante)
  9. Environment:
  10. NT Kernel Model Driver only
  11. --*/
  12. #include "pch.h"
  13. extern ACPI_INTERFACE_STANDARD ACPIInterfaceTable;
  14. LIST_ENTRY AcpiUnresolvedEjectList;
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(PAGE, ACPIBusAndFilterIrpEject)
  17. #pragma alloc_text(PAGE, ACPIBusAndFilterIrpQueryCapabilities)
  18. #pragma alloc_text(PAGE, ACPIBusAndFilterIrpQueryEjectRelations)
  19. #pragma alloc_text(PAGE, ACPIBusAndFilterIrpQueryPnpDeviceState)
  20. #pragma alloc_text(PAGE, ACPIBusAndFilterIrpSetLock)
  21. #pragma alloc_text(PAGE, ACPIBusIrpCancelRemoveOrStopDevice)
  22. #pragma alloc_text(PAGE, ACPIBusIrpDeviceUsageNotification)
  23. #pragma alloc_text(PAGE, ACPIBusIrpEject)
  24. #pragma alloc_text(PAGE, ACPIBusIrpQueryBusInformation)
  25. #pragma alloc_text(PAGE, ACPIBusIrpQueryBusRelations)
  26. #pragma alloc_text(PAGE, ACPIBusIrpQueryCapabilities)
  27. #pragma alloc_text(PAGE, ACPIBusIrpQueryDeviceRelations)
  28. #pragma alloc_text(PAGE, ACPIBusIrpQueryId)
  29. #pragma alloc_text(PAGE, ACPIBusIrpQueryInterface)
  30. #pragma alloc_text(PAGE, ACPIBusIrpQueryPnpDeviceState)
  31. #pragma alloc_text(PAGE, ACPIBusIrpQueryRemoveOrStopDevice)
  32. #pragma alloc_text(PAGE, ACPIBusIrpQueryResourceRequirements)
  33. #pragma alloc_text(PAGE, ACPIBusIrpQueryResources)
  34. #pragma alloc_text(PAGE, ACPIBusIrpQueryTargetRelation)
  35. #pragma alloc_text(PAGE, ACPIBusIrpSetLock)
  36. #pragma alloc_text(PAGE, ACPIBusIrpStartDevice)
  37. #pragma alloc_text(PAGE, ACPIBusIrpStartDeviceWorker)
  38. #pragma alloc_text(PAGE, ACPIBusIrpStopDevice)
  39. #pragma alloc_text(PAGE, SmashInterfaceQuery)
  40. #endif
  41. PDEVICE_EXTENSION DebugExtension = NULL;
  42. NTSTATUS
  43. ACPIBusAndFilterIrpEject(
  44. IN PDEVICE_OBJECT DeviceObject,
  45. IN PIRP Irp,
  46. IN PVOID Context,
  47. IN BOOLEAN ProcessingFilterIrp
  48. )
  49. /*++
  50. Routine Description:
  51. This routine is the dispatch point for the IRP_MN_EJECT requests sent to
  52. the PDO.
  53. Arguments:
  54. DeviceObject - Pointer to the device object we received the request for
  55. Irp - Pointer to the request
  56. Return Value:
  57. NTSTATUS
  58. --*/
  59. {
  60. NTSTATUS status = Irp->IoStatus.Status;
  61. PDEVICE_EXTENSION deviceExtension;
  62. PNSOBJ acpiObject;
  63. PDEVICE_EXTENSION parentExtension = NULL;
  64. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  65. UCHAR minorFunction = irpStack->MinorFunction;
  66. ULONG i;
  67. KIRQL oldIrql;
  68. PAGED_CODE();
  69. //
  70. // Get the device extension and acpi object
  71. //
  72. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  73. acpiObject = deviceExtension->AcpiObject;
  74. if ( acpiObject == NULL) {
  75. //
  76. // Don't touch this one
  77. //
  78. status = STATUS_NOT_SUPPORTED;
  79. goto ACPIBusAndFilterIrpEjectExit ;
  80. }
  81. if ( (deviceExtension->DeviceState != Inactive) &&
  82. (deviceExtension->DeviceState != Stopped) ) {
  83. //
  84. // We got called to eject a live node! Yuck, how did this happen?!
  85. //
  86. ACPIDevPrint( (
  87. ACPI_PRINT_FAILURE,
  88. deviceExtension,
  89. "(0x%08lx): ACPIBusAndFilterIrpEject: Active node!\n",
  90. Irp
  91. ) );
  92. status = STATUS_UNSUCCESSFUL ;
  93. goto ACPIBusAndFilterIrpEjectExit ;
  94. }
  95. //
  96. // Bye bye card.
  97. //
  98. ACPIGetNothingEvalIntegerSync(
  99. deviceExtension,
  100. PACKED_EJ0,
  101. 1
  102. );
  103. //
  104. // If this is an eject in S0, make the device go away immediately
  105. // by getting the currrent device status
  106. //
  107. status = ACPIGetDevicePresenceSync(
  108. deviceExtension,
  109. (PVOID *) &i,
  110. NULL
  111. );
  112. if (NT_SUCCESS(status) &&
  113. (!ProcessingFilterIrp) &&
  114. (!(deviceExtension->Flags & DEV_TYPE_NOT_PRESENT))) {
  115. ACPIDevPrint( (
  116. ACPI_PRINT_FAILURE,
  117. deviceExtension,
  118. "(0x%08lx): ACPIBusAndFilterIrpEject: "
  119. "device is still listed as present after _EJ0!\n",
  120. Irp
  121. ) );
  122. //
  123. // The device did not go away. Let us fail this IRP.
  124. //
  125. status = STATUS_UNSUCCESSFUL;
  126. }
  127. ACPIBusAndFilterIrpEjectExit:
  128. //
  129. // done
  130. //
  131. ACPIDevPrint( (
  132. ACPI_PRINT_IRP,
  133. deviceExtension,
  134. "(%#08lx): %s = %#08lx\n",
  135. Irp,
  136. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  137. status
  138. ) );
  139. return status;
  140. }
  141. NTSTATUS
  142. ACPIBusAndFilterIrpQueryCapabilities(
  143. IN PDEVICE_OBJECT DeviceObject,
  144. IN PIRP Irp,
  145. IN PVOID Context,
  146. IN BOOLEAN ProcessingFilterIrp
  147. )
  148. /*++
  149. Routine Description:
  150. This routine handles the IRP_MN_QUERY_CAPABILITIES requests for both
  151. bus and filter devnodes.
  152. Arguments:
  153. DeviceObject - Pointer to the device object we received the request for
  154. Irp - Pointer to the request
  155. Return Value:
  156. NTSTATUS
  157. --*/
  158. {
  159. NTSTATUS status;
  160. PDEVICE_CAPABILITIES capabilities;
  161. PDEVICE_EXTENSION deviceExtension;
  162. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  163. PNSOBJ acpiObject, rmvObject;
  164. UCHAR minorFunction = irpStack->MinorFunction;
  165. ULONG deviceStatus;
  166. ULONG slotUniqueNumber, rmvValue;
  167. PAGED_CODE();
  168. //
  169. // Get the device extension and acpi object
  170. //
  171. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  172. acpiObject = deviceExtension->AcpiObject;
  173. //
  174. // Grab a pointer to the capabilities
  175. //
  176. capabilities = irpStack->Parameters.DeviceCapabilities.Capabilities;
  177. #ifndef HANDLE_BOGUS_CAPS
  178. if (capabilities->Version < 1) {
  179. //
  180. // do not touch irp!
  181. //
  182. status = STATUS_NOT_SUPPORTED;
  183. goto ACPIBusAndFilterIrpQueryCapabilitiesExit;
  184. }
  185. #endif
  186. #if !defined(ACPI_INTERNAL_LOCKING)
  187. //
  188. // An object of this name signifies the node is lockable
  189. //
  190. if (ACPIAmliGetNamedChild( acpiObject, PACKED_LCK) != NULL) {
  191. capabilities->LockSupported = TRUE;
  192. }
  193. #endif
  194. //
  195. // Note presence of _RMV and _EJx methods unless there is a
  196. // capability on the object to the contrary.
  197. //
  198. if ((deviceExtension->Flags & DEV_CAP_NO_REMOVE_OR_EJECT) == 0) {
  199. //
  200. // An object of this name signifies the node is removable,
  201. // unless it's a method which might be trying to tell us the
  202. // device *isn't* removable.
  203. //
  204. rmvObject = ACPIAmliGetNamedChild( acpiObject, PACKED_RMV);
  205. if (rmvObject != NULL) {
  206. if (NSGETOBJTYPE(rmvObject) == OBJTYPE_METHOD) {
  207. //
  208. // Execute the RMV method.
  209. //
  210. status = ACPIGetIntegerSyncValidate(
  211. deviceExtension,
  212. PACKED_RMV,
  213. &rmvValue,
  214. NULL
  215. );
  216. if (NT_SUCCESS(status)) {
  217. capabilities->Removable = rmvValue ? TRUE : FALSE;
  218. } else {
  219. capabilities->Removable = TRUE;
  220. }
  221. } else {
  222. //
  223. // If it's anything other than a method, it means the device is
  224. // removable (even if it's _RMV = 0)
  225. //
  226. capabilities->Removable = TRUE;
  227. }
  228. }
  229. //
  230. // An object of this name signifies the node is ejectable, but we strip
  231. // that away for docks (the profile provider can present these)
  232. //
  233. if (!ACPIDockIsDockDevice(acpiObject)) {
  234. if (ACPIAmliGetNamedChild( acpiObject, PACKED_EJ0) != NULL) {
  235. capabilities->EjectSupported = TRUE;
  236. capabilities->Removable = TRUE;
  237. }
  238. if (ACPIAmliGetNamedChild( acpiObject, PACKED_EJ1) ||
  239. ACPIAmliGetNamedChild( acpiObject, PACKED_EJ2) ||
  240. ACPIAmliGetNamedChild( acpiObject, PACKED_EJ3) ||
  241. ACPIAmliGetNamedChild( acpiObject, PACKED_EJ4)) {
  242. capabilities->WarmEjectSupported = TRUE;
  243. capabilities->Removable = TRUE;
  244. }
  245. }
  246. }
  247. //
  248. // An object of this name will signifies inrush
  249. //
  250. if (ACPIAmliGetNamedChild( acpiObject, PACKED_IRC) != NULL) {
  251. DeviceObject->Flags |= DO_POWER_INRUSH;
  252. }
  253. //
  254. // Is the device disabled?
  255. //
  256. status = ACPIGetDevicePresenceSync(
  257. deviceExtension,
  258. (PVOID *) &deviceStatus,
  259. NULL
  260. );
  261. if (!NT_SUCCESS(status)) {
  262. goto ACPIBusAndFilterIrpQueryCapabilitiesExit;
  263. }
  264. if (!(deviceExtension->Flags & DEV_PROP_DEVICE_ENABLED)) {
  265. if (ACPIAmliGetNamedChild( acpiObject, PACKED_CRS) != NULL &&
  266. ACPIAmliGetNamedChild( acpiObject, PACKED_SRS) == NULL) {
  267. capabilities->HardwareDisabled = 1;
  268. } else if (ProcessingFilterIrp) {
  269. capabilities->HardwareDisabled = 0;
  270. }
  271. } else if (!ProcessingFilterIrp) {
  272. //
  273. // For machines with this attribute set, this means that the
  274. // hardware REALLY isn't present and should always be reported
  275. // as disabled
  276. //
  277. if (AcpiOverrideAttributes & ACPI_OVERRIDE_STA_CHECK) {
  278. capabilities->HardwareDisabled = 1;
  279. } else {
  280. capabilities->HardwareDisabled = 0;
  281. }
  282. }
  283. //
  284. // If we fail the START_DEVICE, then there are some cases where we don't
  285. // want the device to show up in the Device Manager. So try to report this
  286. // capability based on the information from the device presence...
  287. //
  288. if (!(deviceStatus & STA_STATUS_USER_INTERFACE)) {
  289. //
  290. // See the bit that says that we shouldn't the device in the UI if
  291. // the Start Device Fails
  292. //
  293. capabilities->NoDisplayInUI = 1;
  294. }
  295. //
  296. // Determine the slot number
  297. //
  298. if (ACPIAmliGetNamedChild( acpiObject, PACKED_SUN) != NULL) {
  299. //
  300. // If we have UINumber information, use it.
  301. //
  302. status = ACPIGetIntegerSync(
  303. deviceExtension,
  304. PACKED_SUN,
  305. &slotUniqueNumber,
  306. NULL
  307. );
  308. if (NT_SUCCESS(status)) {
  309. capabilities->UINumber = slotUniqueNumber;
  310. }
  311. }
  312. //
  313. // Is there an address?
  314. //
  315. if (ACPIAmliGetNamedChild( acpiObject, PACKED_ADR) != NULL) {
  316. status = ACPIGetAddressSync(
  317. deviceExtension,
  318. &(capabilities->Address),
  319. NULL
  320. );
  321. if (!NT_SUCCESS(status)) {
  322. ACPIDevPrint( (
  323. ACPI_PRINT_CRITICAL,
  324. deviceExtension,
  325. " - Could query device address - %08lx",
  326. status
  327. ) );
  328. goto ACPIBusAndFilterIrpQueryCapabilitiesExit;
  329. }
  330. }
  331. //
  332. // Do the power capabilities
  333. //
  334. status = ACPISystemPowerQueryDeviceCapabilities(
  335. deviceExtension,
  336. capabilities
  337. );
  338. if (!NT_SUCCESS(status)) {
  339. ACPIDevPrint( (
  340. ACPI_PRINT_CRITICAL,
  341. deviceExtension,
  342. " - Could query device capabilities - %08lx",
  343. status
  344. ) );
  345. goto ACPIBusAndFilterIrpQueryCapabilitiesExit;
  346. }
  347. //
  348. // Set the current flags for the capabilities
  349. //
  350. if (!ProcessingFilterIrp) {
  351. //
  352. // Set some rather boolean capabilities
  353. //
  354. capabilities->SilentInstall = TRUE;
  355. capabilities->RawDeviceOK =
  356. (deviceExtension->Flags & DEV_CAP_RAW) ? TRUE : FALSE;
  357. capabilities->UniqueID =
  358. (deviceExtension->InstanceID == NULL ? FALSE : TRUE);
  359. //
  360. // In the filter case, we will just let the underlying pdo determine the
  361. // success or failure of the irp.
  362. //
  363. status = STATUS_SUCCESS;
  364. }
  365. ACPIBusAndFilterIrpQueryCapabilitiesExit:
  366. ACPIDevPrint( (
  367. ACPI_PRINT_IRP,
  368. deviceExtension,
  369. "(0x%08lx): %s = 0x%08lx\n",
  370. Irp,
  371. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  372. status
  373. ) );
  374. return status;
  375. }
  376. NTSTATUS
  377. ACPIBusAndFilterIrpQueryEjectRelations(
  378. IN PDEVICE_OBJECT DeviceObject,
  379. IN PIRP Irp,
  380. IN OUT PDEVICE_RELATIONS *DeviceRelations
  381. )
  382. {
  383. PDEVICE_EXTENSION deviceExtension, additionalExtension;
  384. PNSOBJ acpiObject;
  385. NTSTATUS status ;
  386. PAGED_CODE();
  387. //
  388. // Get the device extension and acpi object
  389. //
  390. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  391. acpiObject = deviceExtension->AcpiObject;
  392. //
  393. // lets look at the ACPIObject that we have so can see if it is valid...
  394. //
  395. if (acpiObject == NULL) {
  396. //
  397. // Invalid name space object <bad>
  398. //
  399. ACPIDevPrint( (
  400. ACPI_PRINT_CRITICAL,
  401. deviceExtension,
  402. "(0x%08lx): ACPIBusAndFilterIrpQueryEjectRelations: "
  403. "invalid ACPIObject (0x%08lx)\n",
  404. Irp,
  405. acpiObject
  406. ) );
  407. //
  408. // Mark the irp as very bad...
  409. //
  410. return STATUS_INVALID_PARAMETER;
  411. }
  412. //
  413. // Mark sure _DCK nodes have ejection relations that include their fake
  414. // dock nodes.
  415. //
  416. if (ACPIDockIsDockDevice(acpiObject)) {
  417. additionalExtension = ACPIDockFindCorrespondingDock( deviceExtension );
  418. } else {
  419. additionalExtension = NULL;
  420. }
  421. status = ACPIDetectEjectDevices(
  422. deviceExtension,
  423. DeviceRelations,
  424. additionalExtension
  425. );
  426. //
  427. // If something went wrong...
  428. //
  429. if (!NT_SUCCESS(status)) {
  430. //
  431. // That's not nice..
  432. //
  433. ACPIDevPrint( (
  434. ACPI_PRINT_CRITICAL,
  435. deviceExtension,
  436. "ACPIBusAndFilterIrpQueryEjectRelations: enum = 0x%08lx\n",
  437. Irp,
  438. status
  439. ) );
  440. }
  441. //
  442. // Done
  443. //
  444. return status ;
  445. }
  446. NTSTATUS
  447. ACPIBusAndFilterIrpQueryPnpDeviceState(
  448. IN PDEVICE_OBJECT DeviceObject,
  449. IN PIRP Irp,
  450. IN PVOID Context,
  451. IN BOOLEAN ProcessingFilterIrp
  452. )
  453. /*++
  454. Routine Description:
  455. This routines tells the system what PNP state the device is in
  456. Arguments:
  457. DeviceObject - The device whose state we want to know
  458. Irp - The request
  459. ProcessingFilterIrp - Are we a filter or not?
  460. Return Value:
  461. NTSTATUS
  462. --*/
  463. {
  464. BOOLEAN staPresent;
  465. NTSTATUS status = STATUS_SUCCESS;
  466. PDEVICE_EXTENSION deviceExtension;
  467. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  468. PNSOBJ nsObj = NULL;
  469. UCHAR minorFunction = irpStack->MinorFunction;
  470. ULONG deviceStatus;
  471. PAGED_CODE();
  472. //
  473. // Get the device extension
  474. //
  475. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  476. //
  477. // We base some of the decisions on wether or not a _STA is *really*
  478. // present or not. Determine that now
  479. //
  480. if ( !(deviceExtension->Flags & DEV_PROP_NO_OBJECT) ) {
  481. nsObj = ACPIAmliGetNamedChild(
  482. deviceExtension->AcpiObject,
  483. PACKED_STA
  484. );
  485. }
  486. staPresent = (nsObj == NULL ? FALSE : TRUE);
  487. //
  488. // Get the device status
  489. //
  490. status = ACPIGetDevicePresenceSync(
  491. deviceExtension,
  492. (PVOID *) &deviceStatus,
  493. NULL
  494. );
  495. if (!NT_SUCCESS(status)) {
  496. goto ACPIBusAndFilterIrpQueryPnpDeviceStateExit;
  497. }
  498. //
  499. // do we show this in the UI?
  500. //
  501. if (deviceExtension->Flags & DEV_CAP_NEVER_SHOW_IN_UI) {
  502. Irp->IoStatus.Information |= PNP_DEVICE_DONT_DISPLAY_IN_UI;
  503. } else if (deviceExtension->Flags & DEV_CAP_NO_SHOW_IN_UI) {
  504. Irp->IoStatus.Information |= PNP_DEVICE_DONT_DISPLAY_IN_UI;
  505. } else if (staPresent || !ProcessingFilterIrp) {
  506. Irp->IoStatus.Information &= ~PNP_DEVICE_DONT_DISPLAY_IN_UI;
  507. }
  508. //
  509. // Is the device not working?
  510. //
  511. if (deviceExtension->Flags & DEV_PROP_DEVICE_FAILED) {
  512. Irp->IoStatus.Information |= PNP_DEVICE_FAILED;
  513. } else if (staPresent && !ProcessingFilterIrp) {
  514. Irp->IoStatus.Information &= ~PNP_DEVICE_FAILED;
  515. }
  516. //
  517. // Can we disable this device?
  518. // Note that anything that isn't a regular device should be
  519. // marked as disableable...
  520. //
  521. if (!(deviceExtension->Flags & DEV_PROP_NO_OBJECT) &&
  522. !(deviceExtension->Flags & DEV_CAP_PROCESSOR) &&
  523. !(deviceExtension->Flags & DEV_CAP_THERMAL_ZONE) &&
  524. !(deviceExtension->Flags & DEV_CAP_BUTTON) ) {
  525. if (!ProcessingFilterIrp) {
  526. //
  527. // Can we actually disable the device?
  528. // Note --- this requires an _DIS, a _PS3, or a _PR0
  529. //
  530. nsObj = ACPIAmliGetNamedChild(
  531. deviceExtension->AcpiObject,
  532. PACKED_DIS
  533. );
  534. if (nsObj == NULL) {
  535. nsObj = ACPIAmliGetNamedChild(
  536. deviceExtension->AcpiObject,
  537. PACKED_PS3
  538. );
  539. }
  540. if (nsObj == NULL) {
  541. nsObj = ACPIAmliGetNamedChild(
  542. deviceExtension->AcpiObject,
  543. PACKED_PR0
  544. );
  545. }
  546. if (deviceExtension->Flags & DEV_CAP_NO_STOP) {
  547. nsObj = NULL;
  548. }
  549. if (nsObj == NULL) {
  550. Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
  551. }
  552. } else {
  553. //
  554. // Can we actually disable the device?
  555. // Note --- this requires an _DIS, a _PS3, or a _PR0
  556. //
  557. nsObj = ACPIAmliGetNamedChild(
  558. deviceExtension->AcpiObject,
  559. PACKED_DIS
  560. );
  561. if (nsObj == NULL) {
  562. nsObj = ACPIAmliGetNamedChild(
  563. deviceExtension->AcpiObject,
  564. PACKED_PS3
  565. );
  566. }
  567. if (nsObj == NULL) {
  568. nsObj = ACPIAmliGetNamedChild(
  569. deviceExtension->AcpiObject,
  570. PACKED_PR0
  571. );
  572. }
  573. if (deviceExtension->Flags & DEV_CAP_NO_STOP) {
  574. nsObj = NULL;
  575. }
  576. if (nsObj != NULL) {
  577. Irp->IoStatus.Information &= ~PNP_DEVICE_NOT_DISABLEABLE;
  578. }
  579. }
  580. } else {
  581. //
  582. // If we have no device object...
  583. //
  584. if (deviceExtension->Flags & DEV_CAP_NO_STOP) {
  585. Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
  586. }
  587. }
  588. ACPIBusAndFilterIrpQueryPnpDeviceStateExit:
  589. ACPIDevPrint( (
  590. ACPI_PRINT_PNP_STATE,
  591. deviceExtension,
  592. ":%s%s%s%s%s%s\n",
  593. ( (Irp->IoStatus.Information & PNP_DEVICE_DISABLED) ? " Disabled" : ""),
  594. ( (Irp->IoStatus.Information & PNP_DEVICE_DONT_DISPLAY_IN_UI) ? " NoShowInUi" : ""),
  595. ( (Irp->IoStatus.Information & PNP_DEVICE_FAILED) ? " Failed" : ""),
  596. ( (Irp->IoStatus.Information & PNP_DEVICE_REMOVED) ? " Removed" : ""),
  597. ( (Irp->IoStatus.Information & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED) ? " ResourceChanged" : ""),
  598. ( (Irp->IoStatus.Information & PNP_DEVICE_NOT_DISABLEABLE) ? " NoDisable" : "")
  599. ) );
  600. //
  601. // Done
  602. //
  603. ACPIDevPrint( (
  604. ACPI_PRINT_IRP,
  605. deviceExtension,
  606. "(0x%08lx): %s = 0x%08lx\n",
  607. Irp,
  608. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  609. status
  610. ) );
  611. return status;
  612. }
  613. NTSTATUS
  614. ACPIBusAndFilterIrpSetLock(
  615. IN PDEVICE_OBJECT DeviceObject,
  616. IN PIRP Irp,
  617. IN PVOID Context,
  618. IN BOOLEAN ProcessingFilterIrp
  619. )
  620. /*++
  621. Routine Description:
  622. This handles lock and unlock requests for PDO's or filters...
  623. Arguments:
  624. DeviceObject - The device to stop
  625. Irp - The request to tell us how to do it...
  626. Return Value:
  627. NTSTATUS
  628. --*/
  629. {
  630. NTSTATUS status = Irp->IoStatus.Status;
  631. PDEVICE_EXTENSION deviceExtension;
  632. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  633. UCHAR minorFunction = irpStack->MinorFunction;
  634. BOOLEAN lockParameter = irpStack->Parameters.SetLock.Lock;
  635. ULONG acpiLockArg ;
  636. NTSTATUS lockStatus ;
  637. PAGED_CODE();
  638. //
  639. // Get the device extension
  640. //
  641. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  642. #if !defined(ACPI_INTERNAL_LOCKING)
  643. //
  644. // Attempt to lock/unlock the device as appropriate
  645. //
  646. acpiLockArg = ((lockParameter) ? 1 : 0) ;
  647. //
  648. // Here we go...
  649. //
  650. #if 0
  651. lockStatus = ACPIGetNothingEvalIntegerSync(
  652. deviceExtension,
  653. PACKED_LCK,
  654. acpiLockArg
  655. );
  656. #endif
  657. if (status == STATUS_NOT_SUPPORTED) {
  658. status = STATUS_SUCCESS ;
  659. }
  660. #endif
  661. //
  662. // done
  663. //
  664. ACPIDevPrint( (
  665. ACPI_PRINT_IRP,
  666. deviceExtension,
  667. "(%#08lx): %s = %#08lx\n",
  668. Irp,
  669. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  670. status
  671. ) );
  672. return status;
  673. }
  674. NTSTATUS
  675. ACPIBusIrpCancelRemoveOrStopDevice(
  676. IN PDEVICE_OBJECT DeviceObject,
  677. IN PIRP Irp
  678. )
  679. /*++
  680. Routine Description:
  681. This routine is called when we no longer wish to remove or stop the device
  682. object
  683. Arguments:
  684. DeviceObject - The device object to be removed
  685. Irp - The request
  686. Return Value:
  687. NTSTATUS
  688. --*/
  689. {
  690. NTSTATUS status = STATUS_SUCCESS;
  691. PDEVICE_EXTENSION deviceExtension;
  692. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  693. UCHAR minorFunction = irpStack->MinorFunction;
  694. PAGED_CODE();
  695. //
  696. // Get the device extension and acpi object
  697. //
  698. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  699. //
  700. // Were we allowed to stop the device?
  701. //
  702. if (!(deviceExtension->Flags & DEV_CAP_NO_STOP) ) {
  703. //
  704. // Check to see if we have placed this device in the inactive state
  705. //
  706. if (deviceExtension->DeviceState == Inactive) {
  707. //
  708. // Mark the device extension as being started
  709. //
  710. deviceExtension->DeviceState = deviceExtension->PreviousState;
  711. }
  712. }
  713. //
  714. // Complete the irp
  715. //
  716. Irp->IoStatus.Status = status;
  717. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  718. //
  719. // Done
  720. //
  721. ACPIDevPrint( (
  722. ACPI_PRINT_IRP,
  723. deviceExtension,
  724. "(0x%08lx): %s = 0x%08lx\n",
  725. Irp,
  726. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  727. status
  728. ) );
  729. return status;
  730. }
  731. NTSTATUS
  732. ACPIBusIrpDeviceUsageNotification(
  733. IN PDEVICE_OBJECT DeviceObject,
  734. IN PIRP Irp
  735. )
  736. /*++
  737. Routine Description:
  738. This routine is called to let ACPI know that the device is on one
  739. particular type of path
  740. Arguments:
  741. DeviceObject - Pointer to the device object we received the request for
  742. Irp - Pointer to the request
  743. Return Value:
  744. NTSTATUS
  745. --*/
  746. {
  747. NTSTATUS status = STATUS_SUCCESS;
  748. PDEVICE_EXTENSION deviceExtension;
  749. PDEVICE_OBJECT parentObject;
  750. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
  751. PAGED_CODE();
  752. //
  753. // Get the device extension
  754. //
  755. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  756. //
  757. // Do we have a parent extension?
  758. //
  759. if (deviceExtension->ParentExtension != NULL) {
  760. //
  761. // Get the parents stack
  762. //
  763. parentObject = deviceExtension->ParentExtension->DeviceObject;
  764. if (parentObject == NULL) {
  765. //
  766. // Fail because we don't have a device object
  767. //
  768. status = STATUS_NO_SUCH_DEVICE;
  769. goto ACPIBusIrpDeviceUsageNotificationExit;
  770. }
  771. //
  772. // Send a synchronous irp down and wait for the result
  773. //
  774. status = ACPIInternalSendSynchronousIrp(
  775. parentObject,
  776. irpSp,
  777. NULL
  778. );
  779. }
  780. //
  781. // Did we succeed
  782. //
  783. if (NT_SUCCESS(status)) {
  784. //
  785. // Do we care about the usage type?
  786. //
  787. if (irpSp->Parameters.UsageNotification.Type ==
  788. DeviceUsageTypeHibernation) {
  789. //
  790. // Yes --- then perform the addition or subtraction required
  791. //
  792. IoAdjustPagingPathCount(
  793. &(deviceExtension->HibernatePathCount),
  794. irpSp->Parameters.UsageNotification.InPath
  795. );
  796. }
  797. }
  798. ACPIBusIrpDeviceUsageNotificationExit:
  799. //
  800. // Complete the request
  801. //
  802. Irp->IoStatus.Status = status;
  803. Irp->IoStatus.Information = 0;
  804. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  805. ACPIDevPrint( (
  806. ACPI_PRINT_IRP,
  807. deviceExtension,
  808. "(0x%08lx): %s = 0x%08lx\n",
  809. Irp,
  810. ACPIDebugGetIrpText(IRP_MJ_PNP, IRP_MN_DEVICE_USAGE_NOTIFICATION),
  811. status
  812. ) );
  813. //
  814. // Done
  815. //
  816. return status;
  817. }
  818. NTSTATUS
  819. ACPIBusIrpEject(
  820. IN PDEVICE_OBJECT DeviceObject,
  821. IN PIRP Irp
  822. )
  823. /*++
  824. Routine Description:
  825. This routine is the dispatch point for the IRP_MN_EJECT requests sent to
  826. the PDO.
  827. Arguments:
  828. DeviceObject - Pointer to the device object we received the request for
  829. Irp - Pointer to the request
  830. Return Value:
  831. NTSTATUS
  832. --*/
  833. {
  834. PAGED_CODE();
  835. return ACPIIrpInvokeDispatchRoutine(
  836. DeviceObject,
  837. Irp,
  838. NULL,
  839. ACPIBusAndFilterIrpEject,
  840. FALSE,
  841. TRUE
  842. );
  843. }
  844. NTSTATUS
  845. ACPIBusIrpQueryBusInformation(
  846. IN PDEVICE_OBJECT DeviceObject,
  847. IN PIRP Irp
  848. )
  849. /*++
  850. Routine Description:
  851. This is only called if the device is of the special type PNP0A06
  852. (EIO Bus). This is because we need to tell the system that this is
  853. the ISA bus
  854. Arguments:
  855. DeviceObject - Pointer to the device object we received the request for
  856. Irp - Pointer to the request
  857. Return Value:
  858. NTSTATUS
  859. --*/
  860. {
  861. NTSTATUS status = STATUS_SUCCESS;
  862. PPNP_BUS_INFORMATION busInfo = NULL;
  863. PAGED_CODE();
  864. //
  865. // Allocate some memory to return the information
  866. //
  867. busInfo = ExAllocatePoolWithTag(
  868. PagedPool,
  869. sizeof(PNP_BUS_INFORMATION),
  870. ACPI_MISC_POOLTAG
  871. );
  872. if (busInfo != NULL) {
  873. //
  874. // The BusNumber = 0 might come back and haunt us
  875. //
  876. // Fill in the record
  877. //
  878. busInfo->BusTypeGuid = GUID_BUS_TYPE_ISAPNP;
  879. busInfo->LegacyBusType = Isa;
  880. busInfo->BusNumber = 0;
  881. } else {
  882. ACPIDevPrint( (
  883. ACPI_PRINT_CRITICAL,
  884. DeviceObject->DeviceExtension,
  885. "ACPIBusIrpQueryBusInformation: Could not allocate 0x%08lx bytes\n",
  886. sizeof(PNP_BUS_INFORMATION)
  887. ) );
  888. status = STATUS_INSUFFICIENT_RESOURCES;
  889. }
  890. //
  891. // Done with the request
  892. //
  893. Irp->IoStatus.Status = status;
  894. Irp->IoStatus.Information = (ULONG_PTR) busInfo;
  895. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  896. //
  897. // Done
  898. //
  899. return status;
  900. }
  901. NTSTATUS
  902. ACPIBusIrpQueryBusRelations(
  903. IN PDEVICE_OBJECT DeviceObject,
  904. IN PIRP Irp,
  905. OUT PDEVICE_RELATIONS *DeviceRelations
  906. )
  907. /*++
  908. Routine Description:
  909. This handles DeviceRelations requests sent onto the ACPI driver
  910. Arguments:
  911. DeviceObject - The object that we care about...
  912. Irp - The request in question
  913. Return Value:
  914. NTSTATUS
  915. --*/
  916. {
  917. NTSTATUS filterStatus;
  918. PDEVICE_EXTENSION deviceExtension;
  919. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  920. PNSOBJ acpiObject;
  921. UCHAR minorFunction = irpStack->MinorFunction;
  922. NTSTATUS status ;
  923. PAGED_CODE();
  924. //
  925. // Get the device extension and acpi object
  926. //
  927. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  928. acpiObject = deviceExtension->AcpiObject;
  929. //
  930. // lets look at the ACPIObject that we have so can see if it is valid...
  931. //
  932. if (acpiObject == NULL) {
  933. //
  934. // Invalid name space object <bad>
  935. //
  936. ACPIDevPrint( (
  937. ACPI_PRINT_CRITICAL,
  938. deviceExtension,
  939. "(0x%08lx): ACPIBusIrpQueryDeviceRelations: "
  940. "invalid ACPIObject (0x%08lx)\n",
  941. Irp,
  942. acpiObject
  943. ) );
  944. //
  945. // Mark the irp as very bad...
  946. //
  947. return STATUS_INVALID_PARAMETER;
  948. }
  949. //
  950. // Active the code to detect unenumerated devices...
  951. //
  952. status = ACPIDetectPdoDevices(
  953. DeviceObject,
  954. DeviceRelations
  955. );
  956. //
  957. // If something went wrong...
  958. //
  959. if (!NT_SUCCESS(status)) {
  960. //
  961. // Ouch bad..
  962. //
  963. ACPIDevPrint( (
  964. ACPI_PRINT_CRITICAL,
  965. deviceExtension,
  966. "(0x%08lx): ACPIBusIrpQueryDeviceRelations: enum = 0x%08lx\n",
  967. Irp,
  968. status
  969. ) );
  970. } else {
  971. //
  972. // Load the filters
  973. //
  974. filterStatus = ACPIDetectFilterDevices(
  975. DeviceObject,
  976. *DeviceRelations
  977. );
  978. if (!NT_SUCCESS(filterStatus)) {
  979. //
  980. // Filter Operation failed
  981. //
  982. ACPIDevPrint( (
  983. ACPI_PRINT_CRITICAL,
  984. deviceExtension,
  985. "(0x%08lx): ACPIBusIrpQueryDeviceRelations: filter = 0x%08lx\n",
  986. Irp,
  987. filterStatus
  988. ) );
  989. }
  990. }
  991. //
  992. // Done
  993. //
  994. return status ;
  995. }
  996. NTSTATUS
  997. ACPIBusIrpQueryCapabilities(
  998. IN PDEVICE_OBJECT DeviceObject,
  999. IN PIRP Irp
  1000. )
  1001. /*++
  1002. Routine Description:
  1003. This routine is the dispatch point for the IRP_MN_QUERY_CAPABILITIES requests sent
  1004. to the PDO
  1005. Arguments:
  1006. DeviceObject - Pointer to the device object we received the request for
  1007. Irp - Pointer to the request
  1008. Return Value:
  1009. NTSTATUS
  1010. --*/
  1011. {
  1012. PAGED_CODE();
  1013. ACPIDebugEnter( "ACPIBusIrpQueryCapabilities" );
  1014. return ACPIIrpInvokeDispatchRoutine(
  1015. DeviceObject,
  1016. Irp,
  1017. NULL,
  1018. ACPIBusAndFilterIrpQueryCapabilities,
  1019. TRUE,
  1020. TRUE
  1021. );
  1022. ACPIDebugExit( "ACPIBusIrpQueryCapabilities" );
  1023. }
  1024. NTSTATUS
  1025. ACPIBusIrpQueryDeviceRelations(
  1026. IN PDEVICE_OBJECT DeviceObject,
  1027. IN PIRP Irp
  1028. )
  1029. /*++
  1030. Routine Description:
  1031. This handles DeviceRelations requests sent onto the ACPI driver
  1032. Arguments:
  1033. DeviceObject - The object that we care about...
  1034. Irp - The request in question
  1035. Return Value:
  1036. NTSTATUS
  1037. --*/
  1038. {
  1039. NTSTATUS status ;
  1040. PDEVICE_EXTENSION deviceExtension;
  1041. PDEVICE_RELATIONS deviceRelations = (PDEVICE_RELATIONS) Irp->IoStatus.Information;
  1042. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  1043. UCHAR minorFunction = irpStack->MinorFunction;
  1044. PAGED_CODE();
  1045. //
  1046. // Get the device extension
  1047. //
  1048. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  1049. //
  1050. // Fork off to the appropriate query relations subtype function
  1051. //
  1052. switch(irpStack->Parameters.QueryDeviceRelations.Type) {
  1053. case TargetDeviceRelation:
  1054. status = ACPIBusIrpQueryTargetRelation(
  1055. DeviceObject,
  1056. Irp,
  1057. &deviceRelations
  1058. );
  1059. break ;
  1060. case BusRelations:
  1061. status = ACPIBusIrpQueryBusRelations(
  1062. DeviceObject,
  1063. Irp,
  1064. &deviceRelations
  1065. );
  1066. break ;
  1067. case EjectionRelations:
  1068. status = ACPIBusAndFilterIrpQueryEjectRelations(
  1069. DeviceObject,
  1070. Irp,
  1071. &deviceRelations
  1072. );
  1073. break ;
  1074. default:
  1075. status = STATUS_NOT_SUPPORTED;
  1076. ACPIDevPrint( (
  1077. ACPI_PRINT_IRP,
  1078. deviceExtension,
  1079. "(0x%08lx): %s - Unhandled Type %d\n",
  1080. Irp,
  1081. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  1082. irpStack->Parameters.QueryDeviceRelations.Type
  1083. ) );
  1084. break ;
  1085. }
  1086. //
  1087. // If we succeeds, then we can always write to the irp
  1088. //
  1089. if (NT_SUCCESS(status)) {
  1090. Irp->IoStatus.Status = status;
  1091. Irp->IoStatus.Information = (ULONG_PTR) deviceRelations;
  1092. } else if ( (status != STATUS_NOT_SUPPORTED) &&
  1093. (deviceRelations == NULL) ) {
  1094. //
  1095. // We explicitely failed the irp, and nobody above us had anything to
  1096. // add.
  1097. //
  1098. Irp->IoStatus.Status = status;
  1099. Irp->IoStatus.Information = (ULONG_PTR) NULL;
  1100. } else {
  1101. //
  1102. // Either we haven't touched the IRP or existing children were already
  1103. // present (placed there by an FDO). Grab our status from what is
  1104. // already present.
  1105. //
  1106. status = Irp->IoStatus.Status;
  1107. }
  1108. //
  1109. // Done with the irp
  1110. //
  1111. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1112. //
  1113. // Done
  1114. //
  1115. ACPIDevPrint( (
  1116. ACPI_PRINT_IRP,
  1117. deviceExtension,
  1118. "(0x%08lx): %s = 0x%08lx\n",
  1119. Irp,
  1120. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  1121. status
  1122. ) );
  1123. return status;
  1124. }
  1125. NTSTATUS
  1126. ACPIBusIrpQueryId(
  1127. IN PDEVICE_OBJECT DeviceObject,
  1128. IN PIRP Irp
  1129. )
  1130. /*++
  1131. Routine Description:
  1132. This routine is the dispatch point for the IRP_MN_QUERY_ID PNP
  1133. minor function
  1134. Note: This is what the returned strings from this function should look
  1135. like. This is from mail that lonny sent.
  1136. DeviceID = ACPI\PNPxxxx
  1137. InstanceID = yyyy
  1138. HardwareID = ACPI\PNPxxxx,*PNPxxxx
  1139. Arguments:
  1140. DeviceObject - The object that we care about
  1141. Irp - The request in question
  1142. Return Value:
  1143. NTSTATUS
  1144. --*/
  1145. {
  1146. BUS_QUERY_ID_TYPE type;
  1147. NTSTATUS status = Irp->IoStatus.Status;
  1148. PDEVICE_EXTENSION deviceExtension;
  1149. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  1150. PUCHAR baseBuffer;
  1151. ULONG baseBufferSize;
  1152. UCHAR minorFunction = irpStack->MinorFunction;
  1153. PAGED_CODE();
  1154. //
  1155. // Get the device extension
  1156. //
  1157. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  1158. //
  1159. // What we do is based on the IdType of the Request...
  1160. //
  1161. type = irpStack->Parameters.QueryId.IdType;
  1162. switch (type) {
  1163. case BusQueryCompatibleIDs:
  1164. //
  1165. // This returns a MULTI-SZ wide string...
  1166. //
  1167. status = ACPIGetCompatibleIDSyncWide(
  1168. deviceExtension,
  1169. &baseBuffer,
  1170. &baseBufferSize
  1171. );
  1172. if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
  1173. status = STATUS_NOT_SUPPORTED;
  1174. break;
  1175. } else if (!NT_SUCCESS(status)) {
  1176. ACPIDevPrint( (
  1177. ACPI_PRINT_FAILURE,
  1178. deviceExtension,
  1179. " (0x%08lx): IRP_MN_QUERY_ID( %d - CID) = 0x%08lx\n",
  1180. Irp,
  1181. type,
  1182. status
  1183. ) );
  1184. break;
  1185. }
  1186. //
  1187. // Store the result in the Irp
  1188. //
  1189. Irp->IoStatus.Information = (ULONG_PTR) baseBuffer;
  1190. break;
  1191. case BusQueryInstanceID:
  1192. //
  1193. // In this case, we have to build the instance id
  1194. //
  1195. status = ACPIGetInstanceIDSyncWide(
  1196. deviceExtension,
  1197. &baseBuffer,
  1198. &baseBufferSize
  1199. );
  1200. if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
  1201. status = STATUS_NOT_SUPPORTED;
  1202. break;
  1203. } else if (!NT_SUCCESS(status)) {
  1204. ACPIDevPrint( (
  1205. ACPI_PRINT_FAILURE,
  1206. deviceExtension,
  1207. " (0x%08lx): IRP_MN_QUERY_ID( %d - UID) = 0x%08lx\n",
  1208. Irp,
  1209. type,
  1210. status
  1211. ) );
  1212. break;
  1213. }
  1214. //
  1215. // Store the result in the Irp
  1216. //
  1217. Irp->IoStatus.Information = (ULONG_PTR) baseBuffer;
  1218. break;
  1219. case BusQueryDeviceID:
  1220. //
  1221. // Get the Device ID as a wide string
  1222. //
  1223. status = ACPIGetDeviceIDSyncWide(
  1224. deviceExtension,
  1225. &baseBuffer,
  1226. &baseBufferSize
  1227. );
  1228. if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
  1229. status = STATUS_NOT_SUPPORTED;
  1230. break;
  1231. } else if (!NT_SUCCESS(status)) {
  1232. ACPIDevPrint( (
  1233. ACPI_PRINT_FAILURE,
  1234. deviceExtension,
  1235. " (0x%08lx): IRP_MN_QUERY_ID( %d - HID) = 0x%08lx\n",
  1236. Irp,
  1237. type,
  1238. status
  1239. ) );
  1240. break;
  1241. }
  1242. //
  1243. // Store the result in the Irp
  1244. //
  1245. Irp->IoStatus.Information = (ULONG_PTR) baseBuffer;
  1246. break;
  1247. case BusQueryHardwareIDs:
  1248. //
  1249. // Get the device ID as a normal string
  1250. //
  1251. status = ACPIGetHardwareIDSyncWide(
  1252. deviceExtension,
  1253. &baseBuffer,
  1254. &baseBufferSize
  1255. );
  1256. if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
  1257. status = STATUS_NOT_SUPPORTED;
  1258. break;
  1259. } else if (!NT_SUCCESS(status)) {
  1260. ACPIDevPrint( (
  1261. ACPI_PRINT_FAILURE,
  1262. deviceExtension,
  1263. " (0x%08lx): IRP_MN_QUERY_ID( %d - UID) = 0x%08lx\n",
  1264. Irp,
  1265. type,
  1266. status
  1267. ) );
  1268. break;
  1269. }
  1270. //
  1271. // Store the result in the Irp
  1272. //
  1273. Irp->IoStatus.Information = (ULONG_PTR) baseBuffer;
  1274. break;
  1275. default:
  1276. ACPIDevPrint( (
  1277. ACPI_PRINT_IRP,
  1278. deviceExtension,
  1279. "(0x%08lx): %s - Unhandled Id %d\n",
  1280. Irp,
  1281. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  1282. type
  1283. ) );
  1284. break;
  1285. } // switch
  1286. //
  1287. // Store the status result of the request and complete it
  1288. //
  1289. Irp->IoStatus.Status = status;
  1290. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1291. ACPIDevPrint( (
  1292. ACPI_PRINT_IRP,
  1293. deviceExtension,
  1294. "(0x%08lx): %s(%d) = 0x%08lx\n",
  1295. Irp,
  1296. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  1297. type,
  1298. status
  1299. ) );
  1300. return status;
  1301. }
  1302. NTSTATUS
  1303. ACPIBusIrpQueryInterface(
  1304. IN PDEVICE_OBJECT DeviceObject,
  1305. IN PIRP Irp
  1306. )
  1307. /*++
  1308. Routine Description:
  1309. This routine handles IRP_MN_QUERY_INTERFACE requests for PDOs owned
  1310. by the ACPI driver. It will eject an 'ACPI' interface and it will
  1311. smash Translator Interfaces for interrupts that have been provided
  1312. by the devnode's FDO.
  1313. Arguments:
  1314. DeviceObject - Pointer to the device object we received the request for
  1315. Irp - Pointer to the request
  1316. Return Value:
  1317. NTSTATUS
  1318. --*/
  1319. {
  1320. CM_RESOURCE_TYPE resource;
  1321. GUID *interfaceType;
  1322. NTSTATUS status = STATUS_NOT_SUPPORTED;
  1323. PDEVICE_EXTENSION deviceExtension;
  1324. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  1325. ULONG count;
  1326. PAGED_CODE();
  1327. //
  1328. // Get the device extension
  1329. //
  1330. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  1331. //
  1332. // Obtain the info we will need from the irp
  1333. //
  1334. resource = (CM_RESOURCE_TYPE)
  1335. PtrToUlong(irpStack->Parameters.QueryInterface.InterfaceSpecificData);
  1336. interfaceType = (LPGUID) irpStack->Parameters.QueryInterface.InterfaceType;
  1337. #if DBG
  1338. {
  1339. NTSTATUS status2;
  1340. UNICODE_STRING guidString;
  1341. status2 = RtlStringFromGUID( interfaceType, &guidString );
  1342. if (NT_SUCCESS(status2)) {
  1343. ACPIDevPrint( (
  1344. ACPI_PRINT_IRP,
  1345. deviceExtension,
  1346. "(0x%08lx): %s - Res %x Type = %wZ\n",
  1347. Irp,
  1348. ACPIDebugGetIrpText(IRP_MJ_PNP, irpStack->MinorFunction),
  1349. resource,
  1350. &guidString
  1351. ) );
  1352. RtlFreeUnicodeString( &guidString );
  1353. }
  1354. }
  1355. #endif
  1356. //
  1357. // *Only* Handle the Guids that we know about. Do Not Ever touch
  1358. // any other GUID
  1359. //
  1360. if (CompareGuid(interfaceType, (PVOID) &GUID_ACPI_INTERFACE_STANDARD)) {
  1361. PACPI_INTERFACE_STANDARD interfaceDestination;
  1362. //
  1363. // Only copy up to current size of the ACPI_INTERFACE structure
  1364. //
  1365. if (irpStack->Parameters.QueryInterface.Size >
  1366. sizeof (ACPI_INTERFACE_STANDARD) ) {
  1367. count = sizeof (ACPI_INTERFACE_STANDARD);
  1368. } else {
  1369. count = irpStack->Parameters.QueryInterface.Size;
  1370. }
  1371. //
  1372. // Find where we will store the interface
  1373. //
  1374. interfaceDestination = (PACPI_INTERFACE_STANDARD)
  1375. irpStack->Parameters.QueryInterface.Interface;
  1376. //
  1377. // Copy from the global table to the caller's table, using size
  1378. // specified. Give caller only what was asked for, for
  1379. // backwards compatibility.
  1380. //
  1381. RtlCopyMemory(
  1382. interfaceDestination,
  1383. &ACPIInterfaceTable,
  1384. count
  1385. );
  1386. //
  1387. // Make sure that we can give the user back the correct context. To do
  1388. // this we need to calculate that the number of bytes we are giving back
  1389. // is at least more than that is required to store a pointer at the
  1390. // correct place in the structure
  1391. //
  1392. if (count > (FIELD_OFFSET(ACPI_INTERFACE_STANDARD, Context) + sizeof(PVOID) ) ) {
  1393. interfaceDestination->Context = DeviceObject;
  1394. }
  1395. //
  1396. // Done with the irp
  1397. //
  1398. status = STATUS_SUCCESS;
  1399. } else if (CompareGuid(interfaceType, (PVOID) &GUID_TRANSLATOR_INTERFACE_STANDARD)) {
  1400. if (resource == CmResourceTypeInterrupt) {
  1401. //
  1402. // Smash any interface that has already been reported because we
  1403. // want to arbitrate UNTRANSLATED resources. We can be certain
  1404. // that the HAL underneath will provide the translator interface that
  1405. // has to be there.
  1406. //
  1407. // TEMPTEMP HACKHACK This should last only as long as the PCI
  1408. // driver is building its IRQ translator.
  1409. //
  1410. // EFN: Remove this HACKHACK on Alpha
  1411. //
  1412. #ifndef _ALPHA_
  1413. if (IsPciBus(DeviceObject)) {
  1414. SmashInterfaceQuery(Irp);
  1415. }
  1416. #endif // _ALPHA_
  1417. } else if ((resource == CmResourceTypePort) || (resource == CmResourceTypeMemory)) {
  1418. //
  1419. // For root PCI buses, determine whether we need to eject a translator or not.
  1420. // This decision will be based on the contents of the _CRS.
  1421. //
  1422. if (IsPciBus(DeviceObject)) {
  1423. status = TranslateEjectInterface(DeviceObject, Irp);
  1424. }
  1425. }
  1426. } else if (CompareGuid(interfaceType, (PVOID) &GUID_PCI_BUS_INTERFACE_STANDARD)) {
  1427. if (IsPciBus(DeviceObject)) {
  1428. status = PciBusEjectInterface(DeviceObject, Irp);
  1429. }
  1430. } else if (CompareGuid(interfaceType, (PVOID) &GUID_BUS_INTERFACE_STANDARD)) {
  1431. //
  1432. // Fail the irp unless we have the correct interface
  1433. //
  1434. Irp->IoStatus.Status = STATUS_NOINTERFACE;
  1435. //
  1436. // Is there are parent to this PDO?
  1437. //
  1438. if (deviceExtension->ParentExtension != NULL) {
  1439. PDEVICE_OBJECT parentObject =
  1440. deviceExtension->ParentExtension->DeviceObject;
  1441. //
  1442. // Make a new irp and send it ownward.
  1443. // Note: Because the Interface pointer is in the IO Stack,
  1444. // by passing down the current stack as the one to copy into
  1445. // the new irp, we effectively get to pass the interfaces for free
  1446. //
  1447. if (parentObject != NULL) {
  1448. Irp->IoStatus.Status = ACPIInternalSendSynchronousIrp(
  1449. parentObject,
  1450. irpStack,
  1451. NULL
  1452. );
  1453. }
  1454. }
  1455. }
  1456. if (status != STATUS_NOT_SUPPORTED) {
  1457. //
  1458. // Set the status code in the Irp to what we will return
  1459. //
  1460. Irp->IoStatus.Status = status;
  1461. } else {
  1462. //
  1463. // Use the status code from the Irp to determine what we will return
  1464. //
  1465. status = Irp->IoStatus.Status;
  1466. }
  1467. //
  1468. // Complete the request
  1469. //
  1470. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1471. return status;
  1472. }
  1473. NTSTATUS
  1474. ACPIBusIrpQueryPnpDeviceState(
  1475. IN PDEVICE_OBJECT DeviceObject,
  1476. IN PIRP Irp
  1477. )
  1478. /*++
  1479. Routine Description:
  1480. This routine is the dispatch point for the IRP_MN_QUERY_DEVICE_STATE
  1481. requests sent to the Physical Device Objects
  1482. Arguments:
  1483. DeviceObject - Pointer to the device object we received the request for
  1484. Irp - Pointer to the request
  1485. Return Value:
  1486. NTSTATUS
  1487. --*/
  1488. {
  1489. PAGED_CODE();
  1490. return ACPIIrpInvokeDispatchRoutine(
  1491. DeviceObject,
  1492. Irp,
  1493. NULL,
  1494. ACPIBusAndFilterIrpQueryPnpDeviceState,
  1495. TRUE,
  1496. TRUE
  1497. );
  1498. }
  1499. NTSTATUS
  1500. ACPIBusIrpQueryPower(
  1501. IN PDEVICE_OBJECT DeviceObject,
  1502. IN PIRP Irp
  1503. )
  1504. /*++
  1505. Routine Description:
  1506. This routines tells the system what PNP state the device is in
  1507. Arguments:
  1508. DeviceObject - The device whose state we want to know
  1509. Irp - The request
  1510. Return Value:
  1511. NTSTATUS
  1512. --*/
  1513. {
  1514. NTSTATUS status;
  1515. PDEVICE_EXTENSION deviceExtension;
  1516. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
  1517. PNSOBJ acpiObject;
  1518. PNSOBJ ejectObject;
  1519. SYSTEM_POWER_STATE systemState;
  1520. ULONG packedEJx;
  1521. //
  1522. // Get the device extension
  1523. //
  1524. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  1525. //
  1526. // Get the Current stack location to determine if we are a system
  1527. // irp or a device irp. We ignore device irps here and any system
  1528. // irp that isn't of type PowerActionWarmEject
  1529. //
  1530. if (irpSp->Parameters.Power.Type != SystemPowerState) {
  1531. //
  1532. // We don't handle this irp
  1533. //
  1534. return ACPIDispatchPowerIrpSuccess( DeviceObject, Irp );
  1535. }
  1536. if (irpSp->Parameters.Power.ShutdownType != PowerActionWarmEject) {
  1537. //
  1538. // No eject work - just complete the IRP.
  1539. //
  1540. return ACPIDispatchPowerIrpSuccess( DeviceObject, Irp );
  1541. }
  1542. if (deviceExtension->Flags & DEV_PROP_NO_OBJECT) {
  1543. //
  1544. // If we don't have an ACPI object, then we can't succeed this request
  1545. //
  1546. return ACPIDispatchPowerIrpFailure( DeviceObject, Irp );
  1547. }
  1548. //
  1549. // Restrict power states to those possible during a warm eject...
  1550. //
  1551. acpiObject = deviceExtension->AcpiObject ;
  1552. if (ACPIDockIsDockDevice(acpiObject)) {
  1553. //
  1554. // Don't touch this device, the profile provider manages eject
  1555. // transitions.
  1556. //
  1557. return ACPIDispatchPowerIrpSuccess( DeviceObject, Irp );
  1558. }
  1559. //
  1560. // What system state are we looking at?
  1561. //
  1562. systemState = irpSp->Parameters.Power.State.SystemState;
  1563. switch (irpSp->Parameters.Power.State.SystemState) {
  1564. case PowerSystemSleeping1: packedEJx = PACKED_EJ1; break;
  1565. case PowerSystemSleeping2: packedEJx = PACKED_EJ2; break;
  1566. case PowerSystemSleeping3: packedEJx = PACKED_EJ3; break;
  1567. case PowerSystemHibernate: packedEJx = PACKED_EJ4; break;
  1568. default: return ACPIDispatchPowerIrpFailure( DeviceObject, Irp );
  1569. }
  1570. //
  1571. // Does the appropriate object exist for this device?
  1572. //
  1573. ejectObject = ACPIAmliGetNamedChild( acpiObject, packedEJx) ;
  1574. if (ejectObject == NULL) {
  1575. //
  1576. // Fail the request, as we cannot eject in this case.
  1577. //
  1578. return ACPIDispatchPowerIrpFailure( DeviceObject, Irp );
  1579. }
  1580. //
  1581. // Succeed the request
  1582. //
  1583. return ACPIDispatchPowerIrpSuccess( DeviceObject, Irp );
  1584. }
  1585. NTSTATUS
  1586. ACPIBusIrpQueryRemoveOrStopDevice(
  1587. IN PDEVICE_OBJECT DeviceObject,
  1588. IN PIRP Irp
  1589. )
  1590. /*++
  1591. Routine Description:
  1592. This routine transitions a device to the Inactive State
  1593. Arguments:
  1594. DeviceObject - The device that is to become inactive
  1595. Irp - The request
  1596. Return Value:
  1597. NTSTATUS
  1598. --*/
  1599. {
  1600. NTSTATUS status;
  1601. PDEVICE_EXTENSION deviceExtension;
  1602. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  1603. UCHAR minorFunction = irpStack->MinorFunction;
  1604. PAGED_CODE();
  1605. //
  1606. // Get the device extension and acpi object
  1607. //
  1608. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  1609. //
  1610. // Are we allowed to stop this device?
  1611. //
  1612. if (deviceExtension->Flags & DEV_CAP_NO_STOP) {
  1613. //
  1614. // No, then fail the irp
  1615. //
  1616. status = STATUS_INVALID_DEVICE_REQUEST;
  1617. } else {
  1618. //
  1619. // Mark the device extension as being inactive
  1620. //
  1621. deviceExtension->PreviousState = deviceExtension->DeviceState;
  1622. deviceExtension->DeviceState = Inactive;
  1623. status = STATUS_SUCCESS;
  1624. }
  1625. //
  1626. // Complete the irp
  1627. //
  1628. Irp->IoStatus.Status = status;
  1629. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1630. //
  1631. // Done processing
  1632. //
  1633. ACPIDevPrint( (
  1634. ACPI_PRINT_IRP,
  1635. deviceExtension,
  1636. "(0x%08lx): %s = 0x%08lx\n",
  1637. Irp,
  1638. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  1639. status
  1640. ) );
  1641. return status;
  1642. }
  1643. NTSTATUS
  1644. ACPIBusIrpQueryResources(
  1645. IN PDEVICE_OBJECT DeviceObject,
  1646. IN PIRP Irp
  1647. )
  1648. /*++
  1649. Routine Description:
  1650. This routine is the dispatch point for the IRP_MN_QUERY_RESOURCES requests sent
  1651. to PDO device objects
  1652. Arguments:
  1653. DeviceObject - Pointer to the device object we received the request for
  1654. Irp - Pointer to the request
  1655. Return Value:
  1656. NTSTATUS
  1657. --*/
  1658. {
  1659. NTSTATUS status;
  1660. PDEVICE_EXTENSION deviceExtension;
  1661. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  1662. PCM_RESOURCE_LIST cmList = NULL;
  1663. PIO_RESOURCE_REQUIREMENTS_LIST ioList = NULL;
  1664. PUCHAR crsBuf = NULL;
  1665. UCHAR minorFunction = irpStack->MinorFunction;
  1666. ULONG deviceStatus;
  1667. ULONG crsBufSize;
  1668. PAGED_CODE();
  1669. //
  1670. // Get the device extension
  1671. //
  1672. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  1673. //
  1674. // Note that at this point, we must evaluate the _DDN for the
  1675. // object and store that in the registry
  1676. //
  1677. ACPIInitDosDeviceName( deviceExtension );
  1678. //
  1679. // The first thing to look for is wether or not the device is present and
  1680. // decoding its resources. We do this by getting the device status and
  1681. // looking at Bit #1
  1682. //
  1683. status = ACPIGetDevicePresenceSync(
  1684. deviceExtension,
  1685. (PVOID *) &deviceStatus,
  1686. NULL
  1687. );
  1688. if (!NT_SUCCESS(status)) {
  1689. goto ACPIBusIrpQueryResourcesExit;
  1690. }
  1691. if ( !(deviceExtension->Flags & DEV_PROP_DEVICE_ENABLED) ) {
  1692. //
  1693. // The device isn't decoding any resources. So asking it for its
  1694. // current resources is doomed to failure
  1695. //
  1696. ACPIDevPrint( (
  1697. ACPI_PRINT_WARNING,
  1698. deviceExtension,
  1699. "(0x%08lx) : ACPIBusIrpQueryResources - Device not Enabled\n",
  1700. Irp
  1701. ) );
  1702. status = STATUS_INVALID_DEVICE_STATE;
  1703. goto ACPIBusIrpQueryResourcesExit;
  1704. }
  1705. //
  1706. // Container objects do not claim resources. So, don't even bother
  1707. // trying to obtain a _CRS
  1708. //
  1709. if (!(deviceExtension->Flags & DEV_CAP_CONTAINER)) {
  1710. //
  1711. // Here we try to find the current resource set
  1712. //
  1713. status = ACPIGetBufferSync(
  1714. deviceExtension,
  1715. PACKED_CRS,
  1716. &crsBuf,
  1717. &crsBufSize
  1718. );
  1719. } else {
  1720. //
  1721. // This is the status code returned if there is no _CRS. It actually
  1722. // doesn't matter what code we use since in the failure case, we
  1723. // should return whatever code was already present in the IRP
  1724. //
  1725. status = STATUS_OBJECT_NAME_NOT_FOUND;
  1726. }
  1727. if (!NT_SUCCESS(status)) {
  1728. //
  1729. // If this is the PCI device, then we *must* succeed, otherwise the OS
  1730. // will not boot.
  1731. //
  1732. if (! (deviceExtension->Flags & DEV_CAP_PCI) ) {
  1733. //
  1734. // Abort. Complete the irp with whatever status code is present
  1735. //
  1736. status = Irp->IoStatus.Status;
  1737. }
  1738. goto ACPIBusIrpQueryResourcesExit;
  1739. }
  1740. //
  1741. // Build a IO_RESOURCE_REQUIREMENT_LISTS
  1742. //
  1743. status = PnpBiosResourcesToNtResources(
  1744. crsBuf,
  1745. (deviceExtension->Flags & DEV_CAP_PCI ?
  1746. PNP_BIOS_TO_IO_NO_CONSUMED_RESOURCES : 0),
  1747. &ioList );
  1748. //
  1749. // Whatever happens, we are done with the buffer
  1750. //
  1751. ExFreePool(crsBuf);
  1752. //
  1753. // if the ioList is empty then we can assume there are no valuable
  1754. // resources in this crs, so we can cleanup.
  1755. //
  1756. if(!ioList){
  1757. if(deviceExtension->Flags & DEV_CAP_PCI){
  1758. //
  1759. // set the status to STATUS_UNSUCCESSFUL so that we catch this when
  1760. // exiting this function and bugcheck.
  1761. //
  1762. status = STATUS_UNSUCCESSFUL;
  1763. }
  1764. goto ACPIBusIrpQueryResourcesExit;
  1765. }
  1766. if (!NT_SUCCESS(status)) {
  1767. //
  1768. // Abort. We failed the irp for a reason. Remember that
  1769. //
  1770. goto ACPIBusIrpQueryResourcesExit;
  1771. }
  1772. //
  1773. // Make sure that if the DEVICE is PCI, that we subtract out the
  1774. // resource that should not be there
  1775. //
  1776. if (deviceExtension->Flags & DEV_CAP_PCI) {
  1777. status = ACPIRangeSubtract(
  1778. &ioList,
  1779. RootDeviceExtension->ResourceList
  1780. );
  1781. if (!NT_SUCCESS(status)) {
  1782. ACPIDevPrint( (
  1783. ACPI_PRINT_CRITICAL,
  1784. deviceExtension,
  1785. "(0x%08lx) : ACPIBusIrpQueryResources "
  1786. "Subtract = 0x%08lx\n",
  1787. Irp,
  1788. status
  1789. ) );
  1790. ExFreePool( ioList );
  1791. goto ACPIBusIrpQueryResourcesExit;
  1792. }
  1793. //
  1794. // Make sure our range is the proper size
  1795. //
  1796. ACPIRangeValidatePciResources( deviceExtension, ioList );
  1797. } else if (deviceExtension->Flags & DEV_CAP_PIC_DEVICE) {
  1798. //
  1799. // Strip out the PIC resources
  1800. //
  1801. status = ACPIRangeFilterPICInterrupt(
  1802. ioList
  1803. );
  1804. if (!NT_SUCCESS(status)) {
  1805. ACPIDevPrint( (
  1806. ACPI_PRINT_CRITICAL,
  1807. deviceExtension,
  1808. "(0x%08lx): ACPIBusIrpQueryResources "
  1809. "FilterPIC = 0x%08lx\n",
  1810. Irp,
  1811. status
  1812. ) );
  1813. ExFreePool( ioList );
  1814. goto ACPIBusIrpQueryResourcesExit;
  1815. }
  1816. }
  1817. //
  1818. // Turn the list into a CM_RESOURCE_LIST
  1819. //
  1820. if (NT_SUCCESS(status)) {
  1821. status = PnpIoResourceListToCmResourceList(
  1822. ioList,
  1823. &cmList
  1824. );
  1825. if (!NT_SUCCESS(status)) {
  1826. ExFreePool( ioList );
  1827. goto ACPIBusIrpQueryResourcesExit;
  1828. }
  1829. }
  1830. //
  1831. // Whatever happens, we are done with the IO list
  1832. //
  1833. ExFreePool(ioList);
  1834. ACPIBusIrpQueryResourcesExit:
  1835. //
  1836. // If this is the PCI device, then we *must* succeed, otherwise the OS
  1837. // will not boot.
  1838. //
  1839. if (!NT_SUCCESS(status) && status != STATUS_INSUFFICIENT_RESOURCES &&
  1840. (deviceExtension->Flags & DEV_CAP_PCI) ) {
  1841. KeBugCheckEx(
  1842. ACPI_BIOS_ERROR,
  1843. ACPI_ROOT_PCI_RESOURCE_FAILURE,
  1844. (ULONG_PTR) deviceExtension,
  1845. 0,
  1846. (ULONG_PTR) Irp
  1847. );
  1848. }
  1849. //
  1850. // Done with Irp
  1851. //
  1852. Irp->IoStatus.Status = status;
  1853. Irp->IoStatus.Information = (ULONG_PTR) ( NT_SUCCESS(status) ? cmList : NULL );
  1854. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1855. //
  1856. // Done
  1857. //
  1858. ACPIDevPrint( (
  1859. ACPI_PRINT_IRP,
  1860. deviceExtension,
  1861. "(0x%08lx): %s = 0x%08lx\n",
  1862. Irp,
  1863. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  1864. status
  1865. ) );
  1866. return status;
  1867. }
  1868. NTSTATUS
  1869. ACPIBusIrpQueryResourceRequirements(
  1870. IN PDEVICE_OBJECT DeviceObject,
  1871. IN PIRP Irp
  1872. )
  1873. /*++
  1874. Routine Description:
  1875. This routine is the dispatch point for the IRP_MN_QUERY_RESOURCES requests sent
  1876. to PDO device objects
  1877. Arguments:
  1878. DeviceObject - Pointer to the device object we received the request for
  1879. Irp - Pointer to the request
  1880. Return Value:
  1881. NTSTATUS
  1882. --*/
  1883. {
  1884. NTSTATUS crsStat;
  1885. NTSTATUS prsStat;
  1886. NTSTATUS status = Irp->IoStatus.Status;
  1887. PCM_RESOURCE_LIST cmList = NULL;
  1888. PDEVICE_EXTENSION deviceExtension;
  1889. PIO_RESOURCE_REQUIREMENTS_LIST resList = NULL;
  1890. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  1891. PUCHAR crsBuf = NULL;
  1892. PUCHAR prsBuf = NULL;
  1893. UCHAR minorFunction = irpStack->MinorFunction;
  1894. ULONG crsBufSize;
  1895. ULONG prsBufSize;
  1896. PAGED_CODE();
  1897. //
  1898. // Get the device extension
  1899. //
  1900. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  1901. //
  1902. // Here we must return a PIO_RESOURCE_REQUIREMENTS_LIST. For
  1903. // now, we will simply obtain some interesting pointers
  1904. // and fall through
  1905. //
  1906. //
  1907. // Container objects are special in that they have _CRS/_PRS but do not
  1908. // claim resources. Rather, they are used to specify a resource
  1909. // translation
  1910. //
  1911. if (!(deviceExtension->Flags & DEV_CAP_CONTAINER)) {
  1912. //
  1913. // Fetch the buffers, as appropriate
  1914. //
  1915. crsStat = ACPIGetBufferSync(
  1916. deviceExtension,
  1917. PACKED_CRS,
  1918. &crsBuf,
  1919. &crsBufSize
  1920. );
  1921. prsStat = ACPIGetBufferSync(
  1922. deviceExtension,
  1923. PACKED_PRS,
  1924. &prsBuf,
  1925. &prsBufSize
  1926. );
  1927. } else {
  1928. //
  1929. // Pretend that there is no _CRS/_PRS present
  1930. //
  1931. crsStat = STATUS_OBJECT_NAME_NOT_FOUND;
  1932. prsStat = STATUS_OBJECT_NAME_NOT_FOUND;
  1933. }
  1934. //
  1935. // If there is a _CRS, then remember to clear the irp-generated status
  1936. // we will want to fall through
  1937. //
  1938. if (NT_SUCCESS(crsStat)) {
  1939. status = STATUS_NOT_SUPPORTED;
  1940. } else if (!NT_SUCCESS(prsStat)) {
  1941. //
  1942. // This is the case where there isn't a _PRS. We jump directly to
  1943. // the point where we complete the irp, note that the irp will
  1944. // be completed with whatever status code is currently present.
  1945. // The only exception to this is if we discovered that we didn't
  1946. // have enough memory to fulfill either operation..
  1947. //
  1948. if (prsStat == STATUS_INSUFFICIENT_RESOURCES ||
  1949. crsStat == STATUS_INSUFFICIENT_RESOURCES) {
  1950. status = STATUS_INSUFFICIENT_RESOURCES;
  1951. }
  1952. goto ACPIBusIrpQueryResourceRequirementsExit;
  1953. }
  1954. //
  1955. // Did we find a PRS?
  1956. //
  1957. if (NT_SUCCESS(prsStat)) {
  1958. //
  1959. // Our first step is to try to use these resources to build the
  1960. // information...
  1961. //
  1962. status = PnpBiosResourcesToNtResources(
  1963. prsBuf,
  1964. 0,
  1965. &resList
  1966. );
  1967. ASSERTMSG("The BIOS has reported inconsistent resources (_PRS). Please upgrade your BIOS.", NT_SUCCESS(status));
  1968. ACPIDevPrint( (
  1969. ACPI_PRINT_IRP,
  1970. deviceExtension,
  1971. "(0x%08lx): %s - ResourcesToNtResources = 0x%08lx\n",
  1972. Irp,
  1973. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  1974. status
  1975. ) );
  1976. //
  1977. // Done with PRS buffer
  1978. //
  1979. ExFreePool(prsBuf);
  1980. //
  1981. // Fall through!!!
  1982. //
  1983. }
  1984. //
  1985. // Earlier, we cleared the status bit if the crsStat was successful. So
  1986. // we should succeed the following this if there was no _PRS, or if there
  1987. // was one but an error occured. Of course, there would have to be
  1988. // a _CRS...
  1989. //
  1990. if (!NT_SUCCESS(status) && NT_SUCCESS(crsStat) ) {
  1991. status = PnpBiosResourcesToNtResources(
  1992. crsBuf,
  1993. (deviceExtension->Flags & DEV_CAP_PCI ?
  1994. PNP_BIOS_TO_IO_NO_CONSUMED_RESOURCES : 0),
  1995. &resList
  1996. );
  1997. ASSERTMSG("The BIOS has reported inconsistent resources (_CRS). Please upgrade your BIOS.", NT_SUCCESS(status));
  1998. }
  1999. //
  2000. // Free the _CRS memory, if appropriate
  2001. //
  2002. if (NT_SUCCESS(crsStat)) {
  2003. ExFreePool( crsBuf );
  2004. }
  2005. //
  2006. // if the resList is empty then we can assume there are no valuable
  2007. // resources in this crs / prs, so we can cleanup.
  2008. //
  2009. if(!resList){
  2010. if(deviceExtension->Flags & DEV_CAP_PCI){
  2011. //
  2012. // set the status to STATUS_UNSUCCESSFUL so that we catch this when
  2013. // exiting this function and bugcheck.
  2014. //
  2015. status = STATUS_UNSUCCESSFUL;
  2016. }
  2017. goto ACPIBusIrpQueryResourceRequirementsExit;
  2018. }
  2019. //
  2020. // Make sure that if the DEVICE is PCI, that we subtract out the
  2021. // resource that should not be there
  2022. //
  2023. if (deviceExtension->Flags & DEV_CAP_PCI) {
  2024. //
  2025. // Make sure our resources are the proper size
  2026. //
  2027. ACPIRangeValidatePciResources( deviceExtension, resList );
  2028. //
  2029. // Subtract out the resources that conflict with the HAL...
  2030. //
  2031. status = ACPIRangeSubtract(
  2032. &resList,
  2033. RootDeviceExtension->ResourceList
  2034. );
  2035. ASSERT(NT_SUCCESS(status));
  2036. if (!NT_SUCCESS(status)) {
  2037. ACPIDevPrint( (
  2038. ACPI_PRINT_CRITICAL,
  2039. deviceExtension,
  2040. "(0x%08lx) : ACPIBusIrpQueryResourceRequirements "
  2041. "Subtract = 0x%08lx\n",
  2042. Irp,
  2043. status
  2044. ) );
  2045. ExFreePool( resList );
  2046. resList = NULL;
  2047. }
  2048. //
  2049. // Make sure our resources are *still* correct
  2050. //
  2051. ACPIRangeValidatePciResources( deviceExtension, resList );
  2052. } else if (deviceExtension->Flags & DEV_CAP_PIC_DEVICE) {
  2053. //
  2054. // Strip out the PIC resources
  2055. //
  2056. status = ACPIRangeFilterPICInterrupt(
  2057. resList
  2058. );
  2059. if (!NT_SUCCESS(status)) {
  2060. ACPIDevPrint( (
  2061. ACPI_PRINT_CRITICAL,
  2062. deviceExtension,
  2063. "(0x%08lx): ACPIBusIrpQueryResources "
  2064. "FilterPIC = 0x%08lx\n",
  2065. Irp,
  2066. status
  2067. ) );
  2068. ExFreePool( resList );
  2069. resList = NULL;
  2070. }
  2071. }
  2072. //
  2073. // Dump the list
  2074. //
  2075. #if DBG
  2076. if (NT_SUCCESS(status)) {
  2077. ACPIDebugResourceRequirementsList( resList, deviceExtension );
  2078. }
  2079. #endif
  2080. //
  2081. // Remember the resource list
  2082. //
  2083. Irp->IoStatus.Information = (ULONG_PTR)
  2084. ( NT_SUCCESS(status) ? resList : NULL );
  2085. ACPIBusIrpQueryResourceRequirementsExit:
  2086. //
  2087. // If this is the PCI device, then we *must* succeed, otherwise the OS
  2088. // will not boot.
  2089. //
  2090. if (!NT_SUCCESS(status) && status != STATUS_INSUFFICIENT_RESOURCES &&
  2091. (deviceExtension->Flags & DEV_CAP_PCI)) {
  2092. ASSERT(NT_SUCCESS(status));
  2093. ACPIDevPrint( (
  2094. ACPI_PRINT_CRITICAL,
  2095. deviceExtension,
  2096. "(0x%08lx): %s = 0x%08lx\n",
  2097. Irp,
  2098. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  2099. status
  2100. ) );
  2101. KeBugCheckEx(
  2102. ACPI_BIOS_ERROR,
  2103. ACPI_ROOT_PCI_RESOURCE_FAILURE,
  2104. (ULONG_PTR) deviceExtension,
  2105. 1,
  2106. (ULONG_PTR) Irp
  2107. );
  2108. }
  2109. //
  2110. // Done Processing Irp
  2111. //
  2112. Irp->IoStatus.Status = status;
  2113. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  2114. //
  2115. // Done
  2116. //
  2117. ACPIDevPrint( (
  2118. ACPI_PRINT_IRP,
  2119. deviceExtension,
  2120. "(0x%08lx): %s = 0x%08lx\n",
  2121. Irp,
  2122. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  2123. status
  2124. ) );
  2125. return status;
  2126. }
  2127. NTSTATUS
  2128. ACPIBusIrpQueryTargetRelation(
  2129. IN PDEVICE_OBJECT DeviceObject,
  2130. IN PIRP Irp,
  2131. OUT PDEVICE_RELATIONS *DeviceRelations
  2132. )
  2133. /*++
  2134. Routine Description:
  2135. This handles DeviceRelations requests sent onto the ACPI driver
  2136. Arguments:
  2137. DeviceObject - The object that we care about...
  2138. Irp - The request in question
  2139. Return Value:
  2140. NTSTATUS
  2141. --*/
  2142. {
  2143. PDEVICE_EXTENSION deviceExtension;
  2144. NTSTATUS status ;
  2145. PAGED_CODE();
  2146. //
  2147. // Nobody should have answered this IRP and sent it down to us. That would
  2148. // be immensely bad...
  2149. //
  2150. ASSERT(*DeviceRelations == NULL) ;
  2151. //
  2152. // Get the device extension
  2153. //
  2154. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  2155. //
  2156. // Allocate some memory for the return buffer
  2157. //
  2158. *DeviceRelations = ExAllocatePoolWithTag(
  2159. NonPagedPool,
  2160. sizeof(DEVICE_RELATIONS),
  2161. ACPI_IRP_POOLTAG
  2162. );
  2163. if (*DeviceRelations == NULL) {
  2164. ACPIDevPrint( (
  2165. ACPI_PRINT_CRITICAL,
  2166. deviceExtension,
  2167. "(0x%08lx): ACPIBusIrpQueryTargetRelation: cannot "
  2168. "allocate %x bytes\n",
  2169. Irp,
  2170. sizeof(DEVICE_RELATIONS)
  2171. ) );
  2172. return STATUS_INSUFFICIENT_RESOURCES;
  2173. }
  2174. //
  2175. // Reference the object
  2176. //
  2177. status = ObReferenceObjectByPointer(
  2178. DeviceObject,
  2179. 0,
  2180. NULL,
  2181. KernelMode
  2182. );
  2183. if (!NT_SUCCESS(status)) {
  2184. ACPIDevPrint( (
  2185. ACPI_PRINT_CRITICAL,
  2186. deviceExtension,
  2187. "(0x%08lx): ACPIBusIrpQueryDeviceRelations: ObReference = %08lx\n",
  2188. Irp,
  2189. status
  2190. ) );
  2191. ExFreePool( *DeviceRelations );
  2192. return status ;
  2193. }
  2194. //
  2195. // Setup the relations
  2196. //
  2197. (*DeviceRelations)->Count = 1;
  2198. (*DeviceRelations)->Objects[0] = DeviceObject;
  2199. //
  2200. // Done
  2201. //
  2202. return status ;
  2203. }
  2204. NTSTATUS
  2205. ACPIBusIrpRemoveDevice(
  2206. IN PDEVICE_OBJECT DeviceObject,
  2207. IN PIRP Irp
  2208. )
  2209. /*++
  2210. Routine Description:
  2211. This routine is called when we need to remove the device object...
  2212. Arguments:
  2213. DeviceObject - The device object to be removed
  2214. Irp - The request
  2215. Return Value:
  2216. NTSTATUS
  2217. --*/
  2218. {
  2219. KIRQL oldIrql;
  2220. LONG oldReferenceCount;
  2221. NTSTATUS status = STATUS_SUCCESS;
  2222. PDEVICE_EXTENSION deviceExtension;
  2223. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  2224. UCHAR minorFunction = irpStack->MinorFunction;
  2225. //
  2226. // Get the device extension.
  2227. //
  2228. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  2229. if (!(deviceExtension->Flags & DEV_TYPE_NOT_ENUMERATED)) {
  2230. //
  2231. // If the device is still physically present, so must the PDO be.
  2232. // This case is essentially a stop.
  2233. //
  2234. deviceExtension->DeviceState = Stopped;
  2235. //
  2236. // Delete the children of this device
  2237. //
  2238. ACPIInitDeleteChildDeviceList( deviceExtension );
  2239. //
  2240. // Mark the request as complete...
  2241. //
  2242. Irp->IoStatus.Status = status;
  2243. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  2244. if (NT_SUCCESS(status)) {
  2245. //
  2246. // Attempt to stop the device, and unlock the device.
  2247. //
  2248. ACPIInitStopDevice( deviceExtension , TRUE);
  2249. }
  2250. return status ;
  2251. }
  2252. //
  2253. // If the device has already been removed, then hhmm...
  2254. //
  2255. if (deviceExtension->DeviceState == Removed) {
  2256. Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE ;
  2257. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  2258. return STATUS_NO_SUCH_DEVICE ;
  2259. }
  2260. //
  2261. // Otherwise, try to stop the device
  2262. //
  2263. if (deviceExtension->DeviceState != SurpriseRemoved) {
  2264. if (IsPciBus(deviceExtension->DeviceObject)) {
  2265. //
  2266. // If this is PCI bridge, then we
  2267. // may have _REG methods to evaluate.
  2268. //
  2269. EnableDisableRegions(deviceExtension->AcpiObject, FALSE);
  2270. }
  2271. //
  2272. // Attempt to stop the device (if possible)
  2273. //
  2274. ACPIInitStopDevice( deviceExtension, TRUE );
  2275. }
  2276. //
  2277. // Delete the children of this device
  2278. //
  2279. ACPIInitDeleteChildDeviceList( deviceExtension );
  2280. //
  2281. // Set the device state as removed
  2282. //
  2283. deviceExtension->DeviceState = Removed;
  2284. //
  2285. // Complete the request
  2286. //
  2287. Irp->IoStatus.Status = STATUS_SUCCESS;
  2288. Irp->IoStatus.Information = (ULONG_PTR) NULL;
  2289. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  2290. //
  2291. // After this point, the device extension is GONE
  2292. //
  2293. ACPIDevPrint( (
  2294. ACPI_PRINT_REMOVE,
  2295. deviceExtension,
  2296. "(0x%08lx): %s = 0x%08lx\n",
  2297. Irp,
  2298. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  2299. STATUS_SUCCESS
  2300. ) );
  2301. //
  2302. // Reset the device extension
  2303. //
  2304. ACPIInitResetDeviceExtension( deviceExtension );
  2305. return STATUS_SUCCESS;
  2306. }
  2307. NTSTATUS
  2308. ACPIBusIrpSetLock(
  2309. IN PDEVICE_OBJECT DeviceObject,
  2310. IN PIRP Irp
  2311. )
  2312. /*++
  2313. Routine Description:
  2314. This routine is the dispatch point for the IRP_MN_SET_LOCK
  2315. requests sent to the PDO.
  2316. Arguments:
  2317. DeviceObject - Pointer to the device object we received the request for
  2318. Irp - Pointer to the request
  2319. Return Value:
  2320. NTSTATUS
  2321. --*/
  2322. {
  2323. PAGED_CODE();
  2324. return ACPIIrpInvokeDispatchRoutine(
  2325. DeviceObject,
  2326. Irp,
  2327. NULL,
  2328. ACPIBusAndFilterIrpSetLock,
  2329. TRUE,
  2330. TRUE
  2331. );
  2332. }
  2333. NTSTATUS
  2334. ACPIBusIrpSetDevicePower(
  2335. IN PDEVICE_OBJECT DeviceObject,
  2336. IN PIRP Irp,
  2337. IN PIO_STACK_LOCATION IrpStack
  2338. )
  2339. /*++
  2340. Routine Description:
  2341. This routine handles device power request for a PDO
  2342. Arguments:
  2343. DeviceObject - The PDO target
  2344. DeviceExtension - The real extension to the target
  2345. Irp - The request
  2346. IrpStack - The current request
  2347. Return Value:
  2348. NTSTATUS
  2349. --*/
  2350. {
  2351. NTSTATUS status;
  2352. PDEVICE_EXTENSION deviceExtension;
  2353. UNREFERENCED_PARAMETER( IrpStack );
  2354. //
  2355. // Get the device extension
  2356. //
  2357. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  2358. //
  2359. // We are going to do some work on the irp, so mark it as being
  2360. // successfull for now
  2361. //
  2362. Irp->IoStatus.Status = STATUS_SUCCESS;
  2363. //
  2364. // Mark the irp as pending
  2365. //
  2366. IoMarkIrpPending( Irp );
  2367. //
  2368. // We might queue up the irp, so this counts as a completion routine.
  2369. // Which means we need to incr the ref count
  2370. //
  2371. InterlockedIncrement( &deviceExtension->OutstandingIrpCount );
  2372. //
  2373. // Queue the irp up. Note that we will *always* call the completion
  2374. // routine, so we don't really care what was returned directly by
  2375. // this call --- the callback gets a chance to execute.
  2376. //
  2377. status = ACPIDeviceIrpDeviceRequest(
  2378. DeviceObject,
  2379. Irp,
  2380. ACPIDeviceIrpCompleteRequest
  2381. );
  2382. //
  2383. // Did we return STATUS_MORE_PROCESSING_REQUIRED (which we used
  2384. // if we overload STATUS_PENDING)
  2385. //
  2386. if (status == STATUS_MORE_PROCESSING_REQUIRED) {
  2387. status = STATUS_PENDING;
  2388. }
  2389. //
  2390. // Note: We called the completion routine, which should have completed
  2391. // the IRP with the same STATUS code as is being returned here (okay, if
  2392. // it is STATUS_PENDING, obviously we haven't completed the IRP, but that
  2393. // is okay).
  2394. //
  2395. return status;
  2396. }
  2397. NTSTATUS
  2398. ACPIBusIrpSetPower (
  2399. IN PDEVICE_OBJECT DeviceObject,
  2400. IN PIRP Irp
  2401. )
  2402. /*++
  2403. Routine Description:
  2404. This routine handles request to set the power state for a Physical
  2405. Device object
  2406. Arguments:
  2407. DeviceObject - The PDO target of the request
  2408. Irp - The request
  2409. Return Value:
  2410. NTSTATUS
  2411. --*/
  2412. {
  2413. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  2414. //
  2415. // Look to see who should actually handle this request
  2416. //
  2417. if (irpStack->Parameters.Power.Type == SystemPowerState) {
  2418. //
  2419. // This is a system request
  2420. //
  2421. return ACPIBusIrpSetSystemPower( DeviceObject, Irp, irpStack );
  2422. } else {
  2423. //
  2424. // This is a device request
  2425. //
  2426. return ACPIBusIrpSetDevicePower( DeviceObject, Irp, irpStack );
  2427. }
  2428. }
  2429. NTSTATUS
  2430. ACPIBusIrpSetSystemPower(
  2431. IN PDEVICE_OBJECT DeviceObject,
  2432. IN PIRP Irp,
  2433. IN PIO_STACK_LOCATION IrpStack
  2434. )
  2435. /*++
  2436. Routine Description:
  2437. This handles request for a system set power irp sent to a PDO
  2438. Arguments:
  2439. DeviceObject - The PDO target of the request
  2440. Irp - The current request
  2441. IrpStack - The current arguments
  2442. Return Value:
  2443. NTSTATUS
  2444. --*/
  2445. {
  2446. DEVICE_POWER_STATE deviceState;
  2447. NTSTATUS status;
  2448. PDEVICE_EXTENSION deviceExtension;
  2449. POWER_STATE powerState;
  2450. SYSTEM_POWER_STATE systemState;
  2451. //
  2452. // Get the device extension
  2453. //
  2454. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  2455. //
  2456. // Grab these two values. They are required for further calculations
  2457. //
  2458. systemState= IrpStack->Parameters.Power.State.SystemState;
  2459. deviceState = deviceExtension->PowerInfo.DevicePowerMatrix[systemState];
  2460. //
  2461. // If our ShutdownAction is PowerActionWarmEject, then we have a special
  2462. // case, and we don't need to request a D-irp for the device
  2463. //
  2464. if (IrpStack->Parameters.Power.ShutdownType == PowerActionWarmEject) {
  2465. ASSERT(!(deviceExtension->Flags & DEV_PROP_NO_OBJECT));
  2466. ASSERT(!ACPIDockIsDockDevice(deviceExtension->AcpiObject));
  2467. //
  2468. // We are going to do some work on the irp, so mark it as being
  2469. // successfull for now
  2470. //
  2471. Irp->IoStatus.Status = STATUS_SUCCESS;
  2472. //
  2473. // Mark the irp as pending
  2474. //
  2475. IoMarkIrpPending( Irp );
  2476. //
  2477. // We might queue up the irp, so this counts as a completion routine.
  2478. // Which means we need to incr the ref count
  2479. //
  2480. InterlockedIncrement( &deviceExtension->OutstandingIrpCount );
  2481. ACPIDevPrint( (
  2482. ACPI_PRINT_REMOVE,
  2483. deviceExtension,
  2484. "(0x%08lx) ACPIBusIrpSetSystemPower: Eject from S%d!\n",
  2485. Irp,
  2486. systemState - PowerSystemWorking
  2487. ) );
  2488. //
  2489. // Request the warm eject
  2490. //
  2491. status = ACPIDeviceIrpWarmEjectRequest(
  2492. deviceExtension,
  2493. Irp,
  2494. ACPIDeviceIrpCompleteRequest,
  2495. FALSE
  2496. );
  2497. //
  2498. // If we got back STATUS_MORE_PROCESSING_REQUIRED, then that is
  2499. // just an alias for STATUS_PENDING, so we make that change now
  2500. //
  2501. if (status == STATUS_MORE_PROCESSING_REQUIRED) {
  2502. status = STATUS_PENDING;
  2503. }
  2504. return status;
  2505. }
  2506. //
  2507. // Look at the device extension and determine if we need to send a
  2508. // D-irp in respond. The rule is that if the device is RAW driven or
  2509. // the current D state of the device is numerically lower then the
  2510. // known D state for the given S state, then we should send the request
  2511. //
  2512. if ( !(deviceExtension->Flags & DEV_CAP_RAW) ) {
  2513. return ACPIDispatchPowerIrpSuccess( DeviceObject, Irp );
  2514. } // if
  2515. if ( (deviceExtension->PowerInfo.PowerState == deviceState) ) {
  2516. return ACPIDispatchPowerIrpSuccess( DeviceObject, Irp );
  2517. } // if
  2518. ACPIDevPrint( (
  2519. ACPI_PRINT_POWER,
  2520. deviceExtension,
  2521. "(0x%08lx) ACPIBusIrpSetSystemPower: send D%d irp!\n",
  2522. Irp,
  2523. deviceState - PowerDeviceD0
  2524. ) );
  2525. //
  2526. // We are going to do some work on the irp, so mark it as being
  2527. // successfull for now
  2528. //
  2529. Irp->IoStatus.Status = STATUS_SUCCESS;
  2530. //
  2531. // Mark the irp as pending
  2532. //
  2533. IoMarkIrpPending( Irp );
  2534. //
  2535. // We might queue up the irp, so this counts as a completion routine.
  2536. // Which means we need to incr the ref count
  2537. //
  2538. InterlockedIncrement( &deviceExtension->OutstandingIrpCount );
  2539. //
  2540. // We need to actually use a PowerState to send the request down, not
  2541. // a device state
  2542. //
  2543. powerState.DeviceState = deviceState;
  2544. //
  2545. // Make the request
  2546. //
  2547. PoRequestPowerIrp(
  2548. DeviceObject,
  2549. IRP_MN_SET_POWER,
  2550. powerState,
  2551. ACPIBusIrpSetSystemPowerComplete,
  2552. Irp,
  2553. NULL
  2554. );
  2555. //
  2556. // Always return pending
  2557. //
  2558. return STATUS_PENDING;
  2559. }
  2560. NTSTATUS
  2561. ACPIBusIrpSetSystemPowerComplete(
  2562. IN PDEVICE_OBJECT DeviceObject,
  2563. IN UCHAR MinorFunction,
  2564. IN POWER_STATE PowerState,
  2565. IN PVOID Context,
  2566. IN PIO_STATUS_BLOCK IoStatus
  2567. )
  2568. /*++
  2569. Routine Description:
  2570. This routine is called when the created D-irp has been sent throughout
  2571. the stack
  2572. Arguments:
  2573. DeviceObject - The device that received the request
  2574. MinorFunction - The function that was requested of the device
  2575. PowerState - The power state the device was sent to
  2576. Context - The original system irp
  2577. IoStatus - The result of the request
  2578. Return Value:
  2579. NTSTATUS
  2580. --*/
  2581. {
  2582. PIRP irp = (PIRP) Context;
  2583. PDEVICE_EXTENSION deviceExtension;
  2584. //
  2585. // Get the device extension
  2586. //
  2587. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  2588. //
  2589. // Make sure that we have cleared the information field
  2590. //
  2591. irp->IoStatus.Information = 0;
  2592. //
  2593. // Call this wrapper function so that we don't have to duplicated code
  2594. //
  2595. ACPIDeviceIrpCompleteRequest(
  2596. deviceExtension,
  2597. (PVOID) irp,
  2598. IoStatus->Status
  2599. );
  2600. //
  2601. // Done
  2602. //
  2603. return IoStatus->Status;
  2604. }
  2605. typedef struct {
  2606. KEVENT Event;
  2607. PIRP Irp;
  2608. } START_DEVICE_CONTEXT, *PSTART_DEVICE_CONTEXT;
  2609. NTSTATUS
  2610. ACPIBusIrpStartDevice(
  2611. IN PDEVICE_OBJECT DeviceObject,
  2612. IN PIRP Irp
  2613. )
  2614. /*++
  2615. Routine Description:
  2616. This handles a request to start the device
  2617. Arguments:
  2618. DeviceObject - The device to start
  2619. Irp - The request to the device to tell it to stop
  2620. Return Value:
  2621. NTSTATUS
  2622. --*/
  2623. {
  2624. NTSTATUS status = STATUS_SUCCESS;
  2625. PDEVICE_EXTENSION deviceExtension;
  2626. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  2627. UCHAR minorFunction = irpStack->MinorFunction;
  2628. PAGED_CODE();
  2629. //
  2630. // Get the device extension and acpi object
  2631. //
  2632. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  2633. //
  2634. // If this is a PCI root bus (the only way that it can be here is if
  2635. // we enumerated this as a PNP0A03 device object) then we need to do
  2636. // a few extra things
  2637. //
  2638. if (deviceExtension->Flags & DEV_CAP_PCI) {
  2639. //
  2640. // The IRQ Arbiter needs to have the FDO of the PCI
  2641. // bus. So here is a PDO. From this, can be gotten
  2642. // the FDO. And only do it once.
  2643. //
  2644. if (!PciInterfacesInstantiated) {
  2645. AcpiArbInitializePciRouting( DeviceObject );
  2646. }
  2647. //
  2648. // We need to get the PME interface as well
  2649. //
  2650. if (!PciPmeInterfaceInstantiated) {
  2651. ACPIWakeInitializePmeRouting( DeviceObject );
  2652. }
  2653. }
  2654. //
  2655. // Pass the real work off to this function
  2656. //
  2657. status = ACPIInitStartDevice(
  2658. DeviceObject,
  2659. irpStack->Parameters.StartDevice.AllocatedResources,
  2660. ACPIBusIrpStartDeviceCompletion,
  2661. Irp,
  2662. Irp
  2663. );
  2664. if (NT_SUCCESS(status)) {
  2665. return STATUS_PENDING;
  2666. } else {
  2667. return status;
  2668. }
  2669. }
  2670. VOID
  2671. ACPIBusIrpStartDeviceCompletion(
  2672. IN PDEVICE_EXTENSION DeviceExtension,
  2673. IN PVOID Context,
  2674. IN NTSTATUS Status
  2675. )
  2676. /*++
  2677. Routine Description:
  2678. This is the call back routine that is invoked when we have finished
  2679. programming the resources
  2680. This routine completes the irp
  2681. Arguments:
  2682. DeviceExtension - Extension of the device that was started
  2683. Context - The Irp
  2684. Status - The result
  2685. Return Value:
  2686. None
  2687. --*/
  2688. {
  2689. PIRP irp = (PIRP) Context;
  2690. PWORK_QUEUE_CONTEXT workContext = &(DeviceExtension->Pdo.WorkContext);
  2691. irp->IoStatus.Status = Status;
  2692. if (NT_SUCCESS(Status)) {
  2693. DeviceExtension->DeviceState = Started;
  2694. } else {
  2695. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( irp );
  2696. UCHAR minorFunction = irpStack->MinorFunction;
  2697. //
  2698. // Complete the irp --- we can do this at DPC level without problem
  2699. //
  2700. IoCompleteRequest( irp, IO_NO_INCREMENT );
  2701. //
  2702. // Let the world know
  2703. //
  2704. ACPIDevPrint( (
  2705. ACPI_PRINT_IRP,
  2706. DeviceExtension,
  2707. "(0x%08lx): %s = 0x%08lx\n",
  2708. irp,
  2709. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  2710. Status
  2711. ) );
  2712. return;
  2713. }
  2714. //
  2715. // We can't run EnableDisableRegions at DPC level,
  2716. // so queue a worker item.
  2717. //
  2718. ExInitializeWorkItem(
  2719. &(workContext->Item),
  2720. ACPIBusIrpStartDeviceWorker,
  2721. workContext
  2722. );
  2723. workContext->DeviceObject = DeviceExtension->DeviceObject;
  2724. workContext->Irp = irp;
  2725. ExQueueWorkItem(
  2726. &(workContext->Item),
  2727. DelayedWorkQueue
  2728. );
  2729. }
  2730. VOID
  2731. ACPIBusIrpStartDeviceWorker(
  2732. IN PVOID Context
  2733. )
  2734. /*++
  2735. Routine Description:
  2736. This routine is called at PASSIVE_LEVEL after we after turned on the
  2737. device
  2738. Arguments:
  2739. Context - Contains the arguments passed to the START_DEVICE function
  2740. Return Value:
  2741. None
  2742. --*/
  2743. {
  2744. NTSTATUS status;
  2745. PDEVICE_EXTENSION deviceExtension;
  2746. PDEVICE_OBJECT deviceObject;
  2747. PIRP irp;
  2748. PIO_STACK_LOCATION irpStack;
  2749. PWORK_QUEUE_CONTEXT workContext = (PWORK_QUEUE_CONTEXT) Context;
  2750. UCHAR minorFunction;
  2751. PAGED_CODE();
  2752. //
  2753. // Grab the parameters that we need out of the Context
  2754. //
  2755. deviceObject = workContext->DeviceObject;
  2756. deviceExtension = ACPIInternalGetDeviceExtension( deviceObject );
  2757. irp = workContext->Irp;
  2758. irpStack = IoGetCurrentIrpStackLocation( irp );
  2759. minorFunction = irpStack->MinorFunction;
  2760. status = irp->IoStatus.Status;
  2761. //
  2762. // Update the status of the device
  2763. //
  2764. if (NT_SUCCESS(status)) {
  2765. if (IsNsobjPciBus(deviceExtension->AcpiObject)) {
  2766. //
  2767. // This may be a PCI bridge, so we
  2768. // may have _REG methods to evaluate.
  2769. // N.B. This work is done here, instead
  2770. // of in ACPIBusIrpStartDevice because we
  2771. // need to wait until after the resources
  2772. // have been programmed.
  2773. //
  2774. EnableDisableRegions(deviceExtension->AcpiObject, TRUE);
  2775. }
  2776. }
  2777. //
  2778. // Complete the request
  2779. //
  2780. irp->IoStatus.Status = status;
  2781. irp->IoStatus.Information = (ULONG_PTR) NULL;
  2782. IoCompleteRequest( irp, IO_NO_INCREMENT );
  2783. //
  2784. // Let the world know
  2785. //
  2786. ACPIDevPrint( (
  2787. ACPI_PRINT_IRP,
  2788. deviceExtension,
  2789. "(0x%08lx): %s = 0x%08lx\n",
  2790. irp,
  2791. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  2792. status
  2793. ) );
  2794. }
  2795. NTSTATUS
  2796. ACPIBusIrpStopDevice(
  2797. IN PDEVICE_OBJECT DeviceObject,
  2798. IN PIRP Irp
  2799. )
  2800. /*++
  2801. Routine Description:
  2802. This handles a request to stop the device...
  2803. Arguments:
  2804. DeviceObject - The device to stop
  2805. Irp - The request to the device to tell it to stop..
  2806. Return Value:
  2807. NTSTATUS
  2808. --*/
  2809. {
  2810. NTSTATUS status = STATUS_SUCCESS;
  2811. PDEVICE_EXTENSION deviceExtension;
  2812. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  2813. PNSOBJ acpiObject;
  2814. UCHAR minorFunction = irpStack->MinorFunction;
  2815. PAGED_CODE();
  2816. //
  2817. // Get the device extension and acpi object
  2818. //
  2819. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  2820. acpiObject = deviceExtension->AcpiObject;
  2821. //
  2822. // We are trying to be intelligent here. If we got a stop without being
  2823. // in the inactive state, then we should remember what state we where in
  2824. //
  2825. if (deviceExtension->DeviceState != Inactive) {
  2826. deviceExtension->DeviceState = deviceExtension->PreviousState;
  2827. }
  2828. if (IsPciBus(deviceExtension->DeviceObject)) {
  2829. //
  2830. // If this is PCI bridge, then we
  2831. // may have _REG methods to evaluate.
  2832. //
  2833. EnableDisableRegions(deviceExtension->AcpiObject, FALSE);
  2834. }
  2835. //
  2836. // Set the device as 'Stopped'
  2837. //
  2838. deviceExtension->DeviceState = Stopped;
  2839. //
  2840. // Mark the request as complete...
  2841. //
  2842. Irp->IoStatus.Status = status;
  2843. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  2844. if (NT_SUCCESS(status)) {
  2845. //
  2846. // Attempt to stop the device
  2847. //
  2848. ACPIInitStopDevice( deviceExtension, FALSE );
  2849. }
  2850. //
  2851. // Done
  2852. //
  2853. ACPIDevPrint( (
  2854. ACPI_PRINT_IRP,
  2855. deviceExtension,
  2856. "(0x%08lx): %s = 0x%08lx\n",
  2857. Irp,
  2858. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  2859. status
  2860. ) );
  2861. return status;
  2862. }
  2863. NTSTATUS
  2864. ACPIBusIrpSurpriseRemoval(
  2865. IN PDEVICE_OBJECT DeviceObject,
  2866. IN PIRP Irp
  2867. )
  2868. /*++
  2869. Routine Description:
  2870. This routine is the dispatch point for surprise remove
  2871. Arguments:
  2872. DeviceObject - The device object
  2873. Irp - The request in question
  2874. Return Value:
  2875. NTSTATUS
  2876. --*/
  2877. {
  2878. KIRQL oldIrql;
  2879. NTSTATUS status = STATUS_SUCCESS;
  2880. PDEVICE_EXTENSION deviceExtension;
  2881. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  2882. PNSOBJ acpiObject;
  2883. UCHAR minorFunction = irpStack->MinorFunction;
  2884. PDEVICE_EXTENSION newDeviceExtension ;
  2885. //
  2886. // Get the device extension and acpi object.
  2887. //
  2888. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  2889. acpiObject = deviceExtension->AcpiObject;
  2890. //
  2891. // If we are already removed, then this isn't a valid request
  2892. //
  2893. if (deviceExtension->DeviceState == Removed) {
  2894. return ACPIDispatchIrpSurpriseRemoved( DeviceObject, Irp );
  2895. }
  2896. if ( !ACPIInternalIsReportedMissing(deviceExtension) ) {
  2897. //
  2898. // If the device is still physically present, then an FDO used
  2899. // IoInvalidatePnpDeviceState to set the device to disabled. No
  2900. // QueryRemove/Remove combination happens here, we just get a
  2901. // SurpriseRemove as we are already started. It is actually appropriate
  2902. // to set it to stop as we may get restarted after remove strips the
  2903. // complaining FDO off.
  2904. //
  2905. deviceExtension->DeviceState = Stopped;
  2906. //
  2907. // Mark the request as complete...
  2908. //
  2909. Irp->IoStatus.Status = status;
  2910. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  2911. if (NT_SUCCESS(status)) {
  2912. //
  2913. // Attempt to stop the device
  2914. //
  2915. ACPIInitStopDevice( deviceExtension, TRUE );
  2916. }
  2917. return status;
  2918. }
  2919. if (IsPciBus(deviceExtension->DeviceObject)) {
  2920. //
  2921. // If this is PCI bridge, then we
  2922. // may have _REG methods to evaluate.
  2923. //
  2924. EnableDisableRegions(deviceExtension->AcpiObject, FALSE);
  2925. }
  2926. //
  2927. // Set the device state as surprise removed
  2928. //
  2929. deviceExtension->DeviceState = SurpriseRemoved;
  2930. //
  2931. // Attempt to stop the device (if possible)
  2932. //
  2933. ACPIInitStopDevice( deviceExtension, TRUE );
  2934. //
  2935. // Is the device really gone? In other words, did ACPI not see it the
  2936. // last time that it was enumerated?
  2937. //
  2938. ACPIBuildSurpriseRemovedExtension(deviceExtension);
  2939. //
  2940. // Complete the request
  2941. //
  2942. Irp->IoStatus.Status = status ;
  2943. Irp->IoStatus.Information = (ULONG_PTR) NULL;
  2944. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  2945. //
  2946. // Done
  2947. //
  2948. ACPIDevPrint( (
  2949. ACPI_PRINT_REMOVE,
  2950. deviceExtension,
  2951. "(0x%08lx): %s = 0x%08lx\n",
  2952. Irp,
  2953. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  2954. status
  2955. ) );
  2956. return status ;
  2957. }
  2958. NTSTATUS
  2959. ACPIBusIrpUnhandled(
  2960. IN PDEVICE_OBJECT DeviceObject,
  2961. IN PIRP Irp
  2962. )
  2963. /*++
  2964. Routine Description:
  2965. This routine is the dispatch point for all unhandled irps
  2966. Arguments:
  2967. DeviceObject - The device object that we (do not) care about
  2968. Irp - The request in question
  2969. Return Value:
  2970. NTSTATUS
  2971. --*/
  2972. {
  2973. NTSTATUS status;
  2974. PDEVICE_EXTENSION deviceExtension;
  2975. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  2976. UCHAR minorFunction = irpStack->MinorFunction;
  2977. //
  2978. // Get the device extension
  2979. //
  2980. deviceExtension = ACPIInternalGetDeviceExtension( DeviceObject );
  2981. //
  2982. // Auto-complete the IRP as something we don't handle...
  2983. //
  2984. status = Irp->IoStatus.Status;
  2985. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  2986. //
  2987. // Done
  2988. //
  2989. ACPIDevPrint( (
  2990. ACPI_PRINT_IRP,
  2991. deviceExtension,
  2992. "(0x%08lx): %s = 0x%08lx\n",
  2993. Irp,
  2994. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  2995. status
  2996. ) );
  2997. return status;
  2998. }
  2999. VOID
  3000. SmashInterfaceQuery(
  3001. IN OUT PIRP Irp
  3002. )
  3003. {
  3004. GUID *interfaceType;
  3005. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  3006. PAGED_CODE();
  3007. interfaceType = (LPGUID) irpStack->Parameters.QueryInterface.InterfaceType;
  3008. RtlZeroMemory(interfaceType, sizeof(GUID));
  3009. Irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
  3010. }