git: cba5d7ab32fd - main - atkbd: Fix first keystroke force reset
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 May 2025 19:43:03 UTC
The branch main has been updated by emaste:
URL: https://cgit.FreeBSD.org/src/commit/?id=cba5d7ab32fd0b4e9c4312cc967baf137377f812
commit cba5d7ab32fd0b4e9c4312cc967baf137377f812
Author: SHENGYI HUNG <aokblast@FreeBSD.org>
AuthorDate: 2025-05-24 02:31:18 +0000
Commit: Ed Maste <emaste@FreeBSD.org>
CommitDate: 2025-05-28 19:42:44 +0000
atkbd: Fix first keystroke force reset
Some i8042 falsely return KBD_ACK for ECHO command which cuase the
keyboard echo test failed.
Without passing echo test, the keyboard is considered as unconfigured.
Though it is an incorrect behavior, we still regard it as a
correct to prevent the force reset (a step for configure a keyboard)
of whole keyboard when the first key interrupt reached.
Co-Authored-By: Aymeric Wibo <obiwac@freebsd.org>
Reviewed By: wulf, obiwac, emaste
Sponsored By: FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D50498
---
sys/dev/atkbdc/atkbd.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/sys/dev/atkbdc/atkbd.c b/sys/dev/atkbdc/atkbd.c
index 403afcd6c2e2..e046b59803b0 100644
--- a/sys/dev/atkbdc/atkbd.c
+++ b/sys/dev/atkbdc/atkbd.c
@@ -1249,6 +1249,7 @@ setup_kbd_port(KBDC kbdc, int port, int intr)
static int
get_kbd_echo(KBDC kbdc)
{
+ int data;
/* enable the keyboard port, but disable the keyboard intr. */
if (setup_kbd_port(kbdc, TRUE, FALSE))
/* CONTROLLER ERROR: there is very little we can do... */
@@ -1256,7 +1257,18 @@ get_kbd_echo(KBDC kbdc)
/* see if something is present */
write_kbd_command(kbdc, KBDC_ECHO);
- if (read_kbd_data(kbdc) != KBD_ECHO) {
+ data = read_kbd_data(kbdc);
+
+ /*
+ * Some i8042 falsely return KBD_ACK for ECHO comamnd.
+ * Thought it is not a correct behavior for AT keyboard, we accept
+ * and consume it to prevent resetting the whole keyboard after the
+ * first interrupt.
+ */
+ if (data == KBD_ACK)
+ data = read_kbd_data(kbdc);
+
+ if (data != KBD_ECHO) {
empty_both_buffers(kbdc, 10);
test_controller(kbdc);
test_kbd_port(kbdc);