USG_PG3/usr/source/io1/dhdm.c
#
/*
*/
/*
* DM-BB driver
*/
#include "../head/param.h"
#include "../head/tty.h"
#include "../head/conf.h"
#define DMADDR 0170500
struct tty dh11[];
int ndh11; /* Set by dh.c to number of lines */
#define IENABLE 0100 /* interrupt enable */
#define DMBUSY 020 /* dm cycling */
#define SCENABL 040
#define TURNOFF 1 /* line enable only */
struct dmregs {
int dmcsr;
int dmlstat;
int dmfill1;
int dmfill2;
};
/*
* Fetch and set modem control status.
* Accessed via switch on ctlsw table in conf.c
*/
dhmctl(dev, action)
{
register svcsr;
register minor, dmaddr;
int sps, status;
minor = dev.d_minor & 0377;
dmaddr = DMADDR + (minor>>4)*8;
sps = PS->integ;
spl5();
while((svcsr = dmaddr->dmcsr)&DMBUSY)
dmaddr->dmcsr =& ~SCENABL;
dmaddr->dmcsr = minor & 017;
if (action == FSTATUS)
status = (dmaddr->dmlstat>>4)&07;
else {
dmaddr->dmlstat = dmbits(action);
status = 0;
}
dmaddr->dmcsr = svcsr|(IENABLE|SCENABL);
PS->integ = sps;
return(status);
}
/*
* DM11 interrupt. Pass modem status to line discipline routine.
* Implement specified action.
*/
dmint(dev)
{
register struct tty *tp;
register action, dmaddr;
int status;
dmaddr = DMADDR + (dev*8);
if (dmaddr->dmcsr&DONE) {
tp = &dh11[(dev<<4) + (dmaddr->dmcsr&017)];
dmaddr->dmcsr =& ~(DONE|SCENABL);
if (tp < &dh11[ndh11]) {
status = (dmaddr->dmlstat>>4)&07;
action = (*linesw[tp->t_discp].l_mt)(tp, status);
if (action != 0)
dmaddr->dmlstat = dmbits(action);
}
dmaddr->dmcsr =| SCENABL;
}
}
/*
* Translate specified action into bits for dm line status register
*/
dmbits(action)
{
register lstat;
switch(action&03) {
case DISABLE:
lstat = 0;
break;
case HUP:
lstat = TURNOFF;
break;
case TURNON:
/*
* Set enable and data terminal ready. Set primary and secondary
* carrier status according to bits 2 and 3 of "action"
*/
lstat = action;
}
return(lstat);
}