- 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
This commit is contained in:
Cameron Gutman 2010-03-26 02:33:28 +00:00
parent deac9bacde
commit 937d6233d7
2 changed files with 67 additions and 13 deletions

View 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");

View 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;
}