* 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().
* SHOULD RATHER QUEUE SOFTWARE INTERRUPT AT CLOCK TIME.
int dzcntrlr(), dzslave(), dzrint();
struct uba_dinfo
*dzinfo
[NDZ11
];
int (*dzivec
[])() = { dzrint
, 0 }; /* omit dzxint so we can do it here */
struct uba_driver dzdriver
=
{ dzcntrlr
, dzslave
, (int (*)())0, 0, 0, dzstd
, dzinfo
, dzivec
};
#define MSE 040 /* Master Scan Enable */
#define RIE 0100 /* Receiver Interrupt Enable */
#define SAE 010000 /* Silo Alarm Enable */
#define TIE 040000 /* Transmit Interrupt Enable */
#define DZ_IEN (MSE+RIE+TIE+SAE)
#define SSPEED 7 /* std speed = 300 baud */
{ 0,020,021,022,023,024,0,025,026,027,030,032,034,036,0,0 };
((struct device
*)reg
)->dzcsr
|= IENABLE
;
/* get it to interrupt */
dzslave(ui
, reg
, slaveno
, uban
)
register struct uba_dinfo
*ui
;
register struct pdma
*pdp
= &dzpdma
[ui
->ui_unit
*8];
register struct tty
*tp
= &dz_tty
[ui
->ui_unit
*8];
register int *urk
= (int *)(®
- 24); /* white magic */
for (cnt
= 0; cnt
< 8; cnt
++) {
pdp
->p_addr
= (struct device
*)reg
;
if ((cp
= calloc(12)) == 0)
uba_hd
[uban
].uh_vec
[*urk
] = (int (*)())cp
; /* more white magic */
*cp
++ = 0xbb; *cp
++ = 0xff; *cp
++ = 0xd0; /* black magic */
*cp
++ = ui
->ui_unit
&0x3f; *cp
++ = 0x50;
*cp
++ = 0x17; *cp
++ = 0x9f;
for (cnt
= 0; cnt
< 4; cnt
++)
*cp
++ = urk2
, urk2
>>= 4; /* the spell ends */
if (unit
>= dz_cnt
|| dzpdma
[unit
].p_addr
== 0) {
timeout(dzscan
, (caddr_t
)0, 60);
tp
->t_addr
= (caddr_t
)&dzpdma
[unit
];
if ((tp
->t_state
& ISOPEN
) == 0) {
tp
->t_ospeed
= tp
->t_ispeed
= SSPEED
;
tp
->t_flags
= ODDP
|EVENP
|ECHO
;
/*tp->t_state |= HUPCLS;*/
} else if (tp
->t_state
&XCLUDE
&& u
.u_uid
!= 0) {
while ((tp
->t_state
& CARR_ON
) == 0) {
sleep((caddr_t
)&tp
->t_rawq
, TTIPRI
);
(*linesw
[tp
->t_line
].l_open
)(dev
, tp
);
(*linesw
[tp
->t_line
].l_close
)(tp
);
((struct pdma
*)(tp
->t_addr
))->p_addr
->dzbrk
=
(dz_brk
[dz
] &= ~(1 << (unit
&07)));
if (tp
->t_state
& HUPCLS
)
tp
= &dz_tty
[minor(dev
)];
(*linesw
[tp
->t_line
].l_read
)(tp
);
tp
= &dz_tty
[minor(dev
)];
(*linesw
[tp
->t_line
].l_write
)(tp
);
register struct device
*dzaddr
;
register struct tty
*tp0
;
s
= spl6(); /* see comment in clock.c */
/* as long as we are here, service them all */
for (unit
= 0; unit
< NDZ
; unit
+= 8) {
if ((dzact
& (1<<(unit
>>3))) == 0)
dzaddr
= dzpdma
[unit
].p_addr
;
while ((c
= dzaddr
->dzrbuf
) < 0) { /* char present */
if (tp
>= &dz_tty
[dz_cnt
])
if ((tp
->t_state
& ISOPEN
) == 0) {
wakeup((caddr_t
)&tp
->t_rawq
);
/* framing error = break */
c
= 0; /* null for getty */
if (((tp
->t_flags
& (EVENP
|ODDP
)) == EVENP
)
|| ((tp
->t_flags
& (EVENP
|ODDP
)) == ODDP
))
if (tp
->t_line
== NETLDISC
) {
(*linesw
[tp
->t_line
].l_rint
)(c
, tp
);
dzioctl(dev
, cmd
, addr
, flag
)
register int unit
= minor(dev
);
register int dz
= unit
>> 3;
cmd
= (*linesw
[tp
->t_line
].l_ioctl
)(tp
, cmd
, addr
);
if (ttioctl(tp
, cmd
, addr
, flag
)) {
if (cmd
==TIOCSETP
|| cmd
==TIOCSETN
)
((struct pdma
*)(tp
->t_addr
))->p_addr
->dzbrk
=
(dz_brk
[dz
] |= 1 << (unit
&07));
((struct pdma
*)(tp
->t_addr
))->p_addr
->dzbrk
=
(dz_brk
[dz
] &= ~(1 << (unit
&07)));
register struct device
*dzaddr
;
dzaddr
= dzpdma
[unit
].p_addr
;
dzmodem(unit
, OFF
); /* hang up line */
lpr
= (dz_speeds
[tp
->t_ispeed
]<<8) | (unit
& 07);
if ((tp
->t_local
&LLITOUT
) || (tp
->t_flags
&RAW
))
if ((tp
->t_flags
& EVENP
) == 0)
if ((tp
->t_flags
& (EVENP
|ODDP
)) == (EVENP
|ODDP
))
else if (tp
->t_flags
& EVENP
)
else if (tp
->t_flags
& ODDP
)
lpr
|= (BITS7
|OPAR
|PENABLE
);
lpr
|= TWOSB
; /* 110 baud: 2 stop bits */
register struct pdma
*dp
;
s
= spl6(); /* block the clock */
dp
= (struct pdma
*)tp
->t_addr
;
ndflush(&tp
->t_outq
, dp
->p_mem
-tp
->t_outq
.c_cf
);
(*linesw
[tp
->t_line
].l_start
)(tp
);
if (tp
->t_outq
.c_cc
== 0 || (tp
->t_state
&BUSY
)==0)
dp
->p_addr
->dztcr
&= ~(1 << (minor(tp
->t_dev
)&07));
register struct pdma
*dp
;
register struct device
*dzaddr
;
dp
= (struct pdma
*)tp
->t_addr
;
if (tp
->t_state
& (TIMEOUT
|BUSY
|TTSTOP
))
if (tp
->t_state
&ASLEEP
&& tp
->t_outq
.c_cc
<= TTLOWAT(tp
)) {
mcstart(tp
->t_chan
, (caddr_t
)&tp
->t_outq
);
wakeup((caddr_t
)&tp
->t_outq
);
if (tp
->t_outq
.c_cc
== 0)
cc
= ndqb(&tp
->t_outq
, 0);
cc
= ndqb(&tp
->t_outq
, 0200);
timeout(ttrstrt
, (caddr_t
)tp
, (cc
&0177) + 6);
dp
->p_end
= dp
->p_mem
= tp
->t_outq
.c_cf
;
dzaddr
->dztcr
|= 1 << (minor(tp
->t_dev
) & 07);
* Assume call is made at spl6.
register struct pdma
*dp
;
dp
= (struct pdma
*)tp
->t_addr
;
if (tp
->t_state
& BUSY
) {
if ((tp
->t_state
&TTSTOP
)==0)
register struct device
*dzaddr
;
dzaddr
= dzpdma
[unit
].p_addr
;
register struct device
*dzaddr
;
for (i
= 0; i
< dz_cnt
; i
++) {
dzaddr
= dzpdma
[i
].p_addr
;
if (dzaddr
->dzmsr
& bit
|| (i
== 6 || i
== 7)) {
if ((tp
->t_state
& CARR_ON
) == 0) {
wakeup((caddr_t
)&tp
->t_rawq
);
if ((tp
->t_state
&CARR_ON
) && (tp
->t_local
&LNOHANG
)==0) {
if (tp
->t_state
&ISOPEN
) {
gsignal(tp
->t_pgrp
, SIGHUP
);
gsignal(tp
->t_pgrp
, SIGCONT
);
flushtty(tp
, FREAD
|FWRITE
);
timeout(dzscan
, (caddr_t
)0, 2*HZ
);
* Reset state of driver if UBA reset was necessary.
* Reset parameters and restart transmission on open lines.
/*** WE SHOULD LOOK TO SEE IF WE CARE ABOUT UBA BEING RESET ***/
for (unit
= 0; unit
< NDZ
; unit
++) {
if (tp
->t_state
& (ISOPEN
|WOPEN
)) {