Another rewrite of the mouse detection code by Logan_V8_TT with minor changes by me to get it really working with my mouse. This version should solve the problem where the mouse wasn't moving and also the conflicts with serial port debugging.

svn path=/trunk/; revision=7806
This commit is contained in:
Filip Navara 2004-01-21 15:25:01 +00:00
parent 5844d90709
commit cad98f04c0

View file

@ -106,9 +106,9 @@ void ClearMouse(ULONG Port)
unsigned int Restarts = 0, i; unsigned int Restarts = 0, i;
for (i = 0; i < 60000; i++) for (i = 0; i < 60000; i++)
{ {
unsigned Temp = READ_PORT_UCHAR((PUCHAR)Port); unsigned Temp = READ_PORT_UCHAR((PUCHAR)Port);
if (Temp != 0) if (Temp != 0)
{ {
Restarts++; Restarts++;
if (Restarts < 300000) if (Restarts < 300000)
i = 0; i = 0;
@ -170,8 +170,8 @@ SerialMouseInterruptService(IN PKINTERRUPT Interrupt, PVOID ServiceContext)
if (DeviceExtension->PacketBufferPosition == 3) if (DeviceExtension->PacketBufferPosition == 3)
{ {
/* Retrieve change in x and y from packet */ /* Retrieve change in x and y from packet */
Input->LastX = (signed char)(PacketBuffer[1] | ((PacketBuffer[0] & 0x03) << 6)); Input->LastX = (signed char)(PacketBuffer[1] | ((PacketBuffer[0] & 0x03) << 6));
Input->LastY = (signed char)(PacketBuffer[2] | ((PacketBuffer[0] & 0x0c) << 4)); Input->LastY = (signed char)(PacketBuffer[2] | ((PacketBuffer[0] & 0x0c) << 4));
/* Determine the current state of the buttons */ /* Determine the current state of the buttons */
Input->RawButtons = (DeviceExtension->PreviousButtons & MOUSE_BUTTON_MIDDLE) | Input->RawButtons = (DeviceExtension->PreviousButtons & MOUSE_BUTTON_MIDDLE) |
@ -300,8 +300,8 @@ SerialMouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
*(PMOUSE_ATTRIBUTES)Irp->AssociatedIrp.SystemBuffer = *(PMOUSE_ATTRIBUTES)Irp->AssociatedIrp.SystemBuffer =
DeviceExtension->AttributesInformation; DeviceExtension->AttributesInformation;
Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES); Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES);
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} else { } else {
Status = STATUS_BUFFER_TOO_SMALL; Status = STATUS_BUFFER_TOO_SMALL;
} }
break; break;
@ -354,86 +354,92 @@ SerialMouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
} }
return Status; return Status;
} }
VOID SerialMouseIsrDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) VOID SerialMouseIsrDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{ {
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
ULONG Queue; ULONG Queue;
Queue = DeviceExtension->ActiveQueue % 2; Queue = DeviceExtension->ActiveQueue % 2;
InterlockedIncrement(&DeviceExtension->ActiveQueue); InterlockedIncrement(&DeviceExtension->ActiveQueue);
(*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.CallBack)( (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.CallBack)(
DeviceExtension->ClassInformation.DeviceObject, DeviceExtension->ClassInformation.DeviceObject,
DeviceExtension->MouseInputData[Queue], DeviceExtension->MouseInputData[Queue],
NULL, NULL,
&DeviceExtension->InputDataCount[Queue]); &DeviceExtension->InputDataCount[Queue]);
DeviceExtension->InputDataCount[Queue] = 0; DeviceExtension->InputDataCount[Queue] = 0;
} }
void InitializeSerialPort(ULONG Port, unsigned int LineControl) void InitializeSerialPort(ULONG Port)
{ {
WRITE_PORT_UCHAR((PUCHAR)Port + 3, 0x80); /* set DLAB on */ ULONG LineControl;
WRITE_PORT_UCHAR((PUCHAR)Port, 0x60); /* speed LO byte */
WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0); /* speed HI byte */ /* Read old value from line control register */
WRITE_PORT_UCHAR((PUCHAR)Port + 3, LineControl); LineControl = READ_PORT_UCHAR((PUCHAR)Port + 3);
WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0); /* set comm and DLAB to 0 */ /* NOT SURE WHAT IS THIS SUPPOSED TO DO! */
WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0);
WRITE_PORT_UCHAR((PUCHAR)Port + 2, 0);
/* Set DLAB on */
WRITE_PORT_UCHAR((PUCHAR)Port + 3, 0x80);
/* Set serial port speed */
WRITE_PORT_UCHAR((PUCHAR)Port, 0x60);
WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0);
/* Set DLAB off and restore the old value of line control reg. */
WRITE_PORT_UCHAR((PUCHAR)Port + 3, LineControl & ~0x80);
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x09); /* DR int enable */ WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x09); /* DR int enable */
(void) READ_PORT_UCHAR((PUCHAR)Port + 5); /* clear error bits */ (void) READ_PORT_UCHAR((PUCHAR)Port + 5); /* clear error bits */
KeStallExecutionProcessor(150000); /* Wait > 100 ms */
} }
ULONG DetectMicrosoftMouse(ULONG Port) ULONG DetectMicrosoftMouse(ULONG Port)
{ {
/*
* Detection method number two. CuteMouse (GPL DOS Mouse driver
* cutemouse.sourceforge.net) assembler port to C by Logan_V8_TT
*/
CHAR Buffer[4]; CHAR Buffer[4];
ULONG i; ULONG i;
ULONG TimeOut = 250; UCHAR LCR, MCR;
UCHAR LineControl;
/* Save original control */
LineControl = READ_PORT_UCHAR((PUCHAR)Port + 4);
/* Inactivate RTS and set DTR */ /* Save original LCR/MCR */
WRITE_PORT_UCHAR((PUCHAR)Port + 4, (LineControl & ~0x02) | 0x01); LCR = READ_PORT_UCHAR((PUCHAR)Port + 3); /* LCR (line ctrl reg) */
KeStallExecutionProcessor(150000); /* Wait > 100 ms */ MCR = READ_PORT_UCHAR((PUCHAR)Port + 4); /* MCR (modem ctrl reg) */
/* Clear buffer */ /* Reset UART */
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0); /* MCR: DTR/RTS/OUT2 off */
WRITE_PORT_UCHAR((PUCHAR)Port + 2, 0); /* FCR: disable FIFO */
KeStallExecutionProcessor(150000); /* Wait > 100 ms */
/* Set communications parameters */
InitializeSerialPort(Port);
/* Enable DTR/RTS (OUT2 disabled) */
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 3);
/* Discard serial buffer data */
while (READ_PORT_UCHAR((PUCHAR)Port + 5) & 0x01) while (READ_PORT_UCHAR((PUCHAR)Port + 5) & 0x01)
(void)READ_PORT_UCHAR((PUCHAR)Port); (void)READ_PORT_UCHAR((PUCHAR)Port);
KeStallExecutionProcessor(100000); /* Wait */
/* /* Read the data */
* Send modem control with 'Data Terminal Ready' and 'Request To Send'
* message. This enables mouse to identify.
*/
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x03);
/* Wait 10 milliseconds for the mouse getting ready */
KeStallExecutionProcessor(10000);
/* Read first four bytes, which contains Microsoft Mouse signs */
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{
while (((READ_PORT_UCHAR((PUCHAR)Port + 5) & 1) == 0) && (TimeOut > 0))
{
KeStallExecutionProcessor(1000);
--TimeOut;
if (TimeOut == 0)
return MOUSE_TYPE_NONE;
}
Buffer[i] = READ_PORT_UCHAR((PUCHAR)Port); Buffer[i] = READ_PORT_UCHAR((PUCHAR)Port);
}
/* Restore control */ /* Restore LCR/MCR */
WRITE_PORT_UCHAR((PUCHAR)Port + 4, LineControl); WRITE_PORT_UCHAR((PUCHAR)Port + 3, LCR); /* LCR (line ctrl reg) */
WRITE_PORT_UCHAR((PUCHAR)Port + 4, MCR); /* MCR (modem ctrl reg) */
/* Check that four bytes for signs */
for (i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
{ {
/* Sign for Microsoft Ballpoint */ /* Sign for Microsoft Ballpoint */
if (Buffer[i] == 'B') if (Buffer[i] == 'B')
{ {
DbgPrint("Microsoft Ballpoint device detected"); DbgPrint("Microsoft Ballpoint device detected");
DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET"); DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET");
@ -464,6 +470,7 @@ ULONG DetectMicrosoftMouse(ULONG Port)
} }
return MOUSE_TYPE_NONE; return MOUSE_TYPE_NONE;
} }
PDEVICE_OBJECT PDEVICE_OBJECT
@ -541,16 +548,23 @@ InitializeMouse(ULONG Port, ULONG Irq, PDRIVER_OBJECT DriverObject)
ULONG MouseType; ULONG MouseType;
/* Try to detect mouse on specified port */ /* Try to detect mouse on specified port */
InitializeSerialPort(Port, 2);
MouseType = DetectMicrosoftMouse(Port); MouseType = DetectMicrosoftMouse(Port);
/* Enable interrupts */
WRITE_PORT_UCHAR((PUCHAR)(Port) + 1, 1);
ClearMouse(Port);
/* No mouse, no need to continue */ /* No mouse, no need to continue */
if (MouseType == MOUSE_TYPE_NONE) if (MouseType == MOUSE_TYPE_NONE)
{
WRITE_PORT_UCHAR((PUCHAR)(Port) + 1, 1);
InitializeSerialPort(Port);
return FALSE; return FALSE;
}
/* Enable interrupts */
WRITE_PORT_UCHAR((PUCHAR)(Port) + 1, 1);
ClearMouse(Port);
/* Enable RTS, DTR and OUT2 */
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x0b);
/* Allocate new device */ /* Allocate new device */
DeviceObject = AllocatePointerDevice(DriverObject); DeviceObject = AllocatePointerDevice(DriverObject);
@ -559,6 +573,7 @@ InitializeMouse(ULONG Port, ULONG Irq, PDRIVER_OBJECT DriverObject)
DbgPrint("Oops, couldn't creat device object.\n"); DbgPrint("Oops, couldn't creat device object.\n");
return FALSE; return FALSE;
} }
DeviceExtension = DeviceObject->DeviceExtension; DeviceExtension = DeviceObject->DeviceExtension;
/* Setup device extension structure */ /* Setup device extension structure */