mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
Fixed race condition between psaux ISR and DPC.
svn path=/trunk/; revision=3686
This commit is contained in:
parent
58aee3a2d8
commit
6072415050
3 changed files with 101 additions and 92 deletions
|
@ -19,101 +19,112 @@ int mouse_replies_expected = 0;
|
||||||
BOOLEAN STDCALL
|
BOOLEAN STDCALL
|
||||||
ps2_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext)
|
ps2_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext)
|
||||||
{
|
{
|
||||||
// char tmpstr[100];
|
|
||||||
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)ServiceContext;
|
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)ServiceContext;
|
||||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
int state_dx, state_dy, state_buttons;
|
int state_dx, state_dy, state_buttons;
|
||||||
unsigned scancode;
|
unsigned scancode;
|
||||||
unsigned status = controller_read_status();
|
unsigned status = controller_read_status();
|
||||||
scancode = controller_read_input();
|
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)
|
if ((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0)
|
||||||
{
|
{
|
||||||
// mouse_handle_event(scancode); proceed to handle it
|
// mouse_handle_event(scancode); proceed to handle it
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return FALSE; // keyboard_handle_event(scancode);
|
return FALSE; // keyboard_handle_event(scancode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mouse_replies_expected > 0)
|
if (mouse_replies_expected > 0)
|
||||||
{
|
|
||||||
if (scancode == MOUSE_ACK)
|
|
||||||
{
|
{
|
||||||
mouse_replies_expected--;
|
if (scancode == MOUSE_ACK)
|
||||||
return;
|
{
|
||||||
|
mouse_replies_expected--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_replies_expected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mouse_replies_expected = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add this scancode to the mouse event queue. */
|
/* Add this scancode to the mouse event queue. */
|
||||||
|
|
||||||
mouse_buffer[mouse_buffer_position] = scancode;
|
mouse_buffer[mouse_buffer_position] = scancode;
|
||||||
mouse_buffer_position++;
|
mouse_buffer_position++;
|
||||||
|
|
||||||
// If the buffer is full, parse this event
|
/* If the buffer is full, parse this event */
|
||||||
if (mouse_buffer_position == 3)
|
if (mouse_buffer_position == 3)
|
||||||
{
|
{
|
||||||
mouse_buffer_position = 0;
|
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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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)))
|
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;
|
/* FIXME: Implement button state, see /include/ntddmous.h */
|
||||||
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
||||||
|
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)
|
Input = &DeviceExtension->MouseInputData[Queue]
|
||||||
{
|
[DeviceExtension->InputDataCount[Queue]];
|
||||||
return TRUE;
|
Input->RawButtons = state_buttons;
|
||||||
}
|
Input->ButtonData = state_buttons;
|
||||||
|
Input->LastX = state_dx;
|
||||||
DeviceExtension->MouseInputData[DeviceExtension->InputDataCount].RawButtons = state_buttons;
|
Input->LastY = state_dy;
|
||||||
DeviceExtension->MouseInputData[DeviceExtension->InputDataCount].ButtonData = state_buttons;
|
DeviceExtension->InputDataCount[Queue]++;
|
||||||
DeviceExtension->MouseInputData[DeviceExtension->InputDataCount].LastX = state_dx;
|
|
||||||
DeviceExtension->MouseInputData[DeviceExtension->InputDataCount].LastY = state_dy;
|
KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp,
|
||||||
DeviceExtension->InputDataCount++;
|
NULL);
|
||||||
|
return TRUE;
|
||||||
KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp, NULL);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,8 +211,9 @@ BOOLEAN mouse_init (PDEVICE_OBJECT DeviceObject)
|
||||||
|
|
||||||
has_mouse = TRUE;
|
has_mouse = TRUE;
|
||||||
|
|
||||||
DeviceExtension->InputDataCount = 0;
|
DeviceExtension->InputDataCount[0] = 0;
|
||||||
DeviceExtension->MouseInputData = ExAllocatePool(NonPagedPool, sizeof(MOUSE_INPUT_DATA) * MOUSE_BUFFER_SIZE);
|
DeviceExtension->InputDataCount[1] = 0;
|
||||||
|
DeviceExtension->ActiveQueue = 0;
|
||||||
|
|
||||||
// Enable the PS/2 mouse port
|
// Enable the PS/2 mouse port
|
||||||
controller_write_command_word (CONTROLLER_COMMAND_MOUSE_ENABLE);
|
controller_write_command_word (CONTROLLER_COMMAND_MOUSE_ENABLE);
|
||||||
|
|
|
@ -96,11 +96,6 @@ PS2MouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
|
||||||
VOID PS2MouseInitializeDataQueue(PVOID Context)
|
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
|
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)
|
VOID PS2MouseIsrDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
|
||||||
{
|
{
|
||||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
|
ULONG Queue;
|
||||||
|
|
||||||
|
Queue = DeviceExtension->ActiveQueue % 2;
|
||||||
|
InterlockedIncrement(&DeviceExtension->ActiveQueue);
|
||||||
(*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.CallBack)(
|
(*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.CallBack)(
|
||||||
DeviceExtension->ClassInformation.DeviceObject,
|
DeviceExtension->ClassInformation.DeviceObject,
|
||||||
DeviceExtension->MouseInputData,
|
DeviceExtension->MouseInputData[Queue],
|
||||||
NULL,
|
NULL,
|
||||||
&DeviceExtension->InputDataCount);
|
&DeviceExtension->InputDataCount[Queue]);
|
||||||
|
DeviceExtension->InputDataCount[Queue] = 0;
|
||||||
DeviceExtension->InputDataCount = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
|
@ -188,7 +185,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
|
|
||||||
DeviceExtension = DeviceObject->DeviceExtension;
|
DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
KeInitializeDpc(&DeviceExtension->IsrDpc, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject);
|
KeInitializeDpc(&DeviceExtension->IsrDpc, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject);
|
||||||
KeInitializeDpc(&DeviceExtension->IsrDpcRetry, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject);
|
|
||||||
|
|
||||||
mouse_init(DeviceObject);
|
mouse_init(DeviceObject);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
typedef struct _DEVICE_EXTENSION {
|
typedef struct _DEVICE_EXTENSION {
|
||||||
|
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
ULONG InputDataCount;
|
|
||||||
PMOUSE_INPUT_DATA MouseInputData;
|
|
||||||
CLASS_INFORMATION ClassInformation;
|
|
||||||
|
|
||||||
PKINTERRUPT MouseInterrupt;
|
ULONG ActiveQueue;
|
||||||
|
ULONG InputDataCount[2];
|
||||||
|
MOUSE_INPUT_DATA MouseInputData[2][MOUSE_BUFFER_SIZE];
|
||||||
|
|
||||||
|
CLASS_INFORMATION ClassInformation;
|
||||||
|
|
||||||
|
PKINTERRUPT MouseInterrupt;
|
||||||
KDPC IsrDpc;
|
KDPC IsrDpc;
|
||||||
KDPC IsrDpcRetry;
|
|
||||||
|
|
||||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||||
|
|
Loading…
Reference in a new issue