* This driver mimics dh.c; see it for explanation of common code.
* Driver information for auto-configuration stuff.
int dzprobe(), dzattach(), dzrint();
struct uba_device
*dzinfo
[NDZ
];
struct uba_driver dzdriver
=
{ dzprobe
, 0, dzattach
, 0, dzstd
, "dz", dzinfo
};
#define DZ_CLR 020 /* Reset dz */
#define DZ_MSE 040 /* Master Scan Enable */
#define DZ_RIE 0100 /* Receiver Interrupt Enable */
#define DZ_SAE 010000 /* Silo Alarm Enable */
#define DZ_TIE 040000 /* Transmit Interrupt Enable */
#define DZ_IEN (DZ_MSE+DZ_RIE+DZ_TIE+DZ_SAE)
/* Flags for modem-control */
int dzstart(), dzxint(), dzdma();
struct tty dz_tty
[NDZLINE
];
int dz_cnt
= { NDZLINE
};
short dzcsr
; /* control-status register */
short dzrbuf
; /* receiver buffer */
#define dzlpr dzrbuf /* line parameter reg is write of dzrbuf */
char dztcr
; /* transmit control register */
char dzdtr
; /* data terminal ready */
char dztbuf
; /* transmit buffer */
char dzbrk
; /* break control */
#define dzmsr dzbrk /* modem status register */
* Software copy of dzbrk since it isn't readable
* The dz doesn't interrupt on carrier transitions, so
* we have to use a timer to watch it.
char dz_timer
; /* timer started? */
* Pdma structures for fast output code
struct pdma dzpdma
[NDZLINE
];
{ 0,020,021,022,023,024,0,025,026,027,030,032,034,036,0,0 };
register struct device
*dzaddr
= (struct device
*)reg
;
br
= 0; cvec
= br
; br
= cvec
;
dzaddr
->dzcsr
= DZ_TIE
|DZ_MSE
;
dzaddr
->dztcr
= 1; /* enable any line */
dzaddr
->dzcsr
= DZ_CLR
; /* reset everything */
if (cvec
&& cvec
!= 0x200)
register struct uba_device
*ui
;
register struct pdma
*pdp
= &dzpdma
[ui
->ui_unit
*8];
register struct tty
*tp
= &dz_tty
[ui
->ui_unit
*8];
for (cntr
= 0; cntr
< 8; cntr
++) {
pdp
->p_addr
= (struct device
*)ui
->ui_addr
;
dzsoftCAR
[ui
->ui_unit
] = ui
->ui_flags
;
timeout(dzscan
, (caddr_t
)0, hz
);
if (unit
>= dz_cnt
|| dzpdma
[unit
].p_addr
== 0) {
tp
->t_addr
= (caddr_t
)&dzpdma
[unit
];
if ((tp
->t_state
& ISOPEN
) == 0) {
tp
->t_ospeed
= tp
->t_ispeed
= B300
;
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
;
if ((dzact
& (1<<dz
)) == 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
);
if (c
&DZ_DO
&& overrun
== 0) {
printf("dz%d: silo overflow\n", dz
);
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
, DZ_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_ispeed
== B110
)
register struct pdma
*dp
;
s
= spl5(); /* block pdma interrupts */
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
&0x7f) + 6);
dp
->p_end
= dp
->p_mem
= tp
->t_outq
.c_cf
;
dzaddr
->dztcr
|= 1 << (minor(tp
->t_dev
) & 07); /* force intr */
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 ((dzsoftCAR
[i
>>3]&bit
) || (dzaddr
->dzmsr
&bit
)) {
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
);
for (dz
= 0; dz
< NDZ
; dz
++)
* Reset state of driver if UBA reset was necessary.
* Reset parameters and restart transmission on open lines.
register struct uba_device
*ui
;
for (unit
= 0; unit
< NDZLINE
; unit
++) {
if (ui
== 0 || ui
->ui_ubanum
!= uban
|| ui
->ui_alive
== 0)
printf(" dz%d", unit
>>3);
if (tp
->t_state
& (ISOPEN
|WOPEN
)) {