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.

1932 lines
48 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. ixpnpdrv.c
  5. Abstract:
  6. Implements functionality necessary for the
  7. HAL to become a PnP-style device driver
  8. after system initialization. This is done
  9. so that the HAL can enumerate the ACPI driver
  10. in the way that the PnP stuff expects.
  11. Author:
  12. Jake Oshins (jakeo) 27-Jan-1997
  13. Environment:
  14. Kernel mode only.
  15. Revision History:
  16. --*/
  17. #include "halp.h"
  18. #include "acpitabl.h"
  19. #include "exboosts.h"
  20. #include "wchar.h"
  21. #include "xxacpi.h"
  22. //
  23. // Cause the GUID to be defined.
  24. //
  25. #ifdef ALLOC_DATA_PRAGMA
  26. #pragma const_seg("PAGECONST")
  27. #endif // ALLOC_DATA_PRAGMA
  28. #include "initguid.h"
  29. #include "wdmguid.h"
  30. #include "halpnpp.h"
  31. #ifdef ALLOC_DATA_PRAGMA
  32. #pragma const_seg()
  33. #endif // ALLOC_DATA_PRAGMA
  34. #if DBG
  35. ULONG HalDebug = 0;
  36. #endif
  37. extern WCHAR HalHardwareIdString[];
  38. #if defined(NT_UP) && defined(APIC_HAL)
  39. extern WCHAR MpHalHardwareIdString[];
  40. #endif
  41. typedef enum {
  42. Hal = 0x80,
  43. AcpiDriver,
  44. WdDriver
  45. } PDO_TYPE;
  46. typedef enum {
  47. PdoExtensionType = 0xc0,
  48. FdoExtensionType
  49. } EXTENSION_TYPE;
  50. typedef struct _PDO_EXTENSION *PPDO_EXTENSION;
  51. typedef struct _FDO_EXTENSION *PFDO_EXTENSION;
  52. typedef struct _PDO_EXTENSION{
  53. EXTENSION_TYPE ExtensionType;
  54. PPDO_EXTENSION Next;
  55. PDEVICE_OBJECT PhysicalDeviceObject;
  56. PFDO_EXTENSION ParentFdoExtension;
  57. PDO_TYPE PdoType;
  58. //
  59. // Only valid if PdoType == WdDriver
  60. //
  61. PWATCHDOG_TIMER_RESOURCE_TABLE WdTable;
  62. } PDO_EXTENSION, *PPDO_EXTENSION;
  63. #define ASSERT_PDO_EXTENSION(x) ASSERT((x)->ExtensionType == PdoExtensionType );
  64. typedef struct _FDO_EXTENSION{
  65. EXTENSION_TYPE ExtensionType;
  66. PPDO_EXTENSION ChildPdoList;
  67. PDEVICE_OBJECT PhysicalDeviceObject; // PDO passed into AddDevice()
  68. PDEVICE_OBJECT FunctionalDeviceObject;
  69. PDEVICE_OBJECT AttachedDeviceObject;
  70. } FDO_EXTENSION, *PFDO_EXTENSION;
  71. #define ASSERT_FDO_EXTENSION(x) ASSERT((x)->ExtensionType == FdoExtensionType );
  72. INT_ROUTE_INTERFACE_STANDARD PciIrqRoutingInterface = {0};
  73. NTSTATUS
  74. HalpDriverEntry (
  75. IN PDRIVER_OBJECT DriverObject,
  76. IN PUNICODE_STRING RegistryPath
  77. );
  78. NTSTATUS
  79. HalpAddDevice(
  80. IN PDRIVER_OBJECT DriverObject,
  81. IN PDEVICE_OBJECT PhysicalDeviceObject
  82. );
  83. NTSTATUS
  84. HalpDispatchPnp(
  85. IN PDEVICE_OBJECT DeviceObject,
  86. IN OUT PIRP Irp
  87. );
  88. NTSTATUS
  89. HalpDispatchPower(
  90. IN PDEVICE_OBJECT DeviceObject,
  91. IN OUT PIRP Irp
  92. );
  93. NTSTATUS
  94. HalpDispatchWmi(
  95. IN PDEVICE_OBJECT DeviceObject,
  96. IN OUT PIRP Irp
  97. );
  98. NTSTATUS
  99. HalpQueryDeviceRelations(
  100. IN PDEVICE_OBJECT DeviceObject,
  101. IN DEVICE_RELATION_TYPE RelationType,
  102. OUT PDEVICE_RELATIONS *DeviceRelations
  103. );
  104. NTSTATUS
  105. HalpQueryIdPdo(
  106. IN PDEVICE_OBJECT PdoExtension,
  107. IN BUS_QUERY_ID_TYPE IdType,
  108. IN OUT PWSTR *BusQueryId
  109. );
  110. NTSTATUS
  111. HalpQueryIdFdo(
  112. IN PDEVICE_OBJECT PdoExtension,
  113. IN BUS_QUERY_ID_TYPE IdType,
  114. IN OUT PWSTR *BusQueryId
  115. );
  116. NTSTATUS
  117. HalpQueryCapabilities(
  118. IN PDEVICE_OBJECT PdoExtension,
  119. IN PDEVICE_CAPABILITIES Capabilities
  120. );
  121. NTSTATUS
  122. HalpQueryResources(
  123. PDEVICE_OBJECT DeviceObject,
  124. PCM_RESOURCE_LIST *Resources
  125. );
  126. NTSTATUS
  127. HalpQueryResourceRequirements(
  128. PDEVICE_OBJECT DeviceObject,
  129. PIO_RESOURCE_REQUIREMENTS_LIST *Requirements
  130. );
  131. NTSTATUS
  132. HalpQueryInterface(
  133. IN PDEVICE_OBJECT DeviceObject,
  134. IN LPCGUID InterfaceType,
  135. IN USHORT Version,
  136. IN PVOID InterfaceSpecificData,
  137. IN ULONG InterfaceBufferSize,
  138. IN OUT PINTERFACE Interface,
  139. IN OUT PULONG_PTR Length
  140. );
  141. #if defined(_WIN64)
  142. //
  143. // Define the PNP interface functions.
  144. //
  145. VOID
  146. HalPnpInterfaceReference(
  147. PVOID Context
  148. );
  149. VOID
  150. HalPnpInterfaceDereference(
  151. PVOID Context
  152. );
  153. struct _DMA_ADAPTER *
  154. HalPnpGetDmaAdapter(
  155. IN PVOID Context,
  156. IN struct _DEVICE_DESCRIPTION *DeviceDescriptor,
  157. OUT PULONG NumberOfMapRegisters
  158. );
  159. #endif // _WIN64
  160. NTSTATUS
  161. HalIrqTranslateResourcesRoot(
  162. IN PVOID Context,
  163. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
  164. IN RESOURCE_TRANSLATION_DIRECTION Direction,
  165. IN ULONG AlternativesCount, OPTIONAL
  166. IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
  167. IN PDEVICE_OBJECT PhysicalDeviceObject,
  168. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
  169. );
  170. NTSTATUS
  171. HalIrqTranslateResourceRequirementsRoot(
  172. IN PVOID Context,
  173. IN PIO_RESOURCE_DESCRIPTOR Source,
  174. IN PDEVICE_OBJECT PhysicalDeviceObject,
  175. OUT PULONG TargetCount,
  176. OUT PIO_RESOURCE_DESCRIPTOR *Target
  177. );
  178. VOID
  179. HalpMaskAcpiInterrupt(
  180. VOID
  181. );
  182. VOID
  183. HalpUnmaskAcpiInterrupt(
  184. VOID
  185. );
  186. // from xxacpi.c
  187. NTSTATUS
  188. HalpQueryAcpiResourceRequirements(
  189. IN PIO_RESOURCE_REQUIREMENTS_LIST *Requirements
  190. );
  191. NTSTATUS
  192. HalpOpenRegistryKey(
  193. OUT PHANDLE Handle,
  194. IN HANDLE BaseHandle OPTIONAL,
  195. IN PUNICODE_STRING KeyName,
  196. IN ACCESS_MASK DesiredAccess,
  197. IN BOOLEAN Create
  198. );
  199. PVOID
  200. HalpGetAcpiTable(
  201. IN ULONG Signature
  202. );
  203. #ifdef ACPI_CMOS_ACTIVATE
  204. VOID
  205. HalpCmosNullReference(
  206. PVOID Context
  207. );
  208. VOID
  209. HalpCmosNullDereference(
  210. PVOID Context
  211. );
  212. #endif // ACPI_CMOS_ACTIVATE
  213. #define HAL_DRIVER_NAME L"\\Driver\\ACPI_HAL"
  214. #ifdef ALLOC_PRAGMA
  215. #pragma alloc_text(PAGE, HaliInitPnpDriver)
  216. #pragma alloc_text(PAGE, HalpOpenRegistryKey)
  217. #pragma alloc_text(PAGE, HalpDriverEntry)
  218. #pragma alloc_text(PAGE, HalpAddDevice)
  219. #pragma alloc_text(PAGE, HalpDispatchPnp)
  220. #pragma alloc_text(PAGELK, HalpDispatchPower)
  221. #pragma alloc_text(PAGE, HalpDispatchWmi)
  222. #pragma alloc_text(PAGE, HalpQueryDeviceRelations)
  223. #pragma alloc_text(PAGE, HalpQueryIdPdo)
  224. #pragma alloc_text(PAGE, HalpQueryIdFdo)
  225. #pragma alloc_text(PAGE, HalpQueryCapabilities)
  226. #pragma alloc_text(PAGE, HalpQueryResources)
  227. #pragma alloc_text(PAGE, HalpQueryResourceRequirements)
  228. #pragma alloc_text(PAGE, HalpQueryInterface)
  229. #endif
  230. PDRIVER_OBJECT HalpDriverObject;
  231. NTSTATUS
  232. HaliInitPnpDriver(
  233. VOID
  234. )
  235. /*++
  236. Routine Description:
  237. This routine starts the process of making the HAL into
  238. a "driver," which is necessary because we need to
  239. enumerate a Plug and Play PDO for the ACPI driver.
  240. Arguments:
  241. None.
  242. Return Value:
  243. NTSTATUS.
  244. --*/
  245. {
  246. UNICODE_STRING DriverName;
  247. NTSTATUS Status;
  248. PAGED_CODE();
  249. RtlInitUnicodeString( &DriverName, HAL_DRIVER_NAME );
  250. Status = IoCreateDriver( &DriverName, HalpDriverEntry );
  251. ASSERT( NT_SUCCESS( Status ));
  252. return Status;
  253. }
  254. NTSTATUS
  255. HalpOpenRegistryKey(
  256. OUT PHANDLE Handle,
  257. IN HANDLE BaseHandle OPTIONAL,
  258. IN PUNICODE_STRING KeyName,
  259. IN ACCESS_MASK DesiredAccess,
  260. IN BOOLEAN Create
  261. )
  262. /*++
  263. Routine Description:
  264. Opens or creates a VOLATILE registry key using the name passed in based
  265. at the BaseHandle node.
  266. Arguments:
  267. Handle - Pointer to the handle which will contain the registry key that
  268. was opened.
  269. BaseHandle - Handle to the base path from which the key must be opened.
  270. KeyName - Name of the Key that must be opened/created.
  271. DesiredAccess - Specifies the desired access that the caller needs to
  272. the key.
  273. Create - Determines if the key is to be created if it does not exist.
  274. Return Value:
  275. The function value is the final status of the operation.
  276. --*/
  277. {
  278. OBJECT_ATTRIBUTES objectAttributes;
  279. ULONG disposition;
  280. PAGED_CODE();
  281. //
  282. // Initialize the object for the key.
  283. //
  284. InitializeObjectAttributes( &objectAttributes,
  285. KeyName,
  286. OBJ_CASE_INSENSITIVE,
  287. BaseHandle,
  288. (PSECURITY_DESCRIPTOR) NULL );
  289. //
  290. // Create the key or open it, as appropriate based on the caller's
  291. // wishes.
  292. //
  293. if (Create) {
  294. return ZwCreateKey( Handle,
  295. DesiredAccess,
  296. &objectAttributes,
  297. 0,
  298. (PUNICODE_STRING) NULL,
  299. REG_OPTION_VOLATILE,
  300. &disposition );
  301. } else {
  302. return ZwOpenKey( Handle,
  303. DesiredAccess,
  304. &objectAttributes );
  305. }
  306. }
  307. NTSTATUS
  308. HalpDriverEntry (
  309. IN PDRIVER_OBJECT DriverObject,
  310. IN PUNICODE_STRING RegistryPath
  311. )
  312. /*++
  313. Routine Description:
  314. This is the callback function when we call IoCreateDriver to create a
  315. PnP Driver Object. In this function, we need to remember the DriverObject.
  316. Arguments:
  317. DriverObject - Pointer to the driver object created by the system.
  318. RegistryPath - is NULL.
  319. Return Value:
  320. STATUS_SUCCESS
  321. --*/
  322. {
  323. NTSTATUS status;
  324. PDEVICE_OBJECT detectedDeviceObject = NULL;
  325. ANSI_STRING AKeyName;
  326. PAGED_CODE();
  327. //
  328. // File the pointer to our driver object away
  329. //
  330. HalpDriverObject = DriverObject;
  331. //
  332. // Fill in the driver object
  333. //
  334. DriverObject->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE)HalpAddDevice;
  335. DriverObject->MajorFunction[ IRP_MJ_PNP ] = HalpDispatchPnp;
  336. DriverObject->MajorFunction[ IRP_MJ_POWER ] = HalpDispatchPower;
  337. DriverObject->MajorFunction[ IRP_MJ_SYSTEM_CONTROL ] = HalpDispatchWmi;
  338. status = IoReportDetectedDevice(DriverObject,
  339. InterfaceTypeUndefined,
  340. -1,
  341. -1,
  342. NULL,
  343. NULL,
  344. FALSE,
  345. &detectedDeviceObject);
  346. ASSERT(detectedDeviceObject);
  347. if (!(NT_SUCCESS(status))) {
  348. return status;
  349. }
  350. HalpAddDevice(DriverObject,
  351. detectedDeviceObject);
  352. return STATUS_SUCCESS;
  353. }
  354. NTSTATUS
  355. HalpAddDevice(
  356. IN PDRIVER_OBJECT DriverObject,
  357. IN PDEVICE_OBJECT PhysicalDeviceObject
  358. )
  359. /*++
  360. Routine Description:
  361. This routine handles AddDevice for an madeup PDO device.
  362. Arguments:
  363. DriverObject - Pointer to our pseudo driver object.
  364. DeviceObject - Pointer to the device object for which this requestapplies.
  365. Return Value:
  366. NT status.
  367. --*/
  368. {
  369. PDEVICE_OBJECT functionalDeviceObject;
  370. PDEVICE_OBJECT acpiChildDeviceObject;
  371. PDEVICE_OBJECT wdChildDeviceObject;
  372. PDEVICE_OBJECT AttachedDevice;
  373. NTSTATUS status;
  374. PFDO_EXTENSION FdoExtension;
  375. PPDO_EXTENSION AcpiPdoExtension;
  376. PPDO_EXTENSION WdPdoExtension;
  377. PWATCHDOG_TIMER_RESOURCE_TABLE WdTable;
  378. PAGED_CODE();
  379. //
  380. // We've been given the PhysicalDeviceObject. Create the
  381. // FunctionalDeviceObject. Our FDO will be nameless.
  382. //
  383. status = IoCreateDevice(
  384. DriverObject, // our driver object
  385. sizeof(FDO_EXTENSION), // size of our extension
  386. NULL, // our name
  387. FILE_DEVICE_BUS_EXTENDER, // device type
  388. 0, // device characteristics
  389. FALSE, // not exclusive
  390. &functionalDeviceObject // store new device object here
  391. );
  392. if( !NT_SUCCESS( status )){
  393. DbgBreakPoint();
  394. return status;
  395. }
  396. //
  397. // Fill in the FDO extension
  398. //
  399. FdoExtension = (PFDO_EXTENSION)functionalDeviceObject->DeviceExtension;
  400. FdoExtension->ExtensionType = FdoExtensionType;
  401. FdoExtension->PhysicalDeviceObject = PhysicalDeviceObject;
  402. FdoExtension->FunctionalDeviceObject = functionalDeviceObject;
  403. functionalDeviceObject->Flags &= ~(DO_DEVICE_INITIALIZING);
  404. //
  405. // Now attach to the PDO we were given.
  406. //
  407. AttachedDevice = IoAttachDeviceToDeviceStack(functionalDeviceObject,
  408. PhysicalDeviceObject );
  409. if(AttachedDevice == NULL){
  410. //
  411. // Couldn't attach. Delete the FDO.
  412. //
  413. IoDeleteDevice( functionalDeviceObject );
  414. return STATUS_NO_SUCH_DEVICE;
  415. }
  416. FdoExtension->AttachedDeviceObject = AttachedDevice;
  417. //
  418. // Next, create a PDO for the ACPI driver.
  419. //
  420. status = IoCreateDevice(
  421. DriverObject, // our driver object
  422. sizeof(PDO_EXTENSION), // size of our extension
  423. NULL, // our name
  424. FILE_DEVICE_BUS_EXTENDER, // device type
  425. FILE_AUTOGENERATED_DEVICE_NAME, // device characteristics
  426. FALSE, // not exclusive
  427. &acpiChildDeviceObject // store new device object here
  428. );
  429. if (!NT_SUCCESS(status)) {
  430. HalPrint(("Could not create ACPI device object status=0x%08x",status));
  431. return status;
  432. }
  433. //
  434. // Fill in the PDO extension
  435. //
  436. AcpiPdoExtension = (PPDO_EXTENSION)acpiChildDeviceObject->DeviceExtension;
  437. AcpiPdoExtension->ExtensionType = PdoExtensionType;
  438. AcpiPdoExtension->Next = NULL;
  439. AcpiPdoExtension->PhysicalDeviceObject = acpiChildDeviceObject;
  440. AcpiPdoExtension->ParentFdoExtension = FdoExtension;
  441. AcpiPdoExtension->PdoType = AcpiDriver;
  442. //
  443. // Look for the watchdog timer ACPI table
  444. // and if it is found then eject a PDO to handle the device
  445. //
  446. WdTable = (PWATCHDOG_TIMER_RESOURCE_TABLE) HalpGetAcpiTable( WDTT_SIGNATURE );
  447. if (WdTable) {
  448. //
  449. // Next, create a PDO for the WD driver.
  450. //
  451. status = IoCreateDevice(
  452. DriverObject, // our driver object
  453. sizeof(PDO_EXTENSION), // size of our extension
  454. NULL, // our name
  455. FILE_DEVICE_BUS_EXTENDER, // device type
  456. FILE_AUTOGENERATED_DEVICE_NAME, // device characteristics
  457. FALSE, // not exclusive
  458. &wdChildDeviceObject // store new device object here
  459. );
  460. if (!NT_SUCCESS(status)) {
  461. HalPrint(("Could not create WD device object status=0x%08x",status));
  462. IoDeleteDevice( acpiChildDeviceObject );
  463. return status;
  464. }
  465. //
  466. // Fill in the PDO extension
  467. //
  468. WdPdoExtension = (PPDO_EXTENSION)wdChildDeviceObject->DeviceExtension;
  469. WdPdoExtension->ExtensionType = PdoExtensionType;
  470. WdPdoExtension->Next = NULL;
  471. WdPdoExtension->PhysicalDeviceObject = wdChildDeviceObject;
  472. WdPdoExtension->ParentFdoExtension = FdoExtension;
  473. WdPdoExtension->PdoType = WdDriver;
  474. WdPdoExtension->WdTable = WdTable;
  475. //
  476. // Link in the device extension
  477. //
  478. AcpiPdoExtension->Next = WdPdoExtension;
  479. wdChildDeviceObject->Flags &= ~(DO_DEVICE_INITIALIZING);
  480. }
  481. acpiChildDeviceObject->Flags &= ~(DO_DEVICE_INITIALIZING);
  482. //
  483. // Record this as a child of the HAL
  484. //
  485. FdoExtension->ChildPdoList = AcpiPdoExtension;
  486. return STATUS_SUCCESS;
  487. }
  488. NTSTATUS
  489. HalpPassIrpFromFdoToPdo(
  490. PDEVICE_OBJECT DeviceObject,
  491. PIRP Irp
  492. )
  493. /*++
  494. Description:
  495. Given an FDO, pass the IRP to the next device object in the
  496. device stack. This is the PDO if there are no lower level
  497. filters.
  498. Arguments:
  499. DeviceObject - the Fdo
  500. Irp - the request
  501. Return Value:
  502. Returns the result from calling the next level.
  503. --*/
  504. {
  505. PIO_STACK_LOCATION irpSp; // our stack location
  506. PIO_STACK_LOCATION nextIrpSp; // next guy's
  507. PFDO_EXTENSION fdoExtension;
  508. //
  509. // Get the pointer to the device extension.
  510. //
  511. fdoExtension = (PFDO_EXTENSION)DeviceObject->DeviceExtension;
  512. IoSkipCurrentIrpStackLocation(Irp);
  513. //
  514. // Call the PDO driver with the request.
  515. //
  516. return IoCallDriver(fdoExtension->AttachedDeviceObject ,Irp);
  517. }
  518. NTSTATUS
  519. HalpDispatchPnp(
  520. IN PDEVICE_OBJECT DeviceObject,
  521. IN OUT PIRP Irp
  522. )
  523. /*++
  524. Routine Description:
  525. This routine handles all IRP_MJ_PNP IRPs for madeup PDO device.
  526. Arguments:
  527. DeviceObject - Pointer to the device object for which this IRP applies.
  528. Irp - Pointer to the IRP_MJ_PNP IRP to dispatch.
  529. Return Value:
  530. NT status.
  531. --*/
  532. {
  533. PIO_STACK_LOCATION irpSp;
  534. NTSTATUS status;
  535. ULONG length;
  536. DEVICE_RELATION_TYPE relationType;
  537. EXTENSION_TYPE extensionType;
  538. BOOLEAN passDown;
  539. #if DBG
  540. PUCHAR objectTypeString;
  541. #endif //DBG
  542. PAGED_CODE();
  543. extensionType = ((PFDO_EXTENSION)(DeviceObject->DeviceExtension))->ExtensionType;
  544. //
  545. // Get a pointer to our stack location and take appropriate action based
  546. // on the minor function.
  547. //
  548. irpSp = IoGetCurrentIrpStackLocation(Irp);
  549. status = Irp->IoStatus.Status;
  550. switch (extensionType) {
  551. case PdoExtensionType:
  552. #if DBG
  553. objectTypeString = "PDO";
  554. #endif //DBG
  555. switch (irpSp->MinorFunction) {
  556. case IRP_MN_START_DEVICE:
  557. HalPrint(("HAL: (%s) Start_Device Irp received\n",
  558. objectTypeString));
  559. //
  560. // If we get a start device request for a PDO, we simply
  561. // return success.
  562. //
  563. status = STATUS_SUCCESS;
  564. break;
  565. case IRP_MN_QUERY_STOP_DEVICE:
  566. HalPrint(("(%s) Query_Stop_Device Irp received",
  567. objectTypeString));
  568. status = STATUS_SUCCESS;
  569. break;
  570. case IRP_MN_CANCEL_STOP_DEVICE:
  571. HalPrint(("(%s) Cancel_Stop_Device Irp received",
  572. objectTypeString));
  573. status = STATUS_SUCCESS;
  574. break;
  575. case IRP_MN_STOP_DEVICE:
  576. HalPrint(("HAL: (%s) Stop_Device Irp received\n",
  577. objectTypeString));
  578. //
  579. // If we get a stop device request for a PDO, we simply
  580. // return success.
  581. //
  582. status = STATUS_SUCCESS;
  583. break;
  584. case IRP_MN_QUERY_RESOURCES:
  585. HalPrint(("HAL: (%s) Query_Resources Irp received\n",
  586. objectTypeString));
  587. status = HalpQueryResources(DeviceObject,
  588. (PCM_RESOURCE_LIST*)&Irp->IoStatus.Information);
  589. break;
  590. case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
  591. HalPrint(("HAL: (%s) Query_Resource_Requirements Irp received\n",
  592. objectTypeString));
  593. status = HalpQueryResourceRequirements(DeviceObject,
  594. (PIO_RESOURCE_REQUIREMENTS_LIST*)&Irp->IoStatus.Information);
  595. break;
  596. case IRP_MN_QUERY_REMOVE_DEVICE:
  597. HalPrint(("(%s) Query_Remove_device Irp for %x",
  598. objectTypeString,
  599. DeviceObject));
  600. status = STATUS_UNSUCCESSFUL;
  601. break;
  602. case IRP_MN_CANCEL_REMOVE_DEVICE:
  603. HalPrint(("(%s) Cancel_Remove_device Irp for %x",
  604. objectTypeString,
  605. DeviceObject));
  606. status = STATUS_SUCCESS;
  607. break;
  608. case IRP_MN_REMOVE_DEVICE:
  609. HalPrint(("HAL: (%s) Remove_device Irp for PDO %x\n",
  610. objectTypeString,
  611. DeviceObject));
  612. status = STATUS_SUCCESS;
  613. break;
  614. case IRP_MN_QUERY_DEVICE_RELATIONS:
  615. HalPrint(("HAL: (%s) Query_Device_Relations Irp received\n",
  616. objectTypeString));
  617. relationType = irpSp->Parameters.QueryDeviceRelations.Type;
  618. status = HalpQueryDeviceRelations(DeviceObject,
  619. relationType,
  620. (PDEVICE_RELATIONS*)&Irp->IoStatus.Information);
  621. break;
  622. case IRP_MN_QUERY_ID:
  623. HalPrint(("HAL: (%s) Query_Id Irp received\n",
  624. objectTypeString));
  625. status = HalpQueryIdPdo(DeviceObject,
  626. irpSp->Parameters.QueryId.IdType,
  627. (PWSTR*)&Irp->IoStatus.Information);
  628. break;
  629. case IRP_MN_QUERY_INTERFACE:
  630. HalPrint(("HAL: (%s) Query_Interface Irp received\n",
  631. objectTypeString));
  632. status = HalpQueryInterface(
  633. DeviceObject,
  634. irpSp->Parameters.QueryInterface.InterfaceType,
  635. irpSp->Parameters.QueryInterface.Version,
  636. irpSp->Parameters.QueryInterface.InterfaceSpecificData,
  637. irpSp->Parameters.QueryInterface.Size,
  638. irpSp->Parameters.QueryInterface.Interface,
  639. &Irp->IoStatus.Information
  640. );
  641. break;
  642. case IRP_MN_QUERY_CAPABILITIES:
  643. HalPrint(("HAL: (%s) Query_Capabilities Irp received\n",
  644. objectTypeString));
  645. status = HalpQueryCapabilities(DeviceObject,
  646. irpSp->Parameters.DeviceCapabilities.Capabilities);
  647. break;
  648. case IRP_MN_DEVICE_USAGE_NOTIFICATION:
  649. HalPrint(("HAL: DEVICE_USAGE Irp received\n"));
  650. status = STATUS_SUCCESS;
  651. break;
  652. default:
  653. HalPrint(("HAL: (%s) Unsupported Irp (%d) received\n",
  654. objectTypeString,
  655. irpSp->MinorFunction));
  656. status = STATUS_NOT_SUPPORTED ;
  657. break;
  658. }
  659. break; // end PDO cases
  660. case FdoExtensionType:
  661. #if DBG
  662. objectTypeString = "FDO";
  663. #endif //DBG
  664. passDown = TRUE;
  665. //
  666. // In case we don't touch this IRP, save the current status.
  667. //
  668. switch (irpSp->MinorFunction) {
  669. case IRP_MN_QUERY_DEVICE_RELATIONS:
  670. HalPrint(("HAL: (%s) Query_Device_Relations Irp received\n",
  671. objectTypeString));
  672. relationType = irpSp->Parameters.QueryDeviceRelations.Type;
  673. status = HalpQueryDeviceRelations(DeviceObject,
  674. relationType,
  675. (PDEVICE_RELATIONS*)&Irp->IoStatus.Information);
  676. break;
  677. case IRP_MN_QUERY_INTERFACE:
  678. HalPrint(("HAL: (%s) Query_Interface Irp received\n",
  679. objectTypeString));
  680. status = HalpQueryInterface(
  681. DeviceObject,
  682. irpSp->Parameters.QueryInterface.InterfaceType,
  683. irpSp->Parameters.QueryInterface.Version,
  684. irpSp->Parameters.QueryInterface.InterfaceSpecificData,
  685. irpSp->Parameters.QueryInterface.Size,
  686. irpSp->Parameters.QueryInterface.Interface,
  687. &Irp->IoStatus.Information
  688. );
  689. break;
  690. case IRP_MN_QUERY_ID:
  691. HalPrint(("HAL: (%s) Query_Id Irp received\n",
  692. objectTypeString));
  693. status = HalpQueryIdFdo(DeviceObject,
  694. irpSp->Parameters.QueryId.IdType,
  695. (PWSTR*)&Irp->IoStatus.Information);
  696. break;
  697. default:
  698. //
  699. // Ignore any PNP Irps unknown by the FDO but allow them
  700. // down to the PDO.
  701. //
  702. status = STATUS_NOT_SUPPORTED ;
  703. break;
  704. }
  705. if (passDown && (NT_SUCCESS(status) || (status == STATUS_NOT_SUPPORTED))) {
  706. //
  707. // Pass FDO IRPs down to the PDO.
  708. //
  709. // Set Irp status first.
  710. //
  711. if (status != STATUS_NOT_SUPPORTED) {
  712. Irp->IoStatus.Status = status;
  713. }
  714. HalPrint(("HAL: (%s) Passing down Irp (%x)\n",
  715. objectTypeString, irpSp->MinorFunction));
  716. return HalpPassIrpFromFdoToPdo(DeviceObject, Irp);
  717. }
  718. break; // end FDO cases
  719. default:
  720. HalPrint(( "HAL: Received IRP for unknown Device Object\n"));
  721. status = STATUS_INVALID_DEVICE_REQUEST ;
  722. break;
  723. }
  724. //
  725. // Complete the Irp and return.
  726. //
  727. if (status != STATUS_NOT_SUPPORTED) {
  728. Irp->IoStatus.Status = status;
  729. } else {
  730. status = Irp->IoStatus.Status ;
  731. }
  732. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  733. return status;
  734. }
  735. NTSTATUS
  736. HalpDispatchPower(
  737. IN PDEVICE_OBJECT DeviceObject,
  738. IN OUT PIRP Irp
  739. )
  740. /*++
  741. Routine Description:
  742. This routine handles all IRP_MJ_POWER IRPs for madeup PDO device.
  743. Note: We don't actually handle any Power IRPs at this level so
  744. all we do is return the status from the incoming IRP.
  745. Arguments:
  746. DeviceObject - Pointer to the device object for which this IRP applies.
  747. Irp - Pointer to the IRP_MJ_POWER IRP to dispatch.
  748. Return Value:
  749. NT status.
  750. --*/
  751. {
  752. NTSTATUS Status;
  753. EXTENSION_TYPE extensionType;
  754. PIO_STACK_LOCATION irpSp;
  755. HalPrint(("Hal: Power IRP for DevObj: %x\n", DeviceObject));
  756. extensionType = ((PFDO_EXTENSION)(DeviceObject->DeviceExtension))->ExtensionType;
  757. irpSp = IoGetCurrentIrpStackLocation(Irp);
  758. //
  759. // Simply store the appropriate status and complete the request.
  760. //
  761. Status = Irp->IoStatus.Status;
  762. PoStartNextPowerIrp(Irp);
  763. if (extensionType == FdoExtensionType) {
  764. switch (irpSp->MinorFunction) {
  765. case IRP_MN_SET_POWER:
  766. if (irpSp->Parameters.Power.Type == SystemPowerState) {
  767. switch (irpSp->Parameters.Power.State.SystemState) {
  768. case PowerSystemSleeping1:
  769. case PowerSystemSleeping2:
  770. case PowerSystemSleeping3:
  771. case PowerSystemHibernate:
  772. //
  773. // Allocate structures used for starting up
  774. // processors while resuming from sleep.
  775. //
  776. HalpBuildResumeStructures();
  777. HalpMaskAcpiInterrupt();
  778. break;
  779. case PowerSystemWorking:
  780. HalpUnmaskAcpiInterrupt();
  781. //
  782. // Free structures used for starting up
  783. // processors while resuming from sleep.
  784. //
  785. HalpFreeResumeStructures();
  786. break;
  787. default:
  788. break;
  789. }
  790. }
  791. //
  792. // Fall through.
  793. //
  794. case IRP_MN_QUERY_POWER:
  795. Irp->IoStatus.Status = Status = STATUS_SUCCESS;
  796. //
  797. // Fall through.
  798. //
  799. default:
  800. Status = HalpPassIrpFromFdoToPdo(DeviceObject, Irp);
  801. break;
  802. }
  803. } else {
  804. switch (irpSp->MinorFunction) {
  805. case IRP_MN_SET_POWER:
  806. case IRP_MN_QUERY_POWER:
  807. Irp->IoStatus.Status = Status = STATUS_SUCCESS;
  808. //
  809. // Fall through.
  810. //
  811. default:
  812. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  813. break;
  814. }
  815. }
  816. return Status;
  817. }
  818. NTSTATUS
  819. HalpDispatchWmi(
  820. IN PDEVICE_OBJECT DeviceObject,
  821. IN OUT PIRP Irp
  822. )
  823. {
  824. NTSTATUS Status;
  825. EXTENSION_TYPE extensionType;
  826. extensionType = ((PFDO_EXTENSION)(DeviceObject->DeviceExtension))->ExtensionType;
  827. if (extensionType == FdoExtensionType) {
  828. Status = HalpPassIrpFromFdoToPdo(DeviceObject, Irp);
  829. } else {
  830. Status = Irp->IoStatus.Status;
  831. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  832. }
  833. return Status;
  834. }
  835. NTSTATUS
  836. HalpQueryDeviceRelations(
  837. IN PDEVICE_OBJECT DeviceObject,
  838. IN DEVICE_RELATION_TYPE RelationType,
  839. OUT PDEVICE_RELATIONS *DeviceRelations
  840. )
  841. /*++
  842. Routine Description:
  843. This routine builds a DEVICE_RELATIONS structure that
  844. tells the PnP manager how many children we have.
  845. Arguments:
  846. DeviceObject - FDO of ACPI_HAL
  847. RelationType - we only respond to BusRelations
  848. DeviceRelations - pointer to the structure
  849. Return Value:
  850. status
  851. --*/
  852. {
  853. PFDO_EXTENSION FdoExtension;
  854. PDEVICE_RELATIONS relations = NULL;
  855. ULONG relationsCount = 0;
  856. EXTENSION_TYPE extensionType;
  857. ULONG i;
  858. PPDO_EXTENSION Next;
  859. NTSTATUS Status = STATUS_NOT_SUPPORTED;
  860. PAGED_CODE();
  861. FdoExtension = (PFDO_EXTENSION)DeviceObject->DeviceExtension;
  862. extensionType = FdoExtension->ExtensionType;
  863. switch(RelationType) {
  864. case BusRelations:
  865. if (extensionType == FdoExtensionType) {
  866. Next = FdoExtension->ChildPdoList;
  867. while (Next) {
  868. relationsCount += 1;
  869. Next = Next->Next;
  870. }
  871. relations = ExAllocatePoolWithTag(
  872. PagedPool,
  873. sizeof(DEVICE_RELATIONS) * relationsCount,
  874. HAL_POOL_TAG
  875. );
  876. if (relations == NULL) {
  877. return STATUS_INSUFFICIENT_RESOURCES;
  878. }
  879. relations->Count = relationsCount;
  880. i = 0;
  881. Next = FdoExtension->ChildPdoList;
  882. while (Next) {
  883. relations->Objects[i] = Next->PhysicalDeviceObject;
  884. ObReferenceObject( relations->Objects[i] );
  885. i += 1;
  886. Next = Next->Next;
  887. }
  888. *DeviceRelations = relations;
  889. return STATUS_SUCCESS;
  890. }
  891. break;
  892. case TargetDeviceRelation:
  893. if (extensionType == PdoExtensionType) {
  894. relations = ExAllocatePoolWithTag(
  895. PagedPool,
  896. sizeof(DEVICE_RELATIONS),
  897. HAL_POOL_TAG
  898. );
  899. if (relations == NULL) {
  900. return STATUS_INSUFFICIENT_RESOURCES;
  901. }
  902. relations->Count = 1;
  903. relations->Objects[0] = DeviceObject;
  904. ObReferenceObject( relations->Objects[0] );
  905. *DeviceRelations = relations;
  906. return STATUS_SUCCESS;
  907. }
  908. break;
  909. }
  910. return Status;
  911. }
  912. NTSTATUS
  913. HalpQueryIdPdo(
  914. IN PDEVICE_OBJECT DeviceObject,
  915. IN BUS_QUERY_ID_TYPE IdType,
  916. IN OUT PWSTR *BusQueryId
  917. )
  918. /*++
  919. Routine Description:
  920. This routine identifies each of the children that were
  921. enumerated in HalpQueryDeviceRelations.
  922. Arguments:
  923. DeviceObject - PDO of the child
  924. IdType - the type of ID to be returned, currently ignored
  925. BusQueryId - pointer to the wide string being returned
  926. Return Value:
  927. status
  928. --*/
  929. {
  930. PPDO_EXTENSION PdoExtension = DeviceObject->DeviceExtension;
  931. PWSTR idString;
  932. PWCHAR sourceString;
  933. ULONG stringLen;
  934. static WCHAR AcpiHardwareIdString[] = L"ACPI_HAL\\PNP0C08\0*PNP0C08";
  935. static WCHAR AcpiCompatibleString[] = L"*PNP0C08";
  936. static WCHAR AcpiInstanceIdString[] = L"0";
  937. static WCHAR WdHardwareIdString[] = L"ACPI_HAL\\PNP0C18\0*PNP0C18";
  938. static WCHAR WdCompatibleString[] = L"*PNP0C18";
  939. PAGED_CODE();
  940. switch (IdType) {
  941. case BusQueryDeviceID:
  942. case BusQueryHardwareIDs:
  943. switch (PdoExtension->PdoType) {
  944. case AcpiDriver:
  945. sourceString = AcpiHardwareIdString;
  946. stringLen = sizeof(AcpiHardwareIdString);
  947. break;
  948. case WdDriver:
  949. HalPrint(("ID query for WD timer device"));
  950. sourceString = WdHardwareIdString;
  951. stringLen = sizeof(WdHardwareIdString);
  952. break;
  953. default:
  954. return STATUS_NOT_SUPPORTED;
  955. }
  956. break;
  957. case BusQueryCompatibleIDs:
  958. return STATUS_NOT_SUPPORTED;
  959. break;
  960. case BusQueryInstanceID:
  961. sourceString = AcpiInstanceIdString;
  962. stringLen = sizeof(AcpiInstanceIdString);
  963. break;
  964. default:
  965. return STATUS_NOT_SUPPORTED;
  966. }
  967. idString = ExAllocatePoolWithTag(PagedPool,
  968. stringLen + sizeof(UNICODE_NULL),
  969. HAL_POOL_TAG);
  970. if (!idString) {
  971. return STATUS_INSUFFICIENT_RESOURCES;
  972. }
  973. RtlCopyMemory(idString,
  974. sourceString, stringLen);
  975. *(idString + stringLen / sizeof(WCHAR)) = UNICODE_NULL;
  976. *BusQueryId = idString;
  977. return STATUS_SUCCESS;
  978. }
  979. NTSTATUS
  980. HalpQueryIdFdo(
  981. IN PDEVICE_OBJECT DeviceObject,
  982. IN BUS_QUERY_ID_TYPE IdType,
  983. IN OUT PWSTR *BusQueryId
  984. )
  985. /*++
  986. Routine Description:
  987. This routine identifies each of the children that were
  988. enumerated in HalpQueryDeviceRelations.
  989. Arguments:
  990. DeviceObject - PDO of the child
  991. IdType - the type of ID to be returned.
  992. BusQueryId - pointer to the wide string being returned
  993. Return Value:
  994. status
  995. --*/
  996. {
  997. PPDO_EXTENSION PdoExtension = DeviceObject->DeviceExtension;
  998. PWSTR idString;
  999. PWCHAR sourceString = NULL;
  1000. ULONG stringLen;
  1001. UNICODE_STRING String;
  1002. WCHAR Buffer[16];
  1003. NTSTATUS Status;
  1004. PWCHAR widechar;
  1005. static WCHAR HalInstanceIdString[] = L"0";
  1006. PAGED_CODE();
  1007. switch (IdType) {
  1008. case BusQueryDeviceID:
  1009. case BusQueryHardwareIDs:
  1010. //
  1011. // For the UP version of the APIC HAL, we want to detect if there is more
  1012. // than one processor installed. If so, we want to return the ID of
  1013. // the MP HAL rather than the UP HAL. This will induce PNP to reconfigure
  1014. // our devnode and setup the MP HAL for the next boot.
  1015. //
  1016. sourceString = HalHardwareIdString;
  1017. #if defined(NT_UP) && defined(APIC_HAL)
  1018. if (HalpMpInfoTable.ProcessorCount > 1) {
  1019. sourceString = MpHalHardwareIdString;
  1020. }
  1021. #endif
  1022. widechar = sourceString;
  1023. while (*widechar != UNICODE_NULL) {
  1024. widechar++;
  1025. }
  1026. stringLen = (ULONG)((PUCHAR)widechar - ((PUCHAR)sourceString) + 2);
  1027. break;
  1028. case BusQueryInstanceID:
  1029. sourceString = HalInstanceIdString;
  1030. stringLen = sizeof(HalInstanceIdString);
  1031. break;
  1032. default:
  1033. break;
  1034. }
  1035. if (sourceString) {
  1036. //
  1037. // Note that hardware IDs and compatible IDs must be terminated by
  1038. // 2 NULLs.
  1039. //
  1040. idString = ExAllocatePoolWithTag(PagedPool,
  1041. stringLen + sizeof(UNICODE_NULL),
  1042. HAL_POOL_TAG);
  1043. if (!idString) {
  1044. HalPrint(( "HalpQueryIdFdo: couldn't allocate pool\n"));
  1045. return STATUS_INSUFFICIENT_RESOURCES;
  1046. }
  1047. RtlCopyMemory(idString,
  1048. sourceString, stringLen);
  1049. *(idString + stringLen / sizeof(WCHAR)) = UNICODE_NULL;
  1050. *BusQueryId = idString;
  1051. return STATUS_SUCCESS;
  1052. } else {
  1053. return STATUS_NOT_SUPPORTED;
  1054. }
  1055. }
  1056. NTSTATUS
  1057. HalpQueryCapabilities(
  1058. IN PDEVICE_OBJECT PdoExtension,
  1059. IN PDEVICE_CAPABILITIES Capabilities
  1060. )
  1061. /*++
  1062. Routine Description:
  1063. This routine fills in the DEVICE_CAPABILITIES structure for
  1064. a device.
  1065. Arguments:
  1066. DeviceObject - PDO of the child
  1067. Capabilities - pointer to the structure to be filled in.
  1068. Return Value:
  1069. status
  1070. --*/
  1071. {
  1072. PAGED_CODE();
  1073. ASSERT(Capabilities->Version == 1);
  1074. if (Capabilities->Version != 1) {
  1075. return STATUS_NOT_SUPPORTED;
  1076. }
  1077. Capabilities->LockSupported = FALSE;
  1078. Capabilities->EjectSupported = FALSE;
  1079. Capabilities->Removable = FALSE;
  1080. Capabilities->DockDevice = FALSE;
  1081. Capabilities->UniqueID = TRUE;
  1082. Capabilities->SilentInstall = TRUE;
  1083. Capabilities->RawDeviceOK = FALSE;
  1084. Capabilities->Address = 0xffffffff;
  1085. Capabilities->UINumber = 0xffffffff;
  1086. Capabilities->D1Latency = 0;
  1087. Capabilities->D2Latency = 0;
  1088. Capabilities->D3Latency = 0;
  1089. //
  1090. // Default S->D mapping
  1091. //
  1092. Capabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
  1093. Capabilities->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
  1094. Capabilities->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
  1095. return STATUS_SUCCESS;
  1096. }
  1097. NTSTATUS
  1098. HalpQueryResources(
  1099. PDEVICE_OBJECT DeviceObject,
  1100. PCM_RESOURCE_LIST *Resources
  1101. )
  1102. {
  1103. PIO_RESOURCE_REQUIREMENTS_LIST requirements;
  1104. PPDO_EXTENSION PdoExtension = DeviceObject->DeviceExtension;
  1105. PIO_RESOURCE_DESCRIPTOR descriptor;
  1106. PCM_RESOURCE_LIST cmResList;
  1107. NTSTATUS status;
  1108. ULONG i;
  1109. PAGED_CODE();
  1110. if (PdoExtension->PdoType == AcpiDriver) {
  1111. //
  1112. // The whole point behind creating a boot config for the
  1113. // ACPI PDO is that the PnP Manager will not terminate
  1114. // its algorithm that tries to reserve boot configs for
  1115. // all of ACPI's children. So it is not necessary that
  1116. // ACPI have a complicated list of resources in its boot
  1117. // config. We'll be happy with just the IRQ.
  1118. //
  1119. // N.B. At the time of this writing, it should also be
  1120. // true that the IRQ is the only resource that the ACPI
  1121. // claims anyhow.
  1122. //
  1123. status = HalpQueryAcpiResourceRequirements(&requirements);
  1124. if (!NT_SUCCESS(status)) {
  1125. return status;
  1126. }
  1127. cmResList = ExAllocatePoolWithTag(PagedPool,
  1128. sizeof(CM_RESOURCE_LIST),
  1129. HAL_POOL_TAG);
  1130. if (!cmResList) {
  1131. ExFreePool(requirements);
  1132. return STATUS_INSUFFICIENT_RESOURCES;
  1133. }
  1134. RtlZeroMemory(cmResList, sizeof(CM_RESOURCE_LIST));
  1135. cmResList->Count = 1;
  1136. cmResList->List[0].InterfaceType = PNPBus;
  1137. cmResList->List[0].BusNumber = -1;
  1138. cmResList->List[0].PartialResourceList.Version = 1;
  1139. cmResList->List[0].PartialResourceList.Revision = 1;
  1140. cmResList->List[0].PartialResourceList.Count = 1;
  1141. cmResList->List[0].PartialResourceList.PartialDescriptors[0].Type =
  1142. CmResourceTypeInterrupt;
  1143. ASSERT(requirements->AlternativeLists == 1);
  1144. for (i = 0; i < requirements->List[0].Count; i++) {
  1145. descriptor = &requirements->List[0].Descriptors[i];
  1146. if (descriptor->Type == CmResourceTypeInterrupt) {
  1147. cmResList->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition =
  1148. descriptor->ShareDisposition;
  1149. cmResList->List[0].PartialResourceList.PartialDescriptors[0].Flags =
  1150. descriptor->Flags;
  1151. ASSERT(descriptor->u.Interrupt.MinimumVector ==
  1152. descriptor->u.Interrupt.MaximumVector);
  1153. cmResList->List[0].PartialResourceList.PartialDescriptors[0].u.Interrupt.Level =
  1154. descriptor->u.Interrupt.MinimumVector;
  1155. cmResList->List[0].PartialResourceList.PartialDescriptors[0].u.Interrupt.Vector =
  1156. descriptor->u.Interrupt.MinimumVector;
  1157. cmResList->List[0].PartialResourceList.PartialDescriptors[0].u.Interrupt.Affinity = -1;
  1158. *Resources = cmResList;
  1159. ExFreePool(requirements);
  1160. return STATUS_SUCCESS;
  1161. }
  1162. }
  1163. ExFreePool(requirements);
  1164. ExFreePool(cmResList);
  1165. return STATUS_NOT_FOUND;
  1166. } else if (PdoExtension->PdoType == WdDriver) {
  1167. return STATUS_SUCCESS;
  1168. } else {
  1169. return STATUS_NOT_SUPPORTED;
  1170. }
  1171. }
  1172. NTSTATUS
  1173. HalpQueryResourceRequirements(
  1174. IN PDEVICE_OBJECT DeviceObject,
  1175. IN PIO_RESOURCE_REQUIREMENTS_LIST *Requirements
  1176. )
  1177. /*++
  1178. Routine Description:
  1179. This routine handles IRP_MN_QUERY_RESOURCE_REQUIREMENTS.
  1180. Arguments:
  1181. DeviceObject - PDO of the child
  1182. Requirements - pointer to be filled in with the devices
  1183. resource requirements.
  1184. Return Value:
  1185. status
  1186. --*/
  1187. {
  1188. PPDO_EXTENSION PdoExtension = DeviceObject->DeviceExtension;
  1189. PAGED_CODE();
  1190. if (PdoExtension->PdoType == AcpiDriver) {
  1191. return HalpQueryAcpiResourceRequirements(Requirements);
  1192. } else if (PdoExtension->PdoType == WdDriver) {
  1193. return STATUS_SUCCESS;
  1194. } else {
  1195. return STATUS_NOT_SUPPORTED;
  1196. }
  1197. }
  1198. NTSTATUS
  1199. HalpQueryInterface(
  1200. IN PDEVICE_OBJECT DeviceObject,
  1201. IN LPCGUID InterfaceType,
  1202. IN USHORT Version,
  1203. IN PVOID InterfaceSpecificData,
  1204. IN ULONG InterfaceBufferSize,
  1205. IN OUT PINTERFACE Interface,
  1206. IN OUT PULONG_PTR Length
  1207. )
  1208. /*++
  1209. Routine Description:
  1210. This routine fills in the interface structure for
  1211. a device.
  1212. Arguments:
  1213. DeviceObject - PDO of the child
  1214. InterfaceType - Pointer to the interface type GUID.
  1215. Version - Supplies the requested interface version.
  1216. InterfaceSpecificData - This is context that means something based on the
  1217. interface.
  1218. InterfaceBufferSize - Supplies the length of the buffer for the interface
  1219. structure.
  1220. Interface - Supplies a pointer where the interface informaiton should
  1221. be returned.
  1222. Length - This value is updated on return to actual number of bytes modified.
  1223. Return Value:
  1224. status
  1225. --*/
  1226. {
  1227. #if defined(_WIN64)
  1228. PPDO_EXTENSION PdoExtension;
  1229. PdoExtension = DeviceObject->DeviceExtension;
  1230. if (PdoExtension->ExtensionType != PdoExtensionType) {
  1231. PdoExtension = NULL;
  1232. }
  1233. if (PdoExtension != NULL &&
  1234. IsEqualGUID(&GUID_BUS_INTERFACE_STANDARD, InterfaceType)) {
  1235. PBUS_INTERFACE_STANDARD standard = (PBUS_INTERFACE_STANDARD)Interface;
  1236. //
  1237. // ASSERT we know about all of the fields in the structure.
  1238. //
  1239. ASSERT(sizeof(BUS_INTERFACE_STANDARD) == FIELD_OFFSET(BUS_INTERFACE_STANDARD, GetBusData) + sizeof(PGET_SET_DEVICE_DATA));
  1240. *Length = sizeof(BUS_INTERFACE_STANDARD);
  1241. if (InterfaceBufferSize < sizeof(BUS_INTERFACE_STANDARD)) {
  1242. return STATUS_BUFFER_TOO_SMALL;
  1243. }
  1244. //
  1245. // The only version this code knows about is 1.
  1246. //
  1247. standard->Size = sizeof(BUS_INTERFACE_STANDARD);
  1248. standard->Version = HAL_BUS_INTERFACE_STD_VERSION;
  1249. standard->Context = DeviceObject;
  1250. standard->InterfaceReference = HalPnpInterfaceReference;
  1251. standard->InterfaceDereference = HalPnpInterfaceDereference;
  1252. standard->TranslateBusAddress = NULL; // BUGBUG
  1253. standard->GetDmaAdapter = HalPnpGetDmaAdapter;
  1254. standard->SetBusData = NULL;
  1255. standard->GetBusData = NULL;
  1256. return STATUS_SUCCESS;
  1257. } else
  1258. #endif // _WIN64
  1259. if (IsEqualGUID(InterfaceType, (PVOID)&GUID_TRANSLATOR_INTERFACE_STANDARD)) {
  1260. PTRANSLATOR_INTERFACE translator = (PTRANSLATOR_INTERFACE)Interface;
  1261. //
  1262. // Common initialization.
  1263. //
  1264. if (InterfaceBufferSize < sizeof(TRANSLATOR_INTERFACE)) {
  1265. *Length = sizeof(TRANSLATOR_INTERFACE);
  1266. return STATUS_BUFFER_TOO_SMALL;
  1267. }
  1268. switch ((CM_RESOURCE_TYPE)PtrToUlong(InterfaceSpecificData)) {
  1269. case CmResourceTypeInterrupt:
  1270. translator->Size = sizeof(TRANSLATOR_INTERFACE);
  1271. translator->Version = HAL_IRQ_TRANSLATOR_VERSION;
  1272. translator->Context = DeviceObject;
  1273. translator->InterfaceReference = HalTranslatorReference;
  1274. translator->InterfaceDereference = HalTranslatorDereference;
  1275. translator->TranslateResources = HalIrqTranslateResourcesRoot;
  1276. translator->TranslateResourceRequirements =
  1277. HalIrqTranslateResourceRequirementsRoot;
  1278. *Length = sizeof(TRANSLATOR_INTERFACE);
  1279. break;
  1280. default:
  1281. return STATUS_NOT_SUPPORTED ;
  1282. }
  1283. return STATUS_SUCCESS;
  1284. }
  1285. #ifdef ACPI_CMOS_ACTIVATE
  1286. else if (IsEqualGUID(InterfaceType, (PVOID) &GUID_ACPI_CMOS_INTERFACE_STANDARD)) {
  1287. PACPI_CMOS_INTERFACE_STANDARD CmosInterface = (PACPI_CMOS_INTERFACE_STANDARD)Interface;
  1288. //
  1289. // Common initialization.
  1290. //
  1291. if (InterfaceBufferSize < sizeof(ACPI_CMOS_INTERFACE_STANDARD)) {
  1292. *Length = sizeof(ACPI_CMOS_INTERFACE_STANDARD);
  1293. return STATUS_BUFFER_TOO_SMALL;
  1294. }
  1295. switch ((CM_RESOURCE_TYPE)InterfaceSpecificData) {
  1296. case CmResourceTypeNull:
  1297. // standard header
  1298. CmosInterface->Size = sizeof(ACPI_CMOS_INTERFACE_STANDARD);
  1299. CmosInterface->Version = 1;
  1300. CmosInterface->InterfaceReference = HalpCmosNullReference;
  1301. CmosInterface->InterfaceDereference = HalpCmosNullReference;
  1302. // cmos interface specific
  1303. CmosInterface->ReadCmos = HalpcGetCmosDataByType;
  1304. CmosInterface->WriteCmos = HalpcSetCmosDataByType;
  1305. *Length = sizeof(ACPI_CMOS_INTERFACE_STANDARD);
  1306. break;
  1307. default:
  1308. return STATUS_NOT_SUPPORTED ;
  1309. }
  1310. return STATUS_SUCCESS;
  1311. }
  1312. #endif // ACPI_CMOS_ACTIVATE
  1313. //
  1314. // If we got here, we don't handle this interface type.
  1315. //
  1316. return STATUS_NOT_SUPPORTED ;
  1317. }
  1318. #if defined(_WIN64)
  1319. VOID
  1320. HalPnpInterfaceReference(
  1321. PVOID Context
  1322. )
  1323. /*++
  1324. Routine Description:
  1325. This function increments the reference count on the interface context.
  1326. Arguments:
  1327. Context - Supplies a pointer to the interface context. This is actually
  1328. the PDO for the root bus.
  1329. Return Value:
  1330. None
  1331. --*/
  1332. {
  1333. PPDO_EXTENSION PdoExtension = ((PDEVICE_OBJECT) Context)->DeviceExtension;
  1334. PAGED_CODE();
  1335. ASSERT_PDO_EXTENSION( PdoExtension );
  1336. }
  1337. VOID
  1338. HalPnpInterfaceDereference(
  1339. PVOID Context
  1340. )
  1341. /*++
  1342. Routine Description:
  1343. This function decrements the reference count on the interface context.
  1344. Arguments:
  1345. Context - Supplies a pointer to the interface context. This is actually
  1346. the PDO for the root bus.
  1347. Return Value:
  1348. None
  1349. --*/
  1350. {
  1351. PPDO_EXTENSION PdoExtension = ((PDEVICE_OBJECT) Context)->DeviceExtension;
  1352. PAGED_CODE();
  1353. ASSERT_PDO_EXTENSION( PdoExtension );
  1354. }
  1355. PDMA_ADAPTER
  1356. HalPnpGetDmaAdapter(
  1357. IN PVOID Context,
  1358. IN struct _DEVICE_DESCRIPTION *DeviceDescriptor,
  1359. OUT PULONG NumberOfMapRegisters
  1360. )
  1361. /*++
  1362. Routine Description:
  1363. This function writes the PCI configuration space.
  1364. Arguments:
  1365. Context - Supplies a pointer to the interface context. This is actually
  1366. the PDO for the root bus.
  1367. DeviceDescriptor - Supplies the device descriptor used to allocate the dma
  1368. adapter object.
  1369. NubmerOfMapRegisters - Returns the maximum number of map registers a device
  1370. can allocate at one time.
  1371. Return Value:
  1372. Returns a DMA adapter or NULL.
  1373. --*/
  1374. {
  1375. PPDO_EXTENSION PdoExtension = ((PDEVICE_OBJECT) Context)->DeviceExtension;
  1376. PAGED_CODE();
  1377. ASSERT_PDO_EXTENSION( PdoExtension );
  1378. return (PDMA_ADAPTER) HalGetAdapter( DeviceDescriptor, NumberOfMapRegisters );
  1379. }
  1380. #endif // _WIN64
  1381. #ifdef ACPI_CMOS_ACTIVATE
  1382. //
  1383. // This section implements a CMOS access method
  1384. //
  1385. VOID
  1386. HalpCmosNullReference(
  1387. PVOID Context
  1388. )
  1389. {
  1390. return;
  1391. }
  1392. VOID
  1393. HalpCmosNullDereference(
  1394. PVOID Context
  1395. )
  1396. {
  1397. return;
  1398. }
  1399. #endif