[ACPI]
authorCameron Gutman <aicommander@gmail.com>
Fri, 26 Mar 2010 02:33:28 +0000 (02:33 +0000)
committerCameron Gutman <aicommander@gmail.com>
Fri, 26 Mar 2010 02:33:28 +0000 (02:33 +0000)
- 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

reactos/drivers/bus/acpi/busmgr/bus.c
reactos/drivers/bus/acpi/main.c

index 6309f20..ae04c2c 100644 (file)
@@ -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");
index 4cbdfda..bc1d78d 100644 (file)
@@ -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;
 }