#include <acpi_bus.h>
#include <acpi_drivers.h>
-//#define NDEBUG
+#include <acpiioct.h>
+#include <poclass.h>
+
+#define NDEBUG
#include <debug.h>
#ifdef ALLOC_PRAGMA
#endif
-
+extern struct acpi_device *sleep_button;
+extern struct acpi_device *power_button;
NTSTATUS
NTAPI
PDEVICE_OBJECT deviceObject = NULL;
PFDO_DEVICE_DATA deviceData = NULL;
PWCHAR deviceName = NULL;
+#ifndef NDEBUG
ULONG nameLength;
+#endif
PAGED_CODE ();
DPRINT("Add Device: 0x%p\n", PhysicalDeviceObject);
- DPRINT1("#################### Bus_CreateClose Creating FDO Device ####################\n");
+ DPRINT("#################### Bus_CreateClose Creating FDO Device ####################\n");
status = IoCreateDevice(DriverObject,
sizeof(FDO_DEVICE_DATA),
NULL,
goto End;
}
- DPRINT1("AddDevice: %p to %p->%p (%ws) \n",
+ DPRINT("AddDevice: %p to %p->%p (%ws) \n",
deviceObject,
deviceData->NextLowerDriver,
PhysicalDeviceObject,
NTSTATUS
NTAPI
-ACPIDispatchDeviceControl(
+ACPIDispatchCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- PIO_STACK_LOCATION IrpSp;
- NTSTATUS Status;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
- DPRINT("Called. IRP is at (0x%X)\n", Irp);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
- Irp->IoStatus.Information = 0;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ACPIDispatchDeviceControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION irpStack;
+ NTSTATUS status = STATUS_NOT_SUPPORTED;
+ PCOMMON_DEVICE_DATA commonData;
+ ULONG Caps = 0;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
- default:
- DPRINT("Unknown IOCTL 0x%X\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- }
+ PAGED_CODE ();
- if (Status != STATUS_PENDING) {
- Irp->IoStatus.Status = Status;
+ irpStack = IoGetCurrentIrpStackLocation (Irp);
+ ASSERT (IRP_MJ_DEVICE_CONTROL == irpStack->MajorFunction);
- DPRINT("Completing IRP at 0x%X\n", Irp);
+ commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- }
+ Irp->IoStatus.Information = 0;
- DPRINT("Leaving. Status 0x%X\n", Status);
+ if (!commonData->IsFDO)
+ {
+ switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_ACPI_EVAL_METHOD:
+ status = Bus_PDO_EvalMethod((PPDO_DEVICE_DATA)commonData,
+ Irp);
+ break;
+
+ case IOCTL_GET_SYS_BUTTON_CAPS:
+ if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
+ {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D"))
+ {
+ DPRINT1("Lid button reported to power manager\n");
+ Caps |= SYS_BUTTON_LID;
+ }
+ else if (((PPDO_DEVICE_DATA)commonData)->AcpiHandle == NULL)
+ {
+ /* We have to return both at the same time because since we
+ * have a NULL handle we are the fixed feature DO and we will
+ * only be called once (not once per device)
+ */
+ if (power_button)
+ {
+ DPRINT1("Fixed power button reported to power manager\n");
+ Caps |= SYS_BUTTON_POWER;
+ }
+ if (sleep_button)
+ {
+ DPRINT1("Fixed sleep button reported to power manager\n");
+ Caps |= SYS_BUTTON_SLEEP;
+ }
+ }
+ if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C"))
+ {
+ DPRINT1("Control method power button reported to power manager\n");
+ Caps |= SYS_BUTTON_POWER;
+ }
+ else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E"))
+ {
+ DPRINT1("Control method sleep reported to power manager\n");
+ Caps |= SYS_BUTTON_SLEEP;
+ }
+ else
+ {
+ DPRINT1("IOCTL_GET_SYS_BUTTON_CAPS sent to a non-button device\n");
+ status = STATUS_INVALID_PARAMETER;
+ }
+
+ if (Caps != 0)
+ {
+ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &Caps, sizeof(Caps));
+ Irp->IoStatus.Information = sizeof(Caps);
+ status = STATUS_SUCCESS;
+ }
+ break;
+
+ /* TODO: Implement other IOCTLs */
+
+ default:
+ DPRINT1("Unsupported IOCTL: %x\n", irpStack->Parameters.DeviceIoControl.IoControlCode);
+ break;
+ }
+ }
+ else
+ DPRINT1("IOCTL sent to the ACPI FDO! Kill the caller!\n");
- return Status;
+ if (status != STATUS_PENDING)
+ {
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
+
+ return status;
}
NTSTATUS
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ACPIDispatchDeviceControl;
DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP;
DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power;
+ DriverObject->MajorFunction [IRP_MJ_CREATE] = ACPIDispatchCreateClose;
+ DriverObject->MajorFunction [IRP_MJ_CLOSE] = ACPIDispatchCreateClose;
DriverObject->DriverExtension->AddDevice = Bus_AddDevice;