From 84f007fba9f16728c11cdf581174f271a8ccb6c2 Mon Sep 17 00:00:00 2001 From: Marcus Overhagen Date: Mon, 30 Jan 2006 20:14:51 +0000 Subject: [PATCH] made access to keyboard controller and dev->flags thread save git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16157 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/bus_managers/ps2/ps2_common.c | 18 +++++++-------- .../kernel/bus_managers/ps2/ps2_common.h | 1 + src/add-ons/kernel/bus_managers/ps2/ps2_dev.c | 22 +++++++++++-------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_common.c b/src/add-ons/kernel/bus_managers/ps2/ps2_common.c index 63169adee5..b1ca2af6df 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_common.c +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_common.c @@ -19,10 +19,10 @@ isa_module_info *gIsa = NULL; -static sem_id sKbcSem; static int32 sIgnoreInterrupts = 0; -bool gMultiplexingActive = false; +bool gMultiplexingActive = false; +sem_id gControllerSem; inline uint8 @@ -90,7 +90,7 @@ ps2_flush() { int i; - acquire_sem(sKbcSem); + acquire_sem(gControllerSem); atomic_add(&sIgnoreInterrupts, 1); for (i = 0; i < 64; i++) { @@ -105,7 +105,7 @@ ps2_flush() } atomic_add(&sIgnoreInterrupts, -1); - release_sem(sKbcSem); + release_sem(gControllerSem); } @@ -115,7 +115,7 @@ ps2_command(uint8 cmd, const uint8 *out, int out_count, uint8 *in, int in_count) status_t res; int i; - acquire_sem(sKbcSem); + acquire_sem(gControllerSem); atomic_add(&sIgnoreInterrupts, 1); res = ps2_wait_write(); @@ -135,7 +135,7 @@ ps2_command(uint8 cmd, const uint8 *out, int out_count, uint8 *in, int in_count) } atomic_add(&sIgnoreInterrupts, -1); - release_sem(sKbcSem); + release_sem(gControllerSem); return res; } @@ -216,7 +216,7 @@ ps2_init(void) if (status < B_OK) goto err_1; - sKbcSem = create_sem(1, "ps/2 keyb ctrl"); + gControllerSem = create_sem(1, "ps/2 keyb ctrl"); status = ps2_dev_init(); @@ -313,7 +313,7 @@ err_4: err_3: ps2_service_exit(); ps2_dev_exit(); - delete_sem(sKbcSem); + delete_sem(gControllerSem); err_2: put_module(B_ISA_MODULE_NAME); err_1: @@ -330,6 +330,6 @@ ps2_uninit(void) remove_io_interrupt_handler(INT_PS2_KEYBOARD, &ps2_interrupt, NULL); ps2_service_exit(); ps2_dev_exit(); - delete_sem(sKbcSem); + delete_sem(gControllerSem); put_module(B_ISA_MODULE_NAME); } 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 c6a21678e2..29e3bbe665 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_common.h +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_common.h @@ -37,6 +37,7 @@ extern device_hooks gKeyboardDeviceHooks; extern device_hooks gMouseDeviceHooks; extern bool gMultiplexingActive; +extern sem_id gControllerSem; // prototypes from common.c 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 44bccf78f4..9c86dc78c6 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_dev.c +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_dev.c @@ -66,7 +66,7 @@ ps2_dev_publish(ps2_dev *dev) dev->active = true; status = devfs_publish_device(dev->name, NULL, - (dev->flags & PS2_FLAG_KEYB) ? &gKeyboardDeviceHooks : &gMouseDeviceHooks); + (atomic_get(&dev->flags) & PS2_FLAG_KEYB) ? &gKeyboardDeviceHooks : &gMouseDeviceHooks); TRACE(("devfs_publish_device %s, status = 0x%08x\n", dev->name, status)); } @@ -155,7 +155,7 @@ ps2_dev_command(ps2_dev *dev, uint8 cmd, const uint8 *out, int out_count, uint8 int32 sem_count; dprintf("ps2_dev_command %02x, %d out, in %d, dev %s\n", cmd, out_count, in_count, dev->name); - + res = get_sem_count(dev->result_sem, &sem_count); if (res == B_OK && sem_count != 0) { dprintf("ps2_dev_command: sem_count %ld, fixing!\n", sem_count); @@ -165,7 +165,7 @@ ps2_dev_command(ps2_dev *dev, uint8 cmd, const uint8 *out, int out_count, uint8 release_sem_etc(dev->result_sem, -sem_count, 0); } - dev->flags |= PS2_FLAG_CMD; + atomic_or(&dev->flags, PS2_FLAG_CMD); dev->result_buf_cnt = in_count; dev->result_buf_idx = 0; @@ -174,11 +174,13 @@ ps2_dev_command(ps2_dev *dev, uint8 cmd, const uint8 *out, int out_count, uint8 res = B_OK; for (i = -1; res == B_OK && i < out_count; i++) { - dev->flags &= ~(PS2_FLAG_ACK | PS2_FLAG_NACK | PS2_FLAG_GETID); + atomic_and(&dev->flags, ~(PS2_FLAG_ACK | PS2_FLAG_NACK | PS2_FLAG_GETID)); if (i == -1 && cmd == PS2_CMD_GET_DEVICE_ID) - dev->flags |= PS2_FLAG_GETID; + atomic_or(&dev->flags, PS2_FLAG_GETID); - if (!(dev->flags & PS2_FLAG_KEYB)) { + acquire_sem(gControllerSem); + + if (!(atomic_get(&dev->flags) & PS2_FLAG_KEYB)) { uint8 prefix_cmd; if (gMultiplexingActive) prefix_cmd = 0x90 + dev->idx; @@ -194,6 +196,8 @@ ps2_dev_command(ps2_dev *dev, uint8 cmd, const uint8 *out, int out_count, uint8 ps2_write_data(i == -1 ? cmd : out[i]); } + release_sem(gControllerSem); + start = system_time(); res = acquire_sem_etc(dev->result_sem, 1, B_RELATIVE_TIMEOUT, 4000000); dprintf("ps2_dev_command wait for ack res %08x, wait-time %Ld\n", res, system_time() - start); @@ -201,11 +205,11 @@ ps2_dev_command(ps2_dev *dev, uint8 cmd, const uint8 *out, int out_count, uint8 if (res != B_OK) break; - if (dev->flags & PS2_FLAG_ACK) { + if (atomic_get(&dev->flags) & PS2_FLAG_ACK) { dprintf("ps2_dev_command got ACK\n"); } - if (dev->flags & PS2_FLAG_NACK) { + if (atomic_get(&dev->flags) & PS2_FLAG_NACK) { dprintf("ps2_dev_command got NACK\n"); res = B_ERROR; break; @@ -228,7 +232,7 @@ ps2_dev_command(ps2_dev *dev, uint8 cmd, const uint8 *out, int out_count, uint8 dprintf("ps2_dev_command data %02x\n", in[i]); } - dev->flags &= ~PS2_FLAG_CMD; + atomic_and(&dev->flags, ~PS2_FLAG_CMD); return res; }