Beispiel #1
0
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__ */
}
Beispiel #2
0
static int
get_typematic(keyboard_t *kbd)
{
#if defined(__i386__) || defined(__amd64__)
	/*
	 * Only some systems allow us to retrieve the keyboard repeat
	 * rate previously set via the BIOS...
	 */
	x86regs_t regs;
	uint8_t *p;

	/*
	 * Traditional entry points of int 0x15 and 0x16 are fixed
	 * and later BIOSes follow them.  (U)EFI CSM specification
	 * also mandates these fixed entry points.
	 *
	 * Validate the entry points here before we proceed further.
	 * It's known that some recent laptops does not have the
	 * same entry point and hang on boot if we call it.
	 */
	if (x86bios_get_intr(0x15) != 0xf000f859 ||
	    x86bios_get_intr(0x16) != 0xf000e82e)
		return (ENODEV);

	/* Is BIOS system configuration table supported? */
	x86bios_init_regs(&regs);
	regs.R_AH = 0xc0;
	x86bios_intr(&regs, 0x15);
	if ((regs.R_FLG & PSL_C) != 0 || regs.R_AH != 0)
		return (ENODEV);

	/* Is int 0x16, function 0x09 supported? */
	p = x86bios_offset((regs.R_ES << 4) + regs.R_BX);
	if (readw(p) < 5 || (readb(p + 6) & 0x40) == 0)
		return (ENODEV);

	/* Is int 0x16, function 0x0306 supported? */
	x86bios_init_regs(&regs);
	regs.R_AH = 0x09;
	x86bios_intr(&regs, 0x16);
	if ((regs.R_AL & 0x08) == 0)
		return (ENODEV);

	x86bios_init_regs(&regs);
	regs.R_AX = 0x0306;
	x86bios_intr(&regs, 0x16);
	kbd->kb_delay1 = typematic_delay(regs.R_BH << 5);
	kbd->kb_delay2 = typematic_rate(regs.R_BL);
	return (0);
#else
	return (ENODEV);
#endif /* __i386__ || __amd64__ */
}
Beispiel #3
0
static int
set_typematic(keyboard_t *kbd)
{
	int val, error;
	atkbd_state_t *state = kbd->kb_data;

	val = typematic(DEFAULT_DELAY, DEFAULT_RATE);
	error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, val);
	if (error == 0) {
		kbd->kb_delay1 = typematic_delay(val);
		kbd->kb_delay2 = typematic_rate(val);
	}

	return (error);
}
Beispiel #4
0
static int
get_typematic(keyboard_t *kbd)
{
#if defined(__i386__) || defined(__amd64__)
    /*
     * Only some systems allow us to retrieve the keyboard repeat
     * rate previously set via the BIOS...
     */
    x86regs_t regs;
    uint8_t *p;

    if (x86bios_get_intr(0x15) == 0 || x86bios_get_intr(0x16) == 0)
        return (ENODEV);

    /* Is BIOS system configuration table supported? */
    x86bios_init_regs(&regs);
    regs.R_AH = 0xc0;
    x86bios_intr(&regs, 0x15);
    if ((regs.R_FLG & PSL_C) != 0 || regs.R_AH != 0)
        return (ENODEV);

    /* Is int 0x16, function 0x09 supported? */
    p = x86bios_offset((regs.R_ES << 4) + regs.R_BX);
    if (readw(p) < 5 || (readb(p + 6) & 0x40) == 0)
        return (ENODEV);

    /* Is int 0x16, function 0x0306 supported? */
    x86bios_init_regs(&regs);
    regs.R_AH = 0x09;
    x86bios_intr(&regs, 0x16);
    if ((regs.R_AL & 0x08) == 0)
        return (ENODEV);

    x86bios_init_regs(&regs);
    regs.R_AX = 0x0306;
    x86bios_intr(&regs, 0x16);
    kbd->kb_delay1 = typematic_delay(regs.R_BH << 5);
    kbd->kb_delay2 = typematic_rate(regs.R_BL);
    return (0);
#else
    return (ENODEV);
#endif /* __i386__ || __amd64__ */
}
Beispiel #5
0
/* some useful control functions */
static int
atkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
{
    /* translate 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;
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    int ival;
#endif

    s = spltty();
    switch (cmd) {

    case KDGKBMODE:		/* get keyboard mode */
        *(int *)arg = state->ks_mode;
        break;
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    case _IO('K', 7):
        ival = IOCPARM_IVAL(arg);
        arg = (caddr_t)&ival;
        /* FALLTHROUGH */
#endif
    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;
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    case _IO('K', 66):
        ival = IOCPARM_IVAL(arg);
        arg = (caddr_t)&ival;
        /* FALLTHROUGH */
#endif
    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;
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    case _IO('K', 20):
        ival = IOCPARM_IVAL(arg);
        arg = (caddr_t)&ival;
        /* FALLTHROUGH */
#endif
    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;

#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    case _IO('K', 67):
        ival = IOCPARM_IVAL(arg);
        arg = (caddr_t)&ival;
        /* FALLTHROUGH */
#endif
    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;
}