xref: /openbsd/sys/dev/ic/cy.c (revision ffccd32b)
1 /*	$OpenBSD: cy.c,v 1.42 2023/09/11 08:41:26 mvs Exp $	*/
2 /*
3  * Copyright (c) 1996 Timo Rossi.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the author nor the names of contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 /*
32  * cy.c
33  *
34  * Driver for Cyclades Cyclom-8/16/32 multiport serial cards
35  * (currently not tested with Cyclom-32 cards)
36  *
37  * Timo Rossi, 1996
38  *
39  * Supports both ISA and PCI Cyclom cards
40  *
41  * Uses CD1400 automatic CTS flow control, and
42  * if CY_HW_RTS is defined, uses CD1400 automatic input flow control.
43  * This requires a special cable that exchanges the RTS and DTR lines.
44  *
45  * Lots of debug output can be enabled by defining CY_DEBUG
46  * Some debugging counters (number of receive/transmit interrupts etc.)
47  * can be enabled by defining CY_DEBUG1
48  *
49  * This version uses the bus_space/io_??() stuff
50  *
51  */
52 
53 #include <sys/param.h>
54 #include <sys/ioctl.h>
55 #include <sys/syslog.h>
56 #include <sys/fcntl.h>
57 #include <sys/tty.h>
58 #include <sys/conf.h>
59 #include <sys/device.h>
60 #include <sys/malloc.h>
61 #include <sys/systm.h>
62 
63 #include <machine/bus.h>
64 #include <machine/intr.h>
65 
66 #include <dev/ic/cd1400reg.h>
67 #include <dev/ic/cyreg.h>
68 
69 
70 int	cy_intr(void *);
71 int	cyparam(struct tty *, struct termios *);
72 void	cystart(struct tty *);
73 void	cy_poll(void *);
74 int	cy_modem_control(struct cy_port *, int, int);
75 void	cy_enable_transmitter(struct cy_port *);
76 void	cd1400_channel_cmd(struct cy_port *, int);
77 int	cy_speed(speed_t, int *, int *, int);
78 
79 struct cfdriver cy_cd = {
80 	NULL, "cy", DV_TTY
81 };
82 
83 /*
84  * Common probe routine
85  *
86  * returns the number of chips found.
87  */
88 int
cy_probe_common(bus_space_tag_t memt,bus_space_handle_t memh,int bustype)89 cy_probe_common(bus_space_tag_t memt, bus_space_handle_t memh, int bustype)
90 {
91 	int cy_chip, chip_offs;
92 	u_char firmware_ver;
93 	int nchips;
94 
95 	/* Cyclom card hardware reset */
96 	bus_space_write_1(memt, memh, CY16_RESET<<bustype, 0);
97 	DELAY(500); /* wait for reset to complete */
98 	bus_space_write_1(memt, memh, CY_CLEAR_INTR<<bustype, 0);
99 
100 #ifdef CY_DEBUG
101 	printf("cy: card reset done\n");
102 #endif
103 
104 	nchips = 0;
105 
106 	for (cy_chip = 0, chip_offs = 0;
107 	    cy_chip < CY_MAX_CD1400s;
108 	    cy_chip++, chip_offs += (CY_CD1400_MEMSPACING << bustype)) {
109 		int i;
110 
111 		/* the last 4 cd1400s are 'interleaved'
112 		   with the first 4 on 32-port boards */
113 		if (cy_chip == 4)
114 			chip_offs -= (CY32_ADDR_FIX << bustype);
115 
116 #ifdef CY_DEBUG
117 		printf("cy: probe chip %d offset 0x%x ... ",
118 		    cy_chip, chip_offs);
119 #endif
120 
121 		/* wait until the chip is ready for command */
122 		DELAY(1000);
123 		if (bus_space_read_1(memt, memh, chip_offs +
124 		    ((CD1400_CCR << 1) << bustype)) != 0) {
125 #ifdef CY_DEBUG
126 			printf("not ready for command\n");
127 #endif
128 			break;
129 		}
130 
131 		/* clear the firmware version reg. */
132 		bus_space_write_1(memt, memh, chip_offs +
133 		    ((CD1400_GFRCR << 1) << bustype), 0);
134 
135 		/*
136 		 * On Cyclom-16 references to non-existent chip 4
137 		 * actually access chip 0 (address line 9 not decoded).
138 		 * Here we check if the clearing of chip 4 GFRCR actually
139 		 * cleared chip 0 GFRCR. In that case we have a 16 port card.
140 		 */
141 		if (cy_chip == 4 &&
142 		    bus_space_read_1(memt, memh, chip_offs +
143 			((CD1400_GFRCR << 1) << bustype)) == 0)
144 			break;
145 
146 		/* reset the chip */
147 		bus_space_write_1(memt, memh, chip_offs +
148 		    ((CD1400_CCR << 1) << bustype),
149 		    CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET);
150 
151 		/* wait for the chip to initialize itself */
152 		for (i = 0; i < 200; i++) {
153 			DELAY(50);
154 			firmware_ver = bus_space_read_1(memt, memh, chip_offs +
155 			    ((CD1400_GFRCR << 1) << bustype));
156 			if ((firmware_ver & 0xf0) == 0x40) /* found a CD1400 */
157 				break;
158 		}
159 #ifdef CY_DEBUG
160 		printf("firmware version 0x%x\n", firmware_ver);
161 #endif
162 
163 		if ((firmware_ver & 0xf0) != 0x40)
164 			break;
165 
166 		/* firmware version OK, CD1400 found */
167 		nchips++;
168 	}
169 
170 	if (nchips == 0) {
171 #ifdef CY_DEBUG
172 		printf("no CD1400s found\n");
173 #endif
174 		return (0);
175 	}
176 
177 #ifdef CY_DEBUG
178 	printf("found %d CD1400s\n", nchips);
179 #endif
180 
181 	return (nchips);
182 }
183 
184 void
cy_attach(struct device * parent,struct device * self)185 cy_attach(struct device *parent, struct device *self)
186 {
187 	int card, port, cy_chip, num_chips, cdu, chip_offs, cy_clock;
188 	struct cy_softc *sc = (void *)self;
189 
190 	card = sc->sc_dev.dv_unit;
191 	num_chips = sc->sc_nr_cd1400s;
192 	if (num_chips == 0)
193 		return;
194 
195 	timeout_set(&sc->sc_poll_to, cy_poll, sc);
196 	bzero(sc->sc_ports, sizeof(sc->sc_ports));
197 	sc->sc_nports = num_chips * CD1400_NO_OF_CHANNELS;
198 
199 	port = 0;
200 	for (cy_chip = 0, chip_offs = 0;
201 	    cy_chip < num_chips;
202 	    cy_chip++, chip_offs += (CY_CD1400_MEMSPACING<<sc->sc_bustype)) {
203 		if (cy_chip == 4)
204 			chip_offs -= (CY32_ADDR_FIX<<sc->sc_bustype);
205 
206 #ifdef CY_DEBUG
207 		printf("attach CD1400 #%d offset 0x%x\n", cy_chip, chip_offs);
208 #endif
209 		sc->sc_cd1400_offs[cy_chip] = chip_offs;
210 
211 		/* configure port 0 as serial port
212 		   (should already be after reset) */
213 		cd_write_reg_sc(sc, cy_chip, CD1400_GCR, 0);
214 
215 		/* Set cy_clock depending on firmware version */
216 		if (cd_read_reg_sc(sc, cy_chip, CD1400_GFRCR) <= 0x46)
217 			cy_clock = CY_CLOCK;
218 		else
219 			cy_clock = CY_CLOCK_60;
220 
221 		/* set up a receive timeout period (1ms) */
222 		cd_write_reg_sc(sc, cy_chip, CD1400_PPR,
223 		    (cy_clock / CD1400_PPR_PRESCALER / 1000) + 1);
224 
225 		for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; cdu++) {
226 			sc->sc_ports[port].cy_port_num = port;
227 			sc->sc_ports[port].cy_memt = sc->sc_memt;
228 			sc->sc_ports[port].cy_memh = sc->sc_memh;
229 			sc->sc_ports[port].cy_chip_offs = chip_offs;
230 			sc->sc_ports[port].cy_bustype = sc->sc_bustype;
231 			sc->sc_ports[port].cy_clock = cy_clock;
232 
233 			/* should we initialize anything else here? */
234 			port++;
235 		} /* for(each port on one CD1400...) */
236 
237 	} /* for(each CD1400 on a card... ) */
238 
239 	printf(": %d ports\n", port);
240 
241 	/* ensure an edge for the next interrupt */
242 	bus_space_write_1(sc->sc_memt, sc->sc_memh,
243 	    CY_CLEAR_INTR<<sc->sc_bustype, 0);
244 }
245 
246 /*
247  * open routine. returns zero if successful, else error code
248  */
249 int cyopen(dev_t, int, int, struct proc *);
250 int cyclose(dev_t, int, int, struct proc *);
251 int cyread(dev_t, struct uio *, int);
252 int cywrite(dev_t, struct uio *, int);
253 struct tty *cytty(dev_t);
254 int cyioctl(dev_t, u_long, caddr_t, int, struct proc *);
255 int cystop(struct tty *, int flag);
256 
257 int
cyopen(dev_t dev,int flag,int mode,struct proc * p)258 cyopen(dev_t dev, int flag, int mode, struct proc *p)
259 {
260 	int card = CY_CARD(dev);
261 	int port = CY_PORT(dev);
262 	struct cy_softc *sc;
263 	struct cy_port *cy;
264 	struct tty *tp;
265 	int s, error;
266 
267 	if (card >= cy_cd.cd_ndevs ||
268 	    (sc = cy_cd.cd_devs[card]) == NULL) {
269 		return (ENXIO);
270 	}
271 
272 #ifdef CY_DEBUG
273 	printf("%s open port %d flag 0x%x mode 0x%x\n", sc->sc_dev.dv_xname,
274 	    port, flag, mode);
275 #endif
276 
277 	cy = &sc->sc_ports[port];
278 
279 	s = spltty();
280 	if (cy->cy_tty == NULL) {
281 		cy->cy_tty = ttymalloc(0);
282 	}
283 	splx(s);
284 
285 	tp = cy->cy_tty;
286 	tp->t_oproc = cystart;
287 	tp->t_param = cyparam;
288 	tp->t_dev = dev;
289 
290 	if (!ISSET(tp->t_state, TS_ISOPEN)) {
291 		SET(tp->t_state, TS_WOPEN);
292 		ttychars(tp);
293 		tp->t_iflag = TTYDEF_IFLAG;
294 		tp->t_oflag = TTYDEF_OFLAG;
295 		tp->t_cflag = TTYDEF_CFLAG;
296 		if (ISSET(cy->cy_openflags, TIOCFLAG_CLOCAL))
297 			SET(tp->t_cflag, CLOCAL);
298 		if (ISSET(cy->cy_openflags, TIOCFLAG_CRTSCTS))
299 			SET(tp->t_cflag, CRTSCTS);
300 		if (ISSET(cy->cy_openflags, TIOCFLAG_MDMBUF))
301 			SET(tp->t_cflag, MDMBUF);
302 		tp->t_lflag = TTYDEF_LFLAG;
303 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
304 
305 		s = spltty();
306 
307 		/*
308 		 * Allocate input ring buffer if we don't already have one
309 		 */
310 		if (cy->cy_ibuf == NULL) {
311 			cy->cy_ibuf = malloc(IBUF_SIZE, M_DEVBUF, M_NOWAIT);
312 			if (cy->cy_ibuf == NULL) {
313 				printf("%s: (port %d) can't allocate input buffer\n",
314 				       sc->sc_dev.dv_xname, port);
315 				splx(s);
316 				return (ENOMEM);
317 			}
318 			cy->cy_ibuf_end = cy->cy_ibuf + IBUF_SIZE;
319 		}
320 
321 		/* mark the ring buffer as empty */
322 		cy->cy_ibuf_rd_ptr = cy->cy_ibuf_wr_ptr = cy->cy_ibuf;
323 
324 		/* select CD1400 channel */
325 		cd_write_reg(cy, CD1400_CAR, port & CD1400_CAR_CHAN);
326 		/* reset the channel */
327 		cd1400_channel_cmd(cy, CD1400_CCR_CMDRESET);
328 		/* encode unit (port) number in LIVR */
329 		/* there is just enough space for 5 bits (32 ports) */
330 		cd_write_reg(cy, CD1400_LIVR, port << 3);
331 
332 		cy->cy_channel_control = 0;
333 
334 		if (!timeout_pending(&sc->sc_poll_to))
335 			timeout_add(&sc->sc_poll_to, 1);
336 
337 		/* this sets parameters and raises DTR */
338 		cyparam(tp, &tp->t_termios);
339 
340 		ttsetwater(tp);
341 
342 		/* raise RTS too */
343 		cy_modem_control(cy, TIOCM_RTS, DMBIS);
344 
345 		cy->cy_carrier_stat = cd_read_reg(cy, CD1400_MSVR2);
346 
347 		/* enable receiver and modem change interrupts */
348 		cd_write_reg(cy, CD1400_SRER,
349 		    CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
350 
351 		if (CY_DIALOUT(dev) ||
352 		    ISSET(cy->cy_openflags, TIOCFLAG_SOFTCAR) ||
353 		    ISSET(tp->t_cflag, MDMBUF) ||
354 		    ISSET(cy->cy_carrier_stat, CD1400_MSVR2_CD))
355 			SET(tp->t_state, TS_CARR_ON);
356 		else
357 			CLR(tp->t_state, TS_CARR_ON);
358 	} else if (ISSET(tp->t_state, TS_XCLUDE) && suser(p) != 0) {
359 		return (EBUSY);
360 	} else {
361 		s = spltty();
362 	}
363 
364 	/* wait for carrier if necessary */
365 	if (!ISSET(flag, O_NONBLOCK)) {
366 		while (!ISSET(tp->t_cflag, CLOCAL) &&
367 		    !ISSET(tp->t_state, TS_CARR_ON)) {
368 			SET(tp->t_state, TS_WOPEN);
369 			error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
370 			    ttopen);
371 			if (error != 0) {
372 				splx(s);
373 				CLR(tp->t_state, TS_WOPEN);
374 				return (error);
375 			}
376 		}
377 	}
378 
379 	splx(s);
380 
381 	return (*linesw[tp->t_line].l_open)(dev, tp, p);
382 }
383 
384 /*
385  * close routine. returns zero if successful, else error code
386  */
387 int
cyclose(dev_t dev,int flag,int mode,struct proc * p)388 cyclose(dev_t dev, int flag, int mode, struct proc *p)
389 {
390 	int card = CY_CARD(dev);
391 	int port = CY_PORT(dev);
392 	struct cy_softc *sc = cy_cd.cd_devs[card];
393 	struct cy_port *cy = &sc->sc_ports[port];
394 	struct tty *tp = cy->cy_tty;
395 	int s;
396 
397 #ifdef CY_DEBUG
398 	printf("%s close port %d, flag 0x%x, mode 0x%x\n", sc->sc_dev.dv_xname,
399 	    port, flag, mode);
400 #endif
401 
402 	(*linesw[tp->t_line].l_close)(tp, flag, p);
403 	s = spltty();
404 
405 	if (ISSET(tp->t_cflag, HUPCL) &&
406 	    !ISSET(cy->cy_openflags, TIOCFLAG_SOFTCAR)) {
407 		/* drop DTR and RTS
408 		   (should we wait for output buffer to become empty first?) */
409 		cy_modem_control(cy, 0, DMSET);
410 	}
411 
412 	/*
413 	 * XXX should we disable modem change and
414 	 * receive interrupts here or somewhere ?
415 	 */
416 	CLR(tp->t_state, TS_BUSY | TS_FLUSH);
417 
418 	splx(s);
419 	ttyclose(tp);
420 
421 	return (0);
422 }
423 
424 /*
425  * Read routine
426  */
427 int
cyread(dev_t dev,struct uio * uio,int flag)428 cyread(dev_t dev, struct uio *uio, int flag)
429 {
430 	int card = CY_CARD(dev);
431 	int port = CY_PORT(dev);
432 	struct cy_softc *sc = cy_cd.cd_devs[card];
433 	struct cy_port *cy = &sc->sc_ports[port];
434 	struct tty *tp = cy->cy_tty;
435 
436 #ifdef CY_DEBUG
437 	printf("%s read port %d uio %p flag 0x%x\n", sc->sc_dev.dv_xname,
438 	    port, uio, flag);
439 #endif
440 
441 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
442 }
443 
444 /*
445  * Write routine
446  */
447 int
cywrite(dev_t dev,struct uio * uio,int flag)448 cywrite(dev_t dev, struct uio *uio, int flag)
449 {
450 	int card = CY_CARD(dev);
451 	int port = CY_PORT(dev);
452 	struct cy_softc *sc = cy_cd.cd_devs[card];
453 	struct cy_port *cy = &sc->sc_ports[port];
454 	struct tty *tp = cy->cy_tty;
455 
456 #ifdef CY_DEBUG
457 	printf("%s write port %d uio %p flag 0x%x\n", sc->sc_dev.dv_xname,
458 	    port, uio, flag);
459 #endif
460 
461 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
462 }
463 
464 /*
465  * return tty pointer
466  */
467 struct tty *
cytty(dev_t dev)468 cytty(dev_t dev)
469 {
470 	int card = CY_CARD(dev);
471 	int port = CY_PORT(dev);
472 	struct cy_softc *sc = cy_cd.cd_devs[card];
473 	struct cy_port *cy = &sc->sc_ports[port];
474 	struct tty *tp = cy->cy_tty;
475 
476 	return (tp);
477 }
478 
479 /*
480  * ioctl routine
481  */
482 int
cyioctl(dev_t dev,u_long cmd,caddr_t data,int flag,struct proc * p)483 cyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
484 {
485 	int card = CY_CARD(dev);
486 	int port = CY_PORT(dev);
487 	struct cy_softc *sc = cy_cd.cd_devs[card];
488 	struct cy_port *cy = &sc->sc_ports[port];
489 	struct tty *tp = cy->cy_tty;
490 	int error;
491 
492 #ifdef CY_DEBUG
493 	printf("%s port %d ioctl cmd 0x%lx data %p flag 0x%x\n",
494 	    sc->sc_dev.dv_xname, port, cmd, data, flag);
495 #endif
496 
497 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
498 	if (error >= 0)
499 		return (error);
500 
501 	error = ttioctl(tp, cmd, data, flag, p);
502 	if (error >= 0)
503 		return (error);
504 
505 	/* XXX should not allow dropping DTR when dialin? */
506 
507 	switch (cmd) {
508 	case TIOCSBRK:		/* start break */
509 		SET(cy->cy_flags, CYF_START_BREAK);
510 		cy_enable_transmitter(cy);
511 		break;
512 
513 	case TIOCCBRK:		/* stop break */
514 		SET(cy->cy_flags, CYF_END_BREAK);
515 		cy_enable_transmitter(cy);
516 		break;
517 
518 	case TIOCSDTR:		/* DTR on */
519 		cy_modem_control(cy, TIOCM_DTR, DMBIS);
520 		break;
521 
522 	case TIOCCDTR:		/* DTR off */
523 		cy_modem_control(cy, TIOCM_DTR, DMBIC);
524 		break;
525 
526 	case TIOCMSET:		/* set new modem control line values */
527 		cy_modem_control(cy, *((int *)data), DMSET);
528 		break;
529 
530 	case TIOCMBIS:		/* turn modem control bits on */
531 		cy_modem_control(cy, *((int *)data), DMBIS);
532 		break;
533 
534 	case TIOCMBIC:		/* turn modem control bits off */
535 		cy_modem_control(cy, *((int *)data), DMBIC);
536 		break;
537 
538 	case TIOCMGET:		/* get modem control/status line state */
539 		*((int *)data) = cy_modem_control(cy, 0, DMGET);
540 		break;
541 
542 	case TIOCGFLAGS:
543 		*((int *)data) = cy->cy_openflags |
544 		    (CY_DIALOUT(dev) ? TIOCFLAG_SOFTCAR : 0);
545 		break;
546 
547 	case TIOCSFLAGS:
548 		error = suser(p);
549 		if (error != 0)
550 			return (EPERM);
551 
552 		cy->cy_openflags = *((int *)data) &
553 		    (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL |
554 		     TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF);
555 		break;
556 
557 	default:
558 		return (ENOTTY);
559 	}
560 
561 	return (0);
562 }
563 
564 /*
565  * start output
566  */
567 void
cystart(struct tty * tp)568 cystart(struct tty *tp)
569 {
570 	int card = CY_CARD(tp->t_dev);
571 	int port = CY_PORT(tp->t_dev);
572 	struct cy_softc *sc = cy_cd.cd_devs[card];
573 	struct cy_port *cy = &sc->sc_ports[port];
574 	int s;
575 
576 #ifdef CY_DEBUG
577 	printf("%s port %d start, tty %p\n", sc->sc_dev.dv_xname, port, tp);
578 #endif
579 
580 	s = spltty();
581 
582 #ifdef CY_DEBUG1
583 	cy->cy_start_count++;
584 #endif
585 
586 	if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) {
587 		ttwakeupwr(tp);
588 		if (tp->t_outq.c_cc == 0)
589 			goto out;
590 
591 		SET(tp->t_state, TS_BUSY);
592 		cy_enable_transmitter(cy);
593 	}
594 out:
595 
596 	splx(s);
597 }
598 
599 /*
600  * stop output
601  */
602 int
cystop(struct tty * tp,int flag)603 cystop(struct tty *tp, int flag)
604 {
605 	int card = CY_CARD(tp->t_dev);
606 	int port = CY_PORT(tp->t_dev);
607 	struct cy_softc *sc = cy_cd.cd_devs[card];
608 	struct cy_port *cy = &sc->sc_ports[port];
609 	int s;
610 
611 #ifdef CY_DEBUG
612 	printf("%s port %d stop tty %p flag 0x%x\n", sc->sc_dev.dv_xname,
613 	    port, tp, flag);
614 #endif
615 
616 	s = spltty();
617 
618 	if (ISSET(tp->t_state, TS_BUSY)) {
619 		if (!ISSET(tp->t_state, TS_TTSTOP))
620 			SET(tp->t_state, TS_FLUSH);
621 
622 		/*
623 		 * the transmit interrupt routine will disable transmit when it
624 		 * notices that CYF_STOP has been set.
625 		 */
626 		SET(cy->cy_flags, CYF_STOP);
627 	}
628 	splx(s);
629 	return (0);
630 }
631 
632 /*
633  * parameter setting routine.
634  * returns 0 if successful, else returns error code
635  */
636 int
cyparam(struct tty * tp,struct termios * t)637 cyparam(struct tty *tp, struct termios *t)
638 {
639 	int card = CY_CARD(tp->t_dev);
640 	int port = CY_PORT(tp->t_dev);
641 	struct cy_softc *sc = cy_cd.cd_devs[card];
642 	struct cy_port *cy = &sc->sc_ports[port];
643 	int ibpr, obpr, i_clk_opt, o_clk_opt;
644 	int s, opt;
645 
646 #ifdef CY_DEBUG
647 	printf("%s port %d param tty %p termios %p\n", sc->sc_dev.dv_xname,
648 	    port, tp, t);
649 	printf("ispeed %d ospeed %d\n", t->c_ispeed, t->c_ospeed);
650 #endif
651 
652 	if (t->c_ospeed != 0 &&
653 	    cy_speed(t->c_ospeed, &o_clk_opt, &obpr, cy->cy_clock) < 0)
654 		return (EINVAL);
655 
656 	if (t->c_ispeed != 0 &&
657 	    cy_speed(t->c_ispeed, &i_clk_opt, &ibpr, cy->cy_clock) < 0)
658 		return (EINVAL);
659 
660 	s = spltty();
661 
662 	/* hang up the line is ospeed is zero, else turn DTR on */
663 	cy_modem_control(cy, TIOCM_DTR, (t->c_ospeed == 0 ? DMBIC : DMBIS));
664 
665 	/* channel was selected by the above call to cy_modem_control() */
666 	/* cd_write_reg(cy, CD1400_CAR, port & CD1400_CAR_CHAN); */
667 
668 	/* set transmit speed */
669 	if (t->c_ospeed != 0) {
670 		cd_write_reg(cy, CD1400_TCOR, o_clk_opt);
671 		cd_write_reg(cy, CD1400_TBPR, obpr);
672 	}
673 	/* set receive speed */
674 	if (t->c_ispeed != 0) {
675 		cd_write_reg(cy, CD1400_RCOR, i_clk_opt);
676 		cd_write_reg(cy, CD1400_RBPR, ibpr);
677 	}
678 
679 	opt = CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN
680 	    | (ISSET(t->c_cflag, CREAD) ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS);
681 
682 	if (opt != cy->cy_channel_control) {
683 		cy->cy_channel_control = opt;
684 		cd1400_channel_cmd(cy, opt);
685 	}
686 
687 	/* compute COR1 contents */
688 	opt = 0;
689 	if (ISSET(t->c_cflag, PARENB)) {
690 		if (ISSET(t->c_cflag, PARODD))
691 			opt |= CD1400_COR1_PARODD;
692 		opt |= CD1400_COR1_PARNORMAL;
693 	}
694 
695 	if (!ISSET(t->c_iflag, INPCK))
696 		opt |= CD1400_COR1_NOINPCK;	/* no parity checking */
697 
698 	if (ISSET(t->c_cflag, CSTOPB))
699 		opt |= CD1400_COR1_STOP2;
700 
701 	switch (t->c_cflag & CSIZE) {
702 	case CS5:
703 		opt |= CD1400_COR1_CS5;
704 		break;
705 
706 	case CS6:
707 		opt |= CD1400_COR1_CS6;
708 		break;
709 
710 	case CS7:
711 		opt |= CD1400_COR1_CS7;
712 		break;
713 
714 	default:
715 		opt |= CD1400_COR1_CS8;
716 		break;
717 	}
718 
719 	cd_write_reg(cy, CD1400_COR1, opt);
720 
721 #ifdef CY_DEBUG
722 	printf("cor1 = 0x%x...", opt);
723 #endif
724 
725 	/*
726 	 * use the CD1400 automatic CTS flow control if CRTSCTS is set
727 	 *
728 	 * CD1400_COR2_ETC is used because breaks are generated with
729 	 * embedded transmit commands
730 	 */
731 	cd_write_reg(cy, CD1400_COR2,
732 	    CD1400_COR2_ETC |
733 	    (ISSET(t->c_cflag, CRTSCTS) ? CD1400_COR2_CCTS_OFLOW : 0));
734 
735 	cd_write_reg(cy, CD1400_COR3, RX_FIFO_THRESHOLD);
736 
737 	cd1400_channel_cmd(cy,
738 	    CD1400_CCR_CMDCORCHG |
739 	    CD1400_CCR_COR1 | CD1400_CCR_COR2 | CD1400_CCR_COR3);
740 
741 	cd_write_reg(cy, CD1400_COR4, CD1400_COR4_PFO_EXCEPTION);
742 	cd_write_reg(cy, CD1400_COR5, 0);
743 
744 	/*
745 	 * set modem change option registers to generate interrupts
746 	 * on carrier detect changes.
747 	 *
748 	 * if hardware RTS handshaking is used (CY_HW_RTS, DTR and RTS lines
749 	 * exchanged), also set the handshaking threshold.
750 	 */
751 #ifdef CY_HW_RTS
752 	cd_write_reg(cy, CD1400_MCOR1, CD1400_MCOR1_CDzd |
753 	    (ISSET(t->c_cflag, CRTSCTS) ? RX_DTR_THRESHOLD : 0));
754 #else
755 	cd_write_reg(cy, CD1400_MCOR1, CD1400_MCOR1_CDzd);
756 #endif /* CY_HW_RTS */
757 
758 	cd_write_reg(cy, CD1400_MCOR2, CD1400_MCOR2_CDod);
759 
760 	/*
761 	 * set receive timeout to approx. 2ms
762 	 * could use more complex logic here...
763 	 * (but is it actually needed or even useful?)
764 	 */
765 	cd_write_reg(cy, CD1400_RTPR, 2);
766 
767 	/*
768 	 * should do anything else here?
769 	 * XXX check MDMBUF handshaking like in com.c?
770 	 */
771 
772 	splx(s);
773 	return (0);
774 }
775 
776 /*
777  * set/get modem line status
778  *
779  * bits can be: TIOCM_DTR, TIOCM_RTS, TIOCM_CTS, TIOCM_CD, TIOCM_RI, TIOCM_DSR
780  *
781  * RTS and DTR are exchanged if CY_HW_RTS is set
782  *
783  */
784 int
cy_modem_control(struct cy_port * cy,int bits,int howto)785 cy_modem_control(struct cy_port *cy, int bits, int howto)
786 {
787 	int s, msvr;
788 
789 	s = spltty();
790 
791 	/* select channel */
792 	cd_write_reg(cy, CD1400_CAR, cy->cy_port_num & CD1400_CAR_CHAN);
793 
794 /* does not manipulate RTS if it is used for flow control */
795 	switch (howto) {
796 	case DMGET:
797 		bits = 0;
798 		if (cy->cy_channel_control & CD1400_CCR_RCVEN)
799 			bits |= TIOCM_LE;
800 		msvr = cd_read_reg(cy, CD1400_MSVR2);
801 #ifdef CY_HW_RTS
802 		if (cd_read_reg(cy, CD1400_MSVR1) & CD1400_MSVR1_RTS)
803 			bits |= TIOCM_DTR;
804 		if (msvr & CD1400_MSVR2_DTR)
805 			bits |= TIOCM_RTS;
806 #else
807 		if (cd_read_reg(cy, CD1400_MSVR1) & CD1400_MSVR1_RTS)
808 			bits |= TIOCM_RTS;
809 		if (msvr & CD1400_MSVR2_DTR)
810 			bits |= TIOCM_DTR;
811 #endif /* CY_HW_RTS */
812 		if (msvr & CD1400_MSVR2_CTS)
813 			bits |= TIOCM_CTS;
814 		if (msvr & CD1400_MSVR2_CD)
815 			bits |= TIOCM_CD;
816 		if (msvr & CD1400_MSVR2_DSR)	/* not connected on some
817 						   Cyclom cards? */
818 			bits |= TIOCM_DSR;
819 		if (msvr & CD1400_MSVR2_RI)	/* not connected on
820 						   Cyclom-8Y cards? */
821 			bits |= TIOCM_RI;
822 		splx(s);
823 		return (bits);
824 
825 	case DMSET: /* replace old values with new ones */
826 #ifdef CY_HW_RTS
827 		if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS))
828 			cd_write_reg(cy, CD1400_MSVR2,
829 			    ((bits & TIOCM_RTS) ? CD1400_MSVR2_DTR : 0));
830 		cd_write_reg(cy, CD1400_MSVR1,
831 		    ((bits & TIOCM_DTR) ? CD1400_MSVR1_RTS : 0));
832 #else
833 		if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS))
834 			cd_write_reg(cy, CD1400_MSVR1,
835 			    ((bits & TIOCM_RTS) ? CD1400_MSVR1_RTS : 0));
836 		cd_write_reg(cy, CD1400_MSVR2,
837 		    ((bits & TIOCM_DTR) ? CD1400_MSVR2_DTR : 0));
838 #endif /* CY_HW_RTS */
839 		break;
840 
841 	case DMBIS: /* set bits */
842 #ifdef CY_HW_RTS
843 		if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS) &&
844 		    (bits & TIOCM_RTS) != 0)
845 			cd_write_reg(cy, CD1400_MSVR2, CD1400_MSVR2_DTR);
846 		if (bits & TIOCM_DTR)
847 			cd_write_reg(cy, CD1400_MSVR1, CD1400_MSVR1_RTS);
848 #else
849 		if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS) &&
850 		    (bits & TIOCM_RTS) != 0)
851 			cd_write_reg(cy, CD1400_MSVR1, CD1400_MSVR1_RTS);
852 		if (bits & TIOCM_DTR)
853 			cd_write_reg(cy, CD1400_MSVR2, CD1400_MSVR2_DTR);
854 #endif /* CY_HW_RTS */
855 		break;
856 
857 	case DMBIC: /* clear bits */
858 #ifdef CY_HW_RTS
859 		if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS) &&
860 		    (bits & TIOCM_RTS))
861 			cd_write_reg(cy, CD1400_MSVR2, 0);
862 		if (bits & TIOCM_DTR)
863 			cd_write_reg(cy, CD1400_MSVR1, 0);
864 #else
865 		if (!ISSET(cy->cy_tty->t_cflag, CRTSCTS) &&
866 		    (bits & TIOCM_RTS))
867 			cd_write_reg(cy, CD1400_MSVR1, 0);
868 		if (bits & TIOCM_DTR)
869 			cd_write_reg(cy, CD1400_MSVR2, 0);
870 #endif /* CY_HW_RTS */
871 		break;
872 	}
873 	splx(s);
874 	return (0);
875 }
876 
877 /*
878  * Upper-level handler loop (called from timer interrupt?)
879  * This routine is common for multiple cards
880  */
881 void
cy_poll(void * arg)882 cy_poll(void *arg)
883 {
884 	int port;
885 	struct cy_softc *sc = arg;
886 	struct cy_port *cy;
887 	struct tty *tp;
888 	static int counter = 0;
889 #ifdef CY_DEBUG1
890 	int did_something;
891 #endif
892 
893 	int s;
894 
895 	s = spltty();
896 
897 	if (sc->sc_events == 0 && ++counter < 200) {
898 		splx(s);
899 		goto out;
900 	}
901 
902 	sc->sc_events = 0;
903 	splx(s);
904 
905 #ifdef CY_DEBUG1
906 	sc->sc_poll_count1++;
907 	did_something = 0;
908 #endif
909 
910 	for (port = 0; port < sc->sc_nports; port++) {
911 		cy = &sc->sc_ports[port];
912 		if ((tp = cy->cy_tty) == NULL || cy->cy_ibuf == NULL ||
913 		    !ISSET(tp->t_state, TS_ISOPEN | TS_WOPEN))
914 			continue;
915 
916 		/*
917 		 * handle received data
918 		 */
919 		while (cy->cy_ibuf_rd_ptr != cy->cy_ibuf_wr_ptr) {
920 			u_char line_stat;
921 			int chr;
922 
923 			line_stat = cy->cy_ibuf_rd_ptr[0];
924 			chr = cy->cy_ibuf_rd_ptr[1];
925 
926 			if (line_stat &
927 			    (CD1400_RDSR_BREAK|CD1400_RDSR_FE))
928 				chr |= TTY_FE;
929 			if (line_stat & CD1400_RDSR_PE)
930 				chr |= TTY_PE;
931 
932 			/*
933 			 * on an overrun error the data is treated as
934 			 * good just as it should be.
935 			 */
936 
937 #ifdef CY_DEBUG
938 			printf("%s port %d ttyinput 0x%x\n",
939 			    sc->sc_dev.dv_xname, port, chr);
940 #endif
941 
942 			(*linesw[tp->t_line].l_rint)(chr, tp);
943 
944 			s = spltty(); /* really necessary? */
945 			if ((cy->cy_ibuf_rd_ptr += 2) ==
946 			    cy->cy_ibuf_end)
947 				cy->cy_ibuf_rd_ptr = cy->cy_ibuf;
948 			splx(s);
949 
950 #ifdef CY_DEBUG1
951 			did_something = 1;
952 #endif
953 		}
954 
955 #ifndef CY_HW_RTS
956 		/*
957 		 * If we don't have any received data in ibuf and
958 		 * CRTSCTS is on and RTS is turned off, it is time
959 		 * to turn RTS back on
960 		 */
961 		if (ISSET(tp->t_cflag, CRTSCTS)) {
962 			/* we can't use cy_modem_control() here as it
963 			    doesn't change RTS if RTSCTS is on */
964 			cd_write_reg(cy, CD1400_CAR,
965 			    port & CD1400_CAR_CHAN);
966 
967 			if ((cd_read_reg(cy,
968 			    CD1400_MSVR1) & CD1400_MSVR1_RTS) == 0) {
969 				cd_write_reg(cy, CD1400_MSVR1,
970 				    CD1400_MSVR1_RTS);
971 #ifdef CY_DEBUG1
972 				did_something = 1;
973 #endif
974 			}
975 		}
976 #endif /* CY_HW_RTS */
977 
978 		/*
979 		 * handle carrier changes
980 		 */
981 		s = spltty();
982 		if (ISSET(cy->cy_flags, CYF_CARRIER_CHANGED)) {
983 			int carrier;
984 
985 			CLR(cy->cy_flags, CYF_CARRIER_CHANGED);
986 			splx(s);
987 
988 			carrier = ((cy->cy_carrier_stat &
989 			    CD1400_MSVR2_CD) != 0);
990 
991 #ifdef CY_DEBUG
992 			printf("%s: cy_poll: carrier change "
993 			    "(port %d, carrier %d)\n",
994 			    sc->sc_dev.dv_xname, port, carrier);
995 #endif
996 			if (CY_DIALIN(tp->t_dev) &&
997 			    !(*linesw[tp->t_line].l_modem)(tp, carrier))
998 				cy_modem_control(cy, TIOCM_DTR, DMBIC);
999 
1000 #ifdef CY_DEBUG1
1001 			did_something = 1;
1002 #endif
1003 		} else {
1004 			splx(s);
1005 		}
1006 
1007 		s = spltty();
1008 		if (ISSET(cy->cy_flags, CYF_START)) {
1009 			CLR(cy->cy_flags, CYF_START);
1010 			splx(s);
1011 
1012 			(*linesw[tp->t_line].l_start)(tp);
1013 
1014 #ifdef CY_DEBUG1
1015 			did_something = 1;
1016 #endif
1017 		} else {
1018 			splx(s);
1019 		}
1020 
1021 		/* could move this to even upper level... */
1022 		if (cy->cy_fifo_overruns) {
1023 			cy->cy_fifo_overruns = 0;
1024 			/* doesn't report overrun count,
1025 			   but shouldn't really matter */
1026 			log(LOG_WARNING, "%s: port %d fifo overrun\n",
1027 			    sc->sc_dev.dv_xname, port);
1028 		}
1029 		if (cy->cy_ibuf_overruns) {
1030 			cy->cy_ibuf_overruns = 0;
1031 			log(LOG_WARNING, "%s: port %d ibuf overrun\n",
1032 			    sc->sc_dev.dv_xname, port);
1033 		}
1034 	} /* for(port...) */
1035 #ifdef CY_DEBUG1
1036 	if (did_something && counter >= 200)
1037 		sc->sc_poll_count2++;
1038 #endif
1039 
1040 	counter = 0;
1041 
1042 out:
1043 	timeout_add(&sc->sc_poll_to, 1);
1044 }
1045 
1046 /*
1047  * hardware interrupt routine
1048  */
1049 int
cy_intr(void * arg)1050 cy_intr(void *arg)
1051 {
1052 	struct cy_softc *sc = arg;
1053 	struct cy_port *cy;
1054 	int cy_chip, stat;
1055 	int int_serviced = -1;
1056 
1057 	/*
1058 	 * Check interrupt status of each CD1400 chip on this card
1059 	 * (multiple cards cannot share the same interrupt)
1060 	 */
1061 	for (cy_chip = 0; cy_chip < sc->sc_nr_cd1400s; cy_chip++) {
1062 
1063 		stat = cd_read_reg_sc(sc, cy_chip, CD1400_SVRR);
1064 		if (stat == 0)
1065 			continue;
1066 
1067 		if (ISSET(stat, CD1400_SVRR_RXRDY)) {
1068 			u_char save_car, save_rir, serv_type;
1069 			u_char line_stat, recv_data, n_chars;
1070 			u_char *buf_p;
1071 
1072 			save_rir = cd_read_reg_sc(sc, cy_chip, CD1400_RIR);
1073 			save_car = cd_read_reg_sc(sc, cy_chip, CD1400_CAR);
1074 			/* enter rx service */
1075 			cd_write_reg_sc(sc, cy_chip, CD1400_CAR, save_rir);
1076 
1077 			serv_type = cd_read_reg_sc(sc, cy_chip, CD1400_RIVR);
1078 			cy = &sc->sc_ports[serv_type >> 3];
1079 
1080 #ifdef CY_DEBUG1
1081 			cy->cy_rx_int_count++;
1082 #endif
1083 
1084 			buf_p = cy->cy_ibuf_wr_ptr;
1085 
1086 			if (ISSET(serv_type, CD1400_RIVR_EXCEPTION)) {
1087 				line_stat = cd_read_reg(cy, CD1400_RDSR);
1088 				recv_data = cd_read_reg(cy, CD1400_RDSR);
1089 
1090 				if (cy->cy_tty == NULL ||
1091 				    !ISSET(cy->cy_tty->t_state, TS_ISOPEN))
1092 					goto end_rx_serv;
1093 
1094 #ifdef CY_DEBUG
1095 				printf("%s port %d recv exception, "
1096 				    "line_stat 0x%x, char 0x%x\n",
1097 				    sc->sc_dev.dv_xname, cy->cy_port_num,
1098 				    line_stat, recv_data);
1099 #endif
1100 				if (ISSET(line_stat, CD1400_RDSR_OE))
1101 					cy->cy_fifo_overruns++;
1102 
1103 				*buf_p++ = line_stat;
1104 				*buf_p++ = recv_data;
1105 				if (buf_p == cy->cy_ibuf_end)
1106 					buf_p = cy->cy_ibuf;
1107 
1108 				if (buf_p == cy->cy_ibuf_rd_ptr) {
1109 					if (buf_p == cy->cy_ibuf)
1110 						buf_p = cy->cy_ibuf_end;
1111 					buf_p -= 2;
1112 					cy->cy_ibuf_overruns++;
1113 				}
1114 				sc->sc_events = 1;
1115 			} else { /* no exception, received data OK */
1116 				n_chars = cd_read_reg(cy, CD1400_RDCR);
1117 
1118 				/* If no tty or not open, discard data */
1119 				if (cy->cy_tty == NULL ||
1120 				    !ISSET(cy->cy_tty->t_state, TS_ISOPEN)) {
1121 					while (n_chars--)
1122 						cd_read_reg(cy, CD1400_RDSR);
1123 					goto end_rx_serv;
1124 				}
1125 
1126 #ifdef CY_DEBUG
1127 				printf("%s port %d receive ok %d chars\n",
1128 				    sc->sc_dev.dv_xname, cy->cy_port_num,
1129 				    n_chars);
1130 #endif
1131 				while (n_chars--) {
1132 					*buf_p++ = 0; /* status: OK */
1133 					*buf_p++ = cd_read_reg(cy,
1134 					    CD1400_RDSR); /* data byte */
1135 					if (buf_p == cy->cy_ibuf_end)
1136 						buf_p = cy->cy_ibuf;
1137 					if (buf_p == cy->cy_ibuf_rd_ptr) {
1138 						if (buf_p == cy->cy_ibuf)
1139 							buf_p = cy->cy_ibuf_end;
1140 						buf_p -= 2;
1141 						cy->cy_ibuf_overruns++;
1142 						break;
1143 					}
1144 				}
1145 				sc->sc_events = 1;
1146 			}
1147 
1148 			cy->cy_ibuf_wr_ptr = buf_p;
1149 
1150 #ifndef CY_HW_RTS
1151 			/* RTS handshaking for incoming data */
1152 			if (ISSET(cy->cy_tty->t_cflag, CRTSCTS)) {
1153 				int bf;
1154 
1155 				bf = buf_p - cy->cy_ibuf_rd_ptr;
1156 				if (bf < 0)
1157 					bf += IBUF_SIZE;
1158 
1159 				if (bf > (IBUF_SIZE/2))	/* turn RTS off */
1160 					cd_write_reg(cy, CD1400_MSVR1, 0);
1161 			}
1162 #endif /* CY_HW_RTS */
1163 
1164 		end_rx_serv:
1165 			/* terminate service context */
1166 			cd_write_reg(cy, CD1400_RIR, save_rir & 0x3f);
1167 			cd_write_reg(cy, CD1400_CAR, save_car);
1168 			int_serviced = 1;
1169 		} /* if(rx_service...) */
1170 
1171 		if (ISSET(stat, CD1400_SVRR_MDMCH)) {
1172 			u_char save_car, save_mir, serv_type, modem_stat;
1173 
1174 			save_mir = cd_read_reg_sc(sc, cy_chip, CD1400_MIR);
1175 			save_car = cd_read_reg_sc(sc, cy_chip, CD1400_CAR);
1176 			/* enter modem service */
1177 			cd_write_reg_sc(sc, cy_chip, CD1400_CAR, save_mir);
1178 
1179 			serv_type = cd_read_reg_sc(sc, cy_chip, CD1400_MIVR);
1180 			cy = &sc->sc_ports[serv_type >> 3];
1181 
1182 #ifdef CY_DEBUG1
1183 			cy->cy_modem_int_count++;
1184 #endif
1185 
1186 			modem_stat = cd_read_reg(cy, CD1400_MSVR2);
1187 
1188 #ifdef CY_DEBUG
1189 			printf("%s port %d modem line change, new stat 0x%x\n",
1190 			    sc->sc_dev.dv_xname, cy->cy_port_num, modem_stat);
1191 #endif
1192 			if (ISSET((cy->cy_carrier_stat ^ modem_stat),
1193 			    CD1400_MSVR2_CD)) {
1194 				SET(cy->cy_flags, CYF_CARRIER_CHANGED);
1195 				sc->sc_events = 1;
1196 			}
1197 
1198 			cy->cy_carrier_stat = modem_stat;
1199 
1200 			/* terminate service context */
1201 			cd_write_reg(cy, CD1400_MIR, save_mir & 0x3f);
1202 			cd_write_reg(cy, CD1400_CAR, save_car);
1203 			int_serviced = 1;
1204 		} /* if(modem_service...) */
1205 
1206 		if (ISSET(stat, CD1400_SVRR_TXRDY)) {
1207 			u_char save_car, save_tir, serv_type, count, ch;
1208 			struct tty *tp;
1209 
1210 			save_tir = cd_read_reg_sc(sc, cy_chip, CD1400_TIR);
1211 			save_car = cd_read_reg_sc(sc, cy_chip, CD1400_CAR);
1212 			/* enter tx service */
1213 			cd_write_reg_sc(sc, cy_chip, CD1400_CAR, save_tir);
1214 
1215 			serv_type = cd_read_reg_sc(sc, cy_chip, CD1400_TIVR);
1216 			cy = &sc->sc_ports[serv_type >> 3];
1217 
1218 #ifdef CY_DEBUG1
1219 			cy->cy_tx_int_count++;
1220 #endif
1221 #ifdef CY_DEBUG
1222 			printf("%s port %d tx service\n", sc->sc_dev.dv_xname,
1223 			    cy->cy_port_num);
1224 #endif
1225 
1226 			/* stop transmitting if no tty or CYF_STOP set */
1227 			tp = cy->cy_tty;
1228 			if (tp == NULL || ISSET(cy->cy_flags, CYF_STOP))
1229 				goto txdone;
1230 
1231 			count = 0;
1232 			if (ISSET(cy->cy_flags, CYF_SEND_NUL)) {
1233 				cd_write_reg(cy, CD1400_TDR, 0);
1234 				cd_write_reg(cy, CD1400_TDR, 0);
1235 				count += 2;
1236 				CLR(cy->cy_flags, CYF_SEND_NUL);
1237 			}
1238 
1239 			if (tp->t_outq.c_cc > 0) {
1240 				SET(tp->t_state, TS_BUSY);
1241 				while (tp->t_outq.c_cc > 0 &&
1242 				    count < CD1400_TX_FIFO_SIZE) {
1243 					ch = getc(&tp->t_outq);
1244 					/* remember to double NUL characters
1245 					   because embedded transmit commands
1246 					   are enabled */
1247 					if (ch == 0) {
1248 						if (count >=
1249 						    CD1400_TX_FIFO_SIZE-2) {
1250 							SET(cy->cy_flags,
1251 							    CYF_SEND_NUL);
1252 							break;
1253 						}
1254 
1255 						cd_write_reg(cy, CD1400_TDR, ch);
1256 						count++;
1257 					}
1258 
1259 					cd_write_reg(cy, CD1400_TDR, ch);
1260 					count++;
1261 				}
1262 			} else {
1263 				/* no data to send -- check if we should
1264 				   start/stop a break */
1265 				/* XXX does this cause too much delay before
1266 				   breaks? */
1267 				if (ISSET(cy->cy_flags, CYF_START_BREAK)) {
1268 					cd_write_reg(cy, CD1400_TDR, 0);
1269 					cd_write_reg(cy, CD1400_TDR, 0x81);
1270 					CLR(cy->cy_flags, CYF_START_BREAK);
1271 				}
1272 				if (ISSET(cy->cy_flags, CYF_END_BREAK)) {
1273 					cd_write_reg(cy, CD1400_TDR, 0);
1274 					cd_write_reg(cy, CD1400_TDR, 0x83);
1275 					CLR(cy->cy_flags, CYF_END_BREAK);
1276 				}
1277 			}
1278 
1279 			if (tp->t_outq.c_cc == 0) {
1280 txdone:
1281 				/*
1282 				 * No data to send or requested to stop.
1283 				 * Disable transmit interrupt
1284 				 */
1285 				cd_write_reg(cy, CD1400_SRER,
1286 				    cd_read_reg(cy, CD1400_SRER)
1287 				    & ~CD1400_SRER_TXRDY);
1288 				CLR(cy->cy_flags, CYF_STOP);
1289 				CLR(tp->t_state, TS_BUSY);
1290 			}
1291 
1292 			if (tp->t_outq.c_cc <= tp->t_lowat) {
1293 				SET(cy->cy_flags, CYF_START);
1294 				sc->sc_events = 1;
1295 			}
1296 
1297 			/* terminate service context */
1298 			cd_write_reg(cy, CD1400_TIR, save_tir & 0x3f);
1299 			cd_write_reg(cy, CD1400_CAR, save_car);
1300 			int_serviced = 1;
1301 		} /* if(tx_service...) */
1302 	} /* for(...all CD1400s on a card) */
1303 
1304 	/* ensure an edge for next interrupt */
1305 	bus_space_write_1(sc->sc_memt, sc->sc_memh,
1306 	    CY_CLEAR_INTR<<sc->sc_bustype, 0);
1307 	return (int_serviced);
1308 }
1309 
1310 /*
1311  * subroutine to enable CD1400 transmitter
1312  */
1313 void
cy_enable_transmitter(struct cy_port * cy)1314 cy_enable_transmitter(struct cy_port *cy)
1315 {
1316 	int s;
1317 	s = spltty();
1318 	cd_write_reg(cy, CD1400_CAR, cy->cy_port_num & CD1400_CAR_CHAN);
1319 	cd_write_reg(cy, CD1400_SRER, cd_read_reg(cy, CD1400_SRER)
1320 	    | CD1400_SRER_TXRDY);
1321 	splx(s);
1322 }
1323 
1324 /*
1325  * Execute a CD1400 channel command
1326  */
1327 void
cd1400_channel_cmd(struct cy_port * cy,int cmd)1328 cd1400_channel_cmd(struct cy_port *cy, int cmd)
1329 {
1330 	u_int waitcnt = 5 * 8 * 1024; /* approx 5 ms */
1331 
1332 #ifdef CY_DEBUG
1333 	printf("c1400_channel_cmd cy %p command 0x%x\n", cy, cmd);
1334 #endif
1335 
1336 	/* wait until cd1400 is ready to process a new command */
1337 	while (cd_read_reg(cy, CD1400_CCR) != 0 && waitcnt-- > 0)
1338 		;
1339 
1340 	if (waitcnt == 0)
1341 		log(LOG_ERR, "cy: channel command timeout\n");
1342 
1343 	cd_write_reg(cy, CD1400_CCR, cmd);
1344 }
1345 
1346 /*
1347  * Compute clock option register and baud rate register values
1348  * for a given speed. Return 0 on success, -1 on failure.
1349  *
1350  * The error between requested and actual speed seems
1351  * to be well within allowed limits (less than 3%)
1352  * with every speed value between 50 and 150000 bps.
1353  */
1354 int
cy_speed(speed_t speed,int * cor,int * bpr,int cy_clock)1355 cy_speed(speed_t speed, int *cor, int *bpr, int cy_clock)
1356 {
1357 	int c, co, br;
1358 
1359 	if (speed < 50 || speed > 150000)
1360 		return (-1);
1361 
1362 	for (c = 0, co = 8; co <= 2048; co <<= 2, c++) {
1363 		br = (cy_clock + (co * speed) / 2) / (co * speed);
1364 		if (br < 0x100) {
1365 			*bpr = br;
1366 			*cor = c;
1367 			return (0);
1368 		}
1369 	}
1370 
1371 	return (-1);
1372 }
1373