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 56c3ba6f5e..28a8afcd23 100644 --- a/src/add-ons/kernel/drivers/input/ps2_hid_new/Jamfile +++ b/src/add-ons/kernel/drivers/input/ps2_hid_new/Jamfile @@ -1,29 +1,13 @@ -SubDir HAIKU_TOP src add-ons kernel drivers input ps2_hid ; +SubDir HAIKU_TOP src add-ons kernel drivers input ps2_hid_new ; SetSubDirSupportedPlatformsBeOSCompatible ; UsePrivateHeaders input ; UsePrivateHeaders kernel ; -if ! $(HAIKU_COMPATIBLE) { -SubDirCcFlags -DCOMPILE_FOR_R5 ; - -KernelAddon ps2_hid : kernel drivers bin : - common.c - keyboard.c - mouse.c -; -} else { -KernelAddon ps2_hid : kernel drivers bin : +KernelAddon ps2_hid_new : kernel drivers bin : common.c keyboard.c mouse.c packet_buffer.cpp ; -} - -Package haiku-inputkit-cvs : - ps2_hid : - boot home config add-ons kernel drivers bin ; - -PackageDriverSymLink haiku-inputkit-cvs : input ps2_hid ; 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 49a737be60..a5c73aeed4 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 @@ -62,6 +62,35 @@ static uint8 *sResultBuffer; static int32 sResultBytes; +inline uint8 +ps2_read_ctrl() +{ + return gIsa->read_io_8(PS2_PORT_CTRL); +} + + +inline uint8 +ps2_read_data() +{ + return gIsa->read_io_8(PS2_PORT_DATA); +} + + +inline void +ps2_write_ctrl(uint8 ctrl) +{ + gIsa->write_io_8(PS2_PORT_CTRL, ctrl); +} + + +inline void +ps2_write_data(uint8 data) +{ + gIsa->write_io_8(PS2_PORT_DATA, data); +} + + + /** Wait until the specified status bits are cleared or set, depending on the * second parameter. * This currently busy waits, but should nonetheless be avoided in interrupt @@ -248,42 +277,27 @@ ps2_wait_for_result(void) } -void -ps2_common_uninitialize(void) +static int32 +ps2_interrupt(void* cookie) { - // do we still need the resources? - if (atomic_add(&sInitialized, -1) > 1) - return; + uint8 ctrl; + uint8 data; + + ctrl = ps2_read_ctrl(); + if (!(ctrl & PS2_STATUS_OUTPUT_BUFFER_FULL)) + return B_UNHANDLED_INTERRUPT; + + data = ps2_read_data(); - delete_sem(sResultSemaphore); - delete_sem(sResultOwnerSemaphore); + 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); } -status_t -ps2_common_initialize(void) -{ - if (atomic_add(&sInitialized, 1) > 0) { - // we're already initialized - return B_OK; - } - - sResultSemaphore = create_sem(0, "ps/2 result"); - if (sResultSemaphore < B_OK) - return sResultSemaphore; - - sResultOwnerSemaphore = create_sem(1, "ps/2 result owner"); - if (sResultOwnerSemaphore < B_OK) { - delete_sem(sResultSemaphore); - return sResultOwnerSemaphore; - } - - sResultBytes = 0; - sResultBuffer = NULL; - - return B_OK; -} - // #pragma mark - // driver interface @@ -302,10 +316,8 @@ publish_devices(void) static char *kDevices[3]; int index = 0; - if (sMouseDetected) kDevices[index++] = DEVICE_MOUSE_NAME; - if (sKeyboardDetected) kDevices[index++] = DEVICE_KEYBOARD_NAME; kDevices[index++] = NULL; @@ -332,45 +344,46 @@ init_driver(void) status_t status; status = get_module(B_ISA_MODULE_NAME, (module_info **)&gIsa); - if (status < B_OK) { - TRACE(("Failed getting isa module: %s\n", strerror(status))); - return status; - } - - // Try to probe for the mouse first, as this can hang the keyboard if no - // mouse is found. - // Probing the mouse first and initializing the keyboard later appearantly - // clears the keyboard stall. - - if (probe_mouse(NULL) == B_OK) - sMouseDetected = true; - else - dprintf("ps2_hid: no mouse detected!\n"); - - if (probe_keyboard() == B_OK) - sKeyboardDetected = true; - else - dprintf("ps2_hid: no keyboard detected!\n"); - - // If there is no keyboard or mouse, we don't need to publish ourselves - if (!sKeyboardDetected && !sMouseDetected) { - put_module(B_ISA_MODULE_NAME); - return B_ERROR; - } - - // A semaphore to synchronize open keyboard and mouse devices + if (status < B_OK) + goto err_1; gDeviceOpenSemaphore = create_sem(1, "ps/2 open"); if (gDeviceOpenSemaphore < B_OK) - return gDeviceOpenSemaphore; + goto err_2; - return get_command_byte(&sCommandByte); + status = install_io_interrupt_handler(INT_PS2_KEYBOARD, &ps2_interrupt, NULL, 0); + if (status) + goto err_3; + + status = install_io_interrupt_handler(INT_PS2_MOUSE, &ps2_interrupt, NULL, 0); + if (status) + goto err_4; + + + + //goto err_5; + + + return B_OK; + +err_5: + remove_io_interrupt_handler(INT_PS2_MOUSE, &ps2_interrupt, NULL); +err_4: + remove_io_interrupt_handler(INT_PS2_KEYBOARD, &ps2_interrupt, NULL); +err_3: + delete_sem(gDeviceOpenSemaphore); +err_2: + put_module(B_ISA_MODULE_NAME); +err_1: + return B_ERROR; } void uninit_driver(void) { + remove_io_interrupt_handler(INT_PS2_MOUSE, &ps2_interrupt, NULL); + remove_io_interrupt_handler(INT_PS2_KEYBOARD, &ps2_interrupt, NULL); delete_sem(gDeviceOpenSemaphore); - put_module(B_ISA_MODULE_NAME); + put_module(B_ISA_MODULE_NAME); } 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 ba873c904a..9e1393ec32 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 @@ -52,6 +52,10 @@ extern status_t ps2_common_initialize(void); extern status_t probe_keyboard(void); extern status_t probe_mouse(size_t *probed_packet_size); +extern int32 mouse_handle_int(uint8 data); +extern int32 keyboard_handle_int(uint8 data); + + extern status_t keyboard_open(const char *name, uint32 flags, void **cookie); extern status_t keyboard_close(void *cookie); extern status_t keyboard_freecookie(void *cookie); diff --git a/src/add-ons/kernel/drivers/input/ps2_hid_new/keyboard.c b/src/add-ons/kernel/drivers/input/ps2_hid_new/keyboard.c index 30294936e2..62c82877f0 100644 --- a/src/add-ons/kernel/drivers/input/ps2_hid_new/keyboard.c +++ b/src/add-ons/kernel/drivers/input/ps2_hid_new/keyboard.c @@ -146,31 +146,24 @@ set_leds(led_info *ledInfo) } -static int32 -handle_keyboard_interrupt(void *data) +int32 keyboard_handle_int(uint8 data) { - uint8 read = gIsa->read_io_8(PS2_PORT_CTRL); - TRACE(("handle_keyboard_interrupt: read = 0x%x\n", read)); + if (atomic_and(&sKeyboardOpenMask, 1) == 0) + return B_HANDLED_INTERRUPT; + - if (read & PS2_STATUS_OUTPUT_BUFFER_FULL) { at_kbd_io keyInfo; uint8 scancode; - read = gIsa->read_io_8(PS2_PORT_DATA); - - // someone else might wait for a result from the keyboard controller - if (ps2_handle_result(read)) - return B_INVOKE_SCHEDULER; - // TODO: Handle braindead "pause" key special case - if (read == EXTENDED_KEY) { + if (data == EXTENDED_KEY) { sIsExtended = true; TRACE(("Extended key\n")); return B_HANDLED_INTERRUPT; } - scancode = read; + scancode = data; TRACE(("scancode: %x\n", scancode)); @@ -200,11 +193,6 @@ handle_keyboard_interrupt(void *data) } release_sem_etc(sKeyboardSem, 1, B_DO_NOT_RESCHEDULE); - } else { - // ToDo: the buffer is not yet available, we should come back soon... - // (depending on how often we see the message below... :-) - dprintf("ps2_hid: keyboard: buffer not available!\n"); - } return B_INVOKE_SCHEDULER; } @@ -309,10 +297,6 @@ keyboard_open(const char *name, uint32 flags, void **_cookie) acquire_sem(gDeviceOpenSemaphore); - status = ps2_common_initialize(); - if (status != B_OK) - goto err1; - sKeyboardSem = create_sem(0, "keyboard_sem"); if (sKeyboardSem < 0) { status = sKeyboardSem; @@ -337,12 +321,6 @@ keyboard_open(const char *name, uint32 flags, void **_cookie) goto err4; } - status = install_io_interrupt_handler(INT_PS2_KEYBOARD, - &handle_keyboard_interrupt, NULL, 0); - if (status < B_OK) - goto err4; - - sInterruptHandlerInstalled = true; release_sem(gDeviceOpenSemaphore); *_cookie = NULL; @@ -355,7 +333,6 @@ err4: err3: delete_sem(sKeyboardSem); err2: - ps2_common_uninitialize(); err1: atomic_and(&sKeyboardOpenMask, 0); release_sem(gDeviceOpenSemaphore); @@ -369,13 +346,10 @@ keyboard_close(void *cookie) { TRACE(("keyboard_close()\n")); - remove_io_interrupt_handler(INT_PS2_KEYBOARD, &handle_keyboard_interrupt, NULL); - sInterruptHandlerInstalled = false; delete_packet_buffer(sKeyBuffer); delete_sem(sKeyboardSem); - ps2_common_uninitialize(); atomic_and(&sKeyboardOpenMask, 0); return B_OK; diff --git a/src/add-ons/kernel/drivers/input/ps2_hid_new/mouse.c b/src/add-ons/kernel/drivers/input/ps2_hid_new/mouse.c index db0699200c..757efbe832 100644 --- a/src/add-ons/kernel/drivers/input/ps2_hid_new/mouse.c +++ b/src/add-ons/kernel/drivers/input/ps2_hid_new/mouse.c @@ -249,17 +249,10 @@ set_mouse_enabled(bool enable) * calls to the handler, each holds a different byte on the data port. */ -static int32 -handle_mouse_interrupt(void* cookie) +int32 mouse_handle_int(uint8 data) { - uint8 data = gIsa->read_io_8(PS2_PORT_CTRL); - if (!(data & PS2_STATUS_OUTPUT_BUFFER_FULL)) { - TRACE(("no ps2 mouse data available\n")); - return B_UNHANDLED_INTERRUPT; - } - - data = gIsa->read_io_8(PS2_PORT_DATA); - TRACE(("mouse interrupt: %d byte: 0x%02x\n", sPacketIndex, data)); + if (atomic_and(&sMouseOpenMask, 1) == 0) + return B_HANDLED_INTERRUPT; if (sPacketIndex == 0 && !(data & 8)) { TRACE(("bad mouse data, trying resync\n"));