mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-29 16:44:03 +00:00
Obtain the initial key repeat rate setting via BIOS in i386 if
possible.
This commit is contained in:
parent
934d11e395
commit
56f5e27c4b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55731
@ -39,6 +39,16 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#ifdef __i386__
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/vm86.h>
|
||||
#include <machine/pc/bios.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#endif /* __i386__ */
|
||||
|
||||
#include <dev/kbd/kbdreg.h>
|
||||
#include <dev/kbd/atkbdreg.h>
|
||||
#include <dev/kbd/atkbdcreg.h>
|
||||
@ -214,6 +224,7 @@ keyboard_switch_t atkbdsw = {
|
||||
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);
|
||||
@ -323,6 +334,7 @@ atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
accentmap_t *accmap;
|
||||
fkeytab_t *fkeymap;
|
||||
int fkeymap_size;
|
||||
int delay[2];
|
||||
int *data = (int *)arg;
|
||||
|
||||
/* XXX */
|
||||
@ -406,6 +418,10 @@ atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
&& (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD))
|
||||
return ENXIO;
|
||||
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)) {
|
||||
@ -430,6 +446,7 @@ 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)) {
|
||||
@ -451,6 +468,10 @@ atkbd_intr(keyboard_t *kbd, void *arg)
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -973,6 +994,39 @@ atkbd_poll(keyboard_t *kbd, int on)
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
@ -39,6 +39,16 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#ifdef __i386__
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/vm86.h>
|
||||
#include <machine/pc/bios.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#endif /* __i386__ */
|
||||
|
||||
#include <dev/kbd/kbdreg.h>
|
||||
#include <dev/kbd/atkbdreg.h>
|
||||
#include <dev/kbd/atkbdcreg.h>
|
||||
@ -214,6 +224,7 @@ keyboard_switch_t atkbdsw = {
|
||||
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);
|
||||
@ -323,6 +334,7 @@ atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
accentmap_t *accmap;
|
||||
fkeytab_t *fkeymap;
|
||||
int fkeymap_size;
|
||||
int delay[2];
|
||||
int *data = (int *)arg;
|
||||
|
||||
/* XXX */
|
||||
@ -406,6 +418,10 @@ atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
&& (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD))
|
||||
return ENXIO;
|
||||
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)) {
|
||||
@ -430,6 +446,7 @@ 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)) {
|
||||
@ -451,6 +468,10 @@ atkbd_intr(keyboard_t *kbd, void *arg)
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -973,6 +994,39 @@ atkbd_poll(keyboard_t *kbd, int on)
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user