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. 7*52693Sralph * @(#)dz.c 7.9 (Berkeley) 6/28/90 8*52693Sralph */ 9*52693Sralph 10*52693Sralph /* 11*52693Sralph * devDC7085.c -- 1252130Smckusick * 1352130Smckusick * %sccs.include.redist.c% 1452130Smckusick * 15*52693Sralph * @(#)dc.c 7.3 (Berkeley) 02/29/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(); 61*52693Sralph void dcintr(); 6252130Smckusick struct driver dcdriver = { 63*52693Sralph "dc", dcprobe, 0, 0, dcintr, 6452130Smckusick }; 6552130Smckusick 6652130Smckusick #define NDCLINE (NDC*4) 6752130Smckusick 6852130Smckusick extern int dcstart(), dcxint(); 6952130Smckusick extern int ttrstrt(); 7052130Smckusick 7152130Smckusick struct tty dc_tty[NDCLINE]; 7252130Smckusick int dc_cnt = NDCLINE; 7352130Smckusick int dcDivertXInput; /* true if diverting KBD input to X */ 7452130Smckusick #ifdef DEBUG 7552130Smckusick int debugChar; 7652130Smckusick #endif 7752130Smckusick 7852130Smckusick /* 7952130Smckusick * Software copy of brk register since it isn't readable 8052130Smckusick */ 8152130Smckusick int dc_brk[NDC]; 8252130Smckusick char dcsoftCAR[NDC]; /* mask of dc's with carrier on (DSR) */ 8352130Smckusick 8452130Smckusick /* 8552130Smckusick * The DC7085 doesn't interrupt on carrier transitions, so 8652130Smckusick * we have to use a timer to watch it. 8752130Smckusick */ 8852130Smckusick int dc_timer; /* true if timer started */ 8952130Smckusick 9052130Smckusick /* 9152130Smckusick * Pdma structures for fast output code 9252130Smckusick */ 9352130Smckusick struct pdma dcpdma[NDCLINE]; 9452130Smckusick 9552130Smckusick struct speedtab dcspeedtab[] = { 9652130Smckusick 0, 0, 9752130Smckusick 50, LPR_B50, 9852130Smckusick 75, LPR_B75, 9952130Smckusick 110, LPR_B110, 10052130Smckusick 134, LPR_B134, 10152130Smckusick 150, LPR_B150, 10252130Smckusick 300, LPR_B300, 10352130Smckusick 600, LPR_B600, 10452130Smckusick 1200, LPR_B1200, 10552130Smckusick 1800, LPR_B1800, 10652130Smckusick 2400, LPR_B2400, 10752130Smckusick 4800, LPR_B4800, 10852130Smckusick 9600, LPR_B9600, 109*52693Sralph #ifdef DS5000 110*52693Sralph 19200, LPR_B19200, 111*52693Sralph #endif 11252130Smckusick -1, -1 11352130Smckusick }; 11452130Smckusick 11552130Smckusick #ifndef PORTSELECTOR 11652130Smckusick #define ISPEED TTYDEF_SPEED 11752130Smckusick #define LFLAG TTYDEF_LFLAG 11852130Smckusick #else 11952130Smckusick #define ISPEED B4800 12052130Smckusick #define LFLAG (TTYDEF_LFLAG & ~ECHO) 12152130Smckusick #endif 12252130Smckusick 12352130Smckusick /* 12452130Smckusick * Ascii values of command keys. 12552130Smckusick */ 12652130Smckusick #define KBD_TAB '\t' 12752130Smckusick #define KBD_DEL 127 12852130Smckusick #define KBD_RET '\r' 12952130Smckusick 13052130Smckusick /* 13152130Smckusick * Define "hardware-independent" codes for the control, shift, meta and 13252130Smckusick * function keys. Codes start after the last 7-bit ASCII code (127) 13352130Smckusick * and are assigned in an arbitrary order. 13452130Smckusick */ 13552130Smckusick #define KBD_NOKEY 128 13652130Smckusick 13752130Smckusick #define KBD_F1 201 13852130Smckusick #define KBD_F2 202 13952130Smckusick #define KBD_F3 203 14052130Smckusick #define KBD_F4 204 14152130Smckusick #define KBD_F5 205 14252130Smckusick #define KBD_F6 206 14352130Smckusick #define KBD_F7 207 14452130Smckusick #define KBD_F8 208 14552130Smckusick #define KBD_F9 209 14652130Smckusick #define KBD_F10 210 14752130Smckusick #define KBD_F11 211 14852130Smckusick #define KBD_F12 212 14952130Smckusick #define KBD_F13 213 15052130Smckusick #define KBD_F14 214 15152130Smckusick #define KBD_HELP 215 15252130Smckusick #define KBD_DO 216 15352130Smckusick #define KBD_F17 217 15452130Smckusick #define KBD_F18 218 15552130Smckusick #define KBD_F19 219 15652130Smckusick #define KBD_F20 220 15752130Smckusick 15852130Smckusick #define KBD_FIND 221 15952130Smckusick #define KBD_INSERT 222 16052130Smckusick #define KBD_REMOVE 223 16152130Smckusick #define KBD_SELECT 224 16252130Smckusick #define KBD_PREVIOUS 225 16352130Smckusick #define KBD_NEXT 226 16452130Smckusick 16552130Smckusick #define KBD_KP_ENTER 227 16652130Smckusick #define KBD_KP_F1 228 16752130Smckusick #define KBD_KP_F2 229 16852130Smckusick #define KBD_KP_F3 230 16952130Smckusick #define KBD_KP_F4 231 17052130Smckusick #define KBD_LEFT 232 17152130Smckusick #define KBD_RIGHT 233 17252130Smckusick #define KBD_DOWN 234 17352130Smckusick #define KBD_UP 235 17452130Smckusick 17552130Smckusick #define KBD_CONTROL 236 17652130Smckusick #define KBD_SHIFT 237 17752130Smckusick #define KBD_CAPSLOCK 238 17852130Smckusick #define KBD_ALTERNATE 239 17952130Smckusick 18052130Smckusick /* 18152130Smckusick * Keyboard to Ascii, unshifted. 18252130Smckusick */ 18352130Smckusick static unsigned char unshiftedAscii[] = { 18452130Smckusick /* 0 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 18552130Smckusick /* 4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 18652130Smckusick /* 8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 18752130Smckusick /* c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 18852130Smckusick /* 10 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 18952130Smckusick /* 14 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19052130Smckusick /* 18 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19152130Smckusick /* 1c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19252130Smckusick /* 20 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19352130Smckusick /* 24 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19452130Smckusick /* 28 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19552130Smckusick /* 2c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19652130Smckusick /* 30 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19752130Smckusick /* 34 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19852130Smckusick /* 38 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 19952130Smckusick /* 3c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20052130Smckusick /* 40 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20152130Smckusick /* 44 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20252130Smckusick /* 48 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20352130Smckusick /* 4c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20452130Smckusick /* 50 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20552130Smckusick /* 54 */ KBD_NOKEY, KBD_NOKEY, KBD_F1, KBD_F2, 20652130Smckusick /* 58 */ KBD_F3, KBD_F4, KBD_F5, KBD_NOKEY, 20752130Smckusick /* 5c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20852130Smckusick /* 60 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 20952130Smckusick /* 64 */ KBD_F6, KBD_F7, KBD_F8, KBD_F9, 21052130Smckusick /* 68 */ KBD_F10, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21152130Smckusick /* 6c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21252130Smckusick /* 70 */ KBD_NOKEY, '\033', KBD_F12, KBD_F13, 21352130Smckusick /* 74 */ KBD_F14, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21452130Smckusick /* 78 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21552130Smckusick /* 7c */ KBD_HELP, KBD_DO, KBD_NOKEY, KBD_NOKEY, 21652130Smckusick /* 80 */ KBD_F17, KBD_F18, KBD_F19, KBD_F20, 21752130Smckusick /* 84 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 21852130Smckusick /* 88 */ KBD_NOKEY, KBD_NOKEY, KBD_FIND, KBD_INSERT, 21952130Smckusick /* 8c */ KBD_REMOVE, KBD_SELECT, KBD_PREVIOUS, KBD_NEXT, 22052130Smckusick /* 90 */ KBD_NOKEY, KBD_NOKEY, '0', KBD_NOKEY, 22152130Smckusick /* 94 */ '.', KBD_KP_ENTER, '1', '2', 22252130Smckusick /* 98 */ '3', '4', '5', '6', 22352130Smckusick /* 9c */ ',', '7', '8', '9', 22452130Smckusick /* a0 */ '-', KBD_KP_F1, KBD_KP_F2, KBD_KP_F3, 22552130Smckusick /* a4 */ KBD_KP_F4, KBD_NOKEY, KBD_NOKEY, KBD_LEFT, 22652130Smckusick /* a8 */ KBD_RIGHT, KBD_DOWN, KBD_UP, KBD_NOKEY, 22752130Smckusick /* ac */ KBD_NOKEY, KBD_NOKEY, KBD_SHIFT, KBD_CONTROL, 22852130Smckusick /* b0 */ KBD_CAPSLOCK, KBD_ALTERNATE, KBD_NOKEY, KBD_NOKEY, 22952130Smckusick /* b4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 23052130Smckusick /* b8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 23152130Smckusick /* bc */ KBD_DEL, KBD_RET, KBD_TAB, '`', 23252130Smckusick /* c0 */ '1', 'q', 'a', 'z', 23352130Smckusick /* c4 */ KBD_NOKEY, '2', 'w', 's', 23452130Smckusick /* c8 */ 'x', '<', KBD_NOKEY, '3', 23552130Smckusick /* cc */ 'e', 'd', 'c', KBD_NOKEY, 23652130Smckusick /* d0 */ '4', 'r', 'f', 'v', 23752130Smckusick /* d4 */ ' ', KBD_NOKEY, '5', 't', 23852130Smckusick /* d8 */ 'g', 'b', KBD_NOKEY, '6', 23952130Smckusick /* dc */ 'y', 'h', 'n', KBD_NOKEY, 24052130Smckusick /* e0 */ '7', 'u', 'j', 'm', 24152130Smckusick /* e4 */ KBD_NOKEY, '8', 'i', 'k', 24252130Smckusick /* e8 */ ',', KBD_NOKEY, '9', 'o', 24352130Smckusick /* ec */ 'l', '.', KBD_NOKEY, '0', 24452130Smckusick /* f0 */ 'p', KBD_NOKEY, ';', '/', 24552130Smckusick /* f4 */ KBD_NOKEY, '=', ']', '\\', 24652130Smckusick /* f8 */ KBD_NOKEY, '-', '[', '\'', 24752130Smckusick /* fc */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 24852130Smckusick }; 24952130Smckusick 25052130Smckusick /* 25152130Smckusick * Keyboard to Ascii, shifted. 25252130Smckusick */ 25352130Smckusick static unsigned char shiftedAscii[] = { 25452130Smckusick /* 0 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 25552130Smckusick /* 4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 25652130Smckusick /* 8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 25752130Smckusick /* c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 25852130Smckusick /* 10 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 25952130Smckusick /* 14 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26052130Smckusick /* 18 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26152130Smckusick /* 1c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26252130Smckusick /* 20 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26352130Smckusick /* 24 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26452130Smckusick /* 28 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26552130Smckusick /* 2c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26652130Smckusick /* 30 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26752130Smckusick /* 34 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26852130Smckusick /* 38 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 26952130Smckusick /* 3c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27052130Smckusick /* 40 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27152130Smckusick /* 44 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27252130Smckusick /* 48 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27352130Smckusick /* 4c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27452130Smckusick /* 50 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27552130Smckusick /* 54 */ KBD_NOKEY, KBD_NOKEY, KBD_F1, KBD_F2, 27652130Smckusick /* 58 */ KBD_F3, KBD_F4, KBD_F5, KBD_NOKEY, 27752130Smckusick /* 5c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27852130Smckusick /* 60 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 27952130Smckusick /* 64 */ KBD_F6, KBD_F7, KBD_F8, KBD_F9, 28052130Smckusick /* 68 */ KBD_F10, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28152130Smckusick /* 6c */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28252130Smckusick /* 70 */ KBD_NOKEY, KBD_F11, KBD_F12, KBD_F13, 28352130Smckusick /* 74 */ KBD_F14, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28452130Smckusick /* 78 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28552130Smckusick /* 7c */ KBD_HELP, KBD_DO, KBD_NOKEY, KBD_NOKEY, 28652130Smckusick /* 80 */ KBD_F17, KBD_F18, KBD_F19, KBD_F20, 28752130Smckusick /* 84 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 28852130Smckusick /* 88 */ KBD_NOKEY, KBD_NOKEY, KBD_FIND, KBD_INSERT, 28952130Smckusick /* 8c */ KBD_REMOVE, KBD_SELECT, KBD_PREVIOUS, KBD_NEXT, 29052130Smckusick /* 90 */ KBD_NOKEY, KBD_NOKEY, '0', KBD_NOKEY, 29152130Smckusick /* 94 */ '.', KBD_KP_ENTER, '1', '2', 29252130Smckusick /* 98 */ '3', '4', '5', '6', 29352130Smckusick /* 9c */ ',', '7', '8', '9', 29452130Smckusick /* a0 */ '-', KBD_KP_F1, KBD_KP_F2, KBD_KP_F3, 29552130Smckusick /* a4 */ KBD_KP_F4, KBD_NOKEY, KBD_NOKEY, KBD_LEFT, 29652130Smckusick /* a8 */ KBD_RIGHT, KBD_DOWN, KBD_UP, KBD_NOKEY, 29752130Smckusick /* ac */ KBD_NOKEY, KBD_NOKEY, KBD_SHIFT, KBD_CONTROL, 29852130Smckusick /* b0 */ KBD_CAPSLOCK, KBD_ALTERNATE, KBD_NOKEY, KBD_NOKEY, 29952130Smckusick /* b4 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 30052130Smckusick /* b8 */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 30152130Smckusick /* bc */ KBD_DEL, KBD_RET, KBD_TAB, '~', 30252130Smckusick /* c0 */ '!', 'q', 'a', 'z', 30352130Smckusick /* c4 */ KBD_NOKEY, '@', 'w', 's', 30452130Smckusick /* c8 */ 'x', '>', KBD_NOKEY, '#', 30552130Smckusick /* cc */ 'e', 'd', 'c', KBD_NOKEY, 30652130Smckusick /* d0 */ '$', 'r', 'f', 'v', 30752130Smckusick /* d4 */ ' ', KBD_NOKEY, '%', 't', 30852130Smckusick /* d8 */ 'g', 'b', KBD_NOKEY, '^', 30952130Smckusick /* dc */ 'y', 'h', 'n', KBD_NOKEY, 31052130Smckusick /* e0 */ '&', 'u', 'j', 'm', 31152130Smckusick /* e4 */ KBD_NOKEY, '*', 'i', 'k', 31252130Smckusick /* e8 */ '<', KBD_NOKEY, '(', 'o', 31352130Smckusick /* ec */ 'l', '>', KBD_NOKEY, ')', 31452130Smckusick /* f0 */ 'p', KBD_NOKEY, ':', '?', 31552130Smckusick /* f4 */ KBD_NOKEY, '+', '}', '|', 31652130Smckusick /* f8 */ KBD_NOKEY, '_', '{', '"', 31752130Smckusick /* fc */ KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, KBD_NOKEY, 31852130Smckusick }; 31952130Smckusick 32052130Smckusick /* 32152130Smckusick * Keyboard initialization string. 32252130Smckusick */ 32352130Smckusick static u_char kbdInitString[] = { 32452130Smckusick LK_LED_ENABLE, LED_ALL, /* show we are resetting keyboard */ 32552130Smckusick LK_DEFAULTS, 32652130Smckusick LK_CMD_MODE(LK_AUTODOWN, 1), 32752130Smckusick LK_CMD_MODE(LK_AUTODOWN, 2), 32852130Smckusick LK_CMD_MODE(LK_AUTODOWN, 3), 32952130Smckusick LK_CMD_MODE(LK_DOWN, 4), /* could also be LK_AUTODOWN */ 33052130Smckusick LK_CMD_MODE(LK_UPDOWN, 5), 33152130Smckusick LK_CMD_MODE(LK_UPDOWN, 6), 33252130Smckusick LK_CMD_MODE(LK_AUTODOWN, 7), 33352130Smckusick LK_CMD_MODE(LK_AUTODOWN, 8), 33452130Smckusick LK_CMD_MODE(LK_AUTODOWN, 9), 33552130Smckusick LK_CMD_MODE(LK_AUTODOWN, 10), 33652130Smckusick LK_CMD_MODE(LK_AUTODOWN, 11), 33752130Smckusick LK_CMD_MODE(LK_AUTODOWN, 12), 33852130Smckusick LK_CMD_MODE(LK_DOWN, 13), 33952130Smckusick LK_CMD_MODE(LK_AUTODOWN, 14), 34052130Smckusick LK_AR_ENABLE, /* we want autorepeat by default */ 34152130Smckusick LK_CL_ENABLE, 0x83, /* keyclick, volume */ 34252130Smckusick LK_KBD_ENABLE, /* the keyboard itself */ 34352130Smckusick LK_BELL_ENABLE, 0x83, /* keyboard bell, volume */ 34452130Smckusick LK_LED_DISABLE, LED_ALL, /* clear keyboard leds */ 34552130Smckusick }; 34652130Smckusick 34752130Smckusick /* 34852130Smckusick * Test to see if device is present. 34952130Smckusick * Return true if found and initialized ok. 35052130Smckusick */ 35152130Smckusick dcprobe(cp) 35252130Smckusick register struct pmax_ctlr *cp; 35352130Smckusick { 35452130Smckusick register dcregs *dcaddr; 35552130Smckusick register struct pdma *pdp; 35652130Smckusick register struct tty *tp; 35752130Smckusick register int cntr; 35852130Smckusick extern dcscan(); 35952130Smckusick extern void dcKBDReset(); 36052130Smckusick extern void MouseInit(); 36152130Smckusick 36252130Smckusick if (cp->pmax_unit >= NDC) 36352130Smckusick return (0); 36452130Smckusick if (badaddr(cp->pmax_addr, 2)) 36552130Smckusick return (0); 36652130Smckusick 36752130Smckusick /* reset chip */ 36852130Smckusick dcaddr = (dcregs *)cp->pmax_addr; 36952130Smckusick dcaddr->dc_csr = CSR_CLR; 37052130Smckusick MachEmptyWriteBuffer(); 37152130Smckusick while (dcaddr->dc_csr & CSR_CLR) 37252130Smckusick ; 37352130Smckusick dcaddr->dc_csr = CSR_MSE | CSR_TIE | CSR_RIE; 37452130Smckusick 37552130Smckusick /* init pseudo DMA structures */ 37652130Smckusick pdp = &dcpdma[cp->pmax_unit * 4]; 37752130Smckusick tp = &dc_tty[cp->pmax_unit * 4]; 37852130Smckusick for (cntr = 0; cntr < 4; cntr++) { 37952130Smckusick pdp->p_addr = dcaddr; 38052130Smckusick pdp->p_arg = (int)tp; 38152130Smckusick pdp->p_fcn = dcxint; 38252130Smckusick tp->t_addr = (caddr_t)pdp; 38352130Smckusick pdp++, tp++; 38452130Smckusick } 38552130Smckusick dcsoftCAR[cp->pmax_unit] = cp->pmax_flags | 0xB; 38652130Smckusick 38752130Smckusick if (dc_timer == 0) { 38852130Smckusick dc_timer = 1; 38952130Smckusick timeout(dcscan, (caddr_t)0, hz); 39052130Smckusick } 391*52693Sralph printf("dc%d at nexus0 csr 0x%x priority %d\n", 392*52693Sralph cp->pmax_unit, cp->pmax_addr, cp->pmax_pri); 39352130Smckusick if (cp->pmax_unit == 0) { 39452130Smckusick int s; 39552130Smckusick 39652130Smckusick s = spltty(); 39752130Smckusick dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_8_BIT_CHAR | 39852130Smckusick KBD_PORT; 39952130Smckusick dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR | 40052130Smckusick LPR_PARENB | LPR_8_BIT_CHAR | MOUSE_PORT; 40152130Smckusick MachEmptyWriteBuffer(); 40252130Smckusick dcKBDReset(); 40352130Smckusick MouseInit(); 40452130Smckusick splx(s); 40552130Smckusick } 40652130Smckusick return (1); 40752130Smckusick } 40852130Smckusick 40952130Smckusick dcopen(dev, flag) 41052130Smckusick dev_t dev; 41152130Smckusick { 41252130Smckusick register struct tty *tp; 41352130Smckusick register int unit; 41452130Smckusick int s, error = 0; 41552130Smckusick extern int dcparam(); 41652130Smckusick 41752130Smckusick unit = minor(dev); 41852130Smckusick if (unit >= dc_cnt || dcpdma[unit].p_addr == 0) 41952130Smckusick return (ENXIO); 42052130Smckusick tp = &dc_tty[unit]; 42152130Smckusick tp->t_addr = (caddr_t)&dcpdma[unit]; 42252130Smckusick tp->t_oproc = dcstart; 42352130Smckusick tp->t_param = dcparam; 42452130Smckusick tp->t_dev = dev; 42552130Smckusick if ((tp->t_state & TS_ISOPEN) == 0) { 42652130Smckusick tp->t_state |= TS_WOPEN; 42752130Smckusick ttychars(tp); 42852130Smckusick #ifndef PORTSELECTOR 42952130Smckusick if (tp->t_ispeed == 0) { 43052130Smckusick #endif 43152130Smckusick tp->t_iflag = TTYDEF_IFLAG; 43252130Smckusick tp->t_oflag = TTYDEF_OFLAG; 43352130Smckusick tp->t_cflag = TTYDEF_CFLAG; 43452130Smckusick tp->t_lflag = LFLAG; 43552130Smckusick tp->t_ispeed = tp->t_ospeed = ISPEED; 43652130Smckusick #ifdef PORTSELECTOR 43752130Smckusick tp->t_cflag |= HUPCL; 43852130Smckusick #else 43952130Smckusick } 44052130Smckusick #endif 44152130Smckusick (void) dcparam(tp, &tp->t_termios); 44252130Smckusick ttsetwater(tp); 44352130Smckusick } else if ((tp->t_state & TS_XCLUDE) && curproc->p_ucred->cr_uid != 0) 44452130Smckusick return (EBUSY); 44552130Smckusick (void) dcmctl(dev, DML_DTR, DMSET); 44652130Smckusick s = spltty(); 44752130Smckusick while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) && 44852130Smckusick !(tp->t_state & TS_CARR_ON)) { 44952130Smckusick tp->t_state |= TS_WOPEN; 45052130Smckusick if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 45152130Smckusick ttopen, 0)) 45252130Smckusick break; 45352130Smckusick } 45452130Smckusick splx(s); 45552130Smckusick if (error) 45652130Smckusick return (error); 45752130Smckusick return ((*linesw[tp->t_line].l_open)(dev, tp)); 45852130Smckusick } 45952130Smckusick 46052130Smckusick /*ARGSUSED*/ 46152130Smckusick dcclose(dev, flag) 46252130Smckusick dev_t dev; 46352130Smckusick { 46452130Smckusick register struct tty *tp; 46552130Smckusick register int unit, bit; 46652130Smckusick 46752130Smckusick unit = minor(dev); 46852130Smckusick tp = &dc_tty[unit]; 46952130Smckusick bit = 1 << ((unit & 03) + 8); 47052130Smckusick if (dc_brk[unit >> 2] & bit) { 47152130Smckusick dc_brk[unit >> 2] &= ~bit; 47252130Smckusick ttyoutput(0, tp); 47352130Smckusick } 47452130Smckusick (*linesw[tp->t_line].l_close)(tp); 47552130Smckusick if ((tp->t_cflag & HUPCL) || (tp->t_state & TS_WOPEN) || 47652130Smckusick !(tp->t_state & TS_ISOPEN)) 47752130Smckusick (void) dcmctl(dev, 0, DMSET); 47852130Smckusick return (ttyclose(tp)); 47952130Smckusick } 48052130Smckusick 48152130Smckusick dcread(dev, uio, flag) 48252130Smckusick dev_t dev; 48352130Smckusick struct uio *uio; 48452130Smckusick { 48552130Smckusick register struct tty *tp; 48652130Smckusick 48752130Smckusick tp = &dc_tty[minor(dev)]; 48852130Smckusick return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 48952130Smckusick } 49052130Smckusick 49152130Smckusick dcwrite(dev, uio, flag) 49252130Smckusick dev_t dev; 49352130Smckusick struct uio *uio; 49452130Smckusick { 49552130Smckusick register struct tty *tp; 49652130Smckusick 49752130Smckusick tp = &dc_tty[minor(dev)]; 49852130Smckusick return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 49952130Smckusick } 50052130Smckusick 50152130Smckusick /*ARGSUSED*/ 50252130Smckusick dcioctl(dev, cmd, data, flag) 50352130Smckusick dev_t dev; 50452130Smckusick caddr_t data; 50552130Smckusick { 50652130Smckusick register struct tty *tp; 50752130Smckusick register int unit = minor(dev); 50852130Smckusick register int dc = unit >> 2; 50952130Smckusick int error; 51052130Smckusick 51152130Smckusick tp = &dc_tty[unit]; 51252130Smckusick error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 51352130Smckusick if (error >= 0) 51452130Smckusick return (error); 51552130Smckusick error = ttioctl(tp, cmd, data, flag); 51652130Smckusick if (error >= 0) 51752130Smckusick return (error); 51852130Smckusick 51952130Smckusick switch (cmd) { 52052130Smckusick 52152130Smckusick case TIOCSBRK: 52252130Smckusick dc_brk[dc] |= 1 << ((unit & 03) + 8); 52352130Smckusick ttyoutput(0, tp); 52452130Smckusick break; 52552130Smckusick 52652130Smckusick case TIOCCBRK: 52752130Smckusick dc_brk[dc] &= ~(1 << ((unit & 03) + 8)); 52852130Smckusick ttyoutput(0, tp); 52952130Smckusick break; 53052130Smckusick 53152130Smckusick case TIOCSDTR: 53252130Smckusick (void) dcmctl(dev, DML_DTR|DML_RTS, DMBIS); 53352130Smckusick break; 53452130Smckusick 53552130Smckusick case TIOCCDTR: 53652130Smckusick (void) dcmctl(dev, DML_DTR|DML_RTS, DMBIC); 53752130Smckusick break; 53852130Smckusick 53952130Smckusick case TIOCMSET: 54052130Smckusick (void) dcmctl(dev, *(int *)data, DMSET); 54152130Smckusick break; 54252130Smckusick 54352130Smckusick case TIOCMBIS: 54452130Smckusick (void) dcmctl(dev, *(int *)data, DMBIS); 54552130Smckusick break; 54652130Smckusick 54752130Smckusick case TIOCMBIC: 54852130Smckusick (void) dcmctl(dev, *(int *)data, DMBIC); 54952130Smckusick break; 55052130Smckusick 55152130Smckusick case TIOCMGET: 55252130Smckusick *(int *)data = dcmctl(dev, 0, DMGET); 55352130Smckusick break; 55452130Smckusick 55552130Smckusick default: 55652130Smckusick return (ENOTTY); 55752130Smckusick } 55852130Smckusick return (0); 55952130Smckusick } 56052130Smckusick 56152130Smckusick dcparam(tp, t) 56252130Smckusick register struct tty *tp; 56352130Smckusick register struct termios *t; 56452130Smckusick { 56552130Smckusick register dcregs *dcaddr; 56652130Smckusick register int lpr; 56752130Smckusick register int cflag = t->c_cflag; 56852130Smckusick int unit = minor(tp->t_dev); 56952130Smckusick int ospeed = ttspeedtab(t->c_ospeed, dcspeedtab); 57052130Smckusick 57152130Smckusick /* check requested parameters */ 57252130Smckusick if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) || 57352130Smckusick (cflag & CSIZE) == CS5 || (cflag & CSIZE) == CS6) 57452130Smckusick return (EINVAL); 57552130Smckusick /* and copy to tty */ 57652130Smckusick tp->t_ispeed = t->c_ispeed; 57752130Smckusick tp->t_ospeed = t->c_ospeed; 57852130Smckusick tp->t_cflag = cflag; 57952130Smckusick 58052130Smckusick dcaddr = dcpdma[unit].p_addr; 58152130Smckusick if (tp == dc_tty + KBD_PORT) { 58252130Smckusick /* handle the keyboard specially */ 58352130Smckusick dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_8_BIT_CHAR | 58452130Smckusick KBD_PORT; 58552130Smckusick MachEmptyWriteBuffer(); 58652130Smckusick return (0); 58752130Smckusick } 58852130Smckusick if (tp == dc_tty + MOUSE_PORT) { 58952130Smckusick /* handle the mouse specially */ 59052130Smckusick dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR | 59152130Smckusick LPR_PARENB | LPR_8_BIT_CHAR | MOUSE_PORT; 59252130Smckusick MachEmptyWriteBuffer(); 59352130Smckusick return (0); 59452130Smckusick } 59552130Smckusick if (ospeed == 0) { 59652130Smckusick (void) dcmctl(unit, 0, DMSET); /* hang up line */ 59752130Smckusick return (0); 59852130Smckusick } 59952130Smckusick lpr = LPR_RXENAB | ospeed | (unit & 03); 60052130Smckusick if ((cflag & CSIZE) == CS7) 60152130Smckusick lpr |= LPR_7_BIT_CHAR; 60252130Smckusick else 60352130Smckusick lpr |= LPR_8_BIT_CHAR; 60452130Smckusick if (cflag & PARENB) 60552130Smckusick lpr |= LPR_PARENB; 60652130Smckusick if (cflag & PARODD) 60752130Smckusick lpr |= LPR_OPAR; 60852130Smckusick if (cflag & CSTOPB) 60952130Smckusick lpr |= LPR_2_STOP; 61052130Smckusick dcaddr->dc_lpr = lpr; 61152130Smckusick MachEmptyWriteBuffer(); 61252130Smckusick return (0); 61352130Smckusick } 61452130Smckusick 615*52693Sralph /* 616*52693Sralph * Check for interrupts from all devices. 617*52693Sralph */ 618*52693Sralph void 619*52693Sralph dcintr(unit) 620*52693Sralph register int unit; 621*52693Sralph { 622*52693Sralph register dcregs *dcaddr; 623*52693Sralph register unsigned csr; 624*52693Sralph 625*52693Sralph unit <<= 2; 626*52693Sralph dcaddr = dcpdma[unit].p_addr; 627*52693Sralph while ((csr = dcaddr->dc_csr) & (CSR_RDONE | CSR_TRDY)) { 628*52693Sralph if (csr & CSR_RDONE) 629*52693Sralph dcrint(unit); 630*52693Sralph if (csr & CSR_TRDY) 631*52693Sralph dcxint(&dc_tty[unit + ((csr >> 8) & 03)]); 632*52693Sralph } 633*52693Sralph } 634*52693Sralph 635*52693Sralph dcrint(unit) 636*52693Sralph register int unit; 637*52693Sralph { 638*52693Sralph register dcregs *dcaddr; 639*52693Sralph register struct tty *tp; 640*52693Sralph register int c, cc; 641*52693Sralph register struct tty *tp0; 642*52693Sralph int overrun = 0; 643*52693Sralph 644*52693Sralph dcaddr = dcpdma[unit].p_addr; 645*52693Sralph tp0 = &dc_tty[unit]; 646*52693Sralph while ((c = dcaddr->dc_rbuf) < 0) { /* char present */ 647*52693Sralph cc = c & 0xff; 648*52693Sralph tp = tp0 + ((c >> 8) & 03); 649*52693Sralph if ((c & RBUF_OERR) && overrun == 0) { 650*52693Sralph log(LOG_WARNING, "dc%d,%d: silo overflow\n", unit >> 2, 651*52693Sralph (c >> 8) & 03); 652*52693Sralph overrun = 1; 653*52693Sralph } 654*52693Sralph /* the keyboard requires special translation */ 655*52693Sralph if (tp == &dc_tty[KBD_PORT]) { 656*52693Sralph #ifdef KADB 657*52693Sralph if (cc == LK_DO) { 658*52693Sralph spl0(); 659*52693Sralph kdbpanic(); 660*52693Sralph return; 661*52693Sralph } 662*52693Sralph #endif 663*52693Sralph #ifdef DEBUG 664*52693Sralph debugChar = cc; 665*52693Sralph #endif 666*52693Sralph if (dcDivertXInput) { 667*52693Sralph pmKbdEvent(cc); 668*52693Sralph return; 669*52693Sralph } 670*52693Sralph if ((cc = dcMapChar(cc)) < 0) 671*52693Sralph return; 672*52693Sralph } else if (tp == &dc_tty[MOUSE_PORT]) { 673*52693Sralph register MouseReport *newRepPtr; 674*52693Sralph static MouseReport currentRep; 675*52693Sralph 676*52693Sralph newRepPtr = ¤tRep; 677*52693Sralph newRepPtr->byteCount++; 678*52693Sralph if (cc & MOUSE_START_FRAME) { 679*52693Sralph /* 680*52693Sralph * The first mouse report byte (button state). 681*52693Sralph */ 682*52693Sralph newRepPtr->state = cc; 683*52693Sralph if (newRepPtr->byteCount > 1) 684*52693Sralph newRepPtr->byteCount = 1; 685*52693Sralph } else if (newRepPtr->byteCount == 2) { 686*52693Sralph /* 687*52693Sralph * The second mouse report byte (delta x). 688*52693Sralph */ 689*52693Sralph newRepPtr->dx = cc; 690*52693Sralph } else if (newRepPtr->byteCount == 3) { 691*52693Sralph /* 692*52693Sralph * The final mouse report byte (delta y). 693*52693Sralph */ 694*52693Sralph newRepPtr->dy = cc; 695*52693Sralph newRepPtr->byteCount = 0; 696*52693Sralph if (newRepPtr->dx != 0 || newRepPtr->dy != 0) { 697*52693Sralph /* 698*52693Sralph * If the mouse moved, 699*52693Sralph * post a motion event. 700*52693Sralph */ 701*52693Sralph pmMouseEvent(newRepPtr); 702*52693Sralph } 703*52693Sralph pmMouseButtons(newRepPtr); 704*52693Sralph } 705*52693Sralph return; 706*52693Sralph } 707*52693Sralph if (!(tp->t_state & TS_ISOPEN)) { 708*52693Sralph wakeup((caddr_t)&tp->t_rawq); 709*52693Sralph #ifdef PORTSELECTOR 710*52693Sralph if (!(tp->t_state & TS_WOPEN)) 711*52693Sralph #endif 712*52693Sralph return; 713*52693Sralph } 714*52693Sralph if (c & RBUF_FERR) 715*52693Sralph cc |= TTY_FE; 716*52693Sralph if (c & RBUF_PERR) 717*52693Sralph cc |= TTY_PE; 718*52693Sralph (*linesw[tp->t_line].l_rint)(cc, tp); 719*52693Sralph } 720*52693Sralph DELAY(10); 721*52693Sralph } 722*52693Sralph 72352130Smckusick dcxint(tp) 72452130Smckusick register struct tty *tp; 72552130Smckusick { 72652130Smckusick register struct pdma *dp; 72752130Smckusick register dcregs *dcaddr; 72852130Smckusick 72952130Smckusick dp = (struct pdma *)tp->t_addr; 73052130Smckusick if (dp->p_mem < dp->p_end) { 73152130Smckusick dcaddr = dp->p_addr; 73252130Smckusick dcaddr->dc_tdr = dc_brk[(tp - dc_tty) >> 2] | *dp->p_mem++; 73352130Smckusick MachEmptyWriteBuffer(); 73452130Smckusick DELAY(10); 73552130Smckusick return; 73652130Smckusick } 73752130Smckusick tp->t_state &= ~TS_BUSY; 73852130Smckusick if (tp->t_state & TS_FLUSH) 73952130Smckusick tp->t_state &= ~TS_FLUSH; 74052130Smckusick else { 74152130Smckusick ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 74252130Smckusick dp->p_end = dp->p_mem = tp->t_outq.c_cf; 74352130Smckusick } 74452130Smckusick if (tp->t_line) 74552130Smckusick (*linesw[tp->t_line].l_start)(tp); 74652130Smckusick else 74752130Smckusick dcstart(tp); 74852130Smckusick if (tp->t_outq.c_cc == 0 || !(tp->t_state & TS_BUSY)) { 74952130Smckusick dp->p_addr->dc_tcr &= ~(1 << (minor(tp->t_dev) & 03)); 75052130Smckusick MachEmptyWriteBuffer(); 75152130Smckusick DELAY(10); 75252130Smckusick } 75352130Smckusick } 75452130Smckusick 75552130Smckusick dcstart(tp) 75652130Smckusick register struct tty *tp; 75752130Smckusick { 75852130Smckusick register struct pdma *dp; 75952130Smckusick register dcregs *dcaddr; 76052130Smckusick register int cc; 76152130Smckusick int s; 76252130Smckusick 76352130Smckusick dp = (struct pdma *)tp->t_addr; 76452130Smckusick dcaddr = dp->p_addr; 76552130Smckusick s = spltty(); 76652130Smckusick if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 76752130Smckusick goto out; 76852130Smckusick if (tp->t_outq.c_cc <= tp->t_lowat) { 76952130Smckusick if (tp->t_state & TS_ASLEEP) { 77052130Smckusick tp->t_state &= ~TS_ASLEEP; 77152130Smckusick wakeup((caddr_t)&tp->t_outq); 77252130Smckusick } 77352674Smckusick selwakeup(&tp->t_wsel); 77452130Smckusick } 77552130Smckusick if (tp->t_outq.c_cc == 0) 77652130Smckusick goto out; 77752130Smckusick /* handle console specially */ 77852130Smckusick if (tp == dc_tty) { 77952130Smckusick while (tp->t_outq.c_cc > 0) { 78052130Smckusick cc = getc(&tp->t_outq) & 0x7f; 78152130Smckusick pmPutc(cc); 78252130Smckusick } 78352130Smckusick /* 78452130Smckusick * After we flush the output queue we may need to wake 78552130Smckusick * up the process that made the output. 78652130Smckusick */ 78752130Smckusick if (tp->t_outq.c_cc <= tp->t_lowat) { 78852130Smckusick if (tp->t_state & TS_ASLEEP) { 78952130Smckusick tp->t_state &= ~TS_ASLEEP; 79052130Smckusick wakeup((caddr_t)&tp->t_outq); 79152130Smckusick } 79252674Smckusick selwakeup(&tp->t_wsel); 79352130Smckusick } 79452130Smckusick goto out; 79552130Smckusick } 79652130Smckusick if (tp->t_flags & (RAW|LITOUT)) 79752130Smckusick cc = ndqb(&tp->t_outq, 0); 79852130Smckusick else { 79952130Smckusick cc = ndqb(&tp->t_outq, 0200); 80052130Smckusick if (cc == 0) { 80152130Smckusick cc = getc(&tp->t_outq); 80252130Smckusick timeout(ttrstrt, (caddr_t)tp, (cc & 0x7f) + 6); 80352130Smckusick tp->t_state |= TS_TIMEOUT; 80452130Smckusick goto out; 80552130Smckusick } 80652130Smckusick } 80752130Smckusick tp->t_state |= TS_BUSY; 80852130Smckusick dp->p_end = dp->p_mem = tp->t_outq.c_cf; 80952130Smckusick dp->p_end += cc; 81052130Smckusick dcaddr->dc_tcr |= 1 << (minor(tp->t_dev) & 03); 81152130Smckusick MachEmptyWriteBuffer(); 81252130Smckusick out: 81352130Smckusick splx(s); 81452130Smckusick } 81552130Smckusick 81652130Smckusick /* 81752130Smckusick * Stop output on a line. 81852130Smckusick */ 81952130Smckusick /*ARGSUSED*/ 82052130Smckusick dcstop(tp, flag) 82152130Smckusick register struct tty *tp; 82252130Smckusick { 82352130Smckusick register struct pdma *dp; 82452130Smckusick register int s; 82552130Smckusick 82652130Smckusick dp = (struct pdma *)tp->t_addr; 82752130Smckusick s = spltty(); 82852130Smckusick if (tp->t_state & TS_BUSY) { 82952130Smckusick dp->p_end = dp->p_mem; 83052130Smckusick if (!(tp->t_state & TS_TTSTOP)) 83152130Smckusick tp->t_state |= TS_FLUSH; 83252130Smckusick } 83352130Smckusick splx(s); 83452130Smckusick } 83552130Smckusick 83652130Smckusick dcmctl(dev, bits, how) 83752130Smckusick dev_t dev; 83852130Smckusick int bits, how; 83952130Smckusick { 84052130Smckusick register dcregs *dcaddr; 84152130Smckusick register int unit, mbits; 84252130Smckusick int b, s; 843*52693Sralph #ifdef DS5000 844*52693Sralph register int msr; 845*52693Sralph #endif 84652130Smckusick 84752130Smckusick unit = minor(dev); 84852130Smckusick b = 1 << (unit & 03); 84952130Smckusick dcaddr = dcpdma[unit].p_addr; 85052130Smckusick s = spltty(); 85152130Smckusick /* only channel 2 has modem control (what about line 3?) */ 852*52693Sralph switch (unit & 03) { 853*52693Sralph case 2: 85452130Smckusick mbits = 0; 85552130Smckusick if (dcaddr->dc_tcr & TCR_DTR2) 85652130Smckusick mbits |= DML_DTR; 857*52693Sralph #ifdef DS3100 85852130Smckusick if (dcaddr->dc_msr & MSR_DSR2) 85952130Smckusick mbits |= DML_DSR | DML_CAR; 860*52693Sralph #endif 861*52693Sralph #ifdef DS5000 862*52693Sralph msr = dcaddr->dc_msr; 863*52693Sralph if (msr & MSR_CD2) 864*52693Sralph mbits |= DML_CAR; 865*52693Sralph if (msr & MSR_DSR2) 866*52693Sralph mbits |= DML_DSR; 867*52693Sralph #endif 868*52693Sralph break; 869*52693Sralph 870*52693Sralph #ifdef DS5000 871*52693Sralph case 3: 872*52693Sralph mbits = 0; 873*52693Sralph if (dcaddr->dc_tcr & TCR_DTR3) 874*52693Sralph mbits |= DML_DTR; 875*52693Sralph msr = dcaddr->dc_msr; 876*52693Sralph if (msr & MSR_CD3) 877*52693Sralph mbits |= DML_CAR; 878*52693Sralph if (msr & MSR_DSR3) 879*52693Sralph mbits |= DML_DSR; 880*52693Sralph break; 881*52693Sralph #endif 882*52693Sralph 883*52693Sralph default: 88452130Smckusick mbits = DML_DTR | DML_DSR | DML_CAR; 885*52693Sralph } 88652130Smckusick switch (how) { 88752130Smckusick case DMSET: 88852130Smckusick mbits = bits; 88952130Smckusick break; 89052130Smckusick 89152130Smckusick case DMBIS: 89252130Smckusick mbits |= bits; 89352130Smckusick break; 89452130Smckusick 89552130Smckusick case DMBIC: 89652130Smckusick mbits &= ~bits; 89752130Smckusick break; 89852130Smckusick 89952130Smckusick case DMGET: 90052130Smckusick (void) splx(s); 90152130Smckusick return (mbits); 90252130Smckusick } 903*52693Sralph switch (unit & 03) { 904*52693Sralph case 2: 90552130Smckusick if (mbits & DML_DTR) 90652130Smckusick dcaddr->dc_tcr |= TCR_DTR2; 90752130Smckusick else 90852130Smckusick dcaddr->dc_tcr &= ~TCR_DTR2; 909*52693Sralph break; 910*52693Sralph 911*52693Sralph #ifdef DS5000 912*52693Sralph case 3: 913*52693Sralph if (mbits & DML_DTR) 914*52693Sralph dcaddr->dc_tcr |= TCR_DTR3; 915*52693Sralph else 916*52693Sralph dcaddr->dc_tcr &= ~TCR_DTR3; 917*52693Sralph #endif 91852130Smckusick } 91952130Smckusick if ((mbits & DML_DTR) && (dcsoftCAR[unit >> 2] & b)) 92052130Smckusick dc_tty[unit].t_state |= TS_CARR_ON; 92152130Smckusick (void) splx(s); 92252130Smckusick return (mbits); 92352130Smckusick } 92452130Smckusick 92552130Smckusick /* 92652130Smckusick * This is called by timeout() periodically. 92752130Smckusick * Check to see if modem status bits have changed. 92852130Smckusick */ 92952130Smckusick dcscan() 93052130Smckusick { 93152130Smckusick register dcregs *dcaddr; 93252130Smckusick register struct tty *tp; 93352130Smckusick register int i, bit, car; 93452130Smckusick int s; 93552130Smckusick 93652130Smckusick s = spltty(); 93752130Smckusick /* only channel 2 has modem control (what about line 3?) */ 93852130Smckusick dcaddr = dcpdma[i = 2].p_addr; 93952130Smckusick tp = &dc_tty[i]; 94052130Smckusick bit = TCR_DTR2; 94152130Smckusick if (dcsoftCAR[i >> 2] & bit) 94252130Smckusick car = 1; 94352130Smckusick else 94452130Smckusick car = dcaddr->dc_msr & MSR_DSR2; 94552130Smckusick if (car) { 94652130Smckusick /* carrier present */ 94752130Smckusick if (!(tp->t_state & TS_CARR_ON)) 94852130Smckusick (void)(*linesw[tp->t_line].l_modem)(tp, 1); 94952130Smckusick } else if ((tp->t_state & TS_CARR_ON) && 95052130Smckusick (*linesw[tp->t_line].l_modem)(tp, 0) == 0) 95152130Smckusick dcaddr->dc_tcr &= ~bit; 95252130Smckusick splx(s); 95352130Smckusick timeout(dcscan, (caddr_t)0, hz); 95452130Smckusick } 95552130Smckusick 95652130Smckusick /* 95752130Smckusick * ---------------------------------------------------------------------------- 95852130Smckusick * 95952130Smckusick * dcKBDPutc -- 96052130Smckusick * 96152130Smckusick * Put a character out to the keyboard. 96252130Smckusick * 96352130Smckusick * Results: 96452130Smckusick * None. 96552130Smckusick * 96652130Smckusick * Side effects: 96752130Smckusick * A character is written to the keyboard. 96852130Smckusick * 96952130Smckusick * ---------------------------------------------------------------------------- 97052130Smckusick */ 97152130Smckusick void 97252130Smckusick dcKBDPutc(c) 97352130Smckusick register int c; 97452130Smckusick { 97552130Smckusick register dcregs *dcaddr; 97652130Smckusick register u_short tcr; 97752130Smckusick register int timeout; 97852130Smckusick int s, line; 97952130Smckusick 98052130Smckusick s = spltty(); 98152130Smckusick 98252130Smckusick dcaddr = dcpdma[KBD_PORT].p_addr; 98352130Smckusick tcr = dcaddr->dc_tcr; 98452130Smckusick dcaddr->dc_tcr = tcr | (1 << KBD_PORT); 98552130Smckusick MachEmptyWriteBuffer(); 98652130Smckusick DELAY(10); 98752130Smckusick while (1) { 98852130Smckusick /* 98952130Smckusick * Wait for transmitter to be not busy. 99052130Smckusick */ 99152130Smckusick timeout = 1000000; 99252130Smckusick while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0) 99352130Smckusick timeout--; 99452130Smckusick if (timeout == 0) { 99552130Smckusick printf("dcKBDPutc: timeout waiting for CSR_TRDY\n"); 99652130Smckusick break; 99752130Smckusick } 99852130Smckusick line = (dcaddr->dc_csr >> 8) & 3; 99952130Smckusick /* 100052130Smckusick * Check to be sure its the right port. 100152130Smckusick */ 100252130Smckusick if (line != KBD_PORT) { 100352130Smckusick tcr |= 1 << line; 100452130Smckusick dcaddr->dc_tcr &= ~(1 << line); 100552130Smckusick MachEmptyWriteBuffer(); 100652130Smckusick DELAY(10); 100752130Smckusick continue; 100852130Smckusick } 100952130Smckusick /* 101052130Smckusick * Start sending the character. 101152130Smckusick */ 101252130Smckusick dcaddr->dc_tdr = dc_brk[0] | (c & 0xff); 101352130Smckusick MachEmptyWriteBuffer(); 101452130Smckusick DELAY(10); 101552130Smckusick /* 101652130Smckusick * Wait for character to be sent. 101752130Smckusick */ 101852130Smckusick while (1) { 101952130Smckusick /* 102052130Smckusick * cc -O bug: this code produces and infinite loop! 102152130Smckusick * while (!(dcaddr->dc_csr & CSR_TRDY)) 102252130Smckusick * ; 102352130Smckusick */ 102452130Smckusick timeout = 1000000; 102552130Smckusick while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0) 102652130Smckusick timeout--; 102752130Smckusick line = (dcaddr->dc_csr >> 8) & 3; 102852130Smckusick if (line != KBD_PORT) { 102952130Smckusick tcr |= 1 << line; 103052130Smckusick dcaddr->dc_tcr &= ~(1 << line); 103152130Smckusick MachEmptyWriteBuffer(); 103252130Smckusick DELAY(10); 103352130Smckusick continue; 103452130Smckusick } 103552130Smckusick dcaddr->dc_tcr &= ~(1 << KBD_PORT); 103652130Smckusick MachEmptyWriteBuffer(); 103752130Smckusick DELAY(10); 103852130Smckusick break; 103952130Smckusick } 104052130Smckusick break; 104152130Smckusick } 104252130Smckusick /* 104352130Smckusick * Enable interrupts for other lines which became ready. 104452130Smckusick */ 104552130Smckusick if (tcr & 0xF) { 104652130Smckusick dcaddr->dc_tcr = tcr; 104752130Smckusick MachEmptyWriteBuffer(); 104852130Smckusick DELAY(10); 104952130Smckusick } 105052130Smckusick 105152130Smckusick splx(s); 105252130Smckusick } 105352130Smckusick 105452130Smckusick #ifdef DEBUG 105552130Smckusick /* 105652130Smckusick * ---------------------------------------------------------------------------- 105752130Smckusick * 1058*52693Sralph * dcDebugGetc -- 105952130Smckusick * 1060*52693Sralph * Read a character from the keyboard if one is ready (i.e., don't wait). 106152130Smckusick * 106252130Smckusick * Results: 106352130Smckusick * A character read from the mouse, -1 if none were ready. 106452130Smckusick * 106552130Smckusick * Side effects: 106652130Smckusick * None. 106752130Smckusick * 106852130Smckusick * ---------------------------------------------------------------------------- 106952130Smckusick */ 107052130Smckusick int 1071*52693Sralph dcDebugGetc() 107252130Smckusick { 107352130Smckusick register dcregs *dcaddr; 107452130Smckusick register int c; 107552130Smckusick 107652130Smckusick dcaddr = dcpdma[KBD_PORT].p_addr; 107752130Smckusick if (!dcaddr) 107852130Smckusick return (0); 107952130Smckusick if (c = debugChar) 108052130Smckusick debugChar = 0; 108152130Smckusick else { 108252130Smckusick while (dcaddr->dc_csr & CSR_RDONE) { 108352130Smckusick c = dcaddr->dc_rbuf; 108452130Smckusick DELAY(10); 108552130Smckusick if (((c >> 8) & 03) == KBD_PORT) 108652130Smckusick break; 108752130Smckusick c = 0; 108852130Smckusick } 108952130Smckusick } 109052130Smckusick return (c & 0xff); 109152130Smckusick } 109252130Smckusick #endif 109352130Smckusick 109452130Smckusick /* 109552130Smckusick * ---------------------------------------------------------------------------- 109652130Smckusick * 1097*52693Sralph * dcKBDGetc -- 1098*52693Sralph * 1099*52693Sralph * Read a character from the keyboard. 1100*52693Sralph * 1101*52693Sralph * Results: 1102*52693Sralph * A character read from the keyboard. 1103*52693Sralph * 1104*52693Sralph * Side effects: 1105*52693Sralph * None. 1106*52693Sralph * 1107*52693Sralph * ---------------------------------------------------------------------------- 1108*52693Sralph */ 1109*52693Sralph int 1110*52693Sralph dcKBDGetc() 1111*52693Sralph { 1112*52693Sralph register dcregs *dcaddr; 1113*52693Sralph register int c; 1114*52693Sralph int s; 1115*52693Sralph 1116*52693Sralph dcaddr = dcpdma[KBD_PORT].p_addr; 1117*52693Sralph if (!dcaddr) 1118*52693Sralph return (-1); 1119*52693Sralph s = spltty(); 1120*52693Sralph for (;;) { 1121*52693Sralph if (!(dcaddr->dc_csr & CSR_RDONE)) 1122*52693Sralph continue; 1123*52693Sralph c = dcaddr->dc_rbuf; 1124*52693Sralph DELAY(10); 1125*52693Sralph if (((c >> 8) & 03) != KBD_PORT) 1126*52693Sralph continue; 1127*52693Sralph if ((c = dcMapChar(c & 0xff)) >= 0) 1128*52693Sralph break; 1129*52693Sralph } 1130*52693Sralph splx(s); 1131*52693Sralph return (c); 1132*52693Sralph } 1133*52693Sralph 1134*52693Sralph /* 1135*52693Sralph * ---------------------------------------------------------------------------- 1136*52693Sralph * 1137*52693Sralph * dcMapChar -- 1138*52693Sralph * 1139*52693Sralph * Map characters from the keyboard to ASCII. Return -1 if there is 1140*52693Sralph * no valid mapping. 1141*52693Sralph * 1142*52693Sralph * Results: 1143*52693Sralph * None. 1144*52693Sralph * 1145*52693Sralph * Side effects: 1146*52693Sralph * Remember state of shift and control keys. 1147*52693Sralph * 1148*52693Sralph * ---------------------------------------------------------------------------- 1149*52693Sralph */ 1150*52693Sralph static int 1151*52693Sralph dcMapChar(cc) 1152*52693Sralph int cc; 1153*52693Sralph { 1154*52693Sralph static u_char shiftDown; 1155*52693Sralph static u_char ctrlDown; 1156*52693Sralph static u_char lastChar; 1157*52693Sralph 1158*52693Sralph switch (cc) { 1159*52693Sralph case KEY_REPEAT: 1160*52693Sralph cc = lastChar; 1161*52693Sralph goto done; 1162*52693Sralph 1163*52693Sralph case KEY_UP: 1164*52693Sralph shiftDown = 0; 1165*52693Sralph ctrlDown = 0; 1166*52693Sralph return (-1); 1167*52693Sralph 1168*52693Sralph case KEY_SHIFT: 1169*52693Sralph if (ctrlDown) 1170*52693Sralph shiftDown = 0; 1171*52693Sralph else 1172*52693Sralph shiftDown = 1; 1173*52693Sralph return (-1); 1174*52693Sralph 1175*52693Sralph case KEY_CONTROL: 1176*52693Sralph if (shiftDown) 1177*52693Sralph ctrlDown = 0; 1178*52693Sralph else 1179*52693Sralph ctrlDown = 1; 1180*52693Sralph return (-1); 1181*52693Sralph 1182*52693Sralph case LK_POWER_ERROR: 1183*52693Sralph case LK_KDOWN_ERROR: 1184*52693Sralph case LK_INPUT_ERROR: 1185*52693Sralph case LK_OUTPUT_ERROR: 1186*52693Sralph log(LOG_WARNING, 1187*52693Sralph "dc0,0: keyboard error, code=%x\n", cc); 1188*52693Sralph return (-1); 1189*52693Sralph } 1190*52693Sralph if (shiftDown) 1191*52693Sralph cc = shiftedAscii[cc]; 1192*52693Sralph else 1193*52693Sralph cc = unshiftedAscii[cc]; 1194*52693Sralph if (cc >= KBD_NOKEY) { 1195*52693Sralph /* 1196*52693Sralph * A function key was typed - ignore it. 1197*52693Sralph */ 1198*52693Sralph return (-1); 1199*52693Sralph } 1200*52693Sralph if (cc >= 'a' && cc <= 'z') { 1201*52693Sralph if (ctrlDown) 1202*52693Sralph cc = cc - 'a' + '\1'; /* ^A */ 1203*52693Sralph else if (shiftDown) 1204*52693Sralph cc = cc - 'a' + 'A'; 1205*52693Sralph } else if (ctrlDown) { 1206*52693Sralph if (cc >= '[' && cc <= '_') 1207*52693Sralph cc = cc - '@'; 1208*52693Sralph else if (cc == ' ' || cc == '@') 1209*52693Sralph cc = '\0'; 1210*52693Sralph } 1211*52693Sralph lastChar = cc; 1212*52693Sralph done: 1213*52693Sralph return (cc); 1214*52693Sralph } 1215*52693Sralph 1216*52693Sralph /* 1217*52693Sralph * ---------------------------------------------------------------------------- 1218*52693Sralph * 121952130Smckusick * dcKBDReset -- 122052130Smckusick * 122152130Smckusick * Reset the keyboard to default characteristics. 122252130Smckusick * 122352130Smckusick * Results: 122452130Smckusick * None. 122552130Smckusick * 122652130Smckusick * Side effects: 122752130Smckusick * None. 122852130Smckusick * 122952130Smckusick * ---------------------------------------------------------------------------- 123052130Smckusick */ 123152130Smckusick void 123252130Smckusick dcKBDReset() 123352130Smckusick { 123452130Smckusick register int i; 123552130Smckusick static int inKBDReset; 123652130Smckusick 123752130Smckusick if (inKBDReset) 123852130Smckusick return; 123952130Smckusick inKBDReset = 1; 124052130Smckusick for (i = 0; i < sizeof(kbdInitString); i++) 124152130Smckusick dcKBDPutc((int)kbdInitString[i]); 124252130Smckusick inKBDReset = 0; 124352130Smckusick } 124452130Smckusick 124552130Smckusick /* 124652130Smckusick * ---------------------------------------------------------------------------- 124752130Smckusick * 124852130Smckusick * MousePutc -- 124952130Smckusick * 125052130Smckusick * Write a character to the mouse. 125152130Smckusick * This is only called at initialization time. 125252130Smckusick * 125352130Smckusick * Results: 125452130Smckusick * None. 125552130Smckusick * 125652130Smckusick * Side effects: 125752130Smckusick * A character is written to the mouse. 125852130Smckusick * 125952130Smckusick * ---------------------------------------------------------------------------- 126052130Smckusick */ 126152130Smckusick static void 126252130Smckusick MousePutc(c) 126352130Smckusick int c; 126452130Smckusick { 126552130Smckusick register dcregs *dcaddr; 126652130Smckusick register u_short tcr; 126752130Smckusick register int timeout; 126852130Smckusick int line; 126952130Smckusick 127052130Smckusick dcaddr = dcpdma[MOUSE_PORT].p_addr; 127152130Smckusick tcr = dcaddr->dc_tcr; 127252130Smckusick dcaddr->dc_tcr = tcr | (1 << MOUSE_PORT); 127352130Smckusick MachEmptyWriteBuffer(); 127452130Smckusick DELAY(10); 127552130Smckusick while (1) { 127652130Smckusick /* 127752130Smckusick * Wait for transmitter to be not busy. 127852130Smckusick */ 127952130Smckusick timeout = 1000000; 128052130Smckusick while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0) 128152130Smckusick timeout--; 128252130Smckusick if (timeout == 0) { 128352130Smckusick printf("MousePutc: timeout waiting for CSR_TRDY\n"); 128452130Smckusick break; 128552130Smckusick } 128652130Smckusick line = (dcaddr->dc_csr >> 8) & 3; 128752130Smckusick /* 128852130Smckusick * Check to be sure its the right port. 128952130Smckusick */ 129052130Smckusick if (line != MOUSE_PORT) { 129152130Smckusick tcr |= 1 << line; 129252130Smckusick dcaddr->dc_tcr &= ~(1 << line); 129352130Smckusick MachEmptyWriteBuffer(); 129452130Smckusick DELAY(10); 129552130Smckusick continue; 129652130Smckusick } 129752130Smckusick /* 129852130Smckusick * Start sending the character. 129952130Smckusick */ 130052130Smckusick dcaddr->dc_tdr = dc_brk[0] | (c & 0xff); 130152130Smckusick MachEmptyWriteBuffer(); 130252130Smckusick DELAY(10); 130352130Smckusick /* 130452130Smckusick * Wait for character to be sent. 130552130Smckusick */ 130652130Smckusick while (1) { 130752130Smckusick /* 130852130Smckusick * cc -O bug: this code produces and infinite loop! 130952130Smckusick * while (!(dcaddr->dc_csr & CSR_TRDY)) 131052130Smckusick * ; 131152130Smckusick */ 131252130Smckusick timeout = 1000000; 131352130Smckusick while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0) 131452130Smckusick timeout--; 131552130Smckusick line = (dcaddr->dc_csr >> 8) & 3; 131652130Smckusick if (line != MOUSE_PORT) { 131752130Smckusick tcr |= 1 << line; 131852130Smckusick dcaddr->dc_tcr &= ~(1 << line); 131952130Smckusick MachEmptyWriteBuffer(); 132052130Smckusick DELAY(10); 132152130Smckusick continue; 132252130Smckusick } 132352130Smckusick dcaddr->dc_tcr &= ~(1 << MOUSE_PORT); 132452130Smckusick MachEmptyWriteBuffer(); 132552130Smckusick DELAY(10); 132652130Smckusick break; 132752130Smckusick } 132852130Smckusick break; 132952130Smckusick } 133052130Smckusick /* 133152130Smckusick * Enable interrupts for other lines which became ready. 133252130Smckusick */ 133352130Smckusick if (tcr & 0xF) { 133452130Smckusick dcaddr->dc_tcr = tcr; 133552130Smckusick MachEmptyWriteBuffer(); 133652130Smckusick DELAY(10); 133752130Smckusick } 133852130Smckusick } 133952130Smckusick 134052130Smckusick /* 134152130Smckusick * ---------------------------------------------------------------------------- 134252130Smckusick * 134352130Smckusick * MouseGetc -- 134452130Smckusick * 134552130Smckusick * Read a character from the mouse. 134652130Smckusick * This is only called at initialization time. 134752130Smckusick * 134852130Smckusick * Results: 134952130Smckusick * A character read from the mouse, -1 if we timed out waiting. 135052130Smckusick * 135152130Smckusick * Side effects: 135252130Smckusick * None. 135352130Smckusick * 135452130Smckusick * ---------------------------------------------------------------------------- 135552130Smckusick */ 135652130Smckusick static int 135752130Smckusick MouseGetc() 135852130Smckusick { 135952130Smckusick register dcregs *dcaddr; 136052130Smckusick register int timeout; 136152130Smckusick register int c; 136252130Smckusick 136352130Smckusick dcaddr = dcpdma[MOUSE_PORT].p_addr; 136452130Smckusick for (timeout = 1000000; timeout > 0; timeout--) { 136552130Smckusick if (!(dcaddr->dc_csr & CSR_RDONE)) 136652130Smckusick continue; 136752130Smckusick c = dcaddr->dc_rbuf; 136852130Smckusick DELAY(10); 136952130Smckusick if (((c >> 8) & 03) != MOUSE_PORT) 137052130Smckusick continue; 137152130Smckusick return (c & 0xff); 137252130Smckusick } 137352130Smckusick 137452130Smckusick return (-1); 137552130Smckusick } 137652130Smckusick 137752130Smckusick /* 137852130Smckusick * ---------------------------------------------------------------------------- 137952130Smckusick * 138052130Smckusick * MouseInit -- 138152130Smckusick * 138252130Smckusick * Initialize the mouse. 138352130Smckusick * 138452130Smckusick * Results: 138552130Smckusick * None. 138652130Smckusick * 138752130Smckusick * Side effects: 138852130Smckusick * None. 138952130Smckusick * 139052130Smckusick * ---------------------------------------------------------------------------- 139152130Smckusick */ 139252130Smckusick static void 139352130Smckusick MouseInit() 139452130Smckusick { 139552130Smckusick int id_byte1, id_byte2, id_byte3, id_byte4; 139652130Smckusick 139752130Smckusick /* 139852130Smckusick * Initialize the mouse. 139952130Smckusick */ 140052130Smckusick MousePutc(MOUSE_SELF_TEST); 140152130Smckusick id_byte1 = MouseGetc(); 140252130Smckusick if (id_byte1 < 0) { 140352130Smckusick printf("MouseInit: Timeout on 1st byte of self-test report\n"); 140452130Smckusick return; 140552130Smckusick } 140652130Smckusick id_byte2 = MouseGetc(); 140752130Smckusick if (id_byte2 < 0) { 140852130Smckusick printf("MouseInit: Timeout on 2nd byte of self-test report\n"); 140952130Smckusick return; 141052130Smckusick } 141152130Smckusick id_byte3 = MouseGetc(); 141252130Smckusick if (id_byte3 < 0) { 141352130Smckusick printf("MouseInit: Timeout on 3rd byte of self-test report\n"); 141452130Smckusick return; 141552130Smckusick } 141652130Smckusick id_byte4 = MouseGetc(); 141752130Smckusick if (id_byte4 < 0) { 141852130Smckusick printf("MouseInit: Timeout on 4th byte of self-test report\n"); 141952130Smckusick return; 142052130Smckusick } 142152130Smckusick if ((id_byte2 & 0x0f) != 0x2) 142252130Smckusick printf("MouseInit: We don't have a mouse!!!\n"); 142352130Smckusick /* 142452130Smckusick * For some reason, the mouse doesn't see this command if it comes 142552130Smckusick * too soon after a self test. 142652130Smckusick */ 142752130Smckusick DELAY(100); 142852130Smckusick MousePutc(MOUSE_INCREMENTAL); 142952130Smckusick } 143052130Smckusick #endif /* NDC */ 1431