From: Cameron Gutman Date: Fri, 26 Mar 2010 02:33:28 +0000 (+0000) Subject: [ACPI] X-Git-Tag: backups/header-work@57446~84^2~2 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=937d6233d7e6f7dd1d27bc05a5bbdf1804114907 [ACPI] - Implement IOCTL_GET_SYS_BUTTON_EVENT - Add the device event to the event list in a DPC instead of an ISR svn path=/trunk/; revision=46457 --- diff --git a/reactos/drivers/bus/acpi/busmgr/bus.c b/reactos/drivers/bus/acpi/busmgr/bus.c index 6309f20cfdb..ae04c2cb31b 100644 --- a/reactos/drivers/bus/acpi/busmgr/bus.c +++ b/reactos/drivers/bus/acpi/busmgr/bus.c @@ -58,6 +58,7 @@ KSPIN_LOCK acpi_bus_event_lock; LIST_HEAD(acpi_bus_event_list); //DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); KEVENT AcpiEventQueue; +KDPC event_dpc; static int @@ -455,6 +456,21 @@ acpi_bus_get_perf_flags ( Event Management -------------------------------------------------------------------------- */ +void +acpi_bus_generate_event_dpc(PKDPC Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2) +{ + struct acpi_bus_event *event = SystemArgument1; + KIRQL OldIrql; + + KeAcquireSpinLock(&acpi_bus_event_lock, &OldIrql); + list_add_tail(&event->node, &acpi_bus_event_list); + KeReleaseSpinLock(&acpi_bus_event_lock, OldIrql); + + KeSetEvent(&AcpiEventQueue, IO_NO_INCREMENT, FALSE); +} int acpi_bus_generate_event ( @@ -463,10 +479,8 @@ acpi_bus_generate_event ( int data) { struct acpi_bus_event *event = NULL; - //unsigned long flags = 0; - KIRQL OldIrql; - DPRINT1("acpi_bus_generate_event"); + DPRINT("acpi_bus_generate_event"); if (!device) return_VALUE(AE_BAD_PARAMETER); @@ -484,14 +498,8 @@ acpi_bus_generate_event ( event->type = type; event->data = data; - //spin_lock_irqsave(&acpi_bus_event_lock, flags); - KeAcquireSpinLock(&acpi_bus_event_lock, &OldIrql); - list_add_tail(&event->node, &acpi_bus_event_list); - KeReleaseSpinLock(&acpi_bus_event_lock, OldIrql); - //spin_unlock_irqrestore(&acpi_bus_event_lock, flags); - - KeSetEvent(&AcpiEventQueue, IO_NO_INCREMENT, FALSE); - //wake_up_interruptible(&acpi_bus_event_queue); + if (!KeInsertQueueDpc(&event_dpc, event, NULL)) + ExFreePool(event); return_VALUE(0); } @@ -506,7 +514,7 @@ acpi_bus_receive_event ( //DECLARE_WAITQUEUE(wait, current); - DPRINT1("acpi_bus_receive_event"); + DPRINT("acpi_bus_receive_event"); if (!event) return AE_BAD_PARAMETER; @@ -1153,9 +1161,11 @@ acpi_bus_add ( case ACPI_BUS_TYPE_SYSTEM: sprintf(device->pnp.bus_id, "%s", "ACPI"); break; + case ACPI_BUS_TYPE_POWER_BUTTONF: case ACPI_BUS_TYPE_POWER_BUTTON: sprintf(device->pnp.bus_id, "%s", "PWRF"); break; + case ACPI_BUS_TYPE_SLEEP_BUTTONF: case ACPI_BUS_TYPE_SLEEP_BUTTON: sprintf(device->pnp.bus_id, "%s", "SLPF"); break; @@ -1589,6 +1599,8 @@ acpi_bus_init (void) DPRINT("acpi_bus_init"); + KeInitializeDpc(&event_dpc, acpi_bus_generate_event_dpc, NULL); + status = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION); if (ACPI_FAILURE(status)) { DPRINT1("Unable to start the ACPI Interpreter\n"); diff --git a/reactos/drivers/bus/acpi/main.c b/reactos/drivers/bus/acpi/main.c index 4cbdfda4468..bc1d78da7c5 100644 --- a/reactos/drivers/bus/acpi/main.c +++ b/reactos/drivers/bus/acpi/main.c @@ -182,6 +182,40 @@ ACPIDispatchCreateClose( return STATUS_SUCCESS; } +VOID +NTAPI +ButtonWaitThread(PVOID Context) +{ + PIRP Irp = Context; + int result; + struct acpi_bus_event event; + ULONG ButtonEvent; + + while (ACPI_SUCCESS(result = acpi_bus_receive_event(&event)) && + event.type != ACPI_BUTTON_NOTIFY_STATUS); + + if (!ACPI_SUCCESS(result)) + { + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + } + else + { + if (strstr(event.bus_id, "PWRF")) + ButtonEvent = SYS_BUTTON_POWER; + else if (strstr(event.bus_id, "SLPF")) + ButtonEvent = SYS_BUTTON_SLEEP; + else + ButtonEvent = 0; + + RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &ButtonEvent, sizeof(ButtonEvent)); + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof(ULONG); + } + + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} + + NTSTATUS NTAPI ACPIDispatchDeviceControl( @@ -192,6 +226,7 @@ ACPIDispatchDeviceControl( NTSTATUS status = STATUS_NOT_SUPPORTED; PCOMMON_DEVICE_DATA commonData; ULONG Caps = 0; + HANDLE ThreadHandle; PAGED_CODE (); @@ -264,7 +299,12 @@ ACPIDispatchDeviceControl( } break; - /* TODO: Implement other IOCTLs */ + case IOCTL_GET_SYS_BUTTON_EVENT: + PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, 0, 0, 0, ButtonWaitThread, Irp); + ZwClose(ThreadHandle); + + status = STATUS_PENDING; + break; default: DPRINT1("Unsupported IOCTL: %x\n", irpStack->Parameters.DeviceIoControl.IoControlCode); @@ -279,6 +319,8 @@ ACPIDispatchDeviceControl( Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); } + else + IoMarkIrpPending(Irp); return status; }