The branch main has been updated by emaste:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=cba5d7ab32fd0b4e9c4312cc967baf137377f812

commit cba5d7ab32fd0b4e9c4312cc967baf137377f812
Author:     SHENGYI HUNG <aokbl...@freebsd.org>
AuthorDate: 2025-05-24 02:31:18 +0000
Commit:     Ed Maste <ema...@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 <obi...@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);

Reply via email to