Beispiel #1
0
void
dartrint(struct dartsoftc *sc, int port)
{
	struct tty *tp;
	unsigned char data, sr;
	struct dart_info *dart;
	bus_addr_t ptaddr;

	dart = &sc->sc_dart[port];
	ptaddr = port ? DART_B_BASE : DART_A_BASE;
	tp = dart->tty;

	/* read status reg */
	while ((sr = dart_read(sc, ptaddr + DART_SRA)) & RXRDY) {
		/* read data and reset receiver */
		data = dart_read(sc, ptaddr + DART_RBA);

		if ((tp->t_state & (TS_ISOPEN|TS_WOPEN)) == 0 &&
		    CONS_PORT != port) {
			return;
		}

		if (sr & RBRK) {
			/* clear break state */
			dart_write(sc, ptaddr + DART_CRA, BRKINTRESET);
			DELAY_CR;
			dart_write(sc, ptaddr + DART_CRA, ERRRESET);

#if defined(DDB)
			if (db_console != 0 && port == CONS_PORT)
				Debugger();
#endif
		} else {
			if (sr & (FRERR|PERR|ROVRN)) { /* errors */
				if (sr & ROVRN)
					printf("dart0: receiver overrun port %c\n", 'A' + port);
				if (sr & FRERR)
					printf("dart0: framing error port %c\n", 'A' + port);
				if (sr & PERR)
					printf("dart0: parity error port %c\n", 'A' + port);
				/* clear error state */
				dart_write(sc, ptaddr + DART_CRA, ERRRESET);
			} else {
				/* no errors */
				(*linesw[tp->t_line].l_rint)(data,tp);
#if 0
				{
					if (tp->t_ispeed == B134) /* CS6 */
						data &= 077;
					else if (tp->t_flags & CS8)
						;
					else
						data &= 0177; /* CS7 */
					ttyinput(data, tp);
				}
#endif
			}
		}
	}
}
Beispiel #2
0
void
dartrint(struct dartsoftc *sc, int port)
{
	struct tty *tp;
	unsigned char data, sr;
	struct dart_info *dart;
	bus_addr_t ptaddr;

	dart = &sc->sc_dart[port];
	ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;
	tp = dart->tty;

	/* read status reg */
	while ((sr = dart_read(sc, ptaddr + DART_SRA)) & RXRDY) {
		/* read data and reset receiver */
		data = dart_read(sc, ptaddr + DART_RBA);

		if ((tp->t_state & (TS_ISOPEN|TS_WOPEN)) == 0 &&
		    (sc->sc_console == 0 || CONS_PORT != port)) {
			return;
		}

		if (sr & RBRK) {
			/* clear break state */
			dart_write(sc, ptaddr + DART_CRA, BRKINTRESET);
			DELAY_CR;
			dart_write(sc, ptaddr + DART_CRA, ERRRESET);

#if defined(DDB)
			if (db_console != 0 &&
			    sc->sc_console && port == CONS_PORT)
				Debugger();
#endif
		} else {
			if (sr & (FRERR | PERR | ROVRN)) { /* errors */
				if (sr & ROVRN)
					log(LOG_WARNING, "%s port %c: "
					    "receiver overrun\n",
					    sc->sc_dev.dv_xname, 'A' + port);
				if (sr & FRERR)
					log(LOG_WARNING, "%s port %c: "
					    "framing error\n",
					    sc->sc_dev.dv_xname, 'A' + port);
				if (sr & PERR)
					log(LOG_WARNING, "%s port %c: "
					    "parity error\n",
					    sc->sc_dev.dv_xname, 'A' + port);
				/* clear error state */
				dart_write(sc, ptaddr + DART_CRA, ERRRESET);
			} else {
				/* no errors */
				(*linesw[tp->t_line].l_rint)(data,tp);
			}
		}
	}
}
Beispiel #3
0
void
dartstart(struct tty *tp)
{
	struct dartsoftc *sc;
	dev_t dev;
	int s;
	u_int port, chip;
	int c, tries;
	bus_addr_t ptaddr;

	if ((tp->t_state & TS_ISOPEN) == 0)
		return;

	dev = tp->t_dev;
	chip = DART_CHIP(dev);
	port = DART_PORT(dev);
	sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
	ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;

	s = spltty();

	if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
		goto bail;

	ttwakeupwr(tp);
	if (tp->t_outq.c_cc == 0)
		goto bail;

	tp->t_state |= TS_BUSY;
	while (tp->t_outq.c_cc != 0) {

		/* load transmitter until it is full */
		for (tries = 10000; tries != 0; tries --)
			if (dart_read(sc, ptaddr + DART_SRA) & TXRDY)
				break;

		if (tries == 0) {
			timeout_add(&tp->t_rstrt_to, 1);
			tp->t_state |= TS_TIMEOUT;
			break;
		} else {
			c = getc(&tp->t_outq);

			dart_write(sc, ptaddr + DART_TBA, c & 0xff);

			sc->sc_sv_reg->sv_imr |=
			    port == A_PORT ? ITXRDYA : ITXRDYB;
			dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
		}
	}
	tp->t_state &= ~TS_BUSY;

bail:
	splx(s);
}
Beispiel #4
0
/*
 * To be called at spltty - tty already locked.
 * Returns status of carrier.
 */
