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