V7/usr/sys/dev/dhdm.c
/*
* DM-BB driver
*/
#include "../h/param.h"
#include "../h/tty.h"
#include "../h/conf.h"
#define DMADDR ((struct device *)0170500)
struct tty dh11[];
int ndh11; /* Set by dh.c to number of lines */
#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 */
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)
{
register struct tty *tp;
register struct device *addr;
register d;
d = minor(dev);
tp = &dh11[d];
addr = DMADDR;
addr += d>>4;
spl5();
addr->dmcsr = d&017;
addr->dmlstat = TURNON;
if (addr->dmlstat&CARRIER) {
tp->t_state |= CARR_ON;
}
addr->dmcsr = IENABLE|SCENABL;
while ((tp->t_state&CARR_ON)==0)
sleep((caddr_t)&tp->t_rawq, TTIPRI);
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 = DMADDR;
addr += d>>4;
s = spl5();
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;
d = minor(dev);
addr = DMADDR;
addr += d;
if (addr->dmcsr&DONE) {
tp = &dh11[(d<<4)+(addr->dmcsr&017)];
if (tp < &dh11[ndh11]) {
wakeup((caddr_t)&tp->t_rawq);
if ((addr->dmlstat&CARRIER)==0) {
if ((tp->t_state&WOPEN)==0) {
signal(tp->t_pgrp, SIGHUP);
addr->dmlstat = 0;
flushtty(tp);
}
tp->t_state &= ~CARR_ON;
} else {
tp->t_state |= CARR_ON;
}
}
addr->dmcsr = IENABLE|SCENABL;
}
}