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