Ultrix-3.1/sys/dev/dhdm.c

Compare this file to the similar file:
Show the results in this format:


/**********************************************************************
 *   Copyright (c) Digital Equipment Corporation 1984, 1985, 1986.    *
 *   All Rights Reserved. 					      *
 *   Reference "/usr/src/COPYRIGHT" for applicable restrictions.      *
 **********************************************************************/

/*
 * SCCSID: @(#)dhdm.c	3.0	4/21/86
 */
/*
 *	DM-BB driver
 *
 *	Modifed to allow use of DM11-BB MCU
 *	equiped with an M7147 in place of M7808.
 *
 *	The origonal dhdm driver did not wait for
 *	the MCU scan busy bit to go to zero prior
 *	to changing the line number in the MCU CSR.
 *	The origonal driver functions properly with the
 *	M7808 module, however, if the M7147 is used the
 *	modems will not be properly initialized.
 *	This dhdm driver waits for MCU scan busy to
 *	go to zero prior to changing the line number.
 *
 * 	Also modified to allow for local or remote
 *	operaton of terminals.
 *
 *	Fred Canter 11/6/82
 *
 *	Changes for O_NDELAY flag in open(): George Mathew 7/24/85
 */
#include <sys/param.h>
#include <sys/tty.h>
#include <sys/conf.h>
#include <sys/devmaj.h>
#include <sys/file.h>	/* needed for FREAD & FWRITE */

int	io_csr[];	/* CSR address now in config file (c.c) */

struct	tty *dh11[];
int	ndh11;		/* Set by dh.c to number of lines */
int	dh_local[];	/* bit per line, 1 = local tty */

#define	DONE	0200
#define	SCENABL	040
#define	CLSCAN	01000
#define	TURNON	03	/* CD lead, line enable */
#define	SECX	010	/* secondary xmit */
#define	RQS	04	/* request to send */
#define	TURNOFF	1	/* line enable only */
#define	CARRIER	0100
#define	CLS	040	/* clear to send */
#define	SECR	020	/* secondary receive */
#define SBUSY	020	/* MCU scan busy */

struct device
{
	int	dmcsr;
	int	dmlstat;
	int	junk[2];
};

#define	B1200	9
#define	B300	7

/*
 * Turn on the line associated with the (DH) device dev.
 */
dmopen(dev, flag)
{
	register struct tty *tp;
	register struct device *addr;
	register d;

	d = minor(dev);
	tp = dh11[d];
	if(dh_local[(d>>4) & 7] & (1 << (d&017))) {
		tp->t_state |= CARR_ON;
		return;
		}
	addr = io_csr[DM_RMAJ];
	addr += d>>4;
	spl5();
	addr->dmcsr &= ~SCENABL;	/* stop MCU scan */
	while (addr->dmcsr & SBUSY);	/* wait for busy = 0 */
	addr->dmcsr = d&017;
	addr->dmlstat = TURNON;
	if (addr->dmlstat&CARRIER) {
		tp->t_state |= CARR_ON;
	}
	addr->dmcsr = IENABLE|SCENABL;
	if((flag&FNDELAY) == 0)
		while ((tp->t_state&CARR_ON)==0)
			sleep((caddr_t)&tp->t_rawq, TTIPRI);
	addr->dmcsr &= ~SCENABL;
	while (addr->dmcsr & SBUSY);
	addr->dmcsr = d&017;
	if (addr->dmlstat&SECR) {
		tp->t_ispeed = B1200;
		tp->t_ospeed = B1200;
		dhparam(dev);
	}
	addr->dmcsr = IENABLE|SCENABL;
	spl0();
}

/*
 * Dump control bits into the DM registers.
 */
dmctl(dev, bits)
{
	register struct device *addr;
	register d, s;

	d = minor(dev);
	addr = io_csr[DM_RMAJ];
	addr += d>>4;
	s = spl5();
	addr->dmcsr &= ~SCENABL;
	while (addr->dmcsr & SBUSY);
	addr->dmcsr = d&017;
	addr->dmlstat = bits;
	addr->dmcsr = IENABLE|SCENABL;
	splx(s);
}

/*
 * DM11 interrupt.
 * Mainly, deal with carrier transitions.
 */
dmint(dev)
{
	register struct tty *tp;
	register struct device *addr;
	register d;
	int ln;

	d = minor(dev);
	addr = io_csr[DM_RMAJ];
	addr += d;
	while (addr->dmcsr & SBUSY);
	if (addr->dmcsr&DONE) {
		ln = (d<<4) + (addr->dmcsr&017);
		tp = dh11[ln];
		if ((ln < ndh11) && tp) {
			wakeup((caddr_t)&tp->t_rawq);
			if ((addr->dmlstat&CARRIER)==0 && 
				(dh_local[d] & (1 << (ln&017))) == 0) {
				if ((tp->t_state&WOPEN)==0) {
					gsignal(tp->t_pgrp, SIGHUP);
					addr->dmlstat = 0;
					flushtty(tp, FREAD|FWRITE);
				}
				tp->t_state &= ~CARR_ON;
			} else {
				tp->t_state |= CARR_ON;
			}
		}
		addr->dmcsr = IENABLE|SCENABL;
	}
}