ReactOS  0.4.15-dev-1187-g119f102
acpienum.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS ACPI bus driver
3  * FILE: acpi/ospm/acpienum.c
4  * PURPOSE: ACPI namespace enumerator
5  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
6  * UPDATE HISTORY:
7  * 01-05-2001 CSH Created
8  */
9 
10 #include "precomp.h"
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 #define HAS_CHILDREN(d) ((d)->children.next != &((d)->children))
16 #define HAS_SIBLINGS(d) (((d)->parent) && ((d)->node.next != &(d)->parent->children))
17 #define NODE_TO_DEVICE(n) (list_entry(n, struct acpi_device, node))
18 
19 extern struct acpi_device *acpi_root;
20 
23  struct acpi_device *Device,
24  PFDO_DEVICE_DATA FdoData
25  )
26 {
27  PDEVICE_OBJECT pdo;
28  PPDO_DEVICE_DATA pdoData;
30  ULONG index;
31  WCHAR temp[256];
33 
34  PAGED_CODE ();
35 
36  //Don't enumerate the root device
37  if (Device->handle == ACPI_ROOT_OBJECT)
38  return STATUS_SUCCESS;
39 
40  /* Check we didnt add this already */
41  for (entry = FdoData->ListOfPDOs.Flink;
42  entry != &FdoData->ListOfPDOs; entry = entry->Flink)
43  {
44  struct acpi_device *CurrentDevice;
45 
47 
48  //dont duplicate devices
49  if (pdoData->AcpiHandle == Device->handle)
50  return STATUS_SUCCESS;
51 
52  //check everything but fixed feature devices
53  if (pdoData->AcpiHandle)
54  acpi_bus_get_device(pdoData->AcpiHandle, &CurrentDevice);
55  else
56  continue;
57 
58  //check if the HID matches
59  if (!strcmp(Device->pnp.hardware_id, CurrentDevice->pnp.hardware_id))
60  {
61  //check if UID exists for both and matches
62  if (Device->flags.unique_id && CurrentDevice->flags.unique_id &&
63  !strcmp(Device->pnp.unique_id, CurrentDevice->pnp.unique_id))
64  {
65  /* We have a UID on both but they're the same so we have to ignore it */
66  DPRINT1("Detected duplicate device: %hs %hs\n", Device->pnp.hardware_id, Device->pnp.unique_id);
67  return STATUS_SUCCESS;
68  }
69  else if (!Device->flags.unique_id && !CurrentDevice->flags.unique_id)
70  {
71  /* No UID so we can only legally have 1 of these devices */
72  DPRINT1("Detected duplicate device: %hs\n", Device->pnp.hardware_id);
73  return STATUS_SUCCESS;
74  }
75  }
76  }
77 
78  DPRINT("Exposing PDO\n"
79  "======AcpiHandle: %p\n"
80  "======HardwareId: %s\n",
81  Device->handle,
82  Device->pnp.hardware_id);
83 
84 
85  //
86  // Create the PDO
87  //
88 
89  DPRINT("FdoData->NextLowerDriver = 0x%p\n", FdoData->NextLowerDriver);
90 
91  status = IoCreateDevice(FdoData->Common.Self->DriverObject,
92  sizeof(PDO_DEVICE_DATA),
93  NULL,
96  FALSE,
97  &pdo);
98 
99  if (!NT_SUCCESS (status)) {
100  return status;
101  }
102 
103  pdoData = (PPDO_DEVICE_DATA) pdo->DeviceExtension;
104  pdoData->AcpiHandle = Device->handle;
105 
106  //
107  // Copy the hardware IDs
108  //
109  index = 0;
110  index += swprintf(&temp[index],
111  L"ACPI\\%hs",
112  Device->pnp.hardware_id);
113  temp[index++] = UNICODE_NULL;
114 
115  index += swprintf(&temp[index],
116  L"*%hs",
117  Device->pnp.hardware_id);
118  temp[index++] = UNICODE_NULL;
119  temp[index++] = UNICODE_NULL;
120 
121  pdoData->HardwareIDs = ExAllocatePoolWithTag(NonPagedPool, index*sizeof(WCHAR), 'DpcA');
122 
123 
124  if (!pdoData->HardwareIDs) {
125  IoDeleteDevice(pdo);
127  }
128 
129  RtlCopyMemory (pdoData->HardwareIDs, temp, index*sizeof(WCHAR));
130  Bus_InitializePdo (pdo, FdoData);
131 
132  //
133  // Device Relation changes if a new pdo is created. So let
134  // the PNP system now about that. This forces it to send bunch of pnp
135  // queries and cause the function driver to be loaded.
136  //
137 
138  //IoInvalidateDeviceRelations (FdoData->UnderlyingPDO, BusRelations);
139 
140  return status;
141 }
142 
143 
144 /* looks alot like acpi_bus_walk doesnt it */
145 NTSTATUS
147 {
148  ULONG Count = 0;
149  struct acpi_device *Device = acpi_root;
150 
151  while(Device)
152  {
153  if (Device->status.present && Device->status.enabled &&
154  Device->flags.hardware_id)
155  {
156  Bus_PlugInDevice(Device, DeviceExtension);
157  Count++;
158  }
159 
160  if (HAS_CHILDREN(Device)) {
161  Device = NODE_TO_DEVICE(Device->children.next);
162  continue;
163  }
164  if (HAS_SIBLINGS(Device)) {
165  Device = NODE_TO_DEVICE(Device->node.next);
166  continue;
167  }
168  while ((Device = Device->parent)) {
169  if (HAS_SIBLINGS(Device)) {
170  Device = NODE_TO_DEVICE(Device->node.next);
171  break;
172  }
173  }
174  }
175  DPRINT("acpi device count: %d\n", Count);
176  return STATUS_SUCCESS;
177 }
178 
179 /* EOF */
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define NODE_TO_DEVICE(n)
Definition: acpienum.c:17
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2029
int acpi_bus_get_device(ACPI_HANDLE handle, struct acpi_device **device)
Definition: bus.c:108
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
NTSTATUS Bus_PlugInDevice(struct acpi_device *Device, PFDO_DEVICE_DATA FdoData)
Definition: acpienum.c:22
static int Link(const char **args)
Definition: vfdcmd.c:2414
PDEVICE_OBJECT Self
Definition: acpisys.h:28
NTSTATUS ACPIEnumerateDevices(PFDO_DEVICE_DATA DeviceExtension)
Definition: acpienum.c:146
#define FILE_DEVICE_CONTROLLER
Definition: winioctl.h:109
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
PWCHAR HardwareIDs
Definition: acpisys.h:44
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
GLuint index
Definition: glext.h:6031
#define ACPI_ROOT_OBJECT
Definition: actypes.h:500
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
LIST_ENTRY ListOfPDOs
Definition: acpisys.h:66
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _PDO_DEVICE_DATA * PPDO_DEVICE_DATA
#define HAS_CHILDREN(d)
Definition: acpienum.c:15
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define HAS_SIBLINGS(d)
Definition: acpienum.c:16
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define index(s, c)
Definition: various.h:29
static const WCHAR L[]
Definition: oid.c:1250
COMMON_DEVICE_DATA Common
Definition: acpisys.h:58
uint32_t entry
Definition: isohybrid.c:63
Definition: typedefs.h:119
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
ACPI_HANDLE AcpiHandle
Definition: acpisys.h:39
static calc_node_t temp
Definition: rpn_ieee.c:38
struct acpi_device_flags flags
Definition: acpi_bus.h:276
#define DPRINT1
Definition: precomp.h:8
PDEVICE_OBJECT NextLowerDriver
Definition: acpisys.h:63
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
struct acpi_device_pnp pnp
Definition: acpi_bus.h:277
VOID Bus_InitializePdo(PDEVICE_OBJECT Pdo, PFDO_DEVICE_DATA FdoData)
Definition: pnp.c:417
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
struct acpi_device * acpi_root
Definition: bus.c:51
#define PAGED_CODE()
Definition: ps.c:97