diff --git a/sys/i386/isa/kbdio.c b/sys/i386/isa/kbdio.c index fe8b3fbb544c..cf8e265f997a 100644 --- a/sys/i386/isa/kbdio.c +++ b/sys/i386/isa/kbdio.c @@ -26,10 +26,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: kbdio.c,v 1.8 1997/02/22 09:36:46 peter Exp $ */ #include "sc.h" +#include "vt.h" #include "psm.h" #include "opt_kbdio.h" @@ -81,7 +82,7 @@ /* constants */ -#define NKBDC max(NSC, NPSM) +#define NKBDC max(max(NSC, NVT), NPSM) #define KBDQ_BUFSIZE 32 /* macros */ diff --git a/sys/i386/isa/pcvt/pcvt_drv.c b/sys/i386/isa/pcvt/pcvt_drv.c index 3b216f0096d9..13d6ede6ee85 100644 --- a/sys/i386/isa/pcvt/pcvt_drv.c +++ b/sys/i386/isa/pcvt/pcvt_drv.c @@ -143,6 +143,11 @@ pcprobe(struct isa_device *dev) #endif /* PCVT_NETBSD > 9 */ #endif /* PCVT_NETBSD > 100 */ { +#ifdef _I386_ISA_KBDIO_H_ + kbdc = kbdc_open(IO_KBD); + reset_keyboard = 1; /* it's now safe to do kbd reset */ +#endif /* _I386_ISA_KBDIO_H_ */ + kbd_code_init(); #if PCVT_NETBSD > 9 @@ -829,6 +834,10 @@ pcrint(int unit) int s; # endif +# ifdef _I386_ISA_KBDIO_H_ + int c; +# endif + #else /* !PCVT_KBD_FIFO */ u_char *cp; #endif /* PCVT_KBD_FIFO */ @@ -844,6 +853,7 @@ pcrint(int unit) return; } +# ifndef _I386_ISA_KBDIO_H_ while (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) /* check 8042 buffer */ { ret = 1; /* got something */ @@ -851,6 +861,12 @@ pcrint(int unit) PCVT_KBD_DELAY(); /* 7 us delay */ dt = inb(CONTROLLER_DATA); /* get it 8042 data */ +# else + while ((c = read_kbd_data_no_wait(kbdc)) != -1) + { + ret = 1; /* got something */ + dt = c; +# endif /* _I386_ISA_KBDIO_H_ */ if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */ { @@ -1069,6 +1085,15 @@ pccnprobe(struct consdev *cp) { struct isa_device *dvp; +#ifdef _I386_ISA_KBDIO_H_ + kbdc = kbdc_open(IO_KBD); + /* + * Don't reset the keyboard via `kbdio' just yet. + * The system clock has not been calibrated... + */ + reset_keyboard = 0; +#endif /* _I386_ISA_KBDIO_H_ */ + /* * Take control if we are the highest priority enabled display device. */ @@ -1437,6 +1462,8 @@ pcvt_xmode_set(int on, struct proc *p) vsp->Crtat = vsp->Memory; /* operate in memory now */ +#ifndef _I386_ISA_KBDIO_H_ + #if PCVT_SCANSET == 2 /* put keyboard to return ancient PC scan codes */ kbc_8042cmd(CONTR_WRITE); @@ -1449,6 +1476,16 @@ pcvt_xmode_set(int on, struct proc *p) #endif /* PCVT_USEKBDSEC */ #endif /* PCVT_SCANSET == 2 */ +#else /* _I386_ISA_KBDIO_H_ */ + +#if PCVT_SCANSET == 2 + /* put keyboard to return ancient PC scan codes */ + set_controller_command_byte(kbdc, + KBD_TRANSLATION, KBD_TRANSLATION); +#endif /* PCVT_SCANSET == 2 */ + +#endif /* !_I386_ISA_KBDIO_H_ */ + #if PCVT_NETBSD > 9 fp->tf_eflags |= PSL_IOPL; #else @@ -1484,6 +1521,8 @@ pcvt_xmode_set(int on, struct proc *p) pcvt_set_scrnsv_tmo(saved_scrnsv_tmo); #endif /* PCVT_SCREENSAVER */ +#ifndef _I386_ISA_KBDIO_H_ + #if PCVT_SCANSET == 2 kbc_8042cmd(CONTR_WRITE); #if PCVT_USEKBDSEC /* security enabled */ @@ -1495,6 +1534,14 @@ pcvt_xmode_set(int on, struct proc *p) #endif /* PCVT_USEKBDSEC */ #endif /* PCVT_SCANSET == 2 */ +#else /* _I386_ISA_KBDIO_H_ */ + +#if PCVT_SCANSET == 2 + set_controller_command_byte(kbdc, KBD_TRANSLATION, 0); +#endif /* PCVT_SCANSET == 2 */ + +#endif /* !_I386_ISA_KBDIO_H_ */ + if(adaptor_type == MDA_ADAPTOR) { /* diff --git a/sys/i386/isa/pcvt/pcvt_hdr.h b/sys/i386/isa/pcvt/pcvt_hdr.h index a4353e7487bf..75dd2c4258a4 100644 --- a/sys/i386/isa/pcvt/pcvt_hdr.h +++ b/sys/i386/isa/pcvt/pcvt_hdr.h @@ -105,6 +105,7 @@ #endif /* PCVT_FREEBSD >= 200 */ #include +#include #if PCVT_NETBSD > 9 #include "device.h" @@ -263,6 +264,8 @@ in the config file" * Keyboard and Keyboard Controller *---------------------------------------------------------------------------*/ +#ifndef _I386_ISA_KBDIO_H_ + #define CONTROLLER_CTRL 0x64 /* W - command, R - status */ #define CONTROLLER_DATA 0x60 /* R/W - data */ @@ -309,6 +312,8 @@ in the config file" #define KEYB_C_ECHO 0xee /* diagnostic, echo 0xee */ #define KEYB_C_LEDS 0xed /* set/reset numlock,capslock & scroll lock */ +#endif /* _I386_ISA_KBDIO_H_ */ + /* responses from the KEYBOARD (via the 8042 controller on mainboard..) */ #define KEYB_R_OVERRUN0 0x00 /* keyboard buffer overflow */ @@ -999,6 +1004,10 @@ u_char chargen_access = 0; /* synchronize access */ u_char keyboard_type = KB_UNKNOWN; /* type of keyboard */ u_char keyboard_is_initialized = 0; /* for ddb sanity */ u_char kbd_polling = 0; /* keyboard is being polled */ +#ifdef _I386_ISA_KBDIO_H_ +u_char reset_keyboard = 0; /* OK to reset keyboard */ +KBDC kbdc = NULL; /* keyboard controller */ +#endif /* _I386_ISA_KBDIO_H_ */ #if PCVT_SHOWKEYS u_char keyboard_show = 0; /* normal display */ @@ -1136,6 +1145,10 @@ extern u_char can_do_132col; extern u_char vga_family; extern u_char keyboard_is_initialized; extern u_char kbd_polling; +#ifdef _I386_ISA_KBDIO_H_ +extern u_char reset_keyboard; +extern KBDC kbdc; +#endif /* _I386_ISA_KBDIO_H_ */ #if PCVT_SHOWKEYS extern u_char keyboard_show; @@ -1266,7 +1279,10 @@ void fkl_on ( struct video_state *svsp ); struct tty *get_pccons ( Dev_t dev ); void init_sfkl ( struct video_state *svsp ); void init_ufkl ( struct video_state *svsp ); +#ifndef _I386_ISA_KBDIO_H_ int kbd_cmd ( int val ); +int kbd_response ( void ); +#endif /* _I386_ISA_KBDIO_H_ */ void kbd_code_init ( void ); void kbd_code_init1 ( void ); diff --git a/sys/i386/isa/pcvt/pcvt_kbd.c b/sys/i386/isa/pcvt/pcvt_kbd.c index 312b912407ba..17bdea85a0cd 100644 --- a/sys/i386/isa/pcvt/pcvt_kbd.c +++ b/sys/i386/isa/pcvt/pcvt_kbd.c @@ -75,8 +75,6 @@ #define LEDSTATE_UPDATE_PENDING (1 << 3) -extern int kbd_response __P((void)); - static void fkey1(void), fkey2(void), fkey3(void), fkey4(void); static void fkey5(void), fkey6(void), fkey7(void), fkey8(void); static void fkey9(void), fkey10(void), fkey11(void), fkey12(void); @@ -93,7 +91,11 @@ static void doreset ( void ); static void ovlinit ( int force ); static void settpmrate ( int rate ); static void setlockkeys ( int snc ); +#ifndef _I386_ISA_KBDIO_H_ static int kbc_8042cmd ( int val ); +#else +static int set_keyboard( int command, int data ); +#endif /* !_I386_ISA_KBDIO_H_ */ static int getokeydef ( unsigned key, struct kbd_ovlkey *thisdef ); static int getckeydef ( unsigned key, struct kbd_ovlkey *thisdef ); static int rmkeydef ( int key ); @@ -168,7 +170,7 @@ do_vgapage(int page) #define PCVT_UPDLED_LOSES_INTR 0 /* disabled for now */ -#if PCVT_UPDLED_LOSES_INTR +#if PCVT_UPDLED_LOSES_INTR || defined(_I386_ISA_KBDIO_H_) /*---------------------------------------------------------------------------* * check for lost keyboard interrupts @@ -199,6 +201,7 @@ static int lost_intr_timeout_queued = 0; static void check_for_lost_intr (void *arg) { +#ifndef _I386_ISA_KBDIO_H_ lost_intr_timeout_queued = 0; if (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) { @@ -206,9 +209,23 @@ check_for_lost_intr (void *arg) pcrint (); splx (opri); } +#else + int opri; + + lost_intr_timeout_queued = 0; + if (kbdc_lock(kbdc, TRUE)) { + opri = spltty (); + kbdc_lock(kbdc, FALSE); + if (kbdc_data_ready(kbdc)) + pcrint (0); + splx (opri); + } + timeout(check_for_lost_intr, (void *)NULL, hz); + lost_intr_timeout_queued = 1; +#endif /* !_I386_ISA_KBDIO_H_ */ } -#endif /* PCVT_UPDLED_LOSES_INTR */ +#endif /* PCVT_UPDLED_LOSES_INTR || defined(_I386_ISA_KBDIO_H_) */ /*---------------------------------------------------------------------------* * update keyboard led's @@ -229,6 +246,8 @@ update_led(void) if (new_ledstate != ledstate) { +#ifndef _I386_ISA_KBDIO_H_ + ledstate = LEDSTATE_UPDATE_PENDING; if(kbd_cmd(KEYB_C_LEDS) != 0) @@ -274,6 +293,19 @@ update_led(void) printf( "Keyboard LED command not ACKed (responses %#x %#x)\n", response1, response2); +#else /* _I386_ISA_KBDIO_H_ */ + + if (kbdc == NULL) { + ledstate = new_ledstate; + splx(opri); + } else { + ledstate = LEDSTATE_UPDATE_PENDING; + splx(opri); + if (set_keyboard(KBDC_SET_LEDS, new_ledstate) == 0) + ledstate = new_ledstate; + } + +#endif /* !_I386_ISA_KBDIO_H_ */ #if PCVT_UPDLED_LOSES_INTR if (lost_intr_timeout_queued) @@ -285,7 +317,9 @@ update_led(void) } +#ifndef _I386_ISA_KBDIO_H_ splx(opri); +#endif #endif /* !PCVT_NO_LED_UPDATE */ } @@ -296,13 +330,20 @@ update_led(void) static void settpmrate(int rate) { +#ifndef _I386_ISA_KBDIO_H_ tpmrate = rate & 0x7f; if(kbd_cmd(KEYB_C_TYPEM) != 0) printf("Keyboard TYPEMATIC command timeout\n"); else if(kbd_cmd(tpmrate) != 0) printf("Keyboard TYPEMATIC data timeout\n"); +#else + tpmrate = rate & 0x7f; + if (set_keyboard(KBDC_SET_TYPEMATIC, tpmrate) != 0) + printf("pcvt: failed to set keyboard TYPEMATIC.\n"); +#endif /* !_I386_ISA_KBDIO_H_ */ } +#ifndef _I386_ISA_KBDIO_H_ /*---------------------------------------------------------------------------* * Pass command to keyboard controller (8042) *---------------------------------------------------------------------------*/ @@ -364,6 +405,55 @@ kbd_response(void) return ch; } +#else +static int +set_keyboard(int command, int data) +{ + int s; + int c; + + if (kbdc == NULL) + return 1; + + /* prevent the timeout routine from polling the keyboard */ + if (!kbdc_lock(kbdc, TRUE)) + return 1; + + /* disable the keyboard and mouse interrupt */ + s = spltty(); + c = get_controller_command_byte(kbdc); + if ((c == -1) + || !set_controller_command_byte(kbdc, + kbdc_get_device_mask(kbdc), + KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT + | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) { + /* CONTROLLER ERROR */ + kbdc_lock(kbdc, FALSE); + splx(s); + return 1; + } + /* + * 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); + + send_kbd_command_and_data(kbdc, command, data); + + /* 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 */ + } + kbdc_lock(kbdc, FALSE); + + return 0; +} +#endif /* !_I386_ISA_KBDIO_H_ */ #if PCVT_SCANSET > 1 /*---------------------------------------------------------------------------* @@ -372,6 +462,7 @@ kbd_response(void) void kbd_emulate_pc(int do_emulation) { +#ifndef _I386_ISA_KBDIO_H_ int cmd, timeo = 10000; cmd = COMMAND_SYSFLG|COMMAND_IRQEN; /* common base cmd */ @@ -388,6 +479,10 @@ kbd_emulate_pc(int do_emulation) if (--timeo == 0) break; outb(CONTROLLER_DATA, cmd); +#else + set_controller_command_byte(kbdc, KBD_TRANSLATION, + (do_emulation) ? KBD_TRANSLATION : 0); +#endif /* !_I386_ISA_KBDIO_H_ */ } #endif /* PCVT_SCANSET > 1 */ @@ -403,6 +498,7 @@ kbd_emulate_pc(int do_emulation) static void doreset(void) { +#ifndef _I386_ISA_KBDIO_H_ int again = 0; int once = 0; int response, opri; @@ -563,6 +659,164 @@ r_entry: #endif /* PCVT_KEYBDID */ +#else /* _I386_ISA_KBDIO_H_ */ + int c; + int m; + int s; + + if (!reset_keyboard) /* no, we are not ready to reset */ + return; + + if (lost_intr_timeout_queued) { + untimeout(check_for_lost_intr, (void *)NULL); + lost_intr_timeout_queued = 0; + } + + if (kbdc == NULL) + kbdc = kbdc_open(IO_KBD); + + if (!kbdc_lock(kbdc, TRUE)) /* strange, somebody got there first */ + return; + + /* remove any noise */ + empty_both_buffers(kbdc, 10); + + s = spltty(); + + /* save the current 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); + kbdc = NULL; + splx(s); + printf("pcvt: unable to get the command byte.\n"); + return; + } + +#if PCVT_USEKBDSEC /* security enabled */ + +# if PCVT_SCANSET == 2 +# define KBDINITCMD 0 +# else /* PCVT_SCANSET != 2 */ +# define KBDINITCMD KBD_TRANSLATION +# endif /* PCVT_SCANSET == 2 */ + +#else /* ! PCVT_USEKBDSEC */ /* security disabled */ + +# if PCVT_SCANSET == 2 +# define KBDINITCMD KBD_OVERRIDE_KBD_LOCK +# else /* PCVT_SCANSET != 2 */ +# define KBDINITCMD KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK +# endif /* PCVT_SCANSET == 2 */ + +#endif /* PCVT_USEKBDSEC */ + + /* disable the keyboard interrupt and the aux port and interrupt */ + if (!set_controller_command_byte(kbdc, + KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS + | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK, + 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... */ + kbdc_set_device_mask(kbdc, m); + kbdc_lock(kbdc, FALSE); + kbdc = NULL; + splx(s); + printf("pcvt: unable to set the command byte.\n"); + return; + } + splx(s); + + /* reset keyboard hardware */ + ledstate = LEDSTATE_UPDATE_PENDING; + if (!reset_kbd(kbdc)) { + /* KEYBOARD ERROR */ + empty_both_buffers(kbdc, 10); + test_controller(kbdc); + test_kbd_port(kbdc); + /* + * We could disable the keyboard port and interrupt now... + * but, the keyboard may still exist. + */ + printf("pcvt: failed to reset the keyboard.\n"); + /* try to restore the original command byte */ + set_controller_command_byte(kbdc, 0xff, c); + kbdc_set_device_mask(kbdc, m); + kbdc_lock(kbdc, FALSE); + kbdc = NULL; + return; + } + +#if PCVT_KEYBDID + + keyboard_type = KB_UNKNOWN; + if (send_kbd_command(kbdc, KBDC_SEND_DEV_ID) == KBD_ACK) { + DELAY(10000); /* 10msec delay */ + switch (read_kbd_data(kbdc)) { + case KEYB_R_MF2ID1: + switch (read_kbd_data(kbdc)) { + case KEYB_R_MF2ID2: + case KEYB_R_MF2ID2HP: + keyboard_type = KB_MFII; + break; + case -1: + default: + break; + } + break; + case -1: + keyboard_type = KB_AT; + /* fall through */ + default: + /* XXX: should we read the second byte? */ + empty_both_buffers(kbdc, 10); /* XXX */ + break; + } + } else { + /* + * The send ID command failed. This error is considered + * benign, but may need recovery. + */ + empty_both_buffers(kbdc, 10); + test_controller(kbdc); + test_kbd_port(kbdc); + } + +#else /* PCVT_KEYBDID */ + + keyboard_type = KB_MFII; /* force it .. */ + +#endif /* PCVT_KEYBDID */ + + /* enable the keyboard port and intr. */ + if (!set_controller_command_byte(kbdc, + KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS, + (c & KBD_AUX_CONTROL_BITS) + | KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) { + /* CONTROLLER ERROR + * This is serious; we are left with the disabled + * keyboard intr. + */ + printf("pcvt: failed to enable the keyboard port and intr.\n"); + kbdc_set_device_mask(kbdc, m); + kbdc_lock(kbdc, FALSE); + kbdc = NULL; + return; + } + + kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS); + kbdc_lock(kbdc, FALSE); + + update_led(); + + timeout(check_for_lost_intr, (void *)NULL, hz); + lost_intr_timeout_queued = 1; + +#endif /* !_I386_ISA_KBDIO_H_ */ } /*---------------------------------------------------------------------------* @@ -984,10 +1238,16 @@ sgetc(int noblock) static char keybuf[2] = {0}; /* the second 0 is a delimiter! */ #endif /* XSERVER */ +#ifdef _I386_ISA_KBDIO_H_ + int c; +#endif /* _I386_ISA_KBDIO_H_ */ + loop: #ifdef XSERVER +#ifndef _I386_ISA_KBDIO_H_ + #if PCVT_KBD_FIFO /* see if there is data from the keyboard available either from */ @@ -1021,6 +1281,32 @@ loop: #endif /* !PCVT_KBD_FIFO */ +#else /* _I386_ISA_KBDIO_H_ */ + +#if PCVT_KBD_FIFO + if (pcvt_kbd_count) { + dt = pcvt_kbd_fifo[pcvt_kbd_rptr++]; + PCVT_DISABLE_INTR(); + pcvt_kbd_count--; + PCVT_ENABLE_INTR(); + if (pcvt_kbd_rptr >= PCVT_KBD_FIFO_SZ) + pcvt_kbd_rptr = 0; + } else +#endif /* PCVT_KBD_FIFO */ + if (!noblock) { + while ((c = read_kbd_data(kbdc)) == -1) + ; + dt = c; + } else { + if ((c = read_kbd_data_no_wait(kbdc)) == -1) + return NULL; + dt = c; + } + + { + +#endif /* !_I386_ISA_KBDIO_H_ */ + /* * If x mode is active, only care for locking keys, then * return the scan code instead of any key translation. @@ -1297,6 +1583,8 @@ no_mouse_event: #else /* !XSERVER */ +#ifndef _I386_ISA_KBDIO_H_ + # if PCVT_KBD_FIFO /* see if there is data from the keyboard available either from */ @@ -1332,8 +1620,33 @@ no_mouse_event: #endif /* !PCVT_KBD_FIFO */ +#else /* _I386_ISA_KBDIO_H_ */ + +#if PCVT_KBD_FIFO + if (pcvt_kbd_count) { + dt = pcvt_kbd_fifo[pcvt_kbd_rptr++]; + PCVT_DISABLE_INTR(); + pcvt_kbd_count--; + PCVT_ENABLE_INTR(); + if (pcvt_kbd_rptr >= PCVT_KBD_FIFO_SZ) + pcvt_kbd_rptr = 0; + } else +#endif /* PCVT_KBD_FIFO */ + if (!noblock) { + while ((c = read_kbd_data(kbdc)) == -1) + ; + dt = c; + } else { + if ((c = read_kbd_data_no_wait(kbdc)) == -1) + return NULL; + dt = c; + } + +#endif /* !_I386_ISA_KBDIO_H_ */ + #endif /* !XSERVER */ +#ifndef _I386_ISA_KBDIO_H_ else { if(noblock) @@ -1341,6 +1654,7 @@ no_mouse_event: else goto loop; } +#endif /* !_I386_ISA_KBDIO_H_ */ #if PCVT_SHOWKEYS showkey (' ', dt); diff --git a/sys/isa/kbdio.c b/sys/isa/kbdio.c index fe8b3fbb544c..cf8e265f997a 100644 --- a/sys/isa/kbdio.c +++ b/sys/isa/kbdio.c @@ -26,10 +26,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: kbdio.c,v 1.8 1997/02/22 09:36:46 peter Exp $ */ #include "sc.h" +#include "vt.h" #include "psm.h" #include "opt_kbdio.h" @@ -81,7 +82,7 @@ /* constants */ -#define NKBDC max(NSC, NPSM) +#define NKBDC max(max(NSC, NVT), NPSM) #define KBDQ_BUFSIZE 32 /* macros */