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()7242379Smckusickdcmgetchar() 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()9542379Smckusickdcmgetchar() 9642379Smckusick { 9742379Smckusick return(0); 9842379Smckusick } 9942379Smckusick #endif 10042379Smckusick dcmputchar(c)10142379Smckusickdcmputchar(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