static int atkbd_reset(KBDC kbdc, int flags, int c) { /* reset keyboard hardware */ if (!(flags & KB_CONF_NO_RESET) && !reset_kbd(kbdc)) { /* * KEYBOARD ERROR * Keyboard reset may fail either because the keyboard * doen't exist, or because the keyboard doesn't pass * the self-test, or the keyboard controller on the * motherboard and the keyboard somehow fail to shake hands. * It is just possible, particularly in the last case, * that the keyboard controller may be left in a hung state. * test_controller() and test_kbd_port() appear to bring * the keyboard controller back (I don't know why and how, * though.) */ empty_both_buffers(kbdc, 10); test_controller(kbdc); test_kbd_port(kbdc); /* * We could disable the keyboard port and interrupt... but, * the keyboard may still exist (see above). */ set_controller_command_byte(kbdc, ALLOW_DISABLE_KBD(kbdc) ? 0xff : KBD_KBD_CONTROL_BITS, c); if (bootverbose) printf("atkbd: failed to reset the keyboard.\n"); return (EIO); } return (0); }
static int get_kbd_echo(KBDC kbdc) { /* 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... */ return ENXIO; /* see if something is present */ write_kbd_command(kbdc, KBDC_ECHO); if (read_kbd_data(kbdc) != KBD_ECHO) { empty_both_buffers(kbdc, 10); test_controller(kbdc); test_kbd_port(kbdc); return ENXIO; } /* enable the keyboard port and intr. */ if (setup_kbd_port(kbdc, TRUE, TRUE)) { /* * CONTROLLER ERROR * This is serious; the keyboard intr is left disabled! */ return ENXIO; } return 0; }
static int probe_keyboard(KBDC kbdc, int flags) { /* * Don't try to print anything in this function. The low-level * console may not have been initialized yet... */ int err; int c; int m; if (!kbdc_lock(kbdc, TRUE)) { /* driver error? */ return ENXIO; } /* flush any noise in the buffer */ empty_both_buffers(kbdc, 10); /* save the current keyboard controller command byte */ m = kbdc_get_device_mask(kbdc) & ~KBD_KBD_CONTROL_BITS; c = get_controller_command_byte(kbdc); if (c == -1) { /* CONTROLLER ERROR */ kbdc_set_device_mask(kbdc, m); kbdc_lock(kbdc, FALSE); return ENXIO; } /* * The keyboard may have been screwed up by the boot block. * We may just be able to recover from error by testing the controller * and the keyboard port. The controller command byte needs to be * saved before this recovery operation, as some controllers seem * to set the command byte to particular values. */ test_controller(kbdc); test_kbd_port(kbdc); err = get_kbd_echo(kbdc); if (err == 0) { kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS); } else { if (c != -1) /* try to restore the command byte as before */ set_controller_command_byte(kbdc, 0xff, c); kbdc_set_device_mask(kbdc, m); } kbdc_lock(kbdc, FALSE); return err; }
/* test the interface to the device */ static int atkbd_test_if(keyboard_t *kbd) { int error; error = 0; empty_both_buffers(((atkbd_state_t *)kbd->kb_data)->kbdc, 10); crit_enter(); if (!test_controller(((atkbd_state_t *)kbd->kb_data)->kbdc)) error = EIO; else if (test_kbd_port(((atkbd_state_t *)kbd->kb_data)->kbdc) != 0) error = EIO; crit_exit(); return error; }
/* test the interface to the device */ static int atkbd_test_if(keyboard_t *kbd) { int error; int s; error = 0; empty_both_buffers(((atkbd_state_t *)kbd->kb_data)->kbdc, 10); s = spltty(); if (!test_controller(((atkbd_state_t *)kbd->kb_data)->kbdc)) error = EIO; else if (test_kbd_port(((atkbd_state_t *)kbd->kb_data)->kbdc) != 0) error = EIO; splx(s); return error; }
static int get_kbd_id(KBDC kbdc) { int id1, id2; empty_both_buffers(kbdc, 10); id1 = id2 = -1; if (send_kbd_command(kbdc, KBDC_SEND_DEV_ID) != KBD_ACK) return -1; DELAY(10000); /* 10 msec delay */ id1 = read_kbd_data(kbdc); if (id1 != -1) id2 = read_kbd_data(kbdc); if ((id1 == -1) || (id2 == -1)) { empty_both_buffers(kbdc, 10); test_controller(kbdc); test_kbd_port(kbdc); return -1; } return ((id2 << 8) | id1); }
int test_if_code(int lognum) { int ec = true; int retval = true; uint8 op = 0; uint8 not_test = false; uint8 or_test = false; uint16 last_ip = ip; uint8 p[16] = { 0 }; while (retval && !game.quit_prog_now) { if (debug_.enabled && (debug_.logic0 || lognum)) debug_console(lognum, lTEST_MODE, NULL); last_ip = ip; op = *(code + ip++); memmove(p, (code + ip), 16); switch (op) { case 0xFF: /* END IF, TEST true */ goto end_test; case 0xFD: not_test = !not_test; continue; case 0xFC: /* OR */ /* if or_test is ON and we hit 0xFC, end of OR, then * or is STILL false so break. */ if (or_test) { ec = false; retval = false; goto end_test; } or_test = true; continue; case 0x00: /* return true? */ goto end_test; case 0x01: ec = test_equal(p[0], p[1]); if (p[0] == 11) timer_hack++; break; case 0x02: ec = test_equal(p[0], getvar(p[1])); if (p[0] == 11 || p[1] == 11) timer_hack++; break; case 0x03: ec = test_less(p[0], p[1]); if (p[0] == 11) timer_hack++; break; case 0x04: ec = test_less(p[0], getvar(p[1])); if (p[0] == 11 || p[1] == 11) timer_hack++; break; case 0x05: ec = test_greater(p[0], p[1]); if (p[0] == 11) timer_hack++; break; case 0x06: ec = test_greater(p[0], getvar(p[1])); if (p[0] == 11 || p[1] == 11) timer_hack++; break; case 0x07: ec = test_isset(p[0]); break; case 0x08: ec = test_isset(getvar(p[0])); break; case 0x09: ec = test_has(p[0]); break; case 0x0A: ec = test_obj_in_room(p[0], p[1]); break; case 0x0B: ec = test_posn(p[0], p[1], p[2], p[3], p[4]); break; case 0x0C: ec = test_controller(p[0]); break; case 0x0D: ec = test_keypressed(); break; case 0x0E: ec = test_said(p[0], (uint8 *) code + (ip + 1)); ip = last_ip; ip++; /* skip opcode */ ip += p[0] * 2; /* skip num_words * 2 */ ip++; /* skip num_words opcode */ break; case 0x0F: debugC(7, kDebugLevelScripts, "comparing [%s], [%s]", game.strings[p[0]], game.strings[p[1]]); ec = test_compare_strings(p[0], p[1]); break; case 0x10: ec = test_obj_in_box(p[0], p[1], p[2], p[3], p[4]); break; case 0x11: ec = test_obj_centre(p[0], p[1], p[2], p[3], p[4]); break; case 0x12: ec = test_obj_right(p[0], p[1], p[2], p[3], p[4]); break; default: ec = false; goto end_test; } if (op <= 0x12) ip += logic_names_test[op].num_args; /* exchange ec value */ if (not_test) ec = !ec; /* not is only enabled for 1 test command */ not_test = false; if (or_test && ec) { /* a true inside an OR statement passes * ENTIRE statement scan for end of OR */ /* CM: test for opcode < 0xfc changed from 'op' to * '*(code+ip)', to avoid problem with the 0xfd (NOT) * opcode byte. Changed a bad ip += ... ip++ construct. * This should fix the crash with Larry's logic.0 code: * * if ((isset(4) || * !isset(2) || * v30 == 2 || * v30 == 1)) { * goto Label1; * } * * The bytecode is: * ff fc 07 04 fd 07 02 01 1e 02 01 1e 01 fc ff */ /* find end of OR */ while (*(code + ip) != 0xFC) { if (*(code + ip) == 0x0E) { /* said */ ip++; /* cover count + ^words */ ip += 1 + ((*(code + ip)) * 2); continue; } if (*(code + ip) < 0xFC) ip += logic_names_test[*(code + ip)].num_args; ip++; } ip++; or_test = false; retval = true; } else { retval = or_test ? retval || ec : retval && ec; } } end_test: /* if false, scan for end of IP? */ if (retval) ip += 2; else { ip = last_ip; while (*(code + ip) != 0xff) { if (*(code + ip) == 0x0e) { ip++; ip += (*(code + ip)) * 2 + 1; } else if (*(code + ip) < 0xfc) { ip += logic_names_test[*(code + ip)].num_args; ip++; } else { ip++; } } ip++; /* skip over 0xFF */ ip += READ_LE_UINT16(code + ip) + 2; } if (debug_.enabled && (debug_.logic0 || lognum)) debug_console(lognum, 0xFF, retval ? "=true" : "=false"); return retval; }
static int init_keyboard(KBDC kbdc, int *type, int flags) { int codeset; int id; int c; if (!kbdc_lock(kbdc, TRUE)) { /* driver error? */ return EIO; } /* temporarily block data transmission from the keyboard */ write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT); /* save the current controller command byte */ empty_both_buffers(kbdc, 200); c = get_controller_command_byte(kbdc); if (c == -1) { /* CONTROLLER ERROR */ kbdc_lock(kbdc, FALSE); printf("atkbd: unable to get the current command byte value.\n"); return EIO; } if (bootverbose) printf("atkbd: the current kbd controller command byte %04x\n", c); #if 0 /* override the keyboard lock switch */ c |= KBD_OVERRIDE_KBD_LOCK; #endif /* 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... */ printf("atkbd: unable to set the command byte.\n"); kbdc_lock(kbdc, FALSE); return EIO; } /* * Check if we have an XT keyboard before we attempt to reset it. * The procedure assumes that the keyboard and the controller have * been set up properly by BIOS and have not been messed up * during the boot process. */ codeset = -1; if (flags & KB_CONF_ALT_SCANCODESET) /* the user says there is a XT keyboard */ codeset = 1; #ifdef KBD_DETECT_XT_KEYBOARD else if ((c & KBD_TRANSLATION) == 0) { /* SET_SCANCODE_SET is not always supported; ignore error */ if (send_kbd_command_and_data(kbdc, KBDC_SET_SCANCODE_SET, 0) == KBD_ACK) codeset = read_kbd_data(kbdc); } if (bootverbose) printf("atkbd: scancode set %d\n", codeset); #endif /* KBD_DETECT_XT_KEYBOARD */ *type = KB_OTHER; id = get_kbd_id(kbdc); switch(id) { case 0x41ab: /* 101/102/... Enhanced */ case 0x83ab: /* ditto */ case 0x54ab: /* SpaceSaver */ case 0x84ab: /* ditto */ #if 0 case 0x90ab: /* 'G' */ case 0x91ab: /* 'P' */ case 0x92ab: /* 'A' */ #endif *type = KB_101; break; case -1: /* AT 84 keyboard doesn't return ID */ *type = KB_84; break; default: break; } if (bootverbose) printf("atkbd: keyboard ID 0x%x (%d)\n", id, *type); /* reset keyboard hardware */ if (!(flags & KB_CONF_NO_RESET) && !reset_kbd(kbdc)) { /* * KEYBOARD ERROR * Keyboard reset may fail either because the keyboard * doen't exist, or because the keyboard doesn't pass * the self-test, or the keyboard controller on the * motherboard and the keyboard somehow fail to shake hands. * It is just possible, particularly in the last case, * that the keyboard controller may be left in a hung state. * test_controller() and test_kbd_port() appear to bring * the keyboard controller back (I don't know why and how, * though.) */ empty_both_buffers(kbdc, 10); test_controller(kbdc); test_kbd_port(kbdc); /* * We could disable the keyboard port and interrupt... but, * the keyboard may still exist (see above). */ set_controller_command_byte(kbdc, 0xff, c); kbdc_lock(kbdc, FALSE); if (bootverbose) printf("atkbd: failed to reset the keyboard.\n"); return EIO; } /* * Allow us to set the XT_KEYBD flag so that keyboards * such as those on the IBM ThinkPad laptop computers can be used * with the standard console driver. */ if (codeset == 1) { if (send_kbd_command_and_data(kbdc, KBDC_SET_SCANCODE_SET, codeset) == KBD_ACK) { /* XT kbd doesn't need scan code translation */ c &= ~KBD_TRANSLATION; } else { /* * KEYBOARD ERROR * The XT kbd isn't usable unless the proper scan * code set is selected. */ set_controller_command_byte(kbdc, 0xff, c); kbdc_lock(kbdc, FALSE); printf("atkbd: unable to set the XT keyboard mode.\n"); return EIO; } } #if defined(__sparc64__) if (send_kbd_command_and_data( kbdc, KBDC_SET_SCANCODE_SET, 2) != KBD_ACK) { printf("atkbd: can't set translation.\n"); } c |= KBD_TRANSLATION; #endif /* enable the keyboard port and intr. */ if (!set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK, (c & (KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK)) | KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) { /* * CONTROLLER ERROR * This is serious; we are left with the disabled * keyboard intr. */ set_controller_command_byte(kbdc, 0xff, c); kbdc_lock(kbdc, FALSE); printf("atkbd: unable to enable the keyboard port and intr.\n"); return EIO; } kbdc_lock(kbdc, FALSE); return 0; }
static int probe_keyboard(KBDC kbdc, int flags) { /* * Don't try to print anything in this function. The low-level * console may not have been initialized yet... */ int err; int c; int m; if (!kbdc_lock(kbdc, TRUE)) { /* driver error? */ return ENXIO; } /* temporarily block data transmission from the keyboard */ write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT); /* flush any noise in the buffer */ empty_both_buffers(kbdc, 100); /* save the current keyboard controller command byte */ m = kbdc_get_device_mask(kbdc) & ~KBD_KBD_CONTROL_BITS; c = get_controller_command_byte(kbdc); if (c == -1) { /* CONTROLLER ERROR */ kbdc_set_device_mask(kbdc, m); kbdc_lock(kbdc, FALSE); return ENXIO; } /* * The keyboard may have been screwed up by the boot block. * We may just be able to recover from error by testing the controller * and the keyboard port. The controller command byte needs to be * saved before this recovery operation, as some controllers seem * to set the command byte to particular values. */ test_controller(kbdc); if (!(flags & KB_CONF_NO_PROBE_TEST)) test_kbd_port(kbdc); err = get_kbd_echo(kbdc); /* * Even if the keyboard doesn't seem to be present (err != 0), * we shall enable the keyboard port and interrupt so that * the driver will be operable when the keyboard is attached * to the system later. It is NOT recommended to hot-plug * the AT keyboard, but many people do so... */ kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS); setup_kbd_port(kbdc, TRUE, TRUE); #if 0 if (err == 0) { kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS); } else { /* try to restore the command byte as before */ set_controller_command_byte(kbdc, 0xff, c); kbdc_set_device_mask(kbdc, m); } #endif kbdc_lock(kbdc, FALSE); return err; }
static int proc_args(int argc, char *argv[]) { unsigned short mode, delay, x, y, size, initial_x, initial_y, final_x, final_y, horizontal, time; unsigned long color; short distance; if (strncmp(argv[1], "init", 4) == 0) { if (argc != 4) { printf("wrong no of arguments for test_init()\n"); return 1; } if ((mode = (unsigned short) parse_long(argv[2], 16)) == LONG_MAX) return 1; if ((delay = (unsigned short) parse_long(argv[3], 10)) == LONG_MAX) return 1; printf("test_init(0x%x, %d)\n", mode, delay); test_init(mode, delay); return 0; } else if (strncmp(argv[1], "square", 6) == 0) { if (argc != 6) { printf("wrong no of arguments for test_square()\n"); return 1; } if ((x = (unsigned short) parse_long(argv[2], 10)) == LONG_MAX) return 1; if ((y = (unsigned short) parse_long(argv[3], 10)) == LONG_MAX) return 1; if ((size = (unsigned short) parse_long(argv[4], 10)) == LONG_MAX) return 1; if ((color = (unsigned long) parse_long(argv[5], 10)) == LONG_MAX) return 1; printf("test_square(%d, %d, %d, %d)\n", x, y, size, color); return test_square(x, y, size, color); } else if (strncmp(argv[1], "line", 4) == 0) { if (argc != 7) { printf("wrong no of arguments for test_line()\n"); return 1; } if ((initial_x = (unsigned short) parse_long(argv[2], 10)) == LONG_MAX) return 1; if ((initial_y = (unsigned short) parse_long(argv[3], 10)) == LONG_MAX) return 1; if ((final_x = (unsigned short) parse_long(argv[4], 10)) == LONG_MAX) return 1; if ((final_y = (unsigned short) parse_long(argv[5], 10)) == LONG_MAX) return 1; if ((color = (unsigned long) parse_long(argv[6], 10)) == LONG_MAX) return 1; printf("test_linee(%d, %d, %d, %d, %d)\n", initial_x, initial_y, final_x, final_y, color); return test_line(initial_x, initial_y, final_x, final_y, color); } else if (strncmp(argv[1], "xpm", 3) == 0) { if (argc != 5) { printf("wrong no of arguments for test_xpm()\n"); return 1; } if ((initial_x = (unsigned short) parse_long(argv[2], 10)) == LONG_MAX) return 1; if ((initial_y = (unsigned short) parse_long(argv[3], 10)) == LONG_MAX) return 1; if (strncmp(argv[4], "pic1", 4) == 0) { printf("test_xpm(%d, %d, %s)\n", initial_x, initial_y, "pic1"); return test_xpm(initial_x, initial_y, pic1); } else if (strncmp(argv[4], "pic2", 4) == 0) { printf("test_xpm(%d, %d, %s)\n", initial_x, initial_y, "pic2"); return test_xpm(initial_x, initial_y, pic2); } else if (strncmp(argv[4], "cross", 5) == 0) { printf("test_xpm(%d, %d, %s)\n", initial_x, initial_y, "cross"); return test_xpm(initial_x, initial_y, cross); } else if (strncmp(argv[4], "pic3", 4) == 0) { printf("test_xpm(%d, %d, %s)\n", initial_x, initial_y, "pic3"); return test_xpm(initial_x, initial_y, pic3); } else if (strncmp(argv[4], "penguin", 7) == 0) { printf("test_xpm(%d, %d, %s)\n", initial_x, initial_y, "penguin"); return test_xpm(initial_x, initial_y, penguin); } } else if (strncmp(argv[1], "move", 4) == 0) { if (argc != 8) { printf("wrong no of arguments for test_move()\n"); return 1; } if ((initial_x = (unsigned short) parse_long(argv[2], 10)) == LONG_MAX) return 1; if ((initial_y = (unsigned short) parse_long(argv[3], 10)) == LONG_MAX) return 1; if ((horizontal = (unsigned short) parse_long(argv[5], 10)) == LONG_MAX) return 1; if ((distance = (short) parse_long(argv[6], 10)) == LONG_MAX) return 1; if ((time = (unsigned short) parse_long(argv[7], 10)) == LONG_MAX) return 1; if (strncmp(argv[4], "pic1", 4) == 0) { printf("test_move(%d, %d, %s, %d, %d, %d)\n", initial_x, initial_y, "pic1", horizontal, distance, time); return test_move(initial_x, initial_y, pic1, horizontal, distance, time); } else if (strncmp(argv[4], "pic2", 4) == 0) { printf("test_move(%d, %d, %s, %d, %d, %d)\n", initial_x, initial_y, "pic2", horizontal, distance, time); return test_move(initial_x, initial_y, pic2, horizontal, distance, time); } else if (strncmp(argv[4], "cross", 5) == 0) { printf("test_move(%d, %d, %s, %d, %d, %d)\n", initial_x, initial_y, "cross", horizontal, distance, time); return test_move(initial_x, initial_y, cross, horizontal, distance, time); } else if (strncmp(argv[4], "pic3", 4) == 0) { printf("test_move(%d, %d, %s, %d, %d, %d)\n", initial_x, initial_y, "pic3", horizontal, distance, time); return test_move(initial_x, initial_y, pic3, horizontal, distance, time); } else if (strncmp(argv[4], "penguin", 7) == 0) { printf("test_move(%d, %d, %s, %d, %d, %d)\n", initial_x, initial_y, "penguin", horizontal, distance, time); return test_move(initial_x, initial_y, penguin, horizontal, distance, time); } } else if(strncmp(argv[1], "controller", 10) == 0) { printf("test_controller()\n"); return test_controller(); } else { printf("non valid function \"%s\" to test\n", argv[1]); return 1; } }
static int init_keyboard(KBDC kbdc, int *type, int flags) { int codeset; int id; int c; int mux_version; int mux_mask; int mux_val; if (!kbdc_lock(kbdc, TRUE)) { /* driver error? */ return EIO; } /* * XXX block data transmission from the keyboard. This can cause * the keyboard to stop sending keystrokes even when re-enabled * under certain circumstances if not followed by a full reset. */ write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT); #if 0 if (atkbd_setmuxmode(kbdc, 1, &mux_version)) { kprintf("atkbd: no mux\n"); mux_version = -1; } else { kprintf("atkbd: mux present version %d\n", mux_version); } #else mux_version = -1; #endif /* save the current controller command byte */ empty_both_buffers(kbdc, 200); c = get_controller_command_byte(kbdc); if (c == -1) { /* CONTROLLER ERROR */ kbdc_lock(kbdc, FALSE); kprintf("atkbd: unable to get the current command byte value.\n"); return EIO; } if (bootverbose) kprintf("atkbd: the current kbd controller command byte %04x\n", c); #if 0 /* override the keyboard lock switch */ c |= KBD_OVERRIDE_KBD_LOCK; #endif /* 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... */ kprintf("atkbd: unable to set the command byte.\n"); kbdc_lock(kbdc, FALSE); return EIO; } /* default codeset */ codeset = -1; /* reset keyboard hardware */ if (!(flags & KB_CONF_NO_RESET) && !reset_kbd(kbdc)) { /* * KEYBOARD ERROR * Keyboard reset may fail either because the keyboard * doen't exist, or because the keyboard doesn't pass * the self-test, or the keyboard controller on the * motherboard and the keyboard somehow fail to shake hands. * It is just possible, particularly in the last case, * that the keyoard controller may be left in a hung state. * test_controller() and test_kbd_port() appear to bring * the keyboard controller back (I don't know why and how, * though.) */ empty_both_buffers(kbdc, 10); test_controller(kbdc); test_kbd_port(kbdc); /* * We could disable the keyboard port and interrupt... but, * the keyboard may still exist (see above). */ set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS, c); kbdc_lock(kbdc, FALSE); if (bootverbose) kprintf("atkbd: failed to reset the keyboard.\n"); return EIO; } /* * Check if we have an XT keyboard before we attempt to reset it. * The procedure assumes that the keyboard and the controller have * been set up properly by BIOS and have not been messed up * during the boot process. */ codeset = -1; if (flags & KB_CONF_ALT_SCANCODESET) /* the user says there is a XT keyboard */ codeset = 1; #ifdef KBD_DETECT_XT_KEYBOARD else if ((c & KBD_TRANSLATION) == 0) { /* SET_SCANCODE_SET is not always supported; ignore error */ if (send_kbd_command_and_data(kbdc, KBDC_SET_SCANCODE_SET, 0) == KBD_ACK) codeset = read_kbd_data(kbdc); } #endif /* KBD_DETECT_XT_KEYBOARD */ if (bootverbose) kprintf("atkbd: scancode set %d\n", codeset); /* * Get the keyboard id. */ *type = KB_OTHER; id = get_kbd_id(kbdc, ATKBD_CMD_GETID); switch(id) { case 0x41ab: /* 101/102/... Enhanced */ case 0x83ab: /* ditto */ case 0x54ab: /* SpaceSaver */ case 0x84ab: /* ditto */ #if 0 case 0x90ab: /* 'G' */ case 0x91ab: /* 'P' */ case 0x92ab: /* 'A' */ #endif *type = KB_101; break; case -1: /* AT 84 keyboard doesn't return ID */ *type = KB_84; break; default: break; } if (bootverbose) kprintf("atkbd: keyboard ID 0x%x (%d)\n", id, *type); /* * Allow us to set the XT_KEYBD flag in UserConfig so that keyboards * such as those on the IBM ThinkPad laptop computers can be used * with the standard console driver. */ if (codeset == 1) { if (send_kbd_command_and_data(kbdc, KBDC_SET_SCANCODE_SET, codeset) == KBD_ACK) { /* XT kbd doesn't need scan code translation */ c &= ~KBD_TRANSLATION; } else { /* * KEYBOARD ERROR * The XT kbd isn't usable unless the proper scan * code set is selected. */ set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS, c); kbdc_lock(kbdc, FALSE); kprintf("atkbd: unable to set the XT keyboard mode.\n"); return EIO; } } #if 0 if (send_kbd_command_and_data(kbdc, ATKBD_CMD_EX_ENABLE, 0x71) != KBD_ACK) kprintf("atkbd: can't CMD_EX_ENABLE\n"); if (send_kbd_command(kbdc, ATKBD_CMD_SETALL_MB) != KBD_ACK) kprintf("atkbd: can't SETALL_MB\n"); if (send_kbd_command(kbdc, ATKBD_CMD_SETALL_MBR) != KBD_ACK) kprintf("atkbd: can't SETALL_MBR\n"); #endif #if 0 if (send_kbd_command_and_data(kbdc, ATKBD_CMD_SSCANSET, 2) != KBD_ACK) kprintf("atkbd: can't SSCANSET\n"); if (send_kbd_command_and_data(kbdc, ATKBD_CMD_GSCANSET, 0) != KBD_ACK) kprintf("atkbd: can't SSCANSET\n"); else kprintf("atkbd: scanset %d\n", read_kbd_data(kbdc)); #endif #if 0 kprintf("atkbd: id %04x\n", get_kbd_id(kbdc, ATKBD_CMD_OK_GETID)); if (send_kbd_command_and_data(kbdc, ATKBD_CMD_SETLEDS, 0) != KBD_ACK) kprintf("atkbd: setleds failed\n"); if (send_kbd_command_and_data(kbdc, ATKBD_CMD_SETREP, 255) != KBD_ACK) kprintf("atkbd: setrep failed\n"); if (send_kbd_command(kbdc, ATKBD_CMD_RESEND) != KBD_ACK) kprintf("atkbd: resend failed\n"); #endif /* * Some keyboards require a SETLEDS command to be sent after * the reset command before they will send keystrokes to us * (Acer C720). */ if (send_kbd_command_and_data(kbdc, ATKBD_CMD_SETLEDS, 0) != KBD_ACK) kprintf("atkbd: setleds failed\n"); send_kbd_command(kbdc, ATKBD_CMD_ENABLE); #if 0 /* DEBUGGING */ { int retry; int c; kprintf("atkbd: waiting for keypress"); for (retry = 0; retry < 10; ++retry) { c = read_kbd_data_no_wait(kbdc); kprintf(" %d", c); tsleep(&c, 0, "wait", hz); } kprintf("\n"); } #endif if (mux_version == -1) { mux_mask = 0; mux_val = 0; } else { mux_mask = KBD_AUX_CONTROL_BITS; mux_val = 0; kprintf("atkbd: setaux for multiplexer\n"); } /* enable the keyboard port and intr. */ if (!set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK | mux_mask, (c & (KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK)) | KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT | mux_val)) { /* * CONTROLLER ERROR * This is serious; we are left with the disabled * keyboard intr. */ set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK | mux_mask, c); kbdc_lock(kbdc, FALSE); kprintf("atkbd: unable to enable the keyboard port and intr.\n"); return EIO; } kbdc_lock(kbdc, FALSE); return 0; }
static int probe_keyboard(KBDC kbdc, int flags) { /* * Don't try to print anything in this function. The low-level * console may not have been initialized yet... */ int err; int c; if (!kbdc_lock(kbdc, TRUE)) { /* driver error? */ return ENXIO; } /* * XXX block data transmission from the keyboard. This can cause * the keyboard to stop sending keystrokes even when re-enabled * under certain circumstances if not followed by a full reset. */ write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT); /* flush any noise in the buffer */ empty_both_buffers(kbdc, 100); /* save the current keyboard controller command byte */ c = get_controller_command_byte(kbdc); if (c == -1) { /* CONTROLLER ERROR */ kbdc_lock(kbdc, FALSE); return ENXIO; } /* * The keyboard may have been screwed up by the boot block. * We may just be able to recover from error by testing the controller * and the keyboard port. The controller command byte needs to be * saved before this recovery operation, as some controllers seem * to set the command byte to particular values. */ test_controller(kbdc); test_kbd_port(kbdc); err = get_kbd_echo(kbdc); /* * Even if the keyboard doesn't seem to be present (err != 0), * we shall enable the keyboard port and interrupt so that * the driver will be operable when the keyboard is attached * to the system later. It is NOT recommended to hot-plug * the AT keyboard, but many people do so... */ setup_kbd_port(kbdc, TRUE, TRUE); #if 0 if (err) { /* try to restore the command byte as before */ set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS, c); } #endif kbdc_lock(kbdc, FALSE); return err; }