BBN-V6/dmr/dhdm.c

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

#
/*
 */

/*
 *	DM-BB driver
 *      Modified for await Dan Franklin Sept 28 1978
 *      Modified by BBN (cdh) 17 Apr 79 for multiple DH interfaces that
 *      may or may not have DM devices.
 */
#include "../h/param.h"
#include "../h/tty.h"
#include "../h/conf.h"

#define DH11    2               /* number of DH11s connnected */
				/* this number should = (NDH11 + 15)/16 */
				/* where NDH11 is defined in dh.c */
/*
 * The following DM addresses should correspond directly with the DH11s
 * that they are associated with.  If there is no DM11 associated with
 * a given DH, define the appropriate address as 0177777 as a flag.
 */

#define DMADR0  0170500
#define DMADR1  0177777

struct	tty dh11[];
int	ndh11;		/* Set by dh.c to number of lines */

#define	DONE	0200
#define	SCENABL	040
#define	CLSCAN	01000
#define	TURNON	07	/* RQ send, CD lead, line enable */
#define TURNOFF 1      /* line enable only */
#define	CARRIER	0100

struct dmregs {
	int	dmcsr;
	int	dmlstat;
};

struct dmregs *dmadrs[DH11]
{       DMADR0,
	DMADR1
};

/* structure to allow selective modem control BBN:cdh 7/31/78 */
/* There should be as many entries in this table as there are DH lines */

char dmodems[DH11][16] {                /* Array to indicate which lines need modem control */
	0, 0, 0, 0, 0, 0, 0, 0,		/* 0 means no modem control, 1 means yes */
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0
};

/*
 * Turn on the line associated with the (DH) device dev.
 */
dmopen(dev)
{
	register struct tty *tp;
	register struct dmregs *dmaddr;
	register int dmno;		/* BBN:cdh */

	tp = &dh11[dev.d_minor];
	dmno = dev.d_minor>>4;
	dmaddr = dmadrs[dmno];

	/* If modem control not wanted, turn on carrier in tp struct, BBN:cdh */

	if (dmodems[dmno][dev.d_minor&017] == 0 || dmaddr == 0177777) {
		tp->t_state =| CARR_ON;
		return;
	}
	dmaddr->dmcsr = dev.d_minor&017;
	dmaddr->dmlstat = TURNON;
	if (dmaddr->dmlstat&CARRIER)
		tp->t_state =| CARR_ON;
	dmaddr->dmcsr = IENABLE|SCENABL;
	spl5();
	while ((tp->t_state&CARR_ON)==0)
		sleep(&tp->t_rawq, TTIPRI);
	spl0();
}

/*
 * If a DH line has the HUPCL mode,
 * turn off carrier when it is closed.
 */
dmclose(dev)
{
	register struct tty *tp;
	register struct dmregs *dmaddr;
	register int dmno;              /* BBN:cdh */

	tp = &dh11[dev.d_minor];
	dmno = dev.d_minor>>4;
	dmaddr = dmadrs[dmno];
	if (tp->t_flags&HUPCL && dmaddr != 0177777 &&   /* BBN:cdh */
	    dmodems[dmno][dev.d_minor&017] != 0) {      /* ignore if no DM */
		dmaddr = dmadrs[dev.d_minor>>4];
		dmaddr->dmcsr = dev.d_minor&017;
		dmaddr->dmlstat = TURNOFF;
		dmaddr->dmcsr = IENABLE|SCENABL;
	}
}

/*
 * DM11 interrupt.
 * Mainly, deal with carrier transitions.
 * One should insure that the minor device number contained in the
 * interrupt vector corresponds to the number of the DH that the DM
 * is associated with, not just the DM number.  This is significant
 * if there exist DH11's (or equivalents) that have no DM11's.
 */
dmint(dmno)
int dmno;
{
	register struct tty *tp;
	register struct dmregs *dmaddr; /* put in a register */
	register int dmline;

	dmaddr = dmadrs[dmno];
	if (dmaddr->dmcsr&DONE) {
		dmline = dmaddr->dmcsr&017;	/* BBN:cdh */
		tp = &dh11[(dmno<<4) + dmline];
		if (tp < &dh11[ndh11]) {
                        if (tp->t_itp) awake(tp->t_itp, 0);
			wakeup(tp);
			if ((dmaddr->dmlstat&CARRIER)==0 &&
			    dmodems[dmno][dmline] != 0) {	/* BBN:cdh */
				if ((tp->t_state&WOPEN)==0) {
					signal(tp, SIGHUP);
					dmaddr->dmlstat = 0;
					flushtty(tp);
				}
				tp->t_state =& ~CARR_ON;
			} else
				tp->t_state =| CARR_ON;
		}
		dmaddr->dmcsr = IENABLE|SCENABL;
	}
}