xref: /csrg-svn/sys/hp300/stand/dcm.c (revision 63163)
142379Smckusick /*
242379Smckusick  * Copyright (c) 1988 University of Utah.
3*63163Sbostic  * Copyright (c) 1990, 1993
4*63163Sbostic  *	The Regents of the University of California.  All rights reserved.
542379Smckusick  *
642379Smckusick  * This code is derived from software contributed to Berkeley by
742379Smckusick  * the Systems Programming Group of the University of Utah Computer
842379Smckusick  * Science Department.
942379Smckusick  *
1042379Smckusick  * %sccs.include.redist.c%
1142379Smckusick  *
12*63163Sbostic  *	@(#)dcm.c	8.1 (Berkeley) 06/10/93
1342379Smckusick  */
1442379Smckusick 
1542379Smckusick #ifdef DCMCONSOLE
1656510Sbostic #include <sys/param.h>
1756510Sbostic #include <hp/dev/cons.h>
1856510Sbostic #include <hp/dev/device.h>
1956510Sbostic #include <hp300/dev/dcmreg.h>
2042379Smckusick 
2149334Shibler struct dcmdevice *dcmcnaddr = NULL;
2242379Smckusick 
2342379Smckusick dcmprobe(cp)
2442379Smckusick 	struct consdev *cp;
2542379Smckusick {
2642379Smckusick 	extern struct hp_hw sc_table[];
2742379Smckusick 	register struct hp_hw *hw;
2842379Smckusick 	register struct dcmdevice *dcm;
2942379Smckusick 
3049334Shibler 	for (hw = sc_table; hw < &sc_table[MAXCTLRS]; hw++)
3149334Shibler 	        if (HW_ISDEV(hw, D_COMMDCM) && !badaddr((caddr_t)hw->hw_kva))
3242379Smckusick 			break;
3349334Shibler 	if (!HW_ISDEV(hw, D_COMMDCM)) {
3442379Smckusick 		cp->cn_pri = CN_DEAD;
3542379Smckusick 		return;
3642379Smckusick 	}
3749334Shibler 	dcmcnaddr = (struct dcmdevice *) hw->hw_kva;
3842379Smckusick 
3949334Shibler 	dcm = dcmcnaddr;
4042379Smckusick 	switch (dcm->dcm_rsid) {
4142379Smckusick 	case DCMID:
4242379Smckusick 		cp->cn_pri = CN_NORMAL;
4342379Smckusick 		break;
4442379Smckusick 	case DCMID|DCMCON:
4542379Smckusick 		cp->cn_pri = CN_REMOTE;
4642379Smckusick 		break;
4742379Smckusick 	default:
4842379Smckusick 		cp->cn_pri = CN_DEAD;
4942379Smckusick 		break;
5042379Smckusick 	}
5142379Smckusick }
5242379Smckusick 
5342379Smckusick dcminit(cp)
5442379Smckusick 	struct consdev *cp;
5542379Smckusick {
5649334Shibler 	register struct dcmdevice *dcm = dcmcnaddr;
5749334Shibler 	register int port = CONUNIT;
5842379Smckusick 
5942379Smckusick 	dcm->dcm_ic = IC_ID;
6042379Smckusick 	while (dcm->dcm_thead[port].ptr != dcm->dcm_ttail[port].ptr)
6142379Smckusick 		;
6242379Smckusick 	dcm->dcm_data[port].dcm_baud = BR_9600;
6342379Smckusick 	dcm->dcm_data[port].dcm_conf = LC_8BITS | LC_1STOP;
6442379Smckusick 	SEM_LOCK(dcm);
6542379Smckusick 	dcm->dcm_cmdtab[port].dcm_data |= CT_CON;
6642379Smckusick 	dcm->dcm_cr |= (1 << port);
6742379Smckusick 	SEM_UNLOCK(dcm);
6842379Smckusick 	DELAY(15000);
6942379Smckusick }
7042379Smckusick 
7142379Smckusick #ifndef SMALL
dcmgetchar()7242379Smckusick dcmgetchar()
7342379Smckusick {
7449334Shibler 	register struct dcmdevice *dcm = dcmcnaddr;
7542379Smckusick 	register struct dcmrfifo *fifo;
7642379Smckusick 	register struct dcmpreg *pp;
7742379Smckusick 	register unsigned head;
7842379Smckusick 	int c, stat, port;
7942379Smckusick 
8049334Shibler 	port = CONUNIT;
8142379Smckusick 	pp = dcm_preg(dcm, port);
8242379Smckusick 	head = pp->r_head & RX_MASK;
8342379Smckusick 	if (head == (pp->r_tail & RX_MASK))
8442379Smckusick 		return(0);
8542379Smckusick 	fifo = &dcm->dcm_rfifos[3-port][head>>1];
8642379Smckusick 	c = fifo->data_char;
8742379Smckusick 	stat = fifo->data_stat;
8842379Smckusick 	pp->r_head = (head + 2) & RX_MASK;
8942379Smckusick 	SEM_LOCK(dcm);
9042379Smckusick 	stat = dcm->dcm_iir;
9142379Smckusick 	SEM_UNLOCK(dcm);
9242379Smckusick 	return(c);
9342379Smckusick }
9442379Smckusick #else
dcmgetchar()9542379Smckusick dcmgetchar()
9642379Smckusick {
9742379Smckusick 	return(0);
9842379Smckusick }
9942379Smckusick #endif
10042379Smckusick 
dcmputchar(c)10142379Smckusick dcmputchar(c)
10242379Smckusick 	register int c;
10342379Smckusick {
10449334Shibler 	register struct dcmdevice *dcm = dcmcnaddr;
10542379Smckusick 	register struct dcmpreg *pp;
10642379Smckusick 	register int timo;
10742379Smckusick 	unsigned tail;
10842379Smckusick 	int port, stat;
10942379Smckusick 
11049334Shibler 	port = CONUNIT;
11142379Smckusick 	pp = dcm_preg(dcm, port);
11242379Smckusick 	tail = pp->t_tail & TX_MASK;
11342379Smckusick 	timo = 50000;
11442379Smckusick 	while (tail != (pp->t_head & TX_MASK) && --timo)
11542379Smckusick 		;
11642379Smckusick 	dcm->dcm_tfifos[3-port][tail].data_char = c;
11742379Smckusick 	pp->t_tail = tail = (tail + 1) & TX_MASK;
11842379Smckusick 	SEM_LOCK(dcm);
11942379Smckusick 	dcm->dcm_cmdtab[port].dcm_data |= CT_TX;
12042379Smckusick 	dcm->dcm_cr |= (1 << port);
12142379Smckusick 	SEM_UNLOCK(dcm);
12242379Smckusick 	timo = 1000000;
12342379Smckusick 	while (tail != (pp->t_head & TX_MASK) && --timo)
12442379Smckusick 		;
12542379Smckusick 	SEM_LOCK(dcm);
12642379Smckusick 	stat = dcm->dcm_iir;
12742379Smckusick 	SEM_UNLOCK(dcm);
12842379Smckusick }
12942379Smckusick #endif
130