diff options
| author | thorpej <thorpej@NetBSD.org> | 1996-09-25 20:44:09 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 1996-09-25 20:44:09 +0000 |
| commit | 63b18ee2f2e7f9877f6860b548180b39e79eacf0 (patch) | |
| tree | e741ca5e56da4784ab470b10a4233674a4f4a2f7 /sys/dev | |
| parent | 75fd343a785a256b5edc4c99185e67a8c6bf4894 (diff) | |
This file is now obsolete.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/isa/cy.c | 1617 |
1 files changed, 0 insertions, 1617 deletions
diff --git a/sys/dev/isa/cy.c b/sys/dev/isa/cy.c deleted file mode 100644 index 84ad1088a53..00000000000 --- a/sys/dev/isa/cy.c +++ /dev/null @@ -1,1617 +0,0 @@ -/* $NetBSD: cy.c,v 1.15 1996/09/05 15:35:09 mycroft Exp $ */ - -/* XXX THIS DRIVER IS BROKEN. IT WILL NOT EVEN COMPILE. */ - -/* - * cyclades cyclom-y serial driver - * Andrew Herbert <andrew@werple.apana.org.au>, 17 August 1993 - * - * Copyright (c) 1993 Andrew Herbert. - * All rights reserved. - * - * 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. The name Andrew Herbert may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY ``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 I 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. - */ - -/* - * Device minor number encoding: - * - * c c x x u u u u - bits in the minor device number - * - * bits meaning - * ---- ------- - * uuuu physical serial line (i.e. unit) to use - * 0-7 on a cyclom-8Y, 0-15 on a cyclom-16Y - * xx unused - * cc carrier control mode - * 00 complete hardware carrier control of the tty. - * DCD must be high for the open(2) to complete. - * 01 dialin pseudo-device (not yet implemented) - * 10 carrier ignored until a high->low transition - * 11 carrier completed ignored - */ - -/* - * Known deficiencies: - * - * * no BREAK handling - breaks are ignored, and can't be sent either - * * no support for bad-char reporting, except via PARMRK - * * no support for dialin + dialout devices - */ - -#include "cy.h" -#if NCY > 0 - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/ioctl.h> -#include <sys/tty.h> -#include <sys/proc.h> -#include <sys/user.h> -#include <sys/conf.h> -#include <sys/file.h> -#include <sys/uio.h> -#include <sys/kernel.h> -#include <sys/syslog.h> - -#include <machine/cpu.h> -#include <machine/pio.h> -#include <machine/cpufunc.h> - -#include <i386/isa/isa_device.h> /* XXX BROKEN */ -#include <dev/ic/cd1400reg.h> - -#define RxFifoThreshold 3 /* 3 characters (out of 12) in the receive - * FIFO before an interrupt is generated - */ -#define FastRawInput /* bypass the regular char-by-char canonical input - * processing whenever possible - */ -#define PollMode /* use polling-based irq service routine, not the - * hardware svcack lines. Must be defined for - * cyclom-16y boards. - * - * XXX cyclom-8y doesn't work without this defined - * either (!) - */ -#undef LogOverruns /* log receive fifo overruns */ -#undef TxBuffer /* buffer driver output, to be slightly more - * efficient - * - * XXX presently buggy - */ -#undef Smarts /* enable slightly more CD1400 intelligence. Mainly - * the output CR/LF processing, plus we can avoid a - * few checks usually done in ttyinput(). - * - * XXX not yet implemented, and not particularly - * worthwhile either. - */ -#define CyDebug /* include debugging code (minimal effect on - * performance) - */ - -#define CY_RX_BUFS 2 /* two receive buffers per port */ -#define CY_RX_BUF_SIZE 256 /* bytes per receive buffer */ -#define CY_TX_BUF_SIZE 512 /* bytes per transmit buffer */ - -/* #define CD1400s_PER_CYCLOM 1 */ /* cyclom-4y */ -#define CD1400s_PER_CYCLOM 2 /* cyclom-8y */ -/* #define CD1400s_PER_CYCLOM 4 */ /* cyclom-16y */ - -#if CD1400s_PER_CYCLOM < 4 -#define CD1400_MEMSIZE 0x400 /* 4*256 bytes per chip: cyclom-[48]y */ -#else -#define CD1400_MEMSIZE 0x100 /* 256 bytes per chip: cyclom-16y */ - /* XXX or is it 0x400 like the rest? */ -#endif - -#define PORTS_PER_CYCLOM (CD1400_NO_OF_CHANNELS * CD1400s_PER_CYCLOM) -#define CYCLOM_RESET_16 0x1400 /* cyclom-16y reset */ -#define CYCLOM_CLEAR_INTR 0x1800 /* intr ack address */ -#define CYCLOM_CLOCK 25000000 /* baud rate clock */ - -#define CY_UNITMASK 0x0f -#define CY_CARRIERMASK 0xC0 -#define CY_CARRIERSHIFT 6 - -#define UNIT(x) (minor(x) & CY_UNITMASK) -#define CARRIER_MODE(x) ((minor(x) & CY_CARRIERMASK) >> CY_CARRIERSHIFT) - -typedef u_char * volatile cy_addr; - -int cyprobe(struct isa_device *dev); -int cyattach(struct isa_device *isdp); -void cystart(struct tty *tp); -int cyparam(struct tty *tp, struct termios *t); -int cyspeed(int speed, int *prescaler_io); -static void cy_channel_init(dev_t dev, int reset); -static void cd1400_channel_cmd(cy_addr base, u_char cmd); - -void delay(int delay); - -extern unsigned int delaycount; /* calibrated 1 ms cpu-spin delay */ - -struct isa_driver cydriver = { - cyprobe, cyattach, "cy" -}; - -/* low-level ping-pong buffer structure */ - -struct cy_buf { - u_char *next_char; /* location of next char to write */ - u_int free; /* free chars remaining in buffer */ - struct cy_buf *next_buf; /* circular, you know */ - u_char buf[CY_RX_BUF_SIZE]; /* start of the buffer */ -}; - -/* low-level ring buffer */ - -#ifdef TxBuffer -struct cy_ring { - u_char buf[CY_TX_BUF_SIZE]; - u_char *head; - u_char *tail; /* next pos. to insert char */ - u_char *endish; /* physical end of buf */ - u_int used; /* no. of chars in queue */ -}; -#endif - - -/* - * define a structure to keep track of each serial line - */ - -struct cy { - cy_addr base_addr; /* base address of this port's cd1400 */ - struct tty *tty; - u_int dtrwait; /* time (in ticks) to hold dtr low after close */ - u_int recv_exception; /* exception chars received */ - u_int recv_normal; /* normal chars received */ - u_int xmit; /* chars transmitted */ - u_int mdm; /* modem signal changes */ -#ifdef CyDebug - u_int start_count; /* no. of calls to cystart() */ - u_int start_real; /* no. of calls that did something */ -#endif - u_char carrier_mode; /* hardware carrier handling mode */ - /* - * 0 = always use - * 1 = always use (dialin port) - * 2 = ignore during open, then use it - * 3 = ignore completely - */ - u_char carrier_delta; /* true if carrier has changed state */ - u_char fifo_overrun; /* true if cd1400 receive fifo has... */ - u_char rx_buf_overrun; /* true if low-level buf overflow */ - u_char intr_enable; /* CD1400 SRER shadow */ - u_char modem_sig; /* CD1400 modem signal shadow */ - u_char channel_control;/* CD1400 CCR control command shadow */ - u_char cor[3]; /* CD1400 COR1-3 shadows */ -#ifdef Smarts - u_char spec_char[4]; /* CD1400 SCHR1-4 shadows */ -#endif - struct cy_buf *rx_buf; /* current receive buffer */ - struct cy_buf rx_buf_pool[CY_RX_BUFS];/* receive ping-pong buffers */ -#ifdef TxBuffer - struct cy_ring tx_buf; /* transmit buffer */ -#endif -}; - -int cydefaultrate = TTYDEF_SPEED; -cy_addr cyclom_base; /* base address of the card */ -static struct cy *info[NCY*PORTS_PER_CYCLOM]; -struct tty *cy_tty[NCY*PORTS_PER_CYCLOM]; -static volatile u_char timeout_scheduled = 0; /* true if a timeout has been scheduled */ - -#ifdef CyDebug -u_int cy_svrr_probes = 0; /* debugging */ -u_int cy_timeouts = 0; -u_int cy_timeout_req = 0; -#endif - -/**********************************************************************/ - -int -cyprobe(struct isa_device *dev) -{ - int i, j; - u_char version = 0; /* firmware version */ - - /* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */ - i = *(cy_addr)(dev->id_maddr + CYCLOM_RESET_16); - - delay(500); /* wait for the board to get its act together (500 us) */ - - for (i = 0; i < CD1400s_PER_CYCLOM; i++) { - cy_addr base = dev->id_maddr + i * CD1400_MEMSIZE; - - /* wait for chip to become ready for new command */ - for (j = 0; j < 100; j += 50) { - delay(50); /* wait 50 us */ - - if (!*(base + CD1400_CCR)) - break; - } - - /* clear the GFRCR register */ - *(base + CD1400_GFRCR) = 0; - - /* issue a reset command */ - *(base + CD1400_CCR) = CD1400_CMD_RESET; - - /* wait for the CD1400 to initialise itself */ - for (j = 0; j < 1000; j += 50) { - delay(50); /* wait 50 us */ - - /* retrieve firmware version */ - version = *(base + CD1400_GFRCR); - if (version) - break; - } - - /* anything in the 40-4f range is fine */ - if ((version & 0xf0) != 0x40) { - return 0; - } - } - - return 1; /* found */ -} - - -int -cyattach(struct isa_device *isdp) -{ -/* u_char unit = UNIT(isdp->id_unit); */ - int i, j, k; - - /* global variable used various routines */ - cyclom_base = (cy_addr)isdp->id_maddr; - - for (i = 0, k = 0; i < CD1400s_PER_CYCLOM; i++) { - cy_addr base = cyclom_base + i * CD1400_MEMSIZE; - - /* setup a 1ms clock tick */ - *(base + CD1400_PPR) = CD1400_CLOCK_25_1MS; - - for (j = 0; j < CD1400_NO_OF_CHANNELS; j++, k++) { - struct cy *ip; - - /* - * grab some space. it'd be more polite to do this in cyopen(), - * but hey. - */ - info[k] = ip = malloc(sizeof(struct cy), M_DEVBUF, M_WAITOK); - - /* clear all sorts of junk */ - bzero(ip, sizeof(struct cy)); - - ip->base_addr = base; - - /* initialise the channel, without resetting it first */ - cy_channel_init(k, 0); - } - } - - /* clear interrupts */ - *(cyclom_base + CYCLOM_CLEAR_INTR) = (u_char)0; - - return 1; -} - - -int -cyopen(dev_t dev, int flag, int mode, struct proc *p) -{ - u_int unit = UNIT(dev); - struct cy *infop; - cy_addr base; - struct tty *tp; - int error = 0; - u_char carrier; - - if (unit >= PORTS_PER_CYCLOM) - return (ENXIO); - - infop = info[unit]; - base = infop->base_addr; - if (!cy_tty[unit]) { - infop->tty = cy_tty[unit] = ttymalloc(); - tty_attach(infop->tty); - } - tp = infop->tty; - - tp->t_oproc = cystart; - tp->t_param = cyparam; - tp->t_dev = dev; - if (!(tp->t_state & TS_ISOPEN)) { - tp->t_state |= TS_WOPEN; - ttychars(tp); - if (tp->t_ispeed == 0) { - tp->t_iflag = TTYDEF_IFLAG; - tp->t_oflag = TTYDEF_OFLAG; - tp->t_cflag = TTYDEF_CFLAG; - tp->t_lflag = TTYDEF_LFLAG; - tp->t_ispeed = tp->t_ospeed = cydefaultrate; - } - - (void) spltty(); - cy_channel_init(unit, 1); /* reset the hardware */ - - /* - * raise dtr and generally set things up correctly. this - * has the side-effect of selecting the appropriate cd1400 - * channel, to help us with subsequent channel control stuff - */ - cyparam(tp, &tp->t_termios); - - /* check carrier, and set t_state's TS_CARR_ON flag accordingly */ - infop->modem_sig = *(base + CD1400_MSVR); - carrier = infop->modem_sig & CD1400_MSVR_CD; - - if (carrier || (infop->carrier_mode >= 2)) - tp->t_state |= TS_CARR_ON; - else - tp->t_state &=~ TS_CARR_ON; - - /* - * enable modem & rx interrupts - relies on cyparam() - * having selected the appropriate cd1400 channel - */ - infop->intr_enable = (1 << 7) | (1 << 4); - *(base + CD1400_SRER) = infop->intr_enable; - - ttsetwater(tp); - } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) - return (EBUSY); - - if (!(flag & O_NONBLOCK)) - while (!(tp->t_cflag & CLOCAL) && - !(tp->t_state & TS_CARR_ON) && !error) - error = ttysleep(tp, (caddr_t)&tp->t_rawq, - TTIPRI|PCATCH, ttopen, 0); - (void) spl0(); - - if (!error) - error = (*linesw[(u_char)tp->t_line].l_open)(dev, tp); - return (error); -} /* end of cyopen() */ - - -void -cyclose_wakeup(caddr_t arg) -{ - wakeup(arg); -} /* end of cyclose_wakeup() */ - - -int -cyclose(dev_t dev, int flag, int mode, struct proc *p) -{ - u_int unit = UNIT(dev); - struct cy *infop = info[unit]; - struct tty *tp = infop->tty; - cy_addr base = infop->base_addr; - int s; - - (*linesw[(u_char)tp->t_line].l_close)(tp, flag); - - s = spltty(); - /* select the appropriate channel on the CD1400 */ - *(base + CD1400_CAR) = (u_char)(unit & 0x03); - - /* disable this channel and lower DTR */ - infop->intr_enable = 0; - *(base + CD1400_SRER) = (u_char)0; /* no intrs */ - *(base + CD1400_DTR) = (u_char)CD1400_DTR_CLEAR; /* no DTR */ - infop->modem_sig &= ~CD1400_MSVR_DTR; - - /* disable receiver (leave transmitter enabled) */ - infop->channel_control = (1 << 4) | (1 << 3) | 1; - cd1400_channel_cmd(base, infop->channel_control); - splx(s); - - ttyclose(tp); -#ifdef broken /* session holds a ref to the tty; can't deallocate */ - ttyfree(tp); - infop->tty = cy_tty[unit] = (struct tty *)NULL; -#endif - - if (infop->dtrwait) { - int error; - - timeout(cyclose_wakeup, (caddr_t)&infop->dtrwait, infop->dtrwait); - do { - error = tsleep((caddr_t)&infop->dtrwait, - TTIPRI|PCATCH, "cyclose", 0); - } while (error == ERESTART); - } - - return 0; -} /* end of cyclose() */ - - -int -cyread(dev_t dev, struct uio *uio, int flag) -{ - u_int unit = UNIT(dev); - struct tty *tp = info[unit]->tty; - - return (*linesw[(u_char)tp->t_line].l_read)(tp, uio, flag); -} /* end of cyread() */ - - -int -cywrite(dev_t dev, struct uio *uio, int flag) -{ - u_int unit = UNIT(dev); - struct tty *tp = info[unit]->tty; - -#ifdef Smarts - /* XXX duplicate ttwrite(), but without so much output processing on - * CR & LF chars. Hardly worth the effort, given that high-throughput - * sessions are raw anyhow. - */ -#else - return (*linesw[(u_char)tp->t_line].l_write)(tp, uio, flag); -#endif -} /* end of cywrite() */ - - -#ifdef Smarts -/* standard line discipline input routine */ -int -cyinput(int c, struct tty *tp) -{ - /* XXX duplicate ttyinput(), but without the IXOFF/IXON/ISTRIP/IPARMRK - * bits, as they are done by the CD1400. Hardly worth the effort, - * given that high-throughput sessions are raw anyhow. - */ -} /* end of cyinput() */ -#endif /* Smarts */ - - -inline static void -service_upper_rx(int unit) -{ - struct cy *ip = info[unit]; - struct tty *tp = ip->tty; - struct cy_buf *buf; - int i; - u_char *ch; - - buf = ip->rx_buf; - - /* give service_rx() a new one */ - disable_intr(); /* faster than spltty() */ - ip->rx_buf = buf->next_buf; - enable_intr(); - - if (tp->t_state & TS_ISOPEN) { - ch = buf->buf; - i = buf->next_char - buf->buf; - -#ifdef FastRawInput - /* try to avoid calling the line discipline stuff if we can */ - if ((tp->t_line == 0) && - !(tp->t_iflag & (ICRNL | IMAXBEL | INLCR)) && - !(tp->t_lflag & (ECHO | ECHONL | ICANON | IEXTEN | - ISIG | PENDIN)) && - !(tp->t_state & (TS_CNTTB | TS_LNCH))) { - - i = b_to_q(ch, i, &tp->t_rawq); - if (i) { - /* - * we have no RTS flow control support on cy-8 - * boards, so this is really just tough luck - */ - - log(LOG_WARNING, "cy%d: tty input queue overflow\n", - unit); - } - - ttwakeup(tp); /* notify any readers */ - } - else -#endif /* FastRawInput */ - { - while (i--) - (*linesw[(u_char)tp->t_line].l_rint)((int)*ch++, tp); - } - } - - /* clear the buffer we've just processed */ - buf->next_char = buf->buf; - buf->free = CY_RX_BUF_SIZE; -} /* end of service_upper_rx() */ - - -#ifdef TxBuffer -static void -service_upper_tx(int unit) -{ - struct cy *ip = info[unit]; - struct tty *tp = ip->tty; - - tp->t_state &=~ (TS_BUSY|TS_FLUSH); - - 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) { - struct cy_ring *txq = &ip->tx_buf; - int free_count = CY_TX_BUF_SIZE - ip->tx_buf.used; - u_char *cp = txq->tail; - int count; - int chars_done; - - tp->t_state |= TS_BUSY; - - /* find the largest contig. copy we can do */ - count = ((txq->endish - cp) > free_count) ? - free_count : txq->endish - cp; - - count = ((cp + free_count) > txq->endish) ? - txq->endish - cp : free_count; - - /* copy the first slab */ - chars_done = q_to_b(&tp->t_outq, cp, count); - - /* check for wrap-around time */ - cp += chars_done; - if (cp == txq->endish) - cp = txq->buf; /* back to the start */ - - /* copy anything else, after we've wrapped around */ - if ((chars_done == count) && (count != free_count)) { - /* copy the second slab */ - count = q_to_b(&tp->t_outq, cp, free_count - count); - cp += count; - chars_done += count; - } - - /* - * update queue, protecting ourselves from any rampant - * lower-layers - */ - disable_intr(); - txq->tail = cp; - txq->used += chars_done; - enable_intr(); - } - - if (!tp->t_outq.c_cc) - tp->t_state &=~ TS_BUSY; -} /* end of service_upper_tx() */ -#endif /* TxBuffer */ - - -inline static void -service_upper_mdm(int unit) -{ - struct cy *ip = info[unit]; - - if (ip->carrier_delta) { - int carrier = ip->modem_sig & CD1400_MSVR_CD; - struct tty *tp = ip->tty; - - if (!(*linesw[(u_char)tp->t_line].l_modem)(tp, carrier)) { - cy_addr base = ip->base_addr; - - /* clear DTR */ - disable_intr(); - *(base + CD1400_CAR) = (u_char)(unit & 0x03); - *(base + CD1400_DTR) = (u_char)CD1400_DTR_CLEAR; - ip->modem_sig &= ~CD1400_MSVR_DTR; - ip->carrier_delta = 0; - enable_intr(); - } - else { - disable_intr(); - ip->carrier_delta = 0; - enable_intr(); - } - } -} /* end of service_upper_mdm() */ - - -/* upper level character processing routine */ -static void -cytimeout(caddr_t ptr) -{ - int unit; - - timeout_scheduled = 0; - -#ifdef CyDebug - cy_timeouts++; -#endif - - /* check each port in turn */ - for (unit = 0; unit < NCY*PORTS_PER_CYCLOM; unit++) { - struct cy *ip = info[unit]; -#ifndef TxBuffer - struct tty *tp = ip->tty; -#endif - - /* ignore anything that is not open */ - if (!ip->tty) - continue; - - /* - * any received chars to handle? (doesn't matter if intr routine - * kicks in while we're testing this) - */ - if (ip->rx_buf->free != CY_RX_BUF_SIZE) - service_upper_rx(unit); - -#ifdef TxBuffer - /* anything to add to the transmit buffer (low-water mark)? */ - if (ip->tx_buf.used < CY_TX_BUF_SIZE/2) - service_upper_tx(unit); -#else - 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); - } -#endif - - /* anything modem signals altered? */ - service_upper_mdm(unit); - - /* any overruns to log? */ -#ifdef LogOverruns - if (ip->fifo_overrun) { - /* - * turn off the alarm - not important enough to bother - * with interrupt protection. - */ - ip->fifo_overrun = 0; - - log(LOG_WARNING, "cy%d: receive fifo overrun\n", unit); - } -#endif - if (ip->rx_buf_overrun) { - /* - * turn off the alarm - not important enough to bother - * with interrupt protection. - */ - ip->rx_buf_overrun = 0; - - log(LOG_WARNING, "cy%d: receive buffer full\n", unit); - } - } -} /* cytimeout() */ - - -inline static void -schedule_upper_service(void) -{ -#ifdef CyDebug - cy_timeout_req++; -#endif - - if (!timeout_scheduled) { - timeout(cytimeout, (caddr_t)0, 1); /* call next tick */ - timeout_scheduled = 1; - } -} /* end of schedule_upper_service() */ - - -/* initialise a channel on the cyclom board */ - -static void -cy_channel_init(dev_t dev, int reset) -{ - u_int unit = UNIT(dev); - int carrier_mode = CARRIER_MODE(dev); - struct cy *ip = info[unit]; - cy_addr base = ip->base_addr; - struct tty *tp = ip->tty; - struct cy_buf *buf, *next_buf; - int i; -#ifndef PollMode - u_char cd1400_unit; -#endif - - /* clear the structure and refill it */ - bzero(ip, sizeof(struct cy)); - ip->base_addr = base; - ip->tty = tp; - ip->carrier_mode = carrier_mode; - - /* select channel of the CD1400 */ - *(base + CD1400_CAR) = (u_char)(unit & 0x03); - - if (reset) - cd1400_channel_cmd(base, 0x80); /* reset the channel */ - - /* set LIVR to 0 - intr routines depend on this */ - *(base + CD1400_LIVR) = 0; - -#ifndef PollMode - /* set top four bits of {R,T,M}ICR to the cd1400 - * number, cd1400_unit - */ - cd1400_unit = unit / CD1400_NO_OF_CHANNELS; - *(base + CD1400_RICR) = (u_char)(cd1400_unit << 4); - *(base + CD1400_TICR) = (u_char)(cd1400_unit << 4); - *(base + CD1400_MICR) = (u_char)(cd1400_unit << 4); -#endif - - ip->dtrwait = hz/4; /* quarter of a second */ - - /* setup low-level buffers */ - i = CY_RX_BUFS; - ip->rx_buf = next_buf = &ip->rx_buf_pool[0]; - while (i--) { - buf = &ip->rx_buf_pool[i]; - - buf->next_char = buf->buf; /* first char to use */ - buf->free = CY_RX_BUF_SIZE; /* i.e. empty */ - buf->next_buf = next_buf; /* where to go next */ - next_buf = buf; - } - -#ifdef TxBuffer - ip->tx_buf.endish = ip->tx_buf.buf + CY_TX_BUF_SIZE; - - /* clear the low-level tx buffer */ - ip->tx_buf.head = ip->tx_buf.tail = ip->tx_buf.buf; - ip->tx_buf.used = 0; -#endif - - /* clear the low-level rx buffer */ - ip->rx_buf->next_char = ip->rx_buf->buf; /* first char to use */ - ip->rx_buf->free = CY_RX_BUF_SIZE; /* completely empty */ -} /* end of cy_channel_init() */ - - -/* service a receive interrupt */ -inline static void -service_rx(int cd, caddr_t base) -{ - struct cy *infop; - unsigned count; - int ch; - u_char serv_type, channel; -#ifdef PollMode - u_char save_rir, save_car; -#endif - - /* setup */ -#ifdef PollMode - save_rir = *(base + CD1400_RIR); - channel = cd * CD1400_NO_OF_CHANNELS + (save_rir & 0x3); - save_car = *(base + CD1400_CAR); - *(base + CD1400_CAR) = save_rir; /* enter modem service */ - serv_type = *(base + CD1400_RIVR); -#else - serv_type = *(base + CD1400_SVCACKR); /* ack receive service */ - channel = ((u_char)*(base + CD1400_RICR)) >> 2; /* get cyclom channel # */ - -#ifdef CyDebug - if (channel >= PORTS_PER_CYCLOM) { - printf("cy: service_rx - channel %02x\n", channel); - panic("cy: service_rx - bad channel"); - } -#endif -#endif - - infop = info[channel]; - - /* read those chars */ - if (serv_type & CD1400_RIVR_EXCEPTION) { - /* read the exception status */ - u_char status = *(base + CD1400_RDSR); - - /* XXX is it a break? Do something if it is! */ - - /* XXX is IGNPAR not set? Store a null in the buffer. */ - -#ifdef LogOverruns - if (status & CD1400_RDSR_OVERRUN) { -#if 0 - ch |= TTY_PE; /* for SLIP */ -#endif - infop->fifo_overrun++; - } -#endif - infop->recv_exception++; - } - else { - struct cy_buf *buf = infop->rx_buf; - - count = (u_char)*(base + CD1400_RDCR); /* how many to read? */ - infop->recv_normal += count; - if (buf->free < count) { - infop->rx_buf_overrun += count; - - /* read & discard everything */ - while (count--) - ch = (u_char)*(base + CD1400_RDSR); - } - else { - /* slurp it into our low-level buffer */ - buf->free -= count; - while (count--) { - ch = (u_char)*(base + CD1400_RDSR); /* read the char */ - *(buf->next_char++) = ch; - } - } - } - -#ifdef PollMode - *(base + CD1400_RIR) = (u_char)(save_rir & 0x3f); /* terminate service context */ -#else - *(base + CD1400_EOSRR) = (u_char)0; /* terminate service context */ -#endif -} /* end of service_rx */ - - -/* service a transmit interrupt */ -inline static void -service_tx(int cd, caddr_t base) -{ - struct cy *ip; -#ifdef TxBuffer - struct cy_ring *txq; -#else - struct tty *tp; -#endif - u_char channel; -#ifdef PollMode - u_char save_tir, save_car; -#else - u_char vector; -#endif - - /* setup */ -#ifdef PollMode - save_tir = *(base + CD1400_TIR); - channel = cd * CD1400_NO_OF_CHANNELS + (save_tir & 0x3); - save_car = *(base + CD1400_CAR); - *(base + CD1400_CAR) = save_tir; /* enter tx service */ -#else - vector = *(base + CD1400_SVCACKT); /* ack transmit service */ - channel = ((u_char)*(base + CD1400_TICR)) >> 2; /* get cyclom channel # */ - -#ifdef CyDebug - if (channel >= PORTS_PER_CYCLOM) { - printf("cy: service_tx - channel %02x\n", channel); - panic("cy: service_tx - bad channel"); - } -#endif -#endif - - ip = info[channel]; -#ifdef TxBuffer - txq = &ip->tx_buf; - - if (txq->used > 0) { - cy_addr base = ip->base_addr; - int count = min(CD1400_FIFOSIZE, txq->used); - int chars_done = count; - u_char *cp = txq->head; - u_char *buf_end = txq->endish; - - /* ip->state |= CY_BUSY; */ - while (count--) { - *(base + CD1400_TDR) = *cp++; - if (cp >= buf_end) - cp = txq->buf; - }; - txq->head = cp; - txq->used -= chars_done; /* important that this is atomic */ - ip->xmit += chars_done; - } - - /* - * disable tx intrs if no more chars to send. we re-enable - * them in cystart() - */ - if (!txq->used) { - ip->intr_enable &=~ (1 << 2); - *(base + CD1400_SRER) = ip->intr_enable; - /* ip->state &= ~CY_BUSY; */ - } -#else - tp = ip->tty; - - if (!(tp->t_state & TS_TTSTOP) && (tp->t_outq.c_cc > 0)) { - cy_addr base = ip->base_addr; - int count = min(CD1400_FIFOSIZE, tp->t_outq.c_cc); - - ip->xmit += count; - tp->t_state |= TS_BUSY; - while (count--) - *(base + CD1400_TDR) = getc(&tp->t_outq); - } - - /* - * disable tx intrs if no more chars to send. we re-enable them - * in cystart() - */ - if (!tp->t_outq.c_cc) { - ip->intr_enable &=~ (1 << 2); - *(base + CD1400_SRER) = ip->intr_enable; - tp->t_state &= ~TS_BUSY; - } -#endif - -#ifdef PollMode - *(base + CD1400_TIR) = (u_char)(save_tir & 0x3f); /* terminate service context */ -#else - *(base + CD1400_EOSRR) = (u_char)0; /* terminate service context */ -#endif -} /* end of service_tx */ - - -/* service a modem status interrupt */ -inline static void -service_mdm(int cd, caddr_t base) -{ - struct cy *infop; - u_char channel, deltas; -#ifdef PollMode - u_char save_mir, save_car; -#else - u_char vector; -#endif - - /* setup */ -#ifdef PollMode - save_mir = *(base + CD1400_MIR); - channel = cd * CD1400_NO_OF_CHANNELS + (save_mir & 0x3); - save_car = *(base + CD1400_CAR); - *(base + CD1400_CAR) = save_mir; /* enter modem service */ -#else - vector = *(base + CD1400_SVCACKM); /* ack modem service */ - channel = ((u_char)*(base + CD1400_MICR)) >> 2; /* get cyclom channel # */ - -#ifdef CyDebug - if (channel >= PORTS_PER_CYCLOM) { - printf("cy: service_mdm - channel %02x\n", channel); - panic("cy: service_mdm - bad channel"); - } -#endif -#endif - - infop = info[channel]; - - /* read the siggies and see what's changed */ - infop->modem_sig = (u_char)*(base + CD1400_MSVR); - deltas = (u_char)*(base + CD1400_MISR); - - if ((infop->carrier_mode <= 2) && (deltas & CD1400_MISR_CDd)) - /* something for the upper layer to deal with */ - infop->carrier_delta = 1; - - infop->mdm++; - - /* terminate service context */ -#ifdef PollMode - *(base + CD1400_MIR) = (u_char)(save_mir & 0x3f); -#else - *(base + CD1400_EOSRR) = (u_char)0; -#endif -} /* end of service_mdm */ - - -int -cyintr(int unit) -{ - int cd; - u_char status; - - /* check each CD1400 in turn */ - for (cd = 0; cd < CD1400s_PER_CYCLOM; cd++) { - cy_addr base = cyclom_base + cd*CD1400_MEMSIZE; - - /* poll to see if it has any work */ - while (status = (u_char)*(base + CD1400_SVRR)) { -#ifdef CyDebug - cy_svrr_probes++; -#endif - /* service requests as appropriate, giving priority to RX */ - if (status & CD1400_SVRR_RX) - service_rx(cd, base); - if (status & CD1400_SVRR_TX) - service_tx(cd, base); - if (status & CD1400_SVRR_MDM) - service_mdm(cd, base); - } - } - - /* request upper level service to deal with whatever happened */ - schedule_upper_service(); - - /* re-enable interrupts on the cyclom */ - *(cyclom_base + CYCLOM_CLEAR_INTR) = (u_char)0; - - return 1; -} - - -int -cyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) -{ - int unit = UNIT(dev); - struct cy *infop = info[unit]; - struct tty *tp = infop->tty; - int error; - - error = (*linesw[(u_char)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) { -#ifdef notyet /* sigh - more junk to do XXX */ - case TIOCSBRK: - break; - case TIOCCBRK: - break; - case TIOCSDTR: - break; - case TIOCCDTR: - break; - - case TIOCMSET: - break; - case TIOCMBIS: - break; - case TIOCMBIC: - break; -#endif /* notyet */ - - case TIOCMGET: { - int bits = 0; - u_char status = infop->modem_sig; - - if (status & CD1400_MSVR_DTR) bits |= TIOCM_DTR | TIOCM_RTS; - if (status & CD1400_MSVR_CD) bits |= TIOCM_CD; - if (status & CD1400_MSVR_CTS) bits |= TIOCM_CTS; - if (status & CD1400_MSVR_DSR) bits |= TIOCM_DSR; -#ifdef CYCLOM_16 - if (status & CD1400_MSVR_RI) bits |= TIOCM_RI; -#endif - if (infop->channel_control & 0x02) bits |= TIOCM_LE; - *(int *)data = bits; - break; - } - -#ifdef TIOCMSBIDIR - case TIOCMSBIDIR: - return (ENOTTY); -#endif /* TIOCMSBIDIR */ - -#ifdef TIOCMGBIDIR - case TIOCMGBIDIR: - return (ENOTTY); -#endif /* TIOCMGBIDIR */ - -#ifdef TIOCMSDTRWAIT - case TIOCMSDTRWAIT: - /* must be root to set dtr delay */ - if (p->p_ucred->cr_uid != 0) - return(EPERM); - - infop->dtrwait = *(u_int *)data; - break; -#endif /* TIOCMSDTRWAIT */ - -#ifdef TIOCMGDTRWAIT - case TIOCMGDTRWAIT: - *(u_int *)data = infop->dtrwait; - break; -#endif /* TIOCMGDTRWAIT */ - - default: - return (ENOTTY); - } - - return 0; -} /* end of cyioctl() */ - - -int -cyparam(struct tty *tp, struct termios *t) -{ - u_char unit = UNIT(tp->t_dev); - struct cy *infop = info[unit]; - cy_addr base = infop->base_addr; - int cflag = t->c_cflag; - int iflag = t->c_iflag; - int ispeed, ospeed; - int itimeout; - int iprescaler, oprescaler; - int s; - u_char cor_change = 0; - u_char opt; - - if (!t->c_ispeed) - t->c_ispeed = t->c_ospeed; - - s = spltty(); - - /* select the appropriate channel on the CD1400 */ - *(base + CD1400_CAR) = unit & 0x03; - - /* handle DTR drop on speed == 0 trick */ - if (t->c_ospeed == 0) { - *(base + CD1400_DTR) = CD1400_DTR_CLEAR; - infop->modem_sig &= ~CD1400_MSVR_DTR; - } - else { - *(base + CD1400_DTR) = CD1400_DTR_SET; - infop->modem_sig |= CD1400_MSVR_DTR; - } - - /* set baud rates if they've changed from last time */ - - if ((ospeed = cyspeed(t->c_ospeed, &oprescaler)) < 0) - return EINVAL; - *(base + CD1400_TBPR) = (u_char)ospeed; - *(base + CD1400_TCOR) = (u_char)oprescaler; - - if ((ispeed = cyspeed(t->c_ispeed, &iprescaler)) < 0) - return EINVAL; - *(base + CD1400_RBPR) = (u_char)ispeed; - *(base + CD1400_RCOR) = (u_char)iprescaler; - - /* - * set receive time-out period - * generate a rx interrupt if no new chars are received in - * this many ticks - * don't bother comparing old & new VMIN, VTIME and ispeed - it - * can't be much worse just to calculate and set it each time! - * certainly less hassle. :-) - */ - - /* - * calculate minimum timeout period: - * 5 ms or the time it takes to receive 1 char, rounded up to the - * next ms, whichever is greater - */ - if (t->c_ispeed > 0) { - itimeout = (t->c_ispeed > 2200) ? 5 : (10000/t->c_ispeed + 1); - - /* if we're using VTIME as an inter-char timeout, and it is set to - * be longer than the minimum calculated above, go for it - */ - if (t->c_cc[VMIN] && t->c_cc[VTIME] && t->c_cc[VTIME]*10 > itimeout) - itimeout = t->c_cc[VTIME]*10; - - /* store it, taking care not to overflow the byte-sized register */ - *(base + CD1400_RTPR) = (u_char)((itimeout <= 255) ? itimeout : 255); - } - - - /* - * channel control - * receiver enable - * transmitter enable (always set) - */ - opt = (1 << 4) | (1 << 3) | ((cflag & CREAD) ? (1 << 1) : 1); - if (opt != infop->channel_control) { - infop->channel_control = opt; - cd1400_channel_cmd(base, opt); - } - -#ifdef Smarts - /* set special chars */ - if (t->c_cc[VSTOP] != _POSIX_VDISABLE && - (t->c_cc[VSTOP] != infop->spec_char[0])) { - *(base + CD1400_SCHR1) = infop->spec_char[0] = t->c_cc[VSTOP]; - } - if (t->c_cc[VSTART] != _POSIX_VDISABLE && - (t->c_cc[VSTART] != infop->spec_char[1])) { - *(base + CD1400_SCHR2) = infop->spec_char[0] = t->c_cc[VSTART]; - } - if (t->c_cc[VINTR] != _POSIX_VDISABLE && - (t->c_cc[VINTR] != infop->spec_char[2])) { - *(base + CD1400_SCHR3) = infop->spec_char[0] = t->c_cc[VINTR]; - } - if (t->c_cc[VSUSP] != _POSIX_VDISABLE && - (t->c_cc[VSUSP] != infop->spec_char[3])) { - *(base + CD1400_SCHR4) = infop->spec_char[0] = t->c_cc[VSUSP]; - } -#endif - - /* - * set channel option register 1 - - * parity mode - * stop bits - * char length - */ - opt = 0; - /* parity */ - if (cflag & PARENB) { - if (cflag & PARODD) - opt |= 1 << 7; - opt |= 2 << 5; /* normal parity mode */ - } - if (!(iflag & INPCK)) - opt |= 1 << 4; /* ignore parity */ - /* stop bits */ - if (cflag & CSTOPB) - opt |= 2 << 2; - /* char length */ - opt |= (cflag & CSIZE) >> 8; /* nasty, but fast */ - if (opt != infop->cor[0]) { - cor_change |= 1 << 1; - *(base + CD1400_COR1) = opt; - } - - /* - * set channel option register 2 - - * flow control - */ - opt = 0; -#ifdef Smarts - if (iflag & IXANY) - opt |= 1 << 7; /* auto output restart on any char after XOFF */ - if (iflag & IXOFF) - opt |= 1 << 6; /* auto XOFF output flow-control */ -#endif - if (cflag & CCTS_OFLOW) - opt |= 1 << 1; /* auto CTS flow-control */ - if (opt != infop->cor[1]) { - cor_change |= 1 << 2; - *(base + CD1400_COR2) = opt; - } - - /* - * set channel option register 3 - - * receiver FIFO interrupt threshold - * flow control - */ - opt = RxFifoThreshold; /* rx fifo threshold */ -#ifdef Smarts - if (t->c_lflag & ICANON) - opt |= 1 << 6; /* detect INTR & SUSP chars */ - if (iflag & IXOFF) - opt |= (1 << 5) | (1 << 4); /* transparent in-band flow control */ -#endif - if (opt != infop->cor[2]) { - cor_change |= 1 << 3; - *(base + CD1400_COR3) = opt; - } - - - /* notify the CD1400 if COR1-3 have changed */ - if (cor_change) { - cor_change |= 1 << 6; /* COR change flag */ - cd1400_channel_cmd(base, cor_change); - } - - /* - * set channel option register 4 - - * CR/NL processing - * break processing - * received exception processing - */ - opt = 0; - if (iflag & IGNCR) - opt |= 1 << 7; -#ifdef Smarts - /* - * we need a new ttyinput() for this, as we don't want to - * have ICRNL && INLCR being done in both layers, or to have - * synchronisation problems - */ - if (iflag & ICRNL) - opt |= 1 << 6; - if (iflag & INLCR) - opt |= 1 << 5; -#endif - if (iflag & IGNBRK) - opt |= 1 << 4; - if (!(iflag & BRKINT)) - opt |= 1 << 3; - if (iflag & IGNPAR) -#ifdef LogOverruns - opt |= 0; /* broken chars cause receive exceptions */ -#else - opt |= 2; /* discard broken chars */ -#endif - else { - if (iflag & PARMRK) - opt |= 4; /* precede broken chars with 0xff 0x0 */ - else -#ifdef LogOverruns - opt |= 0; /* broken chars cause receive exceptions */ -#else - opt |= 3; /* convert framing/parity errs to nulls */ -#endif - } - *(base + CD1400_COR4) = opt; - - /* - * set channel option register 5 - - */ - opt = 0; - if (iflag & ISTRIP) - opt |= 1 << 7; - if (t->c_iflag & IEXTEN) { - opt |= 1 << 6; /* enable LNEXT (e.g. ctrl-v quoting) handling */ - } -#ifdef Smarts - if (t->c_oflag & ONLCR) - opt |= 1 << 1; - if (t->c_oflag & OCRNL) - opt |= 1; -#endif - *(base + CD1400_COR5) = opt; - - /* - * set modem change option register 1 - * generate modem interrupts on which 1 -> 0 input transitions - * also controls auto-DTR output flow-control, which we don't use - */ - opt = (cflag & CLOCAL) ? 0 : 1 << 4; /* CD */ - *(base + CD1400_MCOR1) = opt; - - /* - * set modem change option register 2 - * generate modem interrupts on specific 0 -> 1 input transitions - */ - opt = (cflag & CLOCAL) ? 0 : 1 << 4; /* CD */ - *(base + CD1400_MCOR2) = opt; - - splx(s); - - return 0; -} /* end of cyparam */ - - -void -cystart(struct tty *tp) -{ - u_char unit = UNIT(tp->t_dev); - struct cy *infop = info[unit]; - cy_addr base = infop->base_addr; - int s; - -#ifdef CyDebug - infop->start_count++; -#endif - - /* check the flow-control situation */ - if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) - return; - - 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); - } - -#ifdef TxBuffer - service_upper_tx(unit); /* feed the monster */ -#endif - - s = spltty(); - - if (!(infop->intr_enable & (1 << 2))) { - /* select the channel */ - *(base + CD1400_CAR) = unit & (u_char)3; - - /* (re)enable interrupts to set things in motion */ - infop->intr_enable |= (1 << 2); - *(base + CD1400_SRER) = infop->intr_enable; - - infop->start_real++; - } - - splx(s); -} /* end of cystart() */ - - -void -cystop(struct tty *tp, int flag) -{ - u_char unit = UNIT(tp->t_dev); - struct cy *ip = info[unit]; - cy_addr base = ip->base_addr; - int s; - - s = spltty(); - - /* select the channel */ - *(base + CD1400_CAR) = unit & 3; - - /* halt output by disabling transmit interrupts */ - ip->intr_enable &=~ (1 << 2); - *(base + CD1400_SRER) = ip->intr_enable; - - splx(s); -} - - -int -cyspeed(int speed, int *prescaler_io) -{ - int actual; - int error; - int divider; - int prescaler; - int prescaler_unit; - - if (speed == 0) - return 0; - - if (speed < 0 || speed > 150000) - return -1; - - /* determine which prescaler to use */ - for (prescaler_unit = 4, prescaler = 2048; prescaler_unit; - prescaler_unit--, prescaler >>= 2) { - if (CYCLOM_CLOCK/prescaler/speed > 63) - break; - } - - divider = (CYCLOM_CLOCK/prescaler*2/speed + 1)/2; /* round off */ - if (divider > 255) - divider = 255; - actual = CYCLOM_CLOCK/prescaler/divider; - error = ((actual-speed)*2000/speed +1)/2; /* percentage */ - - /* 3.0% max error tolerance */ - if (error < -30 || error > 30) - return -1; - -#if 0 - printf("prescaler = %d (%d)\n", prescaler, prescaler_unit); - printf("divider = %d (%x)\n", divider, divider); - printf("actual = %d\n", actual); - printf("error = %d\n", error); -#endif - - *prescaler_io = prescaler_unit; - return divider; -} /* end of cyspeed() */ - - -static void -cd1400_channel_cmd(cy_addr base, u_char cmd) -{ - unsigned maxwait = delaycount * 5; /* approx. 5 ms */ - - /* wait for processing of previous command to complete */ - while (*(base + CD1400_CCR) && maxwait--) - ; - - if (!maxwait) - log(LOG_ERR, "cy: channel command timeout (%d loops) - arrgh\n", - delaycount * 5); - - *(base + CD1400_CCR) = cmd; -} /* end of cd1400_channel_cmd() */ - - -#ifdef CyDebug -/* useful in ddb */ -void -cyclear(void) -{ - /* clear the timeout request */ - disable_intr(); - timeout_scheduled = 0; - enable_intr(); -} - -void -cyclearintr(void) -{ - /* clear interrupts */ - *(cyclom_base + CYCLOM_CLEAR_INTR) = (u_char)0; -} - -int -cyparam_dummy(struct tty *tp, struct termios *t) -{ - return 0; -} - -void -cyset(int unit, int active) -{ - if (unit < 0 || unit > PORTS_PER_CYCLOM) { - printf("bad unit number %d\n", unit); - return; - } - cy_tty[unit]->t_param = active ? cyparam : cyparam_dummy; -} - - -/* useful in ddb */ -void -cystatus(int unit) -{ - struct cy *infop = info[unit]; - struct tty *tp = infop->tty; - cy_addr base = infop->base_addr; - - printf("info for channel %d\n", unit); - printf("------------------\n"); - - printf("cd1400 base address:\t0x%x\n", (int)infop->base_addr); - - /* select the port */ - *(base + CD1400_CAR) = (u_char)unit; - - printf("saved channel_control:\t%02x\n", infop->channel_control); - printf("saved cor1:\t\t%02x\n", infop->cor[0]); - printf("service request enable reg:\t%02x (%02x cached)\n", - (u_char)*(base + CD1400_SRER), infop->intr_enable); - printf("service request register:\t%02x\n", - (u_char)*(base + CD1400_SVRR)); - printf("\n"); - printf("modem status:\t\t\t%02x (%02x cached)\n", - (u_char)*(base + CD1400_MSVR), infop->modem_sig); - printf("rx/tx/mdm interrupt registers:\t%02x %02x %02x\n", - (u_char)*(base + CD1400_RIR), (u_char)*(base + CD1400_TIR), - (u_char)*(base + CD1400_MIR)); - printf("\n"); - if (tp) { - printf("tty state:\t\t\t%04x\n", tp->t_state); - printf("upper layer queue lengths:\t%d raw, %d canon, %d output\n", - tp->t_rawq.c_cc, tp->t_canq.c_cc, tp->t_outq.c_cc); - } - else - printf("tty state:\t\t\tclosed\n"); - printf("\n"); - - printf("calls to cystart():\t\t%d (%d useful)\n", - infop->start_count, infop->start_real); - printf("\n"); - printf("total cyclom service probes:\t%d\n", cy_svrr_probes); - printf("calls to upper layer:\t\t%d\n", cy_timeouts); - printf("rx buffer chars free:\t\t%d\n", infop->rx_buf->free); -#ifdef TxBuffer - printf("tx buffer chars used:\t\t%d\n", infop->tx_buf.used); -#endif - printf("received chars:\t\t\t%d good, %d exception\n", - infop->recv_normal, infop->recv_exception); - printf("transmitted chars:\t\t%d\n", infop->xmit); - printf("modem signal deltas:\t\t%d\n", infop->mdm); - printf("\n"); -} /* end of cystatus() */ -#endif -#endif /* NCY > 0 */ |
