this diff changes the way ps/2 and AT keyboards are handled in attempt to gain support for some quirky ones. this includes most laptops that have internally connected ps/2 keyboards.
if you want your keyboard to continue working for the 4.1 release, please test this change now and report back to me privately, off-list, whether your keyboard continues to work or not. include relevant details like what kind of keyboard it is and a dmesg. Index: dev/pckbc/pckbd.c =================================================================== RCS file: /cvs/src/sys/dev/pckbc/pckbd.c,v retrieving revision 1.8 diff -u -r1.8 pckbd.c --- dev/pckbc/pckbd.c 29 Dec 2005 12:31:29 -0000 1.8 +++ dev/pckbc/pckbd.c 10 Jan 2007 15:58:01 -0000 @@ -192,54 +192,75 @@ pckbc_tag_t kbctag; pckbc_slot_t kbcslot; { - u_char cmd[2]; - int res; + /* default to have the 8042 translate the keyboard with table 3 */ + int x = 3; - /* - * Some keyboard/8042 combinations do not seem to work if the keyboard - * is set to table 1; in fact, it would appear that some keyboards just - * ignore the command altogether. So by default, we use the AT scan - * codes and have the 8042 translate them. Unfortunately, this is - * known to not work on some PS/2 machines. We try desperately to deal - * with this by checking the (lack of a) translate bit in the 8042 and - * attempting to set the keyboard to XT mode. If this all fails, well, - * tough luck. - * - * XXX It would perhaps be a better choice to just use AT scan codes - * and not bother with this. - */ - if (pckbc_xt_translation(kbctag, kbcslot, 1)) { - /* The 8042 is translating for us; use AT codes. */ + if (!pckbc_xt_translation(kbctag, kbcslot, 1)) { +#ifdef DEBUG + printf("pckbd: enabling of translation failed\n"); +#endif + /* just set the basic XT table and hope it works */ + x = 1; + } + + /* keep falling back until we hit a table that looks usable */ + for (; x >= 1; x--) { + u_char cmd[2]; +#ifdef DEBUG + printf("pckbd: trying table %d\n", x); +#endif cmd[0] = KBC_SETTABLE; - cmd[1] = 2; - res = pckbc_poll_cmd(kbctag, kbcslot, cmd, 2, 0, 0, 0); - if (res) { + cmd[1] = x; + if (pckbc_poll_cmd(kbctag, kbcslot, cmd, 2, 0, 0, 0)) { u_char cmd[1]; #ifdef DEBUG - printf("pckbd: error setting scanset 2\n"); + printf("pckbd: table set of %d failed"); #endif - /* - * XXX at least one keyboard is reported to lock up - * if a "set table" is attempted, thus the "reset". - * XXX ignore errors, scanset 2 should be - * default anyway. - */ cmd[0] = KBC_RESET; (void)pckbc_poll_cmd(kbctag, kbcslot, cmd, 1, 1, 0, 1); pckbc_flush(kbctag, kbcslot); - res = 0; + + continue; } - } else { - /* Stupid 8042; set keyboard to XT codes. */ - cmd[0] = KBC_SETTABLE; - cmd[1] = 1; - res = pckbc_poll_cmd(kbctag, kbcslot, cmd, 2, 0, 0, 0); + + /* the 8042 took the table set request */ + + if (x == 3) { + /* however, not all that say they can go into table 3 + * actually work, so ask what table it's in now */ + + u_char cmd[1], resp[0]; + + cmd[0] = KBC_SETTABLE; + cmd[1] = 0; + if (pckbc_poll_cmd(kbctag, kbcslot, cmd, 2, 1, resp, 0)) { +#ifdef DEBUG + printf("pckbd: table 3 verification failed\n"); +#endif + /* query failed, let's just step down to table + * 2 to be safe */ + + continue; + } else if (resp[0] == 3) { +#ifdef DEBUG + printf("pckbd: settling on set 3\n"); +#endif + return (0); + } +#ifdef DEBUG + else + printf("pckbd: set %x != 3, trying 2\n", + resp[0]); +#endif + } else { #ifdef DEBUG - if (res) - printf("pckbd: error setting scanset 1\n"); + printf("pckbd: settling on set %d\n", x); #endif + return (0); + } } - return (res); + + return (1); } static int