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