diff options
Diffstat (limited to 'sys/arch/vax/vsa/dc.c')
-rw-r--r-- | sys/arch/vax/vsa/dc.c | 1024 |
1 files changed, 0 insertions, 1024 deletions
diff --git a/sys/arch/vax/vsa/dc.c b/sys/arch/vax/vsa/dc.c deleted file mode 100644 index 1e2e9e7ca19..00000000000 --- a/sys/arch/vax/vsa/dc.c +++ /dev/null @@ -1,1024 +0,0 @@ -/* $OpenBSD: dc.c,v 1.11 2004/09/19 21:34:42 mickey Exp $ */ -/* $NetBSD: dc.c,v 1.4 1996/10/13 03:36:10 christos Exp $ */ -/*- - * 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. 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 - * - * bertram 13-apr-1996: slightly modified for DC367B in VS2000 - */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/ioctl.h> -#include <sys/tty.h> -#include <sys/proc.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 <sys/timeout.h> - -/* - * bertram 17-apr-1996: we could use most of the include files directly - * from the pmax port, only some of the paddings need - * to be changed. For now we use modified copies... - * - * #include <pmax/include/dc7085cons.h> - * #include <pmax/include/pmioctl.h> - * - * #include <pmax/dev/pdma.h> - * #include <pmax/dev/lk201.h> - */ -#include "dc7085cons.h" /* this one is modified !!! */ -#include <pmax/include/pmioctl.h> -#include <pmax/dev/pdma.h> -#include <pmax/dev/lk201.h> - -#include <sys/device.h> - -/* - * here follow some pmax specific includes which we don't need... - */ -#ifdef pmax -#include <machine/autoconf.h> -#include <machine/machConst.h> -#include <pmax/pmax/pmaxtype.h> -#include <pmax/pmax/cons.h> -#endif - -#ifdef vax -#include <machine/sid.h> -#include <machine/uvax.h> -#include <machine/vsbus.h> -#include <pmax/pmax/cons.h> /* we need to modify this for VAXen */ -#define MachEmptyWriteBuffer() /* we don't need this for VAXstation */ -#endif - -#include <pmax/dev/dcvar.h> - -struct dc_softc { - struct device sc_dv; - struct pdma dc_pdma[4]; - void *xmit_cfargs; - void *recv_cfargs; -}; - -/* - * Autoconfiguration data for config. - * - * Use the statically-allocated softc until old autoconfig code and - * config.old are completely gone. - */ -int dcmatch(struct device * parent, void *cfdata, void *aux); -void dcattach(struct device *parent, struct device *self, void *aux); - -int dc_doprobe(void *addr, int unit, int flags, int pri); -int dcintr(void * xxxunit); - -struct cfdriver dc_cd = { - NULL, "dc", DV_TTY -}; -struct cfattach dc_ca = { - sizeof(struct dc_softc), dcmatch, dcattach -}; - - -#define NDCLINE (NDC*4) - -void dcstart(struct tty *); -void dcxint(struct tty *); -void dcPutc(dev_t, int); -void dcscan(void *); -int dcGetc(dev_t); -int dcparam(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 DEBUG -int 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 */ -struct timeout dc_timeout; - -/* - * Pdma structures for fast output code - */ -struct pdma dcpdma[NDCLINE]; - -const 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 - -static struct { - void *xmit_cfargs; - void *recv_cfargs; -} vs2000_hack = { NULL, NULL }; - -/* - * Match driver based on name - */ -int -dcmatch(parent, match, aux) - struct device *parent; - void *match; - void *aux; -{ - struct cfdata *cf = match; - struct confargs *ca = aux; - - static int nunits = 0; - - return (0); - - if (strcmp(ca->ca_name, "dc") != 0 && - strcmp(ca->ca_name, "mdc") != 0 && - strcmp(ca->ca_name, "dc367") != 0 && - strcmp(ca->ca_name, "dc7085") != 0) - return (0); - - /* - * Use statically-allocated softc and attach code until - * old config is completely gone. Don't over-run softc. - */ - if (nunits > NDC) { - printf("dc: too many units for old config\n"); - return (0); - } - nunits++; - return (1); -} - -void -dcattach(parent, self, aux) - struct device *parent; - struct device *self; - void *aux; -{ - register struct confargs *ca = aux; - u_long dcaddr; - - dcaddr = (u_long)ca->ca_ioaddr; - (void) dc_doprobe((void *)uvax_phys2virt(dcaddr), - self->dv_unit, self->dv_cfdata->cf_flags, - ca->ca_intslot); - - /* tie pseudo-slot to device */ -#ifdef notyet - vsbus_intr_register(ca, dcintr, self); - vsbus_intr_enable(ca); -#endif - printf("\n"); -} - -/* - * Is there a framebuffer console device using this serial driver? - * XXX used for ugly special-cased console input that should be redone - * more cleanly. - */ -static inline int -raster_console() -{ - return (cn_tab->cn_pri == CN_INTERNAL || - cn_tab->cn_pri == CN_NORMAL); -} - - -/* - * DC7085 (dz-11) probe routine from old-style config. - * This is only here out of inertia. - */ -int -dc_doprobe(addr, unit, flags, priority) - void *addr; - int unit, flags, priority; -{ - register dcregs *dcaddr; - register struct pdma *pdp; - register struct tty *tp; - register int cntr; - int s; - - if (unit >= NDC) - return (0); - if (badaddr(addr, 2)) - return (0); - - /* - * For a remote console, wait a while for previous output to - * complete. - */ - if (major(cn_tab->cn_dev) == DCDEV && unit == 0 && - cn_tab->cn_pri == CN_REMOTE) - DELAY(10000); - - /* reset chip */ - dcaddr = (dcregs *)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[unit * 4]; - for (cntr = 0; cntr < 4; cntr++) { - pdp->p_addr = (void *)dcaddr; - tp = dc_tty[unit * 4 + cntr] = ttymalloc(); - pdp->p_arg = (int) tp; - pdp->p_fcn = dcxint; - pdp++; - } - dcsoftCAR[unit] = flags | 0xB; - - if (dc_timer == 0) { - dc_timer = 1; - timeout_set(&dc_timeout, dcscan, NULL); - timeout_add(&dc_timeout, hz); - } - - /* - * Special handling for consoles. - */ - if (unit == 0) { - if (cn_tab->cn_pri == CN_INTERNAL || - cn_tab->cn_pri == CN_NORMAL) { - 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;*/ /* FIXME */ - splx(s); - } - } - - 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]; - if (tp == NULL) - tp = dc_tty[unit] = ttymalloc(); - 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)); -} - -struct tty * -dctty(dev) - dev_t dev; -{ - struct tty *tp = dc_tty [minor (dev)]; - return (tp); -} - -/*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, p); - 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 || - (vax_boardtype == -1 && 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 (raster_console()) { - 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. - */ -int -dcintr(xxxunit) - void *xxxunit; -{ - register struct dc_softc *sc = xxxunit; - register dcregs *dcaddr; - register unsigned csr; - - register int unit = sc->sc_dv.dv_unit; - - unit <<= 2; - dcaddr = (dcregs *)dcpdma[unit].p_addr; - while ((csr = dcaddr->dc_csr) & (CSR_RDONE | CSR_TRDY)) { - if (csr & CSR_RDONE) - dcrint(unit); - if (csr & CSR_TRDY) - dcxint(dc_tty[unit + ((csr >> 8) & 03)]); - } - /* XXX check for spurious interrupts */ - return 0; -} - -dcrint(unit) - register int unit; -{ - register dcregs *dcaddr; - register struct tty *tp; - register int c, cc; - int overrun = 0; - - dcaddr = (dcregs *)dcpdma[unit].p_addr; - while ((c = dcaddr->dc_rbuf) < 0) { /* char present */ - cc = c & 0xff; - tp = dc_tty[unit + ((c >> 8) & 03)]; - if ((c & RBUF_OERR) && overrun == 0) { - log(LOG_WARNING, "dc%d,%d: silo overflow\n", unit >> 2, - (c >> 8) & 03); - overrun = 1; - } - /* the keyboard requires special translation */ - if (tp == dc_tty[DCKBD_PORT] && raster_console()) { -#ifdef KADB - if (cc == LK_DO) { - spl0(); - kdbpanic(); - return; - } -#endif -#ifdef DEBUG - debugChar = cc; -#endif - if (dcDivertXInput) { - (*dcDivertXInput)(cc); - return; - } - if ((cc = kbdMapChar(cc)) < 0) - return; -#ifdef notyet - } else if (tp == dc_tty[DCMOUSE_PORT] && dcMouseButtons) { - mouseInput(cc); - return; -#endif - } - if (!(tp->t_state & TS_ISOPEN)) { - wakeup((caddr_t)&tp->t_rawq); -#ifdef PORTSELECTOR - if (!(tp->t_state & TS_WOPEN)) -#endif - return; - } - if (c & RBUF_FERR) - cc |= TTY_FE; - if (c & RBUF_PERR) - cc |= TTY_PE; - (*linesw[tp->t_line].l_rint)(cc, tp); - } - DELAY(10); -} - -void -dcxint(tp) - register struct tty *tp; -{ - register struct pdma *dp; - register dcregs *dcaddr; - int unit = minor(tp->t_dev); - - dp = &dcpdma[unit]; - if (dp->p_mem < dp->p_end) { - dcaddr = (dcregs *)dp->p_addr; - dcaddr->dc_tdr = dc_brk[unit >> 2] | *dp->p_mem++; - MachEmptyWriteBuffer(); - DELAY(10); - return; - } - tp->t_state &= ~TS_BUSY; - if (tp->t_state & TS_FLUSH) - tp->t_state &= ~TS_FLUSH; - else { - ndflush(&tp->t_outq, dp->p_mem - (caddr_t) tp->t_outq.c_cf); - dp->p_end = dp->p_mem = tp->t_outq.c_cf; - } - if (tp->t_line) - (*linesw[tp->t_line].l_start)(tp); - else - dcstart(tp); - if (tp->t_outq.c_cc == 0 || !(tp->t_state & TS_BUSY)) { - dcaddr = (dcregs *)dp->p_addr; - dcaddr->dc_tcr &= ~(1 << (unit & 03)); - MachEmptyWriteBuffer(); - DELAY(10); - } -} - -void -dcstart(tp) - register struct tty *tp; -{ - register struct pdma *dp; - register dcregs *dcaddr; - register int cc; - int s; - - dp = &dcpdma[minor(tp->t_dev)]; - dcaddr = (dcregs *)dp->p_addr; - s = spltty(); - if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) - goto out; - if (tp->t_outq.c_cc <= tp->t_lowat) { - if (tp->t_state & TS_ASLEEP) { - tp->t_state &= ~TS_ASLEEP; - wakeup((caddr_t)&tp->t_outq); - } - selwakeup(&tp->t_wsel); - } - if (tp->t_outq.c_cc == 0) - goto out; - /* handle console specially */ - if (tp == dc_tty[DCKBD_PORT] && raster_console()) { - while (tp->t_outq.c_cc > 0) { - cc = getc(&tp->t_outq) & 0x7f; - cnputc(cc); - } - /* - * After we flush the output queue we may need to wake - * up the process that made the output. - */ - if (tp->t_outq.c_cc <= tp->t_lowat) { - if (tp->t_state & TS_ASLEEP) { - tp->t_state &= ~TS_ASLEEP; - wakeup((caddr_t)&tp->t_outq); - } - selwakeup(&tp->t_wsel); - } - goto out; - } - cc = ndqb(&tp->t_outq, 0); - if (cc == 0) - goto out; - - tp->t_state |= TS_BUSY; - dp->p_end = dp->p_mem = tp->t_outq.c_cf; - dp->p_end += cc; - dcaddr->dc_tcr |= 1 << (minor(tp->t_dev) & 03); - MachEmptyWriteBuffer(); -out: - splx(s); -} - -/* - * Stop output on a line. - */ -/*ARGSUSED*/ -void -dcstop(tp, flag) - register struct tty *tp; -{ - register struct pdma *dp; - register int s; - - dp = &dcpdma[minor(tp->t_dev)]; - s = spltty(); - if (tp->t_state & TS_BUSY) { - dp->p_end = dp->p_mem; - if (!(tp->t_state & TS_TTSTOP)) - tp->t_state |= TS_FLUSH; - } - splx(s); -} - -dcmctl(dev, bits, how) - dev_t dev; - int bits, how; -{ - register dcregs *dcaddr; - register int unit, mbits; - int b, s; - register int msr; - - unit = minor(dev); - b = 1 << (unit & 03); - dcaddr = (dcregs *)dcpdma[unit].p_addr; - s = spltty(); - /* only channel 2 has modem control (what about line 3?) */ - mbits = DML_DTR | DML_DSR | DML_CAR; - switch (unit & 03) { - case 2: - mbits = 0; - if (dcaddr->dc_tcr & TCR_DTR2) - mbits |= DML_DTR; - msr = dcaddr->dc_msr; - if (msr & MSR_CD2) - mbits |= DML_CAR; - if (msr & MSR_DSR2) { - if (vax_boardtype == -1) - mbits |= DML_CAR | DML_DSR; - else - mbits |= DML_DSR; - } - break; - - case 3: - if (vax_boardtype != -1) { - mbits = 0; - if (dcaddr->dc_tcr & TCR_DTR3) - mbits |= DML_DTR; - msr = dcaddr->dc_msr; - if (msr & MSR_CD3) - mbits |= DML_CAR; - if (msr & MSR_DSR3) - mbits |= DML_DSR; - } - } - switch (how) { - case DMSET: - mbits = bits; - break; - - case DMBIS: - mbits |= bits; - break; - - case DMBIC: - mbits &= ~bits; - break; - - case DMGET: - splx(s); - return (mbits); - } - switch (unit & 03) { - case 2: - if (mbits & DML_DTR) - dcaddr->dc_tcr |= TCR_DTR2; - else - dcaddr->dc_tcr &= ~TCR_DTR2; - break; - - case 3: - if (vax_boardtype != -1) { - if (mbits & DML_DTR) - dcaddr->dc_tcr |= TCR_DTR3; - else - dcaddr->dc_tcr &= ~TCR_DTR3; - } - } - if ((mbits & DML_DTR) && (dcsoftCAR[unit >> 2] & b)) - dc_tty[unit]->t_state |= TS_CARR_ON; - splx(s); - return (mbits); -} - -/* - * This is called by timeout() periodically. - * Check to see if modem status bits have changed. - */ -void -dcscan(arg) - void *arg; -{ - register dcregs *dcaddr; - register struct tty *tp; - register int i, bit, car; - int s; - - s = spltty(); - /* only channel 2 has modem control (what about line 3?) */ - dcaddr = (dcregs *)dcpdma[i = 2].p_addr; - tp = dc_tty[i]; - bit = TCR_DTR2; - if (dcsoftCAR[i >> 2] & bit) - car = 1; - else - car = dcaddr->dc_msr & MSR_DSR2; - if (car) { - /* carrier present */ - if (!(tp->t_state & TS_CARR_ON)) - (void)(*linesw[tp->t_line].l_modem)(tp, 1); - } else if ((tp->t_state & TS_CARR_ON) && - (*linesw[tp->t_line].l_modem)(tp, 0) == 0) - dcaddr->dc_tcr &= ~bit; - splx(s); - timeout_add(&dc_timeout, hz); -} - -/* - * ---------------------------------------------------------------------------- - * - * dcGetc -- - * - * Read a character from a serial line. - * - * Results: - * A character read from the serial port. - * - * Side effects: - * None. - * - * ---------------------------------------------------------------------------- - */ -int -dcGetc(dev) - dev_t dev; -{ - register dcregs *dcaddr; - register int c; - int s; - - dcaddr = (dcregs *)dcpdma[minor(dev)].p_addr; - if (!dcaddr) - return (0); - s = spltty(); - for (;;) { - if (!(dcaddr->dc_csr & CSR_RDONE)) - continue; - c = dcaddr->dc_rbuf; - DELAY(10); - if (((c >> 8) & 03) == (minor(dev) & 03)) - break; - } - splx(s); - return (c & 0xff); -} - -/* - * Send a char on a port, non interrupt driven. - */ -void -dcPutc(dev, c) - dev_t dev; - int c; -{ - register dcregs *dcaddr; - register u_short tcr; - register int timeout; - int s, line; - - s = spltty(); - - dcaddr = (dcregs *)dcpdma[minor(dev)].p_addr; - tcr = dcaddr->dc_tcr; - dcaddr->dc_tcr = tcr | (1 << minor(dev)); - MachEmptyWriteBuffer(); - DELAY(10); - while (1) { - /* - * Wait for transmitter to be not busy. - */ - timeout = 1000000; - while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0) - timeout--; - if (timeout == 0) { - printf("dcPutc: timeout waiting for CSR_TRDY\n"); - break; - } - line = (dcaddr->dc_csr >> 8) & 3; - /* - * Check to be sure its the right port. - */ - if (line != minor(dev)) { - tcr |= 1 << line; - dcaddr->dc_tcr &= ~(1 << line); - MachEmptyWriteBuffer(); - DELAY(10); - continue; - } - /* - * Start sending the character. - */ - dcaddr->dc_tdr = dc_brk[0] | (c & 0xff); - MachEmptyWriteBuffer(); - DELAY(10); - /* - * Wait for character to be sent. - */ - while (1) { - /* - * cc -O bug: this code produces and infinite loop! - * while (!(dcaddr->dc_csr & CSR_TRDY)) - * ; - */ - timeout = 1000000; - while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0) - timeout--; - line = (dcaddr->dc_csr >> 8) & 3; - if (line != minor(dev)) { - tcr |= 1 << line; - dcaddr->dc_tcr &= ~(1 << line); - MachEmptyWriteBuffer(); - DELAY(10); - continue; - } - dcaddr->dc_tcr &= ~(1 << minor(dev)); - MachEmptyWriteBuffer(); - DELAY(10); - break; - } - break; - } - /* - * Enable interrupts for other lines which became ready. - */ - if (tcr & 0xF) { - dcaddr->dc_tcr = tcr; - MachEmptyWriteBuffer(); - DELAY(10); - } - - splx(s); -} -#endif /* NDC */ |