1119482Sobrien/*- 238465Smsmith * Copyright (c) 1998 Michael Smith (msmith@freebsd.org) 338465Smsmith * Copyright (c) 1997 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) 438465Smsmith * All rights reserved. 538465Smsmith * 638465Smsmith * Redistribution and use in source and binary forms, with or without 738465Smsmith * modification, are permitted provided that the following conditions 838465Smsmith * are met: 938465Smsmith * 1. Redistributions of source code must retain the above copyright 1038465Smsmith * notice, this list of conditions and the following disclaimer. 1138465Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1238465Smsmith * notice, this list of conditions and the following disclaimer in the 1338465Smsmith * documentation and/or other materials provided with the distribution. 1438465Smsmith * 1538465Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1638465Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1738465Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1838465Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1938465Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2038465Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2138465Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2238465Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2338465Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2438465Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2538465Smsmith * SUCH DAMAGE. 2638465Smsmith * 27119482Sobrien * Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp 2838465Smsmith */ 2938465Smsmith 30119482Sobrien#include <sys/cdefs.h> 31119482Sobrien__FBSDID("$FreeBSD$"); 32119482Sobrien 3338465Smsmith#include <stand.h> 3439441Smsmith#include <bootstrap.h> 3539441Smsmith#include <btxv86.h> 3640016Smsmith#include <machine/psl.h> 3739441Smsmith#include "libi386.h" 3838465Smsmith 3939441Smsmith#if KEYBOARD_PROBE 4038465Smsmith#include <machine/cpufunc.h> 4138465Smsmith 4238465Smsmithstatic int probe_keyboard(void); 4339441Smsmith#endif 4438465Smsmithstatic void vidc_probe(struct console *cp); 4538465Smsmithstatic int vidc_init(int arg); 4639441Smsmithstatic void vidc_putchar(int c); 4739441Smsmithstatic int vidc_getchar(void); 4839441Smsmithstatic int vidc_ischar(void); 4938465Smsmith 5040212Speterstatic int vidc_started; 5140212Speter 5242002Sabial#ifdef TERM_EMU 5384371Syokota#define MAXARGS 8 5484371Syokota#define DEFAULT_FGCOLOR 7 5584371Syokota#define DEFAULT_BGCOLOR 0 5684371Syokota 5764187Sjhbvoid end_term(void); 5842002Sabialvoid bail_out(int c); 5942002Sabialvoid vidc_term_emu(int c); 60199855Ssobomaxvoid get_pos(int *x, int *y); 61199855Ssobomaxvoid curs_move(int *_x, int *_y, int x, int y); 6242002Sabialvoid write_char(int c, int fg, int bg); 6342002Sabialvoid scroll_up(int rows, int fg, int bg); 6442002Sabialvoid CD(void); 6542002Sabialvoid CM(void); 6642002Sabialvoid HO(void); 6742002Sabial 6884371Syokotastatic int args[MAXARGS], argc; 6984371Syokotastatic int fg_c, bg_c, curx, cury; 7042002Sabialstatic int esc; 7142002Sabial#endif 7242002Sabial 7342002Sabial 7438465Smsmithstruct console vidconsole = { 7538465Smsmith "vidconsole", 7638465Smsmith "internal video/keyboard", 7738465Smsmith 0, 7838465Smsmith vidc_probe, 7938465Smsmith vidc_init, 8039441Smsmith vidc_putchar, 8139441Smsmith vidc_getchar, 8239441Smsmith vidc_ischar 8338465Smsmith}; 8438465Smsmith 8538465Smsmithstatic void 8638465Smsmithvidc_probe(struct console *cp) 8738465Smsmith{ 8838465Smsmith 8938465Smsmith /* look for a keyboard */ 9039441Smsmith#if KEYBOARD_PROBE 9139441Smsmith if (probe_keyboard()) 9238465Smsmith#endif 9339441Smsmith { 9439441Smsmith 9538465Smsmith cp->c_flags |= C_PRESENTIN; 9638465Smsmith } 9738465Smsmith 9838465Smsmith /* XXX for now, always assume we can do BIOS screen output */ 9938465Smsmith cp->c_flags |= C_PRESENTOUT; 10038465Smsmith} 10138465Smsmith 10238465Smsmithstatic int 10338465Smsmithvidc_init(int arg) 10438465Smsmith{ 10540212Speter int i; 10640016Smsmith 10740212Speter if (vidc_started && arg == 0) 10884276Syokota return (0); 10940212Speter vidc_started = 1; 11042002Sabial#ifdef TERM_EMU 11142002Sabial /* Init terminal emulator */ 11242002Sabial end_term(); 113199855Ssobomax get_pos(&curx, &cury); 114199855Ssobomax curs_move(&curx, &cury, curx, cury); 11584371Syokota fg_c = DEFAULT_FGCOLOR; 11684371Syokota bg_c = DEFAULT_BGCOLOR; 11742002Sabial#endif 11884276Syokota for (i = 0; i < 10 && vidc_ischar(); i++) 11984276Syokota (void)vidc_getchar(); 12084276Syokota return (0); /* XXX reinit? */ 12138465Smsmith} 12238465Smsmith 123199855Ssobomaxvoid 12442207Sabialvidc_biosputchar(int c) 12542207Sabial{ 12684276Syokota 12742207Sabial v86.ctl = 0; 12842207Sabial v86.addr = 0x10; 12942291Speter v86.eax = 0xe00 | (c & 0xff); 13042207Sabial v86.ebx = 0x7; 13142207Sabial v86int(); 13242207Sabial} 13342207Sabial 13442207Sabialstatic void 13542002Sabialvidc_rawputchar(int c) 13639441Smsmith{ 13740775Smsmith int i; 13840775Smsmith 13984276Syokota if (c == '\t') 14040775Smsmith /* lame tab expansion */ 14140775Smsmith for (i = 0; i < 8; i++) 14242002Sabial vidc_rawputchar(' '); 14342002Sabial else { 14442002Sabial#ifndef TERM_EMU 14542207Sabial vidc_biosputchar(c); 14642002Sabial#else 14742002Sabial /* Emulate AH=0eh (teletype output) */ 14842002Sabial switch(c) { 14942207Sabial case '\a': 15084276Syokota vidc_biosputchar(c); 15184276Syokota return; 15242002Sabial case '\r': 15384276Syokota curx = 0; 154199855Ssobomax curs_move(&curx, &cury, curx, cury); 15584276Syokota return; 15642002Sabial case '\n': 15784276Syokota cury++; 15884276Syokota if (cury > 24) { 15984276Syokota scroll_up(1, fg_c, bg_c); 16084276Syokota cury--; 16184276Syokota } else { 162199855Ssobomax curs_move(&curx, &cury, curx, cury); 16384276Syokota } 16484276Syokota return; 16542002Sabial case '\b': 16684276Syokota if (curx > 0) { 16784276Syokota curx--; 168199855Ssobomax curs_move(&curx, &cury, curx, cury); 16984276Syokota /* write_char(' ', fg_c, bg_c); XXX destructive(!) */ 17042002Sabial return; 17184276Syokota } 17284276Syokota return; 17342002Sabial default: 17484276Syokota write_char(c, fg_c, bg_c); 17584276Syokota curx++; 17684276Syokota if (curx > 79) { 17784276Syokota curx = 0; 17884276Syokota cury++; 17984276Syokota } 18084276Syokota if (cury > 24) { 18184276Syokota curx = 0; 18284276Syokota scroll_up(1, fg_c, bg_c); 18384276Syokota cury--; 18484276Syokota } 18542002Sabial } 186199855Ssobomax curs_move(&curx, &cury, curx, cury); 18742002Sabial#endif 18842002Sabial } 18942002Sabial} 19042002Sabial 19142002Sabial#ifdef TERM_EMU 19242002Sabial 19342002Sabial/* Get cursor position on the screen. Result is in edx. Sets 19442002Sabial * curx and cury appropriately. 19542002Sabial */ 19642002Sabialvoid 197199855Ssobomaxget_pos(int *x, int *y) 19842002Sabial{ 19984276Syokota 20042002Sabial v86.ctl = 0; 20142002Sabial v86.addr = 0x10; 20242002Sabial v86.eax = 0x0300; 20342002Sabial v86.ebx = 0x0; 20442002Sabial v86int(); 205199855Ssobomax *x = v86.edx & 0x00ff; 206199855Ssobomax *y = (v86.edx & 0xff00) >> 8; 20742002Sabial} 20842002Sabial 20942002Sabial/* Move cursor to x rows and y cols (0-based). */ 21042002Sabialvoid 211199855Ssobomaxcurs_move(int *_x, int *_y, int x, int y) 21242002Sabial{ 21384276Syokota 21442002Sabial v86.ctl = 0; 21542002Sabial v86.addr = 0x10; 21642002Sabial v86.eax = 0x0200; 21742002Sabial v86.ebx = 0x0; 21884276Syokota v86.edx = ((0x00ff & y) << 8) + (0x00ff & x); 21942002Sabial v86int(); 220199855Ssobomax *_x = x; 221199855Ssobomax *_y = y; 22242002Sabial /* If there is ctrl char at this position, cursor would be invisible. 22342002Sabial * Make it a space instead. 22442002Sabial */ 22584276Syokota v86.ctl = 0; 22642002Sabial v86.addr = 0x10; 22742002Sabial v86.eax = 0x0800; 22884276Syokota v86.ebx = 0x0; 22942002Sabial v86int(); 23084354Syokota#define isvisible(c) (((c) >= 32) && ((c) < 255)) 23184276Syokota if (!isvisible(v86.eax & 0x00ff)) { 23284276Syokota write_char(' ', fg_c, bg_c); 23342002Sabial } 23442002Sabial} 23542002Sabial 23642002Sabial/* Scroll up the whole window by a number of rows. If rows==0, 23742002Sabial * clear the window. fg and bg are attributes for the new lines 23842002Sabial * inserted in the window. 23942002Sabial */ 24042002Sabialvoid 24164187Sjhbscroll_up(int rows, int fgcol, int bgcol) 24242002Sabial{ 24384276Syokota 24484276Syokota if (rows == 0) 24584276Syokota rows = 25; 24684276Syokota v86.ctl = 0; 24784276Syokota v86.addr = 0x10; 24884276Syokota v86.eax = 0x0600 + (0x00ff & rows); 24984276Syokota v86.ebx = (bgcol << 12) + (fgcol << 8); 25084276Syokota v86.ecx = 0x0; 25184276Syokota v86.edx = 0x184f; 25284276Syokota v86int(); 25342002Sabial} 25442002Sabial 25542002Sabial/* Write character and attribute at cursor position. */ 25642002Sabialvoid 25764187Sjhbwrite_char(int c, int fgcol, int bgcol) 25842002Sabial{ 25984276Syokota 26084276Syokota v86.ctl = 0; 26184276Syokota v86.addr = 0x10; 26284276Syokota v86.eax = 0x0900 + (0x00ff & c); 26384276Syokota v86.ebx = (bgcol << 4) + fgcol; 26484276Syokota v86.ecx = 0x1; 26584276Syokota v86int(); 26642002Sabial} 26742002Sabial 26842002Sabial/**************************************************************/ 26942002Sabial/* 27042002Sabial * Screen manipulation functions. They use accumulated data in 27142002Sabial * args[] and argc variables. 27242002Sabial * 27342002Sabial */ 27442002Sabial 27542002Sabial/* Clear display from current position to end of screen */ 27642002Sabialvoid 27742002SabialCD(void) 27842002Sabial{ 27984276Syokota 280199855Ssobomax get_pos(&curx, &cury); 28184277Syokota if (curx > 0) { 28284277Syokota v86.ctl = 0; 28384277Syokota v86.addr = 0x10; 28484277Syokota v86.eax = 0x0600; 28584277Syokota v86.ebx = (bg_c << 4) + fg_c; 28684277Syokota v86.ecx = (cury << 8) + curx; 28784277Syokota v86.edx = (cury << 8) + 79; 28884277Syokota v86int(); 28984277Syokota if (++cury > 24) { 29084277Syokota end_term(); 29184277Syokota return; 29284277Syokota } 29384277Syokota } 29442002Sabial v86.ctl = 0; 29542002Sabial v86.addr = 0x10; 29642002Sabial v86.eax = 0x0600; 29784276Syokota v86.ebx = (bg_c << 4) + fg_c; 29884277Syokota v86.ecx = (cury << 8) + 0; 29984277Syokota v86.edx = (24 << 8) + 79; 30042002Sabial v86int(); 30142002Sabial end_term(); 30242002Sabial} 30342002Sabial 30442002Sabial/* Absolute cursor move to args[0] rows and args[1] columns 30542002Sabial * (the coordinates are 1-based). 30642002Sabial */ 30742002Sabialvoid 30842002SabialCM(void) 30942002Sabial{ 31084276Syokota 31184276Syokota if (args[0] > 0) 31284276Syokota args[0]--; 31384276Syokota if (args[1] > 0) 31484276Syokota args[1]--; 315199855Ssobomax curs_move(&curx, &cury, args[1], args[0]); 31642002Sabial end_term(); 31742002Sabial} 31842002Sabial 31942002Sabial/* Home cursor (left top corner) */ 32042002Sabialvoid 32142002SabialHO(void) 32242002Sabial{ 32384276Syokota 32484276Syokota argc = 1; 32584276Syokota args[0] = args[1] = 1; 32684276Syokota CM(); 32742002Sabial} 32842002Sabial 32942002Sabial/* Clear internal state of the terminal emulation code */ 33042002Sabialvoid 33142002Sabialend_term(void) 33242002Sabial{ 33384276Syokota 33484276Syokota esc = 0; 33584276Syokota argc = -1; 33642002Sabial} 33742002Sabial 33842002Sabial/* Gracefully exit ESC-sequence processing in case of misunderstanding */ 33942002Sabialvoid 34042002Sabialbail_out(int c) 34142002Sabial{ 34284371Syokota char buf[16], *ch; 34384371Syokota int i; 34442002Sabial 34584371Syokota if (esc) { 34684276Syokota vidc_rawputchar('\033'); 34784371Syokota if (esc != '\033') 34884371Syokota vidc_rawputchar(esc); 34984371Syokota for (i = 0; i <= argc; ++i) { 35084371Syokota sprintf(buf, "%d", args[i]); 35184276Syokota ch = buf; 35284276Syokota while (*ch) 35384276Syokota vidc_rawputchar(*ch++); 35442002Sabial } 35584276Syokota } 35684276Syokota vidc_rawputchar(c); 35784276Syokota end_term(); 35842002Sabial} 35942002Sabial 36084371Syokotastatic void 361144837Sstefanfget_arg(int c) 36284371Syokota{ 36384371Syokota 36484371Syokota if (argc < 0) 36584371Syokota argc = 0; 36684371Syokota args[argc] *= 10; 36784371Syokota args[argc] += c - '0'; 36884371Syokota} 36984371Syokota 37042002Sabial/* Emulate basic capabilities of cons25 terminal */ 37142002Sabialvoid 37242002Sabialvidc_term_emu(int c) 37342002Sabial{ 37484371Syokota static int ansi_col[] = { 37584371Syokota 0, 4, 2, 6, 1, 5, 3, 7, 37684371Syokota }; 37784371Syokota int t; 37884371Syokota int i; 37942002Sabial 38084371Syokota switch (esc) { 38184371Syokota case 0: 38284371Syokota switch (c) { 38384371Syokota case '\033': 38484371Syokota esc = c; 38584371Syokota break; 38684371Syokota default: 38742002Sabial vidc_rawputchar(c); 38884371Syokota break; 38942002Sabial } 39084371Syokota break; 39142002Sabial 39242002Sabial case '\033': 39384371Syokota switch (c) { 39484371Syokota case '[': 39584371Syokota esc = c; 39684371Syokota args[0] = 0; 39784371Syokota argc = -1; 39884371Syokota break; 39984371Syokota default: 40084371Syokota bail_out(c); 40184371Syokota break; 40284371Syokota } 40342002Sabial break; 40484371Syokota 40542002Sabial case '[': 40684371Syokota switch (c) { 40784371Syokota case ';': 40884371Syokota if (argc < 0) /* XXX */ 40984371Syokota argc = 0; 41084371Syokota else if (argc + 1 >= MAXARGS) 41184371Syokota bail_out(c); 41284371Syokota else 41384371Syokota args[++argc] = 0; 41484371Syokota break; 41584371Syokota case 'H': 41684371Syokota if (argc < 0) 41742002Sabial HO(); 41884371Syokota else if (argc == 1) 41942002Sabial CM(); 42084371Syokota else 42142002Sabial bail_out(c); 42284371Syokota break; 42384371Syokota case 'J': 42484371Syokota if (argc < 0) 42584371Syokota CD(); 42684371Syokota else 42784371Syokota bail_out(c); 42884371Syokota break; 42984371Syokota case 'm': 43084371Syokota if (argc < 0) { 43184371Syokota fg_c = DEFAULT_FGCOLOR; 43284371Syokota bg_c = DEFAULT_BGCOLOR; 43342002Sabial } 43484371Syokota for (i = 0; i <= argc; ++i) { 43584371Syokota switch (args[i]) { 43684371Syokota case 0: /* back to normal */ 43784371Syokota fg_c = DEFAULT_FGCOLOR; 43884371Syokota bg_c = DEFAULT_BGCOLOR; 43984371Syokota break; 44084371Syokota case 1: /* bold */ 44184371Syokota fg_c |= 0x8; 44284371Syokota break; 44384371Syokota case 4: /* underline */ 44484371Syokota case 5: /* blink */ 44584371Syokota bg_c |= 0x8; 44684371Syokota break; 44784371Syokota case 7: /* reverse */ 44884371Syokota t = fg_c; 44984371Syokota fg_c = bg_c; 45084371Syokota bg_c = t; 45184371Syokota break; 45284371Syokota case 30: case 31: case 32: case 33: 45384371Syokota case 34: case 35: case 36: case 37: 45484371Syokota fg_c = ansi_col[args[i] - 30]; 45584371Syokota break; 45684371Syokota case 39: /* normal */ 45784371Syokota fg_c = DEFAULT_FGCOLOR; 45884371Syokota break; 45984371Syokota case 40: case 41: case 42: case 43: 46084371Syokota case 44: case 45: case 46: case 47: 46184371Syokota bg_c = ansi_col[args[i] - 40]; 46284371Syokota break; 46384371Syokota case 49: /* normal */ 46484371Syokota bg_c = DEFAULT_BGCOLOR; 46584371Syokota break; 46684371Syokota } 46784371Syokota } 46884371Syokota end_term(); 46984371Syokota break; 47084371Syokota default: 47184371Syokota if (isdigit(c)) 47284371Syokota get_arg(c); 47384371Syokota else 47442002Sabial bail_out(c); 47584371Syokota break; 47684371Syokota } 47742002Sabial break; 47884371Syokota 47942002Sabial default: 48084371Syokota bail_out(c); 48142002Sabial break; 48242002Sabial } 48339441Smsmith} 48442002Sabial#endif 48539441Smsmith 48642002Sabialstatic void 48742002Sabialvidc_putchar(int c) 48842002Sabial{ 48942002Sabial#ifdef TERM_EMU 49042002Sabial vidc_term_emu(c); 49142002Sabial#else 49242002Sabial vidc_rawputchar(c); 49342002Sabial#endif 49442002Sabial} 49542002Sabial 49638465Smsmithstatic int 49739441Smsmithvidc_getchar(void) 49838465Smsmith{ 49984276Syokota 50039441Smsmith if (vidc_ischar()) { 50139441Smsmith v86.ctl = 0; 50239441Smsmith v86.addr = 0x16; 50339441Smsmith v86.eax = 0x0; 50439441Smsmith v86int(); 50584276Syokota return (v86.eax & 0xff); 50638465Smsmith } else { 50784276Syokota return (-1); 50838465Smsmith } 50938465Smsmith} 51038465Smsmith 51139441Smsmithstatic int 51239441Smsmithvidc_ischar(void) 51339441Smsmith{ 51484276Syokota 51540032Smsmith v86.ctl = V86_FLAGS; 51639441Smsmith v86.addr = 0x16; 51739441Smsmith v86.eax = 0x100; 51839441Smsmith v86int(); 519226746Sjhb return (!V86_ZR(v86.efl)); 52039441Smsmith} 52139441Smsmith 52239441Smsmith#if KEYBOARD_PROBE 52339441Smsmith 52438465Smsmith#define PROBE_MAXRETRY 5 52538465Smsmith#define PROBE_MAXWAIT 400 52638465Smsmith#define IO_DUMMY 0x84 52738465Smsmith#define IO_KBD 0x060 /* 8042 Keyboard */ 52838465Smsmith 52938465Smsmith/* selected defines from kbdio.h */ 53038465Smsmith#define KBD_STATUS_PORT 4 /* status port, read */ 53138465Smsmith#define KBD_DATA_PORT 0 /* data port, read/write 53238465Smsmith * also used as keyboard command 53338465Smsmith * and mouse command port 53438465Smsmith */ 53538465Smsmith#define KBDC_ECHO 0x00ee 53638465Smsmith#define KBDS_ANY_BUFFER_FULL 0x0001 53738465Smsmith#define KBDS_INPUT_BUFFER_FULL 0x0002 53838465Smsmith#define KBD_ECHO 0x00ee 53938465Smsmith 54038465Smsmith/* 7 microsec delay necessary for some keyboard controllers */ 54138465Smsmithstatic void 54238465Smsmithdelay7(void) 54338465Smsmith{ 54438465Smsmith /* 54542002Sabial * I know this is broken, but no timer is available yet at this stage... 54638465Smsmith * See also comments in `delay1ms()'. 54738465Smsmith */ 54838465Smsmith inb(IO_DUMMY); inb(IO_DUMMY); 54938465Smsmith inb(IO_DUMMY); inb(IO_DUMMY); 55038465Smsmith inb(IO_DUMMY); inb(IO_DUMMY); 55138465Smsmith} 55238465Smsmith 55338465Smsmith/* 55438465Smsmith * This routine uses an inb to an unused port, the time to execute that 55538465Smsmith * inb is approximately 1.25uS. This value is pretty constant across 55638465Smsmith * all CPU's and all buses, with the exception of some PCI implentations 55780203Skris * that do not forward this I/O address to the ISA bus as they know it 55838465Smsmith * is not a valid ISA bus address, those machines execute this inb in 55938465Smsmith * 60 nS :-(. 56038465Smsmith * 56138465Smsmith */ 56238465Smsmithstatic void 56338465Smsmithdelay1ms(void) 56438465Smsmith{ 56538465Smsmith int i = 800; 56638465Smsmith while (--i >= 0) 56738465Smsmith (void)inb(0x84); 56838465Smsmith} 56938465Smsmith 57038465Smsmith/* 57138465Smsmith * We use the presence/absence of a keyboard to determine whether the internal 57238465Smsmith * console can be used for input. 57338465Smsmith * 57438465Smsmith * Perform a simple test on the keyboard; issue the ECHO command and see 57538465Smsmith * if the right answer is returned. We don't do anything as drastic as 57638465Smsmith * full keyboard reset; it will be too troublesome and take too much time. 57738465Smsmith */ 57838465Smsmithstatic int 57938465Smsmithprobe_keyboard(void) 58038465Smsmith{ 58138465Smsmith int retry = PROBE_MAXRETRY; 58238465Smsmith int wait; 58338465Smsmith int i; 58438465Smsmith 58538465Smsmith while (--retry >= 0) { 58638465Smsmith /* flush any noise */ 58738465Smsmith while (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) { 58838465Smsmith delay7(); 58938465Smsmith inb(IO_KBD + KBD_DATA_PORT); 59038465Smsmith delay1ms(); 59138465Smsmith } 59238465Smsmith 59338465Smsmith /* wait until the controller can accept a command */ 59438465Smsmith for (wait = PROBE_MAXWAIT; wait > 0; --wait) { 59538465Smsmith if (((i = inb(IO_KBD + KBD_STATUS_PORT)) 59638465Smsmith & (KBDS_INPUT_BUFFER_FULL | KBDS_ANY_BUFFER_FULL)) == 0) 59738465Smsmith break; 59838465Smsmith if (i & KBDS_ANY_BUFFER_FULL) { 59938465Smsmith delay7(); 60038465Smsmith inb(IO_KBD + KBD_DATA_PORT); 60138465Smsmith } 60238465Smsmith delay1ms(); 60338465Smsmith } 60438465Smsmith if (wait <= 0) 60538465Smsmith continue; 60638465Smsmith 60738465Smsmith /* send the ECHO command */ 60838465Smsmith outb(IO_KBD + KBD_DATA_PORT, KBDC_ECHO); 60938465Smsmith 61038465Smsmith /* wait for a response */ 61138465Smsmith for (wait = PROBE_MAXWAIT; wait > 0; --wait) { 61238465Smsmith if (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) 61338465Smsmith break; 61438465Smsmith delay1ms(); 61538465Smsmith } 61638465Smsmith if (wait <= 0) 61738465Smsmith continue; 61838465Smsmith 61938465Smsmith delay7(); 62038465Smsmith i = inb(IO_KBD + KBD_DATA_PORT); 62138465Smsmith#ifdef PROBE_KBD_BEBUG 62238465Smsmith printf("probe_keyboard: got 0x%x.\n", i); 62338465Smsmith#endif 62438465Smsmith if (i == KBD_ECHO) { 62538465Smsmith /* got the right answer */ 626232309Sjkim return (1); 62738465Smsmith } 62838465Smsmith } 62938465Smsmith 630232309Sjkim return (0); 63138465Smsmith} 63239441Smsmith#endif /* KEYBOARD_PROBE */ 633