diff --git a/sortix/kb/ps2.cpp b/sortix/kb/ps2.cpp
index b867d821..ebd77738 100644
--- a/sortix/kb/ps2.cpp
+++ b/sortix/kb/ps2.cpp
@@ -1,6 +1,6 @@
-/******************************************************************************
+/*******************************************************************************
- COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
This file is part of Sortix.
@@ -14,13 +14,13 @@
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
- You should have received a copy of the GNU General Public License along
- with Sortix. If not, see .
+ You should have received a copy of the GNU General Public License along with
+ Sortix. If not, see .
kb/ps2.cpp
A driver for the PS2 Keyboard.
-******************************************************************************/
+*******************************************************************************/
#include
#include
@@ -58,6 +58,7 @@ namespace Sortix
this->interrupt = interrupt;
this->leds = 0;
this->scancodeescaped = false;
+ this->kblock = KTHREAD_MUTEX_INITIALIZER;
Interrupt::RegisterHandler(interrupt, PS2Keyboard__OnInterrupt, this);
// If any scancodes were already pending, our interrupt handler will
@@ -71,16 +72,43 @@ namespace Sortix
delete[] queue;
}
+ struct PS2KeyboardWork
+ {
+ PS2Keyboard* kb;
+ uint8_t scancode;
+ };
+
+ static void PS2Keyboard__InterruptWork(void* payload, size_t size)
+ {
+ ASSERT(size == sizeof(PS2KeyboardWork));
+ PS2KeyboardWork* work = (PS2KeyboardWork*) payload;
+ work->kb->InterruptWork(work->scancode);
+ }
+
void PS2Keyboard::OnInterrupt(CPU::InterruptRegisters* /*regs*/)
{
uint8_t scancode = PopScancode();
+#ifdef GOT_ACTUAL_KTHREAD
+ PS2KeyboardWork work;
+ work.kb = this;
+ work.scancode = scancode;
+ Interrupt::ScheduleWork(PS2Keyboard__InterruptWork, &work, sizeof(work));
+#else
+ InterruptWork(scancode);
+#endif
+ }
+
+ void PS2Keyboard::InterruptWork(uint8_t scancode)
+ {
+ kthread_mutex_lock(&kblock);
int kbkey = DecodeScancode(scancode);
- if ( !kbkey ) { return; }
+ if ( !kbkey ) { kthread_mutex_unlock(&kblock); return; }
if ( !PushKey(kbkey) )
{
Log::PrintF("Warning: dropping keystroke due to insufficient "
"storage space in PS2 keyboard driver.\n");
+ kthread_mutex_unlock(&kblock);
return;
}
@@ -92,6 +120,8 @@ namespace Sortix
if ( newleds != leds ) { UpdateLEDs(leds = newleds); }
+ kthread_mutex_unlock(&kblock);
+
NotifyOwner();
}
@@ -137,8 +167,10 @@ namespace Sortix
void PS2Keyboard::SetOwner(KeyboardOwner* owner, void* user)
{
+ kthread_mutex_lock(&kblock);
this->owner = owner;
this->ownerptr = user;
+ kthread_mutex_unlock(&kblock);
if ( queueused ) { NotifyOwner(); }
}
@@ -177,16 +209,19 @@ namespace Sortix
int PS2Keyboard::Read()
{
+ ScopedLock lock(&kblock);
return PopKey();
}
size_t PS2Keyboard::GetPending() const
{
+ ScopedLock lock(&kblock);
return queueused;
}
bool PS2Keyboard::HasPending() const
{
+ ScopedLock lock(&kblock);
return queueused;
}
}
diff --git a/sortix/kb/ps2.h b/sortix/kb/ps2.h
index feccb8f2..840baf2f 100644
--- a/sortix/kb/ps2.h
+++ b/sortix/kb/ps2.h
@@ -1,6 +1,6 @@
-/******************************************************************************
+/*******************************************************************************
- COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
This file is part of Sortix.
@@ -14,17 +14,18 @@
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
- You should have received a copy of the GNU General Public License along
- with Sortix. If not, see .
+ You should have received a copy of the GNU General Public License along with
+ Sortix. If not, see .
kb/ps2.h
A driver for the PS2 Keyboard.
-******************************************************************************/
+*******************************************************************************/
#ifndef SORTIX_KB_PS2_H
#define SORTIX_KB_PS2_H
+#include
#include "../keyboard.h"
namespace Sortix
@@ -41,6 +42,7 @@ namespace Sortix
public:
void OnInterrupt(CPU::InterruptRegisters* regs);
+ void InterruptWork(uint8_t scancode);
private:
uint8_t PopScancode();
@@ -61,6 +63,7 @@ namespace Sortix
uint8_t interrupt;
bool scancodeescaped;
uint8_t leds;
+ mutable kthread_mutex_t kblock;
};
}