summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>1996-11-14 22:19:17 +0000
committersos <sos@FreeBSD.org>1996-11-14 22:19:17 +0000
commit5cc90762eaa845e5950abb6b1da4a7a1c8d4493e (patch)
tree650a2881d1f41e3f84cc51aa2e2bbbe5d8633068 /sys
parent9ac487e987d38affc737e37ce761c2e8a8278372 (diff)
downloadFreeBSD-src-5cc90762eaa845e5950abb6b1da4a7a1c8d4493e.zip
FreeBSD-src-5cc90762eaa845e5950abb6b1da4a7a1c8d4493e.tar.gz
Finally a start at sharing the kdb controller routines between
syscons and psm, curtesy Kazutaka Yokota with minor changes by me. This contains an update of the psm driver as well. This also fixes the breakage that I introduced to the psm driver by making syscons poll for keyboard events in the atempt to fix the hanging keyboard problem. It works perfectly for me, and I'd like to hear from all that have had keyboard/ps/2 mouse problems if this is the cure... Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
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 3e641a7..de049da 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 95a66e4..a7322b7 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 3e727a6..a4fca64 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 ef95daa..5b806e6 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 3e727a6..a4fca64 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 3e641a7..de049da 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 95a66e4..a7322b7 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 d34b634..0000000
--- 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 0000000..f326295
--- /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 0000000..c547780
--- /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 ef95daa..5b806e6 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 0000000..f326295
--- /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 0000000..c547780
--- /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 ef95daa..5b806e6 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 95a66e4..a7322b7 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_ */
OpenPOWER on IntegriCloud