int
dartmctl(struct dartsoftc *sc, int port, int flags, int how)
{
	int newflags, flagsmask;
	struct dart_info *dart;
	int s;

	dart = &sc->sc_dart[port];

	s = spltty();

	flagsmask = port == A_PORT ? (OPDTRA | OPRTSA) : (OPDTRB | OPRTSB);
	newflags = (flags & TIOCM_DTR ? (OPDTRA | OPDTRB) : 0) |
	    (flags & TIOCM_RTS ? (OPRTSA | OPRTSB) : 0);
	newflags &= flagsmask;	/* restrict to the port we are acting on */

	switch (how) {
	case DMSET:
		dart_write(sc, DART_OPRS, newflags);
		dart_write(sc, DART_OPRR, ~newflags);
		/* only replace the sv_opr bits for the port we are acting on */
		sc->sc_sv_reg->sv_opr &= ~flagsmask;
		sc->sc_sv_reg->sv_opr |= newflags;
		break;
	case DMBIS:
		dart_write(sc, DART_OPRS, newflags);
		sc->sc_sv_reg->sv_opr |= newflags;
		break;
	case DMBIC:
		dart_write(sc, DART_OPRR, newflags);
		sc->sc_sv_reg->sv_opr &= ~newflags;
		break;
	case DMGET:
		flags = 0;
		if (port == A_PORT) {
			if (sc->sc_sv_reg->sv_opr & OPDTRA)
				flags |= TIOCM_DTR;
			if (sc->sc_sv_reg->sv_opr & OPRTSA)
				flags |= TIOCM_RTS;
		} else {
			if (sc->sc_sv_reg->sv_opr & OPDTRB)
				flags |= TIOCM_DTR;
			if (sc->sc_sv_reg->sv_opr & OPRTSB)
				flags |= TIOCM_RTS;
		}
		break;
	}

	splx(s);
	return (flags);
}
Beispiel #5
0
void
dartxint(struct dartsoftc *sc, int port)
{
	struct tty *tp;
	struct dart_info *dart;

	dart = &sc->sc_dart[port];
	tp = dart->tty;

	if ((tp->t_state & (TS_ISOPEN|TS_WOPEN))==0)
		goto out;

	if (tp->t_state & TS_BUSY) {
		tp->t_state &= ~(TS_BUSY | TS_FLUSH);
		dartstart(tp);
		if (tp->t_state & TS_BUSY) {
			/* do not disable transmitter, yet */
			return;
		}
	}
out:

	/* disable transmitter */
	sc->sc_sv_reg->sv_imr &= port == A_PORT ? ~ITXRDYA : ~ITXRDYB;
	dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
}
Beispiel #6
0
void
dartxint(struct dartsoftc *sc, int port)
{
	struct tty *tp;
	struct dart_info *dart;

	dart = &sc->sc_dart[port];
	tp = dart->tty;

	if ((tp->t_state & (TS_ISOPEN|TS_WOPEN))==0)
		goto out;

	if (tp->t_state & TS_FLUSH)
		tp->t_state &= ~TS_FLUSH;

	if (tp->t_state & TS_BUSY) {
		tp->t_state &= ~TS_BUSY;
		dartstart(tp);
		if (tp->t_state & TS_BUSY) {
			return;
		}
	}
out:

	/* disable transmitter */
	if (port == 0)
		sc->sc_sv_reg.sv_imr &= ~ITXRDYA;
	else
		sc->sc_sv_reg.sv_imr &= ~ITXRDYB;

	dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr);
}
Beispiel #7
0
int
dartintr(void *arg)
{
	struct dartsoftc *sc = arg;
	unsigned char isr, imr;
	int port;

	/* read interrupt status register and mask with imr */
	isr = dart_read(sc, DART_ISR);
	imr = sc->sc_sv_reg->sv_imr;

	if ((isr & imr) == 0) {
		/*
		 * We got an interrupt on a disabled condition (such as TX
		 * ready change on a disabled port). This should not happen,
		 * but we have to claim the interrupt anyway.
		 */
#if defined(DIAGNOSTIC) && !defined(MULTIPROCESSOR)
		printf("%s: spurious interrupt, isr %x imr %x\n",
		    sc->sc_dev.dv_xname, isr, imr);
#endif
		return (1);
	}
	isr &= imr;

	if (isr & IIPCHG) {
		unsigned int ip, ipcr;

		ip = dart_read(sc, DART_IP);
		ipcr = dart_read(sc, DART_IPCR);
		dartmodemtrans(sc, ip, ipcr);
		return (1);
	}

	if (isr & (IRXRDYA | ITXRDYA))
		port = 0;
#ifdef DIAGNOSTIC
	else if ((isr & (IRXRDYB | ITXRDYB)) == 0) {
		printf("%s: spurious interrupt, isr %x\n",
		    sc->sc_dev.dv_xname, isr);
		return (1);	/* claim it anyway */
	}
#endif
	else
		port = 1;

	if (isr & (IRXRDYA | IRXRDYB))
		dartrint(sc, port);
	if (isr & (ITXRDYA | ITXRDYB))
		dartxint(sc, port);
	if (isr & (port == A_PORT ? IBRKA : IBRKB))
		dart_write(sc, port == A_PORT ? DART_CRA : DART_CRB,
		    BRKINTRESET);

	return (1);
}
Beispiel #8
0
int
dartintr(void *arg)
{
	struct dartsoftc *sc = arg;
	unsigned char isr, imr;
	int port;

	/* read interrupt status register and mask with imr */
	isr = dart_read(sc, DART_ISR);
	imr = sc->sc_sv_reg.sv_imr;

	if ((isr & imr) == 0) {
		/*
		 * We got an interrupt on a disabled condition (such as TX
		 * ready change on a disabled port). This should not happen,
		 * but we have to claim the interrupt anyway.
		 */
#ifdef DIAGNOSTIC
		printf("dartintr: spurious interrupt, isr %x imr %x\n",
		    isr, imr);
#endif
		return (1);
	}
	isr &= imr;

	if (isr & IIPCHG) {
		unsigned int ip, ipcr;

		ip = dart_read(sc, DART_IP);
		ipcr = dart_read(sc, DART_IPCR);
		dartmodemtrans(sc, ip, ipcr);
		return (1);
	}

	if (isr & (IRXRDYA | ITXRDYA))
		port = 0;
	else if (isr & (IRXRDYB | ITXRDYB))
		port = 1;
	else {
		printf("dartintr: spurious interrupt, isr 0x%08x\n", isr);
		return (1);	/* claim it anyway */
	}

	if (isr & (IRXRDYA | IRXRDYB)) {
		dartrint(sc, port);
	}
	if (isr & (ITXRDYA | ITXRDYB)) {
		dartxint(sc, port);
	}
	if ((port == A_PORT && (isr & IBRKA)) ||
	    (port == B_PORT && (isr & IBRKB))) {
		dart_write(sc, port ? DART_CRB : DART_CRA, BRKINTRESET);
	}

	return (1);
}
Beispiel #9
0
int
dartmctl(dev_t dev, int flags, int how)
{
	struct dartsoftc *sc;
	int port;
	int newflags = 0;
	struct dart_info *dart;
	int s;

	port = DART_PORT(dev);
	if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS)
		return (ENODEV);

	sc = (struct dartsoftc *)dart_cd.cd_devs[0];
	dart = &sc->sc_dart[port];

	s = spltty();

	HANDLE_FLAG(TIOCM_DTR, port, OPDTRA, OPDTRB);
	HANDLE_FLAG(TIOCM_RTS, port, OPRTSA, OPRTSB);

	switch (how) {
	case DMSET:
		dart_write(sc, DART_OPRS, newflags);
		dart_write(sc, DART_OPRR, ~newflags);
		break;
	case DMBIS:
		dart_write(sc, DART_OPRS, newflags);
		break;
	case DMBIC:
		dart_write(sc, DART_OPRR, newflags);
		break;
	case DMGET:
		flags = 0;	/* XXX not supported */
		break;
	}

	splx(s);
	return (flags);
}
Beispiel #10
0
void
dart_common_attach(struct dartsoftc *sc)
{
	if (sc->sc_console) {
		sc->sc_sv_reg = &dartcn_sv;

		if (A_PORT != CONS_PORT) {
			sc->sc_sv_reg->sv_mr1[A_PORT] = PARDIS | RXRTS | CL8;
			sc->sc_sv_reg->sv_mr2[A_PORT] = /* TXCTS | */ SB1;
			sc->sc_sv_reg->sv_csr[A_PORT] = BD9600;
			sc->sc_sv_reg->sv_cr[A_PORT]  = TXEN | RXEN;
			sc->sc_sv_reg->sv_opr |= OPDTRA | OPRTSA;
		} else {
			sc->sc_sv_reg->sv_mr1[B_PORT] = PARDIS | RXRTS | CL8;
			sc->sc_sv_reg->sv_mr2[B_PORT] = /* TXCTS | */ SB1;
			sc->sc_sv_reg->sv_csr[B_PORT] = BD9600;
			sc->sc_sv_reg->sv_cr[B_PORT]  = TXEN | RXEN;
			sc->sc_sv_reg->sv_opr |= OPDTRB | OPRTSB;
		}
	} else {
		sc->sc_sv_reg = &sc->sc_sv_reg_storage;

		sc->sc_sv_reg->sv_mr1[A_PORT] = PARDIS | RXRTS | CL8;
		sc->sc_sv_reg->sv_mr2[A_PORT] = /* TXCTS | */ SB1;
		sc->sc_sv_reg->sv_csr[A_PORT] = BD9600;
		sc->sc_sv_reg->sv_cr[A_PORT]  = TXEN | RXEN;

		sc->sc_sv_reg->sv_mr1[B_PORT] = PARDIS | RXRTS | CL8;
		sc->sc_sv_reg->sv_mr2[B_PORT] = /* TXCTS | */ SB1;
		sc->sc_sv_reg->sv_csr[B_PORT] = BD9600;
		sc->sc_sv_reg->sv_cr[B_PORT]  = TXEN | RXEN;

		sc->sc_sv_reg->sv_opr = OPDTRA | OPRTSA | OPDTRB | OPRTSB;

		/* Start out with Tx and RX interrupts disabled */
		/* Enable input port change interrupt */
		sc->sc_sv_reg->sv_imr  = IIPCHG;
	}

	/* reset port a */
	if (sc->sc_console == 0 || CONS_PORT != A_PORT) {
		dart_write(sc, DART_CRA, RXRESET | TXDIS | RXDIS);
		DELAY_CR;
		dart_write(sc, DART_CRA, TXRESET | TXDIS | RXDIS);
		DELAY_CR;
		dart_write(sc, DART_CRA, ERRRESET | TXDIS | RXDIS);
		DELAY_CR;
		dart_write(sc, DART_CRA, BRKINTRESET | TXDIS | RXDIS);
		DELAY_CR;
		dart_write(sc, DART_CRA, MRRESET | TXDIS | RXDIS);
#if 0
		DELAY_CR;
#endif

		dart_write(sc, DART_MR1A, sc->sc_sv_reg->sv_mr1[A_PORT]);
		dart_write(sc, DART_MR2A, sc->sc_sv_reg->sv_mr2[A_PORT]);
		dart_write(sc, DART_CSRA, sc->sc_sv_reg->sv_csr[A_PORT]);
		dart_write(sc, DART_CRA, sc->sc_sv_reg->sv_cr[A_PORT]);
	}

	/* reset port b */
	if (sc->sc_console == 0 || CONS_PORT != B_PORT) {
		dart_write(sc, DART_CRB, RXRESET | TXDIS | RXDIS);
		DELAY_CR;
		dart_write(sc, DART_CRB, TXRESET | TXDIS | RXDIS);
		DELAY_CR;
		dart_write(sc, DART_CRB, ERRRESET | TXDIS | RXDIS);
		DELAY_CR;
		dart_write(sc, DART_CRB, BRKINTRESET | TXDIS | RXDIS);
		DELAY_CR;
		dart_write(sc, DART_CRB, MRRESET | TXDIS | RXDIS);
#if 0
		DELAY_CR;
#endif

		dart_write(sc, DART_MR1B, sc->sc_sv_reg->sv_mr1[B_PORT]);
		dart_write(sc, DART_MR2B, sc->sc_sv_reg->sv_mr2[B_PORT]);
		dart_write(sc, DART_CSRB, sc->sc_sv_reg->sv_csr[B_PORT]);
		dart_write(sc, DART_CRB, sc->sc_sv_reg->sv_cr[B_PORT]);
	}

	/* initialize common register of a DUART */
	dart_write(sc, DART_OPRS, sc->sc_sv_reg->sv_opr);

#if 0
	dart_write(sc, DART_CTUR, SLCTIM >> 8);
	dart_write(sc, DART_CTLR, SLCTIM & 0xff);
	dart_write(sc, DART_ACR, BDSET2 | CCLK16 | IPDCDIB | IPDCDIA);
#endif
	dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
	dart_write(sc, DART_OPCR, OPSET | SPKRDIS);

	sc->sc_dart[A_PORT].tty = sc->sc_dart[B_PORT].tty = NULL;
	sc->sc_dart[A_PORT].dart_swflags = sc->sc_dart[B_PORT].dart_swflags = 0;
	if (sc->sc_console)
		sc->sc_dart[CONS_PORT].dart_swflags |= TIOCFLAG_SOFTCAR;

	printf("\n");
}
Beispiel #11
0
int
dartparam(struct tty *tp, struct termios *t)
{
	int flags;
	u_int port, chip;
	int speeds;
	unsigned char mr1, mr2;
	struct dart_info *dart;
	struct dartsoftc *sc;
	dev_t dev;
	bus_addr_t ptaddr;

	dev = tp->t_dev;
	chip = DART_CHIP(dev);
	port = DART_PORT(dev);
	sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
	dart = &sc->sc_dart[port];
	ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;

	tp->t_ispeed = t->c_ispeed;
	tp->t_ospeed = t->c_ospeed;
	tp->t_cflag = t->c_cflag;

	flags = tp->t_flags;

	/* Reset to make global changes*/
	/* disable Tx and Rx */

	if (sc->sc_console == 0 || CONS_PORT != port) {
		if (port == A_PORT)
			sc->sc_sv_reg->sv_imr &= ~(ITXRDYA | IRXRDYA);
		else
			sc->sc_sv_reg->sv_imr &= ~(ITXRDYB | IRXRDYB);
		dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);

		/* hang up on zero baud rate */
		if (tp->t_ispeed == 0) {
			dartmctl(sc, port, HUPCL, DMSET);
			return (0);
		} else {
			/* set baudrate */
			speeds = dart_speed(tp->t_ispeed);
			if (speeds == NOBAUD)
				speeds = sc->sc_sv_reg->sv_csr[port];
			dart_write(sc, ptaddr + DART_CSRA, speeds);
			sc->sc_sv_reg->sv_csr[port] = speeds;
		}

		/* get saved mode registers and clear set up parameters */
		mr1 = sc->sc_sv_reg->sv_mr1[port];
		mr1 &= ~(CLMASK | PARTYPEMASK | PARMODEMASK);

		mr2 = sc->sc_sv_reg->sv_mr2[port];
		mr2 &= ~SBMASK;

		/* set up character size */
		switch (t->c_cflag & CSIZE) {
		case CL8:
			mr1 |= CL8;
			break;
		case CL7:
			mr1 |= CL7;
			break;
		case CL6:
			mr1 |= CL6;
			break;
		case CL5:
			mr1 |= CL5;
			break;
		}

		/* set up stop bits */
		if (tp->t_ospeed == B110)
			mr2 |= SB2;
		else
			mr2 |= SB1;

		/* set up parity */
		if (t->c_cflag & PARENB) {
			mr1 |= PAREN;
			if (t->c_cflag & PARODD)
				mr1 |= ODDPAR;
			else
				mr1 |= EVENPAR;
		} else
			mr1 |= PARDIS;

		if (sc->sc_sv_reg->sv_mr1[port] != mr1 ||
		    sc->sc_sv_reg->sv_mr2[port] != mr2) {
			/* write mode registers to duart */
			dart_write(sc, ptaddr + DART_CRA, MRRESET);
			dart_write(sc, ptaddr + DART_MR1A, mr1);
			dart_write(sc, ptaddr + DART_MR2A, mr2);

			/* save changed mode registers */
			sc->sc_sv_reg->sv_mr1[port] = mr1;
			sc->sc_sv_reg->sv_mr2[port] = mr2;
		}
	}

	/* enable transmitter? */
	if (tp->t_state & TS_BUSY) {
		sc->sc_sv_reg->sv_imr |= port == A_PORT ? ITXRDYA : ITXRDYB;
		dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
	}

	/* re-enable the receiver */
