[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


Other related posts:

  • » [haiku-development] [PATCH 3/4] Use emergency driver for PS2 keyboard handler