summaryrefslogtreecommitdiff
path: root/sys/arch/vax/vsa/dc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/vax/vsa/dc.c')
-rw-r--r--sys/arch/vax/vsa/dc.c1024
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 */