aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorSøren Schmidt <sos@FreeBSD.org>1996-11-14 22:19:17 +0000
committerSøren Schmidt <sos@FreeBSD.org>1996-11-14 22:19:17 +0000
commit6a90d9750d93e0fc7c4e3cffdb8efb33a9135ccc (patch)
tree650a2881d1f41e3f84cc51aa2e2bbbe5d8633068 /sys/dev
parent83a856baa661ee7dd73ea4d4fa95cbdc19276d29 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/syscons/syscons.c173
1 files changed, 71 insertions, 102 deletions
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index ef95daa32977..5b806e61e74c 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.185 1996/11/11 22:01:56 nate Exp $
+ * $Id: syscons.c,v 1.182.2.3 1996/11/12 09:08:53 phk Exp $
*/
#include "sc.h"
@@ -69,6 +69,7 @@
#include <i386/isa/isa_device.h>
#include <i386/isa/timerreg.h>
#include <i386/isa/kbdtables.h>
+#include <i386/isa/kbdio.h>
#include <i386/isa/syscons.h>
#if !defined(MAXCONS)
@@ -101,6 +102,7 @@ static scr_stat *new_scp, *old_scp;
static term_stat kernel_console;
static default_attr *current_default;
static int flags = 0;
+static int sc_port;
static char init_done = COLD;
static u_short sc_buffer[ROW*COL];
static char switch_in_progress = FALSE;
@@ -192,8 +194,6 @@ static void history_to_screen(scr_stat *scp);
static int history_up_line(scr_stat *scp);
static int history_down_line(scr_stat *scp);
static int mask2attr(struct term_stat *term);
-static void kbd_wait(void);
-static void kbd_cmd(u_char command);
static void update_leds(int which);
static void set_vgaregs(char *modetable);
static void set_font_mode(void);
@@ -294,73 +294,72 @@ move_crsr(scr_stat *scp, int x, int y)
static int
scprobe(struct isa_device *dev)
{
- int i, j, retries = 5;
- int xt_keyboard = 0;
- u_char val;
+ int c;
- /* Enable interrupts and keyboard controller */
- kbd_wait();
- outb(KB_STAT, KB_WRITE);
- kbd_wait();
- outb(KB_DATA, KB_MODE);
+ sc_port = dev->id_iobase;
- /* flush any noise in the buffer */
- while (inb(KB_STAT) & KB_BUF_FULL) {
- DELAY(100);
- (void) inb(KB_DATA);
+ /* save the current keyboard controller command byte */
+ write_controller_command(sc_port, KBDC_GET_COMMAND_BYTE);
+ c = read_controller_data(sc_port);
+ if (c == -1) {
+ printf("sc%d: unable to get the current command byte value.\n",
+ dev->id_unit);
+ goto fail;
}
- /* Reset keyboard hardware */
- while (retries--) {
- kbd_wait();
- outb(KB_DATA, KB_RESET);
- for (i=0; i<10000; i++) {
- DELAY(100);
- val = inb(KB_DATA);
- if (val == KB_ACK || val == KB_ECHO)
- goto gotres;
- if (val == KB_RESEND)
- break;
- }
- }
-gotres:
- if (retries < 0) {
- printf("scprobe: keyboard won't accept RESET command\n");
+ /*
+ * enable the keyboard port, but disable the keyboard intr.
+ * the aux port (mouse port) is disabled too.
+ */
+ write_controller_command(sc_port, KBDC_DISABLE_KBD_PORT);
+ set_controller_command_byte(sc_port,
+ c&~(KBD_KBD_CONTROL_BITS|KBD_AUX_CONTROL_BITS),
+ KBD_ENABLE_KBD_PORT|KBD_DISABLE_KBD_INT
+ |KBD_DISABLE_AUX_PORT|KBD_DISABLE_AUX_INT);
+
+ /* flush any noise in the buffer */
+ empty_both_buffers(sc_port);
+
+ /* reset keyboard hardware */
+ if (!reset_kbd(sc_port)) {
+ /*
+ * Keyboard reset may fail either because the keyboard doen't exist,
+ * or because the keyboard doesn't pass the self-test, or the keyboard
+ * controller on the motherboard and the keyboard somehow fail to
+ * shake hands. It is just possible, particularly in the last case,
+ * that the keyoard controller may be left in a hung state.
+ * test_controller() and test_kbd_port() appear to bring the keyboard
+ * controller back (I don't know why and how, though.)
+ */
+ test_controller(sc_port);
+ test_kbd_port(sc_port);
+ /* We could disable the keyboard port and interrupt... but,
+ * the keyboard may still exist (see above). Just leave the command
+ * byte as before.
+ */
+ set_controller_command_byte(sc_port, c, 0);
goto fail;
- } else {
- i = 10; /* At most 10 retries. */
-gotack:
- DELAY(100);
- j = 1000; /* Wait at most 1 s. */
- while ((inb(KB_STAT) & KB_BUF_FULL) == 0 && --j > 0) DELAY(1000);
- DELAY(1000);
- val = inb(KB_DATA);
- if (val == KB_ACK && --i > 0)
- goto gotack;
- if (val != KB_RESET_DONE) {
- printf("scprobe: keyboard RESET failed (result = 0x%02x)\n", val);
- goto fail;
- }
}
/*
* Allow us to set the XT_KEYBD flag in UserConfig so that keyboards
* such as those on the IBM ThinkPad laptop computers can be used
* with the standard console driver.
*/
- if ( dev->id_flags & XT_KEYBD )
- xt_keyboard = 1;
- if ( xt_keyboard ) {
- kbd_wait();
- outb(KB_DATA, 0xF0);
- kbd_wait();
- outb(KB_DATA, 1);
- kbd_wait();
+ if (dev->id_flags & XT_KEYBD) {
+ if (send_kbd_command_and_data(
+ sc_port, KBDC_SET_SCAN_CODESET, 1) == KBD_ACK)
+ /* XT kbd doesn't need scan code translation */
+ c &= ~KBD_TRANSLATION;
+ wait_while_controller_busy(sc_port);
}
+ /* enable the keyboard port and intr. */
+ set_controller_command_byte(sc_port, c & ~KBD_KBD_CONTROL_BITS,
+ KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT);
- succeed:
+succeed:
return (IO_KBDSIZE);
- fail:
+fail:
return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
}
@@ -1122,8 +1121,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
if (*data & 0x80)
return EINVAL;
i = spltty();
- kbd_cmd(KB_SETRAD);
- kbd_cmd(*data);
+ send_kbd_command_and_data(sc_port, KBDC_SET_TYPEMATIC, *data);
splx(i);
return 0;
@@ -1466,7 +1464,7 @@ scrn_timer()
* This Ugly hack calls scintr if input is ready and
* conveniently hides the problem. XXX
*/
- if (inb(KB_STAT) & KB_BUF_FULL)
+ if (inb(sc_port + KBD_STATUS_PORT) & KBDS_KBD_BUFFER_FULL)
scintr(0);
/* should we just return ? */
@@ -2489,21 +2487,25 @@ history_down_line(scr_stat *scp)
static u_int
scgetc(u_int flags)
{
+ struct key_t *key;
u_char scancode, keycode;
u_int state, action;
- struct key_t *key;
+ int c;
static u_char esc_flag = 0, compose = 0;
static u_int chr = 0;
next_code:
- if (inb(KB_STAT) & KB_BUF_FULL) {
- DELAY(25);
- scancode = inb(KB_DATA);
+ /* first see if there is something in the keyboard port */
+ if (flags & SCGETC_NONBLOCK) {
+ c = read_kbd_data_no_wait(sc_port);
+ if (c == -1)
+ return(NOKEY);
+ } else {
+ do {
+ c = read_kbd_data(sc_port);
+ } while(c == -1);
}
- else if (flags & SCGETC_NONBLOCK)
- return(NOKEY);
- else
- goto next_code;
+ scancode = (u_char)c;
/* do the /dev/random device a favour */
if (!(flags & SCGETC_CN))
@@ -2954,40 +2956,6 @@ mask2attr(struct term_stat *term)
}
static void
-kbd_wait(void)
-{
- int i = 500;
-
- while (i--) {
- if ((inb(KB_STAT) & KB_READY) == 0)
- break;
- DELAY (25);
- }
-}
-
-static void
-kbd_cmd(u_char command)
-{
- int i, retry = 5;
- do {
- kbd_wait();
- outb(KB_DATA, command);
- i = 50000;
- while (i--) {
- if (inb(KB_STAT) & KB_BUF_FULL) {
- int val;
- DELAY(25);
- val = inb(KB_DATA);
- if (val == KB_ACK)
- return;
- if (val == KB_RESEND)
- break;
- }
- }
- } while (retry--);
-}
-
-static void
update_leds(int which)
{
int s;
@@ -3000,9 +2968,10 @@ update_leds(int which)
else
which &= ~CLKED;
}
+
s = spltty();
- kbd_cmd(KB_SETLEDS);
- kbd_cmd(xlate_leds[which & LED_MASK]);
+ send_kbd_command_and_data(sc_port, KBDC_SET_LEDS,
+ xlate_leds[which & LED_MASK]);
splx(s);
}