xref: /reactos/hal/halx86/acpi/halpnpdd.c (revision ffb20d33)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:         ReactOS HAL
3c2c66affSColin Finck  * LICENSE:         BSD - See COPYING.ARM in the top level directory
4c2c66affSColin Finck  * FILE:            hal/halx86/acpi/halpnpdd.c
5c2c66affSColin Finck  * PURPOSE:         HAL Plug and Play Device Driver
6c2c66affSColin Finck  * PROGRAMMERS:     ReactOS Portable Systems Group
7c2c66affSColin Finck  */
8c2c66affSColin Finck 
9c2c66affSColin Finck /* INCLUDES *******************************************************************/
10c2c66affSColin Finck 
11c2c66affSColin Finck #include <hal.h>
12ba1ed89fSSerge Gautherie 
13ba1ed89fSSerge Gautherie #include <initguid.h>
14ba1ed89fSSerge Gautherie #include <wdmguid.h>
15ba1ed89fSSerge Gautherie 
16c2c66affSColin Finck #define NDEBUG
17c2c66affSColin Finck #include <debug.h>
18c2c66affSColin Finck 
19c2c66affSColin Finck typedef enum _EXTENSION_TYPE
20c2c66affSColin Finck {
21c2c66affSColin Finck     PdoExtensionType = 0xC0,
22c2c66affSColin Finck     FdoExtensionType
23c2c66affSColin Finck } EXTENSION_TYPE;
24c2c66affSColin Finck 
25c2c66affSColin Finck typedef enum _PDO_TYPE
26c2c66affSColin Finck {
27c2c66affSColin Finck     AcpiPdo = 0x80,
28c2c66affSColin Finck     WdPdo
29c2c66affSColin Finck } PDO_TYPE;
30c2c66affSColin Finck 
31c2c66affSColin Finck typedef struct _FDO_EXTENSION
32c2c66affSColin Finck {
33c2c66affSColin Finck     EXTENSION_TYPE ExtensionType;
34c2c66affSColin Finck     struct _PDO_EXTENSION* ChildPdoList;
35c2c66affSColin Finck     PDEVICE_OBJECT PhysicalDeviceObject;
36c2c66affSColin Finck     PDEVICE_OBJECT FunctionalDeviceObject;
37c2c66affSColin Finck     PDEVICE_OBJECT AttachedDeviceObject;
38c2c66affSColin Finck } FDO_EXTENSION, *PFDO_EXTENSION;
39c2c66affSColin Finck 
40c2c66affSColin Finck typedef struct _PDO_EXTENSION
41c2c66affSColin Finck {
42c2c66affSColin Finck     EXTENSION_TYPE ExtensionType;
43c2c66affSColin Finck     struct _PDO_EXTENSION* Next;
44c2c66affSColin Finck     PDEVICE_OBJECT PhysicalDeviceObject;
45c2c66affSColin Finck     PFDO_EXTENSION ParentFdoExtension;
46c2c66affSColin Finck     PDO_TYPE PdoType;
47c2c66affSColin Finck     PDESCRIPTION_HEADER WdTable;
48c2c66affSColin Finck     LONG InterfaceReferenceCount;
49c2c66affSColin Finck } PDO_EXTENSION, *PPDO_EXTENSION;
50c2c66affSColin Finck 
51c2c66affSColin Finck /* GLOBALS ********************************************************************/
52c2c66affSColin Finck 
53c2c66affSColin Finck PDRIVER_OBJECT HalpDriverObject;
54c2c66affSColin Finck 
55c2c66affSColin Finck /* PRIVATE FUNCTIONS **********************************************************/
56c2c66affSColin Finck 
57c2c66affSColin Finck NTSTATUS
58c2c66affSColin Finck NTAPI
HalpAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT TargetDevice)59c2c66affSColin Finck HalpAddDevice(IN PDRIVER_OBJECT DriverObject,
60c2c66affSColin Finck               IN PDEVICE_OBJECT TargetDevice)
61c2c66affSColin Finck {
62c2c66affSColin Finck     NTSTATUS Status;
63c2c66affSColin Finck     PFDO_EXTENSION FdoExtension;
64f75318b6SVictor Perevertkin     PPDO_EXTENSION PdoExtension;
65c2c66affSColin Finck     PDEVICE_OBJECT DeviceObject, AttachedDevice;
66f75318b6SVictor Perevertkin     PDEVICE_OBJECT PdoDeviceObject;
67f75318b6SVictor Perevertkin     PDESCRIPTION_HEADER Wdrt;
68c2c66affSColin Finck 
69c2c66affSColin Finck     DPRINT("HAL: PnP Driver ADD!\n");
70c2c66affSColin Finck 
71c2c66affSColin Finck     /* Create the FDO */
72c2c66affSColin Finck     Status = IoCreateDevice(DriverObject,
73c2c66affSColin Finck                             sizeof(FDO_EXTENSION),
74c2c66affSColin Finck                             NULL,
75c2c66affSColin Finck                             FILE_DEVICE_BUS_EXTENDER,
76c2c66affSColin Finck                             0,
77c2c66affSColin Finck                             FALSE,
78c2c66affSColin Finck                             &DeviceObject);
79c2c66affSColin Finck     if (!NT_SUCCESS(Status))
80c2c66affSColin Finck     {
81c2c66affSColin Finck         /* Should not happen */
82c2c66affSColin Finck         DbgBreakPoint();
83c2c66affSColin Finck         return Status;
84c2c66affSColin Finck     }
85c2c66affSColin Finck 
86c2c66affSColin Finck     /* Setup the FDO extension */
87c2c66affSColin Finck     FdoExtension = DeviceObject->DeviceExtension;
88c2c66affSColin Finck     FdoExtension->ExtensionType = FdoExtensionType;
89c2c66affSColin Finck     FdoExtension->PhysicalDeviceObject = TargetDevice;
90c2c66affSColin Finck     FdoExtension->FunctionalDeviceObject = DeviceObject;
91c2c66affSColin Finck     FdoExtension->ChildPdoList = NULL;
92c2c66affSColin Finck 
93c2c66affSColin Finck     /* FDO is done initializing */
94c2c66affSColin Finck     DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
95c2c66affSColin Finck 
96c2c66affSColin Finck     /* Attach to the physical device object (the bus) */
97c2c66affSColin Finck     AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject, TargetDevice);
98c2c66affSColin Finck     if (!AttachedDevice)
99c2c66affSColin Finck     {
100c2c66affSColin Finck         /* Failed, undo everything */
101c2c66affSColin Finck         IoDeleteDevice(DeviceObject);
102c2c66affSColin Finck         return STATUS_NO_SUCH_DEVICE;
103c2c66affSColin Finck     }
104c2c66affSColin Finck 
105c2c66affSColin Finck     /* Save the attachment */
106c2c66affSColin Finck     FdoExtension->AttachedDeviceObject = AttachedDevice;
107c2c66affSColin Finck 
108f75318b6SVictor Perevertkin     /* Create the PDO */
109f75318b6SVictor Perevertkin     Status = IoCreateDevice(DriverObject,
110f75318b6SVictor Perevertkin                             sizeof(PDO_EXTENSION),
111f75318b6SVictor Perevertkin                             NULL,
112f75318b6SVictor Perevertkin                             FILE_DEVICE_BUS_EXTENDER,
113f75318b6SVictor Perevertkin                             FILE_AUTOGENERATED_DEVICE_NAME,
114f75318b6SVictor Perevertkin                             FALSE,
115f75318b6SVictor Perevertkin                             &PdoDeviceObject);
116f75318b6SVictor Perevertkin     if (!NT_SUCCESS(Status))
117f75318b6SVictor Perevertkin     {
118f75318b6SVictor Perevertkin         /* Fail */
119f75318b6SVictor Perevertkin         DPRINT1("HAL: Could not create ACPI device object status=0x%08x\n", Status);
120f75318b6SVictor Perevertkin         return Status;
121f75318b6SVictor Perevertkin     }
122f75318b6SVictor Perevertkin 
123f75318b6SVictor Perevertkin     /* Setup the PDO device extension */
124f75318b6SVictor Perevertkin     PdoExtension = PdoDeviceObject->DeviceExtension;
125f75318b6SVictor Perevertkin     PdoExtension->ExtensionType = PdoExtensionType;
126f75318b6SVictor Perevertkin     PdoExtension->PhysicalDeviceObject = PdoDeviceObject;
127f75318b6SVictor Perevertkin     PdoExtension->ParentFdoExtension = FdoExtension;
128f75318b6SVictor Perevertkin     PdoExtension->PdoType = AcpiPdo;
129f75318b6SVictor Perevertkin 
130f75318b6SVictor Perevertkin     /* Add the PDO to the head of the list */
131f75318b6SVictor Perevertkin     PdoExtension->Next = FdoExtension->ChildPdoList;
132f75318b6SVictor Perevertkin     FdoExtension->ChildPdoList = PdoExtension;
133f75318b6SVictor Perevertkin 
134f75318b6SVictor Perevertkin     /* Initialization is finished */
135f75318b6SVictor Perevertkin     PdoDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
136f75318b6SVictor Perevertkin 
137f75318b6SVictor Perevertkin     /* Find the ACPI watchdog table */
138f75318b6SVictor Perevertkin     Wdrt = HalAcpiGetTable(0, 'TRDW');
139f75318b6SVictor Perevertkin     if (Wdrt)
140f75318b6SVictor Perevertkin     {
141f75318b6SVictor Perevertkin         /* FIXME: TODO */
142f75318b6SVictor Perevertkin         DPRINT1("You have an ACPI Watchdog. That's great! You should be proud ;-)\n");
143f75318b6SVictor Perevertkin     }
144c2c66affSColin Finck 
145c2c66affSColin Finck     /* Return status */
146c2c66affSColin Finck     DPRINT("Device added %lx\n", Status);
147c2c66affSColin Finck     return Status;
148c2c66affSColin Finck }
149c2c66affSColin Finck 
150c2c66affSColin Finck NTSTATUS
151c2c66affSColin Finck NTAPI
HalpQueryInterface(IN PDEVICE_OBJECT DeviceObject,IN CONST GUID * InterfaceType,IN USHORT Version,IN PVOID InterfaceSpecificData,IN ULONG InterfaceBufferSize,IN PINTERFACE Interface,OUT PULONG Length)152c2c66affSColin Finck HalpQueryInterface(IN PDEVICE_OBJECT DeviceObject,
153c2c66affSColin Finck                    IN CONST GUID* InterfaceType,
154c2c66affSColin Finck                    IN USHORT Version,
155c2c66affSColin Finck                    IN PVOID InterfaceSpecificData,
156c2c66affSColin Finck                    IN ULONG InterfaceBufferSize,
157c2c66affSColin Finck                    IN PINTERFACE Interface,
158c2c66affSColin Finck                    OUT PULONG Length)
159c2c66affSColin Finck {
160ba1ed89fSSerge Gautherie     if (IsEqualIID(InterfaceType, &GUID_ACPI_REGS_INTERFACE_STANDARD))
161ba1ed89fSSerge Gautherie     {
162ba1ed89fSSerge Gautherie         DPRINT1("HalpQueryInterface(GUID_ACPI_REGS_INTERFACE_STANDARD) is UNIMPLEMENTED\n");
163ba1ed89fSSerge Gautherie     }
164ba1ed89fSSerge Gautherie     else if (IsEqualIID(InterfaceType, &GUID_ACPI_PORT_RANGES_INTERFACE_STANDARD))
165ba1ed89fSSerge Gautherie     {
166ba1ed89fSSerge Gautherie         DPRINT1("HalpQueryInterface(GUID_ACPI_PORT_RANGES_INTERFACE_STANDARD) is UNIMPLEMENTED\n");
167ba1ed89fSSerge Gautherie     }
168ba1ed89fSSerge Gautherie     else
169ba1ed89fSSerge Gautherie     {
170ba1ed89fSSerge Gautherie         DPRINT1("HalpQueryInterface({%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}) is UNIMPLEMENTED\n",
171ba1ed89fSSerge Gautherie                 InterfaceType->Data1, InterfaceType->Data2, InterfaceType->Data3,
172ba1ed89fSSerge Gautherie                 InterfaceType->Data4[0], InterfaceType->Data4[1],
173ba1ed89fSSerge Gautherie                 InterfaceType->Data4[2], InterfaceType->Data4[3],
174ba1ed89fSSerge Gautherie                 InterfaceType->Data4[4], InterfaceType->Data4[5],
175ba1ed89fSSerge Gautherie                 InterfaceType->Data4[6], InterfaceType->Data4[7]);
176ba1ed89fSSerge Gautherie     }
177c2c66affSColin Finck     return STATUS_NOT_SUPPORTED;
178c2c66affSColin Finck }
179c2c66affSColin Finck 
180c2c66affSColin Finck NTSTATUS
181c2c66affSColin Finck NTAPI
HalpQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject,IN DEVICE_RELATION_TYPE RelationType,OUT PDEVICE_RELATIONS * DeviceRelations)182c2c66affSColin Finck HalpQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject,
183c2c66affSColin Finck                          IN DEVICE_RELATION_TYPE RelationType,
184c2c66affSColin Finck                          OUT PDEVICE_RELATIONS* DeviceRelations)
185c2c66affSColin Finck {
186c2c66affSColin Finck     EXTENSION_TYPE ExtensionType;
187c2c66affSColin Finck     PPDO_EXTENSION PdoExtension;
188c2c66affSColin Finck     PFDO_EXTENSION FdoExtension;
189c2c66affSColin Finck     PDEVICE_RELATIONS PdoRelations, FdoRelations;
190c2c66affSColin Finck     PDEVICE_OBJECT* ObjectEntry;
191c2c66affSColin Finck     ULONG i = 0, PdoCount = 0;
192c2c66affSColin Finck 
193c2c66affSColin Finck     /* Get FDO device extension and PDO count */
194c2c66affSColin Finck     FdoExtension = DeviceObject->DeviceExtension;
195c2c66affSColin Finck     ExtensionType = FdoExtension->ExtensionType;
196c2c66affSColin Finck 
197c2c66affSColin Finck     /* What do they want? */
198c2c66affSColin Finck     if (RelationType == BusRelations)
199c2c66affSColin Finck     {
200c2c66affSColin Finck         /* This better be an FDO */
201c2c66affSColin Finck         if (ExtensionType == FdoExtensionType)
202c2c66affSColin Finck         {
203c2c66affSColin Finck             /* Count how many PDOs we have */
204c2c66affSColin Finck             PdoExtension = FdoExtension->ChildPdoList;
205c2c66affSColin Finck             while (PdoExtension)
206c2c66affSColin Finck             {
207c2c66affSColin Finck                 /* Next one */
208c2c66affSColin Finck                 PdoExtension = PdoExtension->Next;
209c2c66affSColin Finck                 PdoCount++;
210c2c66affSColin Finck             }
211c2c66affSColin Finck 
212c2c66affSColin Finck             /* Add the PDOs that already exist in the device relations */
213c2c66affSColin Finck             if (*DeviceRelations)
214c2c66affSColin Finck             {
215c2c66affSColin Finck                 PdoCount += (*DeviceRelations)->Count;
216c2c66affSColin Finck             }
217c2c66affSColin Finck 
218c2c66affSColin Finck             /* Allocate our structure */
219c2c66affSColin Finck             FdoRelations = ExAllocatePoolWithTag(PagedPool,
220c2c66affSColin Finck                                                  FIELD_OFFSET(DEVICE_RELATIONS,
221c2c66affSColin Finck                                                               Objects) +
222c2c66affSColin Finck                                                  sizeof(PDEVICE_OBJECT) * PdoCount,
223c2c66affSColin Finck                                                  TAG_HAL);
224c2c66affSColin Finck             if (!FdoRelations) return STATUS_INSUFFICIENT_RESOURCES;
225c2c66affSColin Finck 
226c2c66affSColin Finck             /* Save our count */
227c2c66affSColin Finck             FdoRelations->Count = PdoCount;
228c2c66affSColin Finck 
229c2c66affSColin Finck             /* Query existing relations */
230c2c66affSColin Finck             ObjectEntry = FdoRelations->Objects;
231c2c66affSColin Finck             if (*DeviceRelations)
232c2c66affSColin Finck             {
233c2c66affSColin Finck                 /* Check if there were any */
234c2c66affSColin Finck                 if ((*DeviceRelations)->Count)
235c2c66affSColin Finck                 {
236c2c66affSColin Finck                     /* Loop them all */
237c2c66affSColin Finck                     do
238c2c66affSColin Finck                     {
239c2c66affSColin Finck                         /* Copy into our structure */
240c2c66affSColin Finck                         *ObjectEntry++ = (*DeviceRelations)->Objects[i];
241c2c66affSColin Finck                     }
242c2c66affSColin Finck                     while (++i < (*DeviceRelations)->Count);
243c2c66affSColin Finck                 }
244c2c66affSColin Finck 
245c2c66affSColin Finck                 /* Free existing structure */
246c2c66affSColin Finck                 ExFreePool(*DeviceRelations);
247c2c66affSColin Finck             }
248c2c66affSColin Finck 
249c2c66affSColin Finck             /* Now check if we have a PDO list */
250c2c66affSColin Finck             PdoExtension = FdoExtension->ChildPdoList;
251c2c66affSColin Finck             if (PdoExtension)
252c2c66affSColin Finck             {
253c2c66affSColin Finck                 /* Loop the PDOs */
254c2c66affSColin Finck                 do
255c2c66affSColin Finck                 {
256c2c66affSColin Finck                     /* Save our own PDO and reference it */
257c2c66affSColin Finck                     *ObjectEntry++ = PdoExtension->PhysicalDeviceObject;
258c2c66affSColin Finck                     ObReferenceObject(PdoExtension->PhysicalDeviceObject);
259c2c66affSColin Finck 
260c2c66affSColin Finck                     /* Go to our next PDO */
261c2c66affSColin Finck                     PdoExtension = PdoExtension->Next;
262c2c66affSColin Finck                 }
263c2c66affSColin Finck                 while (PdoExtension);
264c2c66affSColin Finck             }
265c2c66affSColin Finck 
266c2c66affSColin Finck             /* Return the new structure */
267c2c66affSColin Finck             *DeviceRelations = FdoRelations;
268c2c66affSColin Finck             return STATUS_SUCCESS;
269c2c66affSColin Finck         }
270c2c66affSColin Finck     }
271c2c66affSColin Finck     else
272c2c66affSColin Finck     {
273c2c66affSColin Finck         /* The only other thing we support is a target relation for the PDO */
274c2c66affSColin Finck         if ((RelationType == TargetDeviceRelation) &&
275c2c66affSColin Finck             (ExtensionType == PdoExtensionType))
276c2c66affSColin Finck         {
277c2c66affSColin Finck             /* Only one entry */
278c2c66affSColin Finck             PdoRelations = ExAllocatePoolWithTag(PagedPool,
279c2c66affSColin Finck                                                  sizeof(DEVICE_RELATIONS),
280c2c66affSColin Finck                                                  TAG_HAL);
281c2c66affSColin Finck             if (!PdoRelations) return STATUS_INSUFFICIENT_RESOURCES;
282c2c66affSColin Finck 
283c2c66affSColin Finck             /* Fill it out and reference us */
284c2c66affSColin Finck             PdoRelations->Count = 1;
285c2c66affSColin Finck             PdoRelations->Objects[0] = DeviceObject;
286c2c66affSColin Finck             ObReferenceObject(DeviceObject);
287c2c66affSColin Finck 
288c2c66affSColin Finck             /* Return it */
289c2c66affSColin Finck             *DeviceRelations = PdoRelations;
290c2c66affSColin Finck             return STATUS_SUCCESS;
291c2c66affSColin Finck         }
292c2c66affSColin Finck     }
293c2c66affSColin Finck 
294c2c66affSColin Finck     /* We don't support anything else */
295c2c66affSColin Finck     return STATUS_NOT_SUPPORTED;
296c2c66affSColin Finck }
297c2c66affSColin Finck 
298c2c66affSColin Finck NTSTATUS
299c2c66affSColin Finck NTAPI
HalpQueryCapabilities(IN PDEVICE_OBJECT DeviceObject,OUT PDEVICE_CAPABILITIES Capabilities)300c2c66affSColin Finck HalpQueryCapabilities(IN PDEVICE_OBJECT DeviceObject,
301c2c66affSColin Finck                       OUT PDEVICE_CAPABILITIES Capabilities)
302c2c66affSColin Finck {
303c2c66affSColin Finck     //PPDO_EXTENSION PdoExtension;
304c2c66affSColin Finck     NTSTATUS Status;
305c2c66affSColin Finck     PAGED_CODE();
306c2c66affSColin Finck 
307c2c66affSColin Finck     /* Get the extension and check for valid version */
308c2c66affSColin Finck     //PdoExtension = DeviceObject->DeviceExtension;
309c2c66affSColin Finck     ASSERT(Capabilities->Version == 1);
310c2c66affSColin Finck     if (Capabilities->Version == 1)
311c2c66affSColin Finck     {
312c2c66affSColin Finck         /* Can't lock or eject us */
313c2c66affSColin Finck         Capabilities->LockSupported = FALSE;
314c2c66affSColin Finck         Capabilities->EjectSupported = FALSE;
315c2c66affSColin Finck 
316c2c66affSColin Finck         /* Can't remove or dock us */
317c2c66affSColin Finck         Capabilities->Removable = FALSE;
318c2c66affSColin Finck         Capabilities->DockDevice = FALSE;
319c2c66affSColin Finck 
320c2c66affSColin Finck         /* Can't access us raw */
321c2c66affSColin Finck         Capabilities->RawDeviceOK = FALSE;
322c2c66affSColin Finck 
323c2c66affSColin Finck         /* We have a unique ID, and don't bother the user */
324c2c66affSColin Finck         Capabilities->UniqueID = TRUE;
325c2c66affSColin Finck         Capabilities->SilentInstall = TRUE;
326c2c66affSColin Finck 
327*ffb20d33SRatin Gao         /* Fill out the address */
328c2c66affSColin Finck         Capabilities->Address = InterfaceTypeUndefined;
329c2c66affSColin Finck         Capabilities->UINumber = InterfaceTypeUndefined;
330c2c66affSColin Finck 
331c2c66affSColin Finck         /* Fill out latencies */
332c2c66affSColin Finck         Capabilities->D1Latency = 0;
333c2c66affSColin Finck         Capabilities->D2Latency = 0;
334c2c66affSColin Finck         Capabilities->D3Latency = 0;
335c2c66affSColin Finck 
336c2c66affSColin Finck         /* Fill out supported device states */
337c2c66affSColin Finck         Capabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
338c2c66affSColin Finck         Capabilities->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
339c2c66affSColin Finck         Capabilities->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
340c2c66affSColin Finck         Capabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
341c2c66affSColin Finck 
342c2c66affSColin Finck         /* Done */
343c2c66affSColin Finck         Status = STATUS_SUCCESS;
344c2c66affSColin Finck     }
345c2c66affSColin Finck     else
346c2c66affSColin Finck     {
347c2c66affSColin Finck         /* Fail */
348c2c66affSColin Finck         Status = STATUS_NOT_SUPPORTED;
349c2c66affSColin Finck     }
350c2c66affSColin Finck 
351c2c66affSColin Finck     /* Return status */
352c2c66affSColin Finck     return Status;
353c2c66affSColin Finck }
354c2c66affSColin Finck 
355c2c66affSColin Finck NTSTATUS
356c2c66affSColin Finck NTAPI
HalpQueryResources(IN PDEVICE_OBJECT DeviceObject,OUT PCM_RESOURCE_LIST * Resources)357c2c66affSColin Finck HalpQueryResources(IN PDEVICE_OBJECT DeviceObject,
358c2c66affSColin Finck                    OUT PCM_RESOURCE_LIST *Resources)
359c2c66affSColin Finck {
360c2c66affSColin Finck     PPDO_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
361c2c66affSColin Finck     NTSTATUS Status;
362c2c66affSColin Finck     PCM_RESOURCE_LIST ResourceList;
363c2c66affSColin Finck     PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
364c2c66affSColin Finck     PIO_RESOURCE_DESCRIPTOR Descriptor;
365c2c66affSColin Finck     PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDesc;
366c2c66affSColin Finck     ULONG i;
367c2c66affSColin Finck     PAGED_CODE();
368c2c66affSColin Finck 
369c2c66affSColin Finck     /* Only the ACPI PDO has requirements */
370c2c66affSColin Finck     if (DeviceExtension->PdoType == AcpiPdo)
371c2c66affSColin Finck     {
372c2c66affSColin Finck         /* Query ACPI requirements */
373c2c66affSColin Finck         Status = HalpQueryAcpiResourceRequirements(&RequirementsList);
374c2c66affSColin Finck         if (!NT_SUCCESS(Status)) return Status;
375c2c66affSColin Finck 
376c2c66affSColin Finck         ASSERT(RequirementsList->AlternativeLists == 1);
377c2c66affSColin Finck 
378c2c66affSColin Finck         /* Allocate the resourcel ist */
379c2c66affSColin Finck         ResourceList = ExAllocatePoolWithTag(PagedPool,
380c2c66affSColin Finck                                              sizeof(CM_RESOURCE_LIST),
381c2c66affSColin Finck                                              TAG_HAL);
382c2c66affSColin Finck         if (!ResourceList )
383c2c66affSColin Finck         {
384c2c66affSColin Finck             /* Fail, no memory */
385c2c66affSColin Finck             Status = STATUS_INSUFFICIENT_RESOURCES;
386c2c66affSColin Finck             ExFreePoolWithTag(RequirementsList, TAG_HAL);
387c2c66affSColin Finck             return Status;
388c2c66affSColin Finck         }
389c2c66affSColin Finck 
390c2c66affSColin Finck         /* Initialize it */
391c2c66affSColin Finck         RtlZeroMemory(ResourceList, sizeof(CM_RESOURCE_LIST));
392c2c66affSColin Finck         ResourceList->Count = 1;
393c2c66affSColin Finck 
394c2c66affSColin Finck         /* Setup the list fields */
395c2c66affSColin Finck         ResourceList->List[0].BusNumber = -1;
396c2c66affSColin Finck         ResourceList->List[0].InterfaceType = PNPBus;
397c2c66affSColin Finck         ResourceList->List[0].PartialResourceList.Version = 1;
398c2c66affSColin Finck         ResourceList->List[0].PartialResourceList.Revision = 1;
399c2c66affSColin Finck         ResourceList->List[0].PartialResourceList.Count = 0;
400c2c66affSColin Finck 
401c2c66affSColin Finck         /* Setup the first descriptor */
402c2c66affSColin Finck         PartialDesc = ResourceList->List[0].PartialResourceList.PartialDescriptors;
403c2c66affSColin Finck 
404c2c66affSColin Finck         /* Find the requirement descriptor for the SCI */
405c2c66affSColin Finck         for (i = 0; i < RequirementsList->List[0].Count; i++)
406c2c66affSColin Finck         {
407c2c66affSColin Finck             /* Get this descriptor */
408c2c66affSColin Finck             Descriptor = &RequirementsList->List[0].Descriptors[i];
409c2c66affSColin Finck             if (Descriptor->Type == CmResourceTypeInterrupt)
410c2c66affSColin Finck             {
411c2c66affSColin Finck                 /* Copy requirements descriptor into resource descriptor */
412c2c66affSColin Finck                 PartialDesc->Type = CmResourceTypeInterrupt;
413c2c66affSColin Finck                 PartialDesc->ShareDisposition = Descriptor->ShareDisposition;
414c2c66affSColin Finck                 PartialDesc->Flags = Descriptor->Flags;
415c2c66affSColin Finck                 ASSERT(Descriptor->u.Interrupt.MinimumVector ==
416c2c66affSColin Finck                        Descriptor->u.Interrupt.MaximumVector);
417c2c66affSColin Finck                 PartialDesc->u.Interrupt.Vector = Descriptor->u.Interrupt.MinimumVector;
418c2c66affSColin Finck                 PartialDesc->u.Interrupt.Level = Descriptor->u.Interrupt.MinimumVector;
419c2c66affSColin Finck                 PartialDesc->u.Interrupt.Affinity = 0xFFFFFFFF;
420c2c66affSColin Finck 
421c2c66affSColin Finck                 ResourceList->List[0].PartialResourceList.Count++;
422c2c66affSColin Finck 
423c2c66affSColin Finck                 break;
424c2c66affSColin Finck             }
425c2c66affSColin Finck         }
426c2c66affSColin Finck 
427c2c66affSColin Finck         /* Return resources and success */
428c2c66affSColin Finck         *Resources = ResourceList;
429c2c66affSColin Finck 
430c2c66affSColin Finck         ExFreePoolWithTag(RequirementsList, TAG_HAL);
431c2c66affSColin Finck 
432c2c66affSColin Finck         return STATUS_SUCCESS;
433c2c66affSColin Finck     }
434c2c66affSColin Finck     else if (DeviceExtension->PdoType == WdPdo)
435c2c66affSColin Finck     {
436c2c66affSColin Finck         /* Watchdog doesn't */
437c2c66affSColin Finck         return STATUS_NOT_SUPPORTED;
438c2c66affSColin Finck     }
439c2c66affSColin Finck     else
440c2c66affSColin Finck     {
441c2c66affSColin Finck         /* This shouldn't happen */
442c2c66affSColin Finck         return STATUS_UNSUCCESSFUL;
443c2c66affSColin Finck     }
444c2c66affSColin Finck }
445c2c66affSColin Finck 
446c2c66affSColin Finck NTSTATUS
447c2c66affSColin Finck NTAPI
HalpQueryResourceRequirements(IN PDEVICE_OBJECT DeviceObject,OUT PIO_RESOURCE_REQUIREMENTS_LIST * Requirements)448c2c66affSColin Finck HalpQueryResourceRequirements(IN PDEVICE_OBJECT DeviceObject,
449c2c66affSColin Finck                               OUT PIO_RESOURCE_REQUIREMENTS_LIST *Requirements)
450c2c66affSColin Finck {
451c2c66affSColin Finck     PPDO_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
452c2c66affSColin Finck     PAGED_CODE();
453c2c66affSColin Finck 
454c2c66affSColin Finck     /* Only the ACPI PDO has requirements */
455c2c66affSColin Finck     if (DeviceExtension->PdoType == AcpiPdo)
456c2c66affSColin Finck     {
457c2c66affSColin Finck         /* Query ACPI requirements */
458c2c66affSColin Finck         return HalpQueryAcpiResourceRequirements(Requirements);
459c2c66affSColin Finck     }
460c2c66affSColin Finck     else if (DeviceExtension->PdoType == WdPdo)
461c2c66affSColin Finck     {
462c2c66affSColin Finck         /* Watchdog doesn't */
463c2c66affSColin Finck         return STATUS_NOT_SUPPORTED;
464c2c66affSColin Finck     }
465c2c66affSColin Finck     else
466c2c66affSColin Finck     {
467c2c66affSColin Finck         /* This shouldn't happen */
468c2c66affSColin Finck         return STATUS_UNSUCCESSFUL;
469c2c66affSColin Finck     }
470c2c66affSColin Finck }
471c2c66affSColin Finck 
472c2c66affSColin Finck NTSTATUS
473c2c66affSColin Finck NTAPI
HalpQueryIdPdo(IN PDEVICE_OBJECT DeviceObject,IN BUS_QUERY_ID_TYPE IdType,OUT PUSHORT * BusQueryId)474c2c66affSColin Finck HalpQueryIdPdo(IN PDEVICE_OBJECT DeviceObject,
475c2c66affSColin Finck                IN BUS_QUERY_ID_TYPE IdType,
476c2c66affSColin Finck                OUT PUSHORT *BusQueryId)
477c2c66affSColin Finck {
478c2c66affSColin Finck     PPDO_EXTENSION PdoExtension;
479c2c66affSColin Finck     PDO_TYPE PdoType;
480c2c66affSColin Finck     PWCHAR CurrentId;
481c2c66affSColin Finck     WCHAR Id[100];
482c2c66affSColin Finck     NTSTATUS Status;
483c2c66affSColin Finck     SIZE_T Length = 0;
484c2c66affSColin Finck     PWCHAR Buffer;
485c2c66affSColin Finck 
486c2c66affSColin Finck     /* Get the PDO type */
487c2c66affSColin Finck     PdoExtension = DeviceObject->DeviceExtension;
488c2c66affSColin Finck     PdoType = PdoExtension->PdoType;
489c2c66affSColin Finck 
490c2c66affSColin Finck     /* What kind of ID is being requested? */
491c2c66affSColin Finck     DPRINT("ID: %d\n", IdType);
492c2c66affSColin Finck     switch (IdType)
493c2c66affSColin Finck     {
494c2c66affSColin Finck         case BusQueryDeviceID:
495c2c66affSColin Finck         case BusQueryHardwareIDs:
496c2c66affSColin Finck 
497c2c66affSColin Finck             /* What kind of PDO is this? */
498c2c66affSColin Finck             if (PdoType == AcpiPdo)
499c2c66affSColin Finck             {
500c2c66affSColin Finck                 /* ACPI ID */
501c2c66affSColin Finck                 CurrentId = L"ACPI_HAL\\PNP0C08";
502c2c66affSColin Finck                 RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
503c2c66affSColin Finck                 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
504c2c66affSColin Finck 
505c2c66affSColin Finck                 CurrentId = L"*PNP0C08";
506c2c66affSColin Finck                 RtlCopyMemory(&Id[wcslen(Id) + 1], CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
507c2c66affSColin Finck                 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
508c2c66affSColin Finck             }
509c2c66affSColin Finck             else if (PdoType == WdPdo)
510c2c66affSColin Finck             {
511c2c66affSColin Finck                 /* WatchDog ID */
512c2c66affSColin Finck                 CurrentId = L"ACPI_HAL\\PNP0C18";
513c2c66affSColin Finck                 RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
514c2c66affSColin Finck                 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
515c2c66affSColin Finck 
516c2c66affSColin Finck                 CurrentId = L"*PNP0C18";
517c2c66affSColin Finck                 RtlCopyMemory(&Id[wcslen(Id) + 1], CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
518c2c66affSColin Finck                 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
519c2c66affSColin Finck             }
520c2c66affSColin Finck             else
521c2c66affSColin Finck             {
522c2c66affSColin Finck                 /* Unknown */
523c2c66affSColin Finck                 return STATUS_NOT_SUPPORTED;
524c2c66affSColin Finck             }
525c2c66affSColin Finck             break;
526c2c66affSColin Finck 
527c2c66affSColin Finck         case BusQueryInstanceID:
528c2c66affSColin Finck 
529c2c66affSColin Finck             /* Instance ID */
530c2c66affSColin Finck             CurrentId = L"0";
531c2c66affSColin Finck             RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
532c2c66affSColin Finck             Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
533c2c66affSColin Finck             break;
534c2c66affSColin Finck 
535c2c66affSColin Finck         case BusQueryCompatibleIDs:
536c2c66affSColin Finck         default:
537c2c66affSColin Finck 
538c2c66affSColin Finck             /* We don't support anything else */
539c2c66affSColin Finck             return STATUS_NOT_SUPPORTED;
540c2c66affSColin Finck     }
541c2c66affSColin Finck 
542c2c66affSColin Finck 
543c2c66affSColin Finck     /* Allocate the buffer */
544c2c66affSColin Finck     Buffer = ExAllocatePoolWithTag(PagedPool,
545c2c66affSColin Finck                                    Length + sizeof(UNICODE_NULL),
546c2c66affSColin Finck                                    TAG_HAL);
547c2c66affSColin Finck     if (Buffer)
548c2c66affSColin Finck     {
549c2c66affSColin Finck         /* Copy the string and null-terminate it */
550c2c66affSColin Finck         RtlCopyMemory(Buffer, Id, Length);
551c2c66affSColin Finck         Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
552c2c66affSColin Finck 
553c2c66affSColin Finck         /* Return string */
554c2c66affSColin Finck         *BusQueryId = Buffer;
555c2c66affSColin Finck         Status = STATUS_SUCCESS;
556c2c66affSColin Finck         DPRINT("Returning: %S\n", *BusQueryId);
557c2c66affSColin Finck     }
558c2c66affSColin Finck     else
559c2c66affSColin Finck     {
560c2c66affSColin Finck         /* Fail */
561c2c66affSColin Finck         Status = STATUS_INSUFFICIENT_RESOURCES;
562c2c66affSColin Finck     }
563c2c66affSColin Finck 
564c2c66affSColin Finck     /* Return status */
565c2c66affSColin Finck     return Status;
566c2c66affSColin Finck }
567c2c66affSColin Finck 
568c2c66affSColin Finck NTSTATUS
569c2c66affSColin Finck NTAPI
HalpQueryIdFdo(IN PDEVICE_OBJECT DeviceObject,IN BUS_QUERY_ID_TYPE IdType,OUT PUSHORT * BusQueryId)570c2c66affSColin Finck HalpQueryIdFdo(IN PDEVICE_OBJECT DeviceObject,
571c2c66affSColin Finck                IN BUS_QUERY_ID_TYPE IdType,
572c2c66affSColin Finck                OUT PUSHORT *BusQueryId)
573c2c66affSColin Finck {
574c2c66affSColin Finck     NTSTATUS Status;
575c2c66affSColin Finck     SIZE_T Length;
576c2c66affSColin Finck     PWCHAR Id;
577c2c66affSColin Finck     PWCHAR Buffer;
578c2c66affSColin Finck 
579c2c66affSColin Finck     /* What kind of ID is being requested? */
580c2c66affSColin Finck     DPRINT("ID: %d\n", IdType);
581c2c66affSColin Finck     switch (IdType)
582c2c66affSColin Finck     {
583c2c66affSColin Finck         case BusQueryDeviceID:
584c2c66affSColin Finck         case BusQueryHardwareIDs:
585c2c66affSColin Finck 
586c2c66affSColin Finck             /* This is our hardware ID */
587c2c66affSColin Finck             Id = HalHardwareIdString;
588c2c66affSColin Finck             break;
589c2c66affSColin Finck 
590c2c66affSColin Finck         case BusQueryInstanceID:
591c2c66affSColin Finck 
592c2c66affSColin Finck             /* And our instance ID */
593c2c66affSColin Finck             Id = L"0";
594c2c66affSColin Finck             break;
595c2c66affSColin Finck 
596c2c66affSColin Finck         default:
597c2c66affSColin Finck 
598c2c66affSColin Finck             /* We don't support anything else */
599c2c66affSColin Finck             return STATUS_NOT_SUPPORTED;
600c2c66affSColin Finck     }
601c2c66affSColin Finck 
602c2c66affSColin Finck     /* Calculate the length */
603c2c66affSColin Finck     Length = (wcslen(Id) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
604c2c66affSColin Finck 
605c2c66affSColin Finck     /* Allocate the buffer */
606c2c66affSColin Finck     Buffer = ExAllocatePoolWithTag(PagedPool,
607c2c66affSColin Finck                                    Length + sizeof(UNICODE_NULL),
608c2c66affSColin Finck                                    TAG_HAL);
609c2c66affSColin Finck     if (Buffer)
610c2c66affSColin Finck     {
611c2c66affSColin Finck         /* Copy the string and null-terminate it */
612c2c66affSColin Finck         RtlCopyMemory(Buffer, Id, Length);
613c2c66affSColin Finck         Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
614c2c66affSColin Finck 
615c2c66affSColin Finck         /* Return string */
616c2c66affSColin Finck         *BusQueryId = Buffer;
617c2c66affSColin Finck         Status = STATUS_SUCCESS;
618c2c66affSColin Finck         DPRINT("Returning: %S\n", *BusQueryId);
619c2c66affSColin Finck     }
620c2c66affSColin Finck     else
621c2c66affSColin Finck     {
622c2c66affSColin Finck         /* Fail */
623c2c66affSColin Finck         Status = STATUS_INSUFFICIENT_RESOURCES;
624c2c66affSColin Finck     }
625c2c66affSColin Finck 
626c2c66affSColin Finck     /* Return status */
627c2c66affSColin Finck     return Status;
628c2c66affSColin Finck }
629c2c66affSColin Finck 
630c2c66affSColin Finck NTSTATUS
631c2c66affSColin Finck NTAPI
HalpDispatchPnp(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)632c2c66affSColin Finck HalpDispatchPnp(IN PDEVICE_OBJECT DeviceObject,
633c2c66affSColin Finck                 IN PIRP Irp)
634c2c66affSColin Finck {
635c2c66affSColin Finck     PIO_STACK_LOCATION IoStackLocation;
636c2c66affSColin Finck     //PPDO_EXTENSION PdoExtension;
637c2c66affSColin Finck     PFDO_EXTENSION FdoExtension;
638c2c66affSColin Finck     NTSTATUS Status;
639c2c66affSColin Finck     UCHAR Minor;
640c2c66affSColin Finck 
641c2c66affSColin Finck     /* Get the device extension and stack location */
642c2c66affSColin Finck     FdoExtension = DeviceObject->DeviceExtension;
643c2c66affSColin Finck     IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
644c2c66affSColin Finck     Minor = IoStackLocation->MinorFunction;
645c2c66affSColin Finck 
646c2c66affSColin Finck     /* FDO? */
647c2c66affSColin Finck     if (FdoExtension->ExtensionType == FdoExtensionType)
648c2c66affSColin Finck     {
649c2c66affSColin Finck         /* Query the IRP type */
650c2c66affSColin Finck         switch (Minor)
651c2c66affSColin Finck         {
652c2c66affSColin Finck             case IRP_MN_QUERY_DEVICE_RELATIONS:
653c2c66affSColin Finck 
654c2c66affSColin Finck                 /* Call the worker */
655c2c66affSColin Finck                 DPRINT("Querying device relations for FDO\n");
656c2c66affSColin Finck                 Status = HalpQueryDeviceRelations(DeviceObject,
657c2c66affSColin Finck                                                   IoStackLocation->Parameters.QueryDeviceRelations.Type,
658c2c66affSColin Finck                                                   (PVOID)&Irp->IoStatus.Information);
659c2c66affSColin Finck                 break;
660c2c66affSColin Finck 
661c2c66affSColin Finck             case IRP_MN_QUERY_INTERFACE:
662c2c66affSColin Finck 
663c2c66affSColin Finck                 /* Call the worker */
664c2c66affSColin Finck                 DPRINT("Querying interface for FDO\n");
665c2c66affSColin Finck                 Status = HalpQueryInterface(DeviceObject,
666c2c66affSColin Finck                                             IoStackLocation->Parameters.QueryInterface.InterfaceType,
667c2c66affSColin Finck                                             IoStackLocation->Parameters.QueryInterface.Size,
668c2c66affSColin Finck                                             IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData,
669c2c66affSColin Finck                                             IoStackLocation->Parameters.QueryInterface.Version,
670c2c66affSColin Finck                                             IoStackLocation->Parameters.QueryInterface.Interface,
671c2c66affSColin Finck                                             (PVOID)&Irp->IoStatus.Information);
672c2c66affSColin Finck                 break;
673c2c66affSColin Finck 
674c2c66affSColin Finck 
675c2c66affSColin Finck             case IRP_MN_QUERY_ID:
676c2c66affSColin Finck 
677c2c66affSColin Finck                 /* Call the worker */
678c2c66affSColin Finck                 DPRINT("Querying ID for FDO\n");
679c2c66affSColin Finck                 Status = HalpQueryIdFdo(DeviceObject,
680c2c66affSColin Finck                                         IoStackLocation->Parameters.QueryId.IdType,
681c2c66affSColin Finck                                         (PVOID)&Irp->IoStatus.Information);
682c2c66affSColin Finck                 break;
683c2c66affSColin Finck 
684c2c66affSColin Finck             case IRP_MN_QUERY_CAPABILITIES:
685c2c66affSColin Finck 
686c2c66affSColin Finck                 /* Call the worker */
687c2c66affSColin Finck                 DPRINT("Querying the capabilities for the FDO\n");
688c2c66affSColin Finck                 Status = HalpQueryCapabilities(DeviceObject,
689c2c66affSColin Finck                                                IoStackLocation->Parameters.DeviceCapabilities.Capabilities);
690c2c66affSColin Finck                 break;
691c2c66affSColin Finck 
692c2c66affSColin Finck             default:
693c2c66affSColin Finck 
694c2c66affSColin Finck                 DPRINT("Other IRP: %lx\n", Minor);
6958248f02fSVictor Perevertkin                 Status = STATUS_NOT_SUPPORTED;
696c2c66affSColin Finck                 break;
697c2c66affSColin Finck         }
698c2c66affSColin Finck 
6998248f02fSVictor Perevertkin         /* What happpened? */
7008248f02fSVictor Perevertkin         if ((NT_SUCCESS(Status)) || (Status == STATUS_NOT_SUPPORTED))
7018248f02fSVictor Perevertkin         {
7028248f02fSVictor Perevertkin             /* Set the IRP status, unless this isn't understood */
7038248f02fSVictor Perevertkin             if (Status != STATUS_NOT_SUPPORTED)
7048248f02fSVictor Perevertkin             {
7058248f02fSVictor Perevertkin                 Irp->IoStatus.Status = Status;
7068248f02fSVictor Perevertkin             }
7078248f02fSVictor Perevertkin 
7088248f02fSVictor Perevertkin             /* Pass it on */
7098248f02fSVictor Perevertkin             IoSkipCurrentIrpStackLocation(Irp);
7108248f02fSVictor Perevertkin             return IoCallDriver(FdoExtension->AttachedDeviceObject, Irp);
7118248f02fSVictor Perevertkin         }
7128248f02fSVictor Perevertkin 
7138248f02fSVictor Perevertkin         /* Otherwise, we failed, so set the status and complete the request */
7148248f02fSVictor Perevertkin         DPRINT1("IRP failed with status: %lx\n", Status);
715c2c66affSColin Finck         Irp->IoStatus.Status = Status;
716c2c66affSColin Finck         IoCompleteRequest(Irp, IO_NO_INCREMENT);
717c2c66affSColin Finck         return Status;
718c2c66affSColin Finck     }
719c2c66affSColin Finck     else
720c2c66affSColin Finck     {
721c2c66affSColin Finck         /* This is a PDO instead */
722c2c66affSColin Finck         ASSERT(FdoExtension->ExtensionType == PdoExtensionType);
723c2c66affSColin Finck         //PdoExtension = (PPDO_EXTENSION)FdoExtension;
724c2c66affSColin Finck         /* Query the IRP type */
725c2c66affSColin Finck         Status = STATUS_SUCCESS;
726c2c66affSColin Finck         switch (Minor)
727c2c66affSColin Finck         {
728c2c66affSColin Finck             case IRP_MN_START_DEVICE:
729c2c66affSColin Finck 
730c2c66affSColin Finck                 /* We only care about a PCI PDO */
731c2c66affSColin Finck                 DPRINT1("Start device received\n");
732c2c66affSColin Finck                 /* Complete the IRP normally */
733c2c66affSColin Finck                 break;
734c2c66affSColin Finck 
735c2c66affSColin Finck             case IRP_MN_REMOVE_DEVICE:
736c2c66affSColin Finck 
737c2c66affSColin Finck                 /* Check if this is a PCI device */
738c2c66affSColin Finck                 DPRINT1("Remove device received\n");
739c2c66affSColin Finck 
740c2c66affSColin Finck                 /* We're done */
741c2c66affSColin Finck                 Status = STATUS_SUCCESS;
742c2c66affSColin Finck                 break;
743c2c66affSColin Finck 
744c2c66affSColin Finck             case IRP_MN_SURPRISE_REMOVAL:
745c2c66affSColin Finck 
746c2c66affSColin Finck                 /* Inherit whatever status we had */
747c2c66affSColin Finck                 DPRINT1("Surprise removal IRP\n");
748c2c66affSColin Finck                 Status = Irp->IoStatus.Status;
749c2c66affSColin Finck                 break;
750c2c66affSColin Finck 
751c2c66affSColin Finck             case IRP_MN_QUERY_DEVICE_RELATIONS:
752c2c66affSColin Finck 
753c2c66affSColin Finck                 /* Query the device relations */
754c2c66affSColin Finck                 DPRINT("Querying PDO relations\n");
755c2c66affSColin Finck                 Status = HalpQueryDeviceRelations(DeviceObject,
756c2c66affSColin Finck                                                   IoStackLocation->Parameters.QueryDeviceRelations.Type,
757c2c66affSColin Finck                                                   (PVOID)&Irp->IoStatus.Information);
758c2c66affSColin Finck                 break;
759c2c66affSColin Finck 
760c2c66affSColin Finck             case IRP_MN_QUERY_INTERFACE:
761c2c66affSColin Finck 
762c2c66affSColin Finck                 /* Call the worker */
763c2c66affSColin Finck                 DPRINT("Querying interface for PDO\n");
764c2c66affSColin Finck                 Status = HalpQueryInterface(DeviceObject,
765c2c66affSColin Finck                                             IoStackLocation->Parameters.QueryInterface.InterfaceType,
766c2c66affSColin Finck                                             IoStackLocation->Parameters.QueryInterface.Size,
767c2c66affSColin Finck                                             IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData,
768c2c66affSColin Finck                                             IoStackLocation->Parameters.QueryInterface.Version,
769c2c66affSColin Finck                                             IoStackLocation->Parameters.QueryInterface.Interface,
770c2c66affSColin Finck                                             (PVOID)&Irp->IoStatus.Information);
771c2c66affSColin Finck                 break;
772c2c66affSColin Finck 
773c2c66affSColin Finck             case IRP_MN_QUERY_CAPABILITIES:
774c2c66affSColin Finck 
775c2c66affSColin Finck                 /* Call the worker */
776c2c66affSColin Finck                 DPRINT("Querying the capabilities for the PDO\n");
777c2c66affSColin Finck                 Status = HalpQueryCapabilities(DeviceObject,
778c2c66affSColin Finck                                                IoStackLocation->Parameters.DeviceCapabilities.Capabilities);
779c2c66affSColin Finck                 break;
780c2c66affSColin Finck 
781c2c66affSColin Finck             case IRP_MN_QUERY_RESOURCES:
782c2c66affSColin Finck 
783c2c66affSColin Finck                 /* Call the worker */
784c2c66affSColin Finck                 DPRINT("Querying the resources for the PDO\n");
785c2c66affSColin Finck                 Status = HalpQueryResources(DeviceObject, (PVOID)&Irp->IoStatus.Information);
786c2c66affSColin Finck                 break;
787c2c66affSColin Finck 
788c2c66affSColin Finck             case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
789c2c66affSColin Finck 
790c2c66affSColin Finck                 /* Call the worker */
791c2c66affSColin Finck                 DPRINT("Querying the resource requirements for the PDO\n");
792c2c66affSColin Finck                 Status = HalpQueryResourceRequirements(DeviceObject,
793c2c66affSColin Finck                                                        (PVOID)&Irp->IoStatus.Information);
794c2c66affSColin Finck                 break;
795c2c66affSColin Finck 
796c2c66affSColin Finck             case IRP_MN_QUERY_ID:
797c2c66affSColin Finck 
798c2c66affSColin Finck                 /* Call the worker */
799c2c66affSColin Finck                 DPRINT("Query the ID for the PDO\n");
800c2c66affSColin Finck                 Status = HalpQueryIdPdo(DeviceObject,
801c2c66affSColin Finck                                         IoStackLocation->Parameters.QueryId.IdType,
802c2c66affSColin Finck                                         (PVOID)&Irp->IoStatus.Information);
803c2c66affSColin Finck                 break;
804c2c66affSColin Finck 
805c2c66affSColin Finck             default:
806c2c66affSColin Finck 
807c2c66affSColin Finck                 /* We don't handle anything else, so inherit the old state */
808c2c66affSColin Finck                 DPRINT("Illegal IRP: %lx\n", Minor);
809c2c66affSColin Finck                 Status = Irp->IoStatus.Status;
810c2c66affSColin Finck                 break;
811c2c66affSColin Finck         }
812c2c66affSColin Finck 
813c2c66affSColin Finck         /* If it's not supported, inherit the old status */
814c2c66affSColin Finck         if (Status == STATUS_NOT_SUPPORTED) Status = Irp->IoStatus.Status;
815c2c66affSColin Finck 
816c2c66affSColin Finck         /* Complete the IRP */
817c2c66affSColin Finck         DPRINT("IRP completed with status: %lx\n", Status);
818c2c66affSColin Finck         Irp->IoStatus.Status = Status;
819c2c66affSColin Finck         IoCompleteRequest(Irp, IO_NO_INCREMENT);
820c2c66affSColin Finck         return Status;
821c2c66affSColin Finck     }
822c2c66affSColin Finck }
823c2c66affSColin Finck 
824c2c66affSColin Finck NTSTATUS
825c2c66affSColin Finck NTAPI
HalpDispatchWmi(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)826c2c66affSColin Finck HalpDispatchWmi(IN PDEVICE_OBJECT DeviceObject,
827c2c66affSColin Finck                 IN PIRP Irp)
828c2c66affSColin Finck {
829c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK("HAL: PnP Driver WMI!\n");
830c2c66affSColin Finck     return STATUS_SUCCESS;
831c2c66affSColin Finck }
832c2c66affSColin Finck 
833c2c66affSColin Finck NTSTATUS
834c2c66affSColin Finck NTAPI
HalpDispatchPower(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)835c2c66affSColin Finck HalpDispatchPower(IN PDEVICE_OBJECT DeviceObject,
836c2c66affSColin Finck                   IN PIRP Irp)
837c2c66affSColin Finck {
838c2c66affSColin Finck     PFDO_EXTENSION FdoExtension;
839c2c66affSColin Finck 
840c2c66affSColin Finck     DPRINT("HAL: PnP Driver Power!\n");
841c2c66affSColin Finck     FdoExtension = DeviceObject->DeviceExtension;
842c2c66affSColin Finck     if (FdoExtension->ExtensionType == FdoExtensionType)
843c2c66affSColin Finck     {
844c2c66affSColin Finck         PoStartNextPowerIrp(Irp);
845c2c66affSColin Finck         IoSkipCurrentIrpStackLocation(Irp);
846c2c66affSColin Finck         return PoCallDriver(FdoExtension->AttachedDeviceObject, Irp);
847c2c66affSColin Finck     }
848c2c66affSColin Finck     else
849c2c66affSColin Finck     {
850c2c66affSColin Finck         PoStartNextPowerIrp(Irp);
851c2c66affSColin Finck         Irp->IoStatus.Status = STATUS_SUCCESS;
852c2c66affSColin Finck         IoCompleteRequest(Irp, IO_NO_INCREMENT);
853c2c66affSColin Finck         return STATUS_SUCCESS;
854c2c66affSColin Finck     }
855c2c66affSColin Finck }
856c2c66affSColin Finck 
857c2c66affSColin Finck NTSTATUS
858c2c66affSColin Finck NTAPI
HalpDriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)859c2c66affSColin Finck HalpDriverEntry(IN PDRIVER_OBJECT DriverObject,
860c2c66affSColin Finck                 IN PUNICODE_STRING RegistryPath)
861c2c66affSColin Finck {
862c2c66affSColin Finck     NTSTATUS Status;
863c2c66affSColin Finck     PDEVICE_OBJECT TargetDevice = NULL;
864c2c66affSColin Finck 
865c2c66affSColin Finck     DPRINT("HAL: PnP Driver ENTRY!\n");
866c2c66affSColin Finck 
867c2c66affSColin Finck     /* This is us */
868c2c66affSColin Finck     HalpDriverObject = DriverObject;
869c2c66affSColin Finck 
870c2c66affSColin Finck     /* Set up add device */
871c2c66affSColin Finck     DriverObject->DriverExtension->AddDevice = HalpAddDevice;
872c2c66affSColin Finck 
873c2c66affSColin Finck     /* Set up the callouts */
874c2c66affSColin Finck     DriverObject->MajorFunction[IRP_MJ_PNP] = HalpDispatchPnp;
875c2c66affSColin Finck     DriverObject->MajorFunction[IRP_MJ_POWER] = HalpDispatchPower;
876c2c66affSColin Finck     DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HalpDispatchWmi;
877c2c66affSColin Finck 
8788aff2c9dSVictor Perevertkin     /* Create the PDO and tell the PnP manager about us*/
8798aff2c9dSVictor Perevertkin     Status = IoReportDetectedDevice(DriverObject,
8808aff2c9dSVictor Perevertkin                                     InterfaceTypeUndefined,
8818aff2c9dSVictor Perevertkin                                     -1,
8828aff2c9dSVictor Perevertkin                                     -1,
883c2c66affSColin Finck                                     NULL,
8848aff2c9dSVictor Perevertkin                                     NULL,
885c2c66affSColin Finck                                     FALSE,
886c2c66affSColin Finck                                     &TargetDevice);
887c2c66affSColin Finck     if (!NT_SUCCESS(Status))
888c2c66affSColin Finck         return Status;
889c2c66affSColin Finck 
890c2c66affSColin Finck     TargetDevice->Flags &= ~DO_DEVICE_INITIALIZING;
891c2c66affSColin Finck 
892c2c66affSColin Finck     /* Set up the device stack */
893c2c66affSColin Finck     Status = HalpAddDevice(DriverObject, TargetDevice);
894c2c66affSColin Finck     if (!NT_SUCCESS(Status))
895c2c66affSColin Finck     {
896c2c66affSColin Finck         IoDeleteDevice(TargetDevice);
897c2c66affSColin Finck         return Status;
898c2c66affSColin Finck     }
899c2c66affSColin Finck 
900c2c66affSColin Finck     /* Return to kernel */
901c2c66affSColin Finck     return Status;
902c2c66affSColin Finck }
903c2c66affSColin Finck 
904c2c66affSColin Finck NTSTATUS
905c2c66affSColin Finck NTAPI
HaliInitPnpDriver(VOID)906c2c66affSColin Finck HaliInitPnpDriver(VOID)
907c2c66affSColin Finck {
908c2c66affSColin Finck     NTSTATUS Status;
909c2c66affSColin Finck     UNICODE_STRING DriverString;
910c2c66affSColin Finck     PAGED_CODE();
911c2c66affSColin Finck 
912c2c66affSColin Finck     /* Create the driver */
913c2c66affSColin Finck     RtlInitUnicodeString(&DriverString, L"\\Driver\\ACPI_HAL");
914c2c66affSColin Finck     Status = IoCreateDriver(&DriverString, HalpDriverEntry);
915c2c66affSColin Finck 
916c2c66affSColin Finck     /* Return status */
917c2c66affSColin Finck     return Status;
918c2c66affSColin Finck }
919c2c66affSColin Finck 
920c2c66affSColin Finck /* EOF */
921