summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarthur.lin <arthur.lin@lcfc.corp-partner.google.com>2022-08-10 15:01:51 +0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-08-17 07:27:02 +0000
commit42b05e8e248bb283e0f8e8e672fd2a159df0041d (patch)
treed28c0feb68b655ea458d7c1080b5947c30cc3cc7
parent13ed57c472aa589858643e472ed635f77ff9f1e8 (diff)
downloadchrome-ec-42b05e8e248bb283e0f8e8e672fd2a159df0041d.tar.gz
keyboard_8042: fix typematic scan code will be inserted issue
When race condition happened between send typematic scan code and release scan code, ignore send typematic scan code to queue because there is no key pressed at this moment. BUG=b:240309969 BRANCH=none TEST=make buildall -j Signed-off-by: arthur.lin <arthur.lin@lcfc.corp-partner.google.com> Change-Id: Iee4fab87e6769d8ff0503f140505090a6fb87d7d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3823778 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r--common/keyboard_8042.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/common/keyboard_8042.c b/common/keyboard_8042.c
index b1282ced91..0c7041937f 100644
--- a/common/keyboard_8042.c
+++ b/common/keyboard_8042.c
@@ -267,7 +267,8 @@ static void aux_enable_irq(int enable)
* @param to_host Data to send
* @param chan Channel to send data on
*/
-static void i8042_send_to_host(int len, const uint8_t *bytes, uint8_t chan)
+static void i8042_send_to_host(int len, const uint8_t *bytes, uint8_t chan,
+ int is_typematic)
{
int i;
struct data_byte data;
@@ -275,15 +276,20 @@ static void i8042_send_to_host(int len, const uint8_t *bytes, uint8_t chan)
/* Enqueue output data if there's space */
mutex_lock(&to_host_mutex);
- for (i = 0; i < len; i++)
- kblog_put(chan == CHAN_AUX ? 'a' : 's', bytes[i]);
-
- if (queue_space(&to_host) >= len) {
- kblog_put('t', to_host.state->tail);
- for (i = 0; i < len; i++) {
- data.chan = chan;
- data.byte = bytes[i];
- queue_add_unit(&to_host, &data);
+ if (is_typematic && !typematic_len) {
+ for (i = 0; i < len; i++)
+ kblog_put('r', bytes[i]);
+ } else {
+ for (i = 0; i < len; i++)
+ kblog_put(chan == CHAN_AUX ? 'a' : 's', bytes[i]);
+
+ if (queue_space(&to_host) >= len) {
+ kblog_put('t', to_host.state->tail);
+ for (i = 0; i < len; i++) {
+ data.chan = chan;
+ data.byte = bytes[i];
+ queue_add_unit(&to_host, &data);
+ }
}
}
mutex_unlock(&to_host_mutex);
@@ -453,7 +459,7 @@ void keyboard_state_changed(int row, int col, int is_pressed)
if (ret == EC_SUCCESS) {
ASSERT(len > 0);
if (keystroke_enabled)
- i8042_send_to_host(len, scan_code, CHAN_KBD);
+ i8042_send_to_host(len, scan_code, CHAN_KBD, 0);
}
if (is_pressed) {
@@ -875,7 +881,7 @@ static void i8042_handle_from_host(void)
ret_len = handle_keyboard_data(h.byte, output);
}
- i8042_send_to_host(ret_len, output, chan);
+ i8042_send_to_host(ret_len, output, chan, 0);
}
}
@@ -903,7 +909,7 @@ void keyboard_protocol_task(void *u)
if (keystroke_enabled)
i8042_send_to_host(typematic_len,
typematic_scan_code,
- CHAN_KBD);
+ CHAN_KBD, 1);
typematic_deadline.val =
t.val + typematic_inter_delay;
wait = typematic_inter_delay;
@@ -974,7 +980,7 @@ static void send_aux_data_to_host_deferred(void)
while (!queue_is_empty(&aux_to_host_queue)) {
queue_remove_unit(&aux_to_host_queue, &data);
if (aux_chan_enabled && IS_ENABLED(CONFIG_8042_AUX))
- i8042_send_to_host(1, &data, CHAN_AUX);
+ i8042_send_to_host(1, &data, CHAN_AUX, 0);
else
CPRINTS("AUX Callback ignored");
}
@@ -1032,7 +1038,7 @@ test_mockable void keyboard_update_button(enum keyboard_button_type button,
if (keystroke_enabled) {
CPRINTS5("KB UPDATE BTN");
- i8042_send_to_host(len, scan_code, CHAN_KBD);
+ i8042_send_to_host(len, scan_code, CHAN_KBD, 0);
task_wake(TASK_ID_KEYPROTO);
}
}