aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/alpha/include/console.h16
-rw-r--r--sys/alpha/include/mouse.h100
-rw-r--r--sys/conf/files.i3864
-rw-r--r--sys/dev/syscons/syscons.c181
-rw-r--r--sys/i386/conf/files.i3864
-rw-r--r--sys/i386/include/console.h16
-rw-r--r--sys/i386/include/mouse.h100
-rw-r--r--sys/i386/isa/kbd.h56
-rw-r--r--sys/i386/isa/kbdio.c470
-rw-r--r--sys/i386/isa/kbdio.h204
-rw-r--r--sys/i386/isa/syscons.c181
-rw-r--r--sys/isa/kbdio.c470
-rw-r--r--sys/isa/kbdio.h204
-rw-r--r--sys/isa/syscons.c181
-rw-r--r--sys/sys/mouse.h100
15 files changed, 1854 insertions, 433 deletions
diff --git a/sys/alpha/include/console.h b/sys/alpha/include/console.h
index 3e641a75f57f..de049daad5c5 100644
--- a/sys/alpha/include/console.h
+++ b/sys/alpha/include/console.h
@@ -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: console.h,v 1.24 1996/09/21 14:57:54 bde Exp $
+ * $Id: console.h,v 1.25 1996/09/30 23:00:23 sos Exp $
*/
#ifndef _MACHINE_CONSOLE_H_
@@ -278,20 +278,6 @@ typedef struct ssaver ssaver_t;
#define KB_BUF_FULL 0x02 /* kbd has char pending */
#define KB_READY 0x02 /* kbd ready for command */
#define KB_WRITE 0x43 /* kbd write command */
-#else
-#define KB_DATA 0x60 /* kbd data port */
-#define KB_STAT 0x64 /* kbd status port */
-#define KB_BUF_FULL 0x01 /* kbd has char pending */
-#define KB_READY 0x02 /* kbd ready for command */
-#define KB_MODE 0x4D /* kbd mode (trans, ints enable)*/
-#define KB_WRITE 0x60 /* kbd write command */
-#define KB_RESET_DONE 0xAA /* kbd reset command completed */
-#define KB_SETLEDS 0xED /* kbd set leds */
-#define KB_ECHO 0xEE /* kbd set leds */
-#define KB_SETRAD 0xF3 /* kbd set repeat&delay command */
-#define KB_ACK 0xFA /* kbd acknowledge answer */
-#define KB_RESEND 0xFE /* kbd resend cmd answer */
-#define KB_RESET 0xFF /* kbd reset */
#endif
/* video mode definitions */
diff --git a/sys/alpha/include/mouse.h b/sys/alpha/include/mouse.h
index 95a66e474c6d..a7322b737571 100644
--- a/sys/alpha/include/mouse.h
+++ b/sys/alpha/include/mouse.h
@@ -19,17 +19,36 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: mouse.h,v 1.1 1994/05/17 14:05:31 jkh Exp $
+ * $Id: mouse.h,v 1.1 1994/09/09 11:27:31 dfr Exp $
*/
-struct mouseinfo {
- unsigned char status;
- char xmotion, ymotion;
-};
+#ifndef _MACHINE_MOUSE_H_
+#define _MACHINE_MOUSE_H_
+
+#include <sys/types.h>
+#include <sys/ioccom.h>
+
+/* NOTE: MOUSEIOC and MOUSEIOCREAD are now obsolete, but will stay
+ for compatibility reasons. But, remember, the MOUSEIOCREAD ioctl
+ command doesn't work and never worked before. Some day we shall
+ get rid of these... */
+#define MOUSEIOC ('M'<<8)
+#define MOUSEIOCREAD (MOUSEIOC|60)
+
+#define MOUSE_GETSTATE _IOR('M',0,mouseinfo_t)
+#define MOUSE_GETINFO _IOR('M',1,mousehw_t)
+#define MOUSE_GETMODE _IOR('M',2,mousemode_t)
+#define MOUSE_SETMODE _IOW('M',3,mousemode_t)
+
+typedef struct mouseinfo {
+ unsigned char status;
+ char xmotion;
+ char ymotion;
+} mouseinfo_t;
+/* status */
#define BUTSTATMASK 0x07 /* Any mouse button down if any bit set */
#define BUTCHNGMASK 0x38 /* Any mouse button changed if any bit set */
-
#define BUT3STAT 0x01 /* Button 3 down if set */
#define BUT2STAT 0x02 /* Button 2 down if set */
#define BUT1STAT 0x04 /* Button 1 down if set */
@@ -38,7 +57,70 @@ struct mouseinfo {
#define BUT1CHNG 0x20 /* Button 1 changed if set */
#define MOVEMENT 0x40 /* Mouse movement detected */
-/* Ioctl definitions */
+typedef struct mousehw {
+ int buttons;
+ int iftype; /* MOUSE_IF_XXX */
+ int type; /* mouse/track ball/pad... */
+ int hwid; /* I/F dependent hardware ID
+ for the PS/2 mouse, it will be PSM_XXX_ID */
+} mousehw_t;
+/* iftype */
+#define MOUSE_IF_SERIAL 0
+#define MOUSE_IF_BUS 1
+#define MOUSE_IF_INPORT 2
+#define MOUSE_IF_PS2 3
+/* type */
+#define MOUSE_UNKNOWN (-1) /* should be treated as a mouse */
+#define MOUSE_MOUSE 0
+#define MOUSE_TRACKBALL 1
+#define MOUSE_STICK 2
+#define MOUSE_PAD 3
+
+typedef struct mousemode {
+ int protocol; /* MOUSE_PROTO_XXX */
+ int rate; /* report rate (per sec), -1 if unknown */
+ int resolution; /* ppi, -1 if unknown */
+ int accelfactor; /* accelation factor (must be 1 or greater) */
+} mousemode_t;
+/* protocol */
+#define MOUSE_PROTO_MS 0 /* Microsoft Serial, 3 bytes */
+#define MOUSE_PROTO_MSC 1 /* Mouse Systems, 5 bytes */
+#define MOUSE_PROTO_LOGI 2 /* Logitech, 3 bytes */
+#define MOUSE_PROTO_MM 3 /* MM series, 3 bytes */
+#define MOUSE_PROTO_LOGIMOUSEMAN 4 /* Logitech MouseMan 3/4 bytes */
+#define MOUSE_PROTO_BUS 5 /* MS/Logitech bus mouse */
+#define MOUSE_PROTO_INPORT 6 /* MS/ATI inport mouse */
+#define MOUSE_PROTO_PS2 7 /* PS/2 mouse, 3 bytes */
+
+/* Microsoft Serial mouse data packet */
+#define MOUSE_MSS_PACKETSIZE 3
+#define MOUSE_MSS_SYNCMASK 0x40
+#define MOUSE_MSS_SYNC 0x40
+#define MOUSE_MSS_BUTTONS 0x30
+#define MOUSE_MSS_BUTTON1DOWN 0x20 /* left */
+#define MOUSE_MSS_BUTTON2DOWN 0x00 /* no middle button */
+#define MOUSE_MSS_BUTTON3DOWN 0x10 /* right */
+
+/* Mouse Systems Corp. mouse data packet */
+#define MOUSE_MSC_PACKETSIZE 5
+#define MOUSE_MSC_SYNCMASK 0xf8
+#define MOUSE_MSC_SYNC 0x80
+#define MOUSE_MSC_BUTTONS 0x07
+#define MOUSE_MSC_BUTTON1UP 0x04 /* left */
+#define MOUSE_MSC_BUTTON2UP 0x02 /* middle */
+#define MOUSE_MSC_BUTTON3UP 0x01 /* right */
+
+/* PS/2 mouse data packet */
+#define MOUSE_PS2_PACKETSIZE 3
+#define MOUSE_PS2_SYNCMASK 0x08 /* 0x0c for 2 button mouse */
+#define MOUSE_PS2_SYNC 0x08 /* 0x0c for 2 button mouse */
+#define MOUSE_PS2_BUTTONS 0x07 /* 0x03 for 2 button mouse */
+#define MOUSE_PS2_BUTTON1DOWN 0x01 /* left */
+#define MOUSE_PS2_BUTTON2DOWN 0x04 /* middle */
+#define MOUSE_PS2_BUTTON3DOWN 0x02 /* right */
+#define MOUSE_PS2_XNEG 0x10
+#define MOUSE_PS2_YNEG 0x20
+#define MOUSE_PS2_XOVERFLOW 0x40
+#define MOUSE_PS2_YOVERFLOW 0x80
-#define MOUSEIOC ('M'<<8)
-#define MOUSEIOCREAD (MOUSEIOC|60)
+#endif /* _MACHINE_MOUSE_H_ */
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 3e727a6ee45a..a4fca64e5065 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.142 1996/11/04 22:16:36 guido Exp $
+# $Id: files.i386,v 1.143 1996/11/06 15:13:41 bde Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
@@ -115,6 +115,8 @@ i386/isa/if_zp.c optional zp device-driver
i386/isa/isa.c optional isa device-driver
i386/isa/istallion.c optional stli device-driver
i386/isa/joy.c optional joy device-driver
+i386/isa/kbdio.c optional psm device-driver
+i386/isa/kbdio.c optional sc device-driver
i386/isa/lpt.c optional lpt device-driver
i386/isa/labpc.c optional labpc device-driver
i386/isa/mcd.c optional mcd device-driver
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);
-
- /* flush any noise in the buffer */
- while (inb(KB_STAT) & KB_BUF_FULL) {
- DELAY(100);
- (void) inb(KB_DATA);
- }
-
- /* 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;
- }
+ sc_port = dev->id_iobase;
+
+ /* 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;
}
-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();
- }
-
- succeed:
+ 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:
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);
}
diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386
index 3e727a6ee45a..a4fca64e5065 100644
--- a/sys/i386/conf/files.i386
+++ b/sys/i386/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.142 1996/11/04 22:16:36 guido Exp $
+# $Id: files.i386,v 1.143 1996/11/06 15:13:41 bde Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
@@ -115,6 +115,8 @@ i386/isa/if_zp.c optional zp device-driver
i386/isa/isa.c optional isa device-driver
i386/isa/istallion.c optional stli device-driver
i386/isa/joy.c optional joy device-driver
+i386/isa/kbdio.c optional psm device-driver
+i386/isa/kbdio.c optional sc device-driver
i386/isa/lpt.c optional lpt device-driver
i386/isa/labpc.c optional labpc device-driver
i386/isa/mcd.c optional mcd device-driver
diff --git a/sys/i386/include/console.h b/sys/i386/include/console.h
index 3e641a75f57f..de049daad5c5 100644
--- a/sys/i386/include/console.h
+++ b/sys/i386/include/console.h
@@ -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: console.h,v 1.24 1996/09/21 14:57:54 bde Exp $
+ * $Id: console.h,v 1.25 1996/09/30 23:00:23 sos Exp $
*/
#ifndef _MACHINE_CONSOLE_H_
@@ -278,20 +278,6 @@ typedef struct ssaver ssaver_t;
#define KB_BUF_FULL 0x02 /* kbd has char pending */
#define KB_READY 0x02 /* kbd ready for command */
#define KB_WRITE 0x43 /* kbd write command */
-#else
-#define KB_DATA 0x60 /* kbd data port */
-#define KB_STAT 0x64 /* kbd status port */
-#define KB_BUF_FULL 0x01 /* kbd has char pending */
-#define KB_READY 0x02 /* kbd ready for command */
-#define KB_MODE 0x4D /* kbd mode (trans, ints enable)*/
-#define KB_WRITE 0x60 /* kbd write command */
-#define KB_RESET_DONE 0xAA /* kbd reset command completed */
-#define KB_SETLEDS 0xED /* kbd set leds */
-#define KB_ECHO 0xEE /* kbd set leds */
-#define KB_SETRAD 0xF3 /* kbd set repeat&delay command */
-#define KB_ACK 0xFA /* kbd acknowledge answer */
-#define KB_RESEND 0xFE /* kbd resend cmd answer */
-#define KB_RESET 0xFF /* kbd reset */
#endif
/* video mode definitions */
diff --git a/sys/i386/include/mouse.h b/sys/i386/include/mouse.h
index 95a66e474c6d..a7322b737571 100644
--- a/sys/i386/include/mouse.h
+++ b/sys/i386/include/mouse.h
@@ -19,17 +19,36 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: mouse.h,v 1.1 1994/05/17 14:05:31 jkh Exp $
+ * $Id: mouse.h,v 1.1 1994/09/09 11:27:31 dfr Exp $
*/
-struct mouseinfo {
- unsigned char status;
- char xmotion, ymotion;
-};
+#ifndef _MACHINE_MOUSE_H_
+#define _MACHINE_MOUSE_H_
+
+#include <sys/types.h>
+#include <sys/ioccom.h>
+
+/* NOTE: MOUSEIOC and MOUSEIOCREAD are now obsolete, but will stay
+ for compatibility reasons. But, remember, the MOUSEIOCREAD ioctl
+ command doesn't work and never worked before. Some day we shall
+ get rid of these... */
+#define MOUSEIOC ('M'<<8)
+#define MOUSEIOCREAD (MOUSEIOC|60)
+
+#define MOUSE_GETSTATE _IOR('M',0,mouseinfo_t)
+#define MOUSE_GETINFO _IOR('M',1,mousehw_t)
+#define MOUSE_GETMODE _IOR('M',2,mousemode_t)
+#define MOUSE_SETMODE _IOW('M',3,mousemode_t)
+
+typedef struct mouseinfo {
+ unsigned char status;
+ char xmotion;
+ char ymotion;
+} mouseinfo_t;
+/* status */
#define BUTSTATMASK 0x07 /* Any mouse button down if any bit set */
#define BUTCHNGMASK 0x38 /* Any mouse button changed if any bit set */
-
#define BUT3STAT 0x01 /* Button 3 down if set */
#define BUT2STAT 0x02 /* Button 2 down if set */
#define BUT1STAT 0x04 /* Button 1 down if set */
@@ -38,7 +57,70 @@ struct mouseinfo {
#define BUT1CHNG 0x20 /* Button 1 changed if set */
#define MOVEMENT 0x40 /* Mouse movement detected */
-/* Ioctl definitions */
+typedef struct mousehw {
+ int buttons;
+ int iftype; /* MOUSE_IF_XXX */
+ int type; /* mouse/track ball/pad... */
+ int hwid; /* I/F dependent hardware ID
+ for the PS/2 mouse, it will be PSM_XXX_ID */
+} mousehw_t;
+/* iftype */
+#define MOUSE_IF_SERIAL 0
+#define MOUSE_IF_BUS 1
+#define MOUSE_IF_INPORT 2
+#define MOUSE_IF_PS2 3
+/* type */
+#define MOUSE_UNKNOWN (-1) /* should be treated as a mouse */
+#define MOUSE_MOUSE 0
+#define MOUSE_TRACKBALL 1
+#define MOUSE_STICK 2
+#define MOUSE_PAD 3
+
+typedef struct mousemode {
+ int protocol; /* MOUSE_PROTO_XXX */
+ int rate; /* report rate (per sec), -1 if unknown */
+ int resolution; /* ppi, -1 if unknown */
+ int accelfactor; /* accelation factor (must be 1 or greater) */
+} mousemode_t;
+/* protocol */
+#define MOUSE_PROTO_MS 0 /* Microsoft Serial, 3 bytes */
+#define MOUSE_PROTO_MSC 1 /* Mouse Systems, 5 bytes */
+#define MOUSE_PROTO_LOGI 2 /* Logitech, 3 bytes */
+#define MOUSE_PROTO_MM 3 /* MM series, 3 bytes */
+#define MOUSE_PROTO_LOGIMOUSEMAN 4 /* Logitech MouseMan 3/4 bytes */
+#define MOUSE_PROTO_BUS 5 /* MS/Logitech bus mouse */
+#define MOUSE_PROTO_INPORT 6 /* MS/ATI inport mouse */
+#define MOUSE_PROTO_PS2 7 /* PS/2 mouse, 3 bytes */
+
+/* Microsoft Serial mouse data packet */
+#define MOUSE_MSS_PACKETSIZE 3
+#define MOUSE_MSS_SYNCMASK 0x40
+#define MOUSE_MSS_SYNC 0x40
+#define MOUSE_MSS_BUTTONS 0x30
+#define MOUSE_MSS_BUTTON1DOWN 0x20 /* left */
+#define MOUSE_MSS_BUTTON2DOWN 0x00 /* no middle button */
+#define MOUSE_MSS_BUTTON3DOWN 0x10 /* right */
+
+/* Mouse Systems Corp. mouse data packet */
+#define MOUSE_MSC_PACKETSIZE 5
+#define MOUSE_MSC_SYNCMASK 0xf8
+#define MOUSE_MSC_SYNC 0x80
+#define MOUSE_MSC_BUTTONS 0x07
+#define MOUSE_MSC_BUTTON1UP 0x04 /* left */
+#define MOUSE_MSC_BUTTON2UP 0x02 /* middle */
+#define MOUSE_MSC_BUTTON3UP 0x01 /* right */
+
+/* PS/2 mouse data packet */
+#define MOUSE_PS2_PACKETSIZE 3
+#define MOUSE_PS2_SYNCMASK 0x08 /* 0x0c for 2 button mouse */
+#define MOUSE_PS2_SYNC 0x08 /* 0x0c for 2 button mouse */
+#define MOUSE_PS2_BUTTONS 0x07 /* 0x03 for 2 button mouse */
+#define MOUSE_PS2_BUTTON1DOWN 0x01 /* left */
+#define MOUSE_PS2_BUTTON2DOWN 0x04 /* middle */
+#define MOUSE_PS2_BUTTON3DOWN 0x02 /* right */
+#define MOUSE_PS2_XNEG 0x10
+#define MOUSE_PS2_YNEG 0x20
+#define MOUSE_PS2_XOVERFLOW 0x40
+#define MOUSE_PS2_YOVERFLOW 0x80
-#define MOUSEIOC ('M'<<8)
-#define MOUSEIOCREAD (MOUSEIOC|60)
+#endif /* _MACHINE_MOUSE_H_ */
diff --git a/sys/i386/isa/kbd.h b/sys/i386/isa/kbd.h
deleted file mode 100644
index d34b6340675e..000000000000
--- a/sys/i386/isa/kbd.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Keyboard definitions
- * from: unknown origin, 386BSD 0.1
- * $Id: kbd.h,v 1.3 1993/11/07 17:44:33 wollman Exp $
- */
-
-#ifndef _I386_ISA_KBD_H_
-#define _I386_ISA_KBD_H_ 1
-
-/* Reference: IBM AT Technical Reference Manual,
- * pp. 1-38 to 1-43, 4-3 to 4-22
- */
-
-/* commands sent to KBCMDP */
-
-#define KBC_CMDREAD 0x20 /* read kbd cntrl command byte */
-#define KBC_CMDWRITE 0x60 /* == LD_CMDBYTE in kd.h, write command */
-#define KBC_SELFTEST 0xAA /* perform self test, returns 55 when ok */
-#define KBC_IFTEST 0xAB /* perform interface test */
-#define KBC_DIAGDUMP 0xAC /* send 19 status bytes to system */
-#define KBC_DISKBD 0xAD /* disable keyboard */
-#define KBC_ENAKBD 0xAE /* enable keyboard */
-#define KBC_RDINP 0xC0 /* read input port */
-#define KBC_RDID 0xC4 /* read keyboard ID */
-#define KBC_RDOUTP 0xD0 /* read output port */
-#define KBC_WROUTP 0xD1 /* write output port */
-#define KBC_RDTINP 0xE0 /* read test inputs */
-
-/* commands sent to KBDATAP */
-#define KBC_STSIND 0xED /* set keyboard status indicators */
-#define KBC_ECHO 0xEE /* reply with 0xEE */
-#define KBC_SETTPM 0xF3 /* Set typematic rate/delay */
-#define KBC_ENABLE 0xF4 /* Start scanning */
-#define KBC_SETDEFD 0xF5 /* =KBC_SETDEF, but disable scanning */
-#define KBC_SETDEF 0xF6 /* Set power on defaults */
-#define KBC_RESEND 0xFE /* system wants keyboard to resend last code */
-#define KBC_RESET 0xFF /* Reset the keyboard */
-
-/* responses */
-#define KBR_OVERRUN 0x00 /* Keyboard flooded */
-#define KBR_STOK 0x55 /* Selftest ok response */
-#define KBR_IFOK 0x00 /* Interface test ok */
-#define KBR_IFCL_SA0 0x01 /* Clock Stuck-at-0 fault */
-#define KBR_IFCL_SA1 0x02 /* Clock Stuck-at-1 fault */
-#define KBR_IFDA_SA0 0x03 /* Data Stuck-at-0 fault */
-#define KBR_IFDA_SA1 0x04 /* Data Stuck-at-1 fault */
-#define KBR_RSTDONE 0xAA /* Keyboard reset (BAT) complete */
-#define KBR_E0 0xE0 /* Extended prefix */
-#define KBR_E1 0xE1 /* BREAK'S HIT :-( */
-#define KBR_ECHO 0xEE /* Echo response */
-#define KBR_F0 0xF0 /* Break code prefix */
-#define KBR_ACK 0xFA /* Keyboard did receive command */
-#define KBR_BATFAIL 0xFC /* BAT failed */
-#define KBR_DIAGFAIL 0xFD /* Diagnostic failed response */
-#define KBR_RESEND 0xFE /* Keyboard needs resend of command */
-#endif /* _I386_ISA_KBD_H_ */
diff --git a/sys/i386/isa/kbdio.c b/sys/i386/isa/kbdio.c
new file mode 100644
index 000000000000..f3262958a8f5
--- /dev/null
+++ b/sys/i386/isa/kbdio.c
@@ -0,0 +1,470 @@
+/*-
+ * Copyright (c) 1996 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <machine/clock.h>
+#include <i386/isa/isa.h>
+#include <i386/isa/isa_device.h>
+#include <i386/isa/kbdio.h>
+
+/*
+ * device I/O routines
+ */
+int
+wait_while_controller_busy(int port)
+{
+ /* CPU will stay inside the loop for 100msec at most */
+ int retry = 5000;
+
+ while (inb(port + KBD_STATUS_PORT) & KBDS_CONTROLLER_BUSY) {
+ DELAY(20);
+ if (--retry < 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+int
+wait_until_controller_is_really_idle(int port)
+{
+ /* CPU will stay inside the loop for 100msec at most */
+ int retry = 5000;
+
+ while (inb(port + KBD_STATUS_PORT)
+ & (KBDS_CONTROLLER_BUSY | KBDS_ANY_BUFFER_FULL)) {
+ DELAY(20);
+ if (--retry < 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * wait for any data; whether it's from the controller,
+ * the keyboard, or the aux device.
+ */
+int
+wait_for_data(int port)
+{
+ /* CPU will stay inside the loop for 200msec at most */
+ int retry = 10000;
+
+ while ((inb(port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) == 0) {
+ DELAY(20);
+ if (--retry < 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* wait for data from the keyboard */
+int
+wait_for_kbd_data(int port)
+{
+ /* CPU will stay inside the loop for 200msec at most */
+ int retry = 10000;
+
+ while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ != KBDS_KBD_BUFFER_FULL) {
+ DELAY(20);
+ if (--retry < 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* wait for data from the aux device */
+int
+wait_for_aux_data(int port)
+{
+ /* CPU will stay inside the loop for 200msec at most */
+ int retry = 10000;
+
+ while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ != KBDS_AUX_BUFFER_FULL) {
+ DELAY(20);
+ if (--retry < 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+write_controller_command(int port, int c)
+{
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_COMMAND_PORT, c);
+}
+
+void
+write_controller_data(int port, int c)
+{
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+}
+
+void
+write_kbd_command(int port, int c)
+{
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+}
+
+void
+write_aux_command(int port, int c)
+{
+ write_controller_command(port,KBDC_WRITE_TO_AUX);
+ write_controller_data(port, c);
+}
+
+int
+send_kbd_command(int port, int c)
+{
+ int retry = KBD_MAXRETRY;
+ int res;
+
+ while (retry-- > 0) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+ res = read_controller_data(port);
+ if (res == KBD_ACK)
+ break;
+ }
+ return res;
+}
+
+int
+send_aux_command(int port, int c)
+{
+ int retry = KBD_MAXRETRY;
+ int res;
+
+ while (retry-- > 0) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_COMMAND_PORT, KBDC_WRITE_TO_AUX);
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+ res = read_aux_data(port);
+ if (res == PSM_ACK)
+ break;
+ }
+ return res;
+}
+
+int
+send_kbd_command_and_data(int port, int c, int d)
+{
+ int retry;
+ int res;
+
+ for (retry = KBD_MAXRETRY; retry > 0; --retry) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+ res = read_controller_data(port);
+ if (res == KBD_ACK)
+ break;
+ }
+
+ for (retry = KBD_MAXRETRY; retry > 0; --retry) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, d);
+ res = read_controller_data(port);
+ if (res != KBD_RESEND)
+ break;
+ }
+ return res;
+}
+
+int
+send_aux_command_and_data(int port, int c, int d)
+{
+ int retry;
+ int res;
+
+ for (retry = KBD_MAXRETRY; retry > 0; --retry) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_COMMAND_PORT, KBDC_WRITE_TO_AUX);
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+ res = read_aux_data(port);
+ if (res == PSM_ACK)
+ break;
+ else if (res != PSM_RESEND)
+ return res;
+ }
+
+ for (retry = KBD_MAXRETRY; retry > 0; --retry) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_COMMAND_PORT, KBDC_WRITE_TO_AUX);
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, d);
+ res = read_aux_data(port);
+ if (res != PSM_RESEND)
+ break;
+ }
+ return res;
+}
+
+/*
+ * read one byte from any source; whether from the controller,
+ * the keyboard, or the aux device
+ */
+int
+read_controller_data(int port)
+{
+ wait_while_controller_busy(port);
+ if (!wait_for_data(port))
+ return -1; /* timeout */
+ return inb(port + KBD_DATA_PORT);
+}
+
+/* read one byte from the keyboard */
+int
+read_kbd_data(int port)
+{
+ wait_while_controller_busy(port);
+ if (!wait_for_kbd_data(port))
+ return -1; /* timeout */
+ return inb(port + KBD_DATA_PORT);
+}
+
+/* read one byte from the keyboard, but return immediately if
+ * no data is waiting
+ */
+int
+read_kbd_data_no_wait(int port)
+{
+ wait_while_controller_busy(port);
+ if ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ != KBDS_KBD_BUFFER_FULL)
+ return -1; /* no data */
+ return inb(port + KBD_DATA_PORT);
+}
+
+/* read one byte from the aux device */
+int
+read_aux_data(int port)
+{
+ wait_while_controller_busy(port);
+ if (!wait_for_aux_data(port))
+ return -1; /* timeout */
+ return inb(port + KBD_DATA_PORT);
+}
+
+/* discard data from the keyboard */
+void
+empty_kbd_buffer(int port)
+{
+ int b;
+ int c = 0;
+
+ while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ == KBDS_KBD_BUFFER_FULL) {
+ b = inb(port + KBD_DATA_PORT);
+ ++c;
+ DELAY(20);
+ }
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: %d char read (empty_kbd_buffer)\n",c);
+#endif
+}
+
+/* discard data from the aux device */
+void
+empty_aux_buffer(int port)
+{
+ int b;
+ int c = 0;
+
+ while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ == KBDS_AUX_BUFFER_FULL) {
+ b = inb(port + KBD_DATA_PORT);
+ ++c;
+ DELAY(20);
+ }
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: %d char read (empty_aux_buffer)\n",c);
+#endif
+}
+
+/* discard any data from the keyboard or the aux device */
+void
+empty_both_buffers(int port)
+{
+ int b;
+ int c = 0;
+
+ while (inb(port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
+ b = inb(port + KBD_DATA_PORT);
+ ++c;
+ DELAY(20);
+ }
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: %d char read (empty_both_buffers)\n",c);
+#endif
+}
+
+/* keyboard and mouse device control */
+
+/* NOTE: enable the keyboard port but disable the keyboard
+ * interrupt before calling "reset_kbd()".
+ */
+int
+reset_kbd(int port)
+{
+ int retry = KBD_MAXRETRY;
+ int again = KBD_MAXWAIT;
+ int c;
+
+ while (retry-- > 0) {
+ empty_both_buffers(port);
+ write_kbd_command(port, KBDC_RESET_KBD);
+ c = read_controller_data(port);
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: RESET_KBD return code:%04x\n",c);
+#endif
+ if (c == KBD_ACK) /* keyboard has agreed to reset itself... */
+ break;
+ }
+ if (retry < 0)
+ return FALSE;
+
+ while (again-- > 0) {
+ /* wait awhile, well, in fact we must wait quite loooooooooooong */
+ DELAY(KBD_RESETDELAY*1000);
+ c = read_controller_data(port); /* RESET_DONE/RESET_FAIL */
+ if (c != -1) /* wait again if the controller is not ready */
+ break;
+ }
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: RESET_KBD status:%04x\n",c);
+#endif
+ if (c != KBD_RESET_DONE)
+ return FALSE;
+ return TRUE;
+}
+
+/* NOTE: enable the aux port but disable the aux interrupt
+ * before calling `reset_aux_dev()'.
+ */
+int
+reset_aux_dev(int port)
+{
+ int retry = KBD_MAXRETRY;
+ int again = KBD_MAXWAIT;
+ int c;
+
+ while (retry-- > 0) {
+ empty_both_buffers(port);
+ write_aux_command(port, PSMC_RESET_DEV);
+ c = read_controller_data(port); /* read_aux_data()? */
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: RESET_AUX return code:%04x\n",c);
+#endif
+ if (c == PSM_ACK) /* aux dev is about to reset... */
+ break;
+ }
+ if (retry < 0)
+ return FALSE;
+
+ while (again-- > 0) {
+ /* wait awhile, well, quite looooooooooooong */
+ DELAY(KBD_RESETDELAY*1000);
+ c = read_aux_data(port); /* RESET_DONE/RESET_FAIL */
+ if (c != -1) /* wait again if the controller is not ready */
+ break;
+ }
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: RESET_AUX status:%04x\n",c);
+#endif
+ if (c != PSM_RESET_DONE) /* reset status */
+ return FALSE;
+
+ c = read_aux_data(port); /* device ID */
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: RESET_AUX ID:%04x\n",c);
+#endif
+ /* NOTE: we could check the device ID now, but leave it later... */
+ return TRUE;
+}
+
+/* controller diagnostics and setup */
+
+int
+test_controller(int port)
+{
+ int c;
+
+ empty_both_buffers(port);
+ write_controller_command(port, KBDC_DIAGNOSE);
+ c = read_controller_data(port); /* DIAG_DONE/DIAG_FAIL */
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: DIAGNOSE status:%04x\n",c);
+#endif
+ return (c == KBD_DIAG_DONE);
+}
+
+int
+test_kbd_port(int port)
+{
+ int c;
+
+ empty_both_buffers(port);
+ write_controller_command(port, KBDC_TEST_KBD_PORT);
+ c = read_controller_data(port);
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: TEST_KBD_PORT status:%04x\n",c);
+#endif
+ return c;
+}
+
+int
+test_aux_port(int port)
+{
+ int c;
+
+ empty_both_buffers(port);
+ write_controller_command(port, KBDC_TEST_AUX_PORT);
+ c = read_controller_data(port);
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: TEST_AUX_PORT status:%04x\n",c);
+#endif
+ return c;
+}
+
+void
+set_controller_command_byte(int port, int command, int flag)
+{
+ write_controller_command(port, KBDC_SET_COMMAND_BYTE);
+ write_controller_data(port, command | flag);
+ wait_while_controller_busy(port);
+}
diff --git a/sys/i386/isa/kbdio.h b/sys/i386/isa/kbdio.h
new file mode 100644
index 000000000000..c5477800ec95
--- /dev/null
+++ b/sys/i386/isa/kbdio.h
@@ -0,0 +1,204 @@
+/*-
+ * Copyright (c) 1996 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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$
+ */
+
+#ifndef _I386_ISA_KBDIO_H_
+#define _I386_ISA_KBDIO_H_
+
+/* constants */
+
+/* I/O ports */
+#define KBD_STATUS_PORT 4 /* status port, read */
+#define KBD_COMMAND_PORT 4 /* controller command port, write */
+#define KBD_DATA_PORT 0 /* data port, read/write
+ also used as keyboard command
+ and mouse command port */
+/* FIXME: `IO_PSMSIZE' should really be in `isa.h'. */
+#define IO_PSMSIZE (KBD_COMMAND_PORT - KBD_DATA_PORT + 1) /* 5 */
+
+/* controller commands (sent to KBD_COMMAND_PORT) */
+#define KBDC_SET_COMMAND_BYTE 0x0060
+#define KBDC_GET_COMMAND_BYTE 0x0020
+#define KBDC_WRITE_TO_AUX 0x00d4
+#define KBDC_DISABLE_AUX_PORT 0x00a7
+#define KBDC_ENABLE_AUX_PORT 0x00a8
+#define KBDC_TEST_AUX_PORT 0x00a9
+#define KBDC_DIAGNOSE 0x00aa
+#define KBDC_TEST_KBD_PORT 0x00ab
+#define KBDC_DISABLE_KBD_PORT 0x00ad
+#define KBDC_ENABLE_KBD_PORT 0x00ae
+
+/* controller command byte (set by KBDC_SET_COMMAND_BYTE) */
+#define KBD_TRANSLATION 0x0040
+#define KBD_RESERVED_BITS 0x0004
+#define KBD_ENABLE_KBD_PORT 0x0000
+#define KBD_DISABLE_KBD_PORT 0x0010
+#define KBD_ENABLE_AUX_PORT 0x0000
+#define KBD_DISABLE_AUX_PORT 0x0020
+#define KBD_ENABLE_AUX_INT 0x0002
+#define KBD_DISABLE_AUX_INT 0x0000
+#define KBD_ENABLE_KBD_INT 0x0001
+#define KBD_DISABLE_KBD_INT 0x0000
+#define KBD_KBD_CONTROL_BITS (KBD_DISABLE_KBD_PORT | KBD_ENABLE_KBD_INT)
+#define KBD_AUX_CONTROL_BITS (KBD_DISABLE_AUX_PORT | KBD_ENABLE_AUX_INT)
+
+/* keyboard device commands (sent to KBD_DATA_PORT) */
+#define KBDC_RESET_KBD 0x00ff
+#define KBDC_ENABLE_KBD 0x00f4
+#define KBDC_DISABLE_KBD 0x00f5
+#define KBDC_SET_DEFAULTS 0x00f6
+#define KBDC_SEND_DEV_ID 0x00f2
+#define KBDC_SET_LEDS 0x00ed
+#define KBDC_ECHO 0x00ee
+#define KBDC_SET_SCAN_CODESET 0x00f0
+#define KBDC_SET_TYPEMATIC 0x00f3
+
+/* aux device commands (sent to KBD_DATA_PORT) */
+#define PSMC_RESET_DEV 0x00ff
+#define PSMC_ENABLE_DEV 0x00f4
+#define PSMC_DISABLE_DEV 0x00f5
+#define PSMC_SEND_DEV_ID 0x00f2
+#define PSMC_SEND_DEV_STATUS 0x00e9
+#define PSMC_SET_SCALING11 0x00e6
+#define PSMC_SET_SCALING21 0x00e7
+#define PSMC_SET_RESOLUTION 0x00e8
+#define PSMC_SET_STREAM_MODE 0x00ea
+#define PSMC_SET_SAMPLING_RATE 0x00f3
+
+/* PSMC_SET_RESOLUTION argument */
+#define PSMD_RESOLUTION_25 0 /* 25ppi */
+#define PSMD_RESOLUTION_50 1 /* 50ppi */
+#define PSMD_RESOLUTION_100 2 /* 100ppi (default after reset) */
+#define PSMD_RESOLUTION_200 3 /* 200ppi */
+/* FIXME: I don't know if it's possible to go beyond 200ppi.
+ The values below are of my wild guess. */
+#define PSMD_RESOLUTION_400 4 /* 400ppi */
+#define PSMD_RESOLUTION_800 5 /* 800ppi */
+#define PSMD_MAX_RESOLUTION PSMD_RESOLUTION_800
+
+/* PSMC_SET_SAMPLING_RATE */
+#define PSMD_MAX_RATE 255 /* FIXME: not sure if it's possible */
+
+/* status bits (KBD_STATUS_PORT) */
+#define KBDS_BUFFER_FULL 0x0021
+#define KBDS_ANY_BUFFER_FULL 0x0001
+#define KBDS_KBD_BUFFER_FULL 0x0001
+#define KBDS_AUX_BUFFER_FULL 0x0021
+#define KBDS_CONTROLLER_BUSY 0x0002
+
+/* return code */
+#define KBD_ACK 0x00fa
+#define KBD_RESEND 0x00fe
+#define KBD_RESET_DONE 0x00aa
+#define KBD_RESET_FAIL 0x00fc
+#define KBD_DIAG_DONE 0x0055
+#define KBD_DIAG_FAIL 0x00fd
+#define KBD_ECHO 0x00ee
+
+#define PSM_ACK 0x00fa
+#define PSM_RESEND 0x00fe
+#define PSM_RESET_DONE 0x00aa
+#define PSM_RESET_FAIL 0x00fc
+
+/* aux device ID */
+#define PSM_MOUSE_ID 0
+#define PSM_BALLPOINT_ID 2
+
+#ifdef KERNEL
+
+/* driver specific options: the following options may be set by
+ `options' statements in the kernel configuration file. */
+
+/* retry count */
+#ifndef KBD_MAXRETRY
+#define KBD_MAXRETRY 3
+#endif
+
+/* timing parameters */
+#ifndef KBD_RESETDELAY
+#define KBD_RESETDELAY 200 /* wait 200msec after kbd/mouse reset */
+#endif
+#ifndef KBD_MAXWAIT
+#define KBD_MAXWAIT 5 /* wait 5 times at most after reset */
+#endif
+
+/* debugging */
+/* #define KBDIO_DEBUG produces debugging output */
+
+/* end of driver specific options */
+
+/* misc */
+#ifndef TRUE
+#define TRUE (-1)
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* function prototypes */
+
+int wait_while_controller_busy __P((int port));
+int wait_until_controller_is_really_idle __P((int port));
+
+int wait_for_data __P((int port));
+int wait_for_kbd_data __P((int port));
+int wait_for_aux_data __P((int port));
+
+void write_controller_command __P((int port,int c));
+void write_controller_data __P((int port,int c));
+
+void write_kbd_command __P((int port,int c));
+void write_aux_command __P((int port,int c));
+int send_kbd_command __P((int port,int c));
+int send_aux_command __P((int port,int c));
+int send_kbd_command_and_data __P((int port,int c,int d));
+int send_aux_command_and_data __P((int port,int c,int d));
+
+int read_controller_data __P((int port));
+int read_kbd_data __P((int port));
+int read_kbd_data_no_wait __P((int port));
+int read_aux_data __P((int port));
+
+void empty_kbd_buffer __P((int port));
+void empty_aux_buffer __P((int port));
+void empty_both_buffers __P((int port));
+
+int reset_kbd __P((int port));
+int reset_aux_dev __P((int port));
+
+int test_controller __P((int port));
+int test_kbd_port __P((int port));
+int test_aux_port __P((int port));
+
+void set_controller_command_byte __P((int port,int command,int flag));
+
+#endif /* KERNEL */
+
+#endif /* !_I386_ISA_KBDIO_H_ */
diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c
index ef95daa32977..5b806e61e74c 100644
--- a/sys/i386/isa/syscons.c
+++ b/sys/i386/isa/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);
-
- /* flush any noise in the buffer */
- while (inb(KB_STAT) & KB_BUF_FULL) {
- DELAY(100);
- (void) inb(KB_DATA);
- }
-
- /* 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;
- }
+ sc_port = dev->id_iobase;
+
+ /* 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;
}
-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();
- }
-
- succeed:
+ 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:
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);
}
diff --git a/sys/isa/kbdio.c b/sys/isa/kbdio.c
new file mode 100644
index 000000000000..f3262958a8f5
--- /dev/null
+++ b/sys/isa/kbdio.c
@@ -0,0 +1,470 @@
+/*-
+ * Copyright (c) 1996 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <machine/clock.h>
+#include <i386/isa/isa.h>
+#include <i386/isa/isa_device.h>
+#include <i386/isa/kbdio.h>
+
+/*
+ * device I/O routines
+ */
+int
+wait_while_controller_busy(int port)
+{
+ /* CPU will stay inside the loop for 100msec at most */
+ int retry = 5000;
+
+ while (inb(port + KBD_STATUS_PORT) & KBDS_CONTROLLER_BUSY) {
+ DELAY(20);
+ if (--retry < 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+int
+wait_until_controller_is_really_idle(int port)
+{
+ /* CPU will stay inside the loop for 100msec at most */
+ int retry = 5000;
+
+ while (inb(port + KBD_STATUS_PORT)
+ & (KBDS_CONTROLLER_BUSY | KBDS_ANY_BUFFER_FULL)) {
+ DELAY(20);
+ if (--retry < 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * wait for any data; whether it's from the controller,
+ * the keyboard, or the aux device.
+ */
+int
+wait_for_data(int port)
+{
+ /* CPU will stay inside the loop for 200msec at most */
+ int retry = 10000;
+
+ while ((inb(port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) == 0) {
+ DELAY(20);
+ if (--retry < 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* wait for data from the keyboard */
+int
+wait_for_kbd_data(int port)
+{
+ /* CPU will stay inside the loop for 200msec at most */
+ int retry = 10000;
+
+ while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ != KBDS_KBD_BUFFER_FULL) {
+ DELAY(20);
+ if (--retry < 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* wait for data from the aux device */
+int
+wait_for_aux_data(int port)
+{
+ /* CPU will stay inside the loop for 200msec at most */
+ int retry = 10000;
+
+ while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ != KBDS_AUX_BUFFER_FULL) {
+ DELAY(20);
+ if (--retry < 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+write_controller_command(int port, int c)
+{
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_COMMAND_PORT, c);
+}
+
+void
+write_controller_data(int port, int c)
+{
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+}
+
+void
+write_kbd_command(int port, int c)
+{
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+}
+
+void
+write_aux_command(int port, int c)
+{
+ write_controller_command(port,KBDC_WRITE_TO_AUX);
+ write_controller_data(port, c);
+}
+
+int
+send_kbd_command(int port, int c)
+{
+ int retry = KBD_MAXRETRY;
+ int res;
+
+ while (retry-- > 0) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+ res = read_controller_data(port);
+ if (res == KBD_ACK)
+ break;
+ }
+ return res;
+}
+
+int
+send_aux_command(int port, int c)
+{
+ int retry = KBD_MAXRETRY;
+ int res;
+
+ while (retry-- > 0) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_COMMAND_PORT, KBDC_WRITE_TO_AUX);
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+ res = read_aux_data(port);
+ if (res == PSM_ACK)
+ break;
+ }
+ return res;
+}
+
+int
+send_kbd_command_and_data(int port, int c, int d)
+{
+ int retry;
+ int res;
+
+ for (retry = KBD_MAXRETRY; retry > 0; --retry) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+ res = read_controller_data(port);
+ if (res == KBD_ACK)
+ break;
+ }
+
+ for (retry = KBD_MAXRETRY; retry > 0; --retry) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, d);
+ res = read_controller_data(port);
+ if (res != KBD_RESEND)
+ break;
+ }
+ return res;
+}
+
+int
+send_aux_command_and_data(int port, int c, int d)
+{
+ int retry;
+ int res;
+
+ for (retry = KBD_MAXRETRY; retry > 0; --retry) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_COMMAND_PORT, KBDC_WRITE_TO_AUX);
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, c);
+ res = read_aux_data(port);
+ if (res == PSM_ACK)
+ break;
+ else if (res != PSM_RESEND)
+ return res;
+ }
+
+ for (retry = KBD_MAXRETRY; retry > 0; --retry) {
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_COMMAND_PORT, KBDC_WRITE_TO_AUX);
+ wait_until_controller_is_really_idle(port);
+ outb(port + KBD_DATA_PORT, d);
+ res = read_aux_data(port);
+ if (res != PSM_RESEND)
+ break;
+ }
+ return res;
+}
+
+/*
+ * read one byte from any source; whether from the controller,
+ * the keyboard, or the aux device
+ */
+int
+read_controller_data(int port)
+{
+ wait_while_controller_busy(port);
+ if (!wait_for_data(port))
+ return -1; /* timeout */
+ return inb(port + KBD_DATA_PORT);
+}
+
+/* read one byte from the keyboard */
+int
+read_kbd_data(int port)
+{
+ wait_while_controller_busy(port);
+ if (!wait_for_kbd_data(port))
+ return -1; /* timeout */
+ return inb(port + KBD_DATA_PORT);
+}
+
+/* read one byte from the keyboard, but return immediately if
+ * no data is waiting
+ */
+int
+read_kbd_data_no_wait(int port)
+{
+ wait_while_controller_busy(port);
+ if ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ != KBDS_KBD_BUFFER_FULL)
+ return -1; /* no data */
+ return inb(port + KBD_DATA_PORT);
+}
+
+/* read one byte from the aux device */
+int
+read_aux_data(int port)
+{
+ wait_while_controller_busy(port);
+ if (!wait_for_aux_data(port))
+ return -1; /* timeout */
+ return inb(port + KBD_DATA_PORT);
+}
+
+/* discard data from the keyboard */
+void
+empty_kbd_buffer(int port)
+{
+ int b;
+ int c = 0;
+
+ while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ == KBDS_KBD_BUFFER_FULL) {
+ b = inb(port + KBD_DATA_PORT);
+ ++c;
+ DELAY(20);
+ }
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: %d char read (empty_kbd_buffer)\n",c);
+#endif
+}
+
+/* discard data from the aux device */
+void
+empty_aux_buffer(int port)
+{
+ int b;
+ int c = 0;
+
+ while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ == KBDS_AUX_BUFFER_FULL) {
+ b = inb(port + KBD_DATA_PORT);
+ ++c;
+ DELAY(20);
+ }
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: %d char read (empty_aux_buffer)\n",c);
+#endif
+}
+
+/* discard any data from the keyboard or the aux device */
+void
+empty_both_buffers(int port)
+{
+ int b;
+ int c = 0;
+
+ while (inb(port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
+ b = inb(port + KBD_DATA_PORT);
+ ++c;
+ DELAY(20);
+ }
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: %d char read (empty_both_buffers)\n",c);
+#endif
+}
+
+/* keyboard and mouse device control */
+
+/* NOTE: enable the keyboard port but disable the keyboard
+ * interrupt before calling "reset_kbd()".
+ */
+int
+reset_kbd(int port)
+{
+ int retry = KBD_MAXRETRY;
+ int again = KBD_MAXWAIT;
+ int c;
+
+ while (retry-- > 0) {
+ empty_both_buffers(port);
+ write_kbd_command(port, KBDC_RESET_KBD);
+ c = read_controller_data(port);
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: RESET_KBD return code:%04x\n",c);
+#endif
+ if (c == KBD_ACK) /* keyboard has agreed to reset itself... */
+ break;
+ }
+ if (retry < 0)
+ return FALSE;
+
+ while (again-- > 0) {
+ /* wait awhile, well, in fact we must wait quite loooooooooooong */
+ DELAY(KBD_RESETDELAY*1000);
+ c = read_controller_data(port); /* RESET_DONE/RESET_FAIL */
+ if (c != -1) /* wait again if the controller is not ready */
+ break;
+ }
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: RESET_KBD status:%04x\n",c);
+#endif
+ if (c != KBD_RESET_DONE)
+ return FALSE;
+ return TRUE;
+}
+
+/* NOTE: enable the aux port but disable the aux interrupt
+ * before calling `reset_aux_dev()'.
+ */
+int
+reset_aux_dev(int port)
+{
+ int retry = KBD_MAXRETRY;
+ int again = KBD_MAXWAIT;
+ int c;
+
+ while (retry-- > 0) {
+ empty_both_buffers(port);
+ write_aux_command(port, PSMC_RESET_DEV);
+ c = read_controller_data(port); /* read_aux_data()? */
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: RESET_AUX return code:%04x\n",c);
+#endif
+ if (c == PSM_ACK) /* aux dev is about to reset... */
+ break;
+ }
+ if (retry < 0)
+ return FALSE;
+
+ while (again-- > 0) {
+ /* wait awhile, well, quite looooooooooooong */
+ DELAY(KBD_RESETDELAY*1000);
+ c = read_aux_data(port); /* RESET_DONE/RESET_FAIL */
+ if (c != -1) /* wait again if the controller is not ready */
+ break;
+ }
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: RESET_AUX status:%04x\n",c);
+#endif
+ if (c != PSM_RESET_DONE) /* reset status */
+ return FALSE;
+
+ c = read_aux_data(port); /* device ID */
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: RESET_AUX ID:%04x\n",c);
+#endif
+ /* NOTE: we could check the device ID now, but leave it later... */
+ return TRUE;
+}
+
+/* controller diagnostics and setup */
+
+int
+test_controller(int port)
+{
+ int c;
+
+ empty_both_buffers(port);
+ write_controller_command(port, KBDC_DIAGNOSE);
+ c = read_controller_data(port); /* DIAG_DONE/DIAG_FAIL */
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: DIAGNOSE status:%04x\n",c);
+#endif
+ return (c == KBD_DIAG_DONE);
+}
+
+int
+test_kbd_port(int port)
+{
+ int c;
+
+ empty_both_buffers(port);
+ write_controller_command(port, KBDC_TEST_KBD_PORT);
+ c = read_controller_data(port);
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: TEST_KBD_PORT status:%04x\n",c);
+#endif
+ return c;
+}
+
+int
+test_aux_port(int port)
+{
+ int c;
+
+ empty_both_buffers(port);
+ write_controller_command(port, KBDC_TEST_AUX_PORT);
+ c = read_controller_data(port);
+#ifdef KBDIO_DEBUG
+ log(LOG_DEBUG,"kbdio: TEST_AUX_PORT status:%04x\n",c);
+#endif
+ return c;
+}
+
+void
+set_controller_command_byte(int port, int command, int flag)
+{
+ write_controller_command(port, KBDC_SET_COMMAND_BYTE);
+ write_controller_data(port, command | flag);
+ wait_while_controller_busy(port);
+}
diff --git a/sys/isa/kbdio.h b/sys/isa/kbdio.h
new file mode 100644
index 000000000000..c5477800ec95
--- /dev/null
+++ b/sys/isa/kbdio.h
@@ -0,0 +1,204 @@
+/*-
+ * Copyright (c) 1996 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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$
+ */
+
+#ifndef _I386_ISA_KBDIO_H_
+#define _I386_ISA_KBDIO_H_
+
+/* constants */
+
+/* I/O ports */
+#define KBD_STATUS_PORT 4 /* status port, read */
+#define KBD_COMMAND_PORT 4 /* controller command port, write */
+#define KBD_DATA_PORT 0 /* data port, read/write
+ also used as keyboard command
+ and mouse command port */
+/* FIXME: `IO_PSMSIZE' should really be in `isa.h'. */
+#define IO_PSMSIZE (KBD_COMMAND_PORT - KBD_DATA_PORT + 1) /* 5 */
+
+/* controller commands (sent to KBD_COMMAND_PORT) */
+#define KBDC_SET_COMMAND_BYTE 0x0060
+#define KBDC_GET_COMMAND_BYTE 0x0020
+#define KBDC_WRITE_TO_AUX 0x00d4
+#define KBDC_DISABLE_AUX_PORT 0x00a7
+#define KBDC_ENABLE_AUX_PORT 0x00a8
+#define KBDC_TEST_AUX_PORT 0x00a9
+#define KBDC_DIAGNOSE 0x00aa
+#define KBDC_TEST_KBD_PORT 0x00ab
+#define KBDC_DISABLE_KBD_PORT 0x00ad
+#define KBDC_ENABLE_KBD_PORT 0x00ae
+
+/* controller command byte (set by KBDC_SET_COMMAND_BYTE) */
+#define KBD_TRANSLATION 0x0040
+#define KBD_RESERVED_BITS 0x0004
+#define KBD_ENABLE_KBD_PORT 0x0000
+#define KBD_DISABLE_KBD_PORT 0x0010
+#define KBD_ENABLE_AUX_PORT 0x0000
+#define KBD_DISABLE_AUX_PORT 0x0020
+#define KBD_ENABLE_AUX_INT 0x0002
+#define KBD_DISABLE_AUX_INT 0x0000
+#define KBD_ENABLE_KBD_INT 0x0001
+#define KBD_DISABLE_KBD_INT 0x0000
+#define KBD_KBD_CONTROL_BITS (KBD_DISABLE_KBD_PORT | KBD_ENABLE_KBD_INT)
+#define KBD_AUX_CONTROL_BITS (KBD_DISABLE_AUX_PORT | KBD_ENABLE_AUX_INT)
+
+/* keyboard device commands (sent to KBD_DATA_PORT) */
+#define KBDC_RESET_KBD 0x00ff
+#define KBDC_ENABLE_KBD 0x00f4
+#define KBDC_DISABLE_KBD 0x00f5
+#define KBDC_SET_DEFAULTS 0x00f6
+#define KBDC_SEND_DEV_ID 0x00f2
+#define KBDC_SET_LEDS 0x00ed
+#define KBDC_ECHO 0x00ee
+#define KBDC_SET_SCAN_CODESET 0x00f0
+#define KBDC_SET_TYPEMATIC 0x00f3
+
+/* aux device commands (sent to KBD_DATA_PORT) */
+#define PSMC_RESET_DEV 0x00ff
+#define PSMC_ENABLE_DEV 0x00f4
+#define PSMC_DISABLE_DEV 0x00f5
+#define PSMC_SEND_DEV_ID 0x00f2
+#define PSMC_SEND_DEV_STATUS 0x00e9
+#define PSMC_SET_SCALING11 0x00e6
+#define PSMC_SET_SCALING21 0x00e7
+#define PSMC_SET_RESOLUTION 0x00e8
+#define PSMC_SET_STREAM_MODE 0x00ea
+#define PSMC_SET_SAMPLING_RATE 0x00f3
+
+/* PSMC_SET_RESOLUTION argument */
+#define PSMD_RESOLUTION_25 0 /* 25ppi */
+#define PSMD_RESOLUTION_50 1 /* 50ppi */
+#define PSMD_RESOLUTION_100 2 /* 100ppi (default after reset) */
+#define PSMD_RESOLUTION_200 3 /* 200ppi */
+/* FIXME: I don't know if it's possible to go beyond 200ppi.
+ The values below are of my wild guess. */
+#define PSMD_RESOLUTION_400 4 /* 400ppi */
+#define PSMD_RESOLUTION_800 5 /* 800ppi */
+#define PSMD_MAX_RESOLUTION PSMD_RESOLUTION_800
+
+/* PSMC_SET_SAMPLING_RATE */
+#define PSMD_MAX_RATE 255 /* FIXME: not sure if it's possible */
+
+/* status bits (KBD_STATUS_PORT) */
+#define KBDS_BUFFER_FULL 0x0021
+#define KBDS_ANY_BUFFER_FULL 0x0001
+#define KBDS_KBD_BUFFER_FULL 0x0001
+#define KBDS_AUX_BUFFER_FULL 0x0021
+#define KBDS_CONTROLLER_BUSY 0x0002
+
+/* return code */
+#define KBD_ACK 0x00fa
+#define KBD_RESEND 0x00fe
+#define KBD_RESET_DONE 0x00aa
+#define KBD_RESET_FAIL 0x00fc
+#define KBD_DIAG_DONE 0x0055
+#define KBD_DIAG_FAIL 0x00fd
+#define KBD_ECHO 0x00ee
+
+#define PSM_ACK 0x00fa
+#define PSM_RESEND 0x00fe
+#define PSM_RESET_DONE 0x00aa
+#define PSM_RESET_FAIL 0x00fc
+
+/* aux device ID */
+#define PSM_MOUSE_ID 0
+#define PSM_BALLPOINT_ID 2
+
+#ifdef KERNEL
+
+/* driver specific options: the following options may be set by
+ `options' statements in the kernel configuration file. */
+
+/* retry count */
+#ifndef KBD_MAXRETRY
+#define KBD_MAXRETRY 3
+#endif
+
+/* timing parameters */
+#ifndef KBD_RESETDELAY
+#define KBD_RESETDELAY 200 /* wait 200msec after kbd/mouse reset */
+#endif
+#ifndef KBD_MAXWAIT
+#define KBD_MAXWAIT 5 /* wait 5 times at most after reset */
+#endif
+
+/* debugging */
+/* #define KBDIO_DEBUG produces debugging output */
+
+/* end of driver specific options */
+
+/* misc */
+#ifndef TRUE
+#define TRUE (-1)
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* function prototypes */
+
+int wait_while_controller_busy __P((int port));
+int wait_until_controller_is_really_idle __P((int port));
+
+int wait_for_data __P((int port));
+int wait_for_kbd_data __P((int port));
+int wait_for_aux_data __P((int port));
+
+void write_controller_command __P((int port,int c));
+void write_controller_data __P((int port,int c));
+
+void write_kbd_command __P((int port,int c));
+void write_aux_command __P((int port,int c));
+int send_kbd_command __P((int port,int c));
+int send_aux_command __P((int port,int c));
+int send_kbd_command_and_data __P((int port,int c,int d));
+int send_aux_command_and_data __P((int port,int c,int d));
+
+int read_controller_data __P((int port));
+int read_kbd_data __P((int port));
+int read_kbd_data_no_wait __P((int port));
+int read_aux_data __P((int port));
+
+void empty_kbd_buffer __P((int port));
+void empty_aux_buffer __P((int port));
+void empty_both_buffers __P((int port));
+
+int reset_kbd __P((int port));
+int reset_aux_dev __P((int port));
+
+int test_controller __P((int port));
+int test_kbd_port __P((int port));
+int test_aux_port __P((int port));
+
+void set_controller_command_byte __P((int port,int command,int flag));
+
+#endif /* KERNEL */
+
+#endif /* !_I386_ISA_KBDIO_H_ */
diff --git a/sys/isa/syscons.c b/sys/isa/syscons.c
index ef95daa32977..5b806e61e74c 100644
--- a/sys/isa/syscons.c
+++ b/sys/isa/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);
-
- /* flush any noise in the buffer */
- while (inb(KB_STAT) & KB_BUF_FULL) {
- DELAY(100);
- (void) inb(KB_DATA);
- }
-
- /* 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;
- }
+ sc_port = dev->id_iobase;
+
+ /* 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;
}
-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();
- }
-
- succeed:
+ 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:
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);
}
diff --git a/sys/sys/mouse.h b/sys/sys/mouse.h
index 95a66e474c6d..a7322b737571 100644
--- a/sys/sys/mouse.h
+++ b/sys/sys/mouse.h
@@ -19,17 +19,36 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: mouse.h,v 1.1 1994/05/17 14:05:31 jkh Exp $
+ * $Id: mouse.h,v 1.1 1994/09/09 11:27:31 dfr Exp $
*/
-struct mouseinfo {
- unsigned char status;
- char xmotion, ymotion;
-};
+#ifndef _MACHINE_MOUSE_H_
+#define _MACHINE_MOUSE_H_
+
+#include <sys/types.h>
+#include <sys/ioccom.h>
+
+/* NOTE: MOUSEIOC and MOUSEIOCREAD are now obsolete, but will stay
+ for compatibility reasons. But, remember, the MOUSEIOCREAD ioctl
+ command doesn't work and never worked before. Some day we shall
+ get rid of these... */
+#define MOUSEIOC ('M'<<8)
+#define MOUSEIOCREAD (MOUSEIOC|60)
+
+#define MOUSE_GETSTATE _IOR('M',0,mouseinfo_t)
+#define MOUSE_GETINFO _IOR('M',1,mousehw_t)
+#define MOUSE_GETMODE _IOR('M',2,mousemode_t)
+#define MOUSE_SETMODE _IOW('M',3,mousemode_t)
+
+typedef struct mouseinfo {
+ unsigned char status;
+ char xmotion;
+ char ymotion;
+} mouseinfo_t;
+/* status */
#define BUTSTATMASK 0x07 /* Any mouse button down if any bit set */
#define BUTCHNGMASK 0x38 /* Any mouse button changed if any bit set */
-
#define BUT3STAT 0x01 /* Button 3 down if set */
#define BUT2STAT 0x02 /* Button 2 down if set */
#define BUT1STAT 0x04 /* Button 1 down if set */
@@ -38,7 +57,70 @@ struct mouseinfo {
#define BUT1CHNG 0x20 /* Button 1 changed if set */
#define MOVEMENT 0x40 /* Mouse movement detected */
-/* Ioctl definitions */
+typedef struct mousehw {
+ int buttons;
+ int iftype; /* MOUSE_IF_XXX */
+ int type; /* mouse/track ball/pad... */
+ int hwid; /* I/F dependent hardware ID
+ for the PS/2 mouse, it will be PSM_XXX_ID */
+} mousehw_t;
+/* iftype */
+#define MOUSE_IF_SERIAL 0
+#define MOUSE_IF_BUS 1
+#define MOUSE_IF_INPORT 2
+#define MOUSE_IF_PS2 3
+/* type */
+#define MOUSE_UNKNOWN (-1) /* should be treated as a mouse */
+#define MOUSE_MOUSE 0
+#define MOUSE_TRACKBALL 1
+#define MOUSE_STICK 2
+#define MOUSE_PAD 3
+
+typedef struct mousemode {
+ int protocol; /* MOUSE_PROTO_XXX */
+ int rate; /* report rate (per sec), -1 if unknown */
+ int resolution; /* ppi, -1 if unknown */
+ int accelfactor; /* accelation factor (must be 1 or greater) */
+} mousemode_t;
+/* protocol */
+#define MOUSE_PROTO_MS 0 /* Microsoft Serial, 3 bytes */
+#define MOUSE_PROTO_MSC 1 /* Mouse Systems, 5 bytes */
+#define MOUSE_PROTO_LOGI 2 /* Logitech, 3 bytes */
+#define MOUSE_PROTO_MM 3 /* MM series, 3 bytes */
+#define MOUSE_PROTO_LOGIMOUSEMAN 4 /* Logitech MouseMan 3/4 bytes */
+#define MOUSE_PROTO_BUS 5 /* MS/Logitech bus mouse */
+#define MOUSE_PROTO_INPORT 6 /* MS/ATI inport mouse */
+#define MOUSE_PROTO_PS2 7 /* PS/2 mouse, 3 bytes */
+
+/* Microsoft Serial mouse data packet */
+#define MOUSE_MSS_PACKETSIZE 3
+#define MOUSE_MSS_SYNCMASK 0x40
+#define MOUSE_MSS_SYNC 0x40
+#define MOUSE_MSS_BUTTONS 0x30
+#define MOUSE_MSS_BUTTON1DOWN 0x20 /* left */
+#define MOUSE_MSS_BUTTON2DOWN 0x00 /* no middle button */
+#define MOUSE_MSS_BUTTON3DOWN 0x10 /* right */
+
+/* Mouse Systems Corp. mouse data packet */
+#define MOUSE_MSC_PACKETSIZE 5
+#define MOUSE_MSC_SYNCMASK 0xf8
+#define MOUSE_MSC_SYNC 0x80
+#define MOUSE_MSC_BUTTONS 0x07
+#define MOUSE_MSC_BUTTON1UP 0x04 /* left */
+#define MOUSE_MSC_BUTTON2UP 0x02 /* middle */
+#define MOUSE_MSC_BUTTON3UP 0x01 /* right */
+
+/* PS/2 mouse data packet */
+#define MOUSE_PS2_PACKETSIZE 3
+#define MOUSE_PS2_SYNCMASK 0x08 /* 0x0c for 2 button mouse */
+#define MOUSE_PS2_SYNC 0x08 /* 0x0c for 2 button mouse */
+#define MOUSE_PS2_BUTTONS 0x07 /* 0x03 for 2 button mouse */
+#define MOUSE_PS2_BUTTON1DOWN 0x01 /* left */
+#define MOUSE_PS2_BUTTON2DOWN 0x04 /* middle */
+#define MOUSE_PS2_BUTTON3DOWN 0x02 /* right */
+#define MOUSE_PS2_XNEG 0x10
+#define MOUSE_PS2_YNEG 0x20
+#define MOUSE_PS2_XOVERFLOW 0x40
+#define MOUSE_PS2_YOVERFLOW 0x80
-#define MOUSEIOC ('M'<<8)
-#define MOUSEIOCREAD (MOUSEIOC|60)
+#endif /* _MACHINE_MOUSE_H_ */