📄 dc.c
字号:
/*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Ralph Campbell and Rick Macklem. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)dc.c 8.2 (Berkeley) 11/30/93 *//* * devDC7085.c -- * * This file contains machine-dependent routines that handle the * output queue for the serial lines. * * Copyright (C) 1989 Digital Equipment Corporation. * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appears in all copies. * Digital Equipment Corporation makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devDC7085.c, * v 1.4 89/08/29 11:55:30 nelson Exp $ SPRITE (DECWRL)"; */#include <dc.h>#if NDC > 0/* * DC7085 (DZ-11 look alike) Driver */#include <sys/param.h>#include <sys/systm.h>#include <sys/ioctl.h>#include <sys/tty.h>#include <sys/proc.h>#include <sys/map.h>#include <sys/buf.h>#include <sys/conf.h>#include <sys/file.h>#include <sys/uio.h>#include <sys/kernel.h>#include <sys/syslog.h>#include <machine/dc7085cons.h>#include <machine/pmioctl.h>#include <pmax/pmax/pmaxtype.h>#include <pmax/pmax/cons.h>#include <pmax/dev/device.h>#include <pmax/dev/pdma.h>#include <pmax/dev/fbreg.h>extern int pmax_boardtype;extern struct consdev cn_tab;/* * Driver information for auto-configuration stuff. */int dcprobe();void dcintr();struct driver dcdriver = { "dc", dcprobe, 0, 0, dcintr,};#define NDCLINE (NDC*4)void dcstart __P((struct tty *));void dcxint __P((struct tty *));void dcPutc __P((dev_t, int));void dcscan __P((void *));extern void ttrstrt __P((void *));int dcGetc __P((dev_t));int dcparam __P((struct tty *, struct termios *));struct tty dc_tty[NDCLINE];int dc_cnt = NDCLINE;void (*dcDivertXInput)(); /* X windows keyboard input routine */void (*dcMouseEvent)(); /* X windows mouse motion event routine */void (*dcMouseButtons)(); /* X windows mouse buttons event routine */#ifdef DEBUGint debugChar;#endif/* * Software copy of brk register since it isn't readable */int dc_brk[NDC];char dcsoftCAR[NDC]; /* mask of dc's with carrier on (DSR) *//* * The DC7085 doesn't interrupt on carrier transitions, so * we have to use a timer to watch it. */int dc_timer; /* true if timer started *//* * Pdma structures for fast output code */struct pdma dcpdma[NDCLINE];struct speedtab dcspeedtab[] = { 0, 0, 50, LPR_B50, 75, LPR_B75, 110, LPR_B110, 134, LPR_B134, 150, LPR_B150, 300, LPR_B300, 600, LPR_B600, 1200, LPR_B1200, 1800, LPR_B1800, 2400, LPR_B2400, 4800, LPR_B4800, 9600, LPR_B9600, 19200, LPR_B19200, -1, -1};#ifndef PORTSELECTOR#define ISPEED TTYDEF_SPEED#define LFLAG TTYDEF_LFLAG#else#define ISPEED B4800#define LFLAG (TTYDEF_LFLAG & ~ECHO)#endif/* * Test to see if device is present. * Return true if found and initialized ok. */dcprobe(cp) register struct pmax_ctlr *cp;{ register dcregs *dcaddr; register struct pdma *pdp; register struct tty *tp; register int cntr; int s; if (cp->pmax_unit >= NDC) return (0); if (badaddr(cp->pmax_addr, 2)) return (0); /* * For a remote console, wait a while for previous output to * complete. */ if (major(cn_tab.cn_dev) == DCDEV && cp->pmax_unit == 0 && cn_tab.cn_screen == 0) DELAY(10000); /* reset chip */ dcaddr = (dcregs *)cp->pmax_addr; dcaddr->dc_csr = CSR_CLR; MachEmptyWriteBuffer(); while (dcaddr->dc_csr & CSR_CLR) ; dcaddr->dc_csr = CSR_MSE | CSR_TIE | CSR_RIE; /* init pseudo DMA structures */ pdp = &dcpdma[cp->pmax_unit * 4]; tp = &dc_tty[cp->pmax_unit * 4]; for (cntr = 0; cntr < 4; cntr++) { pdp->p_addr = (void *)dcaddr; pdp->p_arg = (int)tp; pdp->p_fcn = dcxint; pdp++, tp++; } dcsoftCAR[cp->pmax_unit] = cp->pmax_flags | 0xB; if (dc_timer == 0) { dc_timer = 1; timeout(dcscan, (void *)0, hz); } /* * Special handling for consoles. */ if (cp->pmax_unit == 0) { if (cn_tab.cn_screen) { s = spltty(); dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR | LPR_B4800 | DCKBD_PORT; MachEmptyWriteBuffer(); dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR | LPR_PARENB | LPR_8_BIT_CHAR | DCMOUSE_PORT; MachEmptyWriteBuffer(); DELAY(1000); KBDReset(makedev(DCDEV, DCKBD_PORT), dcPutc); MouseInit(makedev(DCDEV, DCMOUSE_PORT), dcPutc, dcGetc); splx(s); } else if (major(cn_tab.cn_dev) == DCDEV) { s = spltty(); dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR | LPR_B9600 | minor(cn_tab.cn_dev); MachEmptyWriteBuffer(); DELAY(1000); cn_tab.cn_disabled = 0; splx(s); } } printf("dc%d at nexus0 csr 0x%x priority %d\n", cp->pmax_unit, cp->pmax_addr, cp->pmax_pri); return (1);}dcopen(dev, flag, mode, p) dev_t dev; int flag, mode; struct proc *p;{ register struct tty *tp; register int unit; int s, error = 0; unit = minor(dev); if (unit >= dc_cnt || dcpdma[unit].p_addr == (void *)0) return (ENXIO); tp = &dc_tty[unit]; tp->t_oproc = dcstart; tp->t_param = dcparam; tp->t_dev = dev; if ((tp->t_state & TS_ISOPEN) == 0) { tp->t_state |= TS_WOPEN; ttychars(tp);#ifndef PORTSELECTOR if (tp->t_ispeed == 0) {#endif tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; tp->t_lflag = LFLAG; tp->t_ispeed = tp->t_ospeed = ISPEED;#ifdef PORTSELECTOR tp->t_cflag |= HUPCL;#else }#endif (void) dcparam(tp, &tp->t_termios); ttsetwater(tp); } else if ((tp->t_state & TS_XCLUDE) && curproc->p_ucred->cr_uid != 0) return (EBUSY); (void) dcmctl(dev, DML_DTR, DMSET); s = spltty(); while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) && !(tp->t_state & TS_CARR_ON)) { tp->t_state |= TS_WOPEN; if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, ttopen, 0)) break; } splx(s); if (error) return (error); return ((*linesw[tp->t_line].l_open)(dev, tp));}/*ARGSUSED*/dcclose(dev, flag, mode, p) dev_t dev; int flag, mode; struct proc *p;{ register struct tty *tp; register int unit, bit; unit = minor(dev); tp = &dc_tty[unit]; bit = 1 << ((unit & 03) + 8); if (dc_brk[unit >> 2] & bit) { dc_brk[unit >> 2] &= ~bit; ttyoutput(0, tp); } (*linesw[tp->t_line].l_close)(tp, flag); if ((tp->t_cflag & HUPCL) || (tp->t_state & TS_WOPEN) || !(tp->t_state & TS_ISOPEN)) (void) dcmctl(dev, 0, DMSET); return (ttyclose(tp));}dcread(dev, uio, flag) dev_t dev; struct uio *uio;{ register struct tty *tp; tp = &dc_tty[minor(dev)]; return ((*linesw[tp->t_line].l_read)(tp, uio, flag));}dcwrite(dev, uio, flag) dev_t dev; struct uio *uio;{ register struct tty *tp; tp = &dc_tty[minor(dev)]; return ((*linesw[tp->t_line].l_write)(tp, uio, flag));}/*ARGSUSED*/dcioctl(dev, cmd, data, flag, p) dev_t dev; int cmd; caddr_t data; int flag; struct proc *p;{ register struct tty *tp; register int unit = minor(dev); register int dc = unit >> 2; int error; tp = &dc_tty[unit]; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); if (error >= 0) return (error); error = ttioctl(tp, cmd, data, flag); if (error >= 0) return (error); switch (cmd) { case TIOCSBRK: dc_brk[dc] |= 1 << ((unit & 03) + 8); ttyoutput(0, tp); break; case TIOCCBRK: dc_brk[dc] &= ~(1 << ((unit & 03) + 8)); ttyoutput(0, tp); break; case TIOCSDTR: (void) dcmctl(dev, DML_DTR|DML_RTS, DMBIS); break; case TIOCCDTR: (void) dcmctl(dev, DML_DTR|DML_RTS, DMBIC); break; case TIOCMSET: (void) dcmctl(dev, *(int *)data, DMSET); break; case TIOCMBIS: (void) dcmctl(dev, *(int *)data, DMBIS); break; case TIOCMBIC: (void) dcmctl(dev, *(int *)data, DMBIC); break; case TIOCMGET: *(int *)data = dcmctl(dev, 0, DMGET); break; default: return (ENOTTY); } return (0);}dcparam(tp, t) register struct tty *tp; register struct termios *t;{ register dcregs *dcaddr; register int lpr; register int cflag = t->c_cflag; int unit = minor(tp->t_dev); int ospeed = ttspeedtab(t->c_ospeed, dcspeedtab); /* check requested parameters */ if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) || (cflag & CSIZE) == CS5 || (cflag & CSIZE) == CS6 || (pmax_boardtype == DS_PMAX && t->c_ospeed == 19200)) return (EINVAL); /* and copy to tty */ tp->t_ispeed = t->c_ispeed; tp->t_ospeed = t->c_ospeed; tp->t_cflag = cflag; dcaddr = (dcregs *)dcpdma[unit].p_addr; /* * Handle console cases specially. */ if (cn_tab.cn_screen) { if (unit == DCKBD_PORT) { dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR | LPR_B4800 | DCKBD_PORT; MachEmptyWriteBuffer(); return (0); } else if (unit == DCMOUSE_PORT) { dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR | LPR_PARENB | LPR_8_BIT_CHAR | DCMOUSE_PORT; MachEmptyWriteBuffer(); return (0); } } else if (tp->t_dev == cn_tab.cn_dev) { dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR | LPR_B9600 | unit; MachEmptyWriteBuffer(); return (0); } if (ospeed == 0) { (void) dcmctl(unit, 0, DMSET); /* hang up line */ return (0); } lpr = LPR_RXENAB | ospeed | (unit & 03); if ((cflag & CSIZE) == CS7) lpr |= LPR_7_BIT_CHAR; else lpr |= LPR_8_BIT_CHAR; if (cflag & PARENB) lpr |= LPR_PARENB; if (cflag & PARODD) lpr |= LPR_OPAR; if (cflag & CSTOPB) lpr |= LPR_2_STOP; dcaddr->dc_lpr = lpr; MachEmptyWriteBuffer(); DELAY(10); return (0);}/* * Check for interrupts from all devices. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -