summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2013-12-09 15:29:28 -0800
committerYung-chieh Lo <yjlou@chromium.org>2013-12-10 01:04:55 +0000
commitef9a9cad9a9f076b3f2ab30c21c9cab3da8d1351 (patch)
treebb78ba47ac41b705ab2adcd586f23532f5833e72
parentfaa02fb3870577acbc508f12996612ed9ea0cdbe (diff)
downloadchrome-ec-ef9a9cad9a9f076b3f2ab30c21c9cab3da8d1351.tar.gz
Fixed two i8042 bugs. (manually cherry-pick)
1. The buffer for host i8042 command is too small so that a command is dropped (buffer full) in some cases. Enlarging it can solve bug. 2. The keystrokes are queued in buffer so that kernel driver cannot get stable CTR value. We workaround this by disabling the keystroke and clearing buffer when keyboard is disabled. BUG=chrome-os-partner:20758 BRANCH=falco,link TEST=Verified on link. Repeatedly press Ctrl + U during booting. The keyboard is working after boot. Original-Change-Id: I7d8daef8d815b8e4d08df6f6a26ab2a471e5b150 Reviewed-on: https://gerrit.chromium.org/gerrit/62986 (cherry picked from commit a1699727a83758defb2e80deab59d34a18bfe581) Change-Id: Ie8aea3be491efb28b3a3ba0d0db30bea6095d662 Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/179405 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--common/i8042.c14
-rw-r--r--common/keyboard.c29
2 files changed, 30 insertions, 13 deletions
diff --git a/common/i8042.c b/common/i8042.c
index 5c3b1bbf06..e474bdd3ac 100644
--- a/common/i8042.c
+++ b/common/i8042.c
@@ -46,8 +46,18 @@ struct host_byte {
uint8_t byte;
};
-/* 4 is big enough for all i8042 commands */
-static uint8_t from_host_buffer[4 * sizeof(struct host_byte)];
+
+/*
+ * we see from kernel is:
+ *
+ * d1 -> i8042 (command) # enable A20 in i8042_platform_init() of
+ * df -> i8042 (parameter) # serio/i8042-x86ia64io.h file.
+ * ff -> i8042 (command)
+ * 20 -> i8042 (command) # read CTR
+ *
+ * Hence, 5 (actually 4 plus one spare) is large enough, but use 8 for safety.
+ */
+static uint8_t from_host_buffer[8 * sizeof(struct host_byte)];
static struct queue from_host = {
.buf_bytes = sizeof(from_host_buffer),
.unit_bytes = sizeof(struct host_byte),
diff --git a/common/keyboard.c b/common/keyboard.c
index 00e423afaf..c65d3679be 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -307,6 +307,15 @@ void keyboard_state_changed(int row, int col, int is_pressed)
}
}
+static void keystroke_enable(int enable)
+{
+ if (!keystroke_enabled && enable)
+ CPRINTF("[%T KS enable]\n");
+ else if (keystroke_enabled && !enable)
+ CPRINTF("[%T KS disable]\n");
+
+ keystroke_enabled = enable;
+}
static void keyboard_enable(int enable)
{
@@ -316,21 +325,19 @@ static void keyboard_enable(int enable)
CPRINTF("[%T KB disable]\n");
reset_rate_and_delay();
typematic_len = 0; /* stop typematic */
+
+ /* Disable keystroke as well in case the BIOS doesn't
+ * disable keystroke where repeated strokes are queued
+ * before kernel initializes keyboard. Hence the kernel
+ * is unable to get stable CTR read (get key codes
+ * instead).
+ */
+ keystroke_enable(0);
+ keyboard_clear_underlying_buffer();
}
keyboard_enabled = enable;
}
-static void keystroke_enable(int enable)
-{
- if (!keystroke_enabled && enable)
- CPRINTF("[%T KS enable]\n");
- else if (keystroke_enabled && !enable)
- CPRINTF("[%T KS disable]\n");
-
- keystroke_enabled = enable;
-}
-
-
static uint8_t read_ctl_ram(uint8_t addr)
{
if (addr < ARRAY_SIZE(controller_ram))