[ACPICA]
[reactos.git] / reactos / drivers / bus / acpi / main.c
1 #include "precomp.h"
2
3 #include <poclass.h>
4
5 #define NDEBUG
6 #include <debug.h>
7
8 NTSTATUS
9 NTAPI
10 DriverEntry (
11 PDRIVER_OBJECT DriverObject,
12 PUNICODE_STRING RegistryPath
13 );
14
15 #ifdef ALLOC_PRAGMA
16 #pragma alloc_text (INIT, DriverEntry)
17 #pragma alloc_text (PAGE, Bus_AddDevice)
18
19 #endif
20
21 extern struct acpi_device *sleep_button;
22 extern struct acpi_device *power_button;
23
24 UNICODE_STRING ProcessorHardwareIds = {0, 0, NULL};
25 LPWSTR ProcessorNameString = NULL;
26
27
28 NTSTATUS
29 NTAPI
30 Bus_AddDevice(
31 PDRIVER_OBJECT DriverObject,
32 PDEVICE_OBJECT PhysicalDeviceObject
33 )
34
35 {
36 NTSTATUS status;
37 PDEVICE_OBJECT deviceObject = NULL;
38 PFDO_DEVICE_DATA deviceData = NULL;
39 PWCHAR deviceName = NULL;
40 #ifndef NDEBUG
41 ULONG nameLength;
42 #endif
43
44 PAGED_CODE ();
45
46 DPRINT("Add Device: 0x%p\n", PhysicalDeviceObject);
47
48 DPRINT("#################### Bus_CreateClose Creating FDO Device ####################\n");
49 status = IoCreateDevice(DriverObject,
50 sizeof(FDO_DEVICE_DATA),
51 NULL,
52 FILE_DEVICE_ACPI,
53 FILE_DEVICE_SECURE_OPEN,
54 TRUE,
55 &deviceObject);
56 if (!NT_SUCCESS(status))
57 {
58 DPRINT1("IoCreateDevice() failed with status 0x%X\n", status);
59 goto End;
60 }
61
62 deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension;
63 RtlZeroMemory (deviceData, sizeof (FDO_DEVICE_DATA));
64
65 //
66 // Set the initial state of the FDO
67 //
68
69 INITIALIZE_PNP_STATE(deviceData->Common);
70
71 deviceData->Common.IsFDO = TRUE;
72
73 deviceData->Common.Self = deviceObject;
74
75 ExInitializeFastMutex (&deviceData->Mutex);
76
77 InitializeListHead (&deviceData->ListOfPDOs);
78
79 // Set the PDO for use with PlugPlay functions
80
81 deviceData->UnderlyingPDO = PhysicalDeviceObject;
82
83 //
84 // Set the initial powerstate of the FDO
85 //
86
87 deviceData->Common.DevicePowerState = PowerDeviceUnspecified;
88 deviceData->Common.SystemPowerState = PowerSystemWorking;
89
90 deviceObject->Flags |= DO_POWER_PAGABLE;
91
92 //
93 // Attach our FDO to the device stack.
94 // The return value of IoAttachDeviceToDeviceStack is the top of the
95 // attachment chain. This is where all the IRPs should be routed.
96 //
97
98 deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack (
99 deviceObject,
100 PhysicalDeviceObject);
101
102 if (NULL == deviceData->NextLowerDriver) {
103
104 status = STATUS_NO_SUCH_DEVICE;
105 goto End;
106 }
107
108
109 #ifndef NDEBUG
110 //
111 // We will demonstrate here the step to retrieve the name of the PDO
112 //
113
114 status = IoGetDeviceProperty (PhysicalDeviceObject,
115 DevicePropertyPhysicalDeviceObjectName,
116 0,
117 NULL,
118 &nameLength);
119
120 if (status != STATUS_BUFFER_TOO_SMALL)
121 {
122 DPRINT1("AddDevice:IoGDP failed (0x%x)\n", status);
123 goto End;
124 }
125
126 deviceName = ExAllocatePoolWithTag(NonPagedPool, nameLength, 'MpcA');
127
128 if (NULL == deviceName) {
129 DPRINT1("AddDevice: no memory to alloc for deviceName(0x%x)\n", nameLength);
130 status = STATUS_INSUFFICIENT_RESOURCES;
131 goto End;
132 }
133
134 status = IoGetDeviceProperty (PhysicalDeviceObject,
135 DevicePropertyPhysicalDeviceObjectName,
136 nameLength,
137 deviceName,
138 &nameLength);
139
140 if (!NT_SUCCESS (status)) {
141
142 DPRINT1("AddDevice:IoGDP(2) failed (0x%x)", status);
143 goto End;
144 }
145
146 DPRINT("AddDevice: %p to %p->%p (%ws) \n",
147 deviceObject,
148 deviceData->NextLowerDriver,
149 PhysicalDeviceObject,
150 deviceName);
151
152 #endif
153
154 //
155 // We are done with initializing, so let's indicate that and return.
156 // This should be the final step in the AddDevice process.
157 //
158 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
159
160 End:
161 if (deviceName){
162 ExFreePoolWithTag(deviceName, 'MpcA');
163 }
164 if (!NT_SUCCESS(status) && deviceObject){
165 if (deviceData && deviceData->NextLowerDriver){
166 IoDetachDevice (deviceData->NextLowerDriver);
167 }
168 IoDeleteDevice (deviceObject);
169 }
170 return status;
171
172 }
173
174 NTSTATUS
175 NTAPI
176 ACPIDispatchCreateClose(
177 IN PDEVICE_OBJECT DeviceObject,
178 IN PIRP Irp)
179 {
180 Irp->IoStatus.Status = STATUS_SUCCESS;
181 Irp->IoStatus.Information = 0;
182
183 IoCompleteRequest(Irp, IO_NO_INCREMENT);
184
185 return STATUS_SUCCESS;
186 }
187
188 VOID
189 NTAPI
190 ButtonWaitThread(PVOID Context)
191 {
192 PIRP Irp = Context;
193 int result;
194 struct acpi_bus_event event;
195 ULONG ButtonEvent;
196
197 while (ACPI_SUCCESS(result = acpi_bus_receive_event(&event)) &&
198 event.type != ACPI_BUTTON_NOTIFY_STATUS);
199
200 if (!ACPI_SUCCESS(result))
201 {
202 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
203 }
204 else
205 {
206 if (strstr(event.bus_id, "PWRF"))
207 ButtonEvent = SYS_BUTTON_POWER;
208 else if (strstr(event.bus_id, "SLPF"))
209 ButtonEvent = SYS_BUTTON_SLEEP;
210 else
211 ButtonEvent = 0;
212
213 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &ButtonEvent, sizeof(ButtonEvent));
214 Irp->IoStatus.Status = STATUS_SUCCESS;
215 Irp->IoStatus.Information = sizeof(ULONG);
216 }
217
218 IoCompleteRequest(Irp, IO_NO_INCREMENT);
219 }
220
221
222 NTSTATUS
223 NTAPI
224 ACPIDispatchDeviceControl(
225 IN PDEVICE_OBJECT DeviceObject,
226 IN PIRP Irp)
227 {
228 PIO_STACK_LOCATION irpStack;
229 NTSTATUS status = STATUS_NOT_SUPPORTED;
230 PCOMMON_DEVICE_DATA commonData;
231 ULONG Caps = 0;
232 HANDLE ThreadHandle;
233
234 PAGED_CODE ();
235
236 irpStack = IoGetCurrentIrpStackLocation (Irp);
237 ASSERT (IRP_MJ_DEVICE_CONTROL == irpStack->MajorFunction);
238
239 commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
240
241 Irp->IoStatus.Information = 0;
242
243 if (!commonData->IsFDO)
244 {
245 switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
246 {
247 case IOCTL_ACPI_EVAL_METHOD:
248 status = Bus_PDO_EvalMethod((PPDO_DEVICE_DATA)commonData,
249 Irp);
250 break;
251
252 case IOCTL_GET_SYS_BUTTON_CAPS:
253 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
254 {
255 status = STATUS_BUFFER_TOO_SMALL;
256 break;
257 }
258
259 if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D"))
260 {
261 DPRINT1("Lid button reported to power manager\n");
262 Caps |= SYS_BUTTON_LID;
263 }
264 else if (((PPDO_DEVICE_DATA)commonData)->AcpiHandle == NULL)
265 {
266 /* We have to return both at the same time because since we
267 * have a NULL handle we are the fixed feature DO and we will
268 * only be called once (not once per device)
269 */
270 if (power_button)
271 {
272 DPRINT("Fixed power button reported to power manager\n");
273 Caps |= SYS_BUTTON_POWER;
274 }
275 if (sleep_button)
276 {
277 DPRINT("Fixed sleep button reported to power manager\n");
278 Caps |= SYS_BUTTON_SLEEP;
279 }
280 }
281 else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C"))
282 {
283 DPRINT("Control method power button reported to power manager\n");
284 Caps |= SYS_BUTTON_POWER;
285 }
286 else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E"))
287 {
288 DPRINT("Control method sleep reported to power manager\n");
289 Caps |= SYS_BUTTON_SLEEP;
290 }
291 else
292 {
293 DPRINT1("IOCTL_GET_SYS_BUTTON_CAPS sent to a non-button device\n");
294 status = STATUS_INVALID_PARAMETER;
295 }
296
297 if (Caps != 0)
298 {
299 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &Caps, sizeof(Caps));
300 Irp->IoStatus.Information = sizeof(Caps);
301 status = STATUS_SUCCESS;
302 }
303 break;
304
305 case IOCTL_GET_SYS_BUTTON_EVENT:
306 PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, 0, 0, 0, ButtonWaitThread, Irp);
307 ZwClose(ThreadHandle);
308
309 status = STATUS_PENDING;
310 break;
311
312 default:
313 DPRINT1("Unsupported IOCTL: %x\n", irpStack->Parameters.DeviceIoControl.IoControlCode);
314 break;
315 }
316 }
317 else
318 DPRINT1("IOCTL sent to the ACPI FDO! Kill the caller!\n");
319
320 if (status != STATUS_PENDING)
321 {
322 Irp->IoStatus.Status = status;
323 IoCompleteRequest(Irp, IO_NO_INCREMENT);
324 }
325 else
326 IoMarkIrpPending(Irp);
327
328 return status;
329 }
330
331 static
332 NTSTATUS
333 AcpiRegOpenKey(IN HANDLE ParentKeyHandle,
334 IN LPCWSTR KeyName,
335 IN ACCESS_MASK DesiredAccess,
336 OUT HANDLE KeyHandle)
337 {
338 OBJECT_ATTRIBUTES ObjectAttributes;
339 UNICODE_STRING Name;
340
341 RtlInitUnicodeString(&Name, KeyName);
342
343 InitializeObjectAttributes(&ObjectAttributes,
344 &Name,
345 OBJ_CASE_INSENSITIVE,
346 ParentKeyHandle,
347 NULL);
348
349 return ZwOpenKey(KeyHandle,
350 DesiredAccess,
351 &ObjectAttributes);
352 }
353
354 static
355 NTSTATUS
356 AcpiRegQueryValue(IN HANDLE KeyHandle,
357 IN LPWSTR ValueName,
358 OUT PULONG Type OPTIONAL,
359 OUT PVOID Data OPTIONAL,
360 IN OUT PULONG DataLength OPTIONAL)
361 {
362 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
363 UNICODE_STRING Name;
364 ULONG BufferLength = 0;
365 NTSTATUS Status;
366
367 RtlInitUnicodeString(&Name, ValueName);
368
369 if (DataLength != NULL)
370 BufferLength = *DataLength;
371
372 /* Check if the caller provided a valid buffer */
373 if ((Data != NULL) && (BufferLength != 0))
374 {
375 BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
376
377 /* Allocate memory for the value */
378 ValueInfo = ExAllocatePoolWithTag(PagedPool, BufferLength, 'MpcA');
379 if (ValueInfo == NULL)
380 return STATUS_NO_MEMORY;
381 }
382 else
383 {
384 /* Caller didn't provide a valid buffer, assume he wants the size only */
385 ValueInfo = NULL;
386 BufferLength = 0;
387 }
388
389 /* Query the value */
390 Status = ZwQueryValueKey(KeyHandle,
391 &Name,
392 KeyValuePartialInformation,
393 ValueInfo,
394 BufferLength,
395 &BufferLength);
396
397 if (DataLength != NULL)
398 *DataLength = BufferLength;
399
400 /* Check if we have the size only */
401 if (ValueInfo == NULL)
402 {
403 /* Check for unexpected status */
404 if ((Status != STATUS_BUFFER_OVERFLOW) &&
405 (Status != STATUS_BUFFER_TOO_SMALL))
406 {
407 return Status;
408 }
409
410 /* All is well */
411 Status = STATUS_SUCCESS;
412 }
413 /* Otherwise the caller wanted data back, check if we got it */
414 else if (NT_SUCCESS(Status))
415 {
416 if (Type != NULL)
417 *Type = ValueInfo->Type;
418
419 /* Copy it */
420 RtlMoveMemory(Data, ValueInfo->Data, ValueInfo->DataLength);
421
422 /* if the type is REG_SZ and data is not 0-terminated
423 * and there is enough space in the buffer NT appends a \0 */
424 if (((ValueInfo->Type == REG_SZ) ||
425 (ValueInfo->Type == REG_EXPAND_SZ) ||
426 (ValueInfo->Type == REG_MULTI_SZ)) &&
427 (ValueInfo->DataLength <= *DataLength - sizeof(WCHAR)))
428 {
429 WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
430 if ((ptr > (WCHAR *)Data) && ptr[-1])
431 *ptr = 0;
432 }
433 }
434
435 /* Free the memory and return status */
436 if (ValueInfo != NULL)
437 {
438 ExFreePoolWithTag(ValueInfo, 'MpcA');
439 }
440
441 return Status;
442 }
443
444 static
445 NTSTATUS
446 GetProcessorInformation(VOID)
447 {
448 LPWSTR ProcessorIdentifier = NULL;
449 LPWSTR ProcessorVendorIdentifier = NULL;
450 LPWSTR HardwareIdsBuffer = NULL;
451 HANDLE ProcessorHandle = NULL;
452 ULONG Length = 0, Level1Length = 0, Level2Length = 0, Level3Length = 0;
453 SIZE_T HardwareIdsLength = 0;
454 SIZE_T VendorIdentifierLength;
455 ULONG i;
456 PWCHAR Ptr;
457 NTSTATUS Status;
458
459 DPRINT("GetProcessorInformation()\n");
460
461 /* Open the key for CPU 0 */
462 Status = AcpiRegOpenKey(NULL,
463 L"\\Registry\\Machine\\Hardware\\Description\\System\\CentralProcessor\\0",
464 KEY_READ,
465 &ProcessorHandle);
466 if (!NT_SUCCESS(Status))
467 {
468 DPRINT1("Failed to open CentralProcessor registry key: 0x%lx\n", Status);
469 goto done;
470 }
471
472 /* Query the processor identifier length */
473 Status = AcpiRegQueryValue(ProcessorHandle,
474 L"Identifier",
475 NULL,
476 NULL,
477 &Length);
478 if (!NT_SUCCESS(Status))
479 {
480 DPRINT1("Failed to query Identifier value: 0x%lx\n", Status);
481 goto done;
482 }
483
484 /* Remember the length as fallback for level 1-3 length */
485 Level1Length = Level2Length = Level3Length = Length;
486
487 /* Allocate a buffer large enough to be zero terminated */
488 Length += sizeof(UNICODE_NULL);
489 ProcessorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
490 if (ProcessorIdentifier == NULL)
491 {
492 DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
493 Status = STATUS_INSUFFICIENT_RESOURCES;
494 goto done;
495 }
496
497 /* Query the processor identifier string */
498 Status = AcpiRegQueryValue(ProcessorHandle,
499 L"Identifier",
500 NULL,
501 ProcessorIdentifier,
502 &Length);
503 if (!NT_SUCCESS(Status))
504 {
505 DPRINT1("Failed to query Identifier value: 0x%lx\n", Status);
506 goto done;
507 }
508
509 /* Query the processor name length */
510 Length = 0;
511 Status = AcpiRegQueryValue(ProcessorHandle,
512 L"ProcessorNameString",
513 NULL,
514 NULL,
515 &Length);
516 if (!NT_SUCCESS(Status))
517 {
518 DPRINT1("Failed to query ProcessorNameString value: 0x%lx\n", Status);
519 goto done;
520 }
521
522 /* Allocate a buffer large enough to be zero terminated */
523 Length += sizeof(UNICODE_NULL);
524 ProcessorNameString = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
525 if (ProcessorNameString == NULL)
526 {
527 DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
528 Status = STATUS_INSUFFICIENT_RESOURCES;
529 goto done;
530 }
531
532 /* Query the processor name string */
533 Status = AcpiRegQueryValue(ProcessorHandle,
534 L"ProcessorNameString",
535 NULL,
536 ProcessorNameString,
537 &Length);
538 if (!NT_SUCCESS(Status))
539 {
540 DPRINT1("Failed to query ProcessorNameString value: 0x%lx\n", Status);
541 goto done;
542 }
543
544 /* Query the vendor identifier length */
545 Length = 0;
546 Status = AcpiRegQueryValue(ProcessorHandle,
547 L"VendorIdentifier",
548 NULL,
549 NULL,
550 &Length);
551 if (!NT_SUCCESS(Status) || (Length == 0))
552 {
553 DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status);
554 goto done;
555 }
556
557 /* Allocate a buffer large enough to be zero terminated */
558 Length += sizeof(UNICODE_NULL);
559 ProcessorVendorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
560 if (ProcessorVendorIdentifier == NULL)
561 {
562 DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
563 Status = STATUS_INSUFFICIENT_RESOURCES;
564 goto done;
565 }
566
567 /* Query the vendor identifier string */
568 Status = AcpiRegQueryValue(ProcessorHandle,
569 L"VendorIdentifier",
570 NULL,
571 ProcessorVendorIdentifier,
572 &Length);
573 if (!NT_SUCCESS(Status))
574 {
575 DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status);
576 goto done;
577 }
578
579 /* Change spaces to underscores */
580 for (i = 0; i < wcslen(ProcessorIdentifier); i++)
581 {
582 if (ProcessorIdentifier[i] == L' ')
583 ProcessorIdentifier[i] = L'_';
584 }
585
586 Ptr = wcsstr(ProcessorIdentifier, L"Stepping");
587 if (Ptr != NULL)
588 {
589 Ptr--;
590 Level1Length = (ULONG)(Ptr - ProcessorIdentifier);
591 }
592
593 Ptr = wcsstr(ProcessorIdentifier, L"Model");
594 if (Ptr != NULL)
595 {
596 Ptr--;
597 Level2Length = (ULONG)(Ptr - ProcessorIdentifier);
598 }
599
600 Ptr = wcsstr(ProcessorIdentifier, L"Family");
601 if (Ptr != NULL)
602 {
603 Ptr--;
604 Level3Length = (ULONG)(Ptr - ProcessorIdentifier);
605 }
606
607 VendorIdentifierLength = (USHORT)wcslen(ProcessorVendorIdentifier);
608
609 /* Calculate the size of the full REG_MULTI_SZ data (see swprintf below) */
610 HardwareIdsLength = (5 + VendorIdentifierLength + 3 + Level1Length + 1 +
611 1 + VendorIdentifierLength + 3 + Level1Length + 1 +
612 5 + VendorIdentifierLength + 3 + Level2Length + 1 +
613 1 + VendorIdentifierLength + 3 + Level2Length + 1 +
614 5 + VendorIdentifierLength + 3 + Level3Length + 1 +
615 1 + VendorIdentifierLength + 3 + Level3Length + 1 +
616 1) * sizeof(WCHAR);
617
618 /* Allocate a buffer to the data */
619 HardwareIdsBuffer = ExAllocatePoolWithTag(PagedPool, HardwareIdsLength, 'IpcA');
620 if (HardwareIdsBuffer == NULL)
621 {
622 Status = STATUS_INSUFFICIENT_RESOURCES;
623 goto done;
624 }
625
626 Length = 0;
627 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
628 HardwareIdsBuffer[Length++] = UNICODE_NULL;
629
630 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
631 HardwareIdsBuffer[Length++] = UNICODE_NULL;
632
633 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier);
634 HardwareIdsBuffer[Length++] = UNICODE_NULL;
635
636 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier);
637 HardwareIdsBuffer[Length++] = UNICODE_NULL;
638
639 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier);
640 HardwareIdsBuffer[Length++] = UNICODE_NULL;
641
642 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier);
643 HardwareIdsBuffer[Length++] = UNICODE_NULL;
644 HardwareIdsBuffer[Length++] = UNICODE_NULL;
645
646 /* Make sure we counted correctly */
647 NT_ASSERT(Length * sizeof(WCHAR) == HardwareIdsLength);
648
649 ProcessorHardwareIds.Length = (SHORT)HardwareIdsLength;
650 ProcessorHardwareIds.MaximumLength = ProcessorHardwareIds.Length;
651 ProcessorHardwareIds.Buffer = HardwareIdsBuffer;
652
653 done:
654 if (ProcessorHandle != NULL)
655 ZwClose(ProcessorHandle);
656
657 if (ProcessorIdentifier != NULL)
658 ExFreePoolWithTag(ProcessorIdentifier, 'IpcA');
659
660 if (ProcessorVendorIdentifier != NULL)
661 ExFreePoolWithTag(ProcessorVendorIdentifier, 'IpcA');
662
663 if (!NT_SUCCESS(Status))
664 {
665 if (HardwareIdsBuffer != NULL)
666 ExFreePoolWithTag(HardwareIdsBuffer, 'IpcA');
667 }
668
669 return Status;
670 }
671
672 NTSTATUS
673 NTAPI
674 DriverEntry (
675 PDRIVER_OBJECT DriverObject,
676 PUNICODE_STRING RegistryPath
677 )
678 {
679 NTSTATUS Status;
680 DPRINT("Driver Entry \n");
681
682 Status = GetProcessorInformation();
683 if (!NT_SUCCESS(Status))
684 {
685 NT_ASSERT(FALSE);
686 return Status;
687 }
688
689 //
690 // Set entry points into the driver
691 //
692 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ACPIDispatchDeviceControl;
693 DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP;
694 DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power;
695 DriverObject->MajorFunction [IRP_MJ_CREATE] = ACPIDispatchCreateClose;
696 DriverObject->MajorFunction [IRP_MJ_CLOSE] = ACPIDispatchCreateClose;
697
698 DriverObject->DriverExtension->AddDevice = Bus_AddDevice;
699
700 return STATUS_SUCCESS;
701 }