152130Smckusick /* 252130Smckusick * Copyright (c) 1992 Regents of the University of California. 352130Smckusick * All rights reserved. 452130Smckusick * 552130Smckusick * This code is derived from software contributed to Berkeley by 652130Smckusick * Ralph Campbell. 752693Sralph * @(#)dz.c 7.9 (Berkeley) 6/28/90 852693Sralph */ 952693Sralph 1052693Sralph /* 1152693Sralph * devDC7085.c -- 1252130Smckusick * 1352130Smckusick * %sccs.include.redist.c% 1452130Smckusick * 15*54146Sralph * @(#)dc.c 7.6 (Berkeley) 06/20/92 1652130Smckusick * 1752130Smckusick * devDC7085.c -- 1852130Smckusick * 1952130Smckusick * This file contains machine-dependent routines that handle the 2052130Smckusick * output queue for the serial lines. 2152130Smckusick * 2252130Smckusick * Copyright (C) 1989 Digital Equipment Corporation. 2352130Smckusick * Permission to use, copy, modify, and distribute this software and 2452130Smckusick * its documentation for any purpose and without fee is hereby granted, 2552130Smckusick * provided that the above copyright notice appears in all copies. 2652130Smckusick * Digital Equipment Corporation makes no representations about the 2752130Smckusick * suitability of this software for any purpose. It is provided "as is" 2852130Smckusick * without express or implied warranty. 2952130Smckusick * 3052130Smckusick * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devDC7085.c, 3152130Smckusick * v 1.4 89/08/29 11:55:30 nelson Exp $ SPRITE (DECWRL)"; 3252130Smckusick */ 3352130Smckusick 3452130Smckusick #include "dc.h" 3552130Smckusick #if NDC > 0 3652130Smckusick /* 3752130Smckusick * DC7085 (DZ-11 look alike) Driver 3852130Smckusick */ 3952130Smckusick #include "param.h" 4052130Smckusick #include "systm.h" 4152130Smckusick #include "ioctl.h" 4252130Smckusick #include "tty.h" 4352130Smckusick #include "proc.h" 4452130Smckusick #include "map.h" 4552130Smckusick #include "buf.h" 4652130Smckusick #include "conf.h" 4752130Smckusick #include "file.h" 4852130Smckusick #include "uio.h" 4952130Smckusick #include "kernel.h" 5052130Smckusick #include "syslog.h" 5152130Smckusick 5252130Smckusick #include "machine/dc7085cons.h" 5352130Smckusick 5452130Smckusick #include "device.h" 5552130Smckusick #include "pdma.h" 5652130Smckusick 5752130Smckusick /* 5852130Smckusick * Driver information for auto-configuration stuff. 5952130Smckusick */ 6052130Smckusick int dcprobe(); 6152693Sralph void dcintr(); 6252130Smckusick struct driver dcdriver = { 6352693Sralph "dc", dcprobe, 0, 0, dcintr, 6452130Smckusick }; 6552130Smckusick 6652130Smckusick #define NDCLINE (NDC*4) 6752130Smckusick 68*54146Sralph extern void dcstart __P((struct tty *)); 69*54146Sralph extern void dcxint __P((struct tty *)); 70*54146Sralph extern void ttrstrt __P((struct tty *)); 7152130Smckusick 7252130Smckusick struct tty dc_tty[NDCLINE]; 7352130Smckusick int dc_cnt = NDCLINE; 7452863Sralph void (*dcDivertXInput)(); /* X windows keyboard input routine */ 7552863Sralph void (*dcMouseEvent)(); /* X windows mouse motion event routine */ 7652863Sralph void (*dcMouseButtons)(); /* X windows mouse buttons event routine */ 7752130Smckusick #ifdef DEBUG 7852130Smckusick int debugChar; 7952130Smckusick #endif 8052130Smckusick 81*54146Sralph static void dcscan __P((void)); 82*54146Sralph static int dcMapChar __P((int)); 83*54146Sralph static void dcKBDReset __P((void)); 84*54146Sralph static void MouseInit __P((void)); 85*54146Sralph 8652130Smckusick /* 8752130Smckusick * Software copy of brk register since it isn't readable 8852130Smckusick */ 8952130Smckusick int dc_brk[NDC]; 9052130Smckusick char dcsoftCAR[NDC]; /* mask of dc's with carrier on (DSR) */ 9152130Smckusick 9252130Smckusick /* 9352130Smckusick * The DC7085 doesn't interrupt on carrier transitions, so 9452130Smckusick * we have to use a timer to watch it. 9552130Smckusick */ 9652130Smckusick int dc_timer; /* true if timer started */ 9752130Smckusick 9852130Smckusick /* 9952130Smckusick * Pdma structures for fast output code 10052130Smckusick */ 10152130Smckusick struct pdma dcpdma[NDCLINE]; 10252130Smckusick 10352130Smckusick struct speedtab dcspeedtab[] = { 10452130Smckusick 0, 0, 10552130Smckusick 50, LPR_B50, 10652130Smckusick 75, LPR_B75, 10752130Smckusick 110, LPR_B110, 10852130Smckusick 134, LPR_B134, 10952130Smckusick 150, LPR_B150, 11052130Smckusick 300, LPR_B300, 11152130Smckusick 600, LPR_B600, 11252130Smckusick 1200, LPR_B1200, 11352130Smckusick 1800, LPR_B1800, 11452130Smckusick 2400, LPR_B2400, 11552130Smckusick 4800, LPR_B4800, 11652130Smckusick 9600, LPR_B9600, 11752693Sralph #ifdef DS5000 11852693Sralph 19200, LPR_B19200, 11952693Sralph #endif 12052130Smckusick -1, -1 12152130Smckusick }; 12252130Smckusick 12352130Smckusick #ifndef PORTSELECTOR 12452130Smckusick #define ISPEED TTYDEF_SPEED 12552130Smckusick #define LFLAG TTYDEF_LFLAG 12652130Smckusick #else 12752130Smckusick #define ISPEED B4800 12852130Smckusick #define LFLAG (TTYDEF_LFLAG & ~ECHO) 12952130Smckusick #endif 13052130Smckusick 13152130Smckusick /* 13252130Smckusick * Ascii values of command keys. 13352130Smckusick */ 13452130Smckusick #define KBD_TAB '\t' 13552130Smckusick #define KBD_DEL 127 13652130Smckusick #define KBD_RET '\r' 13752130Smckusick 13852130Smckusick /* 13952130Smckusick * Define "hardware-independent" codes for the control, shift, meta and 14052130Smckusick * function keys. Codes start after the last 7-bit ASCII code (127) 14152130Smckusick * and are assigned in an arbitrary order. 14252130Smckusick */ 14352130Smckusick #define KBD_NOKEY 128 14452130Smckusick 14552130Smckusick #define KBD_F1 201 14652130Smckusick #define KBD_F2 202 14752130Smckusick #define KBD_F3 203 14852130Smckusick #define KBD_F4 204 14952130Smckusick #define KBD_F5 205 15052130Smckusick #define KBD_F6 206 15152130Smckusick #define KBD_F7 207 15252130Smckusick #define KBD_F8 208 15352130Smckusick #define KBD_F9 209 15452130Smckusick #define KBD_F10 210 15552130Smckusick #define KBD_F11 211 15652130Smckusick #define KBD_F12 212 15752130Smckusick #define KBD_F13 213 15852130Smckusick #define KBD_F14 214 15952130Smckusick #define KBD_HELP 215 16052130Smckusick #define KBD_DO 216 16152130Smckusick #define KBD_F17 217 16252130Smckusick #define KBD_F18 218 16352130Smckusick #define KBD_F19 219 16452130Smckusick #define KBD_F20 220 16552130Smckusick 16652130Smckusick #define KBD_FIND 221 16752130Smckusick #define KBD_INSERT 222 16852130Smckusick #define KBD_REMOVE 223 16952130Smckusick #define KBD_SELECT 224 17052130Smckusick #define KBD_PREVIOUS 225 17152130Smckusick #define KBD_NEXT 226 17252130Smckusick 17352130Smckusick #define KBD_KP_ENTER 227 17452130Smckusick #define KBD_KP_F1 228 17552130Smckusick #define KBD_KP_F2 229 17652130Smckusick #define KBD_KP_F3 230 17752130Smckusick #define KBD_KP_F4 231 17852130Smckusick #define KBD_LEFT 232 17952130Smckusick #define KBD_RIGHT 233 18052130Smckusick #define KBD_DOWN 234 18152130Smckusick #define KBD_UP 235 18252130Smckusick 18352130Smckusick #define KBD_CONTROL 236 18452130Smckusick #define KBD_SHIFT 237 18552130Smckusick #define KBD_CAPSLOCK 238 18652130Smckusick #define KBD_ALTERNATE 239 18752130Smckusick 18852130Smckusick /* 18952130Smckusick * Keyboard to Ascii, unshifted. 19052130Smckusick */ 19152130Smckusick static unsigned char unshiftedAscii[] = { 19252130Smckusick /* 0 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19352130Smckusick /* 4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19452130Smckusick /* 8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19552130Smckusick /* c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19652130Smckusick /* 10 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19752130Smckusick /* 14 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19852130Smckusick /* 18 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19952130Smckusick /* 1c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20052130Smckusick /* 20 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20152130Smckusick /* 24 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20252130Smckusick /* 28 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20352130Smckusick /* 2c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20452130Smckusick /* 30 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20552130Smckusick /* 34 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20652130Smckusick /* 38 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20752130Smckusick /* 3c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20852130Smckusick /* 40 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20952130Smckusick /* 44 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21052130Smckusick /* 48 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21152130Smckusick /* 4c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21252130Smckusick /* 50 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21352130Smckusick /* 54 */ KBD_NOKEY, KBD_NOKEY, KBD_F1, KBD_F2, 21452130Smckusick /* 58 */ KBD_F3, KBD_F4, KBD_F5, KBD_NOKEY, 21552130Smckusick /* 5c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21652130Smckusick /* 60 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21752130Smckusick /* 64 */ KBD_F6, KBD_F7, KBD_F8, KBD_F9, 21852130Smckusick /* 68 */ KBD_F10, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21952130Smckusick /* 6c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 22052130Smckusick /* 70 */ KBD_NOKEY, '\033', KBD_F12, KBD_F13, 22152130Smckusick /* 74 */ KBD_F14, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 22252130Smckusick /* 78 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 22352130Smckusick /* 7c */ KBD_HELP, KBD_DO, KBD_NOKEY, KBD_NOKEY, 22452130Smckusick /* 80 */ KBD_F17, KBD_F18, KBD_F19, KBD_F20, 22552130Smckusick /* 84 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 22652130Smckusick /* 88 */ KBD_NOKEY, KBD_NOKEY, KBD_FIND, KBD_INSERT, 22752130Smckusick /* 8c */ KBD_REMOVE, KBD_SELECT, KBD_PREVIOUS, KBD_NEXT, 22852130Smckusick /* 90 */ KBD_NOKEY, KBD_NOKEY, '0', KBD_NOKEY, 22952130Smckusick /* 94 */ '.', KBD_KP_ENTER, '1', '2', 23052130Smckusick /* 98 */ '3', '4', '5', '6', 23152130Smckusick /* 9c */ ',', '7', '8', '9', 23252130Smckusick /* a0 */ '-', KBD_KP_F1, KBD_KP_F2, KBD_KP_F3, 23352130Smckusick /* a4 */ KBD_KP_F4, KBD_NOKEY, KBD_NOKEY, KBD_LEFT, 23452130Smckusick /* a8 */ KBD_RIGHT, KBD_DOWN, KBD_UP, KBD_NOKEY, 23552130Smckusick /* ac */ KBD_NOKEY, KBD_NOKEY, KBD_SHIFT, KBD_CONTROL, 23652130Smckusick /* b0 */ KBD_CAPSLOCK, KBD_ALTERNATE, KBD_NOKEY, KBD_NOKEY, 23752130Smckusick /* b4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 23852130Smckusick /* b8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 23952130Smckusick /* bc */ KBD_DEL, KBD_RET, KBD_TAB, '`', 24052130Smckusick /* c0 */ '1', 'q', 'a', 'z', 24152130Smckusick /* c4 */ KBD_NOKEY, '2', 'w', 's', 24252130Smckusick /* c8 */ 'x', '<', KBD_NOKEY, '3', 24352130Smckusick /* cc */ 'e', 'd', 'c', KBD_NOKEY, 24452130Smckusick /* d0 */ '4', 'r', 'f', 'v', 24552130Smckusick /* d4 */ ' ', KBD_NOKEY, '5', 't', 24652130Smckusick /* d8 */ 'g', 'b', KBD_NOKEY, '6', 24752130Smckusick /* dc */ 'y', 'h', 'n', KBD_NOKEY, 24852130Smckusick /* e0 */ '7', 'u', 'j', 'm', 24952130Smckusick /* e4 */ KBD_NOKEY, '8', 'i', 'k', 25052130Smckusick /* e8 */ ',', KBD_NOKEY, '9', 'o', 25152130Smckusick /* ec */ 'l', '.', KBD_NOKEY, '0', 25252130Smckusick /* f0 */ 'p', KBD_NOKEY, ';', '/', 25352130Smckusick /* f4 */ KBD_NOKEY, '=', ']', '\\', 25452130Smckusick /* f8 */ KBD_NOKEY, '-', '[', '\'', 25552130Smckusick /* fc */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 25652130Smckusick }; 25752130Smckusick 25852130Smckusick /* 25952130Smckusick * Keyboard to Ascii, shifted. 26052130Smckusick */ 26152130Smckusick static unsigned char shiftedAscii[] = { 26252130Smckusick /* 0 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26352130Smckusick /* 4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26452130Smckusick /* 8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26552130Smckusick /* c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26652130Smckusick /* 10 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26752130Smckusick /* 14 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26852130Smckusick /* 18 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26952130Smckusick /* 1c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27052130Smckusick /* 20 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27152130Smckusick /* 24 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27252130Smckusick /* 28 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27352130Smckusick /* 2c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27452130Smckusick /* 30 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27552130Smckusick /* 34 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27652130Smckusick /* 38 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27752130Smckusick /* 3c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27852130Smckusick /* 40 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27952130Smckusick /* 44 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28052130Smckusick /* 48 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28152130Smckusick /* 4c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28252130Smckusick /* 50 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28352130Smckusick /* 54 */ KBD_NOKEY, KBD_NOKEY, KBD_F1, KBD_F2, 28452130Smckusick /* 58 */ KBD_F3, KBD_F4, KBD_F5, KBD_NOKEY, 28552130Smckusick /* 5c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28652130Smckusick /* 60 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28752130Smckusick /* 64 */ KBD_F6, KBD_F7, KBD_F8, KBD_F9, 28852130Smckusick /* 68 */ KBD_F10, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28952130Smckusick /* 6c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 29052130Smckusick /* 70 */ KBD_NOKEY, KBD_F11, KBD_F12, KBD_F13, 29152130Smckusick /* 74 */ KBD_F14, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 29252130Smckusick /* 78 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 29352130Smckusick /* 7c */ KBD_HELP, KBD_DO, KBD_NOKEY, KBD_NOKEY, 29452130Smckusick /* 80 */ KBD_F17, KBD_F18, KBD_F19, KBD_F20, 29552130Smckusick /* 84 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 29652130Smckusick /* 88 */ KBD_NOKEY, KBD_NOKEY, KBD_FIND, KBD_INSERT, 29752130Smckusick /* 8c */ KBD_REMOVE, KBD_SELECT, KBD_PREVIOUS, KBD_NEXT, 29852130Smckusick /* 90 */ KBD_NOKEY, KBD_NOKEY, '0', KBD_NOKEY, 29952130Smckusick /* 94 */ '.', KBD_KP_ENTER, '1', '2', 30052130Smckusick /* 98 */ '3', '4', '5', '6', 30152130Smckusick /* 9c */ ',', '7', '8', '9', 30252130Smckusick /* a0 */ '-', KBD_KP_F1, KBD_KP_F2, KBD_KP_F3, 30352130Smckusick /* a4 */ KBD_KP_F4, KBD_NOKEY, KBD_NOKEY, KBD_LEFT, 30452130Smckusick /* a8 */ KBD_RIGHT, KBD_DOWN, KBD_UP, KBD_NOKEY, 30552130Smckusick /* ac */ KBD_NOKEY, KBD_NOKEY, KBD_SHIFT, KBD_CONTROL, 30652130Smckusick /* b0 */ KBD_CAPSLOCK, KBD_ALTERNATE, KBD_NOKEY, KBD_NOKEY, 30752130Smckusick /* b4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 30852130Smckusick /* b8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 30952130Smckusick /* bc */ KBD_DEL, KBD_RET, KBD_TAB, '~', 31052130Smckusick /* c0 */ '!', 'q', 'a', 'z', 31152130Smckusick /* c4 */ KBD_NOKEY, '@', 'w', 's', 31252130Smckusick /* c8 */ 'x', '>', KBD_NOKEY, '#', 31352130Smckusick /* cc */ 'e', 'd', 'c', KBD_NOKEY, 31452130Smckusick /* d0 */ '$', 'r', 'f', 'v', 31552130Smckusick /* d4 */ ' ', KBD_NOKEY, '%', 't', 31652130Smckusick /* d8 */ 'g', 'b', KBD_NOKEY, '^', 31752130Smckusick /* dc */ 'y', 'h', 'n', KBD_NOKEY, 31852130Smckusick /* e0 */ '&', 'u', 'j', 'm', 31952130Smckusick /* e4 */ KBD_NOKEY, '*', 'i', 'k', 32052130Smckusick /* e8 */ '<', KBD_NOKEY, '(', 'o', 32152130Smckusick /* ec */ 'l', '>', KBD_NOKEY, ')', 32252130Smckusick /* f0 */ 'p', KBD_NOKEY, ':', '?', 32352130Smckusick /* f4 */ KBD_NOKEY, '+', '}', '|', 32452130Smckusick /* f8 */ KBD_NOKEY, '_', '{', '"', 32552130Smckusick /* fc */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 32652130Smckusick }; 32752130Smckusick 32852130Smckusick /* 32952130Smckusick * Keyboard initialization string. 33052130Smckusick */ 33152130Smckusick static u_char kbdInitString[] = { 33252130Smckusick LK_LED_ENABLE, LED_ALL, /* show we are resetting keyboard */ 33352130Smckusick LK_DEFAULTS, 33452130Smckusick LK_CMD_MODE(LK_AUTODOWN, 1), 33552130Smckusick LK_CMD_MODE(LK_AUTODOWN, 2), 33652130Smckusick LK_CMD_MODE(LK_AUTODOWN, 3), 33752130Smckusick LK_CMD_MODE(LK_DOWN, 4), /* could also be LK_AUTODOWN */ 33852130Smckusick LK_CMD_MODE(LK_UPDOWN, 5), 33952130Smckusick LK_CMD_MODE(LK_UPDOWN, 6), 34052130Smckusick LK_CMD_MODE(LK_AUTODOWN, 7), 34152130Smckusick LK_CMD_MODE(LK_AUTODOWN, 8), 34252130Smckusick LK_CMD_MODE(LK_AUTODOWN, 9), 34352130Smckusick LK_CMD_MODE(LK_AUTODOWN, 10), 34452130Smckusick LK_CMD_MODE(LK_AUTODOWN, 11), 34552130Smckusick LK_CMD_MODE(LK_AUTODOWN, 12), 34652130Smckusick LK_CMD_MODE(LK_DOWN, 13), 34752130Smckusick LK_CMD_MODE(LK_AUTODOWN, 14), 34852130Smckusick LK_AR_ENABLE, /* we want autorepeat by default */ 34952130Smckusick LK_CL_ENABLE, 0x83, /* keyclick, volume */ 35052130Smckusick LK_KBD_ENABLE, /* the keyboard itself */ 35152130Smckusick LK_BELL_ENABLE, 0x83, /* keyboard bell, volume */ 35252130Smckusick LK_LED_DISABLE, LED_ALL, /* clear keyboard leds */ 35352130Smckusick }; 35452130Smckusick 35552130Smckusick /* 35652130Smckusick * Test to see if device is present. 35752130Smckusick * Return true if found and initialized ok. 35852130Smckusick */ 35952130Smckusick dcprobe(cp) 36052130Smckusick register struct pmax_ctlr *cp; 36152130Smckusick { 36252130Smckusick register dcregs *dcaddr; 36352130Smckusick register struct pdma *pdp; 36452130Smckusick register struct tty *tp; 36552130Smckusick register int cntr; 36652130Smckusick 36752130Smckusick if (cp->pmax_unit >= NDC) 36852130Smckusick return (0); 36952130Smckusick if (badaddr(cp->pmax_addr, 2)) 37052130Smckusick return (0); 37152130Smckusick 37252130Smckusick /* reset chip */ 37352130Smckusick dcaddr = (dcregs *)cp->pmax_addr; 37452130Smckusick dcaddr->dc_csr = CSR_CLR; 37552130Smckusick MachEmptyWriteBuffer(); 37652130Smckusick while (dcaddr->dc_csr & CSR_CLR) 37752130Smckusick ; 37852130Smckusick dcaddr->dc_csr = CSR_MSE | CSR_TIE | CSR_RIE; 37952130Smckusick 38052130Smckusick /* init pseudo DMA structures */ 38152130Smckusick pdp = &dcpdma[cp->pmax_unit * 4]; 38252130Smckusick tp = &dc_tty[cp->pmax_unit * 4]; 38352130Smckusick for (cntr = 0; cntr < 4; cntr++) { 38452130Smckusick pdp->p_addr = dcaddr; 38552130Smckusick pdp->p_arg = (int)tp; 38652130Smckusick pdp->p_fcn = dcxint; 38752130Smckusick tp->t_addr = (caddr_t)pdp; 38852130Smckusick pdp++, tp++; 38952130Smckusick } 39052130Smckusick dcsoftCAR[cp->pmax_unit] = cp->pmax_flags | 0xB; 39152130Smckusick 39252130Smckusick if (dc_timer == 0) { 39352130Smckusick dc_timer = 1; 39452130Smckusick timeout(dcscan, (caddr_t)0, hz); 39552130Smckusick } 39652693Sralph printf("dc%d at nexus0 csr 0x%x priority %d\n", 39752693Sralph cp->pmax_unit, cp->pmax_addr, cp->pmax_pri); 39852130Smckusick if (cp->pmax_unit == 0) { 39952130Smckusick int s; 40052130Smckusick 40152130Smckusick s = spltty(); 40252130Smckusick dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_8_BIT_CHAR | 40352130Smckusick KBD_PORT; 40452130Smckusick dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR | 40552130Smckusick LPR_PARENB | LPR_8_BIT_CHAR | MOUSE_PORT; 40652130Smckusick MachEmptyWriteBuffer(); 40752130Smckusick dcKBDReset(); 40852130Smckusick MouseInit(); 40952130Smckusick splx(s); 41052130Smckusick } 41152130Smckusick return (1); 41252130Smckusick } 41352130Smckusick 414*54146Sralph dcopen(dev, flag, mode, p) 41552130Smckusick dev_t dev; 416*54146Sralph int flag, mode; 417*54146Sralph struct proc *p; 41852130Smckusick { 41952130Smckusick register struct tty *tp; 42052130Smckusick register int unit; 42152130Smckusick int s, error = 0; 42252130Smckusick extern int dcparam(); 42352130Smckusick 42452130Smckusick unit = minor(dev); 42552130Smckusick if (unit >= dc_cnt || dcpdma[unit].p_addr == 0) 42652130Smckusick return (ENXIO); 42752130Smckusick tp = &dc_tty[unit]; 42852130Smckusick tp->t_addr = (caddr_t)&dcpdma[unit]; 42952130Smckusick tp->t_oproc = dcstart; 43052130Smckusick tp->t_param = dcparam; 43152130Smckusick tp->t_dev = dev; 43252130Smckusick if ((tp->t_state & TS_ISOPEN) == 0) { 43352130Smckusick tp->t_state |= TS_WOPEN; 43452130Smckusick ttychars(tp); 43552130Smckusick #ifndef PORTSELECTOR 43652130Smckusick if (tp->t_ispeed == 0) { 43752130Smckusick #endif 43852130Smckusick tp->t_iflag = TTYDEF_IFLAG; 43952130Smckusick tp->t_oflag = TTYDEF_OFLAG; 44052130Smckusick tp->t_cflag = TTYDEF_CFLAG; 44152130Smckusick tp->t_lflag = LFLAG; 44252130Smckusick tp->t_ispeed = tp->t_ospeed = ISPEED; 44352130Smckusick #ifdef PORTSELECTOR 44452130Smckusick tp->t_cflag |= HUPCL; 44552130Smckusick #else 44652130Smckusick } 44752130Smckusick #endif 44852130Smckusick (void) dcparam(tp, &tp->t_termios); 44952130Smckusick ttsetwater(tp); 45052130Smckusick } else if ((tp->t_state & TS_XCLUDE) && curproc->p_ucred->cr_uid != 0) 45152130Smckusick return (EBUSY); 45252130Smckusick (void) dcmctl(dev, DML_DTR, DMSET); 45352130Smckusick s = spltty(); 45452130Smckusick while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) && 45552130Smckusick !(tp->t_state & TS_CARR_ON)) { 45652130Smckusick tp->t_state |= TS_WOPEN; 45752130Smckusick if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 45852130Smckusick ttopen, 0)) 45952130Smckusick break; 46052130Smckusick } 46152130Smckusick splx(s); 46252130Smckusick if (error) 46352130Smckusick return (error); 46452130Smckusick return ((*linesw[tp->t_line].l_open)(dev, tp)); 46552130Smckusick } 46652130Smckusick 46752130Smckusick /*ARGSUSED*/ 468*54146Sralph dcclose(dev, flag, mode, p) 46952130Smckusick dev_t dev; 470*54146Sralph int flag, mode; 471*54146Sralph struct proc *p; 47252130Smckusick { 47352130Smckusick register struct tty *tp; 47452130Smckusick register int unit, bit; 47552130Smckusick 47652130Smckusick unit = minor(dev); 47752130Smckusick tp = &dc_tty[unit]; 47852130Smckusick bit = 1 << ((unit & 03) + 8); 47952130Smckusick if (dc_brk[unit >> 2] & bit) { 48052130Smckusick dc_brk[unit >> 2] &= ~bit; 48152130Smckusick ttyoutput(0, tp); 48252130Smckusick } 483*54146Sralph (*linesw[tp->t_line].l_close)(tp, flag); 48452130Smckusick if ((tp->t_cflag & HUPCL) || (tp->t_state & TS_WOPEN) || 48552130Smckusick !(tp->t_state & TS_ISOPEN)) 48652130Smckusick (void) dcmctl(dev, 0, DMSET); 48752130Smckusick return (ttyclose(tp)); 48852130Smckusick } 48952130Smckusick 49052130Smckusick dcread(dev, uio, flag) 49152130Smckusick dev_t dev; 49252130Smckusick struct uio *uio; 49352130Smckusick { 49452130Smckusick register struct tty *tp; 49552130Smckusick 49652130Smckusick tp = &dc_tty[minor(dev)]; 49752130Smckusick return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 49852130Smckusick } 49952130Smckusick 50052130Smckusick dcwrite(dev, uio, flag) 50152130Smckusick dev_t dev; 50252130Smckusick struct uio *uio; 50352130Smckusick { 50452130Smckusick register struct tty *tp; 50552130Smckusick 50652130Smckusick tp = &dc_tty[minor(dev)]; 50752130Smckusick return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 50852130Smckusick } 50952130Smckusick 51052130Smckusick /*ARGSUSED*/ 511*54146Sralph dcioctl(dev, cmd, data, flag, p) 51252130Smckusick dev_t dev; 51352130Smckusick caddr_t data; 514*54146Sralph int flag; 515*54146Sralph struct proc *p; 51652130Smckusick { 51752130Smckusick register struct tty *tp; 51852130Smckusick register int unit = minor(dev); 51952130Smckusick register int dc = unit >> 2; 52052130Smckusick int error; 52152130Smckusick 52252130Smckusick tp = &dc_tty[unit]; 523*54146Sralph error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 52452130Smckusick if (error >= 0) 52552130Smckusick return (error); 52652130Smckusick error = ttioctl(tp, cmd, data, flag); 52752130Smckusick if (error >= 0) 52852130Smckusick return (error); 52952130Smckusick 53052130Smckusick switch (cmd) { 53152130Smckusick 53252130Smckusick case TIOCSBRK: 53352130Smckusick dc_brk[dc] |= 1 << ((unit & 03) + 8); 53452130Smckusick ttyoutput(0, tp); 53552130Smckusick break; 53652130Smckusick 53752130Smckusick case TIOCCBRK: 53852130Smckusick dc_brk[dc] &= ~(1 << ((unit & 03) + 8)); 53952130Smckusick ttyoutput(0, tp); 54052130Smckusick break; 54152130Smckusick 54252130Smckusick case TIOCSDTR: 54352130Smckusick (void) dcmctl(dev, DML_DTR|DML_RTS, DMBIS); 54452130Smckusick break; 54552130Smckusick 54652130Smckusick case TIOCCDTR: 54752130Smckusick (void) dcmctl(dev, DML_DTR|DML_RTS, DMBIC); 54852130Smckusick break; 54952130Smckusick 55052130Smckusick case TIOCMSET: 55152130Smckusick (void) dcmctl(dev, *(int *)data, DMSET); 55252130Smckusick break; 55352130Smckusick 55452130Smckusick case TIOCMBIS: 55552130Smckusick (void) dcmctl(dev, *(int *)data, DMBIS); 55652130Smckusick break; 55752130Smckusick 55852130Smckusick case TIOCMBIC: 55952130Smckusick (void) dcmctl(dev, *(int *)data, DMBIC); 56052130Smckusick break; 56152130Smckusick 56252130Smckusick case TIOCMGET: 56352130Smckusick *(int *)data = dcmctl(dev, 0, DMGET); 56452130Smckusick break; 56552130Smckusick 56652130Smckusick default: 56752130Smckusick return (ENOTTY); 56852130Smckusick } 56952130Smckusick return (0); 57052130Smckusick } 57152130Smckusick 57252130Smckusick dcparam(tp, t) 57352130Smckusick register struct tty *tp; 57452130Smckusick register struct termios *t; 57552130Smckusick { 57652130Smckusick register dcregs *dcaddr; 57752130Smckusick register int lpr; 57852130Smckusick register int cflag = t->c_cflag; 57952130Smckusick int unit = minor(tp->t_dev); 58052130Smckusick int ospeed = ttspeedtab(t->c_ospeed, dcspeedtab); 58152130Smckusick 58252130Smckusick /* check requested parameters */ 58352130Smckusick if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) || 58452130Smckusick (cflag & CSIZE) == CS5 || (cflag & CSIZE) == CS6) 58552130Smckusick return (EINVAL); 58652130Smckusick /* and copy to tty */ 58752130Smckusick tp->t_ispeed = t->c_ispeed; 58852130Smckusick tp->t_ospeed = t->c_ospeed; 58952130Smckusick tp->t_cflag = cflag; 59052130Smckusick 59152130Smckusick dcaddr = dcpdma[unit].p_addr; 59252130Smckusick if (tp == dc_tty + KBD_PORT) { 59352130Smckusick /* handle the keyboard specially */ 59452130Smckusick dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_8_BIT_CHAR | 59552130Smckusick KBD_PORT; 59652130Smckusick MachEmptyWriteBuffer(); 59752130Smckusick return (0); 59852130Smckusick } 59952130Smckusick if (tp == dc_tty + MOUSE_PORT) { 60052130Smckusick /* handle the mouse specially */ 60152130Smckusick dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR | 60252130Smckusick LPR_PARENB | LPR_8_BIT_CHAR | MOUSE_PORT; 60352130Smckusick MachEmptyWriteBuffer(); 60452130Smckusick return (0); 60552130Smckusick } 60652130Smckusick if (ospeed == 0) { 60752130Smckusick (void) dcmctl(unit, 0, DMSET); /* hang up line */ 60852130Smckusick return (0); 60952130Smckusick } 61052130Smckusick lpr = LPR_RXENAB | ospeed | (unit & 03); 61152130Smckusick if ((cflag & CSIZE) == CS7) 61252130Smckusick lpr |= LPR_7_BIT_CHAR; 61352130Smckusick else 61452130Smckusick lpr |= LPR_8_BIT_CHAR; 61552130Smckusick if (cflag & PARENB) 61652130Smckusick lpr |= LPR_PARENB; 61752130Smckusick if (cflag & PARODD) 61852130Smckusick lpr |= LPR_OPAR; 61952130Smckusick if (cflag & CSTOPB) 62052130Smckusick lpr |= LPR_2_STOP; 62152130Smckusick dcaddr->dc_lpr = lpr; 62252130Smckusick MachEmptyWriteBuffer(); 62352130Smckusick return (0); 62452130Smckusick } 62552130Smckusick 62652693Sralph /* 62752693Sralph * Check for interrupts from all devices. 62852693Sralph */ 62952693Sralph void 63052693Sralph dcintr(unit) 63152693Sralph register int unit; 63252693Sralph { 63352693Sralph register dcregs *dcaddr; 63452693Sralph register unsigned csr; 63552693Sralph 63652693Sralph unit <<= 2; 63752693Sralph dcaddr = dcpdma[unit].p_addr; 63852693Sralph while ((csr = dcaddr->dc_csr) & (CSR_RDONE | CSR_TRDY)) { 63952693Sralph if (csr & CSR_RDONE) 64052693Sralph dcrint(unit); 64152693Sralph if (csr & CSR_TRDY) 64252693Sralph dcxint(&dc_tty[unit + ((csr >> 8) & 03)]); 64352693Sralph } 64452693Sralph } 64552693Sralph 64652693Sralph dcrint(unit) 64752693Sralph register int unit; 64852693Sralph { 64952693Sralph register dcregs *dcaddr; 65052693Sralph register struct tty *tp; 65152693Sralph register int c, cc; 65252693Sralph register struct tty *tp0; 65352693Sralph int overrun = 0; 65452693Sralph 65552693Sralph dcaddr = dcpdma[unit].p_addr; 65652693Sralph tp0 = &dc_tty[unit]; 65752693Sralph while ((c = dcaddr->dc_rbuf) < 0) { /* char present */ 65852693Sralph cc = c & 0xff; 65952693Sralph tp = tp0 + ((c >> 8) & 03); 66052693Sralph if ((c & RBUF_OERR) && overrun == 0) { 66152693Sralph log(LOG_WARNING, "dc%d,%d: silo overflow\n", unit >> 2, 66252693Sralph (c >> 8) & 03); 66352693Sralph overrun = 1; 66452693Sralph } 66552693Sralph /* the keyboard requires special translation */ 66652693Sralph if (tp == &dc_tty[KBD_PORT]) { 66752693Sralph #ifdef KADB 66852693Sralph if (cc == LK_DO) { 66952693Sralph spl0(); 67052693Sralph kdbpanic(); 67152693Sralph return; 67252693Sralph } 67352693Sralph #endif 67452693Sralph #ifdef DEBUG 67552693Sralph debugChar = cc; 67652693Sralph #endif 67752693Sralph if (dcDivertXInput) { 67852863Sralph (*dcDivertXInput)(cc); 67952693Sralph return; 68052693Sralph } 68152693Sralph if ((cc = dcMapChar(cc)) < 0) 68252693Sralph return; 68352863Sralph } else if (tp == &dc_tty[MOUSE_PORT] && dcMouseButtons) { 68452863Sralph register MouseReport *mrp; 68552693Sralph static MouseReport currentRep; 68652693Sralph 68752863Sralph mrp = ¤tRep; 68852863Sralph mrp->byteCount++; 68952693Sralph if (cc & MOUSE_START_FRAME) { 69052693Sralph /* 69152693Sralph * The first mouse report byte (button state). 69252693Sralph */ 69352863Sralph mrp->state = cc; 69452863Sralph if (mrp->byteCount > 1) 69552863Sralph mrp->byteCount = 1; 69652863Sralph } else if (mrp->byteCount == 2) { 69752693Sralph /* 69852693Sralph * The second mouse report byte (delta x). 69952693Sralph */ 70052863Sralph mrp->dx = cc; 70152863Sralph } else if (mrp->byteCount == 3) { 70252693Sralph /* 70352693Sralph * The final mouse report byte (delta y). 70452693Sralph */ 70552863Sralph mrp->dy = cc; 70652863Sralph mrp->byteCount = 0; 70752863Sralph if (mrp->dx != 0 || mrp->dy != 0) { 70852693Sralph /* 70952693Sralph * If the mouse moved, 71052693Sralph * post a motion event. 71152693Sralph */ 71252863Sralph (*dcMouseEvent)(mrp); 71352693Sralph } 71452863Sralph (*dcMouseButtons)(mrp); 71552693Sralph } 71652693Sralph return; 71752693Sralph } 71852693Sralph if (!(tp->t_state & TS_ISOPEN)) { 71952693Sralph wakeup((caddr_t)&tp->t_rawq); 72052693Sralph #ifdef PORTSELECTOR 72152693Sralph if (!(tp->t_state & TS_WOPEN)) 72252693Sralph #endif 72352693Sralph return; 72452693Sralph } 72552693Sralph if (c & RBUF_FERR) 72652693Sralph cc |= TTY_FE; 72752693Sralph if (c & RBUF_PERR) 72852693Sralph cc |= TTY_PE; 72952693Sralph (*linesw[tp->t_line].l_rint)(cc, tp); 73052693Sralph } 73152693Sralph DELAY(10); 73252693Sralph } 73352693Sralph 73452755Sralph void 73552130Smckusick dcxint(tp) 73652130Smckusick register struct tty *tp; 73752130Smckusick { 73852130Smckusick register struct pdma *dp; 73952130Smckusick register dcregs *dcaddr; 74052130Smckusick 74152130Smckusick dp = (struct pdma *)tp->t_addr; 74252130Smckusick if (dp->p_mem < dp->p_end) { 74352130Smckusick dcaddr = dp->p_addr; 74452130Smckusick dcaddr->dc_tdr = dc_brk[(tp - dc_tty) >> 2] | *dp->p_mem++; 74552130Smckusick MachEmptyWriteBuffer(); 74652130Smckusick DELAY(10); 74752130Smckusick return; 74852130Smckusick } 74952130Smckusick tp->t_state &= ~TS_BUSY; 75052130Smckusick if (tp->t_state & TS_FLUSH) 75152130Smckusick tp->t_state &= ~TS_FLUSH; 75252130Smckusick else { 75352130Smckusick ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 75452130Smckusick dp->p_end = dp->p_mem = tp->t_outq.c_cf; 75552130Smckusick } 75652130Smckusick if (tp->t_line) 75752130Smckusick (*linesw[tp->t_line].l_start)(tp); 75852130Smckusick else 75952130Smckusick dcstart(tp); 76052130Smckusick if (tp->t_outq.c_cc == 0 || !(tp->t_state & TS_BUSY)) { 76152130Smckusick dp->p_addr->dc_tcr &= ~(1 << (minor(tp->t_dev) & 03)); 76252130Smckusick MachEmptyWriteBuffer(); 76352130Smckusick DELAY(10); 76452130Smckusick } 76552130Smckusick } 76652130Smckusick 76752755Sralph void 76852130Smckusick dcstart(tp) 76952130Smckusick register struct tty *tp; 77052130Smckusick { 77152130Smckusick register struct pdma *dp; 77252130Smckusick register dcregs *dcaddr; 77352130Smckusick register int cc; 77452130Smckusick int s; 77552130Smckusick 77652130Smckusick dp = (struct pdma *)tp->t_addr; 77752130Smckusick dcaddr = dp->p_addr; 77852130Smckusick s = spltty(); 77952130Smckusick if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 78052130Smckusick goto out; 78152130Smckusick if (tp->t_outq.c_cc <= tp->t_lowat) { 78252130Smckusick if (tp->t_state & TS_ASLEEP) { 78352130Smckusick tp->t_state &= ~TS_ASLEEP; 78452130Smckusick wakeup((caddr_t)&tp->t_outq); 78552130Smckusick } 78652674Smckusick selwakeup(&tp->t_wsel); 78752130Smckusick } 78852130Smckusick if (tp->t_outq.c_cc == 0) 78952130Smckusick goto out; 79052130Smckusick /* handle console specially */ 79152130Smckusick if (tp == dc_tty) { 79252130Smckusick while (tp->t_outq.c_cc > 0) { 79352130Smckusick cc = getc(&tp->t_outq) & 0x7f; 79452863Sralph cnputc(cc); 79552130Smckusick } 79652130Smckusick /* 79752130Smckusick * After we flush the output queue we may need to wake 79852130Smckusick * up the process that made the output. 79952130Smckusick */ 80052130Smckusick if (tp->t_outq.c_cc <= tp->t_lowat) { 80152130Smckusick if (tp->t_state & TS_ASLEEP) { 80252130Smckusick tp->t_state &= ~TS_ASLEEP; 80352130Smckusick wakeup((caddr_t)&tp->t_outq); 80452130Smckusick } 80552674Smckusick selwakeup(&tp->t_wsel); 80652130Smckusick } 80752130Smckusick goto out; 80852130Smckusick } 80952130Smckusick if (tp->t_flags & (RAW|LITOUT)) 81052130Smckusick cc = ndqb(&tp->t_outq, 0); 81152130Smckusick else { 81252130Smckusick cc = ndqb(&tp->t_outq, 0200); 81352130Smckusick if (cc == 0) { 81452130Smckusick cc = getc(&tp->t_outq); 81552130Smckusick timeout(ttrstrt, (caddr_t)tp, (cc & 0x7f) + 6); 81652130Smckusick tp->t_state |= TS_TIMEOUT; 81752130Smckusick goto out; 81852130Smckusick } 81952130Smckusick } 82052130Smckusick tp->t_state |= TS_BUSY; 82152130Smckusick dp->p_end = dp->p_mem = tp->t_outq.c_cf; 82252130Smckusick dp->p_end += cc; 82352130Smckusick dcaddr->dc_tcr |= 1 << (minor(tp->t_dev) & 03); 82452130Smckusick MachEmptyWriteBuffer(); 82552130Smckusick out: 82652130Smckusick splx(s); 82752130Smckusick } 82852130Smckusick 82952130Smckusick /* 83052130Smckusick * Stop output on a line. 83152130Smckusick */ 83252130Smckusick /*ARGSUSED*/ 83352130Smckusick dcstop(tp, flag) 83452130Smckusick register struct tty *tp; 83552130Smckusick { 83652130Smckusick register struct pdma *dp; 83752130Smckusick register int s; 83852130Smckusick 83952130Smckusick dp = (struct pdma *)tp->t_addr; 84052130Smckusick s = spltty(); 84152130Smckusick if (tp->t_state & TS_BUSY) { 84252130Smckusick dp->p_end = dp->p_mem; 84352130Smckusick if (!(tp->t_state & TS_TTSTOP)) 84452130Smckusick tp->t_state |= TS_FLUSH; 84552130Smckusick } 84652130Smckusick splx(s); 84752130Smckusick } 84852130Smckusick 84952130Smckusick dcmctl(dev, bits, how) 85052130Smckusick dev_t dev; 85152130Smckusick int bits, how; 85252130Smckusick { 85352130Smckusick register dcregs *dcaddr; 85452130Smckusick register int unit, mbits; 85552130Smckusick int b, s; 85652693Sralph #ifdef DS5000 85752693Sralph register int msr; 85852693Sralph #endif 85952130Smckusick 86052130Smckusick unit = minor(dev); 86152130Smckusick b = 1 << (unit & 03); 86252130Smckusick dcaddr = dcpdma[unit].p_addr; 86352130Smckusick s = spltty(); 86452130Smckusick /* only channel 2 has modem control (what about line 3?) */ 86552693Sralph switch (unit & 03) { 86652693Sralph case 2: 86752130Smckusick mbits = 0; 86852130Smckusick if (dcaddr->dc_tcr & TCR_DTR2) 86952130Smckusick mbits |= DML_DTR; 87052693Sralph #ifdef DS3100 87152130Smckusick if (dcaddr->dc_msr & MSR_DSR2) 87252130Smckusick mbits |= DML_DSR | DML_CAR; 87352693Sralph #endif 87452693Sralph #ifdef DS5000 87552693Sralph msr = dcaddr->dc_msr; 87652693Sralph if (msr & MSR_CD2) 87752693Sralph mbits |= DML_CAR; 87852693Sralph if (msr & MSR_DSR2) 87952693Sralph mbits |= DML_DSR; 88052693Sralph #endif 88152693Sralph break; 88252693Sralph 88352693Sralph #ifdef DS5000 88452693Sralph case 3: 88552693Sralph mbits = 0; 88652693Sralph if (dcaddr->dc_tcr & TCR_DTR3) 88752693Sralph mbits |= DML_DTR; 88852693Sralph msr = dcaddr->dc_msr; 88952693Sralph if (msr & MSR_CD3) 89052693Sralph mbits |= DML_CAR; 89152693Sralph if (msr & MSR_DSR3) 89252693Sralph mbits |= DML_DSR; 89352693Sralph break; 89452693Sralph #endif 89552693Sralph 89652693Sralph default: 89752130Smckusick mbits = DML_DTR | DML_DSR | DML_CAR; 89852693Sralph } 89952130Smckusick switch (how) { 90052130Smckusick case DMSET: 90152130Smckusick mbits = bits; 90252130Smckusick break; 90352130Smckusick 90452130Smckusick case DMBIS: 90552130Smckusick mbits |= bits; 90652130Smckusick break; 90752130Smckusick 90852130Smckusick case DMBIC: 90952130Smckusick mbits &= ~bits; 91052130Smckusick break; 91152130Smckusick 91252130Smckusick case DMGET: 91352130Smckusick (void) splx(s); 91452130Smckusick return (mbits); 91552130Smckusick } 91652693Sralph switch (unit & 03) { 91752693Sralph case 2: 91852130Smckusick if (mbits & DML_DTR) 91952130Smckusick dcaddr->dc_tcr |= TCR_DTR2; 92052130Smckusick else 92152130Smckusick dcaddr->dc_tcr &= ~TCR_DTR2; 92252693Sralph break; 92352693Sralph 92452693Sralph #ifdef DS5000 92552693Sralph case 3: 92652693Sralph if (mbits & DML_DTR) 92752693Sralph dcaddr->dc_tcr |= TCR_DTR3; 92852693Sralph else 92952693Sralph dcaddr->dc_tcr &= ~TCR_DTR3; 93052693Sralph #endif 93152130Smckusick } 93252130Smckusick if ((mbits & DML_DTR) && (dcsoftCAR[unit >> 2] & b)) 93352130Smckusick dc_tty[unit].t_state |= TS_CARR_ON; 93452130Smckusick (void) splx(s); 93552130Smckusick return (mbits); 93652130Smckusick } 93752130Smckusick 93852130Smckusick /* 93952130Smckusick * This is called by timeout() periodically. 94052130Smckusick * Check to see if modem status bits have changed. 94152130Smckusick */ 942*54146Sralph static void 94352130Smckusick dcscan() 94452130Smckusick { 94552130Smckusick register dcregs *dcaddr; 94652130Smckusick register struct tty *tp; 94752130Smckusick register int i, bit, car; 94852130Smckusick int s; 94952130Smckusick 95052130Smckusick s = spltty(); 95152130Smckusick /* only channel 2 has modem control (what about line 3?) */ 95252130Smckusick dcaddr = dcpdma[i = 2].p_addr; 95352130Smckusick tp = &dc_tty[i]; 95452130Smckusick bit = TCR_DTR2; 95552130Smckusick if (dcsoftCAR[i >> 2] & bit) 95652130Smckusick car = 1; 95752130Smckusick else 95852130Smckusick car = dcaddr->dc_msr & MSR_DSR2; 95952130Smckusick if (car) { 96052130Smckusick /* carrier present */ 96152130Smckusick if (!(tp->t_state & TS_CARR_ON)) 96252130Smckusick (void)(*linesw[tp->t_line].l_modem)(tp, 1); 96352130Smckusick } else if ((tp->t_state & TS_CARR_ON) && 96452130Smckusick (*linesw[tp->t_line].l_modem)(tp, 0) == 0) 96552130Smckusick dcaddr->dc_tcr &= ~bit; 96652130Smckusick splx(s); 96752130Smckusick timeout(dcscan, (caddr_t)0, hz); 96852130Smckusick } 96952130Smckusick 97052130Smckusick /* 97152130Smckusick * ---------------------------------------------------------------------------- 97252130Smckusick * 97352130Smckusick * dcKBDPutc -- 97452130Smckusick * 97552130Smckusick * Put a character out to the keyboard. 97652130Smckusick * 97752130Smckusick * Results: 97852130Smckusick * None. 97952130Smckusick * 98052130Smckusick * Side effects: 98152130Smckusick * A character is written to the keyboard. 98252130Smckusick * 98352130Smckusick * ---------------------------------------------------------------------------- 98452130Smckusick */ 98552130Smckusick void 98652130Smckusick dcKBDPutc(c) 98752130Smckusick register int c; 98852130Smckusick { 98952130Smckusick register dcregs *dcaddr; 99052130Smckusick register u_short tcr; 99152130Smckusick register int timeout; 99252130Smckusick int s, line; 99352130Smckusick 99452130Smckusick s = spltty(); 99552130Smckusick 99652130Smckusick dcaddr = dcpdma[KBD_PORT].p_addr; 99752130Smckusick tcr = dcaddr->dc_tcr; 99852130Smckusick dcaddr->dc_tcr = tcr | (1 << KBD_PORT); 99952130Smckusick MachEmptyWriteBuffer(); 100052130Smckusick DELAY(10); 100152130Smckusick while (1) { 100252130Smckusick /* 100352130Smckusick * Wait for transmitter to be not busy. 100452130Smckusick */ 100552130Smckusick timeout = 1000000; 100652130Smckusick while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0) 100752130Smckusick timeout--; 100852130Smckusick if (timeout == 0) { 100952130Smckusick printf("dcKBDPutc: timeout waiting for CSR_TRDY\n"); 101052130Smckusick break; 101152130Smckusick } 101252130Smckusick line = (dcaddr->dc_csr >> 8) & 3; 101352130Smckusick /* 101452130Smckusick * Check to be sure its the right port. 101552130Smckusick */ 101652130Smckusick if (line != KBD_PORT) { 101752130Smckusick tcr |= 1 << line; 101852130Smckusick dcaddr->dc_tcr &= ~(1 << line); 101952130Smckusick MachEmptyWriteBuffer(); 102052130Smckusick DELAY(10); 102152130Smckusick continue; 102252130Smckusick } 102352130Smckusick /* 102452130Smckusick * Start sending the character. 102552130Smckusick */ 102652130Smckusick dcaddr->dc_tdr = dc_brk[0] | (c & 0xff); 102752130Smckusick MachEmptyWriteBuffer(); 102852130Smckusick DELAY(10); 102952130Smckusick /* 103052130Smckusick * Wait for character to be sent. 103152130Smckusick */ 103252130Smckusick while (1) { 103352130Smckusick /* 103452130Smckusick * cc -O bug: this code produces and infinite loop! 103552130Smckusick * while (!(dcaddr->dc_csr & CSR_TRDY)) 103652130Smckusick * ; 103752130Smckusick */ 103852130Smckusick timeout = 1000000; 103952130Smckusick while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0) 104052130Smckusick timeout--; 104152130Smckusick line = (dcaddr->dc_csr >> 8) & 3; 104252130Smckusick if (line != KBD_PORT) { 104352130Smckusick tcr |= 1 << line; 104452130Smckusick dcaddr->dc_tcr &= ~(1 << line); 104552130Smckusick MachEmptyWriteBuffer(); 104652130Smckusick DELAY(10); 104752130Smckusick continue; 104852130Smckusick } 104952130Smckusick dcaddr->dc_tcr &= ~(1 << KBD_PORT); 105052130Smckusick MachEmptyWriteBuffer(); 105152130Smckusick DELAY(10); 105252130Smckusick break; 105352130Smckusick } 105452130Smckusick break; 105552130Smckusick } 105652130Smckusick /* 105752130Smckusick * Enable interrupts for other lines which became ready. 105852130Smckusick */ 105952130Smckusick if (tcr & 0xF) { 106052130Smckusick dcaddr->dc_tcr = tcr; 106152130Smckusick MachEmptyWriteBuffer(); 106252130Smckusick DELAY(10); 106352130Smckusick } 106452130Smckusick 106552130Smckusick splx(s); 106652130Smckusick } 106752130Smckusick 106852130Smckusick #ifdef DEBUG 106952130Smckusick /* 107052130Smckusick * ---------------------------------------------------------------------------- 107152130Smckusick * 107252693Sralph * dcDebugGetc -- 107352130Smckusick * 107452693Sralph * Read a character from the keyboard if one is ready (i.e., don't wait). 107552130Smckusick * 107652130Smckusick * Results: 107752130Smckusick * A character read from the mouse, -1 if none were ready. 107852130Smckusick * 107952130Smckusick * Side effects: 108052130Smckusick * None. 108152130Smckusick * 108252130Smckusick * ---------------------------------------------------------------------------- 108352130Smckusick */ 108452130Smckusick int 108552693Sralph dcDebugGetc() 108652130Smckusick { 108752130Smckusick register dcregs *dcaddr; 108852130Smckusick register int c; 1089*54146Sralph int s; 109052130Smckusick 109152130Smckusick dcaddr = dcpdma[KBD_PORT].p_addr; 109252130Smckusick if (!dcaddr) 109352130Smckusick return (0); 1094*54146Sralph 1095*54146Sralph s = spltty(); 109652130Smckusick if (c = debugChar) 109752130Smckusick debugChar = 0; 109852130Smckusick else { 109952130Smckusick while (dcaddr->dc_csr & CSR_RDONE) { 110052130Smckusick c = dcaddr->dc_rbuf; 110152130Smckusick DELAY(10); 110252130Smckusick if (((c >> 8) & 03) == KBD_PORT) 110352130Smckusick break; 110452130Smckusick c = 0; 110552130Smckusick } 110652130Smckusick } 1107*54146Sralph splx(s); 1108*54146Sralph 110952130Smckusick return (c & 0xff); 111052130Smckusick } 111152130Smckusick #endif 111252130Smckusick 111352130Smckusick /* 111452130Smckusick * ---------------------------------------------------------------------------- 111552130Smckusick * 111652693Sralph * dcKBDGetc -- 111752693Sralph * 111852693Sralph * Read a character from the keyboard. 111952693Sralph * 112052693Sralph * Results: 112152693Sralph * A character read from the keyboard. 112252693Sralph * 112352693Sralph * Side effects: 112452693Sralph * None. 112552693Sralph * 112652693Sralph * ---------------------------------------------------------------------------- 112752693Sralph */ 112852693Sralph int 112952693Sralph dcKBDGetc() 113052693Sralph { 113152693Sralph register dcregs *dcaddr; 113252693Sralph register int c; 113352693Sralph int s; 113452693Sralph 113552693Sralph dcaddr = dcpdma[KBD_PORT].p_addr; 113652693Sralph if (!dcaddr) 113752693Sralph return (-1); 113852693Sralph s = spltty(); 113952693Sralph for (;;) { 114052693Sralph if (!(dcaddr->dc_csr & CSR_RDONE)) 114152693Sralph continue; 114252693Sralph c = dcaddr->dc_rbuf; 114352693Sralph DELAY(10); 114452693Sralph if (((c >> 8) & 03) != KBD_PORT) 114552693Sralph continue; 114652693Sralph if ((c = dcMapChar(c & 0xff)) >= 0) 114752693Sralph break; 114852693Sralph } 114952693Sralph splx(s); 115052693Sralph return (c); 115152693Sralph } 115252693Sralph 115352693Sralph /* 115452693Sralph * ---------------------------------------------------------------------------- 115552693Sralph * 115652693Sralph * dcMapChar -- 115752693Sralph * 115852693Sralph * Map characters from the keyboard to ASCII. Return -1 if there is 115952693Sralph * no valid mapping. 116052693Sralph * 116152693Sralph * Results: 116252693Sralph * None. 116352693Sralph * 116452693Sralph * Side effects: 116552693Sralph * Remember state of shift and control keys. 116652693Sralph * 116752693Sralph * ---------------------------------------------------------------------------- 116852693Sralph */ 116952693Sralph static int 117052693Sralph dcMapChar(cc) 117152693Sralph int cc; 117252693Sralph { 117352693Sralph static u_char shiftDown; 117452693Sralph static u_char ctrlDown; 117552693Sralph static u_char lastChar; 117652693Sralph 117752693Sralph switch (cc) { 117852693Sralph case KEY_REPEAT: 117952693Sralph cc = lastChar; 118052693Sralph goto done; 118152693Sralph 118252693Sralph case KEY_UP: 118352693Sralph shiftDown = 0; 118452693Sralph ctrlDown = 0; 118552693Sralph return (-1); 118652693Sralph 118752693Sralph case KEY_SHIFT: 118852693Sralph if (ctrlDown) 118952693Sralph shiftDown = 0; 119052693Sralph else 119152693Sralph shiftDown = 1; 119252693Sralph return (-1); 119352693Sralph 119452693Sralph case KEY_CONTROL: 119552693Sralph if (shiftDown) 119652693Sralph ctrlDown = 0; 119752693Sralph else 119852693Sralph ctrlDown = 1; 119952693Sralph return (-1); 120052693Sralph 120152693Sralph case LK_POWER_ERROR: 120252693Sralph case LK_KDOWN_ERROR: 120352693Sralph case LK_INPUT_ERROR: 120452693Sralph case LK_OUTPUT_ERROR: 120552693Sralph log(LOG_WARNING, 120652693Sralph "dc0,0: keyboard error, code=%x\n", cc); 120752693Sralph return (-1); 120852693Sralph } 120952693Sralph if (shiftDown) 121052693Sralph cc = shiftedAscii[cc]; 121152693Sralph else 121252693Sralph cc = unshiftedAscii[cc]; 121352693Sralph if (cc >= KBD_NOKEY) { 121452693Sralph /* 121552693Sralph * A function key was typed - ignore it. 121652693Sralph */ 121752693Sralph return (-1); 121852693Sralph } 121952693Sralph if (cc >= 'a' && cc <= 'z') { 122052693Sralph if (ctrlDown) 122152693Sralph cc = cc - 'a' + '\1'; /* ^A */ 122252693Sralph else if (shiftDown) 122352693Sralph cc = cc - 'a' + 'A'; 122452693Sralph } else if (ctrlDown) { 122552693Sralph if (cc >= '[' && cc <= '_') 122652693Sralph cc = cc - '@'; 122752693Sralph else if (cc == ' ' || cc == '@') 122852693Sralph cc = '\0'; 122952693Sralph } 123052693Sralph lastChar = cc; 123152693Sralph done: 123252693Sralph return (cc); 123352693Sralph } 123452693Sralph 123552693Sralph /* 123652693Sralph * ---------------------------------------------------------------------------- 123752693Sralph * 123852130Smckusick * dcKBDReset -- 123952130Smckusick * 124052130Smckusick * Reset the keyboard to default characteristics. 124152130Smckusick * 124252130Smckusick * Results: 124352130Smckusick * None. 124452130Smckusick * 124552130Smckusick * Side effects: 124652130Smckusick * None. 124752130Smckusick * 124852130Smckusick * ---------------------------------------------------------------------------- 124952130Smckusick */ 125052130Smckusick void 125152130Smckusick dcKBDReset() 125252130Smckusick { 125352130Smckusick register int i; 125452130Smckusick static int inKBDReset; 125552130Smckusick 125652130Smckusick if (inKBDReset) 125752130Smckusick return; 125852130Smckusick inKBDReset = 1; 125952130Smckusick for (i = 0; i < sizeof(kbdInitString); i++) 126052130Smckusick dcKBDPutc((int)kbdInitString[i]); 126152130Smckusick inKBDReset = 0; 126252130Smckusick } 126352130Smckusick 126452130Smckusick /* 126552130Smckusick * ---------------------------------------------------------------------------- 126652130Smckusick * 126752130Smckusick * MousePutc -- 126852130Smckusick * 126952130Smckusick * Write a character to the mouse. 127052130Smckusick * This is only called at initialization time. 127152130Smckusick * 127252130Smckusick * Results: 127352130Smckusick * None. 127452130Smckusick * 127552130Smckusick * Side effects: 127652130Smckusick * A character is written to the mouse. 127752130Smckusick * 127852130Smckusick * ---------------------------------------------------------------------------- 127952130Smckusick */ 128052130Smckusick static void 128152130Smckusick MousePutc(c) 128252130Smckusick int c; 128352130Smckusick { 128452130Smckusick register dcregs *dcaddr; 128552130Smckusick register u_short tcr; 128652130Smckusick register int timeout; 128752130Smckusick int line; 128852130Smckusick 128952130Smckusick dcaddr = dcpdma[MOUSE_PORT].p_addr; 129052130Smckusick tcr = dcaddr->dc_tcr; 129152130Smckusick dcaddr->dc_tcr = tcr | (1 << MOUSE_PORT); 129252130Smckusick MachEmptyWriteBuffer(); 129352130Smckusick DELAY(10); 129452130Smckusick while (1) { 129552130Smckusick /* 129652130Smckusick * Wait for transmitter to be not busy. 129752130Smckusick */ 129852130Smckusick timeout = 1000000; 129952130Smckusick while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0) 130052130Smckusick timeout--; 130152130Smckusick if (timeout == 0) { 130252130Smckusick printf("MousePutc: timeout waiting for CSR_TRDY\n"); 130352130Smckusick break; 130452130Smckusick } 130552130Smckusick line = (dcaddr->dc_csr >> 8) & 3; 130652130Smckusick /* 130752130Smckusick * Check to be sure its the right port. 130852130Smckusick */ 130952130Smckusick if (line != MOUSE_PORT) { 131052130Smckusick tcr |= 1 << line; 131152130Smckusick dcaddr->dc_tcr &= ~(1 << line); 131252130Smckusick MachEmptyWriteBuffer(); 131352130Smckusick DELAY(10); 131452130Smckusick continue; 131552130Smckusick } 131652130Smckusick /* 131752130Smckusick * Start sending the character. 131852130Smckusick */ 131952130Smckusick dcaddr->dc_tdr = dc_brk[0] | (c & 0xff); 132052130Smckusick MachEmptyWriteBuffer(); 132152130Smckusick DELAY(10); 132252130Smckusick /* 132352130Smckusick * Wait for character to be sent. 132452130Smckusick */ 132552130Smckusick while (1) { 132652130Smckusick /* 132752130Smckusick * cc -O bug: this code produces and infinite loop! 132852130Smckusick * while (!(dcaddr->dc_csr & CSR_TRDY)) 132952130Smckusick * ; 133052130Smckusick */ 133152130Smckusick timeout = 1000000; 133252130Smckusick while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0) 133352130Smckusick timeout--; 133452130Smckusick line = (dcaddr->dc_csr >> 8) & 3; 133552130Smckusick if (line != MOUSE_PORT) { 133652130Smckusick tcr |= 1 << line; 133752130Smckusick dcaddr->dc_tcr &= ~(1 << line); 133852130Smckusick MachEmptyWriteBuffer(); 133952130Smckusick DELAY(10); 134052130Smckusick continue; 134152130Smckusick } 134252130Smckusick dcaddr->dc_tcr &= ~(1 << MOUSE_PORT); 134352130Smckusick MachEmptyWriteBuffer(); 134452130Smckusick DELAY(10); 134552130Smckusick break; 134652130Smckusick } 134752130Smckusick break; 134852130Smckusick } 134952130Smckusick /* 135052130Smckusick * Enable interrupts for other lines which became ready. 135152130Smckusick */ 135252130Smckusick if (tcr & 0xF) { 135352130Smckusick dcaddr->dc_tcr = tcr; 135452130Smckusick MachEmptyWriteBuffer(); 135552130Smckusick DELAY(10); 135652130Smckusick } 135752130Smckusick } 135852130Smckusick 135952130Smckusick /* 136052130Smckusick * ---------------------------------------------------------------------------- 136152130Smckusick * 136252130Smckusick * MouseGetc -- 136352130Smckusick * 136452130Smckusick * Read a character from the mouse. 136552130Smckusick * This is only called at initialization time. 136652130Smckusick * 136752130Smckusick * Results: 136852130Smckusick * A character read from the mouse, -1 if we timed out waiting. 136952130Smckusick * 137052130Smckusick * Side effects: 137152130Smckusick * None. 137252130Smckusick * 137352130Smckusick * ---------------------------------------------------------------------------- 137452130Smckusick */ 137552130Smckusick static int 137652130Smckusick MouseGetc() 137752130Smckusick { 137852130Smckusick register dcregs *dcaddr; 137952130Smckusick register int timeout; 138052130Smckusick register int c; 138152130Smckusick 138252130Smckusick dcaddr = dcpdma[MOUSE_PORT].p_addr; 138352130Smckusick for (timeout = 1000000; timeout > 0; timeout--) { 138452130Smckusick if (!(dcaddr->dc_csr & CSR_RDONE)) 138552130Smckusick continue; 138652130Smckusick c = dcaddr->dc_rbuf; 138752130Smckusick DELAY(10); 138852130Smckusick if (((c >> 8) & 03) != MOUSE_PORT) 138952130Smckusick continue; 139052130Smckusick return (c & 0xff); 139152130Smckusick } 139252130Smckusick 139352130Smckusick return (-1); 139452130Smckusick } 139552130Smckusick 139652130Smckusick /* 139752130Smckusick * ---------------------------------------------------------------------------- 139852130Smckusick * 139952130Smckusick * MouseInit -- 140052130Smckusick * 140152130Smckusick * Initialize the mouse. 140252130Smckusick * 140352130Smckusick * Results: 140452130Smckusick * None. 140552130Smckusick * 140652130Smckusick * Side effects: 140752130Smckusick * None. 140852130Smckusick * 140952130Smckusick * ---------------------------------------------------------------------------- 141052130Smckusick */ 141152130Smckusick static void 141252130Smckusick MouseInit() 141352130Smckusick { 141452130Smckusick int id_byte1, id_byte2, id_byte3, id_byte4; 141552130Smckusick 141652130Smckusick /* 141752130Smckusick * Initialize the mouse. 141852130Smckusick */ 141952130Smckusick MousePutc(MOUSE_SELF_TEST); 142052130Smckusick id_byte1 = MouseGetc(); 142152130Smckusick if (id_byte1 < 0) { 142252130Smckusick printf("MouseInit: Timeout on 1st byte of self-test report\n"); 142352130Smckusick return; 142452130Smckusick } 142552130Smckusick id_byte2 = MouseGetc(); 142652130Smckusick if (id_byte2 < 0) { 142752130Smckusick printf("MouseInit: Timeout on 2nd byte of self-test report\n"); 142852130Smckusick return; 142952130Smckusick } 143052130Smckusick id_byte3 = MouseGetc(); 143152130Smckusick if (id_byte3 < 0) { 143252130Smckusick printf("MouseInit: Timeout on 3rd byte of self-test report\n"); 143352130Smckusick return; 143452130Smckusick } 143552130Smckusick id_byte4 = MouseGetc(); 143652130Smckusick if (id_byte4 < 0) { 143752130Smckusick printf("MouseInit: Timeout on 4th byte of self-test report\n"); 143852130Smckusick return; 143952130Smckusick } 144052130Smckusick if ((id_byte2 & 0x0f) != 0x2) 144152130Smckusick printf("MouseInit: We don't have a mouse!!!\n"); 144252130Smckusick /* 144352130Smckusick * For some reason, the mouse doesn't see this command if it comes 144452130Smckusick * too soon after a self test. 144552130Smckusick */ 144652130Smckusick DELAY(100); 144752130Smckusick MousePutc(MOUSE_INCREMENTAL); 144852130Smckusick } 144952130Smckusick #endif /* NDC */ 1450