zs.c revision 1.5 1 /* $NetBSD: zs.c,v 1.5 1995/05/14 15:55:51 leo Exp $ */
2
3 /*
4 * Copyright (c) 1995 L. Weppelman (Atari modifications)
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This software was developed by the Computer Systems Engineering group
9 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10 * contributed to Berkeley.
11 *
12 *
13 * All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Lawrence Berkeley Laboratory.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 * must display the following acknowledgement:
28 * This product includes software developed by the University of
29 * California, Berkeley and its contributors.
30 * 4. Neither the name of the University nor the names of its contributors
31 * may be used to endorse or promote products derived from this software
32 * without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 *
46 * @(#)zs.c 8.1 (Berkeley) 7/19/93
47 */
48
49 /*
50 * Zilog Z8530 (ZSCC) driver.
51 *
52 * Runs two tty ports (modem2 and serial2) on zs0.
53 *
54 * This driver knows far too much about chip to usage mappings.
55 */
56 #include <sys/param.h>
57 #include <sys/proc.h>
58 #include <sys/device.h>
59 #include <sys/conf.h>
60 #include <sys/file.h>
61 #include <sys/ioctl.h>
62 #include <sys/tty.h>
63 #include <sys/time.h>
64 #include <sys/kernel.h>
65 #include <sys/syslog.h>
66
67 #include <machine/cpu.h>
68 #include <machine/iomap.h>
69 #include <machine/scu.h>
70 #include <machine/mfp.h>
71
72 #include <dev/ic/z8530.h>
73 #include <atari/dev/zsvar.h>
74 #include "zs.h"
75 #if NZS > 1
76 #error "This driver supports only 1 85C30!"
77 #endif
78
79 #if NZS > 0
80
81 #define PCLK (8000000) /* PCLK pin input clock rate */
82
83 #define splzs spl5
84
85 /*
86 * Software state per found chip.
87 */
88 struct zs_softc {
89 struct device zi_dev; /* base device */
90 volatile struct zsdevice *zi_zs; /* chip registers */
91 struct zs_chanstate zi_cs[2]; /* chan A and B software state */
92 };
93
94 /*
95 * Define the registers for a closed port
96 */
97 u_char zs_init_regs[16] = {
98 /* 0 */ 0,
99 /* 1 */ 0,
100 /* 2 */ 0x60,
101 /* 3 */ 0,
102 /* 4 */ 0,
103 /* 5 */ 0,
104 /* 6 */ 0,
105 /* 7 */ 0,
106 /* 8 */ 0,
107 /* 9 */ ZSWR9_VECTOR_INCL_STAT,
108 /* 10 */ ZSWR10_NRZ,
109 /* 11 */ ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
110 /* 12 */ 0,
111 /* 13 */ 0,
112 /* 14 */ ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA,
113 /* 15 */ 0
114 };
115
116 /* Definition of the driver for autoconfig. */
117 static int zsmatch __P((struct device *, struct cfdata *, void *));
118 static void zsattach __P((struct device *, struct device *, void *));
119 struct cfdriver zscd = {
120 NULL, "zs", (cfmatch_t)zsmatch, zsattach, DV_TTY,
121 sizeof(struct zs_softc), NULL, 0 };
122
123 /* Interrupt handlers. */
124 int zshard __P((long));
125 static int zssoft __P((long));
126 static int zsrint __P((struct zs_chanstate *, volatile struct zschan *));
127 static int zsxint __P((struct zs_chanstate *, volatile struct zschan *));
128 static int zssint __P((struct zs_chanstate *, volatile struct zschan *));
129
130 struct zs_chanstate *zslist;
131
132 /* Routines called from other code. */
133 static void zsstart __P((struct tty *));
134 void zsstop __P((struct tty *, int));
135 static int zsparam __P((struct tty *, struct termios *));
136
137 /* Routines purely local to this driver. */
138 static void zs_reset __P((volatile struct zschan *, int, int));
139 static int zs_modem __P((struct zs_chanstate *, int, int));
140 static void zs_loadchannelregs __P((volatile struct zschan *, u_char *));
141
142 int zsshortcuts; /* number of "shortcut" software interrupts */
143
144 static int
145 zsmatch(pdp, cfp, auxp)
146 struct device *pdp;
147 struct cfdata *cfp;
148 void *auxp;
149 {
150 if(strcmp("zs", auxp) || cfp->cf_unit != 0)
151 return(0);
152 return(1);
153 }
154
155 /*
156 * Attach a found zs.
157 */
158 static void
159 zsattach(parent, dev, aux)
160 struct device *parent;
161 struct device *dev;
162 void *aux;
163 {
164 register struct zs_softc *zi;
165 register struct zs_chanstate *cs;
166 register volatile struct zsdevice *addr;
167 register struct tty *tp;
168 char tmp;
169
170 addr = (struct zsdevice *)AD_SCC;
171 zi = (struct zs_softc *)dev;
172 zi->zi_zs = addr;
173 cs = zi->zi_cs;
174
175 /*
176 * Get the command register into a known state.
177 */
178 tmp = addr->zs_chan[ZS_CHAN_A].zc_csr;
179 tmp = addr->zs_chan[ZS_CHAN_A].zc_csr;
180 tmp = addr->zs_chan[ZS_CHAN_B].zc_csr;
181 tmp = addr->zs_chan[ZS_CHAN_B].zc_csr;
182
183 /*
184 * Do a hardware reset.
185 */
186 ZS_WRITE(&addr->zs_chan[ZS_CHAN_A], 9, ZSWR9_HARD_RESET);
187 delay(50000); /*enough ? */
188 ZS_WRITE(&addr->zs_chan[ZS_CHAN_A], 9, 0);
189
190 /*
191 * Initialize both channels
192 */
193 zs_loadchannelregs(&addr->zs_chan[ZS_CHAN_A], zs_init_regs);
194 zs_loadchannelregs(&addr->zs_chan[ZS_CHAN_B], zs_init_regs);
195
196 if(machineid & ATARI_TT) {
197 /*
198 * enable scc related interrupts
199 */
200 SCU->sys_mask |= SCU_SCC;
201 }
202
203 /* link into interrupt list with order (A,B) (B=A+1) */
204 cs[0].cs_next = &cs[1];
205 cs[1].cs_next = zslist;
206 zslist = cs;
207
208 cs->cs_unit = 0;
209 cs->cs_zc = &addr->zs_chan[ZS_CHAN_A];
210 cs++;
211 cs->cs_unit = 1;
212 cs->cs_zc = &addr->zs_chan[ZS_CHAN_B];
213
214 printf(": serial2 on channel a and modem2 on channel b\n");
215 }
216
217 /*
218 * Open a zs serial port.
219 */
220 int
221 zsopen(dev, flags, mode, p)
222 dev_t dev;
223 int flags;
224 int mode;
225 struct proc *p;
226 {
227 register struct tty *tp;
228 register struct zs_chanstate *cs;
229 struct zs_softc *zi;
230 int unit = ZS_UNIT(dev);
231 int zs = unit >> 1;
232 int error, s;
233
234 if(zs >= zscd.cd_ndevs || (zi = zscd.cd_devs[zs]) == NULL)
235 return (ENXIO);
236 cs = &zi->zi_cs[unit & 1];
237 tp = cs->cs_ttyp;
238 if(tp == NULL) {
239 cs->cs_ttyp = tp = ttymalloc();
240 tp->t_dev = dev;
241 tp->t_oproc = zsstart;
242 tp->t_param = zsparam;
243 }
244
245 s = spltty();
246 if((tp->t_state & TS_ISOPEN) == 0) {
247 ttychars(tp);
248 if(tp->t_ispeed == 0) {
249 tp->t_iflag = TTYDEF_IFLAG;
250 tp->t_oflag = TTYDEF_OFLAG;
251 tp->t_cflag = TTYDEF_CFLAG;
252 tp->t_lflag = TTYDEF_LFLAG;
253 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
254 }
255 (void)zsparam(tp, &tp->t_termios);
256 ttsetwater(tp);
257 }
258 else if(tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
259 splx(s);
260 return (EBUSY);
261 }
262 error = 0;
263 for(;;) {
264 /* loop, turning on the device, until carrier present */
265 zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR, DMSET);
266 if(cs->cs_softcar)
267 tp->t_state |= TS_CARR_ON;
268 if(flags & O_NONBLOCK || tp->t_cflag & CLOCAL ||
269 tp->t_state & TS_CARR_ON)
270 break;
271 tp->t_state |= TS_WOPEN;
272 if(error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
273 ttopen, 0)) {
274 if(!(tp->t_state & TS_ISOPEN)) {
275 zs_modem(cs, 0, DMSET);
276 tp->t_state &= ~TS_WOPEN;
277 ttwakeup(tp);
278 }
279 splx(s);
280 return error;
281 }
282 }
283 splx(s);
284 if(error == 0)
285 error = linesw[tp->t_line].l_open(dev, tp);
286 if(error)
287 zs_modem(cs, 0, DMSET);
288 return(error);
289 }
290
291 /*
292 * Close a zs serial port.
293 */
294 int
295 zsclose(dev, flags, mode, p)
296 dev_t dev;
297 int flags;
298 int mode;
299 struct proc *p;
300 {
301 register struct zs_chanstate *cs;
302 register struct tty *tp;
303 struct zs_softc *zi;
304 int unit = ZS_UNIT(dev);
305 int s;
306
307 zi = zscd.cd_devs[unit >> 1];
308 cs = &zi->zi_cs[unit & 1];
309 tp = cs->cs_ttyp;
310 linesw[tp->t_line].l_close(tp, flags);
311 if(tp->t_cflag & HUPCL || tp->t_state & TS_WOPEN ||
312 (tp->t_state & TS_ISOPEN) == 0) {
313 zs_modem(cs, 0, DMSET);
314 /* hold low for 1 second */
315 (void)tsleep((caddr_t)cs, TTIPRI, ttclos, hz);
316 }
317 if(cs->cs_creg[5] & ZSWR5_BREAK) {
318 s = splzs();
319 cs->cs_preg[5] &= ~ZSWR5_BREAK;
320 cs->cs_creg[5] &= ~ZSWR5_BREAK;
321 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
322 splx(s);
323 }
324 ttyclose(tp);
325
326 /*
327 * Drop all lines and cancel interrupts
328 */
329 zs_loadchannelregs(&zi->zi_zs->zs_chan[unit & 1], zs_init_regs);
330 return (0);
331 }
332
333 /*
334 * Read/write zs serial port.
335 */
336 int
337 zsread(dev, uio, flags)
338 dev_t dev;
339 struct uio *uio;
340 int flags;
341 {
342 register struct zs_chanstate *cs;
343 register struct zs_softc *zi;
344 register struct tty *tp;
345 int unit;
346
347 unit = ZS_UNIT(dev);
348 zi = zscd.cd_devs[unit >> 1];
349 cs = &zi->zi_cs[unit & 1];
350 tp = cs->cs_ttyp;
351
352 return(linesw[tp->t_line].l_read(tp, uio, flags));
353 }
354
355 int
356 zswrite(dev, uio, flags)
357 dev_t dev;
358 struct uio *uio;
359 int flags;
360 {
361 register struct zs_chanstate *cs;
362 register struct zs_softc *zi;
363 register struct tty *tp;
364 int unit;
365
366 unit = ZS_UNIT(dev);
367 zi = zscd.cd_devs[unit >> 1];
368 cs = &zi->zi_cs[unit & 1];
369 tp = cs->cs_ttyp;
370
371 return(linesw[tp->t_line].l_write(tp, uio, flags));
372 }
373
374 struct tty *
375 zstty(dev)
376 dev_t dev;
377 {
378 register struct zs_chanstate *cs;
379 register struct zs_softc *zi;
380 int unit;
381
382 unit = ZS_UNIT(dev);
383 zi = zscd.cd_devs[unit >> 1];
384 cs = &zi->zi_cs[unit & 1];
385 return(cs->cs_ttyp);
386 }
387
388 /*
389 * ZS hardware interrupt. Scan all ZS channels. NB: we know here that
390 * channels are kept in (A,B) pairs.
391 *
392 * Do just a little, then get out; set a software interrupt if more
393 * work is needed.
394 *
395 * We deliberately ignore the vectoring Zilog gives us, and match up
396 * only the number of `reset interrupt under service' operations, not
397 * the order.
398 */
399 int
400 zshard(sr)
401 long sr;
402 {
403 register struct zs_chanstate *a;
404 #define b (a + 1)
405 register volatile struct zschan *zc;
406 register int rr3, intflags = 0, v, i;
407
408 for(a = zslist; a != NULL; a = b->cs_next) {
409 rr3 = ZS_READ(a->cs_zc, 3);
410 if(rr3 & (ZSRR3_IP_A_RX|ZSRR3_IP_A_TX|ZSRR3_IP_A_STAT)) {
411 intflags |= 2;
412 zc = a->cs_zc;
413 i = a->cs_rbput;
414 if(rr3 & ZSRR3_IP_A_RX && (v = zsrint(a, zc)) != 0) {
415 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
416 intflags |= 1;
417 }
418 if(rr3 & ZSRR3_IP_A_TX && (v = zsxint(a, zc)) != 0) {
419 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
420 intflags |= 1;
421 }
422 if(rr3 & ZSRR3_IP_A_STAT && (v = zssint(a, zc)) != 0) {
423 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
424 intflags |= 1;
425 }
426 a->cs_rbput = i;
427 }
428 if(rr3 & (ZSRR3_IP_B_RX|ZSRR3_IP_B_TX|ZSRR3_IP_B_STAT)) {
429 intflags |= 2;
430 zc = b->cs_zc;
431 i = b->cs_rbput;
432 if(rr3 & ZSRR3_IP_B_RX && (v = zsrint(b, zc)) != 0) {
433 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
434 intflags |= 1;
435 }
436 if(rr3 & ZSRR3_IP_B_TX && (v = zsxint(b, zc)) != 0) {
437 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
438 intflags |= 1;
439 }
440 if(rr3 & ZSRR3_IP_B_STAT && (v = zssint(b, zc)) != 0) {
441 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
442 intflags |= 1;
443 }
444 b->cs_rbput = i;
445 }
446 }
447 #undef b
448
449 if(intflags & 1) {
450 if(BASEPRI(sr)) {
451 spl1();
452 zsshortcuts++;
453 return(zssoft(sr));
454 }
455 else add_sicallback(zssoft, 0, 0);
456 }
457 return(intflags & 2);
458 }
459
460 static int
461 zsrint(cs, zc)
462 register struct zs_chanstate *cs;
463 register volatile struct zschan *zc;
464 {
465 register int c = zc->zc_data;
466
467 /* compose receive character and status */
468 c <<= 8;
469 c |= ZS_READ(zc, 1);
470
471 /* clear receive error & interrupt condition */
472 zc->zc_csr = ZSWR0_RESET_ERRORS;
473 zc->zc_csr = ZSWR0_CLR_INTR;
474
475 return(ZRING_MAKE(ZRING_RINT, c));
476 }
477
478 static int
479 zsxint(cs, zc)
480 register struct zs_chanstate *cs;
481 register volatile struct zschan *zc;
482 {
483 register int i = cs->cs_tbc;
484
485 if(i == 0) {
486 zc->zc_csr = ZSWR0_RESET_TXINT;
487 zc->zc_csr = ZSWR0_CLR_INTR;
488 return(ZRING_MAKE(ZRING_XINT, 0));
489 }
490 cs->cs_tbc = i - 1;
491 zc->zc_data = *cs->cs_tba++;
492 zc->zc_csr = ZSWR0_CLR_INTR;
493 return (0);
494 }
495
496 static int
497 zssint(cs, zc)
498 register struct zs_chanstate *cs;
499 register volatile struct zschan *zc;
500 {
501 register int rr0;
502
503 rr0 = zc->zc_csr;
504 zc->zc_csr = ZSWR0_RESET_STATUS;
505 zc->zc_csr = ZSWR0_CLR_INTR;
506 /*
507 * The chip's hardware flow control is, as noted in zsreg.h,
508 * busted---if the DCD line goes low the chip shuts off the
509 * receiver (!). If we want hardware CTS flow control but do
510 * not have it, and carrier is now on, turn HFC on; if we have
511 * HFC now but carrier has gone low, turn it off.
512 */
513 if(rr0 & ZSRR0_DCD) {
514 if(cs->cs_ttyp->t_cflag & CCTS_OFLOW &&
515 (cs->cs_creg[3] & ZSWR3_HFC) == 0) {
516 cs->cs_creg[3] |= ZSWR3_HFC;
517 ZS_WRITE(zc, 3, cs->cs_creg[3]);
518 }
519 }
520 else {
521 if (cs->cs_creg[3] & ZSWR3_HFC) {
522 cs->cs_creg[3] &= ~ZSWR3_HFC;
523 ZS_WRITE(zc, 3, cs->cs_creg[3]);
524 }
525 }
526 return(ZRING_MAKE(ZRING_SINT, rr0));
527 }
528
529 /*
530 * Print out a ring or fifo overrun error message.
531 */
532 static void
533 zsoverrun(unit, ptime, what)
534 int unit;
535 long *ptime;
536 char *what;
537 {
538
539 if(*ptime != time.tv_sec) {
540 *ptime = time.tv_sec;
541 log(LOG_WARNING, "zs%d%c: %s overrun\n", unit >> 1,
542 (unit & 1) + 'a', what);
543 }
544 }
545
546 /*
547 * ZS software interrupt. Scan all channels for deferred interrupts.
548 */
549 int
550 zssoft(sr)
551 long sr;
552 {
553 register struct zs_chanstate *cs;
554 register volatile struct zschan *zc;
555 register struct linesw *line;
556 register struct tty *tp;
557 register int get, n, c, cc, unit, s;
558 int retval = 0;
559
560 s = spltty();
561 for(cs = zslist; cs != NULL; cs = cs->cs_next) {
562 get = cs->cs_rbget;
563 again:
564 n = cs->cs_rbput; /* atomic */
565 if(get == n) /* nothing more on this line */
566 continue;
567 retval = 1;
568 unit = cs->cs_unit; /* set up to handle interrupts */
569 zc = cs->cs_zc;
570 tp = cs->cs_ttyp;
571 line = &linesw[tp->t_line];
572 /*
573 * Compute the number of interrupts in the receive ring.
574 * If the count is overlarge, we lost some events, and
575 * must advance to the first valid one. It may get
576 * overwritten if more data are arriving, but this is
577 * too expensive to check and gains nothing (we already
578 * lost out; all we can do at this point is trade one
579 * kind of loss for another).
580 */
581 n -= get;
582 if(n > ZLRB_RING_SIZE) {
583 zsoverrun(unit, &cs->cs_rotime, "ring");
584 get += n - ZLRB_RING_SIZE;
585 n = ZLRB_RING_SIZE;
586 }
587 while(--n >= 0) {
588 /* race to keep ahead of incoming interrupts */
589 c = cs->cs_rbuf[get++ & ZLRB_RING_MASK];
590 switch (ZRING_TYPE(c)) {
591
592 case ZRING_RINT:
593 c = ZRING_VALUE(c);
594 if(c & ZSRR1_DO)
595 zsoverrun(unit, &cs->cs_fotime, "fifo");
596 cc = c >> 8;
597 if(c & ZSRR1_FE)
598 cc |= TTY_FE;
599 if(c & ZSRR1_PE)
600 cc |= TTY_PE;
601 line->l_rint(cc, tp);
602 break;
603
604 case ZRING_XINT:
605 /*
606 * Transmit done: change registers and resume,
607 * or clear BUSY.
608 */
609 if(cs->cs_heldchange) {
610 int sps;
611
612 sps = splzs();
613 c = zc->zc_csr;
614 if((c & ZSRR0_DCD) == 0)
615 cs->cs_preg[3] &= ~ZSWR3_HFC;
616 bcopy((caddr_t)cs->cs_preg,
617 (caddr_t)cs->cs_creg, 16);
618 zs_loadchannelregs(zc, cs->cs_creg);
619 splx(sps);
620 cs->cs_heldchange = 0;
621 if(cs->cs_heldtbc
622 && (tp->t_state & TS_TTSTOP) == 0) {
623 cs->cs_tbc = cs->cs_heldtbc - 1;
624 zc->zc_data = *cs->cs_tba++;
625 goto again;
626 }
627 }
628 tp->t_state &= ~TS_BUSY;
629 if(tp->t_state & TS_FLUSH)
630 tp->t_state &= ~TS_FLUSH;
631 else ndflush(&tp->t_outq,cs->cs_tba
632 - (caddr_t)tp->t_outq.c_cf);
633 line->l_start(tp);
634 break;
635
636 case ZRING_SINT:
637 /*
638 * Status line change. HFC bit is run in
639 * hardware interrupt, to avoid locking
640 * at splzs here.
641 */
642 c = ZRING_VALUE(c);
643 if((c ^ cs->cs_rr0) & ZSRR0_DCD) {
644 cc = (c & ZSRR0_DCD) != 0;
645 if(line->l_modem(tp, cc) == 0)
646 zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR,
647 cc ? DMBIS : DMBIC);
648 }
649 cs->cs_rr0 = c;
650 break;
651
652 default:
653 log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (%x)\n",
654 unit >> 1, (unit & 1) + 'a', c);
655 break;
656 }
657 }
658 cs->cs_rbget = get;
659 goto again;
660 }
661 splx(s);
662 return (retval);
663 }
664
665 int
666 zsioctl(dev, cmd, data, flag, p)
667 dev_t dev;
668 u_long cmd;
669 caddr_t data;
670 int flag;
671 struct proc *p;
672 {
673 int unit = ZS_UNIT(dev);
674 struct zs_softc *zi = zscd.cd_devs[unit >> 1];
675 register struct tty *tp = zi->zi_cs[unit & 1].cs_ttyp;
676 register int error, s;
677 register struct zs_chanstate *cs = &zi->zi_cs[unit & 1];
678
679 error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p);
680 if(error >= 0)
681 return(error);
682 error = ttioctl(tp, cmd, data, flag, p);
683 if(error >= 0)
684 return (error);
685
686 switch (cmd) {
687 case TIOCSBRK:
688 s = splzs();
689 cs->cs_preg[5] |= ZSWR5_BREAK;
690 cs->cs_creg[5] |= ZSWR5_BREAK;
691 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
692 splx(s);
693 break;
694 case TIOCCBRK:
695 s = splzs();
696 cs->cs_preg[5] &= ~ZSWR5_BREAK;
697 cs->cs_creg[5] &= ~ZSWR5_BREAK;
698 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
699 splx(s);
700 break;
701 case TIOCGFLAGS: {
702 int bits = 0;
703
704 if(cs->cs_softcar)
705 bits |= TIOCFLAG_SOFTCAR;
706 if(cs->cs_creg[15] & ZSWR15_DCD_IE)
707 bits |= TIOCFLAG_CLOCAL;
708 if(cs->cs_creg[3] & ZSWR3_HFC)
709 bits |= TIOCFLAG_CRTSCTS;
710 *(int *)data = bits;
711 break;
712 }
713 case TIOCSFLAGS: {
714 int userbits, driverbits = 0;
715
716 error = suser(p->p_ucred, &p->p_acflag);
717 if(error != 0)
718 return (EPERM);
719
720 userbits = *(int *)data;
721
722 /*
723 * can have `local' or `softcar', and `rtscts' or `mdmbuf'
724 # defaulting to software flow control.
725 */
726 if(userbits & TIOCFLAG_SOFTCAR && userbits & TIOCFLAG_CLOCAL)
727 return(EINVAL);
728 if(userbits & TIOCFLAG_MDMBUF) /* don't support this (yet?) */
729 return(ENXIO);
730
731 s = splzs();
732 if((userbits & TIOCFLAG_SOFTCAR)) {
733 cs->cs_softcar = 1; /* turn on softcar */
734 cs->cs_preg[15] &= ~ZSWR15_DCD_IE; /* turn off dcd */
735 cs->cs_creg[15] &= ~ZSWR15_DCD_IE;
736 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
737 }
738 else if(userbits & TIOCFLAG_CLOCAL) {
739 cs->cs_softcar = 0; /* turn off softcar */
740 cs->cs_preg[15] |= ZSWR15_DCD_IE; /* turn on dcd */
741 cs->cs_creg[15] |= ZSWR15_DCD_IE;
742 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
743 tp->t_termios.c_cflag |= CLOCAL;
744 }
745 if(userbits & TIOCFLAG_CRTSCTS) {
746 cs->cs_preg[15] |= ZSWR15_CTS_IE;
747 cs->cs_creg[15] |= ZSWR15_CTS_IE;
748 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
749 cs->cs_preg[3] |= ZSWR3_HFC;
750 cs->cs_creg[3] |= ZSWR3_HFC;
751 ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
752 tp->t_termios.c_cflag |= CRTSCTS;
753 }
754 else {
755 /* no mdmbuf, so we must want software flow control */
756 cs->cs_preg[15] &= ~ZSWR15_CTS_IE;
757 cs->cs_creg[15] &= ~ZSWR15_CTS_IE;
758 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
759 cs->cs_preg[3] &= ~ZSWR3_HFC;
760 cs->cs_creg[3] &= ~ZSWR3_HFC;
761 ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
762 tp->t_termios.c_cflag &= ~CRTSCTS;
763 }
764 splx(s);
765 break;
766 }
767 case TIOCSDTR:
768 zs_modem(cs, ZSWR5_DTR, DMBIS);
769 break;
770 case TIOCCDTR:
771 zs_modem(cs, ZSWR5_DTR, DMBIC);
772 break;
773 case TIOCMGET:
774 zs_modem(cs, 0, DMGET);
775 break;
776 case TIOCMSET:
777 case TIOCMBIS:
778 case TIOCMBIC:
779 default:
780 return (ENOTTY);
781 }
782 return (0);
783 }
784
785 /*
786 * Start or restart transmission.
787 */
788 static void
789 zsstart(tp)
790 register struct tty *tp;
791 {
792 register struct zs_chanstate *cs;
793 register int s, nch;
794 int unit = ZS_UNIT(tp->t_dev);
795 struct zs_softc *zi = zscd.cd_devs[unit >> 1];
796
797 cs = &zi->zi_cs[unit & 1];
798 s = spltty();
799
800 /*
801 * If currently active or delaying, no need to do anything.
802 */
803 if(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
804 goto out;
805
806 /*
807 * If there are sleepers, and output has drained below low
808 * water mark, awaken.
809 */
810 if(tp->t_outq.c_cc <= tp->t_lowat) {
811 if(tp->t_state & TS_ASLEEP) {
812 tp->t_state &= ~TS_ASLEEP;
813 wakeup((caddr_t)&tp->t_outq);
814 }
815 selwakeup(&tp->t_wsel);
816 }
817
818 nch = ndqb(&tp->t_outq, 0); /* XXX */
819 if(nch) {
820 register char *p = tp->t_outq.c_cf;
821
822 /* mark busy, enable tx done interrupts, & send first byte */
823 tp->t_state |= TS_BUSY;
824 (void) splzs();
825 cs->cs_preg[1] |= ZSWR1_TIE;
826 cs->cs_creg[1] |= ZSWR1_TIE;
827 ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
828 cs->cs_zc->zc_data = *p;
829 cs->cs_tba = p + 1;
830 cs->cs_tbc = nch - 1;
831 } else {
832 /*
833 * Nothing to send, turn off transmit done interrupts.
834 * This is useful if something is doing polled output.
835 */
836 (void) splzs();
837 cs->cs_preg[1] &= ~ZSWR1_TIE;
838 cs->cs_creg[1] &= ~ZSWR1_TIE;
839 ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
840 }
841 out:
842 splx(s);
843 }
844
845 /*
846 * Stop output, e.g., for ^S or output flush.
847 */
848 void
849 zsstop(tp, flag)
850 register struct tty *tp;
851 int flag;
852 {
853 register struct zs_chanstate *cs;
854 register int s, unit = ZS_UNIT(tp->t_dev);
855 struct zs_softc *zi = zscd.cd_devs[unit >> 1];
856
857 cs = &zi->zi_cs[unit & 1];
858 s = splzs();
859 if(tp->t_state & TS_BUSY) {
860 /*
861 * Device is transmitting; must stop it.
862 */
863 cs->cs_tbc = 0;
864 if ((tp->t_state & TS_TTSTOP) == 0)
865 tp->t_state |= TS_FLUSH;
866 }
867 splx(s);
868 }
869
870 /*
871 * Set ZS tty parameters from termios.
872 *
873 * This routine makes use of the fact that only registers
874 * 1, 3, 4, 5, 9, 10, 11, 12, 13, 14, and 15 are written.
875 */
876 static int
877 zsparam(tp, t)
878 register struct tty *tp;
879 register struct termios *t;
880 {
881 int unit = ZS_UNIT(tp->t_dev);
882 struct zs_softc *zi = zscd.cd_devs[unit >> 1];
883 register struct zs_chanstate *cs = &zi->zi_cs[unit & 1];
884 register int tmp, tmp5, cflag, s;
885
886 tmp = t->c_ospeed;
887 if(tmp < 0 || (t->c_ispeed && t->c_ispeed != tmp))
888 return(EINVAL);
889 if(tmp == 0) {
890 /* stty 0 => drop DTR and RTS */
891 zs_modem(cs, 0, DMSET);
892 return(0);
893 }
894 tmp = BPS_TO_TCONST(PCLK / 16, tmp);
895 if(tmp < 2)
896 return(EINVAL);
897
898 cflag = t->c_cflag;
899 tp->t_ispeed = tp->t_ospeed = TCONST_TO_BPS(PCLK / 16, tmp);
900 tp->t_cflag = cflag;
901
902 /*
903 * Block interrupts so that state will not
904 * be altered until we are done setting it up.
905 */
906 s = splzs();
907 cs->cs_preg[12] = tmp;
908 cs->cs_preg[13] = tmp >> 8;
909 cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE;
910 switch(cflag & CSIZE) {
911 case CS5:
912 tmp = ZSWR3_RX_5;
913 tmp5 = ZSWR5_TX_5;
914 break;
915 case CS6:
916 tmp = ZSWR3_RX_6;
917 tmp5 = ZSWR5_TX_6;
918 break;
919 case CS7:
920 tmp = ZSWR3_RX_7;
921 tmp5 = ZSWR5_TX_7;
922 break;
923 case CS8:
924 default:
925 tmp = ZSWR3_RX_8;
926 tmp5 = ZSWR5_TX_8;
927 break;
928 }
929
930 /*
931 * Output hardware flow control on the chip is horrendous: if
932 * carrier detect drops, the receiver is disabled. Hence we
933 * can only do this when the carrier is on.
934 */
935 if(cflag & CCTS_OFLOW && cs->cs_zc->zc_csr & ZSRR0_DCD)
936 tmp |= ZSWR3_HFC | ZSWR3_RX_ENABLE;
937 else tmp |= ZSWR3_RX_ENABLE;
938 cs->cs_preg[3] = tmp;
939 cs->cs_preg[5] = tmp5 | ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS;
940
941 tmp = ZSWR4_CLK_X16 | (cflag & CSTOPB ? ZSWR4_TWOSB : ZSWR4_ONESB);
942 if((cflag & PARODD) == 0)
943 tmp |= ZSWR4_EVENP;
944 if (cflag & PARENB)
945 tmp |= ZSWR4_PARENB;
946 cs->cs_preg[4] = tmp;
947 cs->cs_preg[9] = ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT;
948 cs->cs_preg[10] = ZSWR10_NRZ;
949 cs->cs_preg[11] = ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD;
950 cs->cs_preg[14] = ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA;
951 cs->cs_preg[15] = ZSWR15_BREAK_IE | ZSWR15_DCD_IE;
952
953 /*
954 * If nothing is being transmitted, set up new current values,
955 * else mark them as pending.
956 */
957 if(cs->cs_heldchange == 0) {
958 if (cs->cs_ttyp->t_state & TS_BUSY) {
959 cs->cs_heldtbc = cs->cs_tbc;
960 cs->cs_tbc = 0;
961 cs->cs_heldchange = 1;
962 }
963 else {
964 bcopy((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16);
965 zs_loadchannelregs(cs->cs_zc, cs->cs_creg);
966 }
967 }
968 splx(s);
969 return (0);
970 }
971
972 /*
973 * Raise or lower modem control (DTR/RTS) signals. If a character is
974 * in transmission, the change is deferred.
975 */
976 static int
977 zs_modem(cs, bits, how)
978 struct zs_chanstate *cs;
979 int bits, how;
980 {
981 int s, mbits;
982
983 bits &= ZSWR5_DTR | ZSWR5_RTS;
984
985 s = splzs();
986 mbits = cs->cs_preg[5] & (ZSWR5_DTR | ZSWR5_RTS);
987
988 switch(how) {
989 case DMSET:
990 mbits = bits;
991 break;
992 case DMBIS:
993 mbits |= bits;
994 break;
995 case DMBIC:
996 mbits &= ~bits;
997 break;
998 case DMGET:
999 splx(s);
1000 return(mbits);
1001 }
1002
1003 cs->cs_preg[5] = (cs->cs_preg[5] & ~(ZSWR5_DTR | ZSWR5_RTS)) | mbits;
1004 if(cs->cs_heldchange == 0) {
1005 if(cs->cs_ttyp->t_state & TS_BUSY) {
1006 cs->cs_heldtbc = cs->cs_tbc;
1007 cs->cs_tbc = 0;
1008 cs->cs_heldchange = 1;
1009 }
1010 else {
1011 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
1012 }
1013 }
1014 splx(s);
1015 return(0);
1016 }
1017
1018 /*
1019 * Write the given register set to the given zs channel in the proper order.
1020 * The channel must not be transmitting at the time. The receiver will
1021 * be disabled for the time it takes to write all the registers.
1022 */
1023 static void
1024 zs_loadchannelregs(zc, reg)
1025 volatile struct zschan *zc;
1026 u_char *reg;
1027 {
1028 int i;
1029
1030 zc->zc_csr = ZSM_RESET_ERR; /* reset error condition */
1031 i = zc->zc_data; /* drain fifo */
1032 i = zc->zc_data;
1033 i = zc->zc_data;
1034 ZS_WRITE(zc, 4, reg[4]);
1035 ZS_WRITE(zc, 10, reg[10]);
1036 ZS_WRITE(zc, 3, reg[3] & ~ZSWR3_RX_ENABLE);
1037 ZS_WRITE(zc, 5, reg[5] & ~ZSWR5_TX_ENABLE);
1038 ZS_WRITE(zc, 1, reg[1]);
1039 ZS_WRITE(zc, 9, reg[9]);
1040 ZS_WRITE(zc, 11, reg[11]);
1041 ZS_WRITE(zc, 12, reg[12]);
1042 ZS_WRITE(zc, 13, reg[13]);
1043 ZS_WRITE(zc, 14, reg[14]);
1044 ZS_WRITE(zc, 15, reg[15]);
1045 ZS_WRITE(zc, 3, reg[3]);
1046 ZS_WRITE(zc, 5, reg[5]);
1047 }
1048 #endif /* NZS > 1 */
1049