- Work on serial mouse detection to fix bug #198.

svn path=/trunk/; revision=8221
This commit is contained in:
Filip Navara 2004-02-17 18:01:59 +00:00
parent f3a0075137
commit 7595e479e5

View file

@ -254,21 +254,21 @@ SerialMouseStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
if (KeSynchronizeExecution(DeviceExtension->MouseInterrupt, MouseSynchronizeRoutine, Irp)) if (KeSynchronizeExecution(DeviceExtension->MouseInterrupt, MouseSynchronizeRoutine, Irp))
{ {
KIRQL oldIrql; KIRQL oldIrql;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
oldIrql = KeGetCurrentIrql(); oldIrql = KeGetCurrentIrql();
if (oldIrql < DISPATCH_LEVEL) if (oldIrql < DISPATCH_LEVEL)
{ {
KeRaiseIrql (DISPATCH_LEVEL, &oldIrql); KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
IoStartNextPacket (DeviceObject, FALSE); IoStartNextPacket(DeviceObject, FALSE);
KeLowerIrql(oldIrql); KeLowerIrql(oldIrql);
} }
else else
{ {
IoStartNextPacket (DeviceObject, FALSE); IoStartNextPacket (DeviceObject, FALSE);
} }
} }
} }
@ -377,65 +377,95 @@ VOID SerialMouseIsrDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID C
void InitializeSerialPort(ULONG Port) void InitializeSerialPort(ULONG Port)
{ {
/* DLAB off */ /* DLAB off */
WRITE_PORT_UCHAR((PUCHAR)Port + 3, 0); WRITE_PORT_UCHAR((PUCHAR)Port + 3, 0);
WRITE_PORT_UCHAR((PUCHAR)Port + 2, 0); /* FCR: disable FIFO */ WRITE_PORT_UCHAR((PUCHAR)Port + 2, 0); /* FCR: disable FIFO */
WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0); /* IER: disable ints */ WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0); /* IER: disable ints */
/* Set DLAB on */ /* Set DLAB on */
WRITE_PORT_UCHAR((PUCHAR)Port + 3, 0x80); WRITE_PORT_UCHAR((PUCHAR)Port + 3, 0x80);
/* Set serial port speed */ /* Set serial port speed */
WRITE_PORT_UCHAR((PUCHAR)Port, 0x60); WRITE_PORT_UCHAR((PUCHAR)Port, 0x60);
WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0); WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0);
/* Set DLAB off and set LCR */ /* Set DLAB off and set LCR */
WRITE_PORT_UCHAR((PUCHAR)Port + 3, 2); WRITE_PORT_UCHAR((PUCHAR)Port + 3, 2);
}
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x09); /* DR int enable */ BOOL UARTReadChar(ULONG Port, CHAR *Value, ULONG Timeout)
{
ULONG i, j;
for (i = 0; i < Timeout; i++)
{
for (j = 0; j < 1000; j++)
{
/* Is there a character ready? */
if (READ_PORT_UCHAR((PUCHAR)Port + 5) & 0x01)
{
/* Yes, read it and return */
*Value = READ_PORT_UCHAR((PUCHAR)Port);
return TRUE;
}
else
{
/* No, wait */
KeStallExecutionProcessor(1);
}
}
}
return FALSE;
} }
ULONG DetectMicrosoftMouse(ULONG Port) ULONG DetectMicrosoftMouse(ULONG Port)
{ {
CHAR Buffer[4]; CHAR Buffer[8];
ULONG i; ULONG Count, i;
UCHAR LCR, MCR; UCHAR LCR, MCR;
/* Save original LCR/MCR */ /* Save original LCR/MCR */
LCR = READ_PORT_UCHAR((PUCHAR)Port + 3); /* LCR (line ctrl reg) */ LCR = READ_PORT_UCHAR((PUCHAR)Port + 3); /* LCR (line ctrl reg) */
MCR = READ_PORT_UCHAR((PUCHAR)Port + 4); /* MCR (modem ctrl reg) */ MCR = READ_PORT_UCHAR((PUCHAR)Port + 4); /* MCR (modem ctrl reg) */
/* Reset UART */ /* Reset UART */
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0); /* MCR: DTR/RTS/OUT2 off */ WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0); /* MCR: DTR/RTS/OUT2 off */
/* Set communications parameters */ /* Set communications parameters */
InitializeSerialPort(Port); InitializeSerialPort(Port);
/* Flush receive buffer */ /* Flush receive buffer */
(void) READ_PORT_UCHAR((PUCHAR)Port); (void) READ_PORT_UCHAR((PUCHAR)Port);
KeStallExecutionProcessor(150000); /* Wait > 100 ms */ /* right? -> wait two ticks (approx 1/9 sec) */
KeStallExecutionProcessor(100000);
/* Enable DTR/RTS (OUT2 disabled) */ /* Enable DTR/RTS (OUT2 disabled) */
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 3); WRITE_PORT_UCHAR((PUCHAR)Port + 4, 3);
/* Discard serial buffer data */ if (UARTReadChar(Port, &Buffer[0], 500))
while (READ_PORT_UCHAR((PUCHAR)Port + 5) & 0x01) {
(void)READ_PORT_UCHAR((PUCHAR)Port); Count = 1;
KeStallExecutionProcessor(200000); /* Wait */ while (Count < 8)
{
/* Read the data */ if (UARTReadChar(Port, &Buffer[Count], 100))
for (i = 0; i < 4; i++) Count++;
Buffer[i] = READ_PORT_UCHAR((PUCHAR)Port); else
break;
}
}
else
return MOUSE_TYPE_NONE;
/* Restore LCR/MCR */ /* Restore LCR/MCR */
WRITE_PORT_UCHAR((PUCHAR)Port + 3, LCR); /* LCR (line ctrl reg) */ WRITE_PORT_UCHAR((PUCHAR)Port + 3, LCR); /* LCR (line ctrl reg) */
WRITE_PORT_UCHAR((PUCHAR)Port + 4, MCR); /* MCR (modem ctrl reg) */ WRITE_PORT_UCHAR((PUCHAR)Port + 4, MCR); /* MCR (modem ctrl reg) */
for (i = 0; i < 4; ++i) for (i = 0; i < Count; ++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");
return MOUSE_TYPE_NONE; return MOUSE_TYPE_NONE;
} else } else
/* Sign for Microsoft Mouse protocol followed by button specifier */ /* Sign for Microsoft Mouse protocol followed by button specifier */
if (Buffer[i] == 'M') if (Buffer[i] == 'M')
@ -462,7 +492,6 @@ ULONG DetectMicrosoftMouse(ULONG Port)
} }
return MOUSE_TYPE_NONE; return MOUSE_TYPE_NONE;
} }
PDEVICE_OBJECT PDEVICE_OBJECT
@ -545,8 +574,6 @@ InitializeMouse(ULONG Port, ULONG Irq, PDRIVER_OBJECT DriverObject)
/* 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;
} }
@ -555,7 +582,7 @@ InitializeMouse(ULONG Port, ULONG Irq, PDRIVER_OBJECT DriverObject)
ClearMouse(Port); ClearMouse(Port);
/* Enable RTS, DTR and OUT2 */ /* Enable RTS, DTR and OUT2 */
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x0b); WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x0b);
/* Allocate new device */ /* Allocate new device */
@ -625,9 +652,9 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
DriverObject->MajorFunction[IRP_MJ_CREATE] = SerialMouseDispatch; DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)SerialMouseDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = SerialMouseDispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)SerialMouseDispatch;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = SerialMouseInternalDeviceControl; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = (PDRIVER_DISPATCH)SerialMouseInternalDeviceControl;
DriverObject->DriverStartIo = SerialMouseStartIo; DriverObject->DriverStartIo = SerialMouseStartIo;
return STATUS_SUCCESS; return STATUS_SUCCESS;