diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2023-08-13 21:54:03 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2023-08-13 21:54:03 +0000 |
commit | 3b436d19a3102c59581652341324dc311adf6d51 (patch) | |
tree | a6c5573a867b752c47cba4d73a6dc04544337b7b | |
parent | 6dcc1dc9608e156057d20730b30158371388a251 (diff) |
The 8042 emulation found on Chromebooks does not support the RESET command,
for no good reason, and causes pckbc not to attach. However, sending a `get
keyboard id' works, so this can be used as a second check to give those
fawlty pieces of hardware a chance to work.
Based on a diff submitted by, and tested by, Vladimir 'phcoder' Serbinenko.
-rw-r--r-- | sys/dev/pckbc/pckbd.c | 40 | ||||
-rw-r--r-- | sys/dev/pckbc/pckbdreg.h | 3 |
2 files changed, 35 insertions, 8 deletions
diff --git a/sys/dev/pckbc/pckbd.c b/sys/dev/pckbc/pckbd.c index 71ccf514758..50d523f395a 100644 --- a/sys/dev/pckbc/pckbd.c +++ b/sys/dev/pckbc/pckbd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pckbd.c,v 1.50 2023/07/25 10:00:44 miod Exp $ */ +/* $OpenBSD: pckbd.c,v 1.51 2023/08/13 21:54:02 miod Exp $ */ /* $NetBSD: pckbd.c,v 1.24 2000/06/05 22:20:57 sommerfeld Exp $ */ /*- @@ -344,7 +344,7 @@ pckbdprobe(struct device *parent, void *match, void *aux) { struct cfdata *cf = match; struct pckbc_attach_args *pa = aux; - u_char cmd[1], resp[1]; + u_char cmd[1], resp[2]; int res; /* @@ -363,10 +363,40 @@ pckbdprobe(struct device *parent, void *match, void *aux) /* Reset the keyboard. */ cmd[0] = KBC_RESET; res = pckbc_poll_cmd(pa->pa_tag, pa->pa_slot, cmd, 1, 1, resp, 1); - if (res) { + if (res != 0) { #ifdef DEBUG printf("pckbdprobe: reset error %d\n", res); #endif + } else if (resp[0] != KBR_RSTDONE) { +#ifdef DEBUG + printf("pckbdprobe: reset response 0x%x\n", resp[0]); +#endif + res = EINVAL; + } +#if defined(__i386__) || defined(__amd64__) + if (res) { + /* + * The 8042 emulation on Chromebooks fails the reset + * command but otherwise appears to work correctly. + * Try a "get ID" command to give it a second chance. + */ + cmd[0] = KBC_GETID; + res = pckbc_poll_cmd(pa->pa_tag, pa->pa_slot, + cmd, 1, 2, resp, 0); + if (res != 0) { +#ifdef DEBUG + printf("pckbdprobe: getid error %d\n", res); +#endif + } else if (resp[0] != 0xab || resp[1] != 0x83) { +#ifdef DEBUG + printf("pckbdprobe: unexpected id 0x%x/0x%x\n", + resp[0], resp[1]); +#endif + res = EINVAL; + } + } +#endif + if (res) { /* * There is probably no keyboard connected. * Let the probe succeed if the keyboard is used @@ -387,10 +417,6 @@ pckbdprobe(struct device *parent, void *match, void *aux) #endif return (pckbd_is_console(pa->pa_tag, pa->pa_slot) ? 1 : 0); } - if (resp[0] != KBR_RSTDONE) { - printf("pckbdprobe: reset response 0x%x\n", resp[0]); - return (0); - } /* * Some keyboards seem to leave a second ack byte after the reset. diff --git a/sys/dev/pckbc/pckbdreg.h b/sys/dev/pckbc/pckbdreg.h index 6848f48f817..7acd4eb1703 100644 --- a/sys/dev/pckbc/pckbdreg.h +++ b/sys/dev/pckbc/pckbdreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pckbdreg.h,v 1.2 2003/10/22 09:44:22 jmc Exp $ */ +/* $OpenBSD: pckbdreg.h,v 1.3 2023/08/13 21:54:02 miod Exp $ */ /* $NetBSD: pckbdreg.h,v 1.2 1998/04/07 13:43:16 hannken Exp $ */ /* @@ -12,6 +12,7 @@ #define KBC_DISABLE 0xF5 /* as per KBC_SETDEFAULT, but also disable key scanning */ #define KBC_ENABLE 0xF4 /* enable key scanning */ #define KBC_TYPEMATIC 0xF3 /* set typematic rate and delay */ +#define KBC_GETID 0xF2 /* get keyboard ID (not supported on AT kbd) */ #define KBC_SETTABLE 0xF0 /* set scancode translation table */ #define KBC_MODEIND 0xED /* set mode indicators (i.e. LEDs) */ #define KBC_ECHO 0xEE /* request an echo from the keyboard */ |