[haiku-development] [PATCH 3/4] Use emergency driver for PS2 keyboard handler
- From: Jan Klötzke <jan.kloetzke@xxxxxxxxxx>
- To: haiku-development@xxxxxxxxxxxxx
- Date: Thu, 26 Jun 2008 21:14:55 +0200
---
src/add-ons/kernel/bus_managers/ps2/ps2_common.c | 12 ++++--
src/add-ons/kernel/bus_managers/ps2/ps2_common.h | 2 +
src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c | 37 ++++++++++++++++++--
3 files changed, 44 insertions(+), 7 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 49c5677..19ce13c 100644
--- a/src/add-ons/kernel/bus_managers/ps2/ps2_common.c
+++ b/src/add-ons/kernel/bus_managers/ps2/ps2_common.c
@@ -18,6 +18,7 @@
isa_module_info *gIsa = NULL;
+emergency_module_info *gEmergency = NULL;
bool gActiveMultiplexingEnabled = false;
sem_id gControllerSem;
@@ -299,10 +300,6 @@ ps2_interrupt(void* cookie)
TRACE("ps2: ps2_interrupt ctrl 0x%02x, data 0x%02x (keyb)\n",
ctrl, data);
dev = &ps2_device[PS2_DEVICE_KEYB];
error = (ctrl & 0xC0) != 0;
-
- // TODO: remove me again; let us drop into the kernel debugger
with F12
- if (data == 88)
- panic("keyboard requested halt.\n");
}
dev->history[1] = dev->history[0];
@@ -328,6 +325,9 @@ ps2_init(void)
if (status < B_OK)
return status;
+ /* Don't care if it could be loaded or not... */
+ get_module(B_EMERGENCY_MODULE_NAME, (module_info **)&gEmergency);
+
gControllerSem = create_sem(1, "ps/2 keyb ctrl");
ps2_flush();
@@ -396,6 +396,8 @@ err2:
ps2_dev_exit();
err1:
delete_sem(gControllerSem);
+ if (gEmergency)
+ put_module(B_EMERGENCY_MODULE_NAME);
put_module(B_ISA_MODULE_NAME);
TRACE("ps2: init failed!\n");
return B_ERROR;
@@ -411,5 +413,7 @@ ps2_uninit(void)
ps2_service_exit();
ps2_dev_exit();
delete_sem(gControllerSem);
+ if (gEmergency)
+ put_module(B_EMERGENCY_MODULE_NAME);
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 39eaa5a..8df0eda 100644
--- a/src/add-ons/kernel/bus_managers/ps2/ps2_common.h
+++ b/src/add-ons/kernel/bus_managers/ps2/ps2_common.h
@@ -18,6 +18,7 @@
#include <Drivers.h>
#include <KernelExport.h>
#include <OS.h>
+#include <emergency.h>
#include "ps2_defs.h"
#include "ps2_dev.h"
@@ -39,6 +40,7 @@
// global variables
extern isa_module_info *gIsa;
+extern emergency_module_info *gEmergency;
extern device_hooks gKeyboardDeviceHooks;
extern device_hooks gMouseDeviceHooks;
diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c
b/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c
index 2c9e0fc..7b22d09 100644
--- a/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c
+++ b/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c
@@ -16,6 +16,8 @@
#include <string.h>
+#include "debugger_keymaps.h"
+
#define KEY_BUFFER_SIZE 100
// we will buffer 100 key strokes before we start dropping them
@@ -34,6 +36,7 @@ static int32 sKeyboardOpenMask;
static sem_id sKeyboardSem;
static struct packet_buffer *sKeyBuffer;
static bool sIsExtended = false;
+static int32 sShiftState = 0;
static int32 sKeyboardRepeatRate;
static bigtime_t sKeyboardRepeatDelay;
@@ -116,15 +119,43 @@ keyboard_handle_int(ps2_dev *dev)
if (sIsExtended) {
scancode |= 0x80;
sIsExtended = false;
+ } else {
+ int32 mask = 0;
+ switch (scancode) {
+ case 0x2a: mask = 1; break; /* LShift */
+ case 0x36: mask = 2; break; /* RShift */
+ case 0x58: mask = 4; break; /* F12 */
+ }
+
+ if (keyInfo.is_keydown)
+ atomic_or(&sShiftState, mask);
+ else
+ atomic_and(&sShiftState, ~mask);
}
keyInfo.timestamp = dev->history[0].time;
keyInfo.scancode = scancode;
- if (packet_buffer_write(sKeyBuffer, (uint8 *)&keyInfo, sizeof(keyInfo))
== 0) {
- // If there is no space left in the buffer, we drop this key
stroke. We avoid
- // dropping old key strokes, to not destroy what already was
typed.
+ if ((sShiftState & 0x07) == 0x04 && scancode == 0x58) {
+ /* TODO: remove me again; let us drop into the kernel debugger
with F12 */
+ panic("keyboard requested halt.\n");
+ sShiftState = 0; /* break code not seen by ps2 int
handler */
return B_HANDLED_INTERRUPT;
+ } else {
+ if (((sShiftState & 0x07) > 4)) {
+ /* (LShift || RShift) && F12 && other key */
+ if ((scancode != 0x58) && keyInfo.is_keydown &&
gEmergency)
+
gEmergency->emergency_key(kUnshiftedKeymap[scancode]);
+ return B_HANDLED_INTERRUPT;
+ } else {
+ if (packet_buffer_write(sKeyBuffer, (uint8 *)&keyInfo,
sizeof(keyInfo))
+ == 0) {
+ /* If there is no space left in the buffer, we
drop this key
+ * stroke. We avoid dropping old key strokes,
to not destroy
+ * what already was typed. */
+ return B_HANDLED_INTERRUPT;
+ }
+ }
}
release_sem_etc(sKeyboardSem, 1, B_DO_NOT_RESCHEDULE);
--
1.5.4.2
- References:
- [haiku-development] Emergency keyboard shortcut handler
- From: Jan Klötzke
Other related posts:
- » [haiku-development] [PATCH 3/4] Use emergency driver for PS2 keyboard handler
- [haiku-development] Emergency keyboard shortcut handler
- From: Jan Klötzke