summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/include/mouse.h62
-rw-r--r--sys/dev/syscons/syscons.c71
-rw-r--r--sys/i386/include/mouse.h62
-rw-r--r--sys/i386/isa/kbdio.c255
-rw-r--r--sys/i386/isa/kbdio.h24
-rw-r--r--sys/i386/isa/psm.c640
-rw-r--r--sys/i386/isa/syscons.c71
-rw-r--r--sys/isa/kbdio.c255
-rw-r--r--sys/isa/kbdio.h24
-rw-r--r--sys/isa/syscons.c71
-rw-r--r--sys/sys/mouse.h62
11 files changed, 1096 insertions, 501 deletions
diff --git a/sys/alpha/include/mouse.h b/sys/alpha/include/mouse.h
index 1303a31..110c503 100644
--- a/sys/alpha/include/mouse.h
+++ b/sys/alpha/include/mouse.h
@@ -19,7 +19,7 @@
* 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.2 1996/11/14 22:18:25 sos Exp $
+ * $Id: mouse.h,v 1.1 1994/09/09 11:27:31 dfr Exp $
*/
#ifndef _MACHINE_MOUSE_H_
@@ -29,26 +29,20 @@
#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...
+ * NOTE: MOUSEIOC, MOUSEIOCREAD, and mouseinfo 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 */
@@ -60,6 +54,32 @@ typedef struct mouseinfo {
#define BUT1CHNG 0x20 /* Button 1 changed if set */
#define MOVEMENT 0x40 /* Mouse movement detected */
+#define MOUSE_GETSTATE _IOR('M',0,mousestatus_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)
+
+/* new ioctls */
+
+/* mouse status block */
+typedef struct mousestatus {
+ int button; /* button status */
+ int obutton; /* previous button status */
+ int dx; /* x movement */
+ int dy; /* y movement */
+} mousestatus_t;
+/* button */
+#define MOUSE_BUTTON1DOWN 0x0001 /* left */
+#define MOUSE_BUTTON2DOWN 0x0002 /* middle */
+#define MOUSE_BUTTON3DOWN 0x0004 /* right */
+#define MOUSE_BUTTON4DOWN 0x0008
+#define MOUSE_BUTTON5DOWN 0x0010
+#define MOUSE_BUTTON6DOWN 0x0020
+#define MOUSE_BUTTON7DOWN 0x0040
+#define MOUSE_BUTTON8DOWN 0x0080
+#define MOUSE_STDBUTTONS 0x0007 /* buttons 1-3 */
+#define MOUSE_EXTBUTTONS 0x00f8 /* the others */
+
typedef struct mousehw {
int buttons;
int iftype; /* MOUSE_IF_XXX */
@@ -67,13 +87,11 @@ typedef struct mousehw {
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
@@ -87,7 +105,6 @@ typedef struct mousemode {
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 */
@@ -107,6 +124,9 @@ typedef struct mousemode {
#define MOUSE_MSS_BUTTON2DOWN 0x00 /* no middle button */
#define MOUSE_MSS_BUTTON3DOWN 0x10 /* right */
+/* Logitech MouseMan data packet (M+ protocol) */
+#define MOUSE_LMAN_BUTTON2DOWN 0x20 /* middle button, in the 4th byte */
+
/* Mouse Systems Corp. mouse data packet */
#define MOUSE_MSC_PACKETSIZE 5
#define MOUSE_MSC_SYNCMASK 0xf8
@@ -116,6 +136,17 @@ typedef struct mousemode {
#define MOUSE_MSC_BUTTON2UP 0x02 /* middle */
#define MOUSE_MSC_BUTTON3UP 0x01 /* right */
+/* MM series mouse data packet */
+#define MOUSE_MM_PACKETSIZE 3
+#define MOUSE_MM_SYNCMASK 0xe0
+#define MOUSE_MM_SYNC 0x80
+#define MOUSE_MM_BUTTONS 0x07
+#define MOUSE_MM_BUTTON1DOWN 0x04 /* left */
+#define MOUSE_MM_BUTTON2DOWN 0x02 /* middle */
+#define MOUSE_MM_BUTTON3DOWN 0x01 /* right */
+#define MOUSE_MM_XPOSITIVE 0x10
+#define MOUSE_MM_YPOSITIVE 0x08
+
/* PS/2 mouse data packet */
#define MOUSE_PS2_PACKETSIZE 3
#define MOUSE_PS2_SYNCMASK 0x08 /* 0x0c for 2 button mouse */
@@ -124,6 +155,9 @@ typedef struct mousemode {
#define MOUSE_PS2_BUTTON1DOWN 0x01 /* left */
#define MOUSE_PS2_BUTTON2DOWN 0x04 /* middle */
#define MOUSE_PS2_BUTTON3DOWN 0x02 /* right */
+#define MOUSE_PS2_BUTTON4UP 0x08 /* GlidePoint tapping feature
+ * Yes! this is the same bit as SYNC!
+ */
#define MOUSE_PS2_XNEG 0x10
#define MOUSE_PS2_YNEG 0x20
#define MOUSE_PS2_XOVERFLOW 0x40
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 8b9fff1..691460a 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.188 1996/11/15 08:45:24 sos Exp $
+ * $Id: syscons.c,v 1.189 1996/11/19 17:08:10 nate Exp $
*/
#include "sc.h"
@@ -298,31 +298,47 @@ scprobe(struct isa_device *dev)
sc_port = dev->id_iobase;
+ /* discard anything left after UserConfig */
+ empty_both_buffers(sc_port, 10);
+
/* save the current keyboard controller command byte */
- write_controller_command(sc_port, KBDC_GET_COMMAND_BYTE);
+ c = -1;
+ if (!write_controller_command(sc_port, KBDC_GET_COMMAND_BYTE)) {
+ /* CONTROLLER ERROR */
+ printf("sc%d: unable to get the current command byte value.\n",
+ dev->id_unit);
+ goto fail;
+ }
c = read_controller_data(sc_port);
if (c == -1) {
+ /* CONTROLLER ERROR */
printf("sc%d: unable to get the current command byte value.\n",
dev->id_unit);
goto fail;
}
+#if 0
+ /* override the keyboard lock switch */
+ c |= KBD_OVERRIDE_KBD_LOCK;
+#endif
/*
* 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);
+ if (!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)) {
+ /* CONTROLLER ERROR
+ * there is very little we can do...
+ */
+ printf("sc%d: unable to set the command byte.\n", dev->id_unit);
+ goto fail;
+ }
/* reset keyboard hardware */
if (!reset_kbd(sc_port)) {
- /*
+ /* KEYBOARD ERROR
* 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
@@ -331,15 +347,17 @@ scprobe(struct isa_device *dev)
* test_controller() and test_kbd_port() appear to bring the keyboard
* controller back (I don't know why and how, though.)
*/
+ empty_both_buffers(sc_port, 10);
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.
+ * the keyboard may still exist (see above).
*/
- set_controller_command_byte(sc_port, c, 0);
+ if (bootverbose)
+ printf("sc%d: failed to reset the keyboard.\n", dev->id_unit);
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
@@ -347,19 +365,36 @@ scprobe(struct isa_device *dev)
*/
if (dev->id_flags & XT_KEYBD) {
if (send_kbd_command_and_data(
- sc_port, KBDC_SET_SCAN_CODESET, 1) == KBD_ACK)
+ 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);
+ } else {
+ /* KEYBOARD ERROR
+ * The XT kbd isn't usable unless the proper scan code set
+ * is selected.
+ */
+ printf("sc%d: unable to set the XT keyboard mode.\n", dev->id_unit);
+ goto fail;
+ }
}
/* 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);
+ if (!set_controller_command_byte(sc_port, c & ~KBD_KBD_CONTROL_BITS,
+ KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
+ /* CONTROLLER ERROR
+ * This is serious; we are left with the disabled keyboard intr.
+ */
+ printf("sc%d: unable to enable the keyboard port and intr.\n",
+ dev->id_unit);
+ goto fail;
+ }
succeed:
return (IO_KBDSIZE);
fail:
+ if (c != -1)
+ /* try to restore the command byte as before, if possible */
+ set_controller_command_byte(sc_port, c, 0);
return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
}
diff --git a/sys/i386/include/mouse.h b/sys/i386/include/mouse.h
index 1303a31..110c503 100644
--- a/sys/i386/include/mouse.h
+++ b/sys/i386/include/mouse.h
@@ -19,7 +19,7 @@
* 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.2 1996/11/14 22:18:25 sos Exp $
+ * $Id: mouse.h,v 1.1 1994/09/09 11:27:31 dfr Exp $
*/
#ifndef _MACHINE_MOUSE_H_
@@ -29,26 +29,20 @@
#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...
+ * NOTE: MOUSEIOC, MOUSEIOCREAD, and mouseinfo 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 */
@@ -60,6 +54,32 @@ typedef struct mouseinfo {
#define BUT1CHNG 0x20 /* Button 1 changed if set */
#define MOVEMENT 0x40 /* Mouse movement detected */
+#define MOUSE_GETSTATE _IOR('M',0,mousestatus_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)
+
+/* new ioctls */
+
+/* mouse status block */
+typedef struct mousestatus {
+ int button; /* button status */
+ int obutton; /* previous button status */
+ int dx; /* x movement */
+ int dy; /* y movement */
+} mousestatus_t;
+/* button */
+#define MOUSE_BUTTON1DOWN 0x0001 /* left */
+#define MOUSE_BUTTON2DOWN 0x0002 /* middle */
+#define MOUSE_BUTTON3DOWN 0x0004 /* right */
+#define MOUSE_BUTTON4DOWN 0x0008
+#define MOUSE_BUTTON5DOWN 0x0010
+#define MOUSE_BUTTON6DOWN 0x0020
+#define MOUSE_BUTTON7DOWN 0x0040
+#define MOUSE_BUTTON8DOWN 0x0080
+#define MOUSE_STDBUTTONS 0x0007 /* buttons 1-3 */
+#define MOUSE_EXTBUTTONS 0x00f8 /* the others */
+
typedef struct mousehw {
int buttons;
int iftype; /* MOUSE_IF_XXX */
@@ -67,13 +87,11 @@ typedef struct mousehw {
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
@@ -87,7 +105,6 @@ typedef struct mousemode {
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 */
@@ -107,6 +124,9 @@ typedef struct mousemode {
#define MOUSE_MSS_BUTTON2DOWN 0x00 /* no middle button */
#define MOUSE_MSS_BUTTON3DOWN 0x10 /* right */
+/* Logitech MouseMan data packet (M+ protocol) */
+#define MOUSE_LMAN_BUTTON2DOWN 0x20 /* middle button, in the 4th byte */
+
/* Mouse Systems Corp. mouse data packet */
#define MOUSE_MSC_PACKETSIZE 5
#define MOUSE_MSC_SYNCMASK 0xf8
@@ -116,6 +136,17 @@ typedef struct mousemode {
#define MOUSE_MSC_BUTTON2UP 0x02 /* middle */
#define MOUSE_MSC_BUTTON3UP 0x01 /* right */
+/* MM series mouse data packet */
+#define MOUSE_MM_PACKETSIZE 3
+#define MOUSE_MM_SYNCMASK 0xe0
+#define MOUSE_MM_SYNC 0x80
+#define MOUSE_MM_BUTTONS 0x07
+#define MOUSE_MM_BUTTON1DOWN 0x04 /* left */
+#define MOUSE_MM_BUTTON2DOWN 0x02 /* middle */
+#define MOUSE_MM_BUTTON3DOWN 0x01 /* right */
+#define MOUSE_MM_XPOSITIVE 0x10
+#define MOUSE_MM_YPOSITIVE 0x08
+
/* PS/2 mouse data packet */
#define MOUSE_PS2_PACKETSIZE 3
#define MOUSE_PS2_SYNCMASK 0x08 /* 0x0c for 2 button mouse */
@@ -124,6 +155,9 @@ typedef struct mousemode {
#define MOUSE_PS2_BUTTON1DOWN 0x01 /* left */
#define MOUSE_PS2_BUTTON2DOWN 0x04 /* middle */
#define MOUSE_PS2_BUTTON3DOWN 0x02 /* right */
+#define MOUSE_PS2_BUTTON4UP 0x08 /* GlidePoint tapping feature
+ * Yes! this is the same bit as SYNC!
+ */
#define MOUSE_PS2_XNEG 0x10
#define MOUSE_PS2_YNEG 0x20
#define MOUSE_PS2_XOVERFLOW 0x40
diff --git a/sys/i386/isa/kbdio.c b/sys/i386/isa/kbdio.c
index f326295..797dcff 100644
--- a/sys/i386/isa/kbdio.c
+++ b/sys/i386/isa/kbdio.c
@@ -26,16 +26,23 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: kbdio.c,v 1.1 1996/11/14 22:19:06 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/syslog.h>
#include <machine/clock.h>
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/kbdio.h>
+#ifndef KBDIO_DEBUG
+#define KBDIO_DEBUG 0
+#endif
+
+static int verbose = KBDIO_DEBUG;
+
/*
* device I/O routines
*/
@@ -45,22 +52,7 @@ 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)) {
+ while (inb(port + KBD_STATUS_PORT) & KBDS_INPUT_BUFFER_FULL) {
DELAY(20);
if (--retry < 0)
return FALSE;
@@ -83,6 +75,7 @@ wait_for_data(int port)
if (--retry < 0)
return FALSE;
}
+ DELAY(7);
return TRUE;
}
@@ -99,6 +92,7 @@ wait_for_kbd_data(int port)
if (--retry < 0)
return FALSE;
}
+ DELAY(7);
return TRUE;
}
@@ -115,46 +109,54 @@ wait_for_aux_data(int port)
if (--retry < 0)
return FALSE;
}
+ DELAY(7);
return TRUE;
}
-void
+int
write_controller_command(int port, int c)
{
- wait_until_controller_is_really_idle(port);
+ if (!wait_while_controller_busy(port))
+ return FALSE;
outb(port + KBD_COMMAND_PORT, c);
+ return TRUE;
}
-void
+int
write_controller_data(int port, int c)
{
- wait_until_controller_is_really_idle(port);
+ if (!wait_while_controller_busy(port))
+ return FALSE;
outb(port + KBD_DATA_PORT, c);
+ return TRUE;
}
-void
+int
write_kbd_command(int port, int c)
{
- wait_until_controller_is_really_idle(port);
+ if (!wait_while_controller_busy(port))
+ return FALSE;
outb(port + KBD_DATA_PORT, c);
+ return TRUE;
}
-void
+int
write_aux_command(int port, int c)
{
- write_controller_command(port,KBDC_WRITE_TO_AUX);
- write_controller_data(port, c);
+ if (!write_controller_command(port,KBDC_WRITE_TO_AUX))
+ return FALSE;
+ return write_controller_data(port, c);
}
int
send_kbd_command(int port, int c)
{
int retry = KBD_MAXRETRY;
- int res;
+ int res = -1;
while (retry-- > 0) {
- wait_until_controller_is_really_idle(port);
- outb(port + KBD_DATA_PORT, c);
+ if (!write_kbd_command(port, c))
+ continue;
res = read_controller_data(port);
if (res == KBD_ACK)
break;
@@ -166,13 +168,11 @@ int
send_aux_command(int port, int c)
{
int retry = KBD_MAXRETRY;
- int res;
+ int res = -1;
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);
+ if (!write_aux_command(port, c))
+ continue;
res = read_aux_data(port);
if (res == PSM_ACK)
break;
@@ -184,19 +184,23 @@ int
send_kbd_command_and_data(int port, int c, int d)
{
int retry;
- int res;
+ int res = -1;
for (retry = KBD_MAXRETRY; retry > 0; --retry) {
- wait_until_controller_is_really_idle(port);
- outb(port + KBD_DATA_PORT, c);
+ if (!write_kbd_command(port, c))
+ continue;
res = read_controller_data(port);
if (res == KBD_ACK)
break;
+ else if (res != PSM_RESEND)
+ return res;
}
+ if (retry <= 0)
+ return res;
- for (retry = KBD_MAXRETRY; retry > 0; --retry) {
- wait_until_controller_is_really_idle(port);
- outb(port + KBD_DATA_PORT, d);
+ for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
+ if (!write_kbd_command(port, d))
+ continue;
res = read_controller_data(port);
if (res != KBD_RESEND)
break;
@@ -208,25 +212,23 @@ int
send_aux_command_and_data(int port, int c, int d)
{
int retry;
- int res;
+ int res = -1;
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);
+ if (!write_aux_command(port, c))
+ continue;
res = read_aux_data(port);
if (res == PSM_ACK)
break;
else if (res != PSM_RESEND)
return res;
}
+ if (retry <= 0)
+ 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);
+ for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
+ if (!write_aux_command(port, d))
+ continue;
res = read_aux_data(port);
if (res != PSM_RESEND)
break;
@@ -241,7 +243,6 @@ send_aux_command_and_data(int port, int c, int d)
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);
@@ -251,7 +252,6 @@ read_controller_data(int port)
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);
@@ -263,10 +263,10 @@ read_kbd_data(int port)
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 */
+ DELAY(7);
return inb(port + KBD_DATA_PORT);
}
@@ -274,7 +274,6 @@ read_kbd_data_no_wait(int port)
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);
@@ -282,55 +281,64 @@ read_aux_data(int port)
/* discard data from the keyboard */
void
-empty_kbd_buffer(int port)
+empty_kbd_buffer(int port, int t)
{
int b;
int c = 0;
+ int delta = 2;
- while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ for (; t > 0; t -= delta) {
+ if ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
== KBDS_KBD_BUFFER_FULL) {
+ DELAY(7);
b = inb(port + KBD_DATA_PORT);
++c;
- DELAY(20);
}
-#ifdef KBDIO_DEBUG
+ DELAY(delta*1000);
+ }
+ if ((verbose >= 2) && (c > 0))
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)
+empty_aux_buffer(int port, int t)
{
int b;
int c = 0;
+ int delta = 2;
- while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ for (; t > 0; t -= delta) {
+ if ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
== KBDS_AUX_BUFFER_FULL) {
+ DELAY(7);
b = inb(port + KBD_DATA_PORT);
++c;
- DELAY(20);
}
-#ifdef KBDIO_DEBUG
+ DELAY(delta*1000);
+ }
+ if ((verbose >= 2) && (c > 0))
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)
+empty_both_buffers(int port, int t)
{
int b;
int c = 0;
+ int delta = 2;
- while (inb(port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
+ for (; t > 0; t -= delta) {
+ if (inb(port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
+ DELAY(7);
b = inb(port + KBD_DATA_PORT);
++c;
- DELAY(20);
}
-#ifdef KBDIO_DEBUG
+ DELAY(delta*1000);
+ }
+ if ((verbose >= 2) && (c > 0))
log(LOG_DEBUG,"kbdio: %d char read (empty_both_buffers)\n",c);
-#endif
}
/* keyboard and mouse device control */
@@ -343,15 +351,15 @@ reset_kbd(int port)
{
int retry = KBD_MAXRETRY;
int again = KBD_MAXWAIT;
- int c;
+ int c = KBD_RESEND; /* keep the compiler happy */
while (retry-- > 0) {
- empty_both_buffers(port);
- write_kbd_command(port, KBDC_RESET_KBD);
+ empty_both_buffers(port, 10);
+ if (!write_kbd_command(port, KBDC_RESET_KBD))
+ continue;
c = read_controller_data(port);
-#ifdef KBDIO_DEBUG
+ if (verbose)
log(LOG_DEBUG,"kbdio: RESET_KBD return code:%04x\n",c);
-#endif
if (c == KBD_ACK) /* keyboard has agreed to reset itself... */
break;
}
@@ -365,9 +373,8 @@ reset_kbd(int port)
if (c != -1) /* wait again if the controller is not ready */
break;
}
-#ifdef KBDIO_DEBUG
+ if (verbose)
log(LOG_DEBUG,"kbdio: RESET_KBD status:%04x\n",c);
-#endif
if (c != KBD_RESET_DONE)
return FALSE;
return TRUE;
@@ -381,15 +388,15 @@ reset_aux_dev(int port)
{
int retry = KBD_MAXRETRY;
int again = KBD_MAXWAIT;
- int c;
+ int c = PSM_RESEND; /* keep the compiler happy */
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
+ empty_both_buffers(port, 10);
+ if (!write_aux_command(port, PSMC_RESET_DEV))
+ continue;
+ c = read_controller_data(port);
+ if (verbose)
log(LOG_DEBUG,"kbdio: RESET_AUX return code:%04x\n",c);
-#endif
if (c == PSM_ACK) /* aux dev is about to reset... */
break;
}
@@ -403,16 +410,14 @@ reset_aux_dev(int port)
if (c != -1) /* wait again if the controller is not ready */
break;
}
-#ifdef KBDIO_DEBUG
+ if (verbose)
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
+ if (verbose)
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;
}
@@ -422,49 +427,91 @@ reset_aux_dev(int port)
int
test_controller(int port)
{
- int c;
+ int retry = KBD_MAXRETRY;
+ int again = KBD_MAXWAIT;
+ int c = KBD_DIAG_FAIL;
+
+ while (retry-- > 0) {
+ empty_both_buffers(port, 10);
+ if (write_controller_command(port, KBDC_DIAGNOSE))
+ break;
+ }
+ if (retry < 0)
+ return FALSE;
- empty_both_buffers(port);
- write_controller_command(port, KBDC_DIAGNOSE);
+ while (again-- > 0) {
+ /* wait awhile */
+ DELAY(KBD_RESETDELAY*1000);
c = read_controller_data(port); /* DIAG_DONE/DIAG_FAIL */
-#ifdef KBDIO_DEBUG
+ if (c != -1) /* wait again if the controller is not ready */
+ break;
+ }
+ if (verbose)
log(LOG_DEBUG,"kbdio: DIAGNOSE status:%04x\n",c);
-#endif
return (c == KBD_DIAG_DONE);
}
int
test_kbd_port(int port)
{
- int c;
+ int retry = KBD_MAXRETRY;
+ int again = KBD_MAXWAIT;
+ int c = -1;
- empty_both_buffers(port);
- write_controller_command(port, KBDC_TEST_KBD_PORT);
+ while (retry-- > 0) {
+ empty_both_buffers(port, 10);
+ if (write_controller_command(port, KBDC_TEST_KBD_PORT))
+ break;
+ }
+ if (retry < 0)
+ return FALSE;
+
+ while (again-- > 0) {
c = read_controller_data(port);
-#ifdef KBDIO_DEBUG
+ if (c != -1) /* try again if the controller is not ready */
+ break;
+ }
+ if (verbose)
log(LOG_DEBUG,"kbdio: TEST_KBD_PORT status:%04x\n",c);
-#endif
return c;
}
int
test_aux_port(int port)
{
- int c;
+ int retry = KBD_MAXRETRY;
+ int again = KBD_MAXWAIT;
+ int c = -1;
- empty_both_buffers(port);
- write_controller_command(port, KBDC_TEST_AUX_PORT);
+ while (retry-- > 0) {
+ empty_both_buffers(port, 10);
+ if (write_controller_command(port, KBDC_TEST_AUX_PORT))
+ break;
+ }
+ if (retry < 0)
+ return FALSE;
+
+ while (again-- > 0) {
c = read_controller_data(port);
-#ifdef KBDIO_DEBUG
+ if (c != -1) /* try again if the controller is not ready */
+ break;
+ }
+ if (verbose)
log(LOG_DEBUG,"kbdio: TEST_AUX_PORT status:%04x\n",c);
-#endif
return c;
}
-void
+int
set_controller_command_byte(int port, int command, int flag)
{
- write_controller_command(port, KBDC_SET_COMMAND_BYTE);
- write_controller_data(port, command | flag);
+ if ((command | flag) & KBD_DISABLE_KBD_PORT) {
+ if (!write_controller_command(port, KBDC_DISABLE_KBD_PORT))
+ return FALSE;
+ }
+ if (!write_controller_command(port, KBDC_SET_COMMAND_BYTE))
+ return FALSE;
+ if (!write_controller_data(port, command | flag))
+ return FALSE;
wait_while_controller_busy(port);
+ return TRUE;
}
diff --git a/sys/i386/isa/kbdio.h b/sys/i386/isa/kbdio.h
index c547780..5833b86 100644
--- a/sys/i386/isa/kbdio.h
+++ b/sys/i386/isa/kbdio.h
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: kbdio.h,v 1.1 1996/11/14 22:19:09 sos Exp $
*/
#ifndef _I386_ISA_KBDIO_H_
@@ -58,6 +58,7 @@
/* controller command byte (set by KBDC_SET_COMMAND_BYTE) */
#define KBD_TRANSLATION 0x0040
#define KBD_RESERVED_BITS 0x0004
+#define KBD_OVERRIDE_KBD_LOCK 0x0008
#define KBD_ENABLE_KBD_PORT 0x0000
#define KBD_DISABLE_KBD_PORT 0x0010
#define KBD_ENABLE_AUX_PORT 0x0000
@@ -86,10 +87,12 @@
#define PSMC_DISABLE_DEV 0x00f5
#define PSMC_SEND_DEV_ID 0x00f2
#define PSMC_SEND_DEV_STATUS 0x00e9
+#define PSMC_SEND_DEV_DATA 0x00eb
#define PSMC_SET_SCALING11 0x00e6
#define PSMC_SET_SCALING21 0x00e7
#define PSMC_SET_RESOLUTION 0x00e8
#define PSMC_SET_STREAM_MODE 0x00ea
+#define PSMC_SET_REMOTE_MODE 0x00f0
#define PSMC_SET_SAMPLING_RATE 0x00f3
/* PSMC_SET_RESOLUTION argument */
@@ -111,7 +114,7 @@
#define KBDS_ANY_BUFFER_FULL 0x0001
#define KBDS_KBD_BUFFER_FULL 0x0001
#define KBDS_AUX_BUFFER_FULL 0x0021
-#define KBDS_CONTROLLER_BUSY 0x0002
+#define KBDS_INPUT_BUFFER_FULL 0x0002
/* return code */
#define KBD_ACK 0x00fa
@@ -165,17 +168,16 @@
/* 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));
+int write_controller_command __P((int port,int c));
+int 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 write_kbd_command __P((int port,int c));
+int 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));
@@ -186,9 +188,9 @@ 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));
+void empty_kbd_buffer __P((int port, int t));
+void empty_aux_buffer __P((int port, int t));
+void empty_both_buffers __P((int port, int t));
int reset_kbd __P((int port));
int reset_aux_dev __P((int port));
@@ -197,7 +199,7 @@ 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));
+int set_controller_command_byte __P((int port,int command,int flag));
#endif /* KERNEL */
diff --git a/sys/i386/isa/psm.c b/sys/i386/isa/psm.c
index 2e11729..2709038 100644
--- a/sys/i386/isa/psm.c
+++ b/sys/i386/isa/psm.c
@@ -19,7 +19,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: psm.c,v 1.30 1996/11/27 22:52:25 phk Exp $
+ * $Id: psm.c,v 1.31 1996/11/28 17:18:56 phk Exp $
*/
/*
@@ -51,9 +51,9 @@
* - 3 October 1996.
* - 14 October 1996.
* - 22 October 1996.
- * - 28 October 1996. Start adding IOCTLs.
* - 12 November 1996. IOCTLs and rearranging `psmread', `psmioctl'...
* - 14 November 1996. Uses `kbdio.c'.
+ * - 30 November 1996. More fixes.
*/
#include "psm.h"
@@ -90,20 +90,20 @@
#define PSM_DEBUG 0 /* logging: 0: none, 1: brief, 2: verbose */
#endif
-/* features */
-/* #define PSM_NOCHECKSYNC if defined, don't check the header data byte */
+/* #define PSM_CHECKSYNC if defined, check the header data byte */
+/* features */
#ifndef PSM_ACCEL
#define PSM_ACCEL 0 /* must be one or greater; acceleration will be
* disabled if zero */
#endif
-/* #define PSM_NOEMULATION disables protocol emulation */
+/* #define PSM_EMULATION enables protocol emulation */
/* end of driver specific options */
/* default values */
-#define PSMD_DEFAULT_RESOLUTION 800 /* resolution: 800 ppi */
+#define PSMD_DEFAULT_RESOLUTION 200 /* resolution: 200 ppi */
#define PSMD_DEFAULT_RATE 100 /* report rate: 100 Hz */
/* some macros */
@@ -118,14 +118,6 @@
#define min(x,y) ((x) < (y) ? (x) : (y))
#endif
-/* mouse status block */
-typedef struct mousestatus {
- int button; /* button status */
- int obutton; /* previous button status */
- int dx; /* x movement */
- int dy; /* y movement */
-} mousestatus_t;
-
/* ring buffer */
#define PSM_BUFSIZE 256
@@ -169,7 +161,9 @@ static struct psm_softc { /* Driver status information */
static int psmprobe __P((struct isa_device *));
static int psmattach __P((struct isa_device *));
static int mkms __P((unsigned char *, int *, int, mousestatus_t *));
+static int mkman __P((unsigned char *, int *, int, mousestatus_t *));
static int mkmsc __P((unsigned char *, int *, int, mousestatus_t *));
+static int mkmm __P((unsigned char *, int *, int, mousestatus_t *));
static int mkps2 __P((unsigned char *, int *, int, mousestatus_t *));
static d_open_t psmopen;
@@ -221,7 +215,7 @@ get_mouse_status(int port, int *status)
{
int res;
- empty_both_buffers(port);
+ empty_both_buffers(port, 2);
res = send_aux_command(port, PSMC_SEND_DEV_STATUS);
if (verbose >= 2)
log(LOG_DEBUG, "psm: SEND_AUX_STATUS return code:%04x\n", res);
@@ -238,23 +232,18 @@ get_mouse_status(int port, int *status)
static int
get_aux_id(int port)
{
- int retry;
+ int res;
int id;
- int c;
- for (retry = KBD_MAXRETRY; retry > 0; --retry) {
- empty_both_buffers(port);
- write_aux_command(port, PSMC_SEND_DEV_ID);
+ empty_both_buffers(port, 2);
+ res = send_aux_command(port, PSMC_SEND_DEV_ID);
+ if (verbose >= 2)
+ log(LOG_DEBUG, "psm: SEND_DEV_ID return code:%04x\n", res);
+ if (res != PSM_ACK)
+ return (-1);
+
/* 10ms delay */
DELAY(10000);
- c = read_controller_data(port);
- if (verbose >= 2)
- log(LOG_DEBUG, "psm: SEND_DEV_ID return code:%04x\n", c);
- if (c == PSM_ACK)
- break;
- }
- if (retry <= 0)
- return -1;
id = read_aux_data(port);
if (verbose >= 2)
@@ -287,13 +276,10 @@ set_mouse_scaling(int port)
return (res == PSM_ACK);
}
-static int
-set_mouse_resolution(int port, int res)
-{
- static struct {
+static struct {
int resolution;
int code;
- } rescode[] = {
+} rescode[] = {
{ 25, PSMD_RESOLUTION_25 },
{ 50, PSMD_RESOLUTION_50 },
{ 100, PSMD_RESOLUTION_100 },
@@ -301,12 +287,17 @@ set_mouse_resolution(int port, int res)
{ 400, PSMD_RESOLUTION_400 }, /* ?? */
{ 800, PSMD_RESOLUTION_800 }, /* ?? */
{ INT_MAX, PSMD_MAX_RESOLUTION },
- };
+ { -1 },
+};
+
+static int
+set_mouse_resolution(int port, int res)
+{
int ret;
int i;
if (res <= 0)
- return FALSE;
+ return (-1);
for (i = 0; rescode[i].resolution > 0; ++i)
if (rescode[i].resolution >= res)
break;
@@ -344,6 +335,7 @@ static int
get_mouse_buttons(int port)
{
int c = 2; /* assume two buttons by default */
+ int res;
int status[3];
/*
@@ -352,7 +344,7 @@ get_mouse_buttons(int port)
* scaling to 1:1, set scaling to 1:1. Then the second byte of the
* mouse status bytes is the number of available buttons.
*/
- if (!set_mouse_resolution(port, 25))
+ if (set_mouse_resolution(port, 25) != 25)
return c;
if (set_mouse_scaling(port) && set_mouse_scaling(port)
&& set_mouse_scaling(port) && get_mouse_status(port, status)) {
@@ -386,15 +378,16 @@ is_a_mouse(int id)
if (valid_ids[i] == id)
return TRUE;
return FALSE;
-#endif
+#else
return TRUE;
+#endif
}
static void
recover_from_error(int port)
{
/* discard anything left in the output buffer */
- empty_both_buffers(port);
+ empty_both_buffers(port, 10);
#if 0
/*
@@ -407,19 +400,100 @@ recover_from_error(int port)
* NOTE: somehow diagnostic and keyboard port test commands bring the
* keyboard back.
*/
- test_controller(port);
- test_kbd_port(port);
+ if (!test_controller(port))
+ log(LOG_ERR, "psm: keyboard controller failed.\n");
+ /* if there isn't a keyboard in the system, the following error is OK */
+ if (test_kbd_port(port) != 0) {
+ if (verbose)
+ log(LOG_ERR, "psm: keyboard port failed.\n");
+ }
#endif
}
-static void
+static int
restore_controller(int port, int command_byte)
{
- set_controller_command_byte(port, command_byte, 0);
+ if (!set_controller_command_byte(port, command_byte, 0)) {
+ log(LOG_ERR, "psm: failed to restore the keyboard controller "
+ "command byte.\n");
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+/*
+ * Re-initialize the aux port and device. The aux port must be enabled
+ * and its interrupt must be disabled before calling this routine.
+ * The aux device will be disabled before returning.
+ */
+static int
+reinitialize(dev_t dev, mousemode_t *mode)
+{
+ int port = psm_softc[PSM_UNIT(dev)]->addr;
+ int stat[3];
+ int i;
+
+ switch((i = test_aux_port(port))) {
+ case 0: /* no error */
+ break;
+ case -1: /* time out */
+ default: /* error */
+ recover_from_error(port);
+ log(LOG_ERR, "psm%d: the aux port is not functioning (%d).\n",
+ PSM_UNIT(dev),i);
+ return FALSE;
+ }
+
+ /*
+ * NOTE: some controllers appears to hang the `keyboard' when
+ * the aux port doesn't exist and `PSMC_RESET_DEV' is issued.
+ */
+ if (!reset_aux_dev(port)) {
+ recover_from_error(port);
+ log(LOG_ERR, "psm%d: failed to reset the aux device.\n",
+ PSM_UNIT(dev));
+ return FALSE;
+ }
+
+ /*
+ * both the aux port and the aux device is functioning, see
+ * if the device can be enabled.
+ */
+ if (!enable_aux_dev(port) || !disable_aux_dev(port)) {
+ log(LOG_ERR, "psm%d: failed to enable the aux device.\n",
+ PSM_UNIT(dev));
+ return FALSE;
+ }
+ empty_both_buffers(port, 10);
+
+ /* set mouse parameters */
+ if (mode != (mousemode_t *)NULL) {
+ if (mode->rate > 0)
+ mode->rate = set_mouse_sampling_rate(port, mode->rate);
+ if (mode->resolution > 0)
+ mode->resolution = set_mouse_resolution(port, mode->resolution);
+ set_mouse_scaling(port);
+ set_mouse_mode(port);
+ }
+
+ /* just check the status of the mouse */
+ if (verbose) {
+ get_mouse_status(port, stat);
+ log(LOG_DEBUG, "psm%d: status %02x %02x %02x (reinitialized)\n",
+ PSM_UNIT(dev), stat[0], stat[1], stat[2]);
+ }
+
+ return TRUE;
}
/* psm driver entry points */
+#define endprobe(v) { if (bootverbose) \
+ --verbose; \
+ return (v); \
+ }
+
static int
psmprobe(struct isa_device *dvp)
{
@@ -427,6 +501,7 @@ psmprobe(struct isa_device *dvp)
int ioport = dvp->id_iobase;
struct psm_softc *sc;
int stat[3];
+ int setparams;
int i;
/* validate unit number */
@@ -481,29 +556,43 @@ psmprobe(struct isa_device *dvp)
*/
/* save the current command byte; it will be used later */
- write_controller_command(ioport, KBDC_GET_COMMAND_BYTE);
+ if (!write_controller_command(ioport,KBDC_GET_COMMAND_BYTE)) {
+ /* CONTROLLER ERROR */
+ printf("psm%d: failed to get the current command byte value.\n",
+ unit);
+ free(sc, M_DEVBUF);
+ endprobe(0);
+ }
sc->command_byte = read_controller_data(ioport);
if (verbose) {
printf("psm%d: current command byte:%04x\n",
unit, sc->command_byte);
}
if (sc->command_byte == -1) {
+ /* CONTROLLER ERROR */
printf("psm%d: unable to get the current command byte value.\n",
unit);
free(sc, M_DEVBUF);
- return (0);
+ endprobe(0);
}
/*
* disable the keyboard port while probing the aux port, which must be
* enabled during this routine
*/
- write_controller_command(ioport, KBDC_DISABLE_KBD_PORT);
- set_controller_command_byte(ioport,
- sc->command_byte
- & ~(KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS),
+ if (!set_controller_command_byte(ioport,
+ sc->command_byte & ~(KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS),
KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
- | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+ | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
+ /*
+ * this is CONTROLLER ERROR; I don't know how to recover
+ * from this error...
+ */
+ restore_controller(ioport, sc->command_byte);
+ printf("psm%d: unable to set the command byte.\n", unit);
+ free(sc, M_DEVBUF);
+ endprobe(0);
+ }
/*
* NOTE: `test_aux_port()' is designed to return with zero if the aux
@@ -526,10 +615,8 @@ psmprobe(struct isa_device *dvp)
if (verbose)
printf("psm%d: the aux port is not functioning (%d).\n",
unit, i);
- if (bootverbose)
- --verbose;
free(sc, M_DEVBUF);
- return (0);
+ endprobe(0);
}
/*
@@ -542,7 +629,7 @@ psmprobe(struct isa_device *dvp)
if (verbose)
printf("psm%d: failed to reset the aux device.\n", unit);
free(sc, M_DEVBUF);
- return (0);
+ endprobe(0);
}
/*
* both the aux port and the aux device is functioning, see if the
@@ -551,15 +638,31 @@ psmprobe(struct isa_device *dvp)
* the device can be enabled.
*/
if (!enable_aux_dev(ioport) || !disable_aux_dev(ioport)) {
+ /* MOUSE ERROR */
restore_controller(ioport, sc->command_byte);
if (verbose)
printf("psm%d: failed to enable the aux device.\n", unit);
- if (bootverbose)
- --verbose;
free(sc, M_DEVBUF);
- return (0);
+ endprobe(0);
+ }
+ empty_both_buffers(ioport, 10); /* remove stray data if any */
+
+ /* save the default values after reset */
+ if (get_mouse_status(ioport, stat)) {
+ if (verbose)
+ printf("psm%d: status after reset %02x %02x %02x\n",
+ unit, stat[0], stat[1], stat[2]);
+ sc->mode.rate = stat[2];
+ sc->mode.resolution = PSMD_DEFAULT_RESOLUTION;
+ for (i = 0; rescode[i].resolution > 0; ++i)
+ if (rescode[i].code == stat[1])
+ sc->mode.resolution = rescode[i].resolution;
+ setparams = TRUE;
+ } else {
+ sc->mode.rate = -1;
+ sc->mode.resolution = -1;
+ setparams = FALSE;
}
- empty_both_buffers(ioport); /* remove stray data if any */
/* hardware information */
sc->hw.iftype = MOUSE_IF_PS2;
@@ -570,10 +673,8 @@ psmprobe(struct isa_device *dvp)
restore_controller(ioport, sc->command_byte);
if (verbose)
printf("psm%d: unknown device type (%d).\n", unit, sc->hw.hwid);
- if (bootverbose)
- --verbose;
free(sc, M_DEVBUF);
- return (0);
+ endprobe(0);
}
switch (sc->hw.hwid) {
case PSM_BALLPOINT_ID:
@@ -588,15 +689,18 @@ psmprobe(struct isa_device *dvp)
}
/* # of buttons */
- sc->hw.buttons = get_mouse_buttons(ioport);
+ sc->hw.buttons = (setparams) ? get_mouse_buttons(ioport) : 2;
/* set mouse parameters */
-
- /* FIXME:XXX I don't know if these parameters are reasonable */
/* FIXME:XXX should we set them in `psmattach()' rather than here? */
- sc->mode.rate = set_mouse_sampling_rate(ioport, PSMD_DEFAULT_RATE);
+ if (setparams) {
+ if (sc->mode.rate > 0)
+ sc->mode.rate = set_mouse_sampling_rate(ioport, sc->mode.rate);
+ if (sc->mode.resolution > 0)
sc->mode.resolution =
- set_mouse_resolution(ioport, PSMD_DEFAULT_RESOLUTION);
+ set_mouse_resolution(ioport, sc->mode.resolution);
+ }
+ /* FIXME:XXX I don't know if these parameters are reasonable */
set_mouse_scaling(ioport); /* 1:1 scaling */
set_mouse_mode(ioport); /* stream mode */
@@ -616,9 +720,19 @@ psmprobe(struct isa_device *dvp)
* the course of its operation (this is the case with `syscons'). If
* not,...
*/
+ if (!set_controller_command_byte(ioport,
+ sc->command_byte & ~KBD_AUX_CONTROL_BITS,
+ KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
+ /*
+ * this is CONTROLLER ERROR; I don't know the proper way to
+ * recover from this error...
+ */
+ restore_controller(ioport, sc->command_byte);
+ printf("psm%d: unable to set the command byte.\n", unit);
+ free(sc, M_DEVBUF);
+ endprobe(0);
+ }
sc->command_byte &= ~KBD_AUX_CONTROL_BITS;
- set_controller_command_byte(ioport, sc->command_byte,
- KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
/* done */
psm_softc[unit] = sc;
@@ -673,6 +787,7 @@ psmopen(dev_t dev, int flag, int fmt, struct proc *p)
/* Get device data */
sc = psm_softc[unit];
if ((sc->state & PSM_VALID) == 0)
+ /* the device is no longer valid/functioning */
return (ENXIO);
ioport = sc->addr;
@@ -681,7 +796,6 @@ psmopen(dev_t dev, int flag, int fmt, struct proc *p)
return (EBUSY);
/* Initialize state */
- sc->state |= PSM_OPEN;
sc->rsel.si_flags = 0;
sc->rsel.si_pid = 0;
@@ -697,29 +811,64 @@ psmopen(dev_t dev, int flag, int fmt, struct proc *p)
sc->outputhead = 0;
/* enable the aux port and temporalily disable the keyboard */
- write_controller_command(ioport, KBDC_DISABLE_KBD_PORT);
- set_controller_command_byte(ioport,
+ if (!set_controller_command_byte(ioport,
sc->command_byte & ~KBD_KBD_CONTROL_BITS,
KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
- | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+ | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
+ /* CONTROLLER ERROR; do you know how to get out of this? */
+ set_controller_command_byte(ioport,
+ sc->command_byte, KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+ log(LOG_ERR, "psm%d: unable to set the command byte (psmopen).\n",
+ unit);
+ return (EIO);
+ }
/* enable the mouse device */
if (!enable_aux_dev(ioport)) {
- set_controller_command_byte(ioport, sc->command_byte,
- KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
- log(LOG_ERR, "psm%d: unable to enable the pointing device.\n", unit);
+ /* MOUSE ERROR: failed to enable the mouse because:
+ * 1) the mouse is faulty,
+ * 2) the mouse has been removed(!?)
+ * In the latter case, the keyboard may have hung, and need
+ * recovery procedure...
+ */
+ recover_from_error(ioport);
+#if 0
+ /* FIXME: we could reset the mouse here and try to enable
+ * it again. But it will take long time and it's not a good
+ * idea to disable the keyboard that long...
+ */
+ if (!reinitialize(dev, &sc->mode) || !enable_aux_dev(ioport))
+ recover_from_error(ioport);
+#endif
+ set_controller_command_byte(ioport,
+ sc->command_byte, KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+ /* mark this device is no longer available */
+ sc->state &= ~PSM_VALID;
+ log(LOG_ERR, "psm%d: failed to enable the device (psmopen).\n",
+ unit);
return (EIO);
}
+
if (verbose >= 2) {
get_mouse_status(ioport, stat);
log(LOG_DEBUG, "psm%d: status %02x %02x %02x\n",
unit, stat[0], stat[1], stat[2]);
}
+
/* enable the aux port and interrupt */
+ if (!set_controller_command_byte(ioport, sc->command_byte,
+ KBD_ENABLE_AUX_PORT | KBD_ENABLE_AUX_INT)) {
+ /* CONTROLLER ERROR */
+ disable_aux_dev(ioport);
set_controller_command_byte(ioport, sc->command_byte,
- KBD_ENABLE_AUX_PORT | KBD_ENABLE_AUX_INT);
+ KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+ log(LOG_ERR, "psm%d: failed to enable the aux interrupt (psmopen).\n",
+ unit);
+ return (EIO);
+ }
/* done */
+ sc->state |= PSM_OPEN;
return (0);
}
@@ -730,46 +879,65 @@ psmclose(dev_t dev, int flag, int fmt, struct proc *p)
int ioport = sc->addr;
/* disable the aux interrupt */
- set_controller_command_byte(ioport, sc->command_byte,
- KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+ if (!set_controller_command_byte(ioport, sc->command_byte,
+ KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
+ log(LOG_ERR, "psm%d: failed to disable the aux int (psmclose).\n",
+ PSM_UNIT(dev));
+ /* CONTROLLER ERROR;
+ * NOTE: we shall force our way through. Because the only
+ * ill effect we shall see is that we may not be able
+ * to read ACK from the mouse, and it doesn't matter much
+ * so long as the mouse will accept the DISABLE command.
+ */
+ }
/* remove anything left in the output buffer */
- empty_aux_buffer(ioport);
+ empty_aux_buffer(ioport, 20);
/* disable the aux device, port and interrupt */
- disable_aux_dev(ioport);
- set_controller_command_byte(ioport, sc->command_byte,
- KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+ if (!disable_aux_dev(ioport)) {
+ /* MOUSE ERROR;
+ * NOTE: we don't return error and continue, pretending
+ * we have successfully disabled the device. It's OK because
+ * the interrupt routine will discard any data from the mouse
+ * hereafter.
+ */
+ log(LOG_ERR, "psm%d: failed to disable the device (psmclose).\n",
+ PSM_UNIT(dev));
+ }
+ if (!set_controller_command_byte(ioport, sc->command_byte,
+ KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
+ /* CONTROLLER ERROR;
+ * we shall ignore this error; see the above comment.
+ */
+ log(LOG_ERR, "psm%d: failed to disable the aux port (psmclose).\n",
+ PSM_UNIT(dev));
+ }
/* remove anything left in the output buffer */
- empty_aux_buffer(ioport);
-
- /* Complete the close */
- sc->state &= ~PSM_OPEN;
+ empty_aux_buffer(ioport, 10);
/* close is almost always successful */
+ sc->state &= ~PSM_OPEN;
return (0);
}
+#ifdef PSM_EMULATION
static int
mkms(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
{
static int butmap[] = {
- 0,
- MOUSE_MSS_BUTTON3DOWN, MOUSE_MSS_BUTTON2DOWN,
- MOUSE_MSS_BUTTON3DOWN | MOUSE_MSS_BUTTON2DOWN,
- MOUSE_MSS_BUTTON1DOWN,
- MOUSE_MSS_BUTTON3DOWN | MOUSE_MSS_BUTTON1DOWN,
- MOUSE_MSS_BUTTON2DOWN | MOUSE_MSS_BUTTON1DOWN,
- MOUSE_MSS_BUTTON3DOWN | MOUSE_MSS_BUTTON2DOWN | MOUSE_MSS_BUTTON1DOWN,
+ 0, MOUSE_MSS_BUTTON1DOWN,
+ 0, MOUSE_MSS_BUTTON1DOWN ,
+ MOUSE_MSS_BUTTON3DOWN, MOUSE_MSS_BUTTON1DOWN | MOUSE_MSS_BUTTON3DOWN,
+ MOUSE_MSS_BUTTON3DOWN, MOUSE_MSS_BUTTON1DOWN | MOUSE_MSS_BUTTON3DOWN,
};
unsigned char delta;
if (maxlen - *len < MOUSE_MSS_PACKETSIZE)
return FALSE;
- buf[0] = MOUSE_MSS_SYNC;
- buf[0] |= butmap[status->button & BUTSTATMASK];
+ buf[0] = MOUSE_MSS_SYNC | butmap[status->button & MOUSE_STDBUTTONS];
if (status->dx < -128)
delta = 0x80; /* -128 */
@@ -797,24 +965,23 @@ mkms(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
}
static int
-mkmsc(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
+mkman(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
{
static int butmap[] = {
- 0,
- MOUSE_MSC_BUTTON3UP, MOUSE_MSC_BUTTON2UP,
- MOUSE_MSC_BUTTON3UP | MOUSE_MSC_BUTTON2UP,
- MOUSE_MSC_BUTTON1UP,
- MOUSE_MSC_BUTTON3UP | MOUSE_MSC_BUTTON1UP,
- MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON1UP,
- MOUSE_MSC_BUTTON3UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON1UP,
+ 0, MOUSE_MSS_BUTTON1DOWN,
+ 0, MOUSE_MSS_BUTTON1DOWN,
+ MOUSE_MSS_BUTTON3DOWN, MOUSE_MSS_BUTTON1DOWN | MOUSE_MSS_BUTTON3DOWN,
+ MOUSE_MSS_BUTTON3DOWN, MOUSE_MSS_BUTTON1DOWN | MOUSE_MSS_BUTTON3DOWN,
};
unsigned char delta;
+ int l;
- if (maxlen - *len < MOUSE_PS2_PACKETSIZE)
+ l = ((status->button ^ status->obutton) & MOUSE_BUTTON2DOWN) ?
+ MOUSE_MSS_PACKETSIZE + 1: MOUSE_MSS_PACKETSIZE;
+ if (maxlen - *len < l)
return FALSE;
- buf[0] = MOUSE_MSC_SYNC;
- buf[0] |= ~butmap[status->button & BUTSTATMASK] & MOUSE_MSC_BUTTONS;
+ buf[0] = MOUSE_MSS_SYNC | butmap[status->button & MOUSE_STDBUTTONS];
if (status->dx < -128)
delta = 0x80; /* -128 */
@@ -823,8 +990,8 @@ mkmsc(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
delta = 0x7f; /* 127 */
else
delta = (unsigned char) status->dx;
- buf[1] = delta >> 2;
- buf[3] = delta - buf[1];
+ buf[0] |= (delta & 0xc0) >> 6; /* bit 6-7 */
+ buf[1] = delta & 0x3f; /* bit 0-5 */
if (status->dy < -128)
delta = 0x80; /* -128 */
@@ -833,7 +1000,59 @@ mkmsc(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
delta = 0x7f; /* 127 */
else
delta = (unsigned char) status->dy;
- buf[2] = delta >> 2;
+ buf[0] |= (delta & 0xc0) >> 4; /* bit 6-7 */
+ buf[2] = delta & 0x3f; /* bit 0-5 */
+
+ if (l > MOUSE_MSS_PACKETSIZE)
+ buf[3] = (status->button & MOUSE_BUTTON2DOWN)
+ ? MOUSE_LMAN_BUTTON2DOWN : 0;
+
+ *len += l;
+
+ return TRUE;
+}
+
+static int
+mkmsc(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
+{
+ static int butmap[] = {
+ 0,
+ MOUSE_MSC_BUTTON1UP, MOUSE_MSC_BUTTON2UP,
+ MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP,
+ MOUSE_MSC_BUTTON3UP,
+ MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP,
+ MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
+ MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
+ };
+ register int delta;
+
+ if (maxlen - *len < MOUSE_MSC_PACKETSIZE)
+ return FALSE;
+
+ buf[0] = MOUSE_MSC_SYNC
+ | (~butmap[status->button & MOUSE_STDBUTTONS] & MOUSE_MSC_BUTTONS);
+
+ /* data bytes cannot be between 80h (-128) and 87h (-120).
+ * values we can return is 255 (0ffh) through -251 (10fh = 87h*2 + 1).
+ */
+ if (status->dx < -251)
+ delta = -251;
+ else
+ if (status->dx > 255)
+ delta = 255;
+ else
+ delta = status->dx;
+ buf[1] = delta/2;
+ buf[3] = delta - buf[1];
+
+ if (status->dy < -251)
+ delta = -251;
+ else
+ if (status->dy > 255)
+ delta = 255;
+ else
+ delta = status->dy;
+ buf[2] = delta/2;
buf[4] = delta - buf[2];
*len += MOUSE_MSC_PACKETSIZE;
@@ -842,24 +1061,59 @@ mkmsc(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
}
static int
+mkmm(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
+{
+ static int butmap[] = {
+ 0,
+ MOUSE_MM_BUTTON1DOWN, MOUSE_MM_BUTTON2DOWN,
+ MOUSE_MM_BUTTON1DOWN | MOUSE_MM_BUTTON2DOWN,
+ MOUSE_MM_BUTTON3DOWN,
+ MOUSE_MM_BUTTON1DOWN | MOUSE_MM_BUTTON3DOWN,
+ MOUSE_MM_BUTTON2DOWN | MOUSE_MM_BUTTON3DOWN,
+ MOUSE_MM_BUTTON1DOWN | MOUSE_MM_BUTTON2DOWN | MOUSE_MM_BUTTON3DOWN,
+ };
+ int delta;
+
+ if (maxlen - *len < MOUSE_MM_PACKETSIZE)
+ return FALSE;
+
+ buf[0] = MOUSE_MM_SYNC
+ | butmap[status->button & MOUSE_STDBUTTONS]
+ | ((status->dx > 0) ? MOUSE_MM_XPOSITIVE : 0)
+ | ((status->dy > 0) ? MOUSE_MM_YPOSITIVE : 0);
+
+ delta = (status->dx < 0) ? -status->dx : status->dx;
+ buf[1] = min(delta, 127);
+ delta = (status->dy < 0) ? -status->dy : status->dy;
+ buf[2] = min(delta, 127);
+
+ *len += MOUSE_MM_PACKETSIZE;
+
+ return TRUE;
+}
+#endif /* PSM_EMULATION */
+
+static int
mkps2(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
{
static int butmap[] = {
0,
- MOUSE_PS2_BUTTON3DOWN, MOUSE_PS2_BUTTON2DOWN,
- MOUSE_PS2_BUTTON3DOWN | MOUSE_PS2_BUTTON2DOWN,
- MOUSE_PS2_BUTTON1DOWN,
- MOUSE_PS2_BUTTON3DOWN | MOUSE_PS2_BUTTON1DOWN,
- MOUSE_PS2_BUTTON2DOWN | MOUSE_PS2_BUTTON1DOWN,
- MOUSE_PS2_BUTTON3DOWN | MOUSE_PS2_BUTTON2DOWN | MOUSE_PS2_BUTTON1DOWN,
+ MOUSE_PS2_BUTTON1DOWN, MOUSE_PS2_BUTTON2DOWN,
+ MOUSE_PS2_BUTTON1DOWN | MOUSE_PS2_BUTTON2DOWN,
+ MOUSE_PS2_BUTTON3DOWN,
+ MOUSE_PS2_BUTTON1DOWN | MOUSE_PS2_BUTTON3DOWN,
+ MOUSE_PS2_BUTTON2DOWN | MOUSE_PS2_BUTTON3DOWN,
+ MOUSE_PS2_BUTTON1DOWN | MOUSE_PS2_BUTTON2DOWN | MOUSE_PS2_BUTTON3DOWN,
};
register int delta;
if (maxlen - *len < MOUSE_PS2_PACKETSIZE)
return FALSE;
- buf[0] = MOUSE_PS2_SYNC;
- buf[0] |= butmap[status->button & BUTSTATMASK];
+ buf[0] = ((status->button & MOUSE_BUTTON4DOWN) ? 0 : MOUSE_PS2_BUTTON4UP)
+ | butmap[status->button & MOUSE_STDBUTTONS];
+ if ((verbose >= 2) && ((buf[0] & MOUSE_PS2_BUTTON4UP) == 0))
+ log(LOG_DEBUG, "psm: button 4 down (%04x) (mkps2)\n", buf[0]);
if (status->dx < -128)
delta = -128;
@@ -906,14 +1160,14 @@ psmread(dev_t dev, struct uio *uio, int flag)
return (EWOULDBLOCK);
}
sc->state |= PSM_ASLP;
- error = tsleep((caddr_t) sc, PZERO | PCATCH,
- "psmread", 0);
+ error = tsleep((caddr_t) sc, PZERO | PCATCH, "psmread", 0);
if (error) {
splx(s);
return (error);
}
}
}
+
if (sc->outputbytes >= uio->uio_resid) {
/* nothing to be done */
} else {
@@ -949,8 +1203,8 @@ static int
psmioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
{
struct psm_softc *sc = psm_softc[PSM_UNIT(dev)];
- mouseinfo_t info;
- mousestatus_t *ms;
+ mousemode_t mode;
+ mousestatus_t status;
packetfunc_t func;
int error = 0;
int s;
@@ -967,22 +1221,35 @@ psmioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
break;
case MOUSE_SETMODE:
- if (((mousemode_t *) addr)->rate < 0) {
- error = EINVAL;
- break;
+ mode = *(mousemode_t *) addr;
+ if (mode.rate == 0) {
+ mode.rate = PSMD_DEFAULT_RATE;
+ } else if (mode.rate > 0) {
+ mode.rate = min(mode.rate, PSMD_MAX_RATE);
+ } else { /* mode.rate < 0 */
+ mode.rate = sc->mode.rate;
+ }
+ if (mode.resolution == 0) {
+ mode.resolution = PSMD_DEFAULT_RESOLUTION;
+ } else if (mode.resolution > 0) {
+ mode.resolution = mode.resolution;
+ } else { /* mode.resolution < 0 */
+ mode.resolution = sc->mode.resolution;
}
- if (((mousemode_t *) addr)->resolution < 0) {
- error = EINVAL;
- break;
- }
-#ifndef PSM_NOEMULATION
- switch (((mousemode_t *) addr)->protocol) {
+#ifdef PSM_EMULATION
+ switch (mode.protocol) {
case MOUSE_PROTO_MS:
func = mkms;
break;
+ case MOUSE_PROTO_LOGIMOUSEMAN:
+ func = mkman;
+ break;
case MOUSE_PROTO_MSC:
func = mkmsc;
break;
+ case MOUSE_PROTO_MM:
+ func = mkmm;
+ break;
case MOUSE_PROTO_PS2:
func = mkps2;
break;
@@ -993,42 +1260,59 @@ psmioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
}
if (error)
break;
-#endif /* PSM_NOEMULATION */
- if (((mousemode_t *) addr)->accelfactor < 0) {
+#else
+ mode.protocol = sc->mode.protocol;
+#endif /* PSM_EMULATION */
+ if (mode.accelfactor < 0) {
error = EINVAL;
break;
}
+
s = spltty(); /* disable interrupt while updating */
- sc->mode.rate = (((mousemode_t *) addr)->rate == 0) ?
- PSMD_DEFAULT_RATE :
- min(((mousemode_t *) addr)->rate, PSMD_MAX_RATE);
- sc->mode.resolution = (((mousemode_t *) addr)->resolution == 0) ?
- PSMD_DEFAULT_RESOLUTION :
- ((mousemode_t *) addr)->resolution;
/* temporalily disable the keyboard */
- write_controller_command(sc->addr, KBDC_DISABLE_KBD_PORT);
- set_controller_command_byte(sc->addr,
+ if (!set_controller_command_byte(sc->addr,
sc->command_byte & ~KBD_KBD_CONTROL_BITS,
KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
- | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+ | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
+ /* this is CONTROLLER ERROR; I don't know how to recover
+ * from this error. The least we can do is to send
+ * ENABLE_KBD_PORT...
+ */
+ write_controller_command(sc->addr, KBDC_ENABLE_KBD_PORT);
+ splx(s);
+ log(LOG_ERR, "psm%d: failed to set the command byte (psmioctl).\n",
+ PSM_UNIT(dev));
+ error = EIO;
+ break;
+ }
/* program the mouse */
- sc->mode.rate = set_mouse_sampling_rate(sc->addr, sc->mode.rate);
- sc->mode.resolution =
- set_mouse_resolution(sc->addr, sc->mode.resolution);
+ if (mode.rate > 0)
+ mode.rate = set_mouse_sampling_rate(sc->addr, mode.rate);
+ if (mode.resolution > 0)
+ mode.resolution = set_mouse_resolution(sc->addr, mode.resolution);
/* enable the aux port and interrupt */
- set_controller_command_byte(sc->addr, sc->command_byte,
- KBD_ENABLE_AUX_PORT | KBD_ENABLE_AUX_INT);
-
-#ifndef PSM_NOEMULATION
- sc->mode.protocol = ((mousemode_t *) addr)->protocol;
+ if (!set_controller_command_byte(sc->addr, sc->command_byte,
+ KBD_ENABLE_AUX_PORT | KBD_ENABLE_AUX_INT)) {
+ /* CONTROLLER ERROR; this is serious, we may have
+ * been left with the unaccessible keyboard and
+ * the disabled mouse interrupt.
+ */
+ splx(s);
+ log(LOG_ERR, "psm%d: failed to re-enable the aux port and int (psmioctl).\n",
+ PSM_UNIT(dev));
+ error = EIO;
+ break;
+ }
+
+ sc->mode = mode;
+#ifdef PSM_EMULATION
sc->mkpacket = func;
sc->outputbytes = 0;
sc->outputhead = 0;
-#endif /* PSM_NOEMULATION */
- sc->mode.accelfactor = ((mousemode_t *) addr)->accelfactor;
+#endif /* PSM_EMULATION */
splx(s);
break;
@@ -1038,30 +1322,18 @@ psmioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
break;
case MOUSE_GETSTATE:
- info.status = 0;
- info.xmotion = 0;
- info.ymotion = 0;
-
s = spltty();
if (sc->queue.count > 0) {
- ms = &sc->queue.buf[sc->queue.head];
-
- /* button status */
- info.status = ms->button; /* BUT?STAT bits */
- info.status |= /* BUT?CHNG bits */
- ((ms->button ^ ms->obutton) << 3);
- /* mouse motion */
- info.xmotion = ms->dx;
- info.ymotion = ms->dy;
- if ((info.xmotion != 0) || (info.ymotion != 0))
- info.status |= MOVEMENT;
-
+ status = sc->queue.buf[sc->queue.head];
sc->queue.head = (sc->queue.head + 1) % PSM_BUFSIZE;
--sc->queue.count;
+ } else {
+ status.button = status.obutton = sc->button;
+ status.dx = status.dy = 0;
}
splx(s);
- *(mouseinfo_t *) addr = info;
+ *(mousestatus_t *) addr = status;
break;
default:
@@ -1078,12 +1350,16 @@ psmintr(int unit)
{
/*
* the table to turn PS/2 mouse button bits (MOUSE_PS2_BUTTON?DOWN)
- * into `mouseinfo' button bits (BUT?STAT).
+ * into `mousestatus' button bits (BUTTON?DOWN).
*/
static butmap[8] = {
- 0, BUT1STAT, BUT3STAT, BUT1STAT | BUT3STAT,
- BUT2STAT, BUT1STAT | BUT2STAT, BUT2STAT | BUT3STAT,
- BUT1STAT | BUT2STAT | BUT3STAT
+ 0,
+ MOUSE_BUTTON1DOWN, MOUSE_BUTTON3DOWN,
+ MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN,
+ MOUSE_BUTTON2DOWN,
+ MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN,
+ MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN,
+ MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN
};
register struct psm_softc *sc = psm_softc[unit];
int ioport = sc->addr;
@@ -1095,6 +1371,7 @@ psmintr(int unit)
if ((inb(ioport + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
!= KBDS_AUX_BUFFER_FULL)
return;
+ DELAY(7);
/* read a byte */
c = inb(ioport + KBD_DATA_PORT);
@@ -1103,8 +1380,9 @@ psmintr(int unit)
if ((sc->state & PSM_OPEN) == 0)
return;
+ /* interpret data bytes */
/*
- * interpret data bytes FIXME: there seems no way to reliably
+ * FIXME: there seems no way to reliably
* re-synchronize with the PS/2 mouse once we are out of sync. Sure,
* there is sync bits in the first data byte, but the second and the
* third bytes may have these bits on (they are not functioning as
@@ -1113,10 +1391,14 @@ psmintr(int unit)
* without moving the mouse?)
*/
if (sc->inputbytes == 0) {
-#ifndef PSM_NOCHECKSYNC
+#ifdef PSM_CHECKSYNC
if ((c & MOUSE_PS2_SYNCMASK) == MOUSE_PS2_SYNC)
-#endif /* PSM_NOCHECKSYNC */
sc->ipacket[sc->inputbytes++] = c;
+ else
+ log(LOG_DEBUG, "psmintr: sync. bit is off.\n");
+#else
+ sc->ipacket[sc->inputbytes++] = c;
+#endif /* PSM_CHECKSYNC */
} else {
sc->ipacket[sc->inputbytes++] = c;
if (sc->inputbytes >= MOUSE_PS2_PACKETSIZE) {
@@ -1163,7 +1445,15 @@ psmintr(int unit)
ms->dy = y;
ms->obutton = sc->button; /* previous button state */
sc->button = ms->button = /* latest button state */
- butmap[sc->ipacket[0] & MOUSE_PS2_BUTTONS];
+ butmap[sc->ipacket[0] & MOUSE_PS2_BUTTONS]
+ | ((sc->ipacket[0] & MOUSE_PS2_BUTTON4UP)
+ ? 0 : MOUSE_BUTTON4DOWN);
+#if 0
+ if ((verbose >= 2)
+ && ((sc->ipacket[0] & MOUSE_PS2_BUTTON4UP) == 0))
+ log(LOG_DEBUG, "psm%d: button 4 down (%04x) (psmintr)\n",
+ unit, sc->ipacket[0]);
+#endif
sc->queue.tail =
(sc->queue.tail + 1) % PSM_BUFSIZE;
++sc->queue.count;
diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c
index 8b9fff1..691460a 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.188 1996/11/15 08:45:24 sos Exp $
+ * $Id: syscons.c,v 1.189 1996/11/19 17:08:10 nate Exp $
*/
#include "sc.h"
@@ -298,31 +298,47 @@ scprobe(struct isa_device *dev)
sc_port = dev->id_iobase;
+ /* discard anything left after UserConfig */
+ empty_both_buffers(sc_port, 10);
+
/* save the current keyboard controller command byte */
- write_controller_command(sc_port, KBDC_GET_COMMAND_BYTE);
+ c = -1;
+ if (!write_controller_command(sc_port, KBDC_GET_COMMAND_BYTE)) {
+ /* CONTROLLER ERROR */
+ printf("sc%d: unable to get the current command byte value.\n",
+ dev->id_unit);
+ goto fail;
+ }
c = read_controller_data(sc_port);
if (c == -1) {
+ /* CONTROLLER ERROR */
printf("sc%d: unable to get the current command byte value.\n",
dev->id_unit);
goto fail;
}
+#if 0
+ /* override the keyboard lock switch */
+ c |= KBD_OVERRIDE_KBD_LOCK;
+#endif
/*
* 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);
+ if (!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)) {
+ /* CONTROLLER ERROR
+ * there is very little we can do...
+ */
+ printf("sc%d: unable to set the command byte.\n", dev->id_unit);
+ goto fail;
+ }
/* reset keyboard hardware */
if (!reset_kbd(sc_port)) {
- /*
+ /* KEYBOARD ERROR
* 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
@@ -331,15 +347,17 @@ scprobe(struct isa_device *dev)
* test_controller() and test_kbd_port() appear to bring the keyboard
* controller back (I don't know why and how, though.)
*/
+ empty_both_buffers(sc_port, 10);
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.
+ * the keyboard may still exist (see above).
*/
- set_controller_command_byte(sc_port, c, 0);
+ if (bootverbose)
+ printf("sc%d: failed to reset the keyboard.\n", dev->id_unit);
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
@@ -347,19 +365,36 @@ scprobe(struct isa_device *dev)
*/
if (dev->id_flags & XT_KEYBD) {
if (send_kbd_command_and_data(
- sc_port, KBDC_SET_SCAN_CODESET, 1) == KBD_ACK)
+ 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);
+ } else {
+ /* KEYBOARD ERROR
+ * The XT kbd isn't usable unless the proper scan code set
+ * is selected.
+ */
+ printf("sc%d: unable to set the XT keyboard mode.\n", dev->id_unit);
+ goto fail;
+ }
}
/* 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);
+ if (!set_controller_command_byte(sc_port, c & ~KBD_KBD_CONTROL_BITS,
+ KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
+ /* CONTROLLER ERROR
+ * This is serious; we are left with the disabled keyboard intr.
+ */
+ printf("sc%d: unable to enable the keyboard port and intr.\n",
+ dev->id_unit);
+ goto fail;
+ }
succeed:
return (IO_KBDSIZE);
fail:
+ if (c != -1)
+ /* try to restore the command byte as before, if possible */
+ set_controller_command_byte(sc_port, c, 0);
return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
}
diff --git a/sys/isa/kbdio.c b/sys/isa/kbdio.c
index f326295..797dcff 100644
--- a/sys/isa/kbdio.c
+++ b/sys/isa/kbdio.c
@@ -26,16 +26,23 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: kbdio.c,v 1.1 1996/11/14 22:19:06 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/syslog.h>
#include <machine/clock.h>
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/kbdio.h>
+#ifndef KBDIO_DEBUG
+#define KBDIO_DEBUG 0
+#endif
+
+static int verbose = KBDIO_DEBUG;
+
/*
* device I/O routines
*/
@@ -45,22 +52,7 @@ 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)) {
+ while (inb(port + KBD_STATUS_PORT) & KBDS_INPUT_BUFFER_FULL) {
DELAY(20);
if (--retry < 0)
return FALSE;
@@ -83,6 +75,7 @@ wait_for_data(int port)
if (--retry < 0)
return FALSE;
}
+ DELAY(7);
return TRUE;
}
@@ -99,6 +92,7 @@ wait_for_kbd_data(int port)
if (--retry < 0)
return FALSE;
}
+ DELAY(7);
return TRUE;
}
@@ -115,46 +109,54 @@ wait_for_aux_data(int port)
if (--retry < 0)
return FALSE;
}
+ DELAY(7);
return TRUE;
}
-void
+int
write_controller_command(int port, int c)
{
- wait_until_controller_is_really_idle(port);
+ if (!wait_while_controller_busy(port))
+ return FALSE;
outb(port + KBD_COMMAND_PORT, c);
+ return TRUE;
}
-void
+int
write_controller_data(int port, int c)
{
- wait_until_controller_is_really_idle(port);
+ if (!wait_while_controller_busy(port))
+ return FALSE;
outb(port + KBD_DATA_PORT, c);
+ return TRUE;
}
-void
+int
write_kbd_command(int port, int c)
{
- wait_until_controller_is_really_idle(port);
+ if (!wait_while_controller_busy(port))
+ return FALSE;
outb(port + KBD_DATA_PORT, c);
+ return TRUE;
}
-void
+int
write_aux_command(int port, int c)
{
- write_controller_command(port,KBDC_WRITE_TO_AUX);
- write_controller_data(port, c);
+ if (!write_controller_command(port,KBDC_WRITE_TO_AUX))
+ return FALSE;
+ return write_controller_data(port, c);
}
int
send_kbd_command(int port, int c)
{
int retry = KBD_MAXRETRY;
- int res;
+ int res = -1;
while (retry-- > 0) {
- wait_until_controller_is_really_idle(port);
- outb(port + KBD_DATA_PORT, c);
+ if (!write_kbd_command(port, c))
+ continue;
res = read_controller_data(port);
if (res == KBD_ACK)
break;
@@ -166,13 +168,11 @@ int
send_aux_command(int port, int c)
{
int retry = KBD_MAXRETRY;
- int res;
+ int res = -1;
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);
+ if (!write_aux_command(port, c))
+ continue;
res = read_aux_data(port);
if (res == PSM_ACK)
break;
@@ -184,19 +184,23 @@ int
send_kbd_command_and_data(int port, int c, int d)
{
int retry;
- int res;
+ int res = -1;
for (retry = KBD_MAXRETRY; retry > 0; --retry) {
- wait_until_controller_is_really_idle(port);
- outb(port + KBD_DATA_PORT, c);
+ if (!write_kbd_command(port, c))
+ continue;
res = read_controller_data(port);
if (res == KBD_ACK)
break;
+ else if (res != PSM_RESEND)
+ return res;
}
+ if (retry <= 0)
+ return res;
- for (retry = KBD_MAXRETRY; retry > 0; --retry) {
- wait_until_controller_is_really_idle(port);
- outb(port + KBD_DATA_PORT, d);
+ for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
+ if (!write_kbd_command(port, d))
+ continue;
res = read_controller_data(port);
if (res != KBD_RESEND)
break;
@@ -208,25 +212,23 @@ int
send_aux_command_and_data(int port, int c, int d)
{
int retry;
- int res;
+ int res = -1;
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);
+ if (!write_aux_command(port, c))
+ continue;
res = read_aux_data(port);
if (res == PSM_ACK)
break;
else if (res != PSM_RESEND)
return res;
}
+ if (retry <= 0)
+ 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);
+ for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
+ if (!write_aux_command(port, d))
+ continue;
res = read_aux_data(port);
if (res != PSM_RESEND)
break;
@@ -241,7 +243,6 @@ send_aux_command_and_data(int port, int c, int d)
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);
@@ -251,7 +252,6 @@ read_controller_data(int port)
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);
@@ -263,10 +263,10 @@ read_kbd_data(int port)
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 */
+ DELAY(7);
return inb(port + KBD_DATA_PORT);
}
@@ -274,7 +274,6 @@ read_kbd_data_no_wait(int port)
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);
@@ -282,55 +281,64 @@ read_aux_data(int port)
/* discard data from the keyboard */
void
-empty_kbd_buffer(int port)
+empty_kbd_buffer(int port, int t)
{
int b;
int c = 0;
+ int delta = 2;
- while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ for (; t > 0; t -= delta) {
+ if ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
== KBDS_KBD_BUFFER_FULL) {
+ DELAY(7);
b = inb(port + KBD_DATA_PORT);
++c;
- DELAY(20);
}
-#ifdef KBDIO_DEBUG
+ DELAY(delta*1000);
+ }
+ if ((verbose >= 2) && (c > 0))
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)
+empty_aux_buffer(int port, int t)
{
int b;
int c = 0;
+ int delta = 2;
- while ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ for (; t > 0; t -= delta) {
+ if ((inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
== KBDS_AUX_BUFFER_FULL) {
+ DELAY(7);
b = inb(port + KBD_DATA_PORT);
++c;
- DELAY(20);
}
-#ifdef KBDIO_DEBUG
+ DELAY(delta*1000);
+ }
+ if ((verbose >= 2) && (c > 0))
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)
+empty_both_buffers(int port, int t)
{
int b;
int c = 0;
+ int delta = 2;
- while (inb(port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
+ for (; t > 0; t -= delta) {
+ if (inb(port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
+ DELAY(7);
b = inb(port + KBD_DATA_PORT);
++c;
- DELAY(20);
}
-#ifdef KBDIO_DEBUG
+ DELAY(delta*1000);
+ }
+ if ((verbose >= 2) && (c > 0))
log(LOG_DEBUG,"kbdio: %d char read (empty_both_buffers)\n",c);
-#endif
}
/* keyboard and mouse device control */
@@ -343,15 +351,15 @@ reset_kbd(int port)
{
int retry = KBD_MAXRETRY;
int again = KBD_MAXWAIT;
- int c;
+ int c = KBD_RESEND; /* keep the compiler happy */
while (retry-- > 0) {
- empty_both_buffers(port);
- write_kbd_command(port, KBDC_RESET_KBD);
+ empty_both_buffers(port, 10);
+ if (!write_kbd_command(port, KBDC_RESET_KBD))
+ continue;
c = read_controller_data(port);
-#ifdef KBDIO_DEBUG
+ if (verbose)
log(LOG_DEBUG,"kbdio: RESET_KBD return code:%04x\n",c);
-#endif
if (c == KBD_ACK) /* keyboard has agreed to reset itself... */
break;
}
@@ -365,9 +373,8 @@ reset_kbd(int port)
if (c != -1) /* wait again if the controller is not ready */
break;
}
-#ifdef KBDIO_DEBUG
+ if (verbose)
log(LOG_DEBUG,"kbdio: RESET_KBD status:%04x\n",c);
-#endif
if (c != KBD_RESET_DONE)
return FALSE;
return TRUE;
@@ -381,15 +388,15 @@ reset_aux_dev(int port)
{
int retry = KBD_MAXRETRY;
int again = KBD_MAXWAIT;
- int c;
+ int c = PSM_RESEND; /* keep the compiler happy */
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
+ empty_both_buffers(port, 10);
+ if (!write_aux_command(port, PSMC_RESET_DEV))
+ continue;
+ c = read_controller_data(port);
+ if (verbose)
log(LOG_DEBUG,"kbdio: RESET_AUX return code:%04x\n",c);
-#endif
if (c == PSM_ACK) /* aux dev is about to reset... */
break;
}
@@ -403,16 +410,14 @@ reset_aux_dev(int port)
if (c != -1) /* wait again if the controller is not ready */
break;
}
-#ifdef KBDIO_DEBUG
+ if (verbose)
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
+ if (verbose)
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;
}
@@ -422,49 +427,91 @@ reset_aux_dev(int port)
int
test_controller(int port)
{
- int c;
+ int retry = KBD_MAXRETRY;
+ int again = KBD_MAXWAIT;
+ int c = KBD_DIAG_FAIL;
+
+ while (retry-- > 0) {
+ empty_both_buffers(port, 10);
+ if (write_controller_command(port, KBDC_DIAGNOSE))
+ break;
+ }
+ if (retry < 0)
+ return FALSE;
- empty_both_buffers(port);
- write_controller_command(port, KBDC_DIAGNOSE);
+ while (again-- > 0) {
+ /* wait awhile */
+ DELAY(KBD_RESETDELAY*1000);
c = read_controller_data(port); /* DIAG_DONE/DIAG_FAIL */
-#ifdef KBDIO_DEBUG
+ if (c != -1) /* wait again if the controller is not ready */
+ break;
+ }
+ if (verbose)
log(LOG_DEBUG,"kbdio: DIAGNOSE status:%04x\n",c);
-#endif
return (c == KBD_DIAG_DONE);
}
int
test_kbd_port(int port)
{
- int c;
+ int retry = KBD_MAXRETRY;
+ int again = KBD_MAXWAIT;
+ int c = -1;
- empty_both_buffers(port);
- write_controller_command(port, KBDC_TEST_KBD_PORT);
+ while (retry-- > 0) {
+ empty_both_buffers(port, 10);
+ if (write_controller_command(port, KBDC_TEST_KBD_PORT))
+ break;
+ }
+ if (retry < 0)
+ return FALSE;
+
+ while (again-- > 0) {
c = read_controller_data(port);
-#ifdef KBDIO_DEBUG
+ if (c != -1) /* try again if the controller is not ready */
+ break;
+ }
+ if (verbose)
log(LOG_DEBUG,"kbdio: TEST_KBD_PORT status:%04x\n",c);
-#endif
return c;
}
int
test_aux_port(int port)
{
- int c;
+ int retry = KBD_MAXRETRY;
+ int again = KBD_MAXWAIT;
+ int c = -1;
- empty_both_buffers(port);
- write_controller_command(port, KBDC_TEST_AUX_PORT);
+ while (retry-- > 0) {
+ empty_both_buffers(port, 10);
+ if (write_controller_command(port, KBDC_TEST_AUX_PORT))
+ break;
+ }
+ if (retry < 0)
+ return FALSE;
+
+ while (again-- > 0) {
c = read_controller_data(port);
-#ifdef KBDIO_DEBUG
+ if (c != -1) /* try again if the controller is not ready */
+ break;
+ }
+ if (verbose)
log(LOG_DEBUG,"kbdio: TEST_AUX_PORT status:%04x\n",c);
-#endif
return c;
}
-void
+int
set_controller_command_byte(int port, int command, int flag)
{
- write_controller_command(port, KBDC_SET_COMMAND_BYTE);
- write_controller_data(port, command | flag);
+ if ((command | flag) & KBD_DISABLE_KBD_PORT) {
+ if (!write_controller_command(port, KBDC_DISABLE_KBD_PORT))
+ return FALSE;
+ }
+ if (!write_controller_command(port, KBDC_SET_COMMAND_BYTE))
+ return FALSE;
+ if (!write_controller_data(port, command | flag))
+ return FALSE;
wait_while_controller_busy(port);
+ return TRUE;
}
diff --git a/sys/isa/kbdio.h b/sys/isa/kbdio.h
index c547780..5833b86 100644
--- a/sys/isa/kbdio.h
+++ b/sys/isa/kbdio.h
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: kbdio.h,v 1.1 1996/11/14 22:19:09 sos Exp $
*/
#ifndef _I386_ISA_KBDIO_H_
@@ -58,6 +58,7 @@
/* controller command byte (set by KBDC_SET_COMMAND_BYTE) */
#define KBD_TRANSLATION 0x0040
#define KBD_RESERVED_BITS 0x0004
+#define KBD_OVERRIDE_KBD_LOCK 0x0008
#define KBD_ENABLE_KBD_PORT 0x0000
#define KBD_DISABLE_KBD_PORT 0x0010
#define KBD_ENABLE_AUX_PORT 0x0000
@@ -86,10 +87,12 @@
#define PSMC_DISABLE_DEV 0x00f5
#define PSMC_SEND_DEV_ID 0x00f2
#define PSMC_SEND_DEV_STATUS 0x00e9
+#define PSMC_SEND_DEV_DATA 0x00eb
#define PSMC_SET_SCALING11 0x00e6
#define PSMC_SET_SCALING21 0x00e7
#define PSMC_SET_RESOLUTION 0x00e8
#define PSMC_SET_STREAM_MODE 0x00ea
+#define PSMC_SET_REMOTE_MODE 0x00f0
#define PSMC_SET_SAMPLING_RATE 0x00f3
/* PSMC_SET_RESOLUTION argument */
@@ -111,7 +114,7 @@
#define KBDS_ANY_BUFFER_FULL 0x0001
#define KBDS_KBD_BUFFER_FULL 0x0001
#define KBDS_AUX_BUFFER_FULL 0x0021
-#define KBDS_CONTROLLER_BUSY 0x0002
+#define KBDS_INPUT_BUFFER_FULL 0x0002
/* return code */
#define KBD_ACK 0x00fa
@@ -165,17 +168,16 @@
/* 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));
+int write_controller_command __P((int port,int c));
+int 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 write_kbd_command __P((int port,int c));
+int 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));
@@ -186,9 +188,9 @@ 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));
+void empty_kbd_buffer __P((int port, int t));
+void empty_aux_buffer __P((int port, int t));
+void empty_both_buffers __P((int port, int t));
int reset_kbd __P((int port));
int reset_aux_dev __P((int port));
@@ -197,7 +199,7 @@ 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));
+int set_controller_command_byte __P((int port,int command,int flag));
#endif /* KERNEL */
diff --git a/sys/isa/syscons.c b/sys/isa/syscons.c
index 8b9fff1..691460a 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.188 1996/11/15 08:45:24 sos Exp $
+ * $Id: syscons.c,v 1.189 1996/11/19 17:08:10 nate Exp $
*/
#include "sc.h"
@@ -298,31 +298,47 @@ scprobe(struct isa_device *dev)
sc_port = dev->id_iobase;
+ /* discard anything left after UserConfig */
+ empty_both_buffers(sc_port, 10);
+
/* save the current keyboard controller command byte */
- write_controller_command(sc_port, KBDC_GET_COMMAND_BYTE);
+ c = -1;
+ if (!write_controller_command(sc_port, KBDC_GET_COMMAND_BYTE)) {
+ /* CONTROLLER ERROR */
+ printf("sc%d: unable to get the current command byte value.\n",
+ dev->id_unit);
+ goto fail;
+ }
c = read_controller_data(sc_port);
if (c == -1) {
+ /* CONTROLLER ERROR */
printf("sc%d: unable to get the current command byte value.\n",
dev->id_unit);
goto fail;
}
+#if 0
+ /* override the keyboard lock switch */
+ c |= KBD_OVERRIDE_KBD_LOCK;
+#endif
/*
* 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);
+ if (!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)) {
+ /* CONTROLLER ERROR
+ * there is very little we can do...
+ */
+ printf("sc%d: unable to set the command byte.\n", dev->id_unit);
+ goto fail;
+ }
/* reset keyboard hardware */
if (!reset_kbd(sc_port)) {
- /*
+ /* KEYBOARD ERROR
* 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
@@ -331,15 +347,17 @@ scprobe(struct isa_device *dev)
* test_controller() and test_kbd_port() appear to bring the keyboard
* controller back (I don't know why and how, though.)
*/
+ empty_both_buffers(sc_port, 10);
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.
+ * the keyboard may still exist (see above).
*/
- set_controller_command_byte(sc_port, c, 0);
+ if (bootverbose)
+ printf("sc%d: failed to reset the keyboard.\n", dev->id_unit);
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
@@ -347,19 +365,36 @@ scprobe(struct isa_device *dev)
*/
if (dev->id_flags & XT_KEYBD) {
if (send_kbd_command_and_data(
- sc_port, KBDC_SET_SCAN_CODESET, 1) == KBD_ACK)
+ 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);
+ } else {
+ /* KEYBOARD ERROR
+ * The XT kbd isn't usable unless the proper scan code set
+ * is selected.
+ */
+ printf("sc%d: unable to set the XT keyboard mode.\n", dev->id_unit);
+ goto fail;
+ }
}
/* 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);
+ if (!set_controller_command_byte(sc_port, c & ~KBD_KBD_CONTROL_BITS,
+ KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
+ /* CONTROLLER ERROR
+ * This is serious; we are left with the disabled keyboard intr.
+ */
+ printf("sc%d: unable to enable the keyboard port and intr.\n",
+ dev->id_unit);
+ goto fail;
+ }
succeed:
return (IO_KBDSIZE);
fail:
+ if (c != -1)
+ /* try to restore the command byte as before, if possible */
+ set_controller_command_byte(sc_port, c, 0);
return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
}
diff --git a/sys/sys/mouse.h b/sys/sys/mouse.h
index 1303a31..110c503 100644
--- a/sys/sys/mouse.h
+++ b/sys/sys/mouse.h
@@ -19,7 +19,7 @@
* 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.2 1996/11/14 22:18:25 sos Exp $
+ * $Id: mouse.h,v 1.1 1994/09/09 11:27:31 dfr Exp $
*/
#ifndef _MACHINE_MOUSE_H_
@@ -29,26 +29,20 @@
#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...
+ * NOTE: MOUSEIOC, MOUSEIOCREAD, and mouseinfo 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 */
@@ -60,6 +54,32 @@ typedef struct mouseinfo {
#define BUT1CHNG 0x20 /* Button 1 changed if set */
#define MOVEMENT 0x40 /* Mouse movement detected */
+#define MOUSE_GETSTATE _IOR('M',0,mousestatus_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)
+
+/* new ioctls */
+
+/* mouse status block */
+typedef struct mousestatus {
+ int button; /* button status */
+ int obutton; /* previous button status */
+ int dx; /* x movement */
+ int dy; /* y movement */
+} mousestatus_t;
+/* button */
+#define MOUSE_BUTTON1DOWN 0x0001 /* left */
+#define MOUSE_BUTTON2DOWN 0x0002 /* middle */
+#define MOUSE_BUTTON3DOWN 0x0004 /* right */
+#define MOUSE_BUTTON4DOWN 0x0008
+#define MOUSE_BUTTON5DOWN 0x0010
+#define MOUSE_BUTTON6DOWN 0x0020
+#define MOUSE_BUTTON7DOWN 0x0040
+#define MOUSE_BUTTON8DOWN 0x0080
+#define MOUSE_STDBUTTONS 0x0007 /* buttons 1-3 */
+#define MOUSE_EXTBUTTONS 0x00f8 /* the others */
+
typedef struct mousehw {
int buttons;
int iftype; /* MOUSE_IF_XXX */
@@ -67,13 +87,11 @@ typedef struct mousehw {
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
@@ -87,7 +105,6 @@ typedef struct mousemode {
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 */
@@ -107,6 +124,9 @@ typedef struct mousemode {
#define MOUSE_MSS_BUTTON2DOWN 0x00 /* no middle button */
#define MOUSE_MSS_BUTTON3DOWN 0x10 /* right */
+/* Logitech MouseMan data packet (M+ protocol) */
+#define MOUSE_LMAN_BUTTON2DOWN 0x20 /* middle button, in the 4th byte */
+
/* Mouse Systems Corp. mouse data packet */
#define MOUSE_MSC_PACKETSIZE 5
#define MOUSE_MSC_SYNCMASK 0xf8
@@ -116,6 +136,17 @@ typedef struct mousemode {
#define MOUSE_MSC_BUTTON2UP 0x02 /* middle */
#define MOUSE_MSC_BUTTON3UP 0x01 /* right */
+/* MM series mouse data packet */
+#define MOUSE_MM_PACKETSIZE 3
+#define MOUSE_MM_SYNCMASK 0xe0
+#define MOUSE_MM_SYNC 0x80
+#define MOUSE_MM_BUTTONS 0x07
+#define MOUSE_MM_BUTTON1DOWN 0x04 /* left */
+#define MOUSE_MM_BUTTON2DOWN 0x02 /* middle */
+#define MOUSE_MM_BUTTON3DOWN 0x01 /* right */
+#define MOUSE_MM_XPOSITIVE 0x10
+#define MOUSE_MM_YPOSITIVE 0x08
+
/* PS/2 mouse data packet */
#define MOUSE_PS2_PACKETSIZE 3
#define MOUSE_PS2_SYNCMASK 0x08 /* 0x0c for 2 button mouse */
@@ -124,6 +155,9 @@ typedef struct mousemode {
#define MOUSE_PS2_BUTTON1DOWN 0x01 /* left */
#define MOUSE_PS2_BUTTON2DOWN 0x04 /* middle */
#define MOUSE_PS2_BUTTON3DOWN 0x02 /* right */
+#define MOUSE_PS2_BUTTON4UP 0x08 /* GlidePoint tapping feature
+ * Yes! this is the same bit as SYNC!
+ */
#define MOUSE_PS2_XNEG 0x10
#define MOUSE_PS2_YNEG 0x20
#define MOUSE_PS2_XOVERFLOW 0x40
OpenPOWER on IntegriCloud