combined mouse and keyboard interrupt handler, work in progress...
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15931 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
741e5c2d81
commit
582d6d64ae
|
@ -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 ;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"));
|
||||
|
|
Loading…
Reference in New Issue