* 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.
#define DHADDR ((struct device *)(UBA0_DEV + 0160020))
#define NDH11 16 /* number of lines */
#define UBACVT(x) (cbase + (short)((x)-(char *)cfree))
int dhchars
[(NDH11
+15)/16];
extern struct cblock cfree
[];
/* DEC manuals incorrectly say this bit causes generation of even parity. */
#define SSPEED 7 /* standard speed: 300 baud */
#define DHTIME 2 /* Since Berknet packets are only 100 chars */
#define TURNON 03 /* CD lead + line enable */
#define TURNOFF 01 /* line enable */
#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
;
timeout(dhtimer
, (caddr_t
)0, DHTIME
);
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)
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
;
addr
+= minor(dev
) & 0177;
while ((c
= addr
->dhnxch
) < 0) { /* char. present */
tp
= &dh11
[((minor(dev
)&0177)<<4) + ((c
>>8)&017)];
dhchars
[minor(dev
)&0177]++;
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) */
c
= 0177; /* DEL (intr) */
(*linesw
[tp
->t_line
].l_rint
)(c
,tp
);
dhioctl(dev
, cmd
, addr
, flag
)
tp
= &dh11
[minor(dev
) & 0177];
if (ttioccomm(cmd
, tp
, addr
, dev
)) {
if (cmd
==TIOCSETP
||cmd
==TIOCSETN
)
} else if (cmd
==TIOCSBRK
) {
register int linebit
= 1 << (dev
&017);
((struct device
*)tp
->t_addr
)->dhbreak
|= linebit
;
timeout(dhunbrk
, (caddr_t
)tp
, 25); /* 300-500 ms */
while (((struct device
*)tp
->t_addr
)->dhbreak
& linebit
)
sleep((caddr_t
)&tp
->t_rawq
, TTIPRI
);
((struct device
*)tp
->t_addr
)->dhbreak
&= ~ (1 << (minor(tp
->t_dev
)&017));
wakeup((caddr_t
)&tp
->t_rawq
);
* 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
;
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
;
addr
->un
.dhcsr
&= (short)~XINT
;
bar
= *sbar
& ~addr
->dhbar
;
for(; bar
; d
++, ttybit
<<= 1) {
(*linesw
[tp
->t_line
].l_start
)(tp
);
addr
->un
.dhcsrl
= (d
&017)|IENAB
;
* 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
); else
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.
if ((tp
->t_state
&TTSTOP
)==0)
register struct device
*addr
;
} while (d
< (NDH11
+15)/16);
timeout(dhtimer
, (caddr_t
)0, DHTIME
);