mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols, stricter error checking, removing redundant code, etc. 2. The `psm' driver preserves the default counter resolution and report rate, whatever they are after reset. (Based on reports and suggestion from Nate and Rob Bolin). 3. The `psm' driver now does not check the so-called sync. bit in the first byte of the data packet by default, so that the tapping feature of ALPUS GlidePoint works (based on reports from Louis Mamakos). I tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found no problem; tapping worked. It appears ALPUS produces several models of GlidePoint. I hope the other models are OK too. The check code can still be activated by defining the PSM_CHECKSYNC option in the config file. (The bit checking slightly reduces, if not completely eliminates, weird mouse behavior cased by unsynchronized mouse data packets. It also helps us to detect if the mouse interrupt can ever be lost. But, well, if there are devices which cannot be supported this way...) 4. The `psm' driver does not include the protocol emulation code by default. The code can still be compiled in if the PSM_EMULATION option is specified in the config file. Louis Mamakos suggests the emulation code is putting too much in the kernel, and `moused' works well. I will think about this later and decide if the entire emulation code should be removed. 5. And, of course, the fix in `scprobe()' from Bruce to cure the UserConfig problem. My code in `kbdio.c' is slightly different from his patch, but has the same effect. There still is a possibility that `scprobe()' gets confused, if, for whatever reasons, the user holds down a key for very long time during the boot process. But we cannot cope with everything, can we? Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
This commit is contained in:
parent
661a46b5a1
commit
1f9d9075e4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=20073
@ -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
|
||||
|
@ -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 = read_controller_data(sc_port);
|
||||
if (c == -1) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
empty_both_buffers(port);
|
||||
write_controller_command(port, KBDC_DIAGNOSE);
|
||||
while (retry-- > 0) {
|
||||
empty_both_buffers(port, 10);
|
||||
if (write_controller_command(port, KBDC_DIAGNOSE))
|
||||
break;
|
||||
}
|
||||
if (retry < 0)
|
||||
return FALSE;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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 = read_controller_data(sc_port);
|
||||
if (c == -1) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
255
sys/isa/kbdio.c
255
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;
|
||||
|
||||
empty_both_buffers(port);
|
||||
write_controller_command(port, KBDC_DIAGNOSE);
|
||||
while (retry-- > 0) {
|
||||
empty_both_buffers(port, 10);
|
||||
if (write_controller_command(port, KBDC_DIAGNOSE))
|
||||
break;
|
||||
}
|
||||
if (retry < 0)
|
||||
return FALSE;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 = read_controller_data(sc_port);
|
||||
if (c == -1) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user