From 60724150504131364d7eb660c01b9cba461f1280 Mon Sep 17 00:00:00 2001 From: David Welch Date: Thu, 31 Oct 2002 23:48:06 +0000 Subject: [PATCH] Fixed race condition between psaux ISR and DPC. svn path=/trunk/; revision=3686 --- reactos/drivers/input/psaux/mouse.c | 162 +++++++++++++++------------- reactos/drivers/input/psaux/psaux.c | 16 ++- reactos/drivers/input/psaux/psaux.h | 15 +-- 3 files changed, 101 insertions(+), 92 deletions(-) diff --git a/reactos/drivers/input/psaux/mouse.c b/reactos/drivers/input/psaux/mouse.c index 47c06ba5852..6a6fec0029f 100644 --- a/reactos/drivers/input/psaux/mouse.c +++ b/reactos/drivers/input/psaux/mouse.c @@ -19,101 +19,112 @@ int mouse_replies_expected = 0; BOOLEAN STDCALL ps2_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext) { - // char tmpstr[100]; PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)ServiceContext; PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; - int state_dx, state_dy, state_buttons; unsigned scancode; unsigned status = controller_read_status(); scancode = controller_read_input(); - // Don't handle the mouse event if we aren't connected to the mouse class driver - if(DeviceExtension->ClassInformation.CallBack == NULL) return FALSE; + /* + * Don't handle the mouse event if we aren't connected to the mouse class + * driver + */ + if (DeviceExtension->ClassInformation.CallBack == NULL) + { + return FALSE; + } - if((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0) - { - // mouse_handle_event(scancode); proceed to handle it - } + if ((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0) + { + // mouse_handle_event(scancode); proceed to handle it + } else - { - return FALSE; // keyboard_handle_event(scancode); - } + { + return FALSE; // keyboard_handle_event(scancode); + } if (mouse_replies_expected > 0) - { - if (scancode == MOUSE_ACK) { - mouse_replies_expected--; - return; + if (scancode == MOUSE_ACK) + { + mouse_replies_expected--; + return; + } + + mouse_replies_expected = 0; } - - mouse_replies_expected = 0; - } /* Add this scancode to the mouse event queue. */ - mouse_buffer[mouse_buffer_position] = scancode; mouse_buffer_position++; - - // If the buffer is full, parse this event + + /* If the buffer is full, parse this event */ if (mouse_buffer_position == 3) - { - mouse_buffer_position = 0; - // system_call_debug_print_simple ("We got a mouse event"); - - state_buttons = (mouse_buffer[0] & 1) * GPM_B_LEFT + - (mouse_buffer[0] & 2) * GPM_B_RIGHT + - (mouse_buffer[0] & 4) * GPM_B_MIDDLE; - - /* Some PS/2 mice send reports with negative bit set in data[0] and zero for movement. I think this is a - bug in the mouse, but working around it only causes artifacts when the actual report is -256; they'll - be treated as zero. This should be rare if the mouse sampling rate is set to a reasonable value; the - default of 100 Hz is plenty. (Stephen Tell) */ - - if (mouse_buffer[1] == 0) - { - state_dx = 0; - } - else - { - state_dx = (mouse_buffer[0] & 0x10) ? - mouse_buffer[1] - 256 : - mouse_buffer[1]; - } - - if (mouse_buffer[2] == 0) - { - state_dy = 0; - } - else - { - state_dy = -((mouse_buffer[0] & 0x20) ? - mouse_buffer[2] - 256 : - mouse_buffer[2]); - } + { + mouse_buffer_position = 0; + state_buttons = (mouse_buffer[0] & 1) * GPM_B_LEFT + + (mouse_buffer[0] & 2) * GPM_B_RIGHT + + (mouse_buffer[0] & 4) * GPM_B_MIDDLE; + + /* + * Some PS/2 mice send reports with negative bit set in data[0] and zero + * for movement. I think this is a bug in the mouse, but working around + * it only causes artifacts when the actual report is -256; they'll + * be treated as zero. This should be rare if the mouse sampling rate is + * set to a reasonable value; the default of 100 Hz is plenty. + * (Stephen Tell) + */ + if (mouse_buffer[1] == 0) + { + state_dx = 0; + } + else + { + state_dx = (mouse_buffer[0] & 0x10) ? + mouse_buffer[1] - 256 : + mouse_buffer[1]; + } + + if (mouse_buffer[2] == 0) + { + state_dy = 0; + } + else + { + state_dy = -((mouse_buffer[0] & 0x20) ? + mouse_buffer[2] - 256 : + mouse_buffer[2]); + } + if (((state_dx!=0) || (state_dy!=0) || (state_buttons!=0))) - { - // FIXME: Implement button state, see /include/ntddmous.h + { + ULONG Queue; + PMOUSE_INPUT_DATA Input; - DeviceObject = (PDEVICE_OBJECT)ServiceContext; - DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + /* FIXME: Implement button state, see /include/ntddmous.h */ + + DeviceObject = (PDEVICE_OBJECT)ServiceContext; + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + Queue = DeviceExtension->ActiveQueue % 2; + + if (DeviceExtension->InputDataCount[Queue] == MOUSE_BUFFER_SIZE) + { + return TRUE; + } - if (DeviceExtension->InputDataCount == MOUSE_BUFFER_SIZE) - { - return TRUE; - } - - DeviceExtension->MouseInputData[DeviceExtension->InputDataCount].RawButtons = state_buttons; - DeviceExtension->MouseInputData[DeviceExtension->InputDataCount].ButtonData = state_buttons; - DeviceExtension->MouseInputData[DeviceExtension->InputDataCount].LastX = state_dx; - DeviceExtension->MouseInputData[DeviceExtension->InputDataCount].LastY = state_dy; - DeviceExtension->InputDataCount++; - - KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp, NULL); - - return TRUE; + Input = &DeviceExtension->MouseInputData[Queue] + [DeviceExtension->InputDataCount[Queue]]; + Input->RawButtons = state_buttons; + Input->ButtonData = state_buttons; + Input->LastX = state_dx; + Input->LastY = state_dy; + DeviceExtension->InputDataCount[Queue]++; + + KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp, + NULL); + return TRUE; } } } @@ -200,8 +211,9 @@ BOOLEAN mouse_init (PDEVICE_OBJECT DeviceObject) has_mouse = TRUE; - DeviceExtension->InputDataCount = 0; - DeviceExtension->MouseInputData = ExAllocatePool(NonPagedPool, sizeof(MOUSE_INPUT_DATA) * MOUSE_BUFFER_SIZE); + DeviceExtension->InputDataCount[0] = 0; + DeviceExtension->InputDataCount[1] = 0; + DeviceExtension->ActiveQueue = 0; // Enable the PS/2 mouse port controller_write_command_word (CONTROLLER_COMMAND_MOUSE_ENABLE); diff --git a/reactos/drivers/input/psaux/psaux.c b/reactos/drivers/input/psaux/psaux.c index e8bd4b035fe..a3e7cfc148c 100644 --- a/reactos/drivers/input/psaux/psaux.c +++ b/reactos/drivers/input/psaux/psaux.c @@ -96,11 +96,6 @@ PS2MouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) VOID PS2MouseInitializeDataQueue(PVOID Context) { - ; -/* PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceExtension; - - DeviceExtension->InputDataCount = 0; - DeviceExtension->MouseInputData = ExAllocatePool(NonPagedPool, sizeof(MOUSE_INPUT_DATA) * MOUSE_BUFFER_SIZE); */ } NTSTATUS STDCALL @@ -143,14 +138,16 @@ PS2MouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) VOID PS2MouseIsrDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + ULONG Queue; + Queue = DeviceExtension->ActiveQueue % 2; + InterlockedIncrement(&DeviceExtension->ActiveQueue); (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.CallBack)( DeviceExtension->ClassInformation.DeviceObject, - DeviceExtension->MouseInputData, + DeviceExtension->MouseInputData[Queue], NULL, - &DeviceExtension->InputDataCount); - - DeviceExtension->InputDataCount = 0; + &DeviceExtension->InputDataCount[Queue]); + DeviceExtension->InputDataCount[Queue] = 0; } NTSTATUS STDCALL @@ -188,7 +185,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) DeviceExtension = DeviceObject->DeviceExtension; KeInitializeDpc(&DeviceExtension->IsrDpc, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject); - KeInitializeDpc(&DeviceExtension->IsrDpcRetry, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject); mouse_init(DeviceObject); diff --git a/reactos/drivers/input/psaux/psaux.h b/reactos/drivers/input/psaux/psaux.h index 0dfb62057bf..22eb2b2a11e 100644 --- a/reactos/drivers/input/psaux/psaux.h +++ b/reactos/drivers/input/psaux/psaux.h @@ -1,12 +1,13 @@ typedef struct _DEVICE_EXTENSION { - PDEVICE_OBJECT DeviceObject; - ULONG InputDataCount; - PMOUSE_INPUT_DATA MouseInputData; - CLASS_INFORMATION ClassInformation; + PDEVICE_OBJECT DeviceObject; - PKINTERRUPT MouseInterrupt; + ULONG ActiveQueue; + ULONG InputDataCount[2]; + MOUSE_INPUT_DATA MouseInputData[2][MOUSE_BUFFER_SIZE]; + + CLASS_INFORMATION ClassInformation; + + PKINTERRUPT MouseInterrupt; KDPC IsrDpc; - KDPC IsrDpcRetry; - } DEVICE_EXTENSION, *PDEVICE_EXTENSION;