head 1.46; access; symbols RELENG_5_5_0_RELEASE:1.43.2.1 RELENG_5_5:1.43.2.1.0.4 RELENG_5_5_BP:1.43.2.1 RELENG_5_4_0_RELEASE:1.43.2.1 RELENG_5_4:1.43.2.1.0.2 RELENG_5_4_BP:1.43.2.1 RELENG_4_11_0_RELEASE:1.25.2.5 RELENG_4_11:1.25.2.5.0.6 RELENG_4_11_BP:1.25.2.5 RELENG_5_3_0_RELEASE:1.43 RELENG_5_3:1.43.0.4 RELENG_5_3_BP:1.43 RELENG_5:1.43.0.2 RELENG_5_BP:1.43 RELENG_4_10_0_RELEASE:1.25.2.5 RELENG_4_10:1.25.2.5.0.4 RELENG_4_10_BP:1.25.2.5 RELENG_5_2_1_RELEASE:1.42 RELENG_5_2_0_RELEASE:1.42 RELENG_5_2:1.42.0.2 RELENG_5_2_BP:1.42 RELENG_4_9_0_RELEASE:1.25.2.5 RELENG_4_9:1.25.2.5.0.2 RELENG_4_9_BP:1.25.2.5 RELENG_5_1_0_RELEASE:1.38 RELENG_5_1:1.38.0.2 RELENG_5_1_BP:1.38 RELENG_4_8_0_RELEASE:1.25.2.4 RELENG_4_8:1.25.2.4.0.6 RELENG_4_8_BP:1.25.2.4 RELENG_5_0_0_RELEASE:1.35 RELENG_5_0:1.35.0.2 RELENG_5_0_BP:1.35 RELENG_4_7_0_RELEASE:1.25.2.4 RELENG_4_7:1.25.2.4.0.4 RELENG_4_7_BP:1.25.2.4 RELENG_4_6_2_RELEASE:1.25.2.4 RELENG_4_6_1_RELEASE:1.25.2.4 RELENG_4_6_0_RELEASE:1.25.2.4 RELENG_4_6:1.25.2.4.0.2 RELENG_4_6_BP:1.25.2.4 RELENG_4_5_0_RELEASE:1.25.2.3 RELENG_4_5:1.25.2.3.0.4 RELENG_4_5_BP:1.25.2.3 RELENG_4_4_0_RELEASE:1.25.2.3 RELENG_4_4:1.25.2.3.0.2 RELENG_4_4_BP:1.25.2.3 KSE_MILESTONE_2:1.32 KSE_PRE_MILESTONE_2:1.32 RELENG_4_3_0_RELEASE:1.25.2.2 RELENG_4_3:1.25.2.2.0.2 RELENG_4_3_BP:1.25.2.2 RELENG_4_2_0_RELEASE:1.25.2.2 RELENG_4_1_1_RELEASE:1.25.2.2 PRE_SMPNG:1.27 RELENG_4_1_0_RELEASE:1.25.2.2 RELENG_3_5_0_RELEASE:1.3.2.8 RELENG_4_0_0_RELEASE:1.25 RELENG_4:1.25.0.2 RELENG_4_BP:1.25 RELENG_3_4_0_RELEASE:1.3.2.6 RELENG_3_3_0_RELEASE:1.3.2.6 RELENG_3_2_PAO:1.3.2.2.0.2 RELENG_3_2_PAO_BP:1.3.2.2 RELENG_3_2_0_RELEASE:1.3.2.2 POST_VFS_BIO_NFS_PATCH:1.6 PRE_VFS_BIO_NFS_PATCH:1.6 POST_SMP_VMSHARE:1.6 PRE_SMP_VMSHARE:1.6 POST_NEWBUS:1.6 PRE_NEWBUS:1.5 RELENG_3_1_0_RELEASE:1.3.2.1 RELENG_3:1.3.0.2 RELENG_3_BP:1.3; locks; strict; comment @ * @; 1.46 date 2005.06.10.20.56.38; author marius; state dead; branches; next 1.45; 1.45 date 2005.02.26.18.55.53; author sam; state Exp; branches; next 1.44; 1.44 date 2004.12.15.23.00.47; author jhb; state Exp; branches; next 1.43; 1.43 date 2004.06.10.20.30.56; author jhb; state Exp; branches 1.43.2.1; next 1.42; 1.42 date 2003.10.07.09.21.59; author fjoe; state Exp; branches; next 1.41; 1.41 date 2003.08.24.17.49.15; author obrien; state Exp; branches; next 1.40; 1.40 date 2003.07.13.10.08.33; author simokawa; state Exp; branches; next 1.39; 1.39 date 2003.07.02.16.09.01; author jhb; state Exp; branches; next 1.38; 1.38 date 2003.04.30.12.57.38; author markm; state Exp; branches; next 1.37; 1.37 date 2003.04.29.13.35.59; author kan; state Exp; branches; next 1.36; 1.36 date 2003.02.05.14.03.55; author charnier; state Exp; branches; next 1.35; 1.35 date 2002.08.25.13.16.54; author charnier; state Exp; branches; next 1.34; 1.34 date 2002.04.09.11.18.37; author phk; state Exp; branches; next 1.33; 1.33 date 2002.04.08.19.19.10; author asmodai; state Exp; branches; next 1.32; 1.32 date 2001.07.20.13.05.56; author yokota; state Exp; branches; next 1.31; 1.31 date 2001.01.22.22.54.02; author dwmalone; state Exp; branches; next 1.30; 1.30 date 2000.12.08.21.49.46; author dwmalone; state Exp; branches; next 1.29; 1.29 date 2000.10.15.14.18.18; author phk; state Exp; branches; next 1.28; 1.28 date 2000.10.08.21.33.53; author phk; state Exp; branches; next 1.27; 1.27 date 2000.05.28.12.43.24; author ache; state Exp; branches; next 1.26; 1.26 date 2000.03.19.03.25.11; author yokota; state Exp; branches; next 1.25; 1.25 date 2000.03.11.07.44.10; author yokota; state Exp; branches 1.25.2.1; next 1.24; 1.24 date 2000.02.11.01.22.30; author yokota; state Exp; branches; next 1.23; 1.23 date 2000.01.29.15.08.51; author peter; state Exp; branches; next 1.22; 1.22 date 2000.01.20.13.32.53; author yokota; state Exp; branches; next 1.21; 1.21 date 2000.01.11.13.39.04; author yokota; state Exp; branches; next 1.20; 1.20 date 2000.01.10.08.52.32; author yokota; state Exp; branches; next 1.19; 1.19 date 2000.01.10.08.50.43; author yokota; state Exp; branches; next 1.18; 1.18 date 99.12.13.09.31.42; author yokota; state Exp; branches; next 1.17; 1.17 date 99.12.10.04.31.32; author yokota; state Exp; branches; next 1.16; 1.16 date 99.08.28.00.42.09; author peter; state Exp; branches; next 1.15; 1.15 date 99.08.23.20.58.30; author phk; state Exp; branches; next 1.14; 1.14 date 99.08.22.09.52.32; author yokota; state Exp; branches; next 1.13; 1.13 date 99.08.15.06.06.14; author yokota; state Exp; branches; next 1.12; 1.12 date 99.07.18.06.16.25; author yokota; state Exp; branches; next 1.11; 1.11 date 99.05.30.16.51.30; author phk; state Exp; branches; next 1.10; 1.10 date 99.05.20.09.49.33; author yokota; state Exp; branches; next 1.9; 1.9 date 99.05.18.11.05.58; author yokota; state Exp; branches; next 1.8; 1.8 date 99.05.09.05.00.19; author yokota; state Exp; branches; next 1.7; 1.7 date 99.05.09.04.59.24; author yokota; state Exp; branches; next 1.6; 1.6 date 99.04.16.21.21.55; author peter; state Exp; branches; next 1.5; 1.5 date 99.03.10.10.36.52; author yokota; state Exp; branches; next 1.4; 1.4 date 99.01.28.10.55.55; author yokota; state Exp; branches; next 1.3; 1.3 date 99.01.19.11.31.14; author yokota; state Exp; branches 1.3.2.1; next 1.2; 1.2 date 99.01.13.11.19.19; author yokota; state Exp; branches; next 1.1; 1.1 date 99.01.09.02.44.49; author yokota; state Exp; branches; next ; 1.43.2.1 date 2005.01.07.20.36.00; author jhb; state Exp; branches; next ; 1.25.2.1 date 2000.03.31.12.51.56; author yokota; state Exp; branches; next 1.25.2.2; 1.25.2.2 date 2000.05.28.12.48.22; author ache; state Exp; branches; next 1.25.2.3; 1.25.2.3 date 2001.07.30.16.46.43; author yokota; state Exp; branches; next 1.25.2.4; 1.25.2.4 date 2002.04.08.19.21.38; author asmodai; state Exp; branches; next 1.25.2.5; 1.25.2.5 date 2003.07.19.12.48.35; author simokawa; state Exp; branches; next 1.25.2.6; 1.25.2.6 date 2012.11.17.07.25.47; author svnexp; state Exp; branches; next ; 1.3.2.1 date 99.01.31.12.55.58; author yokota; state Exp; branches; next 1.3.2.2; 1.3.2.2 date 99.05.09.11.02.11; author yokota; state Exp; branches; next 1.3.2.3; 1.3.2.3 date 99.05.28.03.15.58; author yokota; state Exp; branches; next 1.3.2.4; 1.3.2.4 date 99.07.22.12.44.29; author yokota; state Exp; branches; next 1.3.2.5; 1.3.2.5 date 99.08.15.06.07.08; author yokota; state Exp; branches; next 1.3.2.6; 1.3.2.6 date 99.08.29.16.23.34; author peter; state Exp; branches; next 1.3.2.7; 1.3.2.7 date 2000.02.02.12.28.39; author yokota; state Exp; branches; next 1.3.2.8; 1.3.2.8 date 2000.02.02.13.03.22; author yokota; state Exp; branches; next ; desc @@ 1.46 log @- Hook up the new locations of the atkbdc(4), atkbd(4) and psm(4) source files after they were repo-copied to sys/dev/atkbdc. The sources of atkbdc(4) and its children were moved to the new location in preparation for adding an EBus front-end to atkbdc(4) for use on sparc64; i.e. in order to not further scatter them over the whole tree which would have been the result of adding atkbdc_ebus.c in e.g. sys/sparc64/ebus. Another reason for the repo-copies was that some of the sources were misfiled, e.g. sys/isa/atkbd_isa.c wasn't ISA-specific at all but for hanging atkbd(4) off of atkbdc(4) and was renamed to atkbd_atkbdc.c accordingly. Most of sys/isa/psm.c, i.e. expect for its PSMC PNP part, also isn't ISA-specific. - Separate the parts of atkbdc_isa.c which aren't actually ISA-specific but are shareable between different atkbdc(4) bus front-ends into atkbdc_subr.c (repo-copied from atkbdc_isa.c). While here use bus_generic_rl_alloc_resource() and bus_generic_rl_release_resource() respectively in atkbdc_isa.c instead of rolling own versions. - Add sparc64 MD bits to atkbdc(4) and atkbd(4) and an EBus front-end for atkbdc(4). PS/2 controllers and input devices are used on a couple of Sun OEM boards and occur on either the EBus or the ISA bus. Depending on the board it's either the only on-board mean to connect a keyboard and mouse or an alternative to either RS232 or USB devices. - Wrap the PSMC PNP part of psm.c in #ifdef DEV_ISA so it can be compiled without isa(4) (e.g. for EBus-only machines). This ISA-specific part isn't separated into its own source file, yet, as it requires more work than was feasible for 6.0 in order to do it in a clean way. Actually philip@@ is working on a rewrite of psm(4) so a more comprehensive clean-up and separation of hardware dependent and independent parts is expected to happen after 6.0. Tested on: i386, sparc64 (AX1105, AXe and AXi boards) Reviewed by: philip @ text @/*- * Copyright (c) 1999 Kazutaka YOKOTA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer as * the first lines of this file unmodified. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.45 2005/02/26 18:55:53 sam Exp $"); #include "opt_kbd.h" #include "opt_atkbd.h" #include #include #include #include #include #include #include #include #include #ifdef __i386__ #include #include #include #include #include #include #include #endif /* __i386__ */ #include #include #include #include #include static timeout_t atkbd_timeout; int atkbd_probe_unit(int unit, int ctlr, int irq, int flags) { keyboard_switch_t *sw; int args[2]; int error; sw = kbd_get_switch(ATKBD_DRIVER_NAME); if (sw == NULL) return ENXIO; args[0] = ctlr; args[1] = irq; error = (*sw->probe)(unit, args, flags); if (error) return error; return 0; } int atkbd_attach_unit(int unit, keyboard_t **kbd, int ctlr, int irq, int flags) { keyboard_switch_t *sw; int args[2]; int error; sw = kbd_get_switch(ATKBD_DRIVER_NAME); if (sw == NULL) return ENXIO; /* reset, initialize and enable the device */ args[0] = ctlr; args[1] = irq; *kbd = NULL; error = (*sw->probe)(unit, args, flags); if (error) return error; error = (*sw->init)(unit, kbd, args, flags); if (error) return error; (*sw->enable)(*kbd); #ifdef KBD_INSTALL_CDEV /* attach a virtual keyboard cdev */ error = kbd_attach(*kbd); if (error) return error; #endif /* * This is a kludge to compensate for lost keyboard interrupts. * A similar code used to be in syscons. See below. XXX */ atkbd_timeout(*kbd); if (bootverbose) (*sw->diag)(*kbd, bootverbose); return 0; } static void atkbd_timeout(void *arg) { keyboard_t *kbd; int s; /* * The original text of the following comments are extracted * from syscons.c (1.287) * * With release 2.1 of the Xaccel server, the keyboard is left * hanging pretty often. Apparently an interrupt from the * keyboard is lost, and I don't know why (yet). * This ugly hack calls the low-level interrupt routine if input * is ready for the keyboard and conveniently hides the problem. XXX * * Try removing anything stuck in the keyboard controller; whether * it's a keyboard scan code or mouse data. The low-level * interrupt routine doesn't read the mouse data directly, * but the keyboard controller driver will, as a side effect. */ /* * And here is bde's original comment about this: * * This is necessary to handle edge triggered interrupts - if we * returned when our IRQ is high due to unserviced input, then there * would be no more keyboard IRQs until the keyboard is reset by * external powers. * * The keyboard apparently unwedges the irq in most cases. */ s = spltty(); kbd = (keyboard_t *)arg; if ((*kbdsw[kbd->kb_index]->lock)(kbd, TRUE)) { /* * We have seen the lock flag is not set. Let's reset * the flag early, otherwise the LED update routine fails * which may want the lock during the interrupt routine. */ (*kbdsw[kbd->kb_index]->lock)(kbd, FALSE); if ((*kbdsw[kbd->kb_index]->check_char)(kbd)) (*kbdsw[kbd->kb_index]->intr)(kbd, NULL); } splx(s); timeout(atkbd_timeout, arg, hz/10); } /* LOW-LEVEL */ #define ATKBD_DEFAULT 0 typedef struct atkbd_state { KBDC kbdc; /* keyboard controller */ /* XXX: don't move this field; pcvt * expects `kbdc' to be the first * field in this structure. */ int ks_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */ int ks_flags; /* flags */ #define COMPOSE (1 << 0) int ks_polling; int ks_state; /* shift/lock key state */ int ks_accents; /* accent key index (> 0) */ u_int ks_composed_char; /* composed char code (> 0) */ u_char ks_prefix; /* AT scan code prefix */ } atkbd_state_t; /* keyboard driver declaration */ static int atkbd_configure(int flags); static kbd_probe_t atkbd_probe; static kbd_init_t atkbd_init; static kbd_term_t atkbd_term; static kbd_intr_t atkbd_intr; static kbd_test_if_t atkbd_test_if; static kbd_enable_t atkbd_enable; static kbd_disable_t atkbd_disable; static kbd_read_t atkbd_read; static kbd_check_t atkbd_check; static kbd_read_char_t atkbd_read_char; static kbd_check_char_t atkbd_check_char; static kbd_ioctl_t atkbd_ioctl; static kbd_lock_t atkbd_lock; static kbd_clear_state_t atkbd_clear_state; static kbd_get_state_t atkbd_get_state; static kbd_set_state_t atkbd_set_state; static kbd_poll_mode_t atkbd_poll; static keyboard_switch_t atkbdsw = { atkbd_probe, atkbd_init, atkbd_term, atkbd_intr, atkbd_test_if, atkbd_enable, atkbd_disable, atkbd_read, atkbd_check, atkbd_read_char, atkbd_check_char, atkbd_ioctl, atkbd_lock, atkbd_clear_state, atkbd_get_state, atkbd_set_state, genkbd_get_fkeystr, atkbd_poll, genkbd_diag, }; KEYBOARD_DRIVER(atkbd, atkbdsw, atkbd_configure); /* local functions */ static int get_typematic(keyboard_t *kbd); static int setup_kbd_port(KBDC kbdc, int port, int intr); static int get_kbd_echo(KBDC kbdc); static int probe_keyboard(KBDC kbdc, int flags); static int init_keyboard(KBDC kbdc, int *type, int flags); static int write_kbd(KBDC kbdc, int command, int data); static int get_kbd_id(KBDC kbdc); static int typematic(int delay, int rate); static int typematic_delay(int delay); static int typematic_rate(int rate); /* local variables */ /* the initial key map, accent map and fkey strings */ #ifdef ATKBD_DFLT_KEYMAP #define KBD_DFLT_KEYMAP #include "atkbdmap.h" #endif #include /* structures for the default keyboard */ static keyboard_t default_kbd; static atkbd_state_t default_kbd_state; static keymap_t default_keymap; static accentmap_t default_accentmap; static fkeytab_t default_fkeytab[NUM_FKEYS]; /* * The back door to the keyboard driver! * This function is called by the console driver, via the kbdio module, * to tickle keyboard drivers when the low-level console is being initialized. * Almost nothing in the kernel has been initialied yet. Try to probe * keyboards if possible. * NOTE: because of the way the low-level console is initialized, this routine * may be called more than once!! */ static int atkbd_configure(int flags) { keyboard_t *kbd; int arg[2]; int i; /* probe the keyboard controller */ atkbdc_configure(); /* if the driver is disabled, unregister the keyboard if any */ if (resource_disabled("atkbd", ATKBD_DEFAULT)) { i = kbd_find_keyboard(ATKBD_DRIVER_NAME, ATKBD_DEFAULT); if (i >= 0) { kbd = kbd_get_keyboard(i); kbd_unregister(kbd); kbd->kb_flags &= ~KB_REGISTERED; } return 0; } /* XXX: a kludge to obtain the device configuration flags */ if (resource_int_value("atkbd", ATKBD_DEFAULT, "flags", &i) == 0) flags |= i; /* probe the default keyboard */ arg[0] = -1; arg[1] = -1; kbd = NULL; if (atkbd_probe(ATKBD_DEFAULT, arg, flags)) return 0; if (atkbd_init(ATKBD_DEFAULT, &kbd, arg, flags)) return 0; /* return the number of found keyboards */ return 1; } /* low-level functions */ /* detect a keyboard */ static int atkbd_probe(int unit, void *arg, int flags) { KBDC kbdc; int *data = (int *)arg; /* data[0]: controller, data[1]: irq */ /* XXX */ if (unit == ATKBD_DEFAULT) { if (KBD_IS_PROBED(&default_kbd)) return 0; } kbdc = atkbdc_open(data[0]); if (kbdc == NULL) return ENXIO; if (probe_keyboard(kbdc, flags)) { if (flags & KB_CONF_FAIL_IF_NO_KBD) return ENXIO; } return 0; } /* reset and initialize the device */ static int atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) { keyboard_t *kbd; atkbd_state_t *state; keymap_t *keymap; accentmap_t *accmap; fkeytab_t *fkeymap; int fkeymap_size; int delay[2]; int *data = (int *)arg; /* data[0]: controller, data[1]: irq */ int error, needfree; /* XXX */ if (unit == ATKBD_DEFAULT) { *kbdp = kbd = &default_kbd; if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd)) return 0; state = &default_kbd_state; keymap = &default_keymap; accmap = &default_accentmap; fkeymap = default_fkeytab; fkeymap_size = sizeof(default_fkeytab)/sizeof(default_fkeytab[0]); needfree = 0; } else if (*kbdp == NULL) { *kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT | M_ZERO); state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT | M_ZERO); /* NB: these will always be initialized 'cuz !KBD_IS_PROBED */ keymap = malloc(sizeof(key_map), M_DEVBUF, M_NOWAIT); accmap = malloc(sizeof(accent_map), M_DEVBUF, M_NOWAIT); fkeymap = malloc(sizeof(fkey_tab), M_DEVBUF, M_NOWAIT); fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]); needfree = 1; if ((kbd == NULL) || (state == NULL) || (keymap == NULL) || (accmap == NULL) || (fkeymap == NULL)) { error = ENOMEM; goto bad; } } else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) { return 0; } else { kbd = *kbdp; state = (atkbd_state_t *)kbd->kb_data; bzero(state, sizeof(*state)); keymap = kbd->kb_keymap; accmap = kbd->kb_accentmap; fkeymap = kbd->kb_fkeytab; fkeymap_size = kbd->kb_fkeytab_size; needfree = 0; } if (!KBD_IS_PROBED(kbd)) { state->kbdc = atkbdc_open(data[0]); if (state->kbdc == NULL) { error = ENXIO; goto bad; } kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags, 0, 0); bcopy(&key_map, keymap, sizeof(key_map)); bcopy(&accent_map, accmap, sizeof(accent_map)); bcopy(fkey_tab, fkeymap, imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab))); kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size); kbd->kb_data = (void *)state; if (probe_keyboard(state->kbdc, flags)) { /* shouldn't happen */ if (flags & KB_CONF_FAIL_IF_NO_KBD) { error = ENXIO; goto bad; } } else { KBD_FOUND_DEVICE(kbd); } atkbd_clear_state(kbd); state->ks_mode = K_XLATE; /* * FIXME: set the initial value for lock keys in ks_state * according to the BIOS data? */ KBD_PROBE_DONE(kbd); } if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) { kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY; if (KBD_HAS_DEVICE(kbd) && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config) && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) { kbd_unregister(kbd); error = ENXIO; goto bad; } atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state); get_typematic(kbd); delay[0] = kbd->kb_delay1; delay[1] = kbd->kb_delay2; atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); KBD_INIT_DONE(kbd); } if (!KBD_IS_CONFIGURED(kbd)) { if (kbd_register(kbd) < 0) { error = ENXIO; goto bad; } KBD_CONFIG_DONE(kbd); } return 0; bad: if (needfree) { if (state != NULL) free(state, M_DEVBUF); if (keymap != NULL) free(keymap, M_DEVBUF); if (accmap != NULL) free(accmap, M_DEVBUF); if (fkeymap != NULL) free(fkeymap, M_DEVBUF); if (kbd != NULL) { free(kbd, M_DEVBUF); *kbdp = NULL; /* insure ref doesn't leak to caller */ } } return error; } /* finish using this keyboard */ static int atkbd_term(keyboard_t *kbd) { kbd_unregister(kbd); return 0; } /* keyboard interrupt routine */ static int atkbd_intr(keyboard_t *kbd, void *arg) { atkbd_state_t *state; int delay[2]; int c; if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) { /* let the callback function to process the input */ (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT, kbd->kb_callback.kc_arg); } else { /* read and discard the input; no one is waiting for input */ do { c = atkbd_read_char(kbd, FALSE); } while (c != NOKEY); if (!KBD_HAS_DEVICE(kbd)) { /* * The keyboard was not detected before; * it must have been reconnected! */ state = (atkbd_state_t *)kbd->kb_data; init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config); atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state); get_typematic(kbd); delay[0] = kbd->kb_delay1; delay[1] = kbd->kb_delay2; atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); KBD_FOUND_DEVICE(kbd); } } return 0; } /* 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; } /* * Enable the access to the device; until this function is called, * the client cannot read from the keyboard. */ static int atkbd_enable(keyboard_t *kbd) { int s; s = spltty(); KBD_ACTIVATE(kbd); splx(s); return 0; } /* disallow the access to the device */ static int atkbd_disable(keyboard_t *kbd) { int s; s = spltty(); KBD_DEACTIVATE(kbd); splx(s); return 0; } /* read one byte from the keyboard if it's allowed */ static int atkbd_read(keyboard_t *kbd, int wait) { int c; if (wait) c = read_kbd_data(((atkbd_state_t *)kbd->kb_data)->kbdc); else c = read_kbd_data_no_wait(((atkbd_state_t *)kbd->kb_data)->kbdc); if (c != -1) ++kbd->kb_count; return (KBD_IS_ACTIVE(kbd) ? c : -1); } /* check if data is waiting */ static int atkbd_check(keyboard_t *kbd) { if (!KBD_IS_ACTIVE(kbd)) return FALSE; return kbdc_data_ready(((atkbd_state_t *)kbd->kb_data)->kbdc); } /* read char from the keyboard */ static u_int atkbd_read_char(keyboard_t *kbd, int wait) { atkbd_state_t *state; u_int action; int scancode; int keycode; state = (atkbd_state_t *)kbd->kb_data; next_code: /* do we have a composed char to return? */ if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) { action = state->ks_composed_char; state->ks_composed_char = 0; if (action > UCHAR_MAX) return ERRKEY; return action; } /* see if there is something in the keyboard port */ if (wait) { do { scancode = read_kbd_data(state->kbdc); } while (scancode == -1); } else { scancode = read_kbd_data_no_wait(state->kbdc); if (scancode == -1) return NOKEY; } ++kbd->kb_count; #if KBDIO_DEBUG >= 10 printf("atkbd_read_char(): scancode:0x%x\n", scancode); #endif /* return the byte as is for the K_RAW mode */ if (state->ks_mode == K_RAW) return scancode; /* translate the scan code into a keycode */ keycode = scancode & 0x7F; switch (state->ks_prefix) { case 0x00: /* normal scancode */ switch(scancode) { case 0xB8: /* left alt (compose key) released */ if (state->ks_flags & COMPOSE) { state->ks_flags &= ~COMPOSE; if (state->ks_composed_char > UCHAR_MAX) state->ks_composed_char = 0; } break; case 0x38: /* left alt (compose key) pressed */ if (!(state->ks_flags & COMPOSE)) { state->ks_flags |= COMPOSE; state->ks_composed_char = 0; } break; case 0xE0: case 0xE1: state->ks_prefix = scancode; goto next_code; } break; case 0xE0: /* 0xE0 prefix */ state->ks_prefix = 0; switch (keycode) { case 0x1C: /* right enter key */ keycode = 0x59; break; case 0x1D: /* right ctrl key */ keycode = 0x5A; break; case 0x35: /* keypad divide key */ keycode = 0x5B; break; case 0x37: /* print scrn key */ keycode = 0x5C; break; case 0x38: /* right alt key (alt gr) */ keycode = 0x5D; break; case 0x46: /* ctrl-pause/break on AT 101 (see below) */ keycode = 0x68; break; case 0x47: /* grey home key */ keycode = 0x5E; break; case 0x48: /* grey up arrow key */ keycode = 0x5F; break; case 0x49: /* grey page up key */ keycode = 0x60; break; case 0x4B: /* grey left arrow key */ keycode = 0x61; break; case 0x4D: /* grey right arrow key */ keycode = 0x62; break; case 0x4F: /* grey end key */ keycode = 0x63; break; case 0x50: /* grey down arrow key */ keycode = 0x64; break; case 0x51: /* grey page down key */ keycode = 0x65; break; case 0x52: /* grey insert key */ keycode = 0x66; break; case 0x53: /* grey delete key */ keycode = 0x67; break; /* the following 3 are only used on the MS "Natural" keyboard */ case 0x5b: /* left Window key */ keycode = 0x69; break; case 0x5c: /* right Window key */ keycode = 0x6a; break; case 0x5d: /* menu key */ keycode = 0x6b; break; case 0x5e: /* power key */ keycode = 0x6d; break; case 0x5f: /* sleep key */ keycode = 0x6e; break; case 0x63: /* wake key */ keycode = 0x6f; break; default: /* ignore everything else */ goto next_code; } break; case 0xE1: /* 0xE1 prefix */ /* * The pause/break key on the 101 keyboard produces: * E1-1D-45 E1-9D-C5 * Ctrl-pause/break produces: * E0-46 E0-C6 (See above.) */ state->ks_prefix = 0; if (keycode == 0x1D) state->ks_prefix = 0x1D; goto next_code; /* NOT REACHED */ case 0x1D: /* pause / break */ state->ks_prefix = 0; if (keycode != 0x45) goto next_code; keycode = 0x68; break; } if (kbd->kb_type == KB_84) { switch (keycode) { case 0x37: /* *(numpad)/print screen */ if (state->ks_flags & SHIFTS) keycode = 0x5c; /* print screen */ break; case 0x45: /* num lock/pause */ if (state->ks_flags & CTLS) keycode = 0x68; /* pause */ break; case 0x46: /* scroll lock/break */ if (state->ks_flags & CTLS) keycode = 0x6c; /* break */ break; } } else if (kbd->kb_type == KB_101) { switch (keycode) { case 0x5c: /* print screen */ if (state->ks_flags & ALTS) keycode = 0x54; /* sysrq */ break; case 0x68: /* pause/break */ if (state->ks_flags & CTLS) keycode = 0x6c; /* break */ break; } } /* return the key code in the K_CODE mode */ if (state->ks_mode == K_CODE) return (keycode | (scancode & 0x80)); /* compose a character code */ if (state->ks_flags & COMPOSE) { switch (keycode | (scancode & 0x80)) { /* key pressed, process it */ case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */ state->ks_composed_char *= 10; state->ks_composed_char += keycode - 0x40; if (state->ks_composed_char > UCHAR_MAX) return ERRKEY; goto next_code; case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */ state->ks_composed_char *= 10; state->ks_composed_char += keycode - 0x47; if (state->ks_composed_char > UCHAR_MAX) return ERRKEY; goto next_code; case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */ state->ks_composed_char *= 10; state->ks_composed_char += keycode - 0x4E; if (state->ks_composed_char > UCHAR_MAX) return ERRKEY; goto next_code; case 0x52: /* keypad 0 */ state->ks_composed_char *= 10; if (state->ks_composed_char > UCHAR_MAX) return ERRKEY; goto next_code; /* key released, no interest here */ case 0xC7: case 0xC8: case 0xC9: /* keypad 7,8,9 */ case 0xCB: case 0xCC: case 0xCD: /* keypad 4,5,6 */ case 0xCF: case 0xD0: case 0xD1: /* keypad 1,2,3 */ case 0xD2: /* keypad 0 */ goto next_code; case 0x38: /* left alt key */ break; default: if (state->ks_composed_char > 0) { state->ks_flags &= ~COMPOSE; state->ks_composed_char = 0; return ERRKEY; } break; } } /* keycode to key action */ action = genkbd_keyaction(kbd, keycode, scancode & 0x80, &state->ks_state, &state->ks_accents); if (action == NOKEY) goto next_code; else return action; } /* check if char is waiting */ static int atkbd_check_char(keyboard_t *kbd) { atkbd_state_t *state; if (!KBD_IS_ACTIVE(kbd)) return FALSE; state = (atkbd_state_t *)kbd->kb_data; if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) return TRUE; return kbdc_data_ready(state->kbdc); } /* some useful control functions */ static int atkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) { /* trasnlate LED_XXX bits into the device specific bits */ static u_char ledmap[8] = { 0, 4, 2, 6, 1, 5, 3, 7, }; atkbd_state_t *state = kbd->kb_data; int error; int s; int i; s = spltty(); switch (cmd) { case KDGKBMODE: /* get keyboard mode */ *(int *)arg = state->ks_mode; break; case KDSKBMODE: /* set keyboard mode */ switch (*(int *)arg) { case K_XLATE: if (state->ks_mode != K_XLATE) { /* make lock key state and LED state match */ state->ks_state &= ~LOCK_MASK; state->ks_state |= KBD_LED_VAL(kbd); } /* FALLTHROUGH */ case K_RAW: case K_CODE: if (state->ks_mode != *(int *)arg) { atkbd_clear_state(kbd); state->ks_mode = *(int *)arg; } break; default: splx(s); return EINVAL; } break; case KDGETLED: /* get keyboard LED */ *(int *)arg = KBD_LED_VAL(kbd); break; case KDSETLED: /* set keyboard LED */ /* NOTE: lock key state in ks_state won't be changed */ if (*(int *)arg & ~LOCK_MASK) { splx(s); return EINVAL; } i = *(int *)arg; /* replace CAPS LED with ALTGR LED for ALTGR keyboards */ if (state->ks_mode == K_XLATE && kbd->kb_keymap->n_keys > ALTGR_OFFSET) { if (i & ALKED) i |= CLKED; else i &= ~CLKED; } if (KBD_HAS_DEVICE(kbd)) { error = write_kbd(state->kbdc, KBDC_SET_LEDS, ledmap[i & LED_MASK]); if (error) { splx(s); return error; } } KBD_LED_VAL(kbd) = *(int *)arg; break; case KDGKBSTATE: /* get lock key state */ *(int *)arg = state->ks_state & LOCK_MASK; break; case KDSKBSTATE: /* set lock key state */ if (*(int *)arg & ~LOCK_MASK) { splx(s); return EINVAL; } state->ks_state &= ~LOCK_MASK; state->ks_state |= *(int *)arg; splx(s); /* set LEDs and quit */ return atkbd_ioctl(kbd, KDSETLED, arg); case KDSETREPEAT: /* set keyboard repeat rate (new interface) */ splx(s); if (!KBD_HAS_DEVICE(kbd)) return 0; i = typematic(((int *)arg)[0], ((int *)arg)[1]); error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, i); if (error == 0) { kbd->kb_delay1 = typematic_delay(i); kbd->kb_delay2 = typematic_rate(i); } return error; case KDSETRAD: /* set keyboard repeat rate (old interface) */ splx(s); if (!KBD_HAS_DEVICE(kbd)) return 0; error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, *(int *)arg); if (error == 0) { kbd->kb_delay1 = typematic_delay(*(int *)arg); kbd->kb_delay2 = typematic_rate(*(int *)arg); } return error; case PIO_KEYMAP: /* set keyboard translation table */ case PIO_KEYMAPENT: /* set keyboard translation table entry */ case PIO_DEADKEYMAP: /* set accent key translation table */ state->ks_accents = 0; /* FALLTHROUGH */ default: splx(s); return genkbd_commonioctl(kbd, cmd, arg); } splx(s); return 0; } /* lock the access to the keyboard */ static int atkbd_lock(keyboard_t *kbd, int lock) { return kbdc_lock(((atkbd_state_t *)kbd->kb_data)->kbdc, lock); } /* clear the internal state of the keyboard */ static void atkbd_clear_state(keyboard_t *kbd) { atkbd_state_t *state; state = (atkbd_state_t *)kbd->kb_data; state->ks_flags = 0; state->ks_polling = 0; state->ks_state &= LOCK_MASK; /* preserve locking key state */ state->ks_accents = 0; state->ks_composed_char = 0; #if 0 state->ks_prefix = 0; /* XXX */ #endif } /* save the internal state */ static int atkbd_get_state(keyboard_t *kbd, void *buf, size_t len) { if (len == 0) return sizeof(atkbd_state_t); if (len < sizeof(atkbd_state_t)) return -1; bcopy(kbd->kb_data, buf, sizeof(atkbd_state_t)); return 0; } /* set the internal state */ static int atkbd_set_state(keyboard_t *kbd, void *buf, size_t len) { if (len < sizeof(atkbd_state_t)) return ENOMEM; if (((atkbd_state_t *)kbd->kb_data)->kbdc != ((atkbd_state_t *)buf)->kbdc) return ENOMEM; bcopy(buf, kbd->kb_data, sizeof(atkbd_state_t)); return 0; } static int atkbd_poll(keyboard_t *kbd, int on) { atkbd_state_t *state; int s; state = (atkbd_state_t *)kbd->kb_data; s = spltty(); if (on) ++state->ks_polling; else --state->ks_polling; splx(s); return 0; } /* local functions */ static int get_typematic(keyboard_t *kbd) { #ifdef __i386__ /* * Only some systems allow us to retrieve the keyboard repeat * rate previously set via the BIOS... */ struct vm86frame vmf; u_int32_t p; bzero(&vmf, sizeof(vmf)); vmf.vmf_ax = 0xc000; vm86_intcall(0x15, &vmf); if ((vmf.vmf_eflags & PSL_C) || vmf.vmf_ah) return ENODEV; p = BIOS_PADDRTOVADDR(((u_int32_t)vmf.vmf_es << 4) + vmf.vmf_bx); if ((readb(p + 6) & 0x40) == 0) /* int 16, function 0x09 supported? */ return ENODEV; vmf.vmf_ax = 0x0900; vm86_intcall(0x16, &vmf); if ((vmf.vmf_al & 0x08) == 0) /* int 16, function 0x0306 supported? */ return ENODEV; vmf.vmf_ax = 0x0306; vm86_intcall(0x16, &vmf); kbd->kb_delay1 = typematic_delay(vmf.vmf_bh << 5); kbd->kb_delay2 = typematic_rate(vmf.vmf_bl); return 0; #else return ENODEV; #endif /* __i386__ */ } static int setup_kbd_port(KBDC kbdc, int port, int intr) { if (!set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS, ((port) ? KBD_ENABLE_KBD_PORT : KBD_DISABLE_KBD_PORT) | ((intr) ? KBD_ENABLE_KBD_INT : KBD_DISABLE_KBD_INT))) return 1; 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; } /* 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 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; } } #ifdef __alpha__ 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 write_kbd(KBDC kbdc, int command, int data) { int s; /* prevent the timeout routine from polling the keyboard */ if (!kbdc_lock(kbdc, TRUE)) return EBUSY; /* disable the keyboard and mouse interrupt */ s = spltty(); #if 0 c = get_controller_command_byte(kbdc); if ((c == -1) || !set_controller_command_byte(kbdc, kbdc_get_device_mask(kbdc), KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) { /* CONTROLLER ERROR */ kbdc_lock(kbdc, FALSE); splx(s); return EIO; } /* * Now that the keyboard controller is told not to generate * the keyboard and mouse interrupts, call `splx()' to allow * the other tty interrupts. The clock interrupt may also occur, * but the timeout routine (`scrn_timer()') will be blocked * by the lock flag set via `kbdc_lock()' */ splx(s); #endif if (send_kbd_command_and_data(kbdc, command, data) != KBD_ACK) send_kbd_command(kbdc, KBDC_ENABLE_KBD); #if 0 /* restore the interrupts */ if (!set_controller_command_byte(kbdc, kbdc_get_device_mask(kbdc), c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) { /* CONTROLLER ERROR */ } #else splx(s); #endif kbdc_lock(kbdc, FALSE); return 0; } 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); } static int delays[] = { 250, 500, 750, 1000 }; static int rates[] = { 34, 38, 42, 46, 50, 55, 59, 63, 68, 76, 84, 92, 100, 110, 118, 126, 136, 152, 168, 184, 200, 220, 236, 252, 272, 304, 336, 368, 400, 440, 472, 504 }; static int typematic_delay(int i) { return delays[(i >> 5) & 3]; } static int typematic_rate(int i) { return rates[i & 0x1f]; } static int typematic(int delay, int rate) { int value; int i; for (i = sizeof(delays)/sizeof(delays[0]) - 1; i > 0; --i) { if (delay >= delays[i]) break; } value = i << 5; for (i = sizeof(rates)/sizeof(rates[0]) - 1; i > 0; --i) { if (rate >= rates[i]) break; } value |= i; return value; } @ 1.45 log @plug memory leak Noticed by: Coverity Prevent analysis tool @ text @d29 1 a29 1 __FBSDID("$FreeBSD$"); @ 1.44 log @Add a new flag to the atkbd(4) driver to disable testing the keyboard port during the device probe as this can cause hangs on some machines, specifically Compaq R3000Z series amd64 laptops. The flag is bit 3, or 0x8. PR: amd64/67745 Reported by: Neil Winterbauer newntrbr at ucla dot edu, many others Tested by: ade, astrodog at gmail dot com, many others MFC after: 1 week @ text @d347 1 d360 1 d364 1 d369 1 d372 2 a373 11 if (state != NULL) free(state, M_DEVBUF); if (keymap != NULL) free(keymap, M_DEVBUF); if (accmap != NULL) free(accmap, M_DEVBUF); if (fkeymap != NULL) free(fkeymap, M_DEVBUF); if (kbd != NULL) free(kbd, M_DEVBUF); return ENOMEM; d385 1 d390 4 a393 2 if (state->kbdc == NULL) return ENXIO; d404 4 a407 2 if (flags & KB_CONF_FAIL_IF_NO_KBD) return ENXIO; d425 2 a426 1 return ENXIO; d436 4 a439 2 if (kbd_register(kbd) < 0) return ENXIO; d444 16 @ 1.43 log @Remove atdevbase and replace it's remaining uses with direct references to KERNBASE instead. @ text @d1120 2 a1121 1 test_kbd_port(kbdc); @ 1.43.2.1 log @MFC: Add a new flag to the atkbd(4) driver to disable testing the keyboard port during the device probe as this can cause hangs on some machines, specifically Compaq R3000Z series amd64 laptops. The flag is bit 3, or 0x8. @ text @d1120 1 a1120 2 if (!(flags & KB_CONF_NO_PROBE_TEST)) test_kbd_port(kbdc); @ 1.42 log @Assign keycodes for Power, Sleep and Wake keys. Submitted by: Eugene Grosbein @ text @d53 1 @ 1.41 log @Use __FBSDID(). Also some minor style cleanups. @ text @d682 9 @ 1.40 log @Fix for FAIL_IF_NO_KBD case as expected. Even if we have no AT keyboard, an AT keyboard is registered because it's probed with KB_CONF_PROBE_ONLY flag set during console initialization. Unregister the keyboard if it doesn't present while second probe. This should fix USB keyboard only case without 'kbdcontrol -k /dev/kbd1'. @ text @a25 1 * $FreeBSD$ d27 3 @ 1.39 log @- Use the new resource_disabled() helper function to see if devices are disabled. - Change the apm driver to match the acpi driver's behavior by checking to see if the device is disabled in the identify routine instead of in the probe routine. This way if the device is disabled it is never created. Note that a few places (ips(4), Alpha SMP) used "disable" instead of "disabled" for their hint names, and these hints must be changed to "disabled". If this is a big problem, resource_disabled() can always be changed to honor both names. @ text @d420 2 a421 1 && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) d423 1 @ 1.38 log @Fix some easy, global, lint warnings. In most cases, this means making some local variables static. In a couple of cases, this means removing an unused variable. @ text @d280 1 a280 2 if ((resource_int_value("atkbd", ATKBD_DEFAULT, "disabled", &i) == 0) && i != 0) { @ 1.37 log @Deprecate machine/limits.h in favor of new sys/limits.h. Change all in-tree consumers to include Discussed on: standards@@ Partially submitted by: Craig Rodrigues @ text @d208 1 a208 1 keyboard_switch_t atkbdsw = { @ 1.36 log @Spelling. @ text @d37 1 a169 2 #include @ 1.35 log @Replace various spelling with FALLTHROUGH which is lint()able @ text @d1228 1 a1228 1 * that the keyoard controller may be left in a hung state. @ 1.34 log @GC various bits and pieces of USERCONFIG from all over the place. @ text @d834 1 a834 1 /* FALL THROUGH */ d918 1 a918 1 /* FALL THROUGH */ @ 1.33 log @Fix typo: conole -> console PR: 33965 Submitted by: Nicola Vitale @ text @d1248 1 a1248 1 * Allow us to set the XT_KEYBD flag in UserConfig so that keyboards @ 1.32 log @Return consistent key action codes at key press and release events. Otherwise you would see unexpected results if shift or locking keys are defined to give different actions depending on other shift/locking keys' state. Please keep the ukbd module and the kernel in sync, otherwise the USB keyboard won't work after this change. MFC after: 10 days @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.31 2001/01/22 22:54:02 dwmalone Exp $ d267 1 a267 1 * NOTE: because of the way the low-level conole is initialized, this routine @ 1.31 log @Free the kbd pointer when it isn't NULL, as opposed to when it is. This was a typo in the M_ZERO patches. Submitted by: Mike Silbersack @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.30 2000/12/08 21:49:46 dwmalone Exp $ d52 1 a170 1 #include @ 1.30 log @Convert more malloc+bzero to malloc+M_ZERO. Submitted by: josh@@zipperup.org Submitted by: Robert Drehmel @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.29 2000/10/15 14:18:18 phk Exp $ d375 1 a375 1 if (kbd == NULL) @ 1.29 log @Remove unneeded #include @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.28 2000/10/08 21:33:53 phk Exp $ d359 2 a360 5 *kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT); if (kbd == NULL) return ENOMEM; bzero(kbd, sizeof(*kbd)); state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT); d365 2 a366 2 if ((state == NULL) || (keymap == NULL) || (accmap == NULL) || (fkeymap == NULL)) { d375 2 a376 1 free(kbd, M_DEVBUF); a378 1 bzero(state, sizeof(*state)); @ 1.28 log @Initiate deorbit burn sequence for . Replace all in-tree uses with necessary subset of . This is also the appropriate fix for exo-tree sources. Put warnings in to discourage use. November 15th 2000 the warnings will be converted to errors. January 15th 2001 the files will be removed. @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.27 2000/05/28 12:43:24 ache Exp $ a170 1 #include @ 1.27 log @Manipulate with AltGR Led (really CapsLock Led) only in K_XLATE mode, because all other modes not set ALKED flag and it means that CapsLock always turned off for them. Real bug example is X11 which never turn on CapsLock with Russian keyboard. PR: 18651 Submitted by: "Mike E. Matsnev" @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.26 2000/03/19 03:25:11 yokota Exp $ d170 1 a170 1 #include @ 1.26 log @- Properly keep track of I/O port resources. - Use bus_space_read/write() to access the ports. @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.25 2000/03/11 07:44:10 yokota Exp $ d863 2 a864 1 if (kbd->kb_keymap->n_keys > ALTGR_OFFSET) { @ 1.25 log @One more patch for the atkbd driver. It will make sure that the keyboard port and interrupt is enabled and the driver is attached even when the keyboard itself is not present when the system is booting. (This has been the behavior through out 2.X and 3.X, but is somehow broken in 4.0.) # I certainly don't recommend people to `hot-plug' the AT keyboard, # because the interface isn't designed for hot-plugging and such act # will often break the keyboard controller. But, so many people want to # do that anyway... Approved by: jkh @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.24 2000/02/11 01:22:30 yokota Exp $ d39 3 d61 1 a61 1 atkbd_probe_unit(int unit, int port, int irq, int flags) d71 1 a71 1 args[0] = port; d80 1 a80 1 atkbd_attach_unit(int unit, keyboard_t **kbd, int port, int irq, int flags) d91 1 a91 1 args[0] = port; d317 1 a317 1 int *data = (int *)arg; d325 1 a325 1 kbdc = kbdc_open(data[0]); d346 1 a346 1 int *data = (int *)arg; d396 1 a396 1 state->kbdc = kbdc_open(data[0]); d400 1 a400 1 data[0], IO_KBDSIZE); @ 1.25.2.1 log @MFC: - Properly keep track of I/O port resources. - Use bus_space_read/write() to access the ports. atkbd_isa.c 1.8, atkbdc_isa.c 1.15, atkbd.c 1.26, atkbdc.c 1.6, atkbcreg.h 1.6, atkbdreg.h 1.6, pcvt_hdr.h 1.37, psm.c 1.24. @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.25 2000/03/11 07:44:10 yokota Exp $ a38 3 #include #include d58 1 a58 1 atkbd_probe_unit(int unit, int ctlr, int irq, int flags) d68 1 a68 1 args[0] = ctlr; d77 1 a77 1 atkbd_attach_unit(int unit, keyboard_t **kbd, int ctlr, int irq, int flags) d88 1 a88 1 args[0] = ctlr; d314 1 a314 1 int *data = (int *)arg; /* data[0]: controller, data[1]: irq */ d322 1 a322 1 kbdc = atkbdc_open(data[0]); d343 1 a343 1 int *data = (int *)arg; /* data[0]: controller, data[1]: irq */ d393 1 a393 1 state->kbdc = atkbdc_open(data[0]); d397 1 a397 1 0, 0); @ 1.25.2.2 log @MFC: do not sense ALKED in non K_XLATE modes since it never set @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.25.2.1 2000/03/31 12:51:56 yokota Exp $ d863 1 a863 2 if (state->ks_mode == K_XLATE && kbd->kb_keymap->n_keys > ALTGR_OFFSET) { @ 1.25.2.3 log @MFC: fix action code. atkbd_isa.c rev 1.10, atkbd.c rev 1.32, kbd.c rev 1.26, kbdreg.h rev 1.14, ukbd.c 1.32 @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.25.2.2 2000/05/28 12:48:22 ache Exp $ a51 1 #include d170 1 @ 1.25.2.4 log @MFC: Fix typo: conole -> console. PR: 33965 Submitted by: Nicola Vitale @ text @d26 1 a26 1 * $FreeBSD$ d268 1 a268 1 * NOTE: because of the way the low-level console is initialized, this routine @ 1.25.2.5 log @MFC: revision 1.40 Unregister the keyboard if FAIL_IF_NO_KBD is set and reset failed. @ text @d426 1 a426 2 && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) { kbd_unregister(kbd); a427 1 } @ 1.25.2.6 log @Switch importer @ text @d26 1 a26 1 * $FreeBSD: stable/4/sys/dev/kbd/atkbd.c 117779 2003-07-19 12:48:35Z simokawa $ @ 1.24 log @- Be slightly more cautious and try to make more sure the keyboard input queue is emptied when initializing the keyboard controller. - Remove an unnecessary `if' statement. Approved by: jkh @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.23 2000/01/29 15:08:51 peter Exp $ d1111 11 d1129 1 @ 1.23 log @Use config's conditional compilation rather than using #ifdefs that make modular compilation harder. I'm doing this because people seem to like cut/pasting examples of bad practices in existing code. @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.22 2000/01/20 13:32:53 yokota Exp $ d1084 3 d1088 1 a1088 1 empty_both_buffers(kbdc, 10); d1114 2 a1115 3 if (c != -1) /* try to restore the command byte as before */ set_controller_command_byte(kbdc, 0xff, c); d1134 3 @ 1.22 log @- Add some comment from bde on the keyboard interrupt. - Fix obsolete comments. @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.21 2000/01/11 13:39:04 yokota Exp $ a28 1 #include "atkbd.h" a31 2 #if NATKBD > 0 a1392 2 #endif /* NATKBD > 0 */ @ 1.21 log @Rework shifta/ctla/alta key handling. It appears that there was misunderstanding between the PR originator and me. I hope I got it right this time. @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.20 2000/01/10 08:52:32 yokota Exp $ d126 4 a129 2 /* The following comments are extracted from syscons.c (1.287) */ /* d133 7 a139 2 * This ugly hack calls scintr if input is ready for the keyboard * and conveniently hides the problem. XXX d142 8 a149 4 * Try removing anything stuck in the keyboard controller; whether * it's a keyboard scan code or mouse data. `scintr()' doesn't * read the mouse data directly, but `kbdio' routines will, as a * side effect. a165 3 /* cdev driver functions */ @ 1.20 log @Obtain the initial key repeat rate setting via BIOS in i386 if possible. @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.19 2000/01/10 08:50:43 yokota Exp $ a738 1 kbd->kb_prev_key = keycode | (scancode & 0x80); a744 1 kbd->kb_prev_key = keycode | (scancode & 0x80); a750 1 kbd->kb_prev_key = keycode | (scancode & 0x80); a755 1 kbd->kb_prev_key = keycode | (scancode & 0x80); a764 1 kbd->kb_prev_key = keycode | (scancode & 0x80); a773 1 kbd->kb_prev_key = keycode | (scancode & 0x80); a782 1 kbd->kb_prev_key = keycode | (scancode & 0x80); @ 1.19 log @Add some keyboard IDs. @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.18 1999/12/13 09:31:42 yokota Exp $ d42 10 d227 1 d337 1 d421 4 d449 1 d471 4 d996 33 @ 1.18 log @- Remember the keyboard repeat delay and rate. - Add a new ioctl, KDGETREPEAT, to retrieve the keyboard repeat rate. - Delete unnecessary #include. @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.17 1999/12/10 04:31:32 yokota Exp $ d1130 9 a1138 2 case 0x41ab: case 0x83ab: @ 1.17 log @Add support new keys: lshifta, rshifta, lctrla, rctrla, lalta, and ralta. These keys combine shift/ctrl/alt function and the AltLock function. When these keys pressed together with another key, they act just like the ordinary shift/ctrl/alt keys. When these keys are pressed and released alone, Alt lock state is toggled. PR: kern/12475 @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.16 1999/08/28 00:42:09 peter Exp $ a37 1 #include a39 2 #include #include d224 2 d877 6 a882 1 return write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, i); d888 6 a893 1 return write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, *(int *)arg); d1298 18 a1318 5 static int delays[] = { 250, 500, 750, 1000 }; static int rates[] = { 34, 38, 42, 46, 50, 55, 59, 63, 68, 76, 84, 92, 100, 110, 118, 126, 136, 152, 168, 184, 200, 220, 236, 252, 272, 304, 336, 368, 400, 440, 472, 504 }; @ 1.16 log @$Id$ -> $FreeBSD$ @ text @d26 1 a26 1 * $FreeBSD$ d517 2 d561 5 d719 1 d726 1 d733 1 d739 1 d749 1 d759 1 d769 1 d1073 1 a1073 1 empty_both_buffers(kbdc, 10); @ 1.15 log @Convert DEVFS hooks in (most) drivers to make_dev(). Diskslice/label code not yet handled. Vinum, i4b, alpha, pc98 not dealt with (left to respective Maintainers) Add the correct hook for devfs to kern_conf.c The net result of this excercise is that a lot less files depends on DEVFS, and devtoname() gets more sensible output in many cases. A few drivers had minor additional cleanups performed relating to cdevsw registration. A few drivers don't register a cdevsw{} anymore, but only use make_dev(). @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.14 1999/08/22 09:52:32 yokota Exp $ @ 1.14 log @- Remove cdevsw entry points in individual keyboard drivers; instead, use generic entry points for all drivers. - Eliminate bogus makedev(). - Eliminate softc in the lower drivers, as it is no longer necessary. Submitted (95%) by: phk @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.13 1999/08/15 06:06:14 yokota Exp $ a31 1 #include "opt_devfs.h" @ 1.13 log @Correctly save `flags' bits. @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.12 1999/07/18 06:16:25 yokota Exp $ a51 5 #define ATKBD_SOFTC(unit) \ ((atkbd_softc_t *)devclass_get_softc(atkbd_devclass, unit)) extern devclass_t atkbd_devclass; a53 32 #ifdef KBD_INSTALL_CDEV static d_open_t atkbdopen; static d_close_t atkbdclose; static d_read_t atkbdread; static d_ioctl_t atkbdioctl; static d_poll_t atkbdpoll; static struct cdevsw atkbd_cdevsw = { /* open */ atkbdopen, /* close */ atkbdclose, /* read */ atkbdread, /* write */ nowrite, /* ioctl */ atkbdioctl, /* stop */ nostop, /* reset */ noreset, /* devtotty */ nodevtotty, /* poll */ atkbdpoll, /* mmap */ nommap, /* strategy */ nostrategy, /* name */ ATKBD_DRIVER_NAME, /* parms */ noparms, /* maj */ -1, /* dump */ nodump, /* psize */ nopsize, /* flags */ 0, /* maxio */ 0, /* bmaj */ -1 }; #endif /* KBD_INSTALL_CDEV */ d74 1 a74 1 atkbd_attach_unit(int unit, atkbd_softc_t *sc, int port, int irq, int flags) a79 3 if (sc->flags & ATKBD_ATTACHED) return 0; d87 1 a87 1 sc->kbd = NULL; d91 1 a91 1 error = (*sw->init)(unit, &sc->kbd, args, flags); d94 1 a94 1 (*sw->enable)(sc->kbd); d98 1 a98 2 error = kbd_attach(makedev(0, ATKBD_MKMINOR(unit)), sc->kbd, &atkbd_cdevsw); d107 1 a107 1 atkbd_timeout(sc->kbd); d110 1 a110 3 (*sw->diag)(sc->kbd, bootverbose); sc->flags |= ATKBD_ATTACHED; a151 54 #ifdef KBD_INSTALL_CDEV static int atkbdopen(dev_t dev, int flag, int mode, struct proc *p) { atkbd_softc_t *sc; sc = ATKBD_SOFTC(ATKBD_UNIT(dev)); if (sc == NULL) return ENXIO; if (mode & (FWRITE | O_CREAT | O_APPEND | O_TRUNC)) return ENODEV; /* FIXME: set the initial input mode (K_XLATE?) and lock state? */ return genkbdopen(&sc->gensc, sc->kbd, flag, mode, p); } static int atkbdclose(dev_t dev, int flag, int mode, struct proc *p) { atkbd_softc_t *sc; sc = ATKBD_SOFTC(ATKBD_UNIT(dev)); return genkbdclose(&sc->gensc, sc->kbd, flag, mode, p); } static int atkbdread(dev_t dev, struct uio *uio, int flag) { atkbd_softc_t *sc; sc = ATKBD_SOFTC(ATKBD_UNIT(dev)); return genkbdread(&sc->gensc, sc->kbd, uio, flag); } static int atkbdioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p) { atkbd_softc_t *sc; sc = ATKBD_SOFTC(ATKBD_UNIT(dev)); return genkbdioctl(&sc->gensc, sc->kbd, cmd, arg, flag, p); } static int atkbdpoll(dev_t dev, int event, struct proc *p) { atkbd_softc_t *sc; sc = ATKBD_SOFTC(ATKBD_UNIT(dev)); return genkbdpoll(&sc->gensc, sc->kbd, event, p); } #endif /* KBD_INSTALL_CDEV */ @ 1.12 log @- Move the `return' statement the correct place so that the keyboard won't be initialized if `atkbd?' is disabled. @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.11 1999/05/30 16:51:30 phk Exp $ d502 1 @ 1.11 log @This commit should be a extensive NO-OP: Reformat and initialize correctly all "struct cdevsw". Initialize the d_maj and d_bmaj fields. The d_reset field was not removed, although it is never used. I used a program to do most of this, so all the files now use the same consistent format. Please keep it that way. Vinum and i4b not modified, patches emailed to respective authors. @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.10 1999/05/20 09:49:33 yokota Exp $ d358 3 a368 1 return 0; d370 1 a375 3 /* probe the keyboard controller */ atkbdc_configure(); @ 1.10 log @- Include isa/isareg.h rather than i386/isa/isa.h for i386. - Remove unused (thus, commented out) section of code. @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.9 1999/05/18 11:05:58 yokota Exp $ d67 20 a86 5 static struct cdevsw atkbd_cdevsw = { atkbdopen, atkbdclose, atkbdread, nowrite, atkbdioctl, nostop, nullreset, nodevtotty, atkbdpoll, nommap, NULL, ATKBD_DRIVER_NAME, NULL, -1, @ 1.9 log @The previous commit was wrong! This is the correct one ;-< @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.8 1999/05/09 05:00:19 yokota Exp $ d40 1 a49 3 #if 1 #include a51 2 extern devclass_t atkbd_devclass; d55 1 a55 13 #else /* __i386__ */ #include #include extern struct isa_driver atkbddriver; /* XXX: a kludge; see below */ static atkbd_softc_t *atkbd_softc[NATKBD]; #define ATKBD_SOFTC(unit) \ (((unit) >= NATKBD) ? NULL : atkbd_softc[(unit)]) #endif /* __i386__ */ a74 24 #if 0 #ifdef __i386__ atkbd_softc_t *atkbd_get_softc(int unit) { atkbd_softc_t *sc; if (unit >= sizeof(atkbd_softc)/sizeof(atkbd_softc[0])) return NULL; sc = atkbd_softc[unit]; if (sc == NULL) { sc = atkbd_softc[unit] = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT); if (sc == NULL) return NULL; bzero(sc, sizeof(*sc)); } return sc; } #endif /* __i386__ */ #endif @ 1.8 log @Don't confuse cursor keys with numpad keys when composing a char code. PR: kern/10988 @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.7 1999/05/09 04:59:24 yokota Exp $ d829 1 a829 1 switch (keycode) { @ 1.7 log @Minor tweak after the introduction of new-bus to i386; properly check "disabled" and "flags" probe hints. @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.6 1999/04/16 21:21:55 peter Exp $ d829 1 a829 1 switch (scancode) { d833 1 a833 1 state->ks_composed_char += scancode - 0x40; d839 1 a839 1 state->ks_composed_char += scancode - 0x47; d845 1 a845 1 state->ks_composed_char += scancode - 0x4E; @ 1.6 log @Bring the 'new-bus' to the i386. This extensively changes the way the i386 platform boots, it is no longer ISA-centric, and is fully dynamic. Most old drivers compile and run without modification via 'compatability shims' to enable a smoother transition. eisa, isapnp and pccard* are not yet using the new resource manager. Once fully converted, all drivers will be loadable, including PCI and ISA. (Some other changes appear to have snuck in, including a port of Soren's ATA driver to the Alpha. Soren, back this out if you need to.) This is a checkpoint of work-in-progress, but is quite functional. The bulk of the work was done over the last few years by Doug Rabson and Garrett Wollman. Approved by: core @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.5 1999/03/10 10:36:52 yokota Exp $ d383 9 a391 13 /* XXX: a kludge to obtain the device configuration flags */ if (resource_int_value("atkbd", 0, "flags", &i) == 0) { flags |= i; /* if the driver is disabled, unregister the keyboard if any */ if (resource_int_value("atkbd", 0, "disabled", &i) == 0 && i != 0) { i = kbd_find_keyboard(ATKBD_DRIVER_NAME, ATKBD_DEFAULT); if (i >= 0) { kbd = kbd_get_keyboard(i); kbd_unregister(kbd); kbd->kb_flags &= ~KB_REGISTERED; return 0; } d395 4 @ 1.5 log @Keyboard driver update in preparation for the USB keyboard driver. - Refined internal interface in keyboard drivers so that: 1. the side effect of device probe is kept minimal, 2. polling mode function is added, 3. and new ioctl and configuration options are added (see below). - Added new ioctl: KDSETREPEAT Set keyboard typematic rate. There has existed an ioctl command, KDSETRAD, for the same purpose. However, KDSETRAD is dependent on the AT keyboard. KDSETREPEAT provides more generic interface. KDSETRAD will still be supported in the atkbd driver. - Added new configuration options: ATKBD_DFLT_KEYMAP Specify a keymap to be used as the default, built-in keymap. (There has been undocumented options, DKKEYMAP, UKKEYMAP, GRKEYMAP, SWKEYMAP, RUKEYMAP, ESKEYMAP, and ISKEYMAP to set the default keymap. These options are now gone for good. The new option is more general.) KBD_DISABLE_KEYMAP_LOADING Don't allow the user to change the keymap. @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.4 1999/01/28 10:55:55 yokota Exp $ d49 1 a49 1 #ifndef __i386__ d92 1 d114 1 a380 2 #ifdef __i386__ struct isa_device *dev; d384 2 a385 3 dev = find_isadev(isa_devtab_tty, &atkbddriver, 0); if (dev != NULL) { flags |= dev->id_flags; d387 2 a388 1 if (!dev->id_enabled) { d398 1 a398 2 #endif @ 1.4 log @- Fixed the bug which always ignored Ctrl-Pause/Break on the AT 101 keyboard. - Translate some keycode for the 84 keyboard so that the 84 keyboard and the 101 keyboard become more compatible in terms of keycodes. - Updated the built-in keymaps so that it is in line with the recent changes in share/syscons/keymaps. - Added some comment on the Pause/Break key on the 101 keyboard. @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.3 1999/01/19 11:31:14 yokota Exp $ d31 1 d51 1 d54 2 d68 2 a69 1 #define ATKBD_SOFTC(unit) atkbd_softc[(unit)] d115 1 a115 1 atkbd_probe_unit(int unit, atkbd_softc_t *sc, int port, int irq, int flags) d119 1 a119 3 if (sc->flags & ATKBD_ATTACHED) return 0; d127 4 a130 1 return (*sw->probe)(unit, &sc->kbd, args, flags); d134 1 a134 1 atkbd_attach_unit(int unit, atkbd_softc_t *sc) d137 1 d148 7 a154 1 error = (*sw->init)(sc->kbd); d156 1 a156 1 return ENXIO; d210 1 a210 1 (*kbdsw[kbd->kb_index]->intr)(kbd); a223 1 int unit; d225 2 a226 2 unit = ATKBD_UNIT(dev); if ((unit >= NATKBD) || ((sc = ATKBD_SOFTC(unit)) == NULL)) d289 1 d314 1 d334 1 d347 1 d352 4 a377 1 KBDC kbdc; d381 1 d385 1 a385 1 if (dev != NULL) d387 11 d406 2 a407 1 if (atkbd_probe(ATKBD_DEFAULT, &kbd, arg, flags)) d409 6 d416 12 a427 6 /* initialize it */ kbdc = ((atkbd_state_t *)kbd->kb_data)->kbdc; if (!(flags & KB_CONF_PROBE_ONLY) && !KBD_IS_INITIALIZED(kbd)) { if (KBD_HAS_DEVICE(kbd) && init_keyboard(kbdc, &kbd->kb_type, flags) && (flags & KB_CONF_FAIL_IF_NO_KBD)) a428 1 KBD_INIT_DONE(kbd); d431 6 a436 5 /* and register */ if (!KBD_IS_CONFIGURED(kbd)) { if (kbd_register(kbd) < 0) return 0; KBD_CONFIG_DONE(kbd); d438 1 a438 2 return 1; /* return the number of found keyboards */ d441 1 a441 3 /* low-level functions */ /* initialize the keyboard_t structure and try to detect a keyboard */ d443 1 a443 1 atkbd_probe(int unit, keyboard_t **kbdp, void *arg, int flags) a450 1 KBDC kbdc; d456 1 a456 1 if (KBD_IS_PROBED(kbd)) d488 1 a488 1 } else if (KBD_IS_PROBED(*kbdp)) { d500 3 a502 14 state->kbdc = kbdc = kbdc_open(data[0]); if (kbdc == NULL) return ENXIO; kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags, data[0], IO_KBDSIZE); bcopy(&key_map, keymap, sizeof(key_map)); bcopy(&accent_map, accmap, sizeof(accent_map)); bcopy(fkey_tab, fkeymap, imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab))); kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size); kbd->kb_data = (void *)state; if (probe_keyboard(kbdc, flags)) { if (flags & KB_CONF_FAIL_IF_NO_KBD) d504 22 a525 2 } else { KBD_FOUND_DEVICE(kbd); d527 1 a527 24 atkbd_clear_state(kbd); state->ks_mode = K_XLATE; /* * FIXME: set the initial value for lock keys in ks_state * according to the BIOS data? */ KBD_PROBE_DONE(kbd); return 0; } /* reset and initialize the device */ static int atkbd_init(keyboard_t *kbd) { KBDC kbdc; if ((kbd == NULL) || !KBD_IS_PROBED(kbd)) return ENXIO; /* shouldn't happen */ kbdc = ((atkbd_state_t *)kbd->kb_data)->kbdc; if (kbdc == NULL) return ENXIO; /* shouldn't happen */ if (!KBD_IS_INITIALIZED(kbd)) { d529 2 a530 2 && init_keyboard(kbdc, &kbd->kb_type, kbd->kb_config) && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) d532 1 a532 2 atkbd_ioctl(kbd, KDSETLED, (caddr_t)&((atkbd_state_t *)(kbd->kb_data))->ks_state); d554 1 a554 1 atkbd_intr(keyboard_t *kbd) d982 1 a982 1 case KDSETRAD: /* set keyboard repeat rate */ d986 8 a993 2 return write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, *(int *)arg); d1024 1 d1058 16 d1396 24 @ 1.3 log @syscons - Bring down the splash screen when a vty is opened for the first time. - Make sure the splash screen/screen saver is stopped before switching vtys. - Read and save initial values in the BIOS data area early. VESA BIOS may change BIOS data values when switching modes. - Fix missing '&' operator. - Move ISA specific part of driver initialization to syscons_isa.c. atkbd - kbdtables.h is now in /sys/dev/kbd. all - Adjust for forthcoming alpha port. Submitted by: dfr @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.2 1999/01/13 11:19:19 yokota Exp $ d704 3 d752 6 d766 1 a766 1 goto next_code; d769 28 @ 1.3.2.1 log @MFC: keycode fixes (atkbd.c, rev 1.4, kbdtables.h, 1.43, 1.44). @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.4 1999/01/28 10:55:55 yokota Exp $ a703 3 case 0x46: /* ctrl-pause/break on AT 101 (see below) */ keycode = 0x68; break; a748 6 /* * The pause/break key on the 101 keyboard produces: * E1-1D-45 E1-9D-C5 * Ctrl-pause/break produces: * E0-46 E0-C6 (See above.) */ d757 1 a757 1 goto next_code; a759 28 } if (kbd->kb_type == KB_84) { switch (keycode) { case 0x37: /* *(numpad)/print screen */ if (state->ks_flags & SHIFTS) keycode = 0x5c; /* print screen */ break; case 0x45: /* num lock/pause */ if (state->ks_flags & CTLS) keycode = 0x68; /* pause */ break; case 0x46: /* scroll lock/break */ if (state->ks_flags & CTLS) keycode = 0x6c; /* break */ break; } } else if (kbd->kb_type == KB_101) { switch (keycode) { case 0x5c: /* print screen */ if (state->ks_flags & ALTS) keycode = 0x54; /* sysrq */ break; case 0x68: /* pause/break */ if (state->ks_flags & CTLS) keycode = 0x6c; /* break */ break; } @ 1.3.2.2 log @YAMFC: merge updated keyboard driver code: - Refined internal interface in keyboard drivers so that: 1. the side effect of device probe is kept minimal, 2. polling mode function is added, 3. and new ioctl and configuration options are added (see below). - Added new ioctl: KDSETREPEAT Set keyboard typematic rate. There has existed an ioctl command, KDSETRAD, for the same purpose. However, KDSETRAD is dependent on the AT keyboard. KDSETREPEAT provides more generic interface. KDSETRAD will still be supported in the atkbd driver. - Added new configuration options: ATKBD_DFLT_KEYMAP Specify a keymap to be used as the default, built-in keymap. (There has been undocumented options, DKKEYMAP, UKKEYMAP, GRKEYMAP, SWKEYMAP, RUKEYMAP, ESKEYMAP, and ISKEYMAP to set the default keymap. These options are now gone for good. The new option is more general.) KBD_DISABLE_KEYMAP_LOADING Don't allow the user to change the keymap. - And other minor fixes and updates. merged files and revisions --------------------------------------------------------------------- usr.sbin/kbdcontrol/kbdcontrol.c 1.22, 1.23, 1.24, 1.25 usr.sbin/vidcontrol/vidcontrol.c 1.27 sys/alpha/include/console.h 1.42, 1.43, 1.44 sys/dev/kbd/kbd.c 1.4 sys/dev/kbd/kbdreg.h 1.3 sys/dev/kbd/kbdtables.h 1.45 sys/dev/kbd/atkbd.c 1.5, 1.8 sys/dev/kbd/atkbdreg.h 1.2 sys/dev/syscons/syscons.c 1.295, 1.296, 1.299 sys/dev/usb/ukbd.c 1.9, 1.10, 1.11, 1.12, 1.13 sys/i386/conf/LINT 1.565 sys/i386/conf/options.i386 1.109 sys/i386/conf/files.i386 1.228 sys/i386/include/console.h 1.45 sys/i386/isa/atkbd_isa.c 1.3 sys/i386/isa/pcvt/pcvt_kbd.c 1.28, 1.29 sys/isa/atkbd_isa.c 1.2 @ text @d26 1 a26 1 * $Id$ a30 1 #include "opt_atkbd.h" a49 1 #include a51 2 extern devclass_t atkbd_devclass; d64 1 a64 2 #define ATKBD_SOFTC(unit) \ (((unit) >= NATKBD) ? NULL : atkbd_softc[(unit)]) d110 1 a110 1 atkbd_probe_unit(int unit, int port, int irq, int flags) d114 3 a116 1 int error; d124 1 a124 4 error = (*sw->probe)(unit, args, flags); if (error) return error; return 0; d128 1 a128 1 atkbd_attach_unit(int unit, atkbd_softc_t *sc, int port, int irq, int flags) a130 1 int args[2]; d141 1 a141 4 args[0] = port; args[1] = irq; sc->kbd = NULL; error = (*sw->probe)(unit, args, flags); d143 1 a143 4 return error; error = (*sw->init)(unit, &sc->kbd, args, flags); if (error) return error; d197 1 a197 1 (*kbdsw[kbd->kb_index]->intr)(kbd, NULL); d211 1 d213 2 a214 2 sc = ATKBD_SOFTC(ATKBD_UNIT(dev)); if (sc == NULL) a276 1 int ks_polling; a300 1 static kbd_poll_mode_t atkbd_poll; a319 1 atkbd_poll, a331 1 static int typematic(int delay, int rate); a335 4 #ifdef ATKBD_DFLT_KEYMAP #define KBD_DFLT_KEYMAP #include "atkbdmap.h" #endif d358 1 a361 1 int i; d365 1 a365 1 if (dev != NULL) { a366 11 /* if the driver is disabled, unregister the keyboard if any */ if (!dev->id_enabled) { i = kbd_find_keyboard(ATKBD_DRIVER_NAME, ATKBD_DEFAULT); if (i >= 0) { kbd = kbd_get_keyboard(i); kbd_unregister(kbd); kbd->kb_flags &= ~KB_REGISTERED; return 0; } } } d375 1 a375 4 kbd = NULL; if (atkbd_probe(ATKBD_DEFAULT, arg, flags)) return 0; if (atkbd_init(ATKBD_DEFAULT, &kbd, arg, flags)) d378 9 a386 3 /* return the number of found keyboards */ return 1; } d388 3 a390 12 /* low-level functions */ /* detect a keyboard */ static int atkbd_probe(int unit, void *arg, int flags) { KBDC kbdc; int *data = (int *)arg; /* XXX */ if (unit == ATKBD_DEFAULT) { if (KBD_IS_PROBED(&default_kbd)) d392 1 d395 1 a395 8 kbdc = kbdc_open(data[0]); if (kbdc == NULL) return ENXIO; if (probe_keyboard(kbdc, flags)) { if (flags & KB_CONF_FAIL_IF_NO_KBD) return ENXIO; } return 0; d398 3 a400 1 /* reset and initialize the device */ d402 1 a402 1 atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) d410 1 d416 1 a416 1 if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd)) d448 1 a448 1 } else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) { d460 14 a473 3 if (!KBD_IS_PROBED(kbd)) { state->kbdc = kbdc_open(data[0]); if (state->kbdc == NULL) d475 2 a476 22 kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags, data[0], IO_KBDSIZE); bcopy(&key_map, keymap, sizeof(key_map)); bcopy(&accent_map, accmap, sizeof(accent_map)); bcopy(fkey_tab, fkeymap, imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab))); kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size); kbd->kb_data = (void *)state; if (probe_keyboard(state->kbdc, flags)) { /* shouldn't happen */ if (flags & KB_CONF_FAIL_IF_NO_KBD) return ENXIO; } else { KBD_FOUND_DEVICE(kbd); } atkbd_clear_state(kbd); state->ks_mode = K_XLATE; /* * FIXME: set the initial value for lock keys in ks_state * according to the BIOS data? */ KBD_PROBE_DONE(kbd); d478 24 a501 1 if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) { d503 2 a504 2 && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config) && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) d506 2 a507 1 atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state); d529 1 a529 1 atkbd_intr(keyboard_t *kbd, void *arg) d805 1 a805 1 switch (keycode) { d809 1 a809 1 state->ks_composed_char += keycode - 0x40; d815 1 a815 1 state->ks_composed_char += keycode - 0x47; d821 1 a821 1 state->ks_composed_char += keycode - 0x4E; d957 1 a957 1 case KDSETREPEAT: /* set keyboard repeat rate (new interface) */ d961 2 a962 8 i = typematic(((int *)arg)[0], ((int *)arg)[1]); return write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, i); case KDSETRAD: /* set keyboard repeat rate (old interface) */ splx(s); if (!KBD_HAS_DEVICE(kbd)) return 0; return write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, *(int *)arg); a992 1 state->ks_polling = 0; a1025 16 static int atkbd_poll(keyboard_t *kbd, int on) { atkbd_state_t *state; int s; state = (atkbd_state_t *)kbd->kb_data; s = spltty(); if (on) ++state->ks_polling; else --state->ks_polling; splx(s); return 0; } a1347 24 } static int typematic(int delay, int rate) { static int delays[] = { 250, 500, 750, 1000 }; static int rates[] = { 34, 38, 42, 46, 50, 55, 59, 63, 68, 76, 84, 92, 100, 110, 118, 126, 136, 152, 168, 184, 200, 220, 236, 252, 272, 304, 336, 368, 400, 440, 472, 504 }; int value; int i; for (i = sizeof(delays)/sizeof(delays[0]) - 1; i > 0; --i) { if (delay >= delays[i]) break; } value = i << 5; for (i = sizeof(rates)/sizeof(rates[0]) - 1; i > 0; --i) { if (rate >= rates[i]) break; } value |= i; return value; @ 1.3.2.3 log @MFC: Don't confuse cursor keys with numpad keys when composing a char code (rev 1.9). @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.3.2.2 1999/05/09 11:02:11 yokota Exp $ d830 1 a830 1 switch (keycode | (scancode & 0x80)) { @ 1.3.2.4 log @MFC: Move the `return' statement the correct place so that the keyboard won't be initialized if `atkbd?' is disabled. (rev 1.12) @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.3.2.3 1999/05/28 03:15:58 yokota Exp $ a382 3 /* probe the keyboard controller */ atkbdc_configure(); d394 1 a395 1 return 0; d398 2 a399 1 #else d402 1 a402 1 #endif @ 1.3.2.5 log @MFC: Correctly save `flags' bits (rev 1.13). @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.3.2.4 1999/07/22 12:44:29 yokota Exp $ a529 1 kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY; @ 1.3.2.6 log @$Id$ -> $FreeBSD$ @ text @d26 1 a26 1 * $FreeBSD$ @ 1.3.2.7 log @YAMFC: bring in the key repeat rate related code update. - Remember the keyboard repeat delay and rate. Add a new ioctl, KDGETREPEAT. (syscons.c 1.330, atkbd.c 1.18, kbd.c 1.14, kbio.h 1.4) - Obtain the initial key repeat rate setting via BIOS in i386 if possible. (atkbd.c 1.20) @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.3.2.6 1999/08/29 16:23:34 peter Exp $ a32 3 #ifdef __i386__ #include "opt_vm86.h" #endif a44 12 #ifdef __i386__ #ifdef VM86 #include #include #include #include #include #include #endif /* VM86 */ #endif /* __i386__ */ a340 1 static int get_typematic(keyboard_t *kbd); a347 2 static int typematic_delay(int delay); static int typematic_rate(int rate); a452 1 int delay[2]; a535 4 get_typematic(kbd); delay[0] = kbd->kb_delay1; delay[1] = kbd->kb_delay2; atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); a559 1 int delay[2]; a580 4 get_typematic(kbd); delay[0] = kbd->kb_delay1; delay[1] = kbd->kb_delay2; atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); d990 1 a990 6 error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, i); if (error == 0) { kbd->kb_delay1 = typematic_delay(i); kbd->kb_delay2 = typematic_rate(i); } return error; d996 1 a996 6 error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, *(int *)arg); if (error == 0) { kbd->kb_delay1 = typematic_delay(*(int *)arg); kbd->kb_delay2 = typematic_rate(*(int *)arg); } return error; a1079 37 get_typematic(keyboard_t *kbd) { #ifdef __i386__ #ifdef VM86 /* * Only some systems allow us to retrieve the keyboard repeat * rate previously set via the BIOS... */ struct vm86frame vmf; u_int32_t p; bzero(&vmf, sizeof(vmf)); vmf.vmf_ax = 0xc000; vm86_intcall(0x15, &vmf); if ((vmf.vmf_eflags & PSL_C) || vmf.vmf_ah) return ENODEV; p = BIOS_PADDRTOVADDR(((u_int32_t)vmf.vmf_es << 4) + vmf.vmf_bx); if ((readb(p + 6) & 0x40) == 0) /* int 16, function 0x09 supported? */ return ENODEV; vmf.vmf_ax = 0x0900; vm86_intcall(0x16, &vmf); if ((vmf.vmf_al & 0x08) == 0) /* int 16, function 0x0306 supported? */ return ENODEV; vmf.vmf_ax = 0x0306; vm86_intcall(0x16, &vmf); kbd->kb_delay1 = typematic_delay(vmf.vmf_bh << 5); kbd->kb_delay2 = typematic_rate(vmf.vmf_bl); return 0; #else return ENODEV; #endif /* VM86 */ #else return ENODEV; #endif /* __i386__ */ } static int a1400 18 static int delays[] = { 250, 500, 750, 1000 }; static int rates[] = { 34, 38, 42, 46, 50, 55, 59, 63, 68, 76, 84, 92, 100, 110, 118, 126, 136, 152, 168, 184, 200, 220, 236, 252, 272, 304, 336, 368, 400, 440, 472, 504 }; static int typematic_delay(int i) { return delays[(i >> 5) & 3]; } static int typematic_rate(int i) { return rates[i & 0x1f]; } d1404 5 @ 1.3.2.8 log @YAMFC: Remove cdevsw entry points in individual keyboard drivers; instead, use generic entry points for all drivers. Eliminate softc in the lower drivers, as it is no longer necessary. (ukbd.c 1.17, atkbd_isa.c 1.5, atkbd.c 1.14, atkbdreg.h 1.3, kbd.c 1.10, kbdreg.h 1.4) @ text @d26 1 a26 1 * $FreeBSD: src/sys/dev/kbd/atkbd.c,v 1.3.2.7 2000/02/02 12:28:39 yokota Exp $ d69 5 d81 5 d90 39 d149 1 a149 1 atkbd_attach_unit(int unit, keyboard_t **kbd, int port, int irq, int flags) d155 3 d165 1 a165 1 *kbd = NULL; d169 1 a169 1 error = (*sw->init)(unit, kbd, args, flags); d172 1 a172 1 (*sw->enable)(*kbd); d176 2 a177 1 error = kbd_attach(*kbd); d186 1 a186 1 atkbd_timeout(*kbd); d189 3 a191 1 (*sw->diag)(*kbd, bootverbose); d233 54 @ 1.2 log @Use the correct macro to test flags; we need KBD_IS_INITIALIZED here, not KBD_IS_PROBED. @ text @d26 1 a26 1 * $Id: atkbd.c,v 1.1 1999/01/09 02:44:49 yokota Exp $ d50 2 d197 1 a197 1 (*kbdsw[kbd->kb_index]->intr)(kbd, NULL); d336 1 a336 1 #include d529 1 a529 1 atkbd_intr(keyboard_t *kbd, void *arg) d1208 9 @ 1.1 log @Add the new keyboard driver and video card driver. They will be used by console drivers. (They are not yet activated yet. Wait for announcement later.) @ text @d26 1 a26 1 * $Id: $ d378 1 a378 1 if (!(flags & KB_CONF_PROBE_ONLY) && !KBD_IS_PROBED(kbd)) { @