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
This commit is contained in:
parent
db63fe6713
commit
84f007fba9
@ -19,10 +19,10 @@
|
|||||||
|
|
||||||
isa_module_info *gIsa = NULL;
|
isa_module_info *gIsa = NULL;
|
||||||
|
|
||||||
static sem_id sKbcSem;
|
|
||||||
static int32 sIgnoreInterrupts = 0;
|
static int32 sIgnoreInterrupts = 0;
|
||||||
|
|
||||||
bool gMultiplexingActive = false;
|
bool gMultiplexingActive = false;
|
||||||
|
sem_id gControllerSem;
|
||||||
|
|
||||||
|
|
||||||
inline uint8
|
inline uint8
|
||||||
@ -90,7 +90,7 @@ ps2_flush()
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
acquire_sem(sKbcSem);
|
acquire_sem(gControllerSem);
|
||||||
atomic_add(&sIgnoreInterrupts, 1);
|
atomic_add(&sIgnoreInterrupts, 1);
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
@ -105,7 +105,7 @@ ps2_flush()
|
|||||||
}
|
}
|
||||||
|
|
||||||
atomic_add(&sIgnoreInterrupts, -1);
|
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;
|
status_t res;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
acquire_sem(sKbcSem);
|
acquire_sem(gControllerSem);
|
||||||
atomic_add(&sIgnoreInterrupts, 1);
|
atomic_add(&sIgnoreInterrupts, 1);
|
||||||
|
|
||||||
res = ps2_wait_write();
|
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);
|
atomic_add(&sIgnoreInterrupts, -1);
|
||||||
release_sem(sKbcSem);
|
release_sem(gControllerSem);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ ps2_init(void)
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err_1;
|
goto err_1;
|
||||||
|
|
||||||
sKbcSem = create_sem(1, "ps/2 keyb ctrl");
|
gControllerSem = create_sem(1, "ps/2 keyb ctrl");
|
||||||
|
|
||||||
status = ps2_dev_init();
|
status = ps2_dev_init();
|
||||||
|
|
||||||
@ -313,7 +313,7 @@ err_4:
|
|||||||
err_3:
|
err_3:
|
||||||
ps2_service_exit();
|
ps2_service_exit();
|
||||||
ps2_dev_exit();
|
ps2_dev_exit();
|
||||||
delete_sem(sKbcSem);
|
delete_sem(gControllerSem);
|
||||||
err_2:
|
err_2:
|
||||||
put_module(B_ISA_MODULE_NAME);
|
put_module(B_ISA_MODULE_NAME);
|
||||||
err_1:
|
err_1:
|
||||||
@ -330,6 +330,6 @@ ps2_uninit(void)
|
|||||||
remove_io_interrupt_handler(INT_PS2_KEYBOARD, &ps2_interrupt, NULL);
|
remove_io_interrupt_handler(INT_PS2_KEYBOARD, &ps2_interrupt, NULL);
|
||||||
ps2_service_exit();
|
ps2_service_exit();
|
||||||
ps2_dev_exit();
|
ps2_dev_exit();
|
||||||
delete_sem(sKbcSem);
|
delete_sem(gControllerSem);
|
||||||
put_module(B_ISA_MODULE_NAME);
|
put_module(B_ISA_MODULE_NAME);
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ extern device_hooks gKeyboardDeviceHooks;
|
|||||||
extern device_hooks gMouseDeviceHooks;
|
extern device_hooks gMouseDeviceHooks;
|
||||||
|
|
||||||
extern bool gMultiplexingActive;
|
extern bool gMultiplexingActive;
|
||||||
|
extern sem_id gControllerSem;
|
||||||
|
|
||||||
// prototypes from common.c
|
// prototypes from common.c
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ ps2_dev_publish(ps2_dev *dev)
|
|||||||
dev->active = true;
|
dev->active = true;
|
||||||
|
|
||||||
status = devfs_publish_device(dev->name, NULL,
|
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));
|
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;
|
int32 sem_count;
|
||||||
|
|
||||||
dprintf("ps2_dev_command %02x, %d out, in %d, dev %s\n", cmd, out_count, in_count, dev->name);
|
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);
|
res = get_sem_count(dev->result_sem, &sem_count);
|
||||||
if (res == B_OK && sem_count != 0) {
|
if (res == B_OK && sem_count != 0) {
|
||||||
dprintf("ps2_dev_command: sem_count %ld, fixing!\n", sem_count);
|
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);
|
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_cnt = in_count;
|
||||||
dev->result_buf_idx = 0;
|
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;
|
res = B_OK;
|
||||||
for (i = -1; res == B_OK && i < out_count; i++) {
|
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)
|
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;
|
uint8 prefix_cmd;
|
||||||
if (gMultiplexingActive)
|
if (gMultiplexingActive)
|
||||||
prefix_cmd = 0x90 + dev->idx;
|
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]);
|
ps2_write_data(i == -1 ? cmd : out[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
release_sem(gControllerSem);
|
||||||
|
|
||||||
start = system_time();
|
start = system_time();
|
||||||
res = acquire_sem_etc(dev->result_sem, 1, B_RELATIVE_TIMEOUT, 4000000);
|
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);
|
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)
|
if (res != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (dev->flags & PS2_FLAG_ACK) {
|
if (atomic_get(&dev->flags) & PS2_FLAG_ACK) {
|
||||||
dprintf("ps2_dev_command got ACK\n");
|
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");
|
dprintf("ps2_dev_command got NACK\n");
|
||||||
res = B_ERROR;
|
res = B_ERROR;
|
||||||
break;
|
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]);
|
dprintf("ps2_dev_command data %02x\n", in[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->flags &= ~PS2_FLAG_CMD;
|
atomic_and(&dev->flags, ~PS2_FLAG_CMD);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user