From f9ff1193f76399fa22028b20946531535561e714 Mon Sep 17 00:00:00 2001 From: Marcus Overhagen Date: Tue, 11 Apr 2006 21:02:24 +0000 Subject: [PATCH] Removed mouse polling, there seem to exist way too many broken mice for this to work relyable. Reworked interrupt handler calling, and added a data history. Hotplug support will later be implemented using interrupt data. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17097 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/bus_managers/ps2/ps2_common.h | 3 - src/add-ons/kernel/bus_managers/ps2/ps2_dev.c | 15 +-- src/add-ons/kernel/bus_managers/ps2/ps2_dev.h | 8 +- .../kernel/bus_managers/ps2/ps2_keyboard.c | 12 +-- .../kernel/bus_managers/ps2/ps2_mouse.c | 6 +- .../kernel/bus_managers/ps2/ps2_service.c | 97 +------------------ 6 files changed, 26 insertions(+), 115 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_common.h b/src/add-ons/kernel/bus_managers/ps2/ps2_common.h index 44d0e6751b..59f34b0617 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_common.h +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_common.h @@ -58,7 +58,4 @@ extern status_t ps2_command(uint8 cmd, const uint8 *out, int out_count, uint8 *i // prototypes from keyboard.c & mouse.c extern status_t probe_keyboard(void); -extern int32 mouse_handle_int(ps2_dev *dev, uint8 data); -extern int32 keyboard_handle_int(uint8 data); - #endif /* __PS2_COMMON_H */ diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_dev.c b/src/add-ons/kernel/bus_managers/ps2/ps2_dev.c index 3a4b254846..4072421d7d 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_dev.c +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_dev.c @@ -142,8 +142,6 @@ ps2_dev_handle_int(ps2_dev *dev, uint8 data) pass_to_handler: - dev->last_data = system_time(); - if (!dev->active) { ps2_service_notify_device_added(dev); dprintf("ps2: %s not active, data 0x%02x dropped\n", dev->name, data); @@ -158,12 +156,15 @@ pass_to_handler: return B_HANDLED_INTERRUPT; } + + dev->history[4] = dev->history[3]; + dev->history[3] = dev->history[2]; + dev->history[2] = dev->history[1]; + dev->history[1] = dev->history[0]; + dev->history[0].time = system_time(); + dev->history[0].data = data; - // temporary hack... - if (flags & PS2_FLAG_KEYB) - return keyboard_handle_int(data); - else - return mouse_handle_int(dev, data); + return dev->handle_int(dev); } diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_dev.h b/src/add-ons/kernel/bus_managers/ps2/ps2_dev.h index 32c8e49f31..46cc6cbe8c 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_dev.h +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_dev.h @@ -15,6 +15,11 @@ typedef struct ps2_dev ps2_dev; #include "ps2_common.h" +typedef struct +{ + bigtime_t time; + uint8 data; +} data_history; struct ps2_dev { @@ -27,10 +32,11 @@ struct ps2_dev int result_buf_idx; int result_buf_cnt; void * cookie; - bigtime_t last_data; + data_history history[5]; // functions void (*disconnect)(ps2_dev *); + int32 (*handle_int)(ps2_dev *); }; #define PS2_DEVICE_COUNT 5 diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c b/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c index 07ebde3410..865fd19d0d 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c @@ -89,24 +89,23 @@ set_typematic(int32 rate, bigtime_t delay) } -int32 keyboard_handle_int(uint8 data) +static int32 +keyboard_handle_int(ps2_dev *dev) { at_kbd_io keyInfo; - uint8 scancode; + uint8 scancode = dev->history[0].data; if (atomic_and(&sKeyboardOpenMask, 1) == 0) return B_HANDLED_INTERRUPT; // TODO: Handle braindead "pause" key special case - if (data == EXTENDED_KEY) { + if (scancode == EXTENDED_KEY) { sIsExtended = true; TRACE(("Extended key\n")); return B_HANDLED_INTERRUPT; } - scancode = data; - TRACE(("scancode: %x\n", scancode)); // For now, F12 enters the kernel debugger @@ -125,7 +124,7 @@ int32 keyboard_handle_int(uint8 data) sIsExtended = false; } - keyInfo.timestamp = system_time(); + keyInfo.timestamp = dev->history[0].time; keyInfo.scancode = scancode; if (packet_buffer_write(sKeyBuffer, (uint8 *)&keyInfo, sizeof(keyInfo)) == 0) { @@ -250,6 +249,7 @@ keyboard_open(const char *name, uint32 flags, void **_cookie) *_cookie = NULL; ps2_device[PS2_DEVICE_KEYB].disconnect = &ps2_keyboard_disconnect; + ps2_device[PS2_DEVICE_KEYB].handle_int = &keyboard_handle_int; dprintf("ps2: keyboard_open %s success\n", name); return B_OK; diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_mouse.c b/src/add-ons/kernel/bus_managers/ps2/ps2_mouse.c index 4db7b5e1e0..563b26f018 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_mouse.c +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_mouse.c @@ -218,10 +218,11 @@ ps2_mouse_disconnect(ps2_dev *dev) * by read() operations. The full data is obtained using 3 consecutive * calls to the handler, each holds a different byte on the data port. */ -int32 -mouse_handle_int(ps2_dev *dev, uint8 data) +static int32 +mouse_handle_int(ps2_dev *dev) { mouse_cookie *cookie = dev->cookie; + uint8 data = dev->history[0].data; if (cookie->packet_index == 0 && !(data & 8)) { TRACE(("bad mouse data, trying resync\n")); @@ -339,6 +340,7 @@ mouse_open(const char *name, uint32 flags, void **_cookie) cookie->dev = dev; dev->cookie = cookie; dev->disconnect = &ps2_mouse_disconnect; + dev->handle_int = &mouse_handle_int; status = probe_mouse(cookie, &cookie->packet_size); if (status != B_OK) { diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_service.c b/src/add-ons/kernel/bus_managers/ps2/ps2_service.c index 37d733d4a2..7c39482503 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_service.c +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_service.c @@ -16,16 +16,6 @@ static thread_id sServiceThread; static volatile bool sServiceTerminate; static packet_buffer * sServiceCmdBuffer; - -#ifdef DEBUG - #define PS2_SERVICE_INTERVAL 10000000 -#else - #define PS2_SERVICE_INTERVAL 1000000 -#endif - -//#define PS2_PERIODIC_SERVICE - - typedef struct { uint32 id; @@ -72,72 +62,6 @@ ps2_service_notify_device_removed(ps2_dev *dev) } -static status_t -ps2_service_probe_device(ps2_dev *dev) -{ - status_t res; - uint8 data[2]; - - TRACE(("ps2_service_probe_device %s\n", dev->name)); - - // assume device still exists if it sent data during last 500 ms - if (dev->active && (system_time() - dev->last_data) < 500000) - return B_OK; - - if (dev->flags & PS2_FLAG_KEYB) { - -// res = ps2_dev_command(dev, PS2_CMD_ENABLE, NULL, 0, NULL, 0); -// if (res == B_OK) -// return B_OK; - -// snooze(25000); -// res = ps2_dev_command(dev, 0xee, NULL, 0, NULL, 0); // echo -// if (res == B_OK) -// return B_OK; - -// snooze(25000); - res = ps2_dev_command(dev, PS2_CMD_GET_DEVICE_ID, NULL, 0, data, 2); - if (res == B_OK) - return B_OK; - -// if (!dev->active) { -// snooze(25000); -// // 0xFA (Set All Keys Typematic/Make/Break) - Keyboard responds with "ack" (0xFA). -// res = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 0xfa, NULL, 0, NULL, 0); -// if (res == B_OK) -// return B_OK; -// } - - if (!dev->active) { - snooze(25000); - // 0xF3 (Set Typematic Rate/Delay) - data[0] = 0x0b; - res = ps2_dev_command(dev, PS2_CMD_KEYBOARD_SET_TYPEMATIC, data, 1, NULL, 0); - if (res == B_OK) - return B_OK; - } - - } else { - - res = ps2_dev_command(dev, PS2_CMD_GET_DEVICE_ID, NULL, 0, data, 1); - if (res == B_OK) - return B_OK; - - if (!dev->active) { - snooze(25000); - res = ps2_dev_command(dev, PS2_CMD_ENABLE, NULL, 0, NULL, 0); - if (res == B_OK) { - ps2_dev_command(dev, PS2_CMD_DISABLE, NULL, 0, NULL, 0); - return B_OK; - } - } - - } - - return B_ERROR; -} - - static int32 ps2_service_thread(void *arg) { @@ -145,11 +69,7 @@ ps2_service_thread(void *arg) for (;;) { status_t status; - #ifdef PS2_PERIODIC_SERVICE - status = acquire_sem_etc(sServiceSem, 1, B_CAN_INTERRUPT | B_RELATIVE_TIMEOUT, PS2_SERVICE_INTERVAL); - #else - status = acquire_sem_etc(sServiceSem, 1, B_CAN_INTERRUPT, 0); - #endif + status = acquire_sem_etc(sServiceSem, 1, B_CAN_INTERRUPT, 0); if (sServiceTerminate) break; if (status == B_OK) { @@ -172,21 +92,6 @@ ps2_service_thread(void *arg) TRACE(("PS2_SERVICE: unknown id %lu\n", cmd.id)); break; } - - } else if (status == B_TIMED_OUT) { - - // do periodic processing - int i; - for (i = 0; i < (gActiveMultiplexingEnabled ? PS2_DEVICE_COUNT : 2); i++) { - ps2_dev *dev = &ps2_device[i]; - status_t status = ps2_service_probe_device(dev); - if (dev->active && status != B_OK) - ps2_dev_unpublish(dev); - else if (!dev->active && status == B_OK) - ps2_dev_publish(dev); - snooze(50000); - } - } else { dprintf("ps2_service_thread: Error, status 0x%08lx, terminating\n", status); break;