zs.c revision 1.4 1 /* $NetBSD: zs.c,v 1.4 1995/04/22 22:06:45 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 /*
197 * enable scc related interrupts
198 */
199 SCU->sys_mask |= SCU_SCC;
200
201 /* link into interrupt list with order (A,B) (B=A+1) */
202 cs[0].cs_next = &cs[1];
203 cs[1].cs_next = zslist;
204 zslist = cs;
205
206 cs->cs_unit = 0;
207 cs->cs_zc = &addr->zs_chan[ZS_CHAN_A];
208 cs++;
209 cs->cs_unit = 1;
210 cs->cs_zc = &addr->zs_chan[ZS_CHAN_B];
211
212 printf(": serial2 on channel a and modem2 on channel b\n");
213 }
214
215 /*
216 * Open a zs serial port.
217 */
218 int
219 zsopen(dev, flags, mode, p)
220 dev_t dev;
221 int flags;
222 int mode;
223 struct proc *p;
224 {
225 register struct tty *tp;
226 register struct zs_chanstate *cs;
227 struct zs_softc *zi;
228 int unit = ZS_UNIT(dev);
229 int zs = unit >> 1;
230 int error, s;
231
232 if(zs >= zscd.cd_ndevs || (zi = zscd.cd_devs[zs]) == NULL)
233 return (ENXIO);
234 cs = &zi->zi_cs[unit & 1];
235 tp = cs->cs_ttyp;
236 if(tp == NULL) {
237 cs->cs_ttyp = tp = ttymalloc();
238 tp->t_dev = dev;
239 tp->t_oproc = zsstart;
240 tp->t_param = zsparam;
241 }
242
243 s = spltty();
244 if((tp->t_state & TS_ISOPEN) == 0) {
245 ttychars(tp);
246 if(tp->t_ispeed == 0) {
247 tp->t_iflag = TTYDEF_IFLAG;
248 tp->t_oflag = TTYDEF_OFLAG;
249 tp->t_cflag = TTYDEF_CFLAG;
250 tp->t_lflag = TTYDEF_LFLAG;
251 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
252 }
253 (void)zsparam(tp, &tp->t_termios);
254 ttsetwater(tp);
255 }
256 else if(tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
257 splx(s);
258 return (EBUSY);
259 }
260 error = 0;
261 for(;;) {
262 /* loop, turning on the device, until carrier present */
263 zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR, DMSET);
264 if(cs->cs_softcar)
265 tp->t_state |= TS_CARR_ON;
266 if(flags & O_NONBLOCK || tp->t_cflag & CLOCAL ||
267 tp->t_state & TS_CARR_ON)
268 break;
269 tp->t_state |= TS_WOPEN;
270 if(error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
271 ttopen, 0)) {
272 if(!(tp->t_state & TS_ISOPEN)) {
273 zs_modem(cs, 0, DMSET);
274 tp->t_state &= ~TS_WOPEN;
275 ttwakeup(tp);
276 }
277 splx(s);
278 return error;
279 }
280 }
281 splx(s);
282 if(error == 0)
283 error = linesw[tp->t_line].l_open(dev, tp);
284 if(error)
285 zs_modem(cs, 0, DMSET);
286 return(error);
287 }
288
289 /*
290 * Close a zs serial port.
291 */
292 int
293 zsclose(dev, flags, mode, p)
294 dev_t dev;
295 int flags;
296 int mode;
297 struct proc *p;
298 {
299 register struct zs_chanstate *cs;
300 register struct tty *tp;
301 struct zs_softc *zi;
302 int unit = ZS_UNIT(dev);
303 int s;
304
305 zi = zscd.cd_devs[unit >> 1];
306 cs = &zi->zi_cs[unit & 1];
307 tp = cs->cs_ttyp;
308 linesw[tp->t_line].l_close(tp, flags);
309 if(tp->t_cflag & HUPCL || tp->t_state & TS_WOPEN ||
310 (tp->t_state & TS_ISOPEN) == 0) {
311 zs_modem(cs, 0, DMSET);
312 /* hold low for 1 second */
313 (void)tsleep((caddr_t)cs, TTIPRI, ttclos, hz);
314 }
315 if(cs->cs_creg[5] & ZSWR5_BREAK) {
316 s = splzs();
317 cs->cs_preg[5] &= ~ZSWR5_BREAK;
318 cs->cs_creg[5] &= ~ZSWR5_BREAK;
319 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
320 splx(s);
321 }
322 ttyclose(tp);
323
324 /*
325 * Drop all lines and cancel interrupts
326 */
327 zs_loadchannelregs(&zi->zi_zs->zs_chan[unit & 1], zs_init_regs);
328 return (0);
329 }
330
331 /*
332 * Read/write zs serial port.
333 */
334 int
335 zsread(dev, uio, flags)
336 dev_t dev;
337 struct uio *uio;
338 int flags;
339 {
340 register struct zs_chanstate *cs;
341 register struct zs_softc *zi;
342 register struct tty *tp;
343 int unit;
344
345 unit = ZS_UNIT(dev);
346 zi = zscd.cd_devs[unit >> 1];
347 cs = &zi->zi_cs[unit & 1];
348 tp = cs->cs_ttyp;
349
350 return(linesw[tp->t_line].l_read(tp, uio, flags));
351 }
352
353 int
354 zswrite(dev, uio, flags)
355 dev_t dev;
356 struct uio *uio;
357 int flags;
358 {
359 register struct zs_chanstate *cs;
360 register struct zs_softc *zi;
361 register struct tty *tp;
362 int unit;
363
364 unit = ZS_UNIT(dev);
365 zi = zscd.cd_devs[unit >> 1];
366 cs = &zi->zi_cs[unit & 1];
367 tp = cs->cs_ttyp;
368
369 return(linesw[tp->t_line].l_write(tp, uio, flags));
370 }
371
372 struct tty *
373 zstty(dev)
374 dev_t dev;
375 {
376 register struct zs_chanstate *cs;
377 register struct zs_softc *zi;
378 int unit;
379
380 unit = ZS_UNIT(dev);
381 zi = zscd.cd_devs[unit >> 1];
382 cs = &zi->zi_cs[unit & 1];
383 return(cs->cs_ttyp);
384 }
385
386 /*
387 * ZS hardware interrupt. Scan all ZS channels. NB: we know here that
388 * channels are kept in (A,B) pairs.
389 *
390 * Do just a little, then get out; set a software interrupt if more
391 * work is needed.
392 *
393 * We deliberately ignore the vectoring Zilog gives us, and match up
394 * only the number of `reset interrupt under service' operations, not
395 * the order.
396 */
397 int
398 zshard(sr)
399 long sr;
400 {
401 register struct zs_chanstate *a;
402 #define b (a + 1)
403 register volatile struct zschan *zc;
404 register int rr3, intflags = 0, v, i;
405
406 for(a = zslist; a != NULL; a = b->cs_next) {
407 rr3 = ZS_READ(a->cs_zc, 3);
408 if(rr3 & (ZSRR3_IP_A_RX|ZSRR3_IP_A_TX|ZSRR3_IP_A_STAT)) {
409 intflags |= 2;
410 zc = a->cs_zc;
411 i = a->cs_rbput;
412 if(rr3 & ZSRR3_IP_A_RX && (v = zsrint(a, zc)) != 0) {
413 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
414 intflags |= 1;
415 }
416 if(rr3 & ZSRR3_IP_A_TX && (v = zsxint(a, zc)) != 0) {
417 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
418 intflags |= 1;
419 }
420 if(rr3 & ZSRR3_IP_A_STAT && (v = zssint(a, zc)) != 0) {
421 a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
422 intflags |= 1;
423 }
424 a->cs_rbput = i;
425 }
426 if(rr3 & (ZSRR3_IP_B_RX|ZSRR3_IP_B_TX|ZSRR3_IP_B_STAT)) {
427 intflags |= 2;
428 zc = b->cs_zc;
429 i = b->cs_rbput;
430 if(rr3 & ZSRR3_IP_B_RX && (v = zsrint(b, zc)) != 0) {
431 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
432 intflags |= 1;
433 }
434 if(rr3 & ZSRR3_IP_B_TX && (v = zsxint(b, zc)) != 0) {
435 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
436 intflags |= 1;
437 }
438 if(rr3 & ZSRR3_IP_B_STAT && (v = zssint(b, zc)) != 0) {
439 b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
440 intflags |= 1;
441 }
442 b->cs_rbput = i;
443 }
444 }
445 #undef b
446
447 if(intflags & 1) {
448 if(BASEPRI(sr)) {
449 spl1();
450 zsshortcuts++;
451 return(zssoft(sr));
452 }
453 else add_sicallback(zssoft, 0, 0);
454 }
455 return(intflags & 2);
456 }
457
458 static int
459 zsrint(cs, zc)
460 register struct zs_chanstate *cs;
461 register volatile struct zschan *zc;
462 {
463 register int c = zc->zc_data;
464
465 /* compose receive character and status */
466 c <<= 8;
467 c |= ZS_READ(zc, 1);
468
469 /* clear receive error & interrupt condition */
470 zc->zc_csr = ZSWR0_RESET_ERRORS;
471 zc->zc_csr = ZSWR0_CLR_INTR;
472
473 return(ZRING_MAKE(ZRING_RINT, c));
474 }
475
476 static int
477 zsxint(cs, zc)
478 register struct zs_chanstate *cs;
479 register volatile struct zschan *zc;
480 {
481 register int i = cs->cs_tbc;
482
483 if(i == 0) {
484 zc->zc_csr = ZSWR0_RESET_TXINT;
485 zc->zc_csr = ZSWR0_CLR_INTR;
486 return(ZRING_MAKE(ZRING_XINT, 0));
487 }
488 cs->cs_tbc = i - 1;
489 zc->zc_data = *cs->cs_tba++;
490 zc->zc_csr = ZSWR0_CLR_INTR;
491 return (0);
492 }
493
494 static int
495 zssint(cs, zc)
496 register struct zs_chanstate *cs;
497 register volatile struct zschan *zc;
498 {
499 register int rr0;
500
501 rr0 = zc->zc_csr;
502 zc->zc_csr = ZSWR0_RESET_STATUS;
503 zc->zc_csr = ZSWR0_CLR_INTR;
504 /*
505 * The chip's hardware flow control is, as noted in zsreg.h,
506 * busted---if the DCD line goes low the chip shuts off the
507 * receiver (!). If we want hardware CTS flow control but do
508 * not have it, and carrier is now on, turn HFC on; if we have
509 * HFC now but carrier has gone low, turn it off.
510 */
511 if(rr0 & ZSRR0_DCD) {
512 if(cs->cs_ttyp->t_cflag & CCTS_OFLOW &&
513 (cs->cs_creg[3] & ZSWR3_HFC) == 0) {
514 cs->cs_creg[3] |= ZSWR3_HFC;
515 ZS_WRITE(zc, 3, cs->cs_creg[3]);
516 }
517 }
518 else {
519 if (cs->cs_creg[3] & ZSWR3_HFC) {
520 cs->cs_creg[3] &= ~ZSWR3_HFC;
521 ZS_WRITE(zc, 3, cs->cs_creg[3]);
522 }
523 }
524 return(ZRING_MAKE(ZRING_SINT, rr0));
525 }
526
527 /*
528 * Print out a ring or fifo overrun error message.
529 */
530 static void
531 zsoverrun(unit, ptime, what)
532 int unit;
533 long *ptime;
534 char *what;
535 {
536
537 if(*ptime != time.tv_sec) {
538 *ptime = time.tv_sec;
539 log(LOG_WARNING, "zs%d%c: %s overrun\n", unit >> 1,
540 (unit & 1) + 'a', what);
541 }
542 }
543
544 /*
545 * ZS software interrupt. Scan all channels for deferred interrupts.
546 */
547 int
548 zssoft(sr)
549 long sr;
550 {
551 register struct zs_chanstate *cs;
552 register volatile struct zschan *zc;
553 register struct linesw *line;
554 register struct tty *tp;
555 register int get, n, c, cc, unit, s;
556 int retval = 0;
557
558 s = spltty();
559 for(cs = zslist; cs != NULL; cs = cs->cs_next) {
560 get = cs->cs_rbget;
561 again:
562 n = cs->cs_rbput; /* atomic */
563 if(get == n) /* nothing more on this line */
564 continue;
565 retval = 1;
566 unit = cs->cs_unit; /* set up to handle interrupts */
567 zc = cs->cs_zc;
568 tp = cs->cs_ttyp;
569 line = &linesw[tp->t_line];
570 /*
571 * Compute the number of interrupts in the receive ring.
572 * If the count is overlarge, we lost some events, and
573 * must advance to the first valid one. It may get
574 * overwritten if more data are arriving, but this is
575 * too expensive to check and gains nothing (we already
576 * lost out; all we can do at this point is trade one
577 * kind of loss for another).
578 */
579 n -= get;
580 if(n > ZLRB_RING_SIZE) {
581 zsoverrun(unit, &cs->cs_rotime, "ring");
582 get += n - ZLRB_RING_SIZE;
583 n = ZLRB_RING_SIZE;
584 }
585 while(--n >= 0) {
586 /* race to keep ahead of incoming interrupts */
587 c = cs->cs_rbuf[get++ & ZLRB_RING_MASK];
588 switch (ZRING_TYPE(c)) {
589
590 case ZRING_RINT:
591 c = ZRING_VALUE(c);
592 if(c & ZSRR1_DO)
593 zsoverrun(unit, &cs->cs_fotime, "fifo");
594 cc = c >> 8;
595 if(c & ZSRR1_FE)
596 cc |= TTY_FE;
597 if(c & ZSRR1_PE)
598 cc |= TTY_PE;
599 line->l_rint(cc, tp);
600 break;
601
602 case ZRING_XINT:
603 /*
604 * Transmit done: change registers and resume,
605 * or clear BUSY.
606 */
607 if(cs->cs_heldchange) {
608 int sps;
609
610 sps = splzs();
611 c = zc->zc_csr;
612 if((c & ZSRR0_DCD) == 0)
613 cs->cs_preg[3] &= ~ZSWR3_HFC;
614 bcopy((caddr_t)cs->cs_preg,
615 (caddr_t)cs->cs_creg, 16);
616 zs_loadchannelregs(zc, cs->cs_creg);
617 splx(sps);
618 cs->cs_heldchange = 0;
619 if(cs->cs_heldtbc
620 && (tp->t_state & TS_TTSTOP) == 0) {
621 cs->cs_tbc = cs->cs_heldtbc - 1;
622 zc->zc_data = *cs->cs_tba++;
623 goto again;
624 }
625 }
626 tp->t_state &= ~TS_BUSY;
627 if(tp->t_state & TS_FLUSH)
628 tp->t_state &= ~TS_FLUSH;
629 else ndflush(&tp->t_outq,cs->cs_tba
630 - (caddr_t)tp->t_outq.c_cf);
631 line->l_start(tp);
632 break;
633
634 case ZRING_SINT:
635 /*
636 * Status line change. HFC bit is run in
637 * hardware interrupt, to avoid locking
638 * at splzs here.
639 */
640 c = ZRING_VALUE(c);
641 if((c ^ cs->cs_rr0) & ZSRR0_DCD) {
642 cc = (c & ZSRR0_DCD) != 0;
643 if(line->l_modem(tp, cc) == 0)
644 zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR,
645 cc ? DMBIS : DMBIC);
646 }
647 cs->cs_rr0 = c;
648 break;
649
650 default:
651 log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (%x)\n",
652 unit >> 1, (unit & 1) + 'a', c);
653 break;
654 }
655 }
656 cs->cs_rbget = get;
657 goto again;
658 }
659 splx(s);
660 return (retval);
661 }
662
663 int
664 zsioctl(dev, cmd, data, flag, p)
665 dev_t dev;
666 u_long cmd;
667 caddr_t data;
668 int flag;
669 struct proc *p;
670 {
671 int unit = ZS_UNIT(dev);
672 struct zs_softc *zi = zscd.cd_devs[unit >> 1];
673 register struct tty *tp = zi->zi_cs[unit & 1].cs_ttyp;
674 register int error, s;
675 register struct zs_chanstate *cs = &zi->zi_cs[unit & 1];
676
677 error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p);
678 if(error >= 0)
679 return(error);
680 error = ttioctl(tp, cmd, data, flag, p);
681 if(error >= 0)
682 return (error);
683
684 switch (cmd) {
685 case TIOCSBRK:
686 s = splzs();
687 cs->cs_preg[5] |= ZSWR5_BREAK;
688 cs->cs_creg[5] |= ZSWR5_BREAK;
689 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
690 splx(s);
691 break;
692 case TIOCCBRK:
693 s = splzs();
694 cs->cs_preg[5] &= ~ZSWR5_BREAK;
695 cs->cs_creg[5] &= ~ZSWR5_BREAK;
696 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
697 splx(s);
698 break;
699 case TIOCGFLAGS: {
700 int bits = 0;
701
702 if(cs->cs_softcar)
703 bits |= TIOCFLAG_SOFTCAR;
704 if(cs->cs_creg[15] & ZSWR15_DCD_IE)
705 bits |= TIOCFLAG_CLOCAL;
706 if(cs->cs_creg[3] & ZSWR3_HFC)
707 bits |= TIOCFLAG_CRTSCTS;
708 *(int *)data = bits;
709 break;
710 }
711 case TIOCSFLAGS: {
712 int userbits, driverbits = 0;
713
714 error = suser(p->p_ucred, &p->p_acflag);
715 if(error != 0)
716 return (EPERM);
717
718 userbits = *(int *)data;
719
720 /*
721 * can have `local' or `softcar', and `rtscts' or `mdmbuf'
722 # defaulting to software flow control.
723 */
724 if(userbits & TIOCFLAG_SOFTCAR && userbits & TIOCFLAG_CLOCAL)
725 return(EINVAL);
726 if(userbits & TIOCFLAG_MDMBUF) /* don't support this (yet?) */
727 return(ENXIO);
728
729 s = splzs();
730 if((userbits & TIOCFLAG_SOFTCAR)) {
731 cs->cs_softcar = 1; /* turn on softcar */
732 cs->cs_preg[15] &= ~ZSWR15_DCD_IE; /* turn off dcd */
733 cs->cs_creg[15] &= ~ZSWR15_DCD_IE;
734 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
735 }
736 else if(userbits & TIOCFLAG_CLOCAL) {
737 cs->cs_softcar = 0; /* turn off softcar */
738 cs->cs_preg[15] |= ZSWR15_DCD_IE; /* turn on dcd */
739 cs->cs_creg[15] |= ZSWR15_DCD_IE;
740 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
741 tp->t_termios.c_cflag |= CLOCAL;
742 }
743 if(userbits & TIOCFLAG_CRTSCTS) {
744 cs->cs_preg[15] |= ZSWR15_CTS_IE;
745 cs->cs_creg[15] |= ZSWR15_CTS_IE;
746 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
747 cs->cs_preg[3] |= ZSWR3_HFC;
748 cs->cs_creg[3] |= ZSWR3_HFC;
749 ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
750 tp->t_termios.c_cflag |= CRTSCTS;
751 }
752 else {
753 /* no mdmbuf, so we must want software flow control */
754 cs->cs_preg[15] &= ~ZSWR15_CTS_IE;
755 cs->cs_creg[15] &= ~ZSWR15_CTS_IE;
756 ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
757 cs->cs_preg[3] &= ~ZSWR3_HFC;
758 cs->cs_creg[3] &= ~ZSWR3_HFC;
759 ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
760 tp->t_termios.c_cflag &= ~CRTSCTS;
761 }
762 splx(s);
763 break;
764 }
765 case TIOCSDTR:
766 zs_modem(cs, ZSWR5_DTR, DMBIS);
767 break;
768 case TIOCCDTR:
769 zs_modem(cs, ZSWR5_DTR, DMBIC);
770 break;
771 case TIOCMGET:
772 zs_modem(cs, 0, DMGET);
773 break;
774 case TIOCMSET:
775 case TIOCMBIS:
776 case TIOCMBIC:
777 default:
778 return (ENOTTY);
779 }
780 return (0);
781 }
782
783 /*
784 * Start or restart transmission.
785 */
786 static void
787 zsstart(tp)
788 register struct tty *tp;
789 {
790 register struct zs_chanstate *cs;
791 register int s, nch;
792 int unit = ZS_UNIT(tp->t_dev);
793 struct zs_softc *zi = zscd.cd_devs[unit >> 1];
794
795 cs = &zi->zi_cs[unit & 1];
796 s = spltty();
797
798 /*
799 * If currently active or delaying, no need to do anything.
800 */
801 if(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
802 goto out;
803
804 /*
805 * If there are sleepers, and output has drained below low
806 * water mark, awaken.
807 */
808 if(tp->t_outq.c_cc <= tp->t_lowat) {
809 if(tp->t_state & TS_ASLEEP) {
810 tp->t_state &= ~TS_ASLEEP;
811 wakeup((caddr_t)&tp->t_outq);
812 }
813 selwakeup(&tp->t_wsel);
814 }
815
816 nch = ndqb(&tp->t_outq, 0); /* XXX */
817 if(nch) {
818 register char *p = tp->t_outq.c_cf;
819
820 /* mark busy, enable tx done interrupts, & send first byte */
821 tp->t_state |= TS_BUSY;
822 (void) splzs();
823 cs->cs_preg[1] |= ZSWR1_TIE;
824 cs->cs_creg[1] |= ZSWR1_TIE;
825 ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
826 cs->cs_zc->zc_data = *p;
827 cs->cs_tba = p + 1;
828 cs->cs_tbc = nch - 1;
829 } else {
830 /*
831 * Nothing to send, turn off transmit done interrupts.
832 * This is useful if something is doing polled output.
833 */
834 (void) splzs();
835 cs->cs_preg[1] &= ~ZSWR1_TIE;
836 cs->cs_creg[1] &= ~ZSWR1_TIE;
837 ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
838 }
839 out:
840 splx(s);
841 }
842
843 /*
844 * Stop output, e.g., for ^S or output flush.
845 */
846 void
847 zsstop(tp, flag)
848 register struct tty *tp;
849 int flag;
850 {
851 register struct zs_chanstate *cs;
852 register int s, unit = ZS_UNIT(tp->t_dev);
853 struct zs_softc *zi = zscd.cd_devs[unit >> 1];
854
855 cs = &zi->zi_cs[unit & 1];
856 s = splzs();
857 if(tp->t_state & TS_BUSY) {
858 /*
859 * Device is transmitting; must stop it.
860 */
861 cs->cs_tbc = 0;
862 if ((tp->t_state & TS_TTSTOP) == 0)
863 tp->t_state |= TS_FLUSH;
864 }
865 splx(s);
866 }
867
868 /*
869 * Set ZS tty parameters from termios.
870 *
871 * This routine makes use of the fact that only registers
872 * 1, 3, 4, 5, 9, 10, 11, 12, 13, 14, and 15 are written.
873 */
874 static int
875 zsparam(tp, t)
876 register struct tty *tp;
877 register struct termios *t;
878 {
879 int unit = ZS_UNIT(tp->t_dev);
880 struct zs_softc *zi = zscd.cd_devs[unit >> 1];
881 register struct zs_chanstate *cs = &zi->zi_cs[unit & 1];
882 register int tmp, tmp5, cflag, s;
883
884 tmp = t->c_ospeed;
885 if(tmp < 0 || (t->c_ispeed && t->c_ispeed != tmp))
886 return(EINVAL);
887 if(tmp == 0) {
888 /* stty 0 => drop DTR and RTS */
889 zs_modem(cs, 0, DMSET);
890 return(0);
891 }
892 tmp = BPS_TO_TCONST(PCLK / 16, tmp);
893 if(tmp < 2)
894 return(EINVAL);
895
896 cflag = t->c_cflag;
897 tp->t_ispeed = tp->t_ospeed = TCONST_TO_BPS(PCLK / 16, tmp);
898 tp->t_cflag = cflag;
899
900 /*
901 * Block interrupts so that state will not
902 * be altered until we are done setting it up.
903 */
904 s = splzs();
905 cs->cs_preg[12] = tmp;
906 cs->cs_preg[13] = tmp >> 8;
907 cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE;
908 switch(cflag & CSIZE) {
909 case CS5:
910 tmp = ZSWR3_RX_5;
911 tmp5 = ZSWR5_TX_5;
912 break;
913 case CS6:
914 tmp = ZSWR3_RX_6;
915 tmp5 = ZSWR5_TX_6;
916 break;
917 case CS7:
918 tmp = ZSWR3_RX_7;
919 tmp5 = ZSWR5_TX_7;
920 break;
921 case CS8:
922 default:
923 tmp = ZSWR3_RX_8;
924 tmp5 = ZSWR5_TX_8;
925 break;
926 }
927
928 /*
929 * Output hardware flow control on the chip is horrendous: if
930 * carrier detect drops, the receiver is disabled. Hence we
931 * can only do this when the carrier is on.
932 */
933 if(cflag & CCTS_OFLOW && cs->cs_zc->zc_csr & ZSRR0_DCD)
934 tmp |= ZSWR3_HFC | ZSWR3_RX_ENABLE;
935 else tmp |= ZSWR3_RX_ENABLE;
936 cs->cs_preg[3] = tmp;
937 cs->cs_preg[5] = tmp5 | ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS;
938
939 tmp = ZSWR4_CLK_X16 | (cflag & CSTOPB ? ZSWR4_TWOSB : ZSWR4_ONESB);
940 if((cflag & PARODD) == 0)
941 tmp |= ZSWR4_EVENP;
942 if (cflag & PARENB)
943 tmp |= ZSWR4_PARENB;
944 cs->cs_preg[4] = tmp;
945 cs->cs_preg[9] = ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT;
946 cs->cs_preg[10] = ZSWR10_NRZ;
947 cs->cs_preg[11] = ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD;
948 cs->cs_preg[14] = ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA;
949 cs->cs_preg[15] = ZSWR15_BREAK_IE | ZSWR15_DCD_IE;
950
951 /*
952 * If nothing is being transmitted, set up new current values,
953 * else mark them as pending.
954 */
955 if(cs->cs_heldchange == 0) {
956 if (cs->cs_ttyp->t_state & TS_BUSY) {
957 cs->cs_heldtbc = cs->cs_tbc;
958 cs->cs_tbc = 0;
959 cs->cs_heldchange = 1;
960 }
961 else {
962 bcopy((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16);
963 zs_loadchannelregs(cs->cs_zc, cs->cs_creg);
964 }
965 }
966 splx(s);
967 return (0);
968 }
969
970 /*
971 * Raise or lower modem control (DTR/RTS) signals. If a character is
972 * in transmission, the change is deferred.
973 */
974 static int
975 zs_modem(cs, bits, how)
976 struct zs_chanstate *cs;
977 int bits, how;
978 {
979 int s, mbits;
980
981 bits &= ZSWR5_DTR | ZSWR5_RTS;
982
983 s = splzs();
984 mbits = cs->cs_preg[5] & (ZSWR5_DTR | ZSWR5_RTS);
985
986 switch(how) {
987 case DMSET:
988 mbits = bits;
989 break;
990 case DMBIS:
991 mbits |= bits;
992 break;
993 case DMBIC:
994 mbits &= ~bits;
995 break;
996 case DMGET:
997 splx(s);
998 return(mbits);
999 }
1000
1001 cs->cs_preg[5] = (cs->cs_preg[5] & ~(ZSWR5_DTR | ZSWR5_RTS)) | mbits;
1002 if(cs->cs_heldchange == 0) {
1003 if(cs->cs_ttyp->t_state & TS_BUSY) {
1004 cs->cs_heldtbc = cs->cs_tbc;
1005 cs->cs_tbc = 0;
1006 cs->cs_heldchange = 1;
1007 }
1008 else {
1009 ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
1010 }
1011 }
1012 splx(s);
1013 return(0);
1014 }
1015
1016 /*
1017 * Write the given register set to the given zs channel in the proper order.
1018 * The channel must not be transmitting at the time. The receiver will
1019 * be disabled for the time it takes to write all the registers.
1020 */
1021 static void
1022 zs_loadchannelregs(zc, reg)
1023 volatile struct zschan *zc;
1024 u_char *reg;
1025 {
1026 int i;
1027
1028 zc->zc_csr = ZSM_RESET_ERR; /* reset error condition */
1029 i = zc->zc_data; /* drain fifo */
1030 i = zc->zc_data;
1031 i = zc->zc_data;
1032 ZS_WRITE(zc, 4, reg[4]);
1033 ZS_WRITE(zc, 10, reg[10]);
1034 ZS_WRITE(zc, 3, reg[3] & ~ZSWR3_RX_ENABLE);
1035 ZS_WRITE(zc, 5, reg[5] & ~ZSWR5_TX_ENABLE);
1036 ZS_WRITE(zc, 1, reg[1]);
1037 ZS_WRITE(zc, 9, reg[9]);
1038 ZS_WRITE(zc, 11, reg[11]);
1039 ZS_WRITE(zc, 12, reg[12]);
1040 ZS_WRITE(zc, 13, reg[13]);
1041 ZS_WRITE(zc, 14, reg[14]);
1042 ZS_WRITE(zc, 15, reg[15]);
1043 ZS_WRITE(zc, 3, reg[3]);
1044 ZS_WRITE(zc, 5, reg[5]);
1045 }
1046 #endif /* NZS > 1 */
1047