FreeBSD/Linux Kernel Cross Reference
sys/dev/sx/sx.c
1 /*-
2 * Device tsfsdriver for Specialix I/O8+ multiport serial card.
3 *
4 * Copyright 2003 Frank Mayhar <frank@exit.com>
5 *
6 * Derived from the "si" driver by Peter Wemm <peter@netplex.com.au>, using
7 * lots of information from the Linux "specialix" driver by Roger Wolff
8 * <R.E.Wolff@BitWizard.nl> and from the Intel CD1865 "Intelligent Eight-
9 * Channel Communications Controller" datasheet. Roger was also nice
10 * enough to answer numerous questions about stuff specific to the I/O8+
11 * not covered by the CD1865 datasheet.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notices, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notices, this list of conditions and the foljxowing disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE.
26 *
27 * $FreeBSD$
28 */
29
30
31 /* Main tty driver routines for the Specialix I/O8+ device driver. */
32
33 #include "opt_compat.h"
34 #include "opt_debug_sx.h"
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #ifndef BURN_BRIDGES
39 #if defined(COMPAT_43)
40 #include <sys/ioctl_compat.h>
41 #endif
42 #endif
43 #include <sys/tty.h>
44 #include <sys/proc.h>
45 #include <sys/conf.h>
46 #include <sys/fcntl.h>
47 #include <sys/dkstat.h>
48 #include <sys/kernel.h>
49 #include <sys/malloc.h>
50 #include <sys/sysctl.h>
51 #include <sys/bus.h>
52 #include <machine/bus.h>
53 #include <sys/rman.h>
54 #include <machine/resource.h>
55
56 #include <machine/clock.h>
57
58 #include <vm/vm.h>
59 #include <vm/pmap.h>
60
61 #include <machine/stdarg.h>
62
63 #include <dev/sx/cd1865.h>
64 #include <dev/sx/sxvar.h>
65 #include <dev/sx/sx.h>
66 #include <dev/sx/sx_util.h>
67
68 #define SX_BROKEN_CTS
69
70 enum sx_mctl { GET, SET, BIS, BIC };
71
72 static int sx_modem(struct sx_softc *, struct sx_port *, enum sx_mctl, int);
73 static void sx_write_enable(struct sx_port *, int);
74 static void sx_start(struct tty *);
75 static void sx_stop(struct tty *, int);
76 static void sxhardclose(struct sx_port *pp);
77 static void sxdtrwakeup(void *chan);
78 static void sx_shutdown_chan(struct sx_port *);
79
80 #ifdef SX_DEBUG
81 static char *sx_mctl2str(enum sx_mctl cmd);
82 #endif
83
84 static int sxparam(struct tty *, struct termios *);
85
86 static void sx_modem_state(struct sx_softc *sc, struct sx_port *pp, int card);
87
88 static d_open_t sxopen;
89 static d_close_t sxclose;
90 static d_write_t sxwrite;
91 static d_ioctl_t sxioctl;
92
93 #define CDEV_MAJOR 185
94 static struct cdevsw sx_cdevsw = {
95 .d_version = D_VERSION,
96 .d_open = sxopen,
97 .d_close = sxclose,
98 .d_write = sxwrite,
99 .d_ioctl = sxioctl,
100 .d_name = "sx",
101 .d_flags = D_TTY | D_NEEDGIANT,
102 };
103
104 static int sx_debug = 0; /* DBG_ALL|DBG_PRINTF|DBG_MODEM|DBG_IOCTL|DBG_PARAM;e */
105 SYSCTL_INT(_machdep, OID_AUTO, sx_debug, CTLFLAG_RW, &sx_debug, 0, "");
106
107 static struct tty *sx__tty;
108
109 static int sx_numunits;
110
111 devclass_t sx_devclass;
112
113 /*
114 * See sx.h for these values.
115 */
116 static struct speedtab bdrates[] = {
117 { B75, CLK75, },
118 { B110, CLK110, },
119 { B150, CLK150, },
120 { B300, CLK300, },
121 { B600, CLK600, },
122 { B1200, CLK1200, },
123 { B2400, CLK2400, },
124 { B4800, CLK4800, },
125 { B9600, CLK9600, },
126 { B19200, CLK19200, },
127 { B38400, CLK38400, },
128 { B57600, CLK57600, },
129 { B115200, CLK115200, },
130 { -1, -1 },
131 };
132
133
134 /*
135 * Approximate (rounded) character per second rates. Translated at card
136 * initialization time to characters per clock tick.
137 */
138 static int done_chartimes = 0;
139 static struct speedtab chartimes[] = {
140 { B75, 8, },
141 { B110, 11, },
142 { B150, 15, },
143 { B300, 30, },
144 { B600, 60, },
145 { B1200, 120, },
146 { B2400, 240, },
147 { B4800, 480, },
148 { B9600, 960, },
149 { B19200, 1920, },
150 { B38400, 3840, },
151 { B57600, 5760, },
152 { B115200, 11520, },
153 { -1, -1 },
154 };
155 static volatile int in_interrupt = 0; /* Inside interrupt handler? */
156
157 static int sx_flags; /* The flags we were configured with. */
158 SYSCTL_INT(_machdep, OID_AUTO, sx_flags, CTLFLAG_RW, &sx_flags, 0, "");
159
160 #ifdef POLL
161 static int sx_pollrate; /* in addition to irq */
162 static int sx_realpoll = 0; /* poll HW on timer */
163
164 SYSCTL_INT(_machdep, OID_AUTO, sx_pollrate, CTLFLAG_RW, &sx_pollrate, 0, "");
165 SYSCTL_INT(_machdep, OID_AUTO, sx_realpoll, CTLFLAG_RW, &sx_realpoll, 0, "");
166
167 static int init_finished = 0;
168 static void sx_poll(void *);
169 #endif
170
171 /*
172 * sxattach()
173 * Initialize and attach the card, initialize the driver.
174 *
175 * Description:
176 * This is the standard attach routine. It initializes the I/O8+
177 * card, identifies the chip on that card, then allocates and
178 * initializes the various data structures used by the driver
179 * itself.
180 */
181 int
182 sxattach(
183 device_t dev)
184 {
185 int unit;
186 struct sx_softc *sc;
187 struct tty *tp;
188 struct speedtab *spt;
189 int chip, x, y;
190 char rev;
191 int error;
192
193 sc = device_get_softc(dev);
194 unit = device_get_unit(dev);
195 sx_flags = device_get_flags(dev);
196
197 if (sx_numunits < unit + 1)
198 sx_numunits = unit + 1;
199
200 DPRINT((0, DBG_AUTOBOOT, "sx%d: sxattach\n", unit));
201
202 /* Reset the CD1865. */
203 if ((error = sx_init_cd1865(sc, unit)) != 0) {
204 return(error);
205 }
206
207 /*
208 * ID the chip:
209 *
210 * Chip revcode pkgtype
211 * GFRCR SRCR bit 7
212 * CD180 rev B 0x81 0
213 * CD180 rev C 0x82 0
214 * CD1864 rev A 0x82 1
215 * CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
216 * CD1865 rev B 0x84 1
217 * -- Thanks to Gwen Wang, Cirrus Logic (via Roger Wollf).
218 */
219 switch (sx_cd1865_in(sc, CD1865_GFRCR)) {
220 case 0x82:
221 chip = 1864;
222 rev = 'A';
223 break;
224 case 0x83:
225 chip = 1865;
226 rev = 'A';
227 break;
228 case 0x84:
229 chip = 1865;
230 rev = 'B';
231 break;
232 case 0x85:
233 chip = 1865;
234 rev = 'C';
235 break;
236 default:
237 chip = -1;
238 rev = '\0';
239 break;
240 }
241
242 if (bootverbose && chip != -1)
243 printf("sx%d: Specialix I/O8+ CD%d processor rev %c\n",
244 unit, chip, rev);
245 DPRINT((0, DBG_AUTOBOOT, "sx%d: GFRCR 0x%02x\n",
246 unit, sx_cd1865_in(sc, CD1865_GFRCR)));
247 #ifdef POLL
248 if (sx_pollrate == 0) {
249 sx_pollrate = POLLHZ; /* in addition to irq */
250 #ifdef REALPOLL
251 sx_realpoll = 1; /* scan always */
252 #endif
253 }
254 #endif
255 sc->sc_ports = (struct sx_port *)malloc(
256 sizeof(struct sx_port) * SX_NUMCHANS,
257 M_DEVBUF,
258 M_NOWAIT);
259 if (sc->sc_ports == NULL) {
260 printf("sx%d: No memory for sx_port structs!\n", unit);
261 return(EINVAL);
262 }
263 bzero(sc->sc_ports, sizeof(struct sx_port) * SX_NUMCHANS);
264 /*
265 * Allocate tty structures for the channels.
266 */
267 tp = (struct tty *)malloc(sizeof(struct tty) * SX_NUMCHANS,
268 M_DEVBUF,
269 M_NOWAIT);
270 if (tp == NULL) {
271 free(sc->sc_ports, M_DEVBUF);
272 printf("sx%d: No memory for tty structs!\n", unit);
273 return(EINVAL);
274 }
275 bzero(tp, sizeof(struct tty) * SX_NUMCHANS);
276 sx__tty = tp;
277 /*
278 * Initialize the channels.
279 */
280 for (x = 0; x < SX_NUMCHANS; x++) {
281 sc->sc_ports[x].sp_chan = x;
282 sc->sc_ports[x].sp_tty = tp++;
283 sc->sc_ports[x].sp_state = 0; /* internal flag */
284 sc->sc_ports[x].sp_iin.c_iflag = TTYDEF_IFLAG;
285 sc->sc_ports[x].sp_iin.c_oflag = TTYDEF_OFLAG;
286 sc->sc_ports[x].sp_iin.c_cflag = TTYDEF_CFLAG;
287 sc->sc_ports[x].sp_iin.c_lflag = TTYDEF_LFLAG;
288 termioschars(&sc->sc_ports[x].sp_iin);
289 sc->sc_ports[x].sp_iin.c_ispeed = TTYDEF_SPEED;;
290 sc->sc_ports[x].sp_iin.c_ospeed = TTYDEF_SPEED;;
291 sc->sc_ports[x].sp_iout = sc->sc_ports[x].sp_iin;
292 }
293 if (done_chartimes == 0) {
294 for (spt = chartimes ; spt->sp_speed != -1; spt++) {
295 if ((spt->sp_code /= hz) == 0)
296 spt->sp_code = 1;
297 }
298 done_chartimes = 1;
299 }
300 /*
301 * Set up the known devices.
302 */
303 y = unit * (1 << SX_CARDSHIFT);
304 for (x = 0; x < SX_NUMCHANS; x++) {
305 register int num;
306
307 /* DTR/RTS -> RTS devices. */
308 num = x + y;
309 make_dev(&sx_cdevsw, x, 0, 0, 0600, "ttyG%02d", x+y);
310 make_dev(&sx_cdevsw, x + 0x00080, 0, 0, 0600, "cuaG%02d", num);
311 make_dev(&sx_cdevsw, x + 0x10000, 0, 0, 0600, "ttyiG%02d", num);
312 make_dev(&sx_cdevsw, x + 0x10080, 0, 0, 0600, "cuaiG%02d", num);
313 make_dev(&sx_cdevsw, x + 0x20000, 0, 0, 0600, "ttylG%02d", num);
314 make_dev(&sx_cdevsw, x + 0x20080, 0, 0, 0600, "cualG%02d", num);
315 /* DTR/RTS -> DTR devices. */
316 num += SX_NUMCHANS;
317 make_dev(&sx_cdevsw, x + 0x00008, 0, 0, 0600, "ttyG%02d", num);
318 make_dev(&sx_cdevsw, x + 0x00088, 0, 0, 0600, "cuaG%02d", num);
319 make_dev(&sx_cdevsw, x + 0x10008, 0, 0, 0600, "ttyiG%02d", num);
320 make_dev(&sx_cdevsw, x + 0x10088, 0, 0, 0600, "cuaiG%02d", num);
321 make_dev(&sx_cdevsw, x + 0x20008, 0, 0, 0600, "ttylG%02d", num);
322 make_dev(&sx_cdevsw, x + 0x20088, 0, 0, 0600, "cualG%02d", num);
323 }
324 return (0);
325 }
326
327 /*
328 * sxopen()
329 * Open a port on behalf of a user.
330 *
331 * Description:
332 * This is the standard open routine.
333 */
334 static int
335 sxopen(
336 struct cdev *dev,
337 int flag,
338 int mode,
339 d_thread_t *p)
340 {
341 int oldspl, error;
342 int card, chan;
343 struct sx_softc *sc;
344 struct tty *tp;
345 struct sx_port *pp;
346 int mynor = minor(dev);
347
348 card = SX_MINOR2CARD(mynor);
349 if ((sc = devclass_get_softc(sx_devclass, card)) == NULL)
350 return (ENXIO);
351 chan = SX_MINOR2CHAN(mynor);
352 if (chan >= SX_NUMCHANS) {
353 DPRINT((0, DBG_OPEN|DBG_FAIL, "sx%d: nchans %d\n",
354 card, SX_NUMCHANS));
355 return(ENXIO);
356 }
357 #ifdef POLL
358 /*
359 * We've now got a device, so start the poller.
360 */
361 if (init_finished == 0) {
362 timeout(sx_poll, (caddr_t)0L, sx_pollrate);
363 init_finished = 1;
364 }
365 #endif
366 /* initial/lock device */
367 if (DEV_IS_STATE(mynor)) {
368 return(0);
369 }
370 pp = &(sc->sc_ports[chan]);
371 tp = pp->sp_tty; /* the "real" tty */
372 dev->si_tty = tp;
373 DPRINT((pp, DBG_ENTRY|DBG_OPEN, "sxopen(%s,%x,%x,%x)\n",
374 devtoname(dev), flag, mode, p));
375
376 oldspl = spltty(); /* Keep others out */
377 error = 0;
378 /*
379 * The minor also indicates whether the DTR pin on this port is wired
380 * as DTR or as RTS. Default is zero, wired as RTS.
381 */
382 if (DEV_DTRPIN(mynor))
383 pp->sp_state |= SX_SS_DTRPIN;
384 else
385 pp->sp_state &= ~SX_SS_DTRPIN;
386 pp->sp_state &= SX_SS_XMIT; /* Turn off "transmitting" flag. */
387 open_top:
388 /*
389 * If DTR is off and we actually do have a DTR pin, sleep waiting for
390 * it to assert.
391 */
392 while (pp->sp_state & SX_SS_DTR_OFF && SX_DTRPIN(pp)) {
393 error = tsleep(&tp->t_dtr_wait, TTIPRI|PCATCH, "sxdtr", 0);
394 if (error != 0)
395 goto out;
396 }
397
398 if (tp->t_state & TS_ISOPEN) {
399 /*
400 * The device is open, so everything has been initialized.
401 * Handle conflicts.
402 */
403 if (DEV_IS_CALLOUT(mynor)) {
404 if (!pp->sp_active_out) {
405 error = EBUSY;
406 goto out;
407 }
408 }
409 else {
410 if (pp->sp_active_out) {
411 if (flag & O_NONBLOCK) {
412 error = EBUSY;
413 goto out;
414 }
415 error = tsleep(&pp->sp_active_out,
416 TTIPRI|PCATCH,
417 "sxbi", 0);
418 if (error != 0)
419 goto out;
420 goto open_top;
421 }
422 }
423 if (tp->t_state & TS_XCLUDE && suser(p)) {
424 DPRINT((pp, DBG_OPEN|DBG_FAIL,
425 "already open and EXCLUSIVE set\n"));
426 error = EBUSY;
427 goto out;
428 }
429 } else {
430 /*
431 * The device isn't open, so there are no conflicts.
432 * Initialize it. Avoid sleep... :-)
433 */
434 DPRINT((pp, DBG_OPEN, "first open\n"));
435 tp->t_oproc = sx_start;
436 tp->t_stop = sx_stop;
437 tp->t_param = sxparam;
438 tp->t_dev = dev;
439 tp->t_termios = mynor & SX_CALLOUT_MASK
440 ? pp->sp_iout : pp->sp_iin;
441
442 (void)sx_modem(sc, pp, SET, TIOCM_DTR|TIOCM_RTS);
443
444 ++pp->sp_wopeners; /* in case of sleep in sxparam */
445
446 error = sxparam(tp, &tp->t_termios);
447
448 --pp->sp_wopeners;
449 if (error != 0)
450 goto out;
451 /* XXX: we should goto_top if sxparam slept */
452
453 /* set initial DCD state */
454 if (DEV_IS_CALLOUT(mynor) ||
455 (sx_modem(sc, pp, GET, 0) & TIOCM_CD)) {
456 ttyld_modem(tp, 1);
457 }
458 }
459 /* whoops! we beat the close! */
460 if (pp->sp_state & SX_SS_CLOSING) {
461 /* try and stop it from proceeding to bash the hardware */
462 pp->sp_state &= ~SX_SS_CLOSING;
463 }
464 /*
465 * Wait for DCD if necessary
466 */
467 if (!(tp->t_state & TS_CARR_ON) && !DEV_IS_CALLOUT(mynor) &&
468 !(tp->t_cflag & CLOCAL) && !(flag & O_NONBLOCK)) {
469 ++pp->sp_wopeners;
470 DPRINT((pp, DBG_OPEN, "sleeping for carrier\n"));
471 error = tsleep(TSA_CARR_ON(tp), TTIPRI|PCATCH, "sxdcd", 0);
472 --pp->sp_wopeners;
473 if (error != 0)
474 goto out;
475 goto open_top;
476 }
477
478 error = ttyld_open(tp, dev);
479 ttyldoptim(tp);
480 if (tp->t_state & TS_ISOPEN && DEV_IS_CALLOUT(mynor))
481 pp->sp_active_out = TRUE;
482
483 pp->sp_state |= SX_SS_OPEN; /* made it! */
484
485 out:
486 splx(oldspl);
487
488 DPRINT((pp, DBG_OPEN, "leaving sxopen\n"));
489
490 if (!(tp->t_state & TS_ISOPEN) && pp->sp_wopeners == 0)
491 sxhardclose(pp);
492
493 return(error);
494 }
495
496 /*
497 * sxclose()
498 * Close a port for a user.
499 *
500 * Description:
501 * This is the standard close routine.
502 */
503 static int
504 sxclose(
505 struct cdev *dev,
506 int flag,
507 int mode,
508 d_thread_t *p)
509 {
510 struct sx_port *pp;
511 struct tty *tp;
512 int oldspl;
513 int error = 0;
514 int mynor = minor(dev);
515
516 if (DEV_IS_SPECIAL(mynor))
517 return(0);
518
519 oldspl = spltty();
520
521 pp = MINOR2PP(mynor);
522 tp = pp->sp_tty;
523
524 DPRINT((pp, DBG_ENTRY|DBG_CLOSE, "sxclose(%s,%x,%x,%x) sp_state:%x\n",
525 devtoname(dev), flag, mode, p, pp->sp_state));
526
527 /* did we sleep and lose a race? */
528 if (pp->sp_state & SX_SS_CLOSING) {
529 /* error = ESOMETING? */
530 goto out;
531 }
532
533 /* begin race detection.. */
534 pp->sp_state |= SX_SS_CLOSING;
535
536 sx_write_enable(pp, 0); /* block writes for ttywait() */
537
538 /* THIS MAY SLEEP IN TTYWAIT!!! */
539 ttyld_close(tp, flag);
540
541 sx_write_enable(pp, 1);
542
543 /* did we sleep and somebody started another open? */
544 if (!(pp->sp_state & SX_SS_CLOSING)) {
545 /* error = ESOMETING? */
546 goto out;
547 }
548 /* ok. we are now still on the right track.. nuke the hardware */
549
550 sxhardclose(pp);
551 tty_close(tp);
552 pp->sp_state &= ~SX_SS_OPEN;
553
554 out:
555 DPRINT((pp, DBG_CLOSE|DBG_EXIT, "sxclose out\n"));
556 splx(oldspl);
557 return(error);
558 }
559
560 /*
561 * sxhardclose()
562 * Do hard-close processing.
563 *
564 * Description:
565 * Called on last close. Handle DTR and RTS, do cleanup. If we have
566 * pending output in the FIFO, wait for it to clear before we shut down
567 * the hardware.
568 */
569 static void
570 sxhardclose(
571 struct sx_port *pp)
572 {
573 struct sx_softc *sc;
574 struct tty *tp;
575 int oldspl, dcd;
576
577 oldspl = spltty();
578
579 DPRINT((pp, DBG_CLOSE, "sxhardclose sp_state:%x\n", pp->sp_state));
580 tp = pp->sp_tty;
581 sc = PP2SC(pp);
582 dcd = sx_modem(sc, pp, GET, 0) & TIOCM_CD;
583 if (tp->t_cflag & HUPCL ||
584 (!pp->sp_active_out && !dcd && !(pp->sp_iin.c_cflag && CLOCAL)) ||
585 !(tp->t_state & TS_ISOPEN)) {
586 disable_intr();
587 sx_cd1865_out(sc, CD1865_CAR, pp->sp_chan);
588 if (sx_cd1865_in(sc, CD1865_IER|SX_EI) & CD1865_IER_TXRDY) {
589 sx_cd1865_bic(sc, CD1865_IER, CD1865_IER_TXRDY);
590 sx_cd1865_bis(sc, CD1865_IER, CD1865_IER_TXEMPTY);
591 enable_intr();
592 splx(oldspl);
593 ttysleep(tp, (caddr_t)pp,
594 TTOPRI|PCATCH, "sxclose", tp->t_timeout);
595 oldspl = spltty();
596 }
597 else {
598 enable_intr();
599 }
600 (void)sx_modem(sc, pp, BIC, TIOCM_DTR|TIOCM_RTS);
601 /*
602 * If we should hold DTR off for a bit and we actually have a
603 * DTR pin to hold down, schedule sxdtrwakeup().
604 */
605 if (tp->t_dtr_wait != 0 && SX_DTRPIN(pp)) {
606 timeout(sxdtrwakeup, pp, tp->t_dtr_wait);
607 pp->sp_state |= SX_SS_DTR_OFF;
608 }
609
610 }
611 (void)sx_shutdown_chan(pp); /* Turn off the hardware. */
612 pp->sp_active_out = FALSE;
613 wakeup((caddr_t)&pp->sp_active_out);
614 wakeup(TSA_CARR_ON(tp));
615
616 splx(oldspl);
617 }
618
619
620 /*
621 * called at splsoftclock()...
622 */
623 static void
624 sxdtrwakeup(void *chan)
625 {
626 struct sx_port *pp;
627 int oldspl;
628
629 oldspl = spltty();
630 pp = (struct sx_port *)chan;
631 pp->sp_state &= ~SX_SS_DTR_OFF;
632 wakeup(&pp->sp_tty->t_dtr_wait);
633 splx(oldspl);
634 }
635
636 /*
637 * sxwrite()
638 * Handle a write to a port on the I/O8+.
639 *
640 * Description:
641 * This just hands processing off to the line discipline.
642 */
643 static int
644 sxwrite(
645 struct cdev *dev,
646 struct uio *uio,
647 int flag)
648 {
649 struct sx_softc *sc;
650 struct sx_port *pp;
651 struct tty *tp;
652 int error = 0;
653 int mynor = minor(dev);
654 int oldspl;
655
656 pp = MINOR2PP(mynor);
657 sc = PP2SC(pp);
658 tp = pp->sp_tty;
659 DPRINT((pp, DBG_WRITE, "sxwrite %s %x %x\n", devtoname(dev), uio, flag));
660
661 oldspl = spltty();
662 /*
663 * If writes are currently blocked, wait on the "real" tty
664 */
665 while (pp->sp_state & SX_SS_BLOCKWRITE) {
666 pp->sp_state |= SX_SS_WAITWRITE;
667 DPRINT((pp, DBG_WRITE, "sxwrite sleep on SX_SS_BLOCKWRITE\n"));
668 if ((error = ttysleep(tp,
669 (caddr_t)pp,
670 TTOPRI|PCATCH,
671 "sxwrite",
672 tp->t_timeout))) {
673 if (error == EWOULDBLOCK)
674 error = EIO;
675 goto out;
676 }
677 }
678 error = ttyld_write(tp, uio, flag);
679 out: splx(oldspl);
680 DPRINT((pp, DBG_WRITE, "sxwrite out\n"));
681 return (error);
682 }
683
684 /*
685 * sxioctl()
686 * Handle ioctl() processing.
687 *
688 * Description:
689 * This is the standard serial ioctl() routine. It was cribbed almost
690 * entirely from the si(4) driver. Thanks, Peter.
691 */
692 static int
693 sxioctl(
694 struct cdev *dev,
695 u_long cmd,
696 caddr_t data,
697 int flag,
698 d_thread_t *p)
699 {
700 struct sx_softc *sc;
701 struct sx_port *pp;
702 struct tty *tp;
703 int error;
704 int mynor = minor(dev);
705 int oldspl;
706 int blocked = 0;
707 #ifndef BURN_BRIDGES
708 #if defined(COMPAT_43)
709 u_long oldcmd;
710
711 struct termios term;
712 #endif
713 #endif
714
715 pp = MINOR2PP(mynor);
716 tp = pp->sp_tty;
717
718 DPRINT((pp, DBG_ENTRY|DBG_IOCTL, "sxioctl %s %lx %x %x\n",
719 devtoname(dev), cmd, data, flag));
720 if (DEV_IS_STATE(mynor)) {
721 struct termios *ct;
722
723 switch (mynor & SX_STATE_MASK) {
724 case SX_INIT_STATE_MASK:
725 ct = DEV_IS_CALLOUT(mynor) ? &pp->sp_iout :
726 &pp->sp_iin;
727 break;
728 case SX_LOCK_STATE_MASK:
729 ct = DEV_IS_CALLOUT(mynor) ? &pp->sp_lout :
730 &pp->sp_lin;
731 break;
732 default:
733 return(ENODEV);
734 }
735 switch (cmd) {
736 case TIOCSETA:
737 error = suser(p);
738 if (error != 0)
739 return(error);
740 *ct = *(struct termios *)data;
741 return(0);
742 case TIOCGETA:
743 *(struct termios *)data = *ct;
744 return(0);
745 case TIOCGETD:
746 *(int *)data = TTYDISC;
747 return(0);
748 case TIOCGWINSZ:
749 bzero(data, sizeof(struct winsize));
750 return(0);
751 default:
752 return(ENOTTY);
753 }
754 }
755 /*
756 * Do the old-style ioctl compat routines...
757 */
758 #ifndef BURN_BRIDGES
759 #if defined(COMPAT_43)
760 term = tp->t_termios;
761 oldcmd = cmd;
762 error = ttsetcompat(tp, &cmd, data, &term);
763 if (error != 0)
764 return(error);
765 if (cmd != oldcmd)
766 data = (caddr_t)&term;
767 #endif
768 #endif
769 /*
770 * Do the initial / lock state business
771 */
772 if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {
773 int cc;
774 struct termios *dt = (struct termios *)data;
775 struct termios *lt = mynor & SX_CALLOUT_MASK
776 ? &pp->sp_lout : &pp->sp_lin;
777
778 dt->c_iflag = (tp->t_iflag & lt->c_iflag) |
779 (dt->c_iflag & ~lt->c_iflag);
780 dt->c_oflag = (tp->t_oflag & lt->c_oflag) |
781 (dt->c_oflag & ~lt->c_oflag);
782 dt->c_cflag = (tp->t_cflag & lt->c_cflag) |
783 (dt->c_cflag & ~lt->c_cflag);
784 dt->c_lflag = (tp->t_lflag & lt->c_lflag) |
785 (dt->c_lflag & ~lt->c_lflag);
786 for (cc = 0; cc < NCCS; ++cc)
787 if (lt->c_cc[cc] != 0)
788 dt->c_cc[cc] = tp->t_cc[cc];
789 if (lt->c_ispeed != 0)
790 dt->c_ispeed = tp->t_ispeed;
791 if (lt->c_ospeed != 0)
792 dt->c_ospeed = tp->t_ospeed;
793 }
794
795 /*
796 * Block user-level writes to give the ttywait()
797 * a chance to completely drain for commands
798 * that require the port to be in a quiescent state.
799 */
800 switch (cmd) {
801 case TIOCSETAW:
802 case TIOCSETAF:
803 case TIOCDRAIN:
804 #ifndef BURN_BRIDGES
805 #ifdef COMPAT_43
806 case TIOCSETP:
807 #endif
808 #endif
809 blocked++; /* block writes for ttywait() and sxparam() */
810 sx_write_enable(pp, 0);
811 }
812
813 error = ttyioctl(dev, cmd, data, flag, p);
814 ttyldoptim(tp);
815 if (error != ENOTTY)
816 goto out;
817
818 oldspl = spltty();
819
820 sc = PP2SC(pp); /* Need this to do I/O to the card. */
821 error = 0;
822 switch (cmd) {
823 case TIOCSBRK: /* Send BREAK. */
824 DPRINT((pp, DBG_IOCTL, "sxioctl %s BRK S\n",
825 devtoname(dev)));
826 /*
827 * If there's already a break state change pending or
828 * we're already sending a break, just ignore this.
829 * Otherwise, just set our flag and start the
830 * transmitter.
831 */
832 if (!SX_DOBRK(pp) && !SX_BREAK(pp)) {
833 pp->sp_state |= SX_SS_DOBRK;
834 sx_start(tp);
835 }
836 break;
837 case TIOCCBRK: /* Stop sending BREAK. */
838 DPRINT((pp, DBG_IOCTL, "sxioctl %s BRK E\n",
839 devtoname(dev)));
840 /*
841 * If a break is going, set our flag so we turn it off
842 * when we can, then kick the transmitter. If a break
843 * isn't going and the flag is set, turn it off.
844 */
845 if (SX_BREAK(pp)) {
846 pp->sp_state |= SX_SS_DOBRK;
847 sx_start(tp);
848 }
849 else {
850 if (SX_DOBRK(pp))
851 pp->sp_state &= SX_SS_DOBRK;
852 }
853 break;
854 case TIOCSDTR: /* Assert DTR. */
855 DPRINT((pp, DBG_IOCTL, "sxioctl %s +DTR\n",
856 devtoname(dev)));
857 if (SX_DTRPIN(pp)) /* Using DTR? */
858 (void)sx_modem(sc, pp, SET, TIOCM_DTR);
859 break;
860 case TIOCCDTR: /* Clear DTR. */
861 DPRINT((pp, DBG_IOCTL, "sxioctl(%s) -DTR\n",
862 devtoname(dev)));
863 if (SX_DTRPIN(pp)) /* Using DTR? */
864 (void)sx_modem(sc, pp, SET, 0);
865 break;
866 case TIOCMSET: /* Force all modem signals. */
867 DPRINT((pp, DBG_IOCTL, "sxioctl %s =%x\n",
868 devtoname(dev), *(int *)data));
869 (void)sx_modem(sc, pp, SET, *(int *)data);
870 break;
871 case TIOCMBIS: /* Set (some) modem signals. */
872 DPRINT((pp, DBG_IOCTL, "sxioctl %s +%x\n",
873 devtoname(dev), *(int *)data));
874 (void)sx_modem(sc, pp, BIS, *(int *)data);
875 break;
876 case TIOCMBIC: /* Clear (some) modem signals. */
877 DPRINT((pp, DBG_IOCTL, "sxioctl %s -%x\n",
878 devtoname(dev), *(int *)data));
879 (void)sx_modem(sc, pp, BIC, *(int *)data);
880 break;
881 case TIOCMGET: /* Get state of modem signals. */
882 *(int *)data = sx_modem(sc, pp, GET, 0);
883 DPRINT((pp, DBG_IOCTL, "sxioctl(%s) got signals 0x%x\n",
884 devtoname(dev), *(int *)data));
885 break;
886 default:
887 error = ENOTTY;
888 }
889 splx(oldspl);
890
891 out: DPRINT((pp, DBG_IOCTL|DBG_EXIT, "sxioctl out %d\n", error));
892 if (blocked)
893 sx_write_enable(pp, 1);
894 return(error);
895 }
896
897 /*
898 * sxparam()
899 * Configure line parameters.
900 *
901 * Description:
902 * Configure the bitrate, wordsize, flow control and various other serial
903 * port parameters for this line.
904 *
905 * Environment:
906 * Called at spltty(); this may sleep, does not flush nor wait for drain,
907 * nor block writes. Caller must arrange this if it's important..
908 */
909 static int
910 sxparam(
911 struct tty *tp,
912 struct termios *t)
913 {
914 struct sx_softc *sc;
915 struct sx_port *pp = TP2PP(tp);
916 int oldspl, cflag, iflag, oflag, lflag;
917 int error = 0;
918 int ispd = 0;
919 int ospd = 0;
920 unsigned char val, cor1, cor2, cor3, ier;
921
922 sc = PP2SC(pp);
923 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "sxparam %x/%x\n", tp, t));
924 cflag = t->c_cflag;
925 iflag = t->c_iflag;
926 oflag = t->c_oflag;
927 lflag = t->c_lflag;
928 DPRINT((pp, DBG_PARAM, "OF 0x%x CF 0x%x IF 0x%x LF 0x%x\n",
929 oflag, cflag, iflag, lflag));
930
931 /* If the port isn't hung up... */
932 if (t->c_ospeed != 0) {
933 /* Convert bit rate to hardware divisor values. */
934 ospd = ttspeedtab(t->c_ospeed, bdrates);
935 ispd = t->c_ispeed ? ttspeedtab(t->c_ispeed, bdrates) : ospd;
936 /* We only allow standard bit rates. */
937 if (ospd < 0 || ispd < 0)
938 return(EINVAL);
939 }
940 oldspl = spltty(); /* Block other activity. */
941 cor1 = 0;
942 cor2 = 0;
943 cor3 = 0;
944 ier = CD1865_IER_RXD | CD1865_IER_CD;
945 #ifdef notyet
946 /* We don't yet handle this stuff. */
947 val = 0;
948 if (iflag & IGNBRK) /* Breaks */
949 val |= BR_IGN;
950 if (iflag & BRKINT) /* Interrupt on break? */
951 val |= BR_INT;
952 if (iflag & PARMRK) /* Parity mark? */
953 val |= BR_PARMRK;
954 #endif /* notyet */
955 /*
956 * If the device isn't hung up, set the serial port bitrates.
957 */
958 if (t->c_ospeed != 0) {
959 disable_intr();
960 sx_cd1865_out(sc, CD1865_CAR|SX_EI, pp->sp_chan);
961 sx_cd1865_out(sc, CD1865_RBPRH|SX_EI, (ispd >> 8) & 0xff);
962 sx_cd1865_out(sc, CD1865_RBPRL|SX_EI, ispd & 0xff);
963 sx_cd1865_out(sc, CD1865_TBPRH|SX_EI, (ospd >> 8) & 0xff);
964 sx_cd1865_out(sc, CD1865_TBPRL|SX_EI, ospd & 0xff);
965 enable_intr();
966 }
967 if (cflag & CSTOPB) /* Two stop bits? */
968 cor1 |= CD1865_COR1_2SB; /* Yep. */
969 /*
970 * Parity settings.
971 */
972 val = 0;
973 if (cflag & PARENB) { /* Parity enabled? */
974 val = CD1865_COR1_NORMPAR; /* Turn on normal parity handling. */
975 if (cflag & PARODD) /* Odd Parity? */
976 val |= CD1865_COR1_ODDP; /* Turn it on. */
977 }
978 else
979 val = CD1865_COR1_NOPAR; /* Turn off parity detection. */
980 cor1 |= val;
981 if (iflag & IGNPAR) /* Ignore chars with parity errors? */
982 cor1 |= CD1865_COR1_IGNORE;
983 /*
984 * Set word length.
985 */
986 if ((cflag & CS8) == CS8)
987 val = CD1865_COR1_8BITS;
988 else if ((cflag & CS7) == CS7)
989 val = CD1865_COR1_7BITS;
990 else if ((cflag & CS6) == CS6)
991 val = CD1865_COR1_6BITS;
992 else
993 val = CD1865_COR1_5BITS;
994 cor1 |= val;
995 /*
996 * Enable hardware RTS/CTS flow control. We can handle output flow
997 * control at any time, since we have a dedicated CTS pin.
998 * Unfortunately, though, the RTS pin is really the DTR pin. This
999 * means that we can't ever use the automatic input flow control of
1000 * the CD1865 and that we can only use the pin for input flow
1001 * control when it's wired as RTS.
1002 */
1003 if (cflag & CCTS_OFLOW) { /* Output flow control... */
1004 pp->sp_state |= SX_SS_OFLOW;
1005 #ifdef SX_BROKEN_CTS
1006 disable_intr();
1007 sx_cd1865_out(sc, CD1865_CAR|SX_EI, pp->sp_chan);
1008 if (sx_cd1865_in(sc, CD1865_MSVR|SX_EI) & CD1865_MSVR_CTS) {
1009 enable_intr();
1010 pp->sp_state |= SX_SS_OSTOP;
1011 sx_write_enable(pp, 0); /* Block writes. */
1012 }
1013 else {
1014 enable_intr();
1015 }
1016 ier |= CD1865_IER_CTS;
1017 #else /* SX_BROKEN_CTS */
1018 cor2 |= CD1865_COR2_CTSAE; /* Set CTS automatic enable. */
1019 #endif /* SX_BROKEN_CTS */
1020 }
1021 else {
1022 pp->sp_state &= ~SX_SS_OFLOW;
1023 }
1024 if (cflag & CRTS_IFLOW && !SX_DTRPIN(pp)) /* Input flow control. */
1025 pp->sp_state |= SX_SS_IFLOW;
1026 else
1027 pp->sp_state &= ~SX_SS_IFLOW;
1028 if (iflag & IXANY)
1029 cor2 |= CD1865_COR2_IXM; /* Any character is XON. */
1030 if (iflag & IXOFF) {
1031 cor2 |= CD1865_COR2_TXIBE; /* Enable inband flow control.*/
1032 cor3 |= CD1865_COR3_FCT | CD1865_COR3_SCDE; /* Hide from host */
1033 disable_intr();
1034 sx_cd1865_out(sc, CD1865_CAR|SX_EI, pp->sp_chan); /* Sel chan.*/
1035 sx_cd1865_out(sc, CD1865_SCHR1|SX_EI, t->c_cc[VSTART]);
1036 sx_cd1865_out(sc, CD1865_SCHR2|SX_EI, t->c_cc[VSTOP]);
1037 sx_cd1865_out(sc, CD1865_SCHR3|SX_EI, t->c_cc[VSTART]);
1038 sx_cd1865_out(sc, CD1865_SCHR4|SX_EI, t->c_cc[VSTOP]);
1039 enable_intr();
1040 }
1041 /*
1042 * All set, now program the hardware.
1043 */
1044 disable_intr();
1045 sx_cd1865_out(sc, CD1865_CAR|SX_EI, pp->sp_chan); /* Select channel. */
1046 sx_cd1865_out(sc, CD1865_COR1|SX_EI, cor1);
1047 sx_cd1865_out(sc, CD1865_COR2|SX_EI, cor2);
1048 sx_cd1865_out(sc, CD1865_COR3|SX_EI, cor3);
1049 sx_cd1865_wait_CCR(sc, SX_EI);
1050 sx_cd1865_out(sc, CD1865_CCR|SX_EI,
1051 CD1865_CCR_CORCHG1|CD1865_CCR_CORCHG2|CD1865_CCR_CORCHG3);
1052 sx_cd1865_wait_CCR(sc, SX_EI);
1053 enable_intr();
1054 if (SX_DTRPIN(pp))
1055 val = TIOCM_DTR;
1056 else
1057 val = TIOCM_RTS;
1058 if (t->c_ospeed == 0) /* Clear DTR/RTS if we're hung up. */
1059 (void)sx_modem(sc, pp, BIC, val);
1060 else /* If we were hung up, we may have to */
1061 (void)sx_modem(sc, pp, BIS, val); /* re-enable the signal. */
1062 /*
1063 * Last, enable the receiver and transmitter and turn on the
1064 * interrupts we need (receive, carrier-detect and possibly CTS
1065 * (iff we're built with SX_BROKEN_CTS and CCTS_OFLOW is on).
1066 */
1067 disable_intr();
1068 sx_cd1865_out(sc, CD1865_CAR|SX_EI, pp->sp_chan); /* Select channel. */
1069 sx_cd1865_wait_CCR(sc, SX_EI);
1070 sx_cd1865_out(sc, CD1865_CCR|SX_EI, CD1865_CCR_RXEN|CD1865_CCR_TXEN);
1071 sx_cd1865_wait_CCR(sc, SX_EI);
1072 sx_cd1865_out(sc, CD1865_IER|SX_EI, ier);
1073 enable_intr();
1074 DPRINT((pp, DBG_PARAM, "sxparam out\n"));
1075 splx(oldspl);
1076 return(error);
1077 }
1078
1079 /*
1080 * sx_write_enable()
1081 * Enable/disable writes to a card channel.
1082 *
1083 * Description:
1084 * Set or clear the SX_SS_BLOCKWRITE flag in sp_state to block or allow
1085 * writes to a serial port on the card. When we enable writes, we
1086 * wake up anyone sleeping on SX_SS_WAITWRITE for this channel.
1087 *
1088 * Parameters:
1089 * flag 0 - disable writes.
1090 * 1 - enable writes.
1091 */
1092 static void
1093 sx_write_enable(
1094 struct sx_port *pp,
1095 int flag)
1096 {
1097 int oldspl;
1098
1099 oldspl = spltty(); /* Keep interrupts out. */
1100 if (flag) { /* Enable writes to the channel? */
1101 pp->sp_state &= ~SX_SS_BLOCKWRITE; /* Clear our flag. */
1102 if (pp->sp_state & SX_SS_WAITWRITE) { /* Sleepers? */
1103 pp->sp_state &= ~SX_SS_WAITWRITE; /* Clear their flag */
1104 wakeup((caddr_t)pp); /* & wake them up. */
1105 }
1106 }
1107 else /* Disabling writes. */
1108 pp->sp_state |= SX_SS_BLOCKWRITE; /* Set our flag. */
1109 splx(oldspl);
1110 }
1111
1112 /*
1113 * sx_shutdown_chan()
1114 * Shut down a channel on the I/O8+.
1115 *
1116 * Description:
1117 * This does all hardware shutdown processing for a channel on the I/O8+.
1118 * It is called from sxhardclose(). We reset the channel and turn off
1119 * interrupts.
1120 */
1121 static void
1122 sx_shutdown_chan(
1123 struct sx_port *pp)
1124 {
1125 int s;
1126 struct sx_softc *sc;
1127
1128 DPRINT((pp, DBG_ENTRY, "sx_shutdown_chan %x %x\n", pp, pp->sp_state));
1129 sc = PP2SC(pp);
1130 s = spltty();
1131 disable_intr();
1132 sx_cd1865_out(sc, CD1865_CAR, pp->sp_chan); /* Select channel. */
1133 sx_cd1865_wait_CCR(sc, 0); /* Wait for any commands to complete. */
1134 sx_cd1865_out(sc, CD1865_CCR, CD1865_CCR_SOFTRESET); /* Reset chan. */
1135 sx_cd1865_wait_CCR(sc, 0);
1136 sx_cd1865_out(sc, CD1865_IER, 0); /* Disable all interrupts. */
1137 enable_intr();
1138 splx(s);
1139 }
1140
1141 /*
1142 * sx_modem()
1143 * Set/Get state of modem control lines.
1144 *
1145 * Description:
1146 * Get and set the state of the modem control lines that we have available
1147 * on the I/O8+. The only lines we are guaranteed to have are CD and CTS.
1148 * We have DTR if the "DTR/RTS pin is DTR" flag is set, otherwise we have
1149 * RTS through the DTR pin.
1150 */
1151 static int
1152 sx_modem(
1153 struct sx_softc *sc,
1154 struct sx_port *pp,
1155 enum sx_mctl cmd,
1156 int bits)
1157 {
1158 int s, x;
1159
1160 DPRINT((pp, DBG_ENTRY|DBG_MODEM, "sx_modem %x/%s/%x\n",
1161 pp, sx_mctl2str(cmd), bits));
1162 s = spltty(); /* Block interrupts. */
1163 disable_intr();
1164 sx_cd1865_out(sc, CD1865_CAR|SX_EI, pp->sp_chan); /* Select our port. */
1165 x = sx_cd1865_in(sc, CD1865_MSVR|SX_EI); /* Get the current signals. */
1166 #ifdef SX_DEBUG
1167 DPRINT((pp, DBG_MODEM, "sx_modem MSVR 0x%x, CCSR %x GIVR %x SRSR %x\n",
1168 x, sx_cd1865_in(sc, CD1865_CCSR|SX_EI),
1169 sx_cd1865_in(sc, CD1865_GIVR|SX_EI),
1170 sx_cd1865_in(sc, CD1865_SRSR|SX_EI)));
1171 #endif
1172 enable_intr(); /* Allow other interrupts. */
1173 switch (cmd) {
1174 case GET:
1175 bits = TIOCM_LE;
1176 if ((x & CD1865_MSVR_CD) == 0)
1177 bits |= TIOCM_CD;
1178 if ((x & CD1865_MSVR_CTS) == 0)
1179 bits |= TIOCM_CTS;
1180 if ((x & CD1865_MSVR_DTR) == 0) {
1181 if (SX_DTRPIN(pp)) /* Odd pin is DTR? */
1182 bits |= TIOCM_DTR; /* Report DTR. */
1183 else /* Odd pin is RTS. */
1184 bits |= TIOCM_RTS; /* Report RTS. */
1185 }
1186 splx(s);
1187 return(bits);
1188 case SET:
1189 x = CD1865_MSVR_OFF;
1190 if ((bits & TIOCM_RTS && !SX_DTRPIN(pp)) ||
1191 (bits & TIOCM_DTR && SX_DTRPIN(pp)))
1192 x &= ~CD1865_MSVR_DTR;
1193 break;
1194 case BIS:
1195 if ((bits & TIOCM_RTS && !SX_DTRPIN(pp)) ||
1196 (bits & TIOCM_DTR && SX_DTRPIN(pp)))
1197 x &= ~CD1865_MSVR_DTR;
1198 break;
1199 case BIC:
1200 if ((bits & TIOCM_RTS && !SX_DTRPIN(pp)) ||
1201 (bits & TIOCM_DTR && SX_DTRPIN(pp)))
1202 x |= CD1865_MSVR_DTR;
1203 break;
1204 }
1205 DPRINT((pp, DBG_MODEM, "sx_modem MSVR=0x%x\n", x));
1206 disable_intr();
1207 /*
1208 * Set the new modem signals.
1209 */
1210 sx_cd1865_out(sc, CD1865_CAR|SX_EI, pp->sp_chan);
1211 sx_cd1865_out(sc, CD1865_MSVR|SX_EI, x);
1212 enable_intr();
1213 splx(s);
1214 return 0;
1215 }
1216
1217 #ifdef POLL
1218
1219 /*
1220 * sx_poll()
1221 * Poller to catch missed interrupts.
1222 *
1223 * Description:
1224 * Only used if we're complied with POLL. This routine is called every
1225 * sx_pollrate ticks to check for missed interrupts. We check each card
1226 * in the system; if we missed an interrupt, we complain about each one
1227 * and later call sx_intr() to handle them.
1228 */
1229 static void
1230 sx_poll(
1231 void *dummy)
1232 {
1233 struct sx_softc *sc;
1234 struct sx_port *pp;
1235 int card, lost, oldspl, chan;
1236
1237 DPRINT((0, DBG_POLL, "sx_poll\n"));
1238 oldspl = spltty();
1239 if (in_interrupt)
1240 goto out;
1241 lost = 0;
1242 for (card = 0; card < sx_numunits; card++) {
1243 sc = devclass_get_softc(sx_devclass, card);
1244 if (sc == NULL)
1245 continue;
1246 if (sx_cd1865_in(sc, CD1865_SRSR|SX_EI) & CD1865_SRSR_REQint) {
1247 printf("sx%d: lost interrupt\n", card);
1248 lost++;
1249 }
1250 /*
1251 * Gripe about no input flow control.
1252 */
1253 for (chan = 0; chan < SX_NUMCHANS; pp++, chan++) {
1254 pp = &(sc->sc_ports[chan]);
1255 if (pp->sp_delta_overflows > 0) {
1256 printf("sx%d: %d tty level buffer overflows\n",
1257 card, pp->sp_delta_overflows);
1258 pp->sp_delta_overflows = 0;
1259 }
1260 }
1261 }
1262 if (lost || sx_realpoll)
1263 sx_intr(NULL); /* call intr with fake vector */
1264 out: splx(oldspl);
1265 timeout(sx_poll, (caddr_t)0L, sx_pollrate);
1266 }
1267
1268 #endif /* POLL */
1269
1270
1271 /*
1272 * sx_transmit()
1273 * Handle transmit request interrupt.
1274 *
1275 * Description:
1276 * This routine handles the transmit request interrupt from the CD1865
1277 * chip on the I/O8+ card. The CD1865 interrupts us for a transmit
1278 * request under two circumstances: When the last character in the
1279 * transmit FIFO is sent and the channel is ready for more characters
1280 * ("transmit ready"), or when the last bit of the last character in the
1281 * FIFO is actually transmitted ("transmit empty"). In the former case,
1282 * we just pass processing off to sx_start() (via the line discipline)
1283 * to queue more characters. In the latter case, we were waiting for
1284 * the line to flush in sxhardclose() so we need to wake the sleeper.
1285 */
1286 static void
1287 sx_transmit(
1288 struct sx_softc *sc,
1289 struct sx_port *pp,
1290 int card)
1291 {
1292 struct tty *tp;
1293 unsigned char flags;
1294
1295 tp = pp->sp_tty;
1296 /*
1297 * Let others know what we're doing.
1298 */
1299 pp->sp_state |= SX_SS_IXMIT;
1300 /*
1301 * Get the service request enable register to see what we're waiting
1302 * for.
1303 */
1304 flags = sx_cd1865_in(sc, CD1865_SRER|SX_EI);
1305
1306 DPRINT((pp, DBG_TRANSMIT, "sx_xmit %x SRER %x\n", tp, flags));
1307 /*
1308 * "Transmit ready." The transmit FIFO is empty (but there are still
1309 * two characters being transmitted), so we need to tell the line
1310 * discipline to send more.
1311 */
1312 if (flags & CD1865_IER_TXRDY) {
1313 ttyld_start(tp);
1314 pp->sp_state &= ~SX_SS_IXMIT;
1315 DPRINT((pp, DBG_TRANSMIT, "sx_xmit TXRDY out\n"));
1316 return;
1317 }
1318 /*
1319 * "Transmit empty." The transmitter is completely empty; turn off the
1320 * service request and wake up the guy in sxhardclose() who is waiting
1321 * for this.
1322 */
1323 if (flags & CD1865_IER_TXEMPTY) {
1324 flags &= ~CD1865_IER_TXEMPTY;
1325 sx_cd1865_out(sc, CD1865_CAR|SX_EI, pp->sp_chan);
1326 sx_cd1865_out(sc, CD1865_SRER|SX_EI, flags);
1327 wakeup((caddr_t)pp);
1328 }
1329 pp->sp_state &= ~SX_SS_IXMIT;
1330 DPRINT((pp, DBG_TRANSMIT, "sx_xmit out\n"));
1331 }
1332
1333 /*
1334 * sx_modem_state()
1335 * Handle modem state-change request interrupt.
1336 *
1337 * Description:
1338 * Handles changed modem signals CD and CTS. We pass the CD change
1339 * off to the line discipline. We can't handle DSR since there isn't a
1340 * pin for it.
1341 */
1342 static void
1343 sx_modem_state(
1344 struct sx_softc *sc,
1345 struct sx_port *pp,
1346 int card)
1347 {
1348 struct tty *tp;
1349 unsigned char mcr;
1350
1351 /*
1352 * Let others know what we're doing.
1353 */
1354 pp->sp_state |= SX_SS_IMODEM;
1355 tp = pp->sp_tty;
1356 /* Grab the Modem Change Register. */
1357 mcr = sx_cd1865_in(sc, CD1865_MCR|SX_EI);
1358 DPRINT((pp, DBG_MODEM_STATE,
1359 "sx_mdmst %x st %x sp %x mcr %x\n",
1360 tp, tp->t_state, pp->sp_state, mcr));
1361 if (mcr & CD1865_MCR_CDCHG) { /* CD changed? */
1362 if ((sx_cd1865_in(sc, CD1865_MSVR) & CD1865_MSVR_CD) == 0) {
1363 DPRINT((pp, DBG_INTR, "modem carr on t_line %d\n",
1364 tp->t_line));
1365 (void)ttyld_modem(tp, 1);
1366 }
1367 else { /* CD went down. */
1368 DPRINT((pp, DBG_INTR, "modem carr off\n"));
1369 if (ttyld_modem(tp, 0))
1370 (void)sx_modem(sc, pp, SET, 0);
1371 }
1372 }
1373 #ifdef SX_BROKEN_CTS
1374 if (mcr & CD1865_MCR_CTSCHG) { /* CTS changed? */
1375 if (sx_cd1865_in(sc, CD1865_MSVR|SX_EI) & CD1865_MSVR_CTS) {
1376 pp->sp_state |= SX_SS_OSTOP;
1377 sx_cd1865_bic(sc, CD1865_IER|SX_EI, CD1865_IER_TXRDY);
1378 sx_write_enable(pp, 0); /* Block writes. */
1379 }
1380 else {
1381 pp->sp_state &= ~SX_SS_OSTOP;
1382 sx_cd1865_bis(sc, CD1865_IER|SX_EI, CD1865_IER_TXRDY);
1383 sx_write_enable(pp, 1); /* Unblock writes. */
1384 }
1385 }
1386 #endif /* SX_BROKEN_CTS */
1387 /* Clear state-change indicator bits. */
1388 sx_cd1865_out(sc, CD1865_MCR|SX_EI, 0);
1389 pp->sp_state &= ~SX_SS_IMODEM;
1390 }
1391
1392 /*
1393 * sx_receive()
1394 * Handle receive request interrupt.
1395 *
1396 * Description:
1397 * Handle a receive request interrupt from the CD1865. This is just a
1398 * standard "we have characters to process" request, we don't have to
1399 * worry about exceptions like BREAK and such. Exceptions are handled
1400 * by sx_receive_exception().
1401 */
1402 static void
1403 sx_receive(
1404 struct sx_softc *sc,
1405 struct sx_port *pp,
1406 int card)
1407 {
1408 struct tty *tp;
1409 unsigned char count;
1410 int i, x;
1411 static unsigned char sx_rxbuf[SX_BUFFERSIZE]; /* input staging area */
1412
1413 tp = pp->sp_tty;
1414 DPRINT((pp, DBG_RECEIVE,
1415 "sx_rcv %x st %x sp %x\n",
1416 tp, tp->t_state, pp->sp_state));
1417 /*
1418 * Let others know what we're doing.
1419 */
1420 pp->sp_state |= SX_SS_IRCV;
1421 /*
1422 * How many characters are waiting for us?
1423 */
1424 count = sx_cd1865_in(sc, CD1865_RDCR|SX_EI);
1425 if (count == 0) /* None? Bail. */
1426 return;
1427 DPRINT((pp, DBG_RECEIVE, "sx_receive count %d\n", count));
1428 /*
1429 * Pull the characters off the card into our local buffer, then
1430 * process that.
1431 */
1432 for (i = 0; i < count; i++)
1433 sx_rxbuf[i] = sx_cd1865_in(sc, CD1865_RDR|SX_EI);
1434 /*
1435 * If we're not open and connected, bail.
1436 */
1437 if (!(tp->t_state & TS_CONNECTED && tp->t_state & TS_ISOPEN)) {
1438 pp->sp_state &= ~SX_SS_IRCV;
1439 DPRINT((pp, DBG_RECEIVE, "sx_rcv not open\n"));
1440 return;
1441 }
1442 /*
1443 * If the tty input buffers are blocked and we have an RTS pin,
1444 * drop RTS and bail.
1445 */
1446 if (tp->t_state & TS_TBLOCK) {
1447 if (!SX_DTRPIN(pp) && SX_IFLOW(pp)) {
1448 (void)sx_modem(sc, pp, BIC, TIOCM_RTS);
1449 pp->sp_state |= SX_SS_ISTOP;
1450 }
1451 pp->sp_state &= ~SX_SS_IRCV;
1452 return;
1453 }
1454 if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
1455 DPRINT((pp, DBG_RECEIVE, "sx_rcv BYPASS\n"));
1456 /*
1457 * Avoid the grotesquely inefficient lineswitch routine
1458 * (ttyinput) in "raw" mode. It usually takes about 450
1459 * instructions (that's without canonical processing or
1460 * echo!). slinput is reasonably fast (usually 40
1461 * instructions plus call overhead).
1462 */
1463 if (tp->t_rawq.c_cc + count >= SX_I_HIGH_WATER &&
1464 (tp->t_cflag & CRTS_IFLOW || tp->t_iflag & IXOFF) &&
1465 !(tp->t_state & TS_TBLOCK)) {
1466 ttyblock(tp);
1467 DPRINT((pp, DBG_RECEIVE, "sx_rcv block\n"));
1468 }
1469 tk_nin += count;
1470 tk_rawcc += count;
1471 tp->t_rawcc += count;
1472
1473 pp->sp_delta_overflows +=
1474 b_to_q((char *)sx_rxbuf, count, &tp->t_rawq);
1475 ttwakeup(tp);
1476 /*
1477 * If we were stopped and need to start again because of this
1478 * receive, kick the output routine to get things going again.
1479 */
1480 if (tp->t_state & TS_TTSTOP && (tp->t_iflag & IXANY ||
1481 tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
1482 tp->t_state &= ~TS_TTSTOP;
1483 tp->t_lflag &= ~FLUSHO;
1484 sx_start(tp);
1485 }
1486 }
1487 else {
1488 DPRINT((pp, DBG_RECEIVE, "sx_rcv l_rint\n"));
1489 /*
1490 * It'd be nice to not have to go through the function call
1491 * overhead for each char here. It'd be nice to block input
1492 * it, saving a loop here and the call/return overhead.
1493 */
1494 for (x = 0; x < count; x++) {
1495 i = sx_rxbuf[x];
1496 if (ttyld_rint(tp, i) == -1)
1497 pp->sp_delta_overflows++;
1498 }
1499 }
1500 pp->sp_state &= ~SX_SS_IRCV;
1501 DPRINT((pp, DBG_RECEIVE, "sx_rcv out\n"));
1502 }
1503
1504
1505
1506 /*
1507 * sx_receive_exception()
1508 * Handle receive exception request interrupt processing.
1509 *
1510 * Description:
1511 * Handle a receive exception request interrupt from the CD1865.
1512 * Possible exceptions include BREAK, overrun, receiver timeout
1513 * and parity and frame errors. We don't handle receiver timeout,
1514 * we just complain. The rest are passed to ttyinput().
1515 */
1516 static void
1517 sx_receive_exception(
1518 struct sx_softc *sc,
1519 struct sx_port *pp,
1520 int card)
1521 {
1522 struct tty *tp;
1523 unsigned char st;
1524 int ch, isopen;
1525
1526 tp = pp->sp_tty;
1527 /*
1528 * Let others know what we're doing.
1529 */
1530 pp->sp_state |= SX_SS_IRCVEXC;
1531 /*
1532 * Check to see whether we should receive characters.
1533 */
1534 if (tp->t_state & TS_CONNECTED &&
1535 tp->t_state & TS_ISOPEN)
1536 isopen = 1;
1537 else
1538 isopen = 0;
1539
1540 st = sx_cd1865_in(sc, CD1865_RCSR|SX_EI); /* Get the character status.*/
1541 ch = (int)sx_cd1865_in(sc, CD1865_RDR|SX_EI); /* Get the character. */
1542 DPRINT((pp, DBG_RECEIVE_EXC,
1543 "sx_rexc %x st %x sp %x st 0x%x ch 0x%x ('%c')\n",
1544 tp, tp->t_state, pp->sp_state, st, ch, ch));
1545 /* If there's no status or the tty isn't open, bail. */
1546 if (!st || !isopen) {
1547 pp->sp_state &= ~SX_SS_IRCVEXC;
1548 DPRINT((pp, DBG_RECEIVE_EXC, "sx_rexc not open\n"));
1549 return;
1550 }
1551 if (st & CD1865_RCSR_TOUT) /* Receiver timeout; just complain. */
1552 printf("sx%d: port %d: Receiver timeout.\n", card, pp->sp_chan);
1553 else if (st & CD1865_RCSR_BREAK)
1554 ch |= TTY_BI;
1555 else if (st & CD1865_RCSR_PE)
1556 ch |= TTY_PE;
1557 else if (st & CD1865_RCSR_FE)
1558 ch |= TTY_FE;
1559 else if (st & CD1865_RCSR_OE)
1560 ch |= TTY_OE;
1561 ttyld_rint(tp, ch);
1562 pp->sp_state &= ~SX_SS_IRCVEXC;
1563 }
1564
1565 /*
1566 * sx_intr()
1567 * Field interrupts from the I/O8+.
1568 *
1569 * Description:
1570 * The interrupt handler polls ALL ports on ALL adapters each time
1571 * it is called.
1572 */
1573 void
1574 sx_intr(
1575 void *arg)
1576 {
1577 struct sx_softc *sc;
1578 struct sx_port *pp = NULL;
1579 int card;
1580 unsigned char ack;
1581
1582 sc = arg;
1583
1584 DPRINT((0, arg == NULL ? DBG_POLL:DBG_INTR, "sx_intr\n"));
1585 if (in_interrupt)
1586 return;
1587 in_interrupt = 1;
1588
1589 /*
1590 * When we get an int we poll all the channels and do ALL pending
1591 * work, not just the first one we find. This allows all cards to
1592 * share the same vector.
1593 *
1594 * On the other hand, if we're sharing the vector with something
1595 * that's not an I/O8+, we may be making extra work for ourselves.
1596 */
1597 for (card = 0; card < sx_numunits; card++) {
1598 unsigned char st;
1599
1600 sc = devclass_get_softc(sx_devclass, card);
1601 if (sc == NULL)
1602 continue;
1603 /*
1604 * Check the Service Request Status Register to see who
1605 * interrupted us and why. May be a receive, transmit or
1606 * modem-signal-change interrupt. Reading the appropriate
1607 * Request Acknowledge Register acknowledges the request and
1608 * gives us the contents of the Global Service Vector Register,
1609 * which in a daisy-chained configuration (not ours) uniquely
1610 * identifies the particular CD1865 and gives us the request
1611 * type. We mask off the ID part and use the rest.
1612 *
1613 * From the CD1865 specs, it appears that only one request can
1614 * happen at a time, but in testing it's pretty obvious that
1615 * the specs lie. Or perhaps we're just slow enough that the
1616 * requests pile up. Regardless, if we try to process more
1617 * than one at a time without clearing the previous request
1618 * (writing zero to EOIR) first, we hang the card. Thus the
1619 * "else if" logic here.
1620 */
1621 while ((st = (sx_cd1865_in(sc, CD1865_SRSR|SX_EI)) &
1622 CD1865_SRSR_REQint)) {
1623 /*
1624 * Transmit request interrupt.
1625 */
1626 if (st & CD1865_SRSR_TREQint) {
1627 ack = sx_cd1865_in(sc, CD1865_TRAR|SX_EI) &
1628 CD1865_GIVR_ITMASK;
1629 pp = sx_int_port(sc, card);
1630 if (pp == NULL) /* Bad channel. */
1631 goto skip;
1632 pp->sp_state |= SX_SS_INTR; /* In interrupt. */
1633 if (ack == CD1865_GIVR_IT_TX)
1634 sx_transmit(sc, pp, card);
1635 else
1636 printf("sx%d: Bad transmit ack 0x%02x.\n",
1637 card, ack);
1638 }
1639 /*
1640 * Modem signal change request interrupt.
1641 */
1642 else if (st & CD1865_SRSR_MREQint) {
1643 ack = sx_cd1865_in(sc, CD1865_MRAR|SX_EI) &
1644 CD1865_GIVR_ITMASK;
1645 pp = sx_int_port(sc, card);
1646 if (pp == NULL) /* Bad channel. */
1647 goto skip;
1648 pp->sp_state |= SX_SS_INTR; /* In interrupt. */
1649 if (ack == CD1865_GIVR_IT_MODEM)
1650 sx_modem_state(sc, pp, card);
1651 else
1652 printf("sx%d: Bad modem ack 0x%02x.\n",
1653 card, ack);
1654 }
1655 /*
1656 * Receive request interrupt.
1657 */
1658 else if (st & CD1865_SRSR_RREQint) {
1659 ack = sx_cd1865_in(sc, CD1865_RRAR|SX_EI) &
1660 CD1865_GIVR_ITMASK;
1661 pp = sx_int_port(sc, card);
1662 if (pp == NULL) /* Bad channel. */
1663 goto skip;
1664 pp->sp_state |= SX_SS_INTR; /* In interrupt. */
1665 if (ack == CD1865_GIVR_IT_RCV)
1666 sx_receive(sc, pp, card);
1667 else if (ack == CD1865_GIVR_IT_REXC)
1668 sx_receive_exception(sc, pp, card);
1669 else
1670 printf("sx%d: Bad receive ack 0x%02x.\n",
1671 card, ack);
1672 }
1673 /*
1674 * None of the above; this is a "can't happen," but
1675 * you never know...
1676 */
1677 else {
1678 printf("sx%d: Bad service request 0x%02x.\n",
1679 card, st);
1680 }
1681 pp->sp_state &= ~SX_SS_INTR;
1682 skip: sx_cd1865_out(sc, CD1865_EOIR|SX_EI, 0); /* EOI. */
1683 } /* while (st & CD1865_SRSR_REQint) */
1684 } /* for (card = 0; card < sx_numunits; card++) */
1685 in_interrupt = 0;
1686 DPRINT((0, arg == NULL ? DBG_POLL:DBG_INTR, "sx_intr out\n"));
1687 }
1688
1689 /*
1690 * sx_start()
1691 * Handle transmit and state-change stuff.
1692 *
1693 * Description:
1694 * This is part of the line discipline processing; at various points in
1695 * the line discipline he calls ttstart() which calls the oproc routine,
1696 * which is this function. We're called by the line discipline to start
1697 * data transmission and to change signal states (for RTS flow control).
1698 * We're also called by this driver to perform line-breaks and to actually
1699 * do the data transmission.
1700
1701 * We can only fill the FIFO from interrupt since the card only makes it
1702 * available to us during a service request such as TXRDY; this only
1703 * happens at interrupt.
1704 *
1705 * All paths through this code call ttwwakeup().
1706 */
1707 static void
1708 sx_start(
1709 struct tty *tp)
1710 {
1711 struct sx_softc *sc;
1712 struct sx_port *pp;
1713 struct clist *qp;
1714 int s;
1715 int count = CD1865_TFIFOSZ;
1716
1717 s = spltty();
1718 pp = TP2PP(tp);
1719 qp = &tp->t_outq;
1720 DPRINT((pp, DBG_ENTRY|DBG_START,
1721 "sx_start %x st %x sp %x cc %d\n",
1722 tp, tp->t_state, pp->sp_state, qp->c_cc));
1723
1724 /*
1725 * If we're stopped, just wake up sleepers and get out.
1726 */
1727 if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) {
1728 ttwwakeup(tp);
1729 splx(s);
1730 DPRINT((pp, DBG_EXIT|DBG_START, "sx_start out\n", tp->t_state));
1731 return;
1732 }
1733 sc = TP2SC(tp);
1734 /*
1735 * If we're not transmitting, we may have been called to crank up the
1736 * transmitter and start things rolling or we may have been called to
1737 * get a bit of tty state. If the latter, handle it. Either way, if
1738 * we have data to transmit, turn on the transmit-ready interrupt,
1739 * set the XMIT flag and we're done. As soon as we allow interrupts
1740 * the card will interrupt for the first chunk of data. Note that
1741 * we don't mark the tty as busy until we are actually sending data
1742 * and then only if we have more than will fill the FIFO. If there's
1743 * no data to transmit, just handle the tty state.
1744 */
1745 if (!SX_XMITTING(pp)) {
1746 /*
1747 * If we were flow-controlled and input is no longer blocked,
1748 * raise RTS if we can.
1749 */
1750 if (SX_ISTOP(pp) && !(tp->t_state & TS_TBLOCK)) {
1751 if (!SX_DTRPIN(pp) && SX_IFLOW(pp))
1752 (void)sx_modem(sc, pp, BIS, TIOCM_RTS);
1753 pp->sp_state &= ~SX_SS_ISTOP;
1754 }
1755 /*
1756 * If input is blocked, drop RTS if we can and set our flag.
1757 */
1758 if (tp->t_state & TS_TBLOCK) {
1759 if (!SX_DTRPIN(pp) && SX_IFLOW(pp))
1760 (void)sx_modem(sc, pp, BIC, TIOCM_RTS);
1761 pp->sp_state |= SX_SS_ISTOP;
1762 }
1763 if ((qp->c_cc > 0 && !SX_OSTOP(pp)) || SX_DOBRK(pp)) {
1764 disable_intr();
1765 sx_cd1865_out(sc, CD1865_CAR|SX_EI, pp->sp_chan);
1766 sx_cd1865_bis(sc, CD1865_IER|SX_EI, CD1865_IER_TXRDY);
1767 enable_intr();
1768 pp->sp_state |= SX_SS_XMIT;
1769 }
1770 ttwwakeup(tp);
1771 splx(s);
1772 DPRINT((pp, DBG_EXIT|DBG_START,
1773 "sx_start out B st %x sp %x cc %d\n",
1774 tp->t_state, pp->sp_state, qp->c_cc));
1775 return;
1776 }
1777 /*
1778 * If we weren't called from an interrupt or it wasn't a transmit
1779 * interrupt, we've done all we need to do. Everything else is done
1780 * in the transmit interrupt.
1781 */
1782 if (!SX_INTR(pp) || !SX_IXMIT(pp)) {
1783 ttwwakeup(tp);
1784 splx(s);
1785 DPRINT((pp, DBG_EXIT|DBG_START, "sx_start out X\n"));
1786 return;
1787 }
1788 /*
1789 * We're transmitting. If the clist is empty and we don't have a break
1790 * to send, turn off transmit-ready interrupts, and clear the XMIT
1791 * flag. Mark the tty as no longer busy, in case we haven't done
1792 * that yet. A future call to sxwrite() with more characters will
1793 * start up the process once more.
1794 */
1795 if (qp->c_cc == 0 && !SX_DOBRK(pp)) {
1796 disable_intr();
1797 /* sx_cd1865_out(sc, CD1865_CAR|SX_EI, pp->sp_chan);*/
1798 sx_cd1865_bic(sc, CD1865_IER|SX_EI, CD1865_IER_TXRDY);
1799 enable_intr();
1800 pp->sp_state &= ~SX_SS_XMIT;
1801 tp->t_state &= ~TS_BUSY;
1802 ttwwakeup(tp);
1803 splx(s);
1804 DPRINT((pp, DBG_EXIT|DBG_START,
1805 "sx_start out E st %x sp %x\n",
1806 tp->t_state, pp->sp_state));
1807 return;
1808 }
1809 disable_intr();
1810 /*
1811 * If we have a BREAK state-change pending, handle it. If we aren't
1812 * sending a break, start one. If we are, turn it off.
1813 */
1814 if (SX_DOBRK(pp)) {
1815 count -= 2; /* Account for escape chars in FIFO. */
1816 if (SX_BREAK(pp)) { /* Doing break, stop it. */
1817 sx_cd1865_out(sc, CD1865_TDR, CD1865_C_ESC);
1818 sx_cd1865_out(sc, CD1865_TDR, CD1865_C_EBRK);
1819 sx_cd1865_etcmode(sc, SX_EI, pp->sp_chan, 0);
1820 pp->sp_state &= ~SX_SS_BREAK;
1821 }
1822 else { /* Start doing break. */
1823 sx_cd1865_etcmode(sc, SX_EI, pp->sp_chan, 1);
1824 sx_cd1865_out(sc, CD1865_TDR, CD1865_C_ESC);
1825 sx_cd1865_out(sc, CD1865_TDR, CD1865_C_SBRK);
1826 pp->sp_state |= SX_SS_BREAK;
1827 }
1828 pp->sp_state &= ~SX_SS_DOBRK;
1829 }
1830 /*
1831 * We've still got data in the clist, fill the channel's FIFO. The
1832 * CD1865 only gives us access to the FIFO during a transmit ready
1833 * request [interrupt] for this channel.
1834 */
1835 while (qp->c_cc > 0 && count-- >= 0) {
1836 register unsigned char ch, *cp;
1837 int nch;
1838
1839 ch = (char)getc(qp);
1840 /*
1841 * If we're doing a break we're in ETC mode, so we need to
1842 * double any NULs in the stream.
1843 */
1844 if (SX_BREAK(pp)) { /* Doing break, in ETC mode. */
1845 if (ch == '\0') { /* NUL? Double it. */
1846 sx_cd1865_out(sc, CD1865_TDR, ch);
1847 count--;
1848 }
1849 /*
1850 * Peek the next character; if it's a NUL, we need
1851 * to escape it, but we can't if we're out of FIFO.
1852 * We'll do it on the next pass and leave the FIFO
1853 * incompletely filled.
1854 */
1855 if (qp->c_cc > 0) {
1856 cp = qp->c_cf;
1857 cp = nextc(qp, cp, &nch);
1858 if (nch == '\0' && count < 1)
1859 count = -1;
1860 }
1861 }
1862 sx_cd1865_out(sc, CD1865_TDR, ch);
1863 }
1864 enable_intr();
1865 /*
1866 * If we still have data to transmit, mark the tty busy for the
1867 * line discipline.
1868 */
1869 if (qp->c_cc > 0)
1870 tp->t_state |= TS_BUSY;
1871 else
1872 tp->t_state &= ~TS_BUSY;
1873 /* Wake up sleepers if necessary. */
1874 ttwwakeup(tp);
1875 splx(s);
1876 DPRINT((pp, DBG_EXIT|DBG_START,
1877 "sx_start out R %d/%d\n",
1878 count, qp->c_cc));
1879 }
1880
1881 /*
1882 * Stop output on a line. called at spltty();
1883 */
1884 void
1885 sx_stop(
1886 struct tty *tp,
1887 int rw)
1888 {
1889 struct sx_softc *sc;
1890 struct sx_port *pp;
1891 int s;
1892
1893 sc = TP2SC(tp);
1894 pp = TP2PP(tp);
1895 DPRINT((TP2PP(tp), DBG_ENTRY|DBG_STOP, "sx_stop(%x,%x)\n", tp, rw));
1896
1897 s = spltty();
1898 /* XXX: must check (rw & FWRITE | FREAD) etc flushing... */
1899 if (rw & FWRITE) {
1900 disable_intr();
1901 sx_cd1865_out(sc, CD1865_CAR|SX_EI, pp->sp_chan);
1902 sx_cd1865_bic(sc, CD1865_IER|SX_EI, CD1865_IER_TXRDY);
1903 sx_cd1865_wait_CCR(sc, SX_EI); /* Wait for CCR to go idle. */
1904 sx_cd1865_out(sc, CD1865_CCR|SX_EI, CD1865_CCR_TXDIS);
1905 sx_cd1865_wait_CCR(sc, SX_EI);
1906 enable_intr();
1907 /* what level are we meant to be flushing anyway? */
1908 if (tp->t_state & TS_BUSY) {
1909 if ((tp->t_state & TS_TTSTOP) == 0)
1910 tp->t_state |= TS_FLUSH;
1911 tp->t_state &= ~TS_BUSY;
1912 ttwwakeup(tp);
1913 }
1914 }
1915 /*
1916 * Nothing to do for FREAD.
1917 */
1918 splx(s);
1919 }
1920
1921 #ifdef SX_DEBUG
1922
1923 void
1924 sx_dprintf(
1925 struct sx_port *pp,
1926 int flags,
1927 const char *fmt, ...)
1928 {
1929 static char *logbuf = NULL;
1930 static char *linebuf = NULL;
1931 static char *logptr;
1932 char *lbuf;
1933 int n, m;
1934 va_list ap;
1935
1936 if (logbuf == NULL) {
1937 logbuf = (char *)malloc(1024*1024, M_DEVBUF, M_WAITOK);
1938 linebuf = (char *)malloc(256, M_DEVBUF, M_WAITOK);
1939 logptr = logbuf;
1940 }
1941 lbuf = linebuf;
1942 n = 0;
1943 if ((pp == NULL && (sx_debug&flags)) ||
1944 (pp != NULL && ((pp->sp_debug&flags) || (sx_debug&flags)))) {
1945 if (pp != NULL &&
1946 pp->sp_tty != NULL &&
1947 pp->sp_tty->t_dev != NULL) {
1948 n = snprintf(linebuf, 256, "%cx%d(%d): ", 's',
1949 (int)SX_MINOR2CARD(minor(pp->sp_tty->t_dev)),
1950 (int)SX_MINOR2CHAN(minor(pp->sp_tty->t_dev)));
1951 if (n > 256)
1952 n = 256;
1953 lbuf += n;
1954 }
1955 m = n;
1956 va_start(ap, fmt);
1957 n = vsnprintf(lbuf, 256 - m, fmt, ap);
1958 va_end(ap);
1959 if (n > 256 - m)
1960 n = 256 - m;
1961 n += m;
1962 if (logptr + n + 1 > logbuf + (1024 * 1024)) {
1963 bzero(logptr, logbuf + (1024 * 1024) - logptr);
1964 logptr = logbuf;
1965 }
1966 bcopy(linebuf, logptr, n);
1967 logptr += n;
1968 *logptr = '\0';
1969 if (sx_debug & DBG_PRINTF)
1970 printf("%s", linebuf);
1971 }
1972 }
1973
1974 static char *
1975 sx_mctl2str(enum sx_mctl cmd)
1976 {
1977 switch (cmd) {
1978 case GET:
1979 return("GET");
1980 case SET:
1981 return("SET");
1982 case BIS:
1983 return("BIS");
1984 case BIC:
1985 return("BIC");
1986 }
1987 return("BAD");
1988 }
1989
1990 #endif /* DEBUG */
Cache object: 3702cb40df12c3c9e82b83e2f5c31d5d
|