#if 0
	DELAY_CR;
#endif
	sc->sc_sv_reg->sv_imr |= port == A_PORT ? IRXRDYA : IRXRDYB;
	dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);

	return (0);
}
Beispiel #12
0
void
dartstart(struct tty *tp)
{
	struct dartsoftc *sc;
	dev_t dev;
	int s;
	int port, tries;
	int c;
	bus_addr_t ptaddr;

	dev = tp->t_dev;
	port = DART_PORT(dev);
	if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS)
		return;

	if ((tp->t_state & TS_ISOPEN) == 0)
		return;

	sc = (struct dartsoftc *)dart_cd.cd_devs[0];
	ptaddr = port ? DART_B_BASE : DART_A_BASE;

	s = spltty();

	if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
		goto bail;

	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 bail;
	}

	tp->t_state |= TS_BUSY;
	while (tp->t_outq.c_cc != 0) {

		/* load transmitter until it is full */
		for (tries = 10000; tries != 0; tries --)
			if (dart_read(sc, ptaddr + DART_SRA) & TXRDY)
				break;

		if (tries == 0) {
			timeout_add(&tp->t_rstrt_to, 1);
			tp->t_state |= TS_TIMEOUT;
			break;
		} else {
			c = getc(&tp->t_outq);

			dart_write(sc, ptaddr + DART_TBA, c & 0xff);

			if (port == A_PORT)
				sc->sc_sv_reg.sv_imr |= ITXRDYA;
			else
				sc->sc_sv_reg.sv_imr |= ITXRDYB;
			dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr);
		}
	}
	tp->t_state &= ~TS_BUSY;

