diff --git a/src/add-ons/kernel/drivers/input/ps2_hid_new/Jamfile b/src/add-ons/kernel/drivers/input/ps2_hid_new/Jamfile index 9061b3de55..52b2cc0e3c 100644 --- a/src/add-ons/kernel/drivers/input/ps2_hid_new/Jamfile +++ b/src/add-ons/kernel/drivers/input/ps2_hid_new/Jamfile @@ -10,5 +10,6 @@ KernelAddon ps2_hid_new : kernel drivers bin : keyboard.c mouse.c packet_buffer.cpp + ps2_dev.c ps2_service.c ; diff --git a/src/add-ons/kernel/drivers/input/ps2_hid_new/common.c b/src/add-ons/kernel/drivers/input/ps2_hid_new/common.c index 755c28a6db..b7bb27e205 100644 --- a/src/add-ons/kernel/drivers/input/ps2_hid_new/common.c +++ b/src/add-ons/kernel/drivers/input/ps2_hid_new/common.c @@ -10,19 +10,15 @@ */ -#include #include #include "common.h" #include "ps2_service.h" - - -#define DEVICE_MOUSE_NAME "input/mouse/ps2/0" -#define DEVICE_KEYBOARD_NAME "input/keyboard/at/0" +#include "ps2_dev.h" int32 api_version = B_CUR_DRIVER_API_VERSION; -static device_hooks sKeyboardDeviceHooks = { +device_hooks sKeyboardDeviceHooks = { keyboard_open, keyboard_close, keyboard_freecookie, @@ -35,7 +31,7 @@ static device_hooks sKeyboardDeviceHooks = { NULL }; -static device_hooks sMouseDeviceHooks = { +device_hooks sMouseDeviceHooks = { mouse_open, mouse_close, mouse_freecookie, @@ -54,6 +50,7 @@ sem_id gDeviceOpenSemaphore; static sem_id sKbcSem; static int32 sIgnoreInterrupts = 0; +static bool sMultiplexingActive = false; inline uint8 @@ -208,6 +205,7 @@ ps2_interrupt(void* cookie) { uint8 ctrl; uint8 data; + ps2_dev *dev; ctrl = ps2_read_ctrl(); if (!(ctrl & PS2_STATUS_OUTPUT_BUFFER_FULL)) @@ -222,16 +220,18 @@ ps2_interrupt(void* cookie) TRACE(("ps2_interrupt: ctrl 0x%02x, data 0x%02x (%s)\n", ctrl, data, (ctrl & PS2_STATUS_MOUSE_DATA) ? "mouse" : "keyb")); - if (ctrl & PS2_STATUS_MOUSE_DATA) - return mouse_handle_int(data); - else - return keyboard_handle_int(data); + if (ctrl & PS2_STATUS_MOUSE_DATA) { + uint8 idx = 0; + dev = &ps2_device[PS2_DEVICE_MOUSE + idx]; + } else { + dev = &ps2_device[PS2_DEVICE_KEYB]; + } + + return ps2_dev_handle_int(dev, data); } - -// #pragma mark - -// driver interface +// #pragma mark - driver interface status_t @@ -244,29 +244,13 @@ init_hardware(void) const char ** publish_devices(void) { - static char *kDevices[3]; - int index = 0; - - kDevices[index++] = DEVICE_MOUSE_NAME; - - kDevices[index++] = DEVICE_KEYBOARD_NAME; - - kDevices[index++] = NULL; - - //status_t devfs_publish_device(const char *path, NULL, device_hooks *calls); - - return (const char **)kDevices; + return NULL; } device_hooks * find_device(const char *name) { - if (!strcmp(name, DEVICE_MOUSE_NAME)) - return &sMouseDeviceHooks; - else if (!strcmp(name, DEVICE_KEYBOARD_NAME)) - return &sKeyboardDeviceHooks; - return NULL; } @@ -296,7 +280,6 @@ init_driver(void) if (status) goto err_4; - { uint8 d; status_t res; @@ -309,18 +292,14 @@ init_driver(void) res = ps2_set_command_byte(d); dprintf("ps2_set_command_byte: res 0x%08x, d 0x%02x\n", res, d); - - res = ps2_command(0xae, NULL, 0, NULL, 0); - dprintf("KBD enable: res 0x%08x\n", res); + } - res = ps2_command(0xa8, NULL, 0, NULL, 0); - dprintf("AUX enable: res 0x%08x\n", res); - - res = ps2_command(0xab, NULL, 0, &d, 1); - dprintf("KBD test: res 0x%08x, d 0x%02x\n", res, d); - - res = ps2_command(0xa9, NULL, 0, &d, 1); - dprintf("AUX test: res 0x%08x, d 0x%02x\n", res, d); + ps2_service_handle_device_added(&ps2_device[PS2_DEVICE_KEYB]); + ps2_service_handle_device_added(&ps2_device[PS2_DEVICE_MOUSE]); + if (sMultiplexingActive) { + ps2_service_handle_device_added(&ps2_device[PS2_DEVICE_MOUSE + 1]); + ps2_service_handle_device_added(&ps2_device[PS2_DEVICE_MOUSE + 2]); + ps2_service_handle_device_added(&ps2_device[PS2_DEVICE_MOUSE + 3]); } //goto err_5; diff --git a/src/add-ons/kernel/drivers/input/ps2_hid_new/common.h b/src/add-ons/kernel/drivers/input/ps2_hid_new/common.h index b1f518041d..a85a2d7f3b 100644 --- a/src/add-ons/kernel/drivers/input/ps2_hid_new/common.h +++ b/src/add-ons/kernel/drivers/input/ps2_hid_new/common.h @@ -14,6 +14,7 @@ #include +#include #include #include @@ -31,6 +32,9 @@ extern isa_module_info *gIsa; extern sem_id gDeviceOpenSemaphore; +extern device_hooks sKeyboardDeviceHooks; +extern device_hooks sMouseDeviceHooks; + // prototypes from common.c extern status_t ps2_wait_read(); diff --git a/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_dev.c b/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_dev.c new file mode 100644 index 0000000000..ede586c266 --- /dev/null +++ b/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_dev.c @@ -0,0 +1,86 @@ +/* + * Copyright 2005 Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * PS/2 hid device driver + * + * Authors (in chronological order): + * Marcus Overhagen (marcus@overhagen.de) + */ + +#include "ps2_dev.h" +#include "ps2_service.h" + +ps2_dev ps2_device[5] = +{ + { .name = "input/mouse/ps2/0", .active = false }, + { .name = "input/mouse/ps2/1", .active = false }, + { .name = "input/mouse/ps2/2", .active = false }, + { .name = "input/mouse/ps2/3", .active = false }, + { .name = "input/keyboard/at/0", .active = false, .flags = PS2_FLAG_KEYB } +}; + + +void +ps2_dev_publish(ps2_dev *dev) +{ + status_t status; + + if (dev->active) + return; + + TRACE(("ps2_dev_publish %s\n", dev->name)); + + dev->result_sem = create_sem(0, "ps2 result"); + dev->result_buf = NULL; + dev->result_buf_idx = 0; + dev->result_buf_cnt = 0; + dev->flags &= ~PS2_FLAG_KEYB; + + dev->active = true; + + status = devfs_publish_device(dev->name, NULL, + (dev->flags & PS2_FLAG_KEYB) ? sKeyboardDeviceHooks : sMouseDeviceHooks); + + TRACE(("devfs_publish_device %s, status = 0x%08x\n", dev->name, status)); +} + + +void +ps2_dev_unpublish(ps2_dev *dev) +{ + if (!dev->active) + return; + + TRACE(("ps2_dev_unpublish %s\n", dev->name)); + + dev->active = false; + + delete_sem(dev->result_sem); +} + + +int32 +ps2_dev_handle_int(ps2_dev *dev, uint8 data) +{ + if (!dev->active) { + ps2_service_handle_device_added(dev); + return B_HANDLED_INTERRUPT; + } + if (dev->result_buf_cnt) { + dev->result_buf[dev->result_buf_idx] = data; + dev->result_buf_idx++; + dev->result_buf_cnt--; + if (dev->result_buf_cnt == 0) { + release_sem_etc(dev->result_sem, 0, B_DO_NOT_RESCHEDULE); + return B_INVOKE_SCHEDULER; + } + return B_HANDLED_INTERRUPT; + } + + // temporary hack... + if (dev->flags & PS2_FLAG_KEYB) + return keyboard_handle_int(data); + else + return mouse_handle_int(data); +} diff --git a/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_dev.h b/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_dev.h new file mode 100644 index 0000000000..a338f94557 --- /dev/null +++ b/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_dev.h @@ -0,0 +1,38 @@ +/* + * Copyright 2005 Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * PS/2 hid device driver + * + * Authors (in chronological order): + * Marcus Overhagen (marcus@overhagen.de) + */ +#ifndef __PS2_DEV_H +#define __PS2_DEV_H + +#include "common.h" + +typedef struct +{ + const char * name; + bool active; + uint32 flags; + sem_id result_sem; + uint8 * result_buf; + int result_buf_idx; + int result_buf_cnt; +} ps2_dev; + +extern ps2_dev ps2_device[5]; + +#define PS2_DEVICE_MOUSE 0 +#define PS2_DEVICE_KEYB 4 + +#define PS2_FLAG_KEYB 1 + +void ps2_dev_publish(ps2_dev *dev); +void ps2_dev_unpublish(ps2_dev *dev); + +int32 ps2_dev_handle_int(ps2_dev *dev, uint8 data); + +#endif diff --git a/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_service.c b/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_service.c index fa44ff5e6f..7e75ca2197 100644 --- a/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_service.c +++ b/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_service.c @@ -15,6 +15,50 @@ static thread_id sServiceThread; static volatile bool sServiceTerminate; +void +ps2_service_handle_device_added(ps2_dev *dev) +{ + TRACE(("ps2_service_handle_device_added %s\n", dev->name)); + +} + + +void +ps2_service_handle_device_removed(ps2_dev *dev) +{ + TRACE(("ps2_service_handle_device_removed %s\n", dev->name)); +} + + +static status_t +ps2_service_probe_device(ps2_dev *dev) +{ + uint8 d; + status_t res; + + TRACE(("ps2_service_probe_device %s\n", dev->name)); + + if (dev->flags & PS2_FLAG_KEYB) { + + res = ps2_command(0xae, NULL, 0, NULL, 0); + dprintf("KBD enable: res 0x%08x\n", res); + + res = ps2_command(0xab, NULL, 0, &d, 1); + dprintf("KBD test: res 0x%08x, d 0x%02x\n", res, d); + + } else { + + res = ps2_command(0xa8, NULL, 0, NULL, 0); + dprintf("AUX enable: res 0x%08x\n", res); + + res = ps2_command(0xa9, NULL, 0, &d, 1); + dprintf("AUX test: res 0x%08x, d 0x%02x\n", res, d); + } + + return B_OK; +} + + static int32 ps2_service_thread(void *arg) { diff --git a/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_service.h b/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_service.h index d2d86c3f6a..cda0394474 100644 --- a/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_service.h +++ b/src/add-ons/kernel/drivers/input/ps2_hid_new/ps2_service.h @@ -11,8 +11,12 @@ #define __PS2_SERVICE_H #include "common.h" +#include "ps2_dev.h" status_t ps2_service_init(void); void ps2_service_exit(void); +void ps2_service_handle_device_added(ps2_dev *dev); +void ps2_service_handle_device_removed(ps2_dev *dev); + #endif