1/* $NetBSD: dcm.c,v 1.7 2007/03/04 05:59:50 christos Exp $ */ 2 3/* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1990, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer 10 * Science Department. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)dcm.c 8.1 (Berkeley) 6/10/93 37 */ 38 39#ifdef DCMCONSOLE 40#include <sys/param.h> 41#include <dev/cons.h> 42 43#include <hp300/dev/dcmreg.h> 44 45#include <hp300/stand/common/consdefs.h> 46#include <hp300/stand/common/samachdep.h> 47#include <hp300/stand/common/device.h> 48 49struct dcmdevice *dcmcnaddr = NULL; 50 51#define DCMCONUNIT 1 /* XXX */ 52 53void 54dcmprobe(struct consdev *cp) 55{ 56 struct hp_hw *hw; 57 struct dcmdevice *dcm; 58 59 for (hw = sc_table; hw < &sc_table[MAXCTLRS]; hw++) 60 if (HW_ISDEV(hw, D_COMMDCM) && !badaddr((void *)hw->hw_kva)) 61 break; 62 if (!HW_ISDEV(hw, D_COMMDCM)) { 63 cp->cn_pri = CN_DEAD; 64 return; 65 } 66 dcmcnaddr = (struct dcmdevice *) hw->hw_kva; 67 68#ifdef FORCEDCMCONSOLE 69 cp->cn_pri = CN_REMOTE; 70#else 71 dcm = dcmcnaddr; 72 switch (dcm->dcm_rsid) { 73 case DCMID: 74 cp->cn_pri = CN_NORMAL; 75 break; 76 case DCMID|DCMCON: 77 cp->cn_pri = CN_REMOTE; 78 break; 79 default: 80 cp->cn_pri = CN_DEAD; 81 break; 82 } 83 84 curcons_scode = hw->hw_sc; 85#endif 86} 87 88void 89dcminit(struct consdev *cp) 90{ 91 struct dcmdevice *dcm = dcmcnaddr; 92 int port = DCMCONUNIT; 93 94 dcm->dcm_ic = IC_ID; 95 while (dcm->dcm_thead[port].ptr != dcm->dcm_ttail[port].ptr) 96 ; 97 dcm->dcm_data[port].dcm_baud = BR_9600; 98 dcm->dcm_data[port].dcm_conf = LC_8BITS | LC_1STOP; 99 SEM_LOCK(dcm); 100 dcm->dcm_cmdtab[port].dcm_data |= CT_CON; 101 dcm->dcm_cr |= (1 << port); 102 SEM_UNLOCK(dcm); 103 DELAY(15000); 104} 105 106/* ARGSUSED */ 107#ifndef SMALL 108int 109dcmgetchar(dev_t dev) 110{ 111 struct dcmdevice *dcm = dcmcnaddr; 112 struct dcmrfifo *fifo; 113 struct dcmpreg *pp; 114 unsigned int head; 115 int c, stat, port; 116 117 port = DCMCONUNIT; 118 pp = dcm_preg(dcm, port); 119 head = pp->r_head & RX_MASK; 120 if (head == (pp->r_tail & RX_MASK)) 121 return 0; 122 fifo = &dcm->dcm_rfifos[3-port][head>>1]; 123 c = fifo->data_char; 124 stat = fifo->data_stat; 125 pp->r_head = (head + 2) & RX_MASK; 126 SEM_LOCK(dcm); 127 stat = dcm->dcm_iir; 128 SEM_UNLOCK(dcm); 129 return c; 130} 131#else 132int 133dcmgetchar(dev_t dev) 134{ 135 136 return 0; 137} 138#endif 139 140/* ARGSUSED */ 141void 142dcmputchar(dev_t dev, int c) 143{ 144 struct dcmdevice *dcm = dcmcnaddr; 145 struct dcmpreg *pp; 146 int timo; 147 unsigned int tail; 148 int port, stat; 149 150 port = DCMCONUNIT; 151 pp = dcm_preg(dcm, port); 152 tail = pp->t_tail & TX_MASK; 153 timo = 50000; 154 while (tail != (pp->t_head & TX_MASK) && --timo) 155 ; 156 dcm->dcm_tfifos[3-port][tail].data_char = c; 157 pp->t_tail = tail = (tail + 1) & TX_MASK; 158 SEM_LOCK(dcm); 159 dcm->dcm_cmdtab[port].dcm_data |= CT_TX; 160 dcm->dcm_cr |= (1 << port); 161 SEM_UNLOCK(dcm); 162 timo = 1000000; 163 while (tail != (pp->t_head & TX_MASK) && --timo) 164 ; 165 SEM_LOCK(dcm); 166 stat = dcm->dcm_iir; 167 SEM_UNLOCK(dcm); 168} 169#endif 170