moucmn.c revision 2084a447d1acb619df7c393fac41b79d517e4b3d
/*++
Copyright (c) 1990, 1991, 1992, 1993 Microsoft Corporation
Module Name:
Abstract:
The common portions of the Intel i8042 port driver which
apply to the auxiliary (PS/2 mouse) device.
Environment:
Kernel mode only.
Notes:
NOTES: (Future/outstanding issues)
- Powerfail not implemented.
- Consolidate duplicate code, where possible and appropriate.
Revision History:
--*/
#include "stdarg.h"
#include "stdio.h"
#include "string.h"
#include "ntddk.h"
#include "i8042prt.h"
)
/*++
Routine Description:
This routine runs at DISPATCH_LEVEL IRQL to finish processing
mouse interrupts. It is queued in the mouse ISR. The real
work is done via a callback to the connected mouse class driver.
Arguments:
Dpc - Pointer to the DPC object.
DeviceObject - Pointer to the device object.
Irp - Pointer to the Irp.
Context - Not used.
Return Value:
None.
--*/
{
ULONG dataNotConsumed = 0;
ULONG inputDataConsumed = 0;
//
// Use DpcInterlockMouse to determine whether the DPC is running
// concurrently on another processor. We only want one instantiation
// of the DPC to actually do any work. DpcInterlockMouse is -1
// when no DPC is executing. We increment it, and if the result is
// zero then the current instantiation is the only one executing, and it
// is okay to proceed. Otherwise, we just return.
//
//
);
while (moreDpcProcessing) {
dataNotConsumed = 0;
inputDataConsumed = 0;
//
// Get the port InputData queue pointers synchronously.
//
);
if (getPointerContext.InputCount != 0) {
//
// Call the connected class driver's callback ISR with the
// port InputData queue pointers. If we have to wrap the queue,
// break the operation into two pieces, and call the class callback
// ISR once for each piece.
//
//
// We'll have to wrap the InputData circular buffer. Call
// the class callback ISR with the chunk of data starting at
// DataOut and ending at the end of the queue.
//
I8xPrint((
2,
"I8042PRT-I8042MouseIsrDpc: calling class callback\n"
));
I8xPrint((
2,
"I8042PRT-I8042MouseIsrDpc: with Start 0x%x and End 0x%x\n",
));
);
dataNotConsumed = (((PUCHAR)
/ sizeof(MOUSE_INPUT_DATA)) - inputDataConsumed;
I8xPrint((
2,
"I8042PRT-I8042MouseIsrDpc: (Wrap) Call callback consumed %d items, left %d\n",
));
if (dataNotConsumed) {
(inputDataConsumed * sizeof(MOUSE_INPUT_DATA));
} else {
}
}
//
// Call the class callback ISR with data remaining in the queue.
//
if ((dataNotConsumed == 0) &&
I8xPrint((
2,
"I8042PRT-I8042MouseIsrDpc: calling class callback\n"
));
I8xPrint((
2,
"I8042PRT-I8042MouseIsrDpc: with Start 0x%x and End 0x%x\n",
));
);
/ sizeof(MOUSE_INPUT_DATA)) - inputDataConsumed;
I8xPrint((
2,
"I8042PRT-I8042MouseIsrDpc: Call callback consumed %d items, left %d\n",
));
(inputDataConsumed * sizeof(MOUSE_INPUT_DATA));
}
//
// Update the port InputData queue DataOut pointer and InputCount
// synchronously.
//
);
}
if (dataNotConsumed) {
//
// The class driver was unable to consume all the data.
// Reset the interlocked variable to -1. We do not want
// to attempt to move more data to the class driver at this
// point, because it is already overloaded. Need to wait a
// while to give the Raw Input Thread a chance to read some
// of the data out of the class driver's queue. We accomplish
// this "wait" via a timer.
//
interlockedResult = -1;
);
(VOID) KeSetTimer(
);
} else {
//
// Decrement DpcInterlockMouse. If the result goes negative,
// then we're all finished processing the DPC. Otherwise, either
// the ISR incremented DpcInterlockMouse because it has more
// work for the ISR DPC to do, or a concurrent DPC executed on
// some processor while the current DPC was running (the
// concurrent DPC wouldn't have done any work). Make sure that
// the current DPC handles any extra work that is ready to be
// done.
//
);
if (interlockedResult != -1) {
//
// The interlocked variable is still greater than or equal to
// zero. Reset it to zero, so that we execute the loop one
// more time (assuming no more DPCs execute and bump the
// variable up again).
//
interlockedResult = 0;
);
} else {
}
}
}
}
)
/*++
Routine Description:
This routine adds input data from the mouse to the InputData queue.
Arguments:
MouseExtension - Pointer to the mouse portion of the device extension.
InputData - Pointer to the data to add to the InputData queue.
Return Value:
Returns TRUE if the data was added, otherwise FALSE.
--*/
{
I8xPrint((
3,
"I8042PRT-I8xWriteDataToMouseQueue: DataIn 0x%x, DataOut 0x%x\n",
));
I8xPrint((
3,
"I8042PRT-I8xWriteDataToMouseQueue: InputCount %d\n",
));
//
// Check for full input data queue.
//
(MouseExtension->InputCount != 0)) {
//
// The input data queue is full. Intentionally ignore
// the new data.
//
return(FALSE);
} else {
MouseExtension->DataIn++;
I8xPrint((
2,
"I8042PRT-I8xWriteDataToMouseQueue: new InputCount %d\n",
));
}
}
return(TRUE);
}