From a21a8b132494deaf0113a9b715245ba72d48b820 Mon Sep 17 00:00:00 2001 From: Marcus Overhagen Date: Sat, 22 Oct 2005 23:51:43 +0000 Subject: [PATCH] Changed the way how the mouse interrupt handler works. It will now first assemble a complete packet, and then write it into the ring buffer. This way, the last packet can easily be dropped when the ring buffer is full, and we no longer need to flush an old packet from the queue (which could lead to strange effects when handling the remaining packets in the queue). Also fixed the bug that the semaphore was released despite nothing was written to the ring buffer when it was full. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14475 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/drivers/input/ps2_hid/common.c | 2 +- .../kernel/drivers/input/ps2_hid/common.h | 2 +- .../kernel/drivers/input/ps2_hid/mouse.c | 51 +++++++++++-------- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/add-ons/kernel/drivers/input/ps2_hid/common.c b/src/add-ons/kernel/drivers/input/ps2_hid/common.c index 8966d9209b..49a737be60 100644 --- a/src/add-ons/kernel/drivers/input/ps2_hid/common.c +++ b/src/add-ons/kernel/drivers/input/ps2_hid/common.c @@ -342,7 +342,7 @@ init_driver(void) // Probing the mouse first and initializing the keyboard later appearantly // clears the keyboard stall. - if (probe_mouse() == B_OK) + if (probe_mouse(NULL) == B_OK) sMouseDetected = true; else dprintf("ps2_hid: no mouse detected!\n"); diff --git a/src/add-ons/kernel/drivers/input/ps2_hid/common.h b/src/add-ons/kernel/drivers/input/ps2_hid/common.h index 8ee6c663c0..ba873c904a 100644 --- a/src/add-ons/kernel/drivers/input/ps2_hid/common.h +++ b/src/add-ons/kernel/drivers/input/ps2_hid/common.h @@ -50,7 +50,7 @@ extern status_t ps2_common_initialize(void); // prototypes from keyboard.c & mouse.c extern status_t probe_keyboard(void); -extern status_t probe_mouse(void); +extern status_t probe_mouse(size_t *probed_packet_size); extern status_t keyboard_open(const char *name, uint32 flags, void **cookie); extern status_t keyboard_close(void *cookie); diff --git a/src/add-ons/kernel/drivers/input/ps2_hid/mouse.c b/src/add-ons/kernel/drivers/input/ps2_hid/mouse.c index b7bcb9b128..db0699200c 100644 --- a/src/add-ons/kernel/drivers/input/ps2_hid/mouse.c +++ b/src/add-ons/kernel/drivers/input/ps2_hid/mouse.c @@ -70,7 +70,6 @@ // we record that many mouse packets before we start to drop them static sem_id sMouseSem; -static int32 sSync; static struct packet_buffer *sMouseBuffer; static int32 sOpenMask; @@ -79,8 +78,10 @@ static bigtime_t sClickSpeed; static int32 sClickCount; static int sButtonsState; -static int32 sPacketSize; - +static size_t sPacketSize; +static size_t sPacketIndex; +static uint8 sPacketBuffer[PS2_MAX_PACKET_SIZE]; + /** Writes a byte to the mouse device. Uses the control port to indicate * that the byte is sent to the auxiliary device (mouse), instead of the @@ -206,7 +207,7 @@ ps2_mouse_read(mouse_movement *userMovement) if (status < B_OK) return status; - if (packet_buffer_read(sMouseBuffer, packet, sPacketSize) != (ssize_t)sPacketSize) { + if (packet_buffer_read(sMouseBuffer, packet, sPacketSize) != sPacketSize) { TRACE(("error copying buffer\n")); return B_ERROR; } @@ -258,27 +259,31 @@ handle_mouse_interrupt(void* cookie) } data = gIsa->read_io_8(PS2_PORT_DATA); - TRACE(("mouse interrupt : byte %x\n", data)); + TRACE(("mouse interrupt: %d byte: 0x%02x\n", sPacketIndex, data)); - if (sSync == 0 && !(data & 8)) { - TRACE(("mouse resynched, bad data\n")); + if (sPacketIndex == 0 && !(data & 8)) { + TRACE(("bad mouse data, trying resync\n")); return B_HANDLED_INTERRUPT; } - while (packet_buffer_write(sMouseBuffer, &data, sizeof(data)) == 0) { - // we start dropping packets when the buffer is full - packet_buffer_flush(sMouseBuffer, sPacketSize); + sPacketBuffer[sPacketIndex++] = data; + + if (sPacketIndex != sPacketSize) { + // packet not yet complete + return B_HANDLED_INTERRUPT; } - if (++sSync == sPacketSize) { - TRACE(("mouse synched\n")); - sSync = 0; - release_sem_etc(sMouseSem, 1, B_DO_NOT_RESCHEDULE); - - return B_INVOKE_SCHEDULER; + // complete packet is assembled + + sPacketIndex = 0; + + if (packet_buffer_write(sMouseBuffer, sPacketBuffer, sPacketSize) != sPacketSize) { + // buffer is full, drop new data + return B_HANDLED_INTERRUPT; } - return B_HANDLED_INTERRUPT; + release_sem_etc(sMouseSem, 1, B_DO_NOT_RESCHEDULE); + return B_INVOKE_SCHEDULER; } @@ -286,7 +291,7 @@ handle_mouse_interrupt(void* cookie) status_t -probe_mouse(void) +probe_mouse(size_t *probed_packet_size) { int8 deviceId = -1; @@ -313,11 +318,13 @@ probe_mouse(void) } if (deviceId == PS2_DEV_ID_STANDARD) { - sPacketSize = PS2_PACKET_STANDARD; TRACE(("Standard PS/2 mouse found\n")); + if (probed_packet_size) + *probed_packet_size = PS2_PACKET_STANDARD; } else if (deviceId == PS2_DEV_ID_INTELLIMOUSE) { - sPacketSize = PS2_PACKET_INTELLIMOUSE; TRACE(("Extended PS/2 mouse found\n")); + if (probed_packet_size) + *probed_packet_size = PS2_PACKET_INTELLIMOUSE; } else { // Something's wrong. Better quit return B_ERROR; @@ -344,9 +351,11 @@ mouse_open(const char *name, uint32 flags, void **_cookie) acquire_sem(gDeviceOpenSemaphore); - status = probe_mouse(); + status = probe_mouse(&sPacketSize); if (status != B_OK) goto err1; + + sPacketIndex = 0; status = ps2_common_initialize(); if (status != B_OK)