1 /* $NetBSD: dz.c,v 1.37 2008/05/27 14:13:41 ad Exp $ */
3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved.
6 * This code is derived from software contributed to Berkeley by
7 * Ralph Campbell and Rick Macklem.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * Copyright (c) 1996 Ken C. Wellsch. All rights reserved.
37 * This code is derived from software contributed to Berkeley by
38 * Ralph Campbell and Rick Macklem.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by the University of
51 * California, Berkeley and its contributors.
52 * 4. Neither the name of the University nor the names of its contributors
53 * may be used to endorse or promote products derived from this software
54 * without specific prior written permission.
56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 #include <sys/cdefs.h>
70 __KERNEL_RCSID(0, "$NetBSD: dz.c,v 1.37 2008/05/27 14:13:41 ad Exp $");
72 #include <sys/param.h>
73 #include <sys/systm.h>
74 #include <sys/callout.h>
75 #include <sys/ioctl.h>
82 #include <sys/kernel.h>
83 #include <sys/syslog.h>
84 #include <sys/device.h>
85 #include <sys/kauth.h>
89 #include <dev/dec/dzreg.h>
90 #include <dev/dec/dzvar.h>
95 #define DZ_DELAY(x) DELAY(x)
96 #define control __noinline
97 #else /* presumably vax */
98 #define DZ_DELAY(x) /* nothing */
99 #define control inline
103 dz_read1(struct dz_softc
*sc
, u_int off
)
107 rv
= bus_space_read_1(sc
->sc_iot
, sc
->sc_ioh
, off
);
113 dz_read2(struct dz_softc
*sc
, u_int off
)
117 rv
= bus_space_read_2(sc
->sc_iot
, sc
->sc_ioh
, off
);
123 dz_write1(struct dz_softc
*sc
, u_int off
, u_int val
)
126 bus_space_write_1(sc
->sc_iot
, sc
->sc_ioh
, off
, val
);
127 bus_space_barrier(sc
->sc_iot
, sc
->sc_ioh
, sc
->sc_dr
.dr_firstreg
,
128 sc
->sc_dr
.dr_winsize
, BUS_SPACE_BARRIER_WRITE
|
129 BUS_SPACE_BARRIER_READ
);
134 dz_write2(struct dz_softc
*sc
, u_int off
, u_int val
)
137 bus_space_write_2(sc
->sc_iot
, sc
->sc_ioh
, off
, val
);
138 bus_space_barrier(sc
->sc_iot
, sc
->sc_ioh
, sc
->sc_dr
.dr_firstreg
,
139 sc
->sc_dr
.dr_winsize
, BUS_SPACE_BARRIER_WRITE
|
140 BUS_SPACE_BARRIER_READ
);
146 /* Flags used to monitor modem bits, make them understood outside driver */
148 #define DML_DTR TIOCM_DTR
149 #define DML_DCD TIOCM_CD
150 #define DML_RI TIOCM_RI
151 #define DML_BRK 0100000 /* no equivalent, we will mask */
153 static const struct speedtab dzspeedtab
[] =
158 { 110, DZ_LPR_B110
},
159 { 134, DZ_LPR_B134
},
160 { 150, DZ_LPR_B150
},
161 { 300, DZ_LPR_B300
},
162 { 600, DZ_LPR_B600
},
163 { 1200, DZ_LPR_B1200
},
164 { 1800, DZ_LPR_B1800
},
165 { 2000, DZ_LPR_B2000
},
166 { 2400, DZ_LPR_B2400
},
167 { 3600, DZ_LPR_B3600
},
168 { 4800, DZ_LPR_B4800
},
169 { 7200, DZ_LPR_B7200
},
170 { 9600, DZ_LPR_B9600
},
171 { 19200, DZ_LPR_B19200
},
175 static void dzstart(struct tty
*);
176 static int dzparam(struct tty
*, struct termios
*);
177 static unsigned dzmctl(struct dz_softc
*, int, int, int);
178 static void dzscan(void *);
180 static dev_type_open(dzopen
);
181 static dev_type_close(dzclose
);
182 static dev_type_read(dzread
);
183 static dev_type_write(dzwrite
);
184 static dev_type_ioctl(dzioctl
);
185 static dev_type_stop(dzstop
);
186 static dev_type_tty(dztty
);
187 static dev_type_poll(dzpoll
);
189 const struct cdevsw dz_cdevsw
= {
190 dzopen
, dzclose
, dzread
, dzwrite
, dzioctl
,
191 dzstop
, dztty
, dzpoll
, nommap
, ttykqfilter
, D_TTY
195 * The DZ series doesn't interrupt on carrier transitions,
196 * so we have to use a timer to watch it.
198 int dz_timer
; /* true if timer started */
199 struct callout dzscan_ch
;
200 static struct cnm_state dz_cnm_state
;
203 dzattach(struct dz_softc
*sc
, struct evcnt
*parent_evcnt
, int consline
)
207 sc
->sc_rxint
= sc
->sc_brk
= 0;
208 sc
->sc_consline
= consline
;
210 sc
->sc_dr
.dr_tcrw
= sc
->sc_dr
.dr_tcr
;
211 dz_write2(sc
, sc
->sc_dr
.dr_csr
, DZ_CSR_MSE
| DZ_CSR_RXIE
| DZ_CSR_TXIE
);
212 dz_write1(sc
, sc
->sc_dr
.dr_dtr
, 0);
213 dz_write1(sc
, sc
->sc_dr
.dr_break
, 0);
216 /* Initialize our softc structure. Should be done in open? */
218 for (n
= 0; n
< sc
->sc_type
; n
++) {
219 sc
->sc_dz
[n
].dz_sc
= sc
;
220 sc
->sc_dz
[n
].dz_line
= n
;
221 sc
->sc_dz
[n
].dz_tty
= ttymalloc();
224 evcnt_attach_dynamic(&sc
->sc_rintrcnt
, EVCNT_TYPE_INTR
, parent_evcnt
,
225 device_xname(sc
->sc_dev
), "rintr");
226 evcnt_attach_dynamic(&sc
->sc_tintrcnt
, EVCNT_TYPE_INTR
, parent_evcnt
,
227 device_xname(sc
->sc_dev
), "tintr");
229 /* Console magic keys */
230 cn_init_magic(&dz_cnm_state
);
231 cn_set_magic("\047\001"); /* default magic is BREAK */
232 /* VAX will change it in MD code */
234 /* Alas no interrupt on modem bit changes, so we manually scan */
237 callout_init(&dzscan_ch
, 0);
238 callout_reset(&dzscan_ch
, hz
, dzscan
, NULL
);
243 /* Receiver Interrupt */
248 struct dz_softc
*sc
= arg
;
256 while ((c
= dz_read2(sc
, sc
->sc_dr
.dr_rbuf
)) & DZ_RBUF_DATA_VALID
) {
258 line
= DZ_PORT(c
>>8);
259 tp
= sc
->sc_dz
[line
].dz_tty
;
261 /* Must be caught early */
262 if (sc
->sc_dz
[line
].dz_catch
&&
263 (*sc
->sc_dz
[line
].dz_catch
)(sc
->sc_dz
[line
].dz_private
, cc
))
266 if ((c
& (DZ_RBUF_FRAMING_ERR
| 0xff)) == DZ_RBUF_FRAMING_ERR
)
271 cn_check_magic(tp
->t_dev
, mcc
, dz_cnm_state
);
273 if (!(tp
->t_state
& TS_ISOPEN
)) {
274 cv_broadcast(&tp
->t_rawcv
);
278 if ((c
& DZ_RBUF_OVERRUN_ERR
) && overrun
== 0) {
279 log(LOG_WARNING
, "%s: silo overflow, line %d\n",
280 device_xname(sc
->sc_dev
), line
);
284 if (c
& DZ_RBUF_FRAMING_ERR
)
286 if (c
& DZ_RBUF_PARITY_ERR
)
289 (*tp
->t_linesw
->l_rint
)(cc
, tp
);
293 /* Transmitter Interrupt */
298 struct dz_softc
*sc
= arg
;
305 * Switch to POLLED mode.
306 * Some simple measurements indicated that even on
307 * one port, by freeing the scanner in the controller
308 * by either providing a character or turning off
309 * the port when output is complete, the transmitter
310 * was ready to accept more output when polled again.
311 * With just two ports running the game "worms,"
312 * almost every interrupt serviced both transmitters!
313 * Each UART is double buffered, so if the scanner
314 * is quick enough and timing works out, we can even
315 * feed the same port twice.
318 * Do not need to turn off interrupts, already at interrupt level.
319 * Remove the pdma stuff; no great need of it right now.
323 csr
= dz_read2(sc
, sc
->sc_dr
.dr_csr
);
324 if ((csr
& DZ_CSR_TX_READY
) == 0)
327 line
= DZ_PORT(csr
>> 8);
328 tp
= sc
->sc_dz
[line
].dz_tty
;
330 tp
->t_state
&= ~TS_BUSY
;
332 /* Just send out a char if we have one */
333 /* As long as we can fill the chip buffer, we just loop here */
335 tp
->t_state
|= TS_BUSY
;
337 dz_write1(sc
, sc
->sc_dr
.dr_tbuf
, ch
);
341 /* Nothing to send; clear the scan bit */
342 /* Clear xmit scanner bit; dzstart may set it again */
343 tcr
= dz_read2(sc
, sc
->sc_dr
.dr_tcrw
);
346 dz_write1(sc
, sc
->sc_dr
.dr_tcr
, tcr
);
347 if (sc
->sc_dz
[line
].dz_catch
)
350 if (tp
->t_state
& TS_FLUSH
)
351 tp
->t_state
&= ~TS_FLUSH
;
353 ndflush (&tp
->t_outq
, cl
->c_cc
);
355 (*tp
->t_linesw
->l_start
)(tp
);
360 dzopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
362 const int line
= DZ_PORT(minor(dev
));
363 struct dz_softc
*sc
= device_lookup_private(&dz_cd
, DZ_I2C(minor(dev
)));
367 if (sc
== NULL
|| line
>= sc
->sc_type
)
370 /* if some other device is using the line, it's busy */
371 if (sc
->sc_dz
[line
].dz_catch
)
374 tp
= sc
->sc_dz
[line
].dz_tty
;
377 tp
->t_oproc
= dzstart
;
378 tp
->t_param
= dzparam
;
381 if (kauth_authorize_device_tty(l
->l_cred
, KAUTH_DEVICE_TTY_OPEN
, tp
))
384 if ((tp
->t_state
& TS_ISOPEN
) == 0) {
386 if (tp
->t_ispeed
== 0) {
387 tp
->t_iflag
= TTYDEF_IFLAG
;
388 tp
->t_oflag
= TTYDEF_OFLAG
;
389 tp
->t_cflag
= TTYDEF_CFLAG
;
390 tp
->t_lflag
= TTYDEF_LFLAG
;
391 tp
->t_ispeed
= tp
->t_ospeed
= TTYDEF_SPEED
;
393 (void) dzparam(tp
, &tp
->t_termios
);
397 /* Use DMBIS and *not* DMSET or else we clobber incoming bits */
398 if (dzmctl(sc
, line
, DML_DTR
, DMBIS
) & DML_DCD
)
399 tp
->t_state
|= TS_CARR_ON
;
400 mutex_spin_enter(&tty_lock
);
401 while (!(flag
& O_NONBLOCK
) && !(tp
->t_cflag
& CLOCAL
) &&
402 !(tp
->t_state
& TS_CARR_ON
)) {
404 error
= ttysleep(tp
, &tp
->t_rawcv
, true, 0);
409 mutex_spin_exit(&tty_lock
);
412 return ((*tp
->t_linesw
->l_open
)(dev
, tp
));
417 dzclose(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
419 const int line
= DZ_PORT(minor(dev
));
420 struct dz_softc
*sc
= device_lookup_private(&dz_cd
, DZ_I2C(minor(dev
)));
421 struct tty
*tp
= sc
->sc_dz
[line
].dz_tty
;
423 (*tp
->t_linesw
->l_close
)(tp
, flag
);
425 /* Make sure a BREAK state is not left enabled. */
426 (void) dzmctl(sc
, line
, DML_BRK
, DMBIC
);
428 /* Do a hangup if so required. */
429 if ((tp
->t_cflag
& HUPCL
) || tp
->t_wopen
|| !(tp
->t_state
& TS_ISOPEN
))
430 (void) dzmctl(sc
, line
, 0, DMSET
);
436 dzread(dev_t dev
, struct uio
*uio
, int flag
)
438 struct dz_softc
*sc
= device_lookup_private(&dz_cd
, DZ_I2C(minor(dev
)));
439 struct tty
*tp
= sc
->sc_dz
[DZ_PORT(minor(dev
))].dz_tty
;
441 return ((*tp
->t_linesw
->l_read
)(tp
, uio
, flag
));
445 dzwrite(dev_t dev
, struct uio
*uio
, int flag
)
447 struct dz_softc
*sc
= device_lookup_private(&dz_cd
, DZ_I2C(minor(dev
)));
448 struct tty
*tp
= sc
->sc_dz
[DZ_PORT(minor(dev
))].dz_tty
;
450 return ((*tp
->t_linesw
->l_write
)(tp
, uio
, flag
));
454 dzpoll(dev_t dev
, int events
, struct lwp
*l
)
456 struct dz_softc
*sc
= device_lookup_private(&dz_cd
, DZ_I2C(minor(dev
)));
457 struct tty
*tp
= sc
->sc_dz
[DZ_PORT(minor(dev
))].dz_tty
;
459 return ((*tp
->t_linesw
->l_poll
)(tp
, events
, l
));
464 dzioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
466 struct dz_softc
*sc
= device_lookup_private(&dz_cd
, DZ_I2C(minor(dev
)));
467 const int line
= DZ_PORT(minor(dev
));
468 struct tty
*tp
= sc
->sc_dz
[line
].dz_tty
;
471 error
= (*tp
->t_linesw
->l_ioctl
)(tp
, cmd
, data
, flag
, l
);
475 error
= ttioctl(tp
, cmd
, data
, flag
, l
);
481 (void) dzmctl(sc
, line
, DML_BRK
, DMBIS
);
485 (void) dzmctl(sc
, line
, DML_BRK
, DMBIC
);
489 (void) dzmctl(sc
, line
, DML_DTR
, DMBIS
);
493 (void) dzmctl(sc
, line
, DML_DTR
, DMBIC
);
497 (void) dzmctl(sc
, line
, *(int *)data
, DMSET
);
501 (void) dzmctl(sc
, line
, *(int *)data
, DMBIS
);
505 (void) dzmctl(sc
, line
, *(int *)data
, DMBIC
);
509 *(int *)data
= (dzmctl(sc
, line
, 0, DMGET
) & ~DML_BRK
);
513 return (EPASSTHROUGH
);
521 struct dz_softc
*sc
= device_lookup_private(&dz_cd
, DZ_I2C(minor(dev
)));
523 return sc
->sc_dz
[DZ_PORT(minor(dev
))].dz_tty
;
528 dzstop(struct tty
*tp
, int flag
)
530 if ((tp
->t_state
& (TS_BUSY
| TS_TTSTOP
)) == TS_BUSY
)
531 tp
->t_state
|= TS_FLUSH
;
535 dzstart(struct tty
*tp
)
543 if (tp
->t_state
& (TS_TIMEOUT
|TS_BUSY
|TS_TTSTOP
)) {
552 line
= DZ_PORT(minor(tp
->t_dev
));
553 sc
= device_lookup_private(&dz_cd
, DZ_I2C(minor(tp
->t_dev
)));
555 tp
->t_state
|= TS_BUSY
;
556 state
= dz_read2(sc
, sc
->sc_dr
.dr_tcrw
) & 255;
557 if ((state
& (1 << line
)) == 0)
558 dz_write1(sc
, sc
->sc_dr
.dr_tcr
, state
| (1 << line
));
564 dzparam(struct tty
*tp
, struct termios
*t
)
566 struct dz_softc
*sc
= device_lookup_private(&dz_cd
, DZ_I2C(minor(tp
->t_dev
)));
567 const int line
= DZ_PORT(minor(tp
->t_dev
));
568 int cflag
= t
->c_cflag
;
569 int ispeed
= ttspeedtab(t
->c_ispeed
, dzspeedtab
);
570 int ospeed
= ttspeedtab(t
->c_ospeed
, dzspeedtab
);
574 /* check requested parameters */
575 if (ospeed
< 0 || ispeed
< 0 || ispeed
!= ospeed
)
578 tp
->t_ispeed
= t
->c_ispeed
;
579 tp
->t_ospeed
= t
->c_ospeed
;
583 (void) dzmctl(sc
, line
, 0, DMSET
); /* hang up line */
589 /* XXX This is wrong. Flush output or the chip gets very confused. */
592 lpr
= DZ_LPR_RX_ENABLE
| ((ispeed
&0xF)<<8) | line
;
594 switch (cflag
& CSIZE
)
597 lpr
|= DZ_LPR_5_BIT_CHAR
;
600 lpr
|= DZ_LPR_6_BIT_CHAR
;
603 lpr
|= DZ_LPR_7_BIT_CHAR
;
606 lpr
|= DZ_LPR_8_BIT_CHAR
;
610 lpr
|= DZ_LPR_PARENB
;
614 lpr
|= DZ_LPR_2_STOP
;
616 dz_write2(sc
, sc
->sc_dr
.dr_lpr
, lpr
);
624 dzmctl(struct dz_softc
*sc
, int line
, int bits
, int how
)
635 /* external signals as seen from the port */
636 status
= dz_read1(sc
, sc
->sc_dr
.dr_dcd
) | sc
->sc_dsr
;
639 status
= dz_read1(sc
, sc
->sc_dr
.dr_ring
);
643 /* internal signals/state delivered to port */
644 status
= dz_read1(sc
, sc
->sc_dr
.dr_dtr
);
647 if (sc
->sc_brk
& bit
)
669 if (mbits
& DML_DTR
) {
670 dz_write1(sc
, sc
->sc_dr
.dr_dtr
, dz_read1(sc
, sc
->sc_dr
.dr_dtr
) | bit
);
672 dz_write1(sc
, sc
->sc_dr
.dr_dtr
, dz_read1(sc
, sc
->sc_dr
.dr_dtr
) & ~bit
);
675 if (mbits
& DML_BRK
) {
677 dz_write1(sc
, sc
->sc_dr
.dr_break
, sc
->sc_brk
);
680 dz_write1(sc
, sc
->sc_dr
.dr_break
, sc
->sc_brk
);
689 * This is called by timeout() periodically.
690 * Check to see if modem status bits have changed.
703 for (n
= 0; n
< dz_cd
.cd_ndevs
; n
++) {
704 if ((sc
= device_lookup_private(&dz_cd
, n
)) == NULL
)
707 for (port
= 0; port
< sc
->sc_type
; port
++) {
708 tp
= sc
->sc_dz
[port
].dz_tty
;
711 if ((dz_read1(sc
, sc
->sc_dr
.dr_dcd
) | sc
->sc_dsr
) & bit
) {
712 if (!(tp
->t_state
& TS_CARR_ON
))
713 (*tp
->t_linesw
->l_modem
) (tp
, 1);
714 } else if ((tp
->t_state
& TS_CARR_ON
) &&
715 (*tp
->t_linesw
->l_modem
)(tp
, 0) == 0) {
716 tmp
= dz_read2(sc
, sc
->sc_dr
.dr_tcrw
) & 255;
717 dz_write1(sc
, sc
->sc_dr
.dr_tcr
, tmp
& ~bit
);
722 * If the RX interrupt rate is this high, switch
723 * the controller to Silo Alarm - which means don't
724 * interrupt until the RX silo has 16 characters in
725 * it (the silo is 64 characters in all).
726 * Avoid oscillating SA on and off by not turning
727 * if off unless the rate is appropriately low.
729 csr
= dz_read2(sc
, sc
->sc_dr
.dr_csr
);
731 if (sc
->sc_rxint
> 16*10)
733 else if (sc
->sc_rxint
< 10)
736 dz_write2(sc
, sc
->sc_dr
.dr_csr
, csr
);
743 callout_reset(&dzscan_ch
, hz
, dzscan
, NULL
);
747 * Called after an ubareset. The DZ card is reset, but the only thing
748 * that must be done is to start the receiver and transmitter again.
749 * No DMA setup to care about.
752 dzreset(device_t dev
)
754 struct dz_softc
*sc
= device_private(dev
);
758 for (i
= 0; i
< sc
->sc_type
; i
++) {
759 tp
= sc
->sc_dz
[i
].dz_tty
;
761 if (((tp
->t_state
& TS_ISOPEN
) == 0) || (tp
->t_wopen
== 0))
764 dzparam(tp
, &tp
->t_termios
);
765 dzmctl(sc
, i
, DML_DTR
, DMSET
);
766 tp
->t_state
&= ~TS_BUSY
;
767 dzstart(tp
); /* Kick off transmitter again */