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