bail:
	splx(s);
}
Beispiel #13
0
void
dartattach(struct device *parent, struct device *self, void *aux)
{
	struct dartsoftc *sc = (struct dartsoftc *)self;
	struct confargs *ca = aux;
	bus_space_handle_t ioh;

	if (ca->ca_ipl < 0)
		ca->ca_ipl = IPL_TTY;

	sc->sc_iot = ca->ca_iot;
	if (bus_space_map(sc->sc_iot, ca->ca_paddr, DART_SIZE, 0, &ioh) != 0) {
		printf(": can't map registers!\n");
		return;
	}
	sc->sc_ioh = ioh;

	/* save standard initialization */
	sc->sc_sv_reg.sv_mr1[A_PORT] = PARDIS | RXRTS | CL8;
	sc->sc_sv_reg.sv_mr2[A_PORT] = /* TXCTS | */ SB1;
	sc->sc_sv_reg.sv_csr[A_PORT] = BD9600;
	sc->sc_sv_reg.sv_cr[A_PORT]  = TXEN | RXEN;

	sc->sc_sv_reg.sv_mr1[B_PORT] = PARDIS | RXRTS | CL8;
	sc->sc_sv_reg.sv_mr2[B_PORT] = /* TXCTS | */ SB1;
	sc->sc_sv_reg.sv_csr[B_PORT] = BD9600;
	sc->sc_sv_reg.sv_cr[B_PORT]  = TXEN | RXEN;

	/* Start out with Tx and RX interrupts disabled */
	/* Enable input port change interrupt */
	sc->sc_sv_reg.sv_imr  = IIPCHG;

	/*
	 * Although we are still running using the BUG routines,
	 * this device will be elected as the console after
	 * autoconf.
	 * We do not even test since we know we are an MVME188 and
	 * console is always on the first port.
	 */
	printf(": console");

	/* reset port a */
	dart_write(sc, DART_CRA, RXRESET | TXDIS | RXDIS);
	DELAY_CR;
	dart_write(sc, DART_CRA, TXRESET | TXDIS | RXDIS);
	DELAY_CR;
	dart_write(sc, DART_CRA, ERRRESET | TXDIS | RXDIS);
	DELAY_CR;
	dart_write(sc, DART_CRA, BRKINTRESET | TXDIS | RXDIS);
	DELAY_CR;
	dart_write(sc, DART_CRA, MRRESET | TXDIS | RXDIS);
	DELAY_CR;

	/* reset port b */
	dart_write(sc, DART_CRB, RXRESET | TXDIS | RXDIS);
	DELAY_CR;
	dart_write(sc, DART_CRB, TXRESET | TXDIS | RXDIS);
	DELAY_CR;
	dart_write(sc, DART_CRB, ERRRESET | TXDIS | RXDIS);
	DELAY_CR;
	dart_write(sc, DART_CRB, BRKINTRESET | TXDIS | RXDIS);
	DELAY_CR;
	dart_write(sc, DART_CRB, MRRESET | TXDIS | RXDIS);
	DELAY_CR;

	/* initialize ports */
	dart_write(sc, DART_MR1A, sc->sc_sv_reg.sv_mr1[A_PORT]);
	dart_write(sc, DART_MR2A, sc->sc_sv_reg.sv_mr2[A_PORT]);
	dart_write(sc, DART_CSRA, sc->sc_sv_reg.sv_csr[A_PORT]);
	dart_write(sc, DART_CRA, sc->sc_sv_reg.sv_cr[A_PORT]);

	dart_write(sc, DART_MR1B, sc->sc_sv_reg.sv_mr1[B_PORT]);
	dart_write(sc, DART_MR2B, sc->sc_sv_reg.sv_mr2[B_PORT]);
	dart_write(sc, DART_CSRB, sc->sc_sv_reg.sv_csr[B_PORT]);
	dart_write(sc, DART_CRB, sc->sc_sv_reg.sv_cr[B_PORT]);

	/* initialize common register of a DUART */
	dart_write(sc, DART_OPRS, OPDTRA | OPRTSA | OPDTRB | OPRTSB);

	dart_write(sc, DART_CTUR, SLCTIM >> 8);
	dart_write(sc, DART_CTLR, SLCTIM & 0xff);
	dart_write(sc, DART_ACR, BDSET2 | CCLK16 | IPDCDIB | IPDCDIA);
	dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr);
	dart_write(sc, DART_OPCR, OPSET);
	dart_write(sc, DART_IVR, SYSCON_VECT + SYSCV_SCC);

	/* enable interrupts */
	sc->sc_ih.ih_fn = dartintr;
	sc->sc_ih.ih_arg = sc;
	sc->sc_ih.ih_wantframe = 0;
	sc->sc_ih.ih_ipl = ca->ca_ipl;

	sysconintr_establish(SYSCV_SCC, &sc->sc_ih, self->dv_xname);
	printf("\n");
}