* This driver calls on the DHDM driver.
* If the DH has no DM11-BB, then the latter will
* be fake. To insure loading of the correct DM code,
* lib2 should have dhdm.o, dh.o and dhfdm.o in that order.
* When running dz's using only SAE (silo alarm) on input
* it is necessary to call dzrint() at clock interrupt time.
* This is unsafe unless spl5()s in tty code are changed to
* spl6()s to block clock interrupts. Note that the dh driver
* currently in use works the same way as the dz, even though
* we could try to more intelligently manage its silo.
* Thus don't take this out if you have no dz's unless you
* change clock.c and dhtimer().
#define DHADDR ((struct device *)(UBA0_DEV + 0160020))
#define NDH11 16 /* number of lines */
#define UBACVT(x) (cbase + (short)((x)-(char *)cfree))
extern struct cblock cfree
[];
/* DEC manuals incorrectly say this bit causes generation of even parity. */
#define SSPEED 7 /* standard speed: 300 baud */
#define TURNON 03 /* CD lead + line enable */
#define TURNOFF 01 /* line enable */
#define DTR 02 /* data terminal ready */
#define RQS 04 /* request to send */
* Software copy of last dhbar
short dhsar
[(NDH11
+15)/16];
register struct device
*addr
;
tp
->t_addr
= (caddr_t
)addr
;
cbase
= (short)uballoc((caddr_t
)cfree
, NCLIST
*sizeof(struct cblock
), 0);
if ((tp
->t_state
&ISOPEN
) == 0) {
tp
->t_flags
= ODDP
|EVENP
|ECHO
;
if (tp
->t_state
&XCLUDE
&& u
.u_uid
!=0) {
(*linesw
[tp
->t_line
].l_open
)(dev
,tp
);
(*linesw
[tp
->t_line
].l_close
)(tp
);
if (tp
->t_state
&HUPCLS
|| (tp
->t_state
&ISOPEN
)==0)
dmctl(d
, TURNOFF
, DMSET
);
tp
= &dh11
[minor(dev
) & 0177];
(*linesw
[tp
->t_line
].l_read
)(tp
);
tp
= &dh11
[minor(dev
) & 0177];
(*linesw
[tp
->t_line
].l_write
)(tp
);
* DH11 receiver interrupt.
register struct device
*addr
;
register struct tty
*tp0
;
s
= spl6(); /* see comment in clock.c */
addr
+= minor(dev
) & 0177;
tp0
= &dh11
[((minor(dev
)&0177)<<4)];
while ((c
= addr
->dhnxch
) < 0) { /* char. present */
if((tp
->t_state
&ISOPEN
)==0) {
if ((tp
->t_flags
&(EVENP
|ODDP
))==EVENP
|| (tp
->t_flags
&(EVENP
|ODDP
))==ODDP
)
if (c
&FRERROR
) /* break */
c
= 0; /* null (for getty) */
if (tp
->t_line
== NETLDISC
) {
(*linesw
[tp
->t_line
].l_rint
)(c
,tp
);
dhioctl(dev
, cmd
, addr
, flag
)
tp
= &dh11
[minor(dev
) & 0177];
cmd
= (*linesw
[tp
->t_line
].l_ioctl
)(tp
, cmd
, addr
);
if (ttioccomm(cmd
, tp
, addr
, dev
)) {
if (cmd
==TIOCSETP
||cmd
==TIOCSETN
)
((struct device
*)(tp
->t_addr
))->dhbreak
|= 1<<(minor(dev
)&017);
((struct device
*)(tp
->t_addr
))->dhbreak
&= ~(1<<(minor(dev
)&017));
dmctl(minor(dev
), DTR
|RQS
, DMBIS
);
dmctl(minor(dev
), DTR
|RQS
, DMBIC
);
* Set parameters from open or stty into the DH hardware
register struct device
*addr
;
addr
= (struct device
*)tp
->t_addr
;
addr
->un
.dhcsrl
= (d
&017) | IENAB
;
dmctl(d
, TURNOFF
, DMSET
);
d
= ((tp
->t_ospeed
)<<10) | ((tp
->t_ispeed
)<<6);
if ((tp
->t_ispeed
) == 4) /* 134.5 baud */
d
|= BITS6
|PENABLE
|HDUPLX
;
else if (tp
->t_flags
&RAW
)
if ((tp
->t_flags
&EVENP
) == 0)
if ((tp
->t_ospeed
) == 3) /* 110 baud */
* DH11 transmitter interrupt.
* Restart each line which used to be active but has
* terminated transmission since the last interrupt.
register struct device
*addr
;
short ttybit
, bar
, *sbar
;
s
= spl6(); /* block the clock */
addr
->un
.dhcsr
&= (short)~XINT
;
if (addr
->un
.dhcsr
& NXM
) {
addr
->un
.dhcsr
|= CLRNXM
;
bar
= *sbar
& ~addr
->dhbar
;
for(; bar
; d
++, ttybit
<<= 1) {
addr
->un
.dhcsrl
= (d
&017)|IENAB
;
(int)addr
->dhcar
-UBACVT(tp
->t_outq
.c_cf
));
(*linesw
[tp
->t_line
].l_start
)(tp
);
* Start (restart) transmission on the given DH11 line.
register struct device
*addr
;
* If it's currently active, or delaying,
* no need to do anything.
addr
= (struct device
*)tp
->t_addr
;
if (tp
->t_state
&(TIMEOUT
|BUSY
|TTSTOP
))
* If the writer was sleeping on output overflow,
* wake him when low tide is reached.
if (tp
->t_state
&ASLEEP
&& tp
->t_outq
.c_cc
<=TTLOWAT
) {
mcstart(tp
->t_chan
, (caddr_t
)&tp
->t_outq
);
wakeup((caddr_t
)&tp
->t_outq
);
if (tp
->t_outq
.c_cc
== 0)
* Find number of characters to transfer.
nch
= ndqb(&tp
->t_outq
, 0);
nch
= ndqb(&tp
->t_outq
, 0200);
timeout(ttrstrt
, (caddr_t
)tp
, (nch
&0177)+6);
* If any characters were set up, start transmission;
addr
->un
.dhcsrl
= (d
&017)|IENAB
;
addr
->dhcar
= UBACVT(tp
->t_outq
.c_cf
);
* Assume call is made at spl6.
register struct device
*addr
;
addr
= (struct device
*)tp
->t_addr
;
if (tp
->t_state
& BUSY
) {
addr
->un
.dhcsrl
= (d
&017) | IENAB
;
if ((tp
->t_state
&TTSTOP
)==0)
* Silo control is fixed strategy
* here, paralleling only option available
register struct device
*addr
;
} while (d
< (NDH11
+15)/16);