summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2013-07-23 18:02:46 +0800
committerChromeBot <chrome-bot@google.com>2013-07-23 17:37:51 -0700
commita1699727a83758defb2e80deab59d34a18bfe581 (patch)
treec9a563be8bb3d9270b86dfc98bb9d9493e182e2d
parentb702babbb7ae1c9c225e9937f4a7656d36151310 (diff)
downloadchrome-ec-a1699727a83758defb2e80deab59d34a18bfe581.tar.gz
Fixed two i8042 bugs.
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. Change-Id: I7d8daef8d815b8e4d08df6f6a26ab2a471e5b150 Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/62986 Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Commit-Queue: Duncan Laurie <dlaurie@chromium.org> Tested-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r--common/keyboard_8042.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/common/keyboard_8042.c b/common/keyboard_8042.c
index f45c178908..723b091c90 100644
--- a/common/keyboard_8042.c
+++ b/common/keyboard_8042.c
@@ -82,8 +82,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)];
+/*
+ * The buffer for i8042 command from host. So far the largest command
+ * 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),
@@ -419,6 +429,16 @@ 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)
{
if (!keyboard_enabled && enable) {
@@ -427,20 +447,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_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))