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