Incorporate kludge/fix from `syscons' ver 1.207 and 1.209.

1) Dell Latitude XPi
This laptop has a strange, IMHO broken :-), keyboard controller which
wouldn't disable the keyboard interrupt. The kludge is to disable tty
intr. during set_keyboard(), used for changing LED and setting
typematic.

The patch also changes the function name:
    set_keyboard() -> set_keyboard_param()
Although it is a static function, the name corrides with a routine in
`syscons' and is confusing when debugging the kernel which has both
`syscons' and `pcvt' with DDB. (Suggested by Bruce)

2) doreset() bug
doreset() failed to preserve some bits in the keyboard controller's
command byte during keyboard reset. This bug may put some keyboard
controllers in old motherboards (386 and 486) in a strange state,
resulting in complete keyboard lockup or random key input.

Reviewed by:	Joerg
This commit is contained in:
Kazutaka YOKOTA 1997-04-18 12:06:34 +00:00
parent 96bdc21389
commit 03dcce7f3d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=24999

View File

@ -94,7 +94,7 @@ static void setlockkeys ( int snc );
#ifndef _I386_ISA_KBDIO_H_ #ifndef _I386_ISA_KBDIO_H_
static int kbc_8042cmd ( int val ); static int kbc_8042cmd ( int val );
#else #else
static int set_keyboard( int command, int data ); static int set_keyboard_param( int command, int data );
#endif /* !_I386_ISA_KBDIO_H_ */ #endif /* !_I386_ISA_KBDIO_H_ */
static int getokeydef ( unsigned key, struct kbd_ovlkey *thisdef ); static int getokeydef ( unsigned key, struct kbd_ovlkey *thisdef );
static int getckeydef ( unsigned key, struct kbd_ovlkey *thisdef ); static int getckeydef ( unsigned key, struct kbd_ovlkey *thisdef );
@ -301,7 +301,7 @@ update_led(void)
} else { } else {
ledstate = LEDSTATE_UPDATE_PENDING; ledstate = LEDSTATE_UPDATE_PENDING;
splx(opri); splx(opri);
if (set_keyboard(KBDC_SET_LEDS, new_ledstate) == 0) if (set_keyboard_param(KBDC_SET_LEDS, new_ledstate) == 0)
ledstate = new_ledstate; ledstate = new_ledstate;
} }
@ -338,7 +338,7 @@ settpmrate(int rate)
printf("Keyboard TYPEMATIC data timeout\n"); printf("Keyboard TYPEMATIC data timeout\n");
#else #else
tpmrate = rate & 0x7f; tpmrate = rate & 0x7f;
if (set_keyboard(KBDC_SET_TYPEMATIC, tpmrate) != 0) if (set_keyboard_param(KBDC_SET_TYPEMATIC, tpmrate) != 0)
printf("pcvt: failed to set keyboard TYPEMATIC.\n"); printf("pcvt: failed to set keyboard TYPEMATIC.\n");
#endif /* !_I386_ISA_KBDIO_H_ */ #endif /* !_I386_ISA_KBDIO_H_ */
} }
@ -407,7 +407,7 @@ kbd_response(void)
} }
#else #else
static int static int
set_keyboard(int command, int data) set_keyboard_param(int command, int data)
{ {
int s; int s;
int c; int c;
@ -421,11 +421,12 @@ set_keyboard(int command, int data)
/* disable the keyboard and mouse interrupt */ /* disable the keyboard and mouse interrupt */
s = spltty(); s = spltty();
#if 0
c = get_controller_command_byte(kbdc); c = get_controller_command_byte(kbdc);
if ((c == -1) if ((c == -1)
|| !set_controller_command_byte(kbdc, || !set_controller_command_byte(kbdc,
kbdc_get_device_mask(kbdc), kbdc_get_device_mask(kbdc),
KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT KBD_DISBLE_KBD_PORT | KBD_DISABLE_KBD_INT
| KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) { | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/* CONTROLLER ERROR */ /* CONTROLLER ERROR */
kbdc_lock(kbdc, FALSE); kbdc_lock(kbdc, FALSE);
@ -440,15 +441,21 @@ set_keyboard(int command, int data)
* by the lock flag set via `kbdc_lock()' * by the lock flag set via `kbdc_lock()'
*/ */
splx(s); splx(s);
#endif
send_kbd_command_and_data(kbdc, command, data); if (send_kbd_command_and_data(kbdc, command, data) != KBD_ACK)
send_kbd_command(kbdc, KBDC_ENABLE_KBD);
#if 0
/* restore the interrupts */ /* restore the interrupts */
if (!set_controller_command_byte(kbdc, if (!set_controller_command_byte(kbdc,
kbdc_get_device_mask(kbdc), kbdc_get_device_mask(kbdc),
c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) { c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) {
/* CONTROLLER ERROR */ /* CONTROLLER ERROR */
} }
#else
splx(s);
#endif
kbdc_lock(kbdc, FALSE); kbdc_lock(kbdc, FALSE);
return 0; return 0;
@ -716,11 +723,8 @@ r_entry:
/* disable the keyboard interrupt and the aux port and interrupt */ /* disable the keyboard interrupt and the aux port and interrupt */
if (!set_controller_command_byte(kbdc, if (!set_controller_command_byte(kbdc,
KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK,
| KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK, KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT | KBDINITCMD)) {
KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT
| KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT
| KBDINITCMD)) {
/* CONTROLLER ERROR: there is very little we can do... */ /* CONTROLLER ERROR: there is very little we can do... */
kbdc_set_device_mask(kbdc, m); kbdc_set_device_mask(kbdc, m);
kbdc_lock(kbdc, FALSE); kbdc_lock(kbdc, FALSE);
@ -794,9 +798,8 @@ r_entry:
/* enable the keyboard port and intr. */ /* enable the keyboard port and intr. */
if (!set_controller_command_byte(kbdc, if (!set_controller_command_byte(kbdc,
KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS, KBD_KBD_CONTROL_BITS,
(c & KBD_AUX_CONTROL_BITS) KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
| KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
/* CONTROLLER ERROR /* CONTROLLER ERROR
* This is serious; we are left with the disabled * This is serious; we are left with the disabled
* keyboard intr. * keyboard intr.