sab.c revision 1.56 1 /* $NetBSD: sab.c,v 1.56 2021/04/24 23:36:49 thorpej Exp $ */
2 /* $OpenBSD: sab.c,v 1.7 2002/04/08 17:49:42 jason Exp $ */
3
4 /*
5 * Copyright (c) 2001 Jason L. Wright (jason (at) thought.net)
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Jason L. Wright
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 * Effort sponsored in part by the Defense Advanced Research Projects
35 * Agency (DARPA) and Air Force Research Laboratory, Air Force
36 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
37 *
38 */
39
40 /*
41 * SAB82532 Dual UART driver
42 */
43
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: sab.c,v 1.56 2021/04/24 23:36:49 thorpej Exp $");
46
47 #include "opt_kgdb.h"
48 #include <sys/types.h>
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/device.h>
52 #include <sys/conf.h>
53 #include <sys/file.h>
54 #include <sys/ioctl.h>
55 #include <sys/kernel.h>
56 #include <sys/proc.h>
57 #include <sys/tty.h>
58 #include <sys/syslog.h>
59 #include <sys/kauth.h>
60 #include <sys/kgdb.h>
61 #include <sys/intr.h>
62
63 #include <machine/autoconf.h>
64 #include <machine/openfirm.h>
65
66 #include <dev/cons.h>
67
68 #include <dev/ebus/ebusreg.h>
69 #include <dev/ebus/ebusvar.h>
70 #include <sparc64/dev/sab82532reg.h>
71
72 #include "locators.h"
73
74 #define SABUNIT(x) TTUNIT(x)
75 #define SABDIALOUT(x) TTDIALOUT(x)
76
77 #define SABTTY_RBUF_SIZE 1024 /* must be divisible by 2 */
78
79 struct sab_softc {
80 device_t sc_dev;
81 struct intrhand * sc_ih;
82 bus_space_tag_t sc_bt;
83 bus_space_handle_t sc_bh;
84 struct sabtty_softc * sc_child[SAB_NCHAN];
85 u_int sc_nchild;
86 void * sc_softintr;
87 int sc_node;
88 };
89
90 struct sabtty_attach_args {
91 u_int sbt_portno;
92 };
93
94 struct sabtty_softc {
95 device_t sc_dev;
96 struct sab_softc * sc_parent;
97 bus_space_tag_t sc_bt;
98 bus_space_handle_t sc_bh;
99 struct tty * sc_tty;
100 u_int sc_portno;
101 uint8_t sc_pvr_dtr, sc_pvr_dsr;
102 uint8_t sc_imr0, sc_imr1;
103 int sc_openflags;
104 u_char * sc_txp;
105 int sc_txc;
106 int sc_flags;
107 #define SABTTYF_STOP 0x0001
108 #define SABTTYF_DONE 0x0002
109 #define SABTTYF_RINGOVERFLOW 0x0004
110 #define SABTTYF_CDCHG 0x0008
111 #define SABTTYF_CONS_IN 0x0010
112 #define SABTTYF_CONS_OUT 0x0020
113 #define SABTTYF_TXDRAIN 0x0040
114 #define SABTTYF_DONTDDB 0x0080
115 #define SABTTYF_IS_RSC 0x0100
116 uint8_t sc_rbuf[SABTTY_RBUF_SIZE];
117 uint8_t *sc_rend, *sc_rput, *sc_rget;
118 uint8_t sc_polling, sc_pollrfc;
119 };
120
121 struct sabtty_softc *sabtty_cons_input;
122 struct sabtty_softc *sabtty_cons_output;
123
124 #define SAB_READ(sc,r) \
125 bus_space_read_1((sc)->sc_bt, (sc)->sc_bh, (r))
126 #define SAB_WRITE(sc,r,v) \
127 bus_space_write_1((sc)->sc_bt, (sc)->sc_bh, (r), (v))
128 #define SAB_WRITE_BLOCK(sc,r,p,c) \
129 bus_space_write_region_1((sc)->sc_bt, (sc)->sc_bh, (r), (p), (c))
130
131 int sab_match(device_t, cfdata_t, void *);
132 void sab_attach(device_t, device_t, void *);
133 int sab_print(void *, const char *);
134 int sab_intr(void *);
135
136 void sab_softintr(void *);
137 void sab_cnputc(dev_t, int);
138 int sab_cngetc(dev_t);
139 void sab_cnpollc(dev_t, int);
140
141 int sabtty_match(device_t, cfdata_t, void *);
142 void sabtty_attach(device_t, device_t, void *);
143 void sabtty_start(struct tty *);
144 int sabtty_param(struct tty *, struct termios *);
145 int sabtty_intr(struct sabtty_softc *, int *);
146 void sabtty_softintr(struct sabtty_softc *);
147 int sabtty_mdmctrl(struct sabtty_softc *, int, int);
148 void sabtty_cec_wait(struct sabtty_softc *);
149 void sabtty_tec_wait(struct sabtty_softc *);
150 void sabtty_reset(struct sabtty_softc *);
151 void sabtty_flush(struct sabtty_softc *);
152 int sabtty_speed(int);
153 void sabtty_console_flags(struct sabtty_softc *);
154 void sabtty_cnpollc(struct sabtty_softc *, int);
155 bool sabtty_shutdown(device_t, int);
156 int sabttyparam(struct sabtty_softc *, struct tty *, struct termios *);
157
158 #ifdef KGDB
159 int sab_kgdb_check(struct sabtty_softc *);
160 void sab_kgdb_init(struct sabtty_softc *);
161 #endif
162
163 void sabtty_cnputc(struct sabtty_softc *, int);
164 int sabtty_cngetc(struct sabtty_softc *);
165
166 CFATTACH_DECL_NEW(sab, sizeof(struct sab_softc),
167 sab_match, sab_attach, NULL, NULL);
168
169 extern struct cfdriver sab_cd;
170
171 CFATTACH_DECL_NEW(sabtty, sizeof(struct sabtty_softc),
172 sabtty_match, sabtty_attach, NULL, NULL);
173
174 extern struct cfdriver sabtty_cd;
175
176 dev_type_open(sabopen);
177 dev_type_close(sabclose);
178 dev_type_read(sabread);
179 dev_type_write(sabwrite);
180 dev_type_ioctl(sabioctl);
181 dev_type_stop(sabstop);
182 dev_type_tty(sabtty);
183 dev_type_poll(sabpoll);
184
185 static struct cnm_state sabtty_cnm_state;
186
187 const struct cdevsw sabtty_cdevsw = {
188 .d_open = sabopen,
189 .d_close = sabclose,
190 .d_read = sabread,
191 .d_write = sabwrite,
192 .d_ioctl = sabioctl,
193 .d_stop = sabstop,
194 .d_tty = sabtty,
195 .d_poll = sabpoll,
196 .d_mmap = nommap,
197 .d_kqfilter = ttykqfilter,
198 .d_discard = nodiscard,
199 .d_flag = D_TTY
200 };
201
202 struct sabtty_rate {
203 int baud;
204 int n, m;
205 };
206
207 struct sabtty_rate sabtty_baudtable[] = {
208 { 50, 35, 10 },
209 { 75, 47, 9 },
210 { 110, 32, 9 },
211 { 134, 53, 8 },
212 { 150, 47, 8 },
213 { 200, 35, 8 },
214 { 300, 47, 7 },
215 { 600, 47, 6 },
216 { 1200, 47, 5 },
217 { 1800, 31, 5 },
218 { 2400, 47, 4 },
219 { 4800, 47, 3 },
220 { 9600, 47, 2 },
221 { 19200, 47, 1 },
222 { 38400, 23, 1 },
223 { 57600, 15, 1 },
224 { 115200, 7, 1 },
225 { 230400, 3, 1 },
226 { 460800, 1, 1 },
227 { 76800, 11, 1 },
228 { 153600, 5, 1 },
229 { 307200, 3, 1 },
230 { 614400, 3, 0 },
231 { 921600, 0, 1 },
232 };
233
234 int
235 sab_match(device_t parent, cfdata_t match, void *aux)
236 {
237 struct ebus_attach_args *ea = aux;
238 char *compat;
239
240 if (strcmp(ea->ea_name, "se") == 0 ||
241 strcmp(ea->ea_name, "FJSV,se") == 0)
242 return (1);
243
244 compat = prom_getpropstring(ea->ea_node, "compatible");
245 if (compat != NULL && !strcmp(compat, "sab82532"))
246 return (1);
247
248 return (0);
249 }
250
251 void
252 sab_attach(device_t parent, device_t self, void *aux)
253 {
254 struct sab_softc *sc = device_private(self);
255 struct ebus_attach_args *ea = aux;
256 uint8_t r;
257 u_int i;
258 int locs[SABCF_NLOCS];
259
260 sc->sc_dev = self;
261 sc->sc_bt = ea->ea_bustag;
262 sc->sc_node = ea->ea_node;
263
264 /* Use prom mapping, if available. */
265 if (ea->ea_nvaddr)
266 sparc_promaddr_to_handle(sc->sc_bt, ea->ea_vaddr[0],
267 &sc->sc_bh);
268 else if (bus_space_map(sc->sc_bt, EBUS_ADDR_FROM_REG(&ea->ea_reg[0]),
269 ea->ea_reg[0].size, 0, &sc->sc_bh) != 0) {
270 printf(": can't map register space\n");
271 return;
272 }
273
274 sc->sc_ih = bus_intr_establish(ea->ea_bustag, ea->ea_intr[0],
275 IPL_TTY, sab_intr, sc);
276 if (sc->sc_ih == NULL) {
277 printf(": can't map interrupt\n");
278 return;
279 }
280
281 sc->sc_softintr = softint_establish(SOFTINT_SERIAL, sab_softintr, sc);
282 if (sc->sc_softintr == NULL) {
283 printf(": can't get soft intr\n");
284 return;
285 }
286
287 aprint_normal(": rev ");
288 r = SAB_READ(sc, SAB_VSTR) & SAB_VSTR_VMASK;
289 switch (r) {
290 case SAB_VSTR_V_1:
291 aprint_normal("1");
292 break;
293 case SAB_VSTR_V_2:
294 aprint_normal("2");
295 break;
296 case SAB_VSTR_V_32:
297 aprint_normal("3.2");
298 break;
299 default:
300 aprint_normal("unknown(0x%x)", r);
301 break;
302 }
303 aprint_normal("\n");
304 aprint_naive(": Serial controller\n");
305
306 /* Let current output drain */
307 DELAY(100000);
308
309 /* Set all pins, except DTR pins to be inputs */
310 SAB_WRITE(sc, SAB_PCR, ~(SAB_PVR_DTR_A | SAB_PVR_DTR_B));
311 /* Disable port interrupts */
312 SAB_WRITE(sc, SAB_PIM, 0xff);
313 SAB_WRITE(sc, SAB_PVR, SAB_PVR_DTR_A | SAB_PVR_DTR_B | SAB_PVR_MAGIC);
314 SAB_WRITE(sc, SAB_IPC, SAB_IPC_ICPL);
315
316 for (i = 0; i < SAB_NCHAN; i++) {
317 struct sabtty_attach_args stax;
318
319 stax.sbt_portno = i;
320
321 locs[SABCF_CHANNEL] = i;
322
323 sc->sc_child[i] = device_private(
324 config_found(self, &stax, sab_print,
325 CFARG_SUBMATCH, config_stdsubmatch,
326 CFARG_LOCATORS, locs,
327 CFARG_EOL));
328 if (sc->sc_child[i] != NULL)
329 sc->sc_nchild++;
330 }
331 }
332
333 int
334 sab_print(void *args, const char *name)
335 {
336 struct sabtty_attach_args *sa = args;
337
338 if (name)
339 aprint_normal("sabtty at %s", name);
340 aprint_normal(" port %u", sa->sbt_portno);
341 return (UNCONF);
342 }
343
344 int
345 sab_intr(void *vsc)
346 {
347 struct sab_softc *sc = vsc;
348 int r = 0, needsoft = 0;
349 uint8_t gis;
350
351 gis = SAB_READ(sc, SAB_GIS);
352
353 /* channel A */
354 if ((gis & (SAB_GIS_ISA1 | SAB_GIS_ISA0)) && sc->sc_child[0] &&
355 sc->sc_child[0]->sc_tty)
356 r |= sabtty_intr(sc->sc_child[0], &needsoft);
357
358 /* channel B */
359 if ((gis & (SAB_GIS_ISB1 | SAB_GIS_ISB0)) && sc->sc_child[1] &&
360 sc->sc_child[1]->sc_tty)
361 r |= sabtty_intr(sc->sc_child[1], &needsoft);
362
363 if (needsoft)
364 softint_schedule(sc->sc_softintr);
365
366 return (r);
367 }
368
369 void
370 sab_softintr(void *vsc)
371 {
372 struct sab_softc *sc = vsc;
373
374 if (sc->sc_child[0] && sc->sc_child[0]->sc_tty)
375 sabtty_softintr(sc->sc_child[0]);
376 if (sc->sc_child[1] && sc->sc_child[1]->sc_tty)
377 sabtty_softintr(sc->sc_child[1]);
378 }
379
380 int
381 sabtty_match(device_t parent, cfdata_t match, void *aux)
382 {
383
384 return (1);
385 }
386
387 void
388 sabtty_attach(device_t parent, device_t self, void *aux)
389 {
390 struct sabtty_softc *sc = device_private(self);
391 struct sabtty_attach_args *sa = aux;
392 int r;
393 int maj;
394 int is_kgdb = 0;
395
396 sc->sc_dev = self;
397 #ifdef KGDB
398 is_kgdb = sab_kgdb_check(sc);
399 #endif
400
401 if (!is_kgdb) {
402 sc->sc_tty = tty_alloc();
403 if (sc->sc_tty == NULL) {
404 aprint_normal(": failed to allocate tty\n");
405 return;
406 }
407 tty_attach(sc->sc_tty);
408 sc->sc_tty->t_oproc = sabtty_start;
409 sc->sc_tty->t_param = sabtty_param;
410 }
411
412 sc->sc_parent = device_private(parent);
413 sc->sc_bt = sc->sc_parent->sc_bt;
414 sc->sc_portno = sa->sbt_portno;
415 sc->sc_rend = sc->sc_rbuf + SABTTY_RBUF_SIZE;
416
417 switch (sa->sbt_portno) {
418 case 0: /* port A */
419 sc->sc_pvr_dtr = SAB_PVR_DTR_A;
420 sc->sc_pvr_dsr = SAB_PVR_DSR_A;
421 r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh,
422 SAB_CHAN_A, SAB_CHANLEN, &sc->sc_bh);
423 break;
424 case 1: /* port B */
425 sc->sc_pvr_dtr = SAB_PVR_DTR_B;
426 sc->sc_pvr_dsr = SAB_PVR_DSR_B;
427 r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh,
428 SAB_CHAN_B, SAB_CHANLEN, &sc->sc_bh);
429 break;
430 default:
431 aprint_normal(": invalid channel: %u\n", sa->sbt_portno);
432 return;
433 }
434 if (r != 0) {
435 aprint_normal(": failed to allocate register subregion\n");
436 return;
437 }
438
439 sabtty_console_flags(sc);
440
441 if (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) {
442 struct termios t;
443 const char *acc;
444
445 /* Let residual prom output drain */
446 DELAY(100000);
447
448 switch (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) {
449 case SABTTYF_CONS_IN:
450 acc = "input";
451 break;
452 case SABTTYF_CONS_OUT:
453 acc = "output";
454 break;
455 case SABTTYF_CONS_IN|SABTTYF_CONS_OUT:
456 default:
457 acc = "i/o";
458 break;
459 }
460
461 t.c_ispeed= 0;
462 if (sc->sc_flags & SABTTYF_IS_RSC)
463 t.c_ospeed = 115200;
464 else
465 t.c_ospeed = 9600;
466 t.c_cflag = CREAD | CS8 | HUPCL;
467 sc->sc_tty->t_ospeed = 0;
468 sabttyparam(sc, sc->sc_tty, &t);
469
470 if (sc->sc_flags & SABTTYF_CONS_IN) {
471 sabtty_cons_input = sc;
472 cn_tab->cn_pollc = sab_cnpollc;
473 cn_tab->cn_getc = sab_cngetc;
474 maj = cdevsw_lookup_major(&sabtty_cdevsw);
475 cn_tab->cn_dev = makedev(maj, device_unit(self));
476 pmf_device_register1(self, NULL, NULL, sabtty_shutdown);
477 cn_init_magic(&sabtty_cnm_state);
478 cn_set_magic("\047\001"); /* default magic is BREAK */
479 }
480
481 if (sc->sc_flags & SABTTYF_CONS_OUT) {
482 sabtty_tec_wait(sc);
483 sabtty_cons_output = sc;
484 cn_tab->cn_putc = sab_cnputc;
485 maj = cdevsw_lookup_major(&sabtty_cdevsw);
486 cn_tab->cn_dev = makedev(maj, device_unit(self));
487 }
488 aprint_normal(": console %s", acc);
489 } else {
490 /* Not a console... */
491 sabtty_reset(sc);
492
493 #ifdef KGDB
494 if (is_kgdb) {
495 sab_kgdb_init(sc);
496 aprint_normal(": kgdb");
497 }
498 #endif
499 }
500
501 aprint_normal("\n");
502 aprint_naive(": Serial port\n");
503 }
504
505 int
506 sabtty_intr(struct sabtty_softc *sc, int *needsoftp)
507 {
508 uint8_t isr0, isr1;
509 int i, len = 0, needsoft = 0, r = 0, clearfifo = 0;
510
511 isr0 = SAB_READ(sc, SAB_ISR0);
512 isr1 = SAB_READ(sc, SAB_ISR1);
513
514 if (isr0 || isr1)
515 r = 1;
516
517 if (isr0 & SAB_ISR0_RPF) {
518 len = 32;
519 clearfifo = 1;
520 }
521 if (isr0 & SAB_ISR0_TCD) {
522 len = (32 - 1) & SAB_READ(sc, SAB_RBCL);
523 clearfifo = 1;
524 }
525 if (isr0 & SAB_ISR0_TIME) {
526 sabtty_cec_wait(sc);
527 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RFRD);
528 }
529 if (isr0 & SAB_ISR0_RFO) {
530 sc->sc_flags |= SABTTYF_RINGOVERFLOW;
531 clearfifo = 1;
532 }
533 if (len != 0) {
534 uint8_t *ptr, b;
535
536 ptr = sc->sc_rput;
537 for (i = 0; i < len; i++) {
538 b = SAB_READ(sc, SAB_RFIFO);
539 if (i % 2 == 0) /* skip status byte */
540 cn_check_magic(sc->sc_tty->t_dev,
541 b, sabtty_cnm_state);
542 *ptr++ = b;
543 if (ptr == sc->sc_rend)
544 ptr = sc->sc_rbuf;
545 if (ptr == sc->sc_rget) {
546 if (ptr == sc->sc_rbuf)
547 ptr = sc->sc_rend;
548 ptr--;
549 sc->sc_flags |= SABTTYF_RINGOVERFLOW;
550 }
551 }
552 sc->sc_rput = ptr;
553 needsoft = 1;
554 }
555
556 if (clearfifo) {
557 sabtty_cec_wait(sc);
558 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RMC);
559 }
560
561 if (isr0 & SAB_ISR0_CDSC) {
562 sc->sc_flags |= SABTTYF_CDCHG;
563 needsoft = 1;
564 }
565
566 if (isr1 & SAB_ISR1_BRKT)
567 cn_check_magic(sc->sc_tty->t_dev,
568 CNC_BREAK, sabtty_cnm_state);
569
570 if (isr1 & (SAB_ISR1_XPR | SAB_ISR1_ALLS)) {
571 if ((SAB_READ(sc, SAB_STAR) & SAB_STAR_XFW) &&
572 (sc->sc_flags & SABTTYF_STOP) == 0) {
573 if (sc->sc_txc < 32)
574 len = sc->sc_txc;
575 else
576 len = 32;
577
578 if (len > 0) {
579 SAB_WRITE_BLOCK(sc, SAB_XFIFO, sc->sc_txp, len);
580 sc->sc_txp += len;
581 sc->sc_txc -= len;
582
583 sabtty_cec_wait(sc);
584 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XF);
585
586 /*
587 * Prevent the false end of xmit from
588 * confusing things below.
589 */
590 isr1 &= ~SAB_ISR1_ALLS;
591 }
592 }
593
594 if ((sc->sc_txc == 0) || (sc->sc_flags & SABTTYF_STOP)) {
595 if ((sc->sc_imr1 & SAB_IMR1_XPR) == 0) {
596 sc->sc_imr1 |= SAB_IMR1_XPR;
597 sc->sc_imr1 &= ~SAB_IMR1_ALLS;
598 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
599 }
600 }
601 }
602
603 if ((isr1 & SAB_ISR1_ALLS) && ((sc->sc_txc == 0) ||
604 (sc->sc_flags & SABTTYF_STOP))) {
605 if (sc->sc_flags & SABTTYF_TXDRAIN)
606 wakeup(sc);
607 sc->sc_flags &= ~SABTTYF_STOP;
608 sc->sc_flags |= SABTTYF_DONE;
609 sc->sc_imr1 |= SAB_IMR1_ALLS;
610 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
611 needsoft = 1;
612 }
613
614 if (needsoft)
615 *needsoftp = needsoft;
616 return (r);
617 }
618
619 void
620 sabtty_softintr(struct sabtty_softc *sc)
621 {
622 struct tty *tp = sc->sc_tty;
623 int s, flags;
624 uint8_t r;
625
626 if (tp == NULL)
627 return;
628
629 if ((tp->t_state & TS_ISOPEN) == 0)
630 return;
631
632 while (sc->sc_rget != sc->sc_rput) {
633 int data;
634 uint8_t stat;
635
636 data = sc->sc_rget[0];
637 stat = sc->sc_rget[1];
638 sc->sc_rget += 2;
639 if (stat & SAB_RSTAT_PE)
640 data |= TTY_PE;
641 if (stat & SAB_RSTAT_FE)
642 data |= TTY_FE;
643 if (sc->sc_rget == sc->sc_rend)
644 sc->sc_rget = sc->sc_rbuf;
645
646 (*tp->t_linesw->l_rint)(data, tp);
647 }
648
649 s = splhigh();
650 flags = sc->sc_flags;
651 sc->sc_flags &= ~(SABTTYF_DONE|SABTTYF_CDCHG|SABTTYF_RINGOVERFLOW);
652 splx(s);
653
654 if (flags & SABTTYF_CDCHG) {
655 s = spltty();
656 r = SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD;
657 splx(s);
658
659 (*tp->t_linesw->l_modem)(tp, r);
660 }
661
662 if (flags & SABTTYF_RINGOVERFLOW)
663 log(LOG_WARNING, "%s: ring overflow\n",
664 device_xname(sc->sc_dev));
665
666 if (flags & SABTTYF_DONE) {
667 ndflush(&tp->t_outq, sc->sc_txp - tp->t_outq.c_cf);
668 tp->t_state &= ~TS_BUSY;
669 (*tp->t_linesw->l_start)(tp);
670 }
671 }
672
673 int
674 sabopen(dev_t dev, int flags, int mode, struct lwp *l)
675 {
676 struct sabtty_softc *sc;
677 struct tty *tp;
678 int s, s1;
679
680 sc = device_lookup_private(&sabtty_cd, SABUNIT(dev));
681 if (sc == NULL)
682 return (ENXIO);
683
684 tp = sc->sc_tty;
685 tp->t_dev = dev;
686
687 /*
688 * If the device is exclusively for kernel use, deny userland
689 * open.
690 */
691 if (ISSET(tp->t_state, TS_KERN_ONLY))
692 return (EBUSY);
693
694 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
695 return (EBUSY);
696
697 mutex_spin_enter(&tty_lock);
698 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
699 ttychars(tp);
700 tp->t_iflag = TTYDEF_IFLAG;
701 tp->t_oflag = TTYDEF_OFLAG;
702 tp->t_cflag = TTYDEF_CFLAG;
703 if (sc->sc_openflags & TIOCFLAG_CLOCAL)
704 tp->t_cflag |= CLOCAL;
705 if (sc->sc_openflags & TIOCFLAG_CRTSCTS)
706 tp->t_cflag |= CRTSCTS;
707 if (sc->sc_openflags & TIOCFLAG_MDMBUF)
708 tp->t_cflag |= MDMBUF;
709 tp->t_lflag = TTYDEF_LFLAG;
710 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
711
712 sc->sc_rput = sc->sc_rget = sc->sc_rbuf;
713
714 ttsetwater(tp);
715
716 s1 = splhigh();
717 sabtty_reset(sc);
718 sabtty_param(tp, &tp->t_termios);
719 sc->sc_imr0 = SAB_IMR0_PERR | SAB_IMR0_FERR | SAB_IMR0_PLLA;
720 SAB_WRITE(sc, SAB_IMR0, sc->sc_imr0);
721 sc->sc_imr1 = SAB_IMR1_BRK | SAB_IMR1_ALLS | SAB_IMR1_XDU |
722 SAB_IMR1_TIN | SAB_IMR1_CSC | SAB_IMR1_XMR | SAB_IMR1_XPR;
723 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
724 SAB_WRITE(sc, SAB_CCR0, SAB_READ(sc, SAB_CCR0) | SAB_CCR0_PU);
725 sabtty_cec_wait(sc);
726 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XRES);
727 sabtty_cec_wait(sc);
728 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES);
729 sabtty_cec_wait(sc);
730 splx(s1);
731
732 sabtty_flush(sc);
733
734 if ((sc->sc_openflags & TIOCFLAG_SOFTCAR) ||
735 (SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD))
736 tp->t_state |= TS_CARR_ON;
737 else
738 tp->t_state &= ~TS_CARR_ON;
739 }
740
741 if ((flags & O_NONBLOCK) == 0) {
742 while ((tp->t_cflag & CLOCAL) == 0 &&
743 (tp->t_state & TS_CARR_ON) == 0) {
744 int error;
745
746 error = ttysleep(tp, &tp->t_rawcv, true, 0);
747 if (error != 0) {
748 mutex_spin_exit(&tty_lock);
749 return (error);
750 }
751 }
752 }
753
754 mutex_spin_exit(&tty_lock);
755
756 s = (*tp->t_linesw->l_open)(dev, tp);
757 if (s != 0) {
758 mutex_spin_enter(&tty_lock);
759 if (tp->t_state & TS_ISOPEN) {
760 mutex_spin_exit(&tty_lock);
761 return (s);
762 }
763 if (tp->t_cflag & HUPCL) {
764 sabtty_mdmctrl(sc, 0, DMSET);
765 cv_wait(&lbolt, &tty_lock);
766 }
767
768 if ((sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) == 0) {
769 /* Flush and power down if we're not the console */
770 sabtty_flush(sc);
771 sabtty_reset(sc);
772 }
773 mutex_spin_exit(&tty_lock);
774 }
775 return (s);
776 }
777
778 int
779 sabclose(dev_t dev, int flags, int mode, struct lwp *l)
780 {
781 struct sabtty_softc *sc = device_lookup_private(&sabtty_cd, SABUNIT(dev));
782 struct sab_softc *bc = sc->sc_parent;
783 struct tty *tp = sc->sc_tty;
784 int s;
785
786 (*tp->t_linesw->l_close)(tp, flags);
787
788 s = spltty();
789
790 if ((tp->t_state & TS_ISOPEN) == 0) {
791 /* Wait for output drain */
792 sc->sc_imr1 &= ~SAB_IMR1_ALLS;
793 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
794 sc->sc_flags |= SABTTYF_TXDRAIN;
795 (void)tsleep(sc, TTIPRI, ttclos, 5 * hz);
796 sc->sc_imr1 |= SAB_IMR1_ALLS;
797 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
798 sc->sc_flags &= ~SABTTYF_TXDRAIN;
799
800 if (tp->t_cflag & HUPCL) {
801 sabtty_mdmctrl(sc, 0, DMSET);
802 (void)tsleep(bc, TTIPRI, ttclos, hz);
803 }
804
805 if ((sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) == 0) {
806 /* Flush and power down if we're not the console */
807 sabtty_flush(sc);
808 sabtty_reset(sc);
809 }
810 }
811
812 ttyclose(tp);
813 splx(s);
814
815 return (0);
816 }
817
818 int
819 sabread(dev_t dev, struct uio *uio, int flags)
820 {
821 struct sabtty_softc *sc = device_lookup_private(&sabtty_cd, SABUNIT(dev));
822 struct tty *tp = sc->sc_tty;
823
824 return ((*tp->t_linesw->l_read)(tp, uio, flags));
825 }
826
827 int
828 sabwrite(dev_t dev, struct uio *uio, int flags)
829 {
830 struct sabtty_softc *sc = device_lookup_private(&sabtty_cd, SABUNIT(dev));
831 struct tty *tp = sc->sc_tty;
832
833 return ((*tp->t_linesw->l_write)(tp, uio, flags));
834 }
835
836 int
837 sabioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
838 {
839 struct sabtty_softc *sc = device_lookup_private(&sabtty_cd, SABUNIT(dev));
840 struct tty *tp = sc->sc_tty;
841 int error;
842
843 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flags, l);
844 if (error >= 0)
845 return (error);
846
847 error = ttioctl(tp, cmd, data, flags, l);
848 if (error >= 0)
849 return (error);
850
851 error = 0;
852
853 switch (cmd) {
854 case TIOCSBRK:
855 SAB_WRITE(sc, SAB_DAFO,
856 SAB_READ(sc, SAB_DAFO) | SAB_DAFO_XBRK);
857 break;
858 case TIOCCBRK:
859 SAB_WRITE(sc, SAB_DAFO,
860 SAB_READ(sc, SAB_DAFO) & ~SAB_DAFO_XBRK);
861 break;
862 case TIOCSDTR:
863 sabtty_mdmctrl(sc, TIOCM_DTR, DMBIS);
864 break;
865 case TIOCCDTR:
866 sabtty_mdmctrl(sc, TIOCM_DTR, DMBIC);
867 break;
868 case TIOCMBIS:
869 sabtty_mdmctrl(sc, *((int *)data), DMBIS);
870 break;
871 case TIOCMBIC:
872 sabtty_mdmctrl(sc, *((int *)data), DMBIC);
873 break;
874 case TIOCMGET:
875 *((int *)data) = sabtty_mdmctrl(sc, 0, DMGET);
876 break;
877 case TIOCMSET:
878 sabtty_mdmctrl(sc, *((int *)data), DMSET);
879 break;
880 case TIOCGFLAGS:
881 *((int *)data) = sc->sc_openflags;
882 break;
883 case TIOCSFLAGS:
884 if (kauth_authorize_device_tty(l->l_cred,
885 KAUTH_DEVICE_TTY_PRIVSET, tp))
886 error = EPERM;
887 else
888 sc->sc_openflags = *((int *)data) &
889 (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL |
890 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF);
891 break;
892 default:
893 error = ENOTTY;
894 }
895
896 return (error);
897 }
898
899 struct tty *
900 sabtty(dev_t dev)
901 {
902 struct sabtty_softc *sc = device_lookup_private(&sabtty_cd, SABUNIT(dev));
903
904 return (sc->sc_tty);
905 }
906
907 void
908 sabstop(struct tty *tp, int flag)
909 {
910 struct sabtty_softc *sc = device_lookup_private(&sabtty_cd, SABUNIT(tp->t_dev));
911 int s;
912
913 s = spltty();
914 if (tp->t_state & TS_BUSY) {
915 if ((tp->t_state & TS_TTSTOP) == 0)
916 tp->t_state |= TS_FLUSH;
917 sc->sc_flags |= SABTTYF_STOP;
918 sc->sc_imr1 &= ~SAB_IMR1_ALLS;
919 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
920 }
921 splx(s);
922 }
923
924 int
925 sabpoll(dev_t dev, int events, struct lwp *l)
926 {
927 struct sabtty_softc *sc = device_lookup_private(&sabtty_cd, SABUNIT(dev));
928 struct tty *tp = sc->sc_tty;
929
930 return ((*tp->t_linesw->l_poll)(tp, events, l));
931 }
932
933 int
934 sabtty_mdmctrl(struct sabtty_softc *sc, int bits, int how)
935 {
936 uint8_t r;
937 int s;
938
939 s = spltty();
940 switch (how) {
941 case DMGET:
942 bits = 0;
943 if (SAB_READ(sc, SAB_STAR) & SAB_STAR_CTS)
944 bits |= TIOCM_CTS;
945 if ((SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD) == 0)
946 bits |= TIOCM_CD;
947
948 r = SAB_READ(sc, SAB_PVR);
949 if ((r & sc->sc_pvr_dtr) == 0)
950 bits |= TIOCM_DTR;
951 if ((r & sc->sc_pvr_dsr) == 0)
952 bits |= TIOCM_DSR;
953
954 r = SAB_READ(sc, SAB_MODE);
955 if ((r & (SAB_MODE_RTS|SAB_MODE_FRTS)) == SAB_MODE_RTS)
956 bits |= TIOCM_RTS;
957 break;
958 case DMSET:
959 r = SAB_READ(sc, SAB_MODE);
960 if (bits & TIOCM_RTS) {
961 r &= ~SAB_MODE_FRTS;
962 r |= SAB_MODE_RTS;
963 } else
964 r |= SAB_MODE_FRTS | SAB_MODE_RTS;
965 SAB_WRITE(sc, SAB_MODE, r);
966
967 r = SAB_READ(sc, SAB_PVR);
968 if (bits & TIOCM_DTR)
969 r &= ~sc->sc_pvr_dtr;
970 else
971 r |= sc->sc_pvr_dtr;
972 SAB_WRITE(sc, SAB_PVR, r);
973 break;
974 case DMBIS:
975 if (bits & TIOCM_RTS) {
976 r = SAB_READ(sc, SAB_MODE);
977 r &= ~SAB_MODE_FRTS;
978 r |= SAB_MODE_RTS;
979 SAB_WRITE(sc, SAB_MODE, r);
980 }
981 if (bits & TIOCM_DTR) {
982 r = SAB_READ(sc, SAB_PVR);
983 r &= ~sc->sc_pvr_dtr;
984 SAB_WRITE(sc, SAB_PVR, r);
985 }
986 break;
987 case DMBIC:
988 if (bits & TIOCM_RTS) {
989 r = SAB_READ(sc, SAB_MODE);
990 r |= SAB_MODE_FRTS | SAB_MODE_RTS;
991 SAB_WRITE(sc, SAB_MODE, r);
992 }
993 if (bits & TIOCM_DTR) {
994 r = SAB_READ(sc, SAB_PVR);
995 r |= sc->sc_pvr_dtr;
996 SAB_WRITE(sc, SAB_PVR, r);
997 }
998 break;
999 }
1000 splx(s);
1001 return (bits);
1002 }
1003
1004 int
1005 sabttyparam(struct sabtty_softc *sc, struct tty *tp, struct termios *t)
1006 {
1007 int s, ospeed;
1008 tcflag_t cflag;
1009 uint8_t dafo, r;
1010
1011 ospeed = sabtty_speed(t->c_ospeed);
1012 if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
1013 return (EINVAL);
1014
1015 s = spltty();
1016
1017 /* hang up line if ospeed is zero, otherwise raise dtr */
1018 sabtty_mdmctrl(sc, TIOCM_DTR,
1019 (t->c_ospeed == 0) ? DMBIC : DMBIS);
1020
1021 dafo = SAB_READ(sc, SAB_DAFO);
1022
1023 cflag = t->c_cflag;
1024
1025 if (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) {
1026 cflag |= CLOCAL;
1027 cflag &= ~HUPCL;
1028 }
1029
1030 if (cflag & CSTOPB)
1031 dafo |= SAB_DAFO_STOP;
1032 else
1033 dafo &= ~SAB_DAFO_STOP;
1034
1035 dafo &= ~SAB_DAFO_CHL_CSIZE;
1036 switch (cflag & CSIZE) {
1037 case CS5:
1038 dafo |= SAB_DAFO_CHL_CS5;
1039 break;
1040 case CS6:
1041 dafo |= SAB_DAFO_CHL_CS6;
1042 break;
1043 case CS7:
1044 dafo |= SAB_DAFO_CHL_CS7;
1045 break;
1046 default:
1047 dafo |= SAB_DAFO_CHL_CS8;
1048 break;
1049 }
1050
1051 dafo &= ~SAB_DAFO_PARMASK;
1052 if (cflag & PARENB) {
1053 if (cflag & PARODD)
1054 dafo |= SAB_DAFO_PAR_ODD;
1055 else
1056 dafo |= SAB_DAFO_PAR_EVEN;
1057 } else
1058 dafo |= SAB_DAFO_PAR_NONE;
1059 SAB_WRITE(sc, SAB_DAFO, dafo);
1060
1061 if (!(sc->sc_flags & SABTTYF_IS_RSC) && ospeed != 0) {
1062 SAB_WRITE(sc, SAB_BGR, ospeed & 0xff);
1063 r = SAB_READ(sc, SAB_CCR2);
1064 r &= ~(SAB_CCR2_BR9 | SAB_CCR2_BR8);
1065 r |= (ospeed >> 2) & (SAB_CCR2_BR9 | SAB_CCR2_BR8);
1066 SAB_WRITE(sc, SAB_CCR2, r);
1067 }
1068
1069 r = SAB_READ(sc, SAB_MODE);
1070 r |= SAB_MODE_RAC;
1071 if (cflag & CRTSCTS) {
1072 r &= ~(SAB_MODE_RTS | SAB_MODE_FCTS);
1073 r |= SAB_MODE_FRTS;
1074 sc->sc_imr1 &= ~SAB_IMR1_CSC;
1075 } else {
1076 r |= SAB_MODE_RTS | SAB_MODE_FCTS;
1077 r &= ~SAB_MODE_FRTS;
1078 sc->sc_imr1 |= SAB_IMR1_CSC;
1079 }
1080 SAB_WRITE(sc, SAB_MODE, r);
1081 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
1082
1083 tp->t_cflag = cflag;
1084
1085 splx(s);
1086 return (0);
1087 }
1088
1089 int
1090 sabtty_param(struct tty *tp, struct termios *t)
1091 {
1092 struct sabtty_softc *sc = device_lookup_private(&sabtty_cd, SABUNIT(tp->t_dev));
1093
1094 return (sabttyparam(sc, tp, t));
1095 }
1096
1097 void
1098 sabtty_start(struct tty *tp)
1099 {
1100 struct sabtty_softc *sc = device_lookup_private(&sabtty_cd, SABUNIT(tp->t_dev));
1101 int s;
1102
1103 s = spltty();
1104 if ((tp->t_state & (TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) == 0) {
1105 if (ttypull(tp)) {
1106 sc->sc_txc = ndqb(&tp->t_outq, 0);
1107 sc->sc_txp = tp->t_outq.c_cf;
1108 tp->t_state |= TS_BUSY;
1109 sc->sc_imr1 &= ~(SAB_ISR1_XPR | SAB_ISR1_ALLS);
1110 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
1111 }
1112 }
1113 splx(s);
1114 }
1115
1116 void
1117 sabtty_cec_wait(struct sabtty_softc *sc)
1118 {
1119 int i = 50000;
1120
1121 for (;;) {
1122 if ((SAB_READ(sc, SAB_STAR) & SAB_STAR_CEC) == 0)
1123 return;
1124 if (--i == 0)
1125 break;
1126 DELAY(1);
1127 }
1128 }
1129
1130 void
1131 sabtty_tec_wait(struct sabtty_softc *sc)
1132 {
1133 int i = 200000;
1134
1135 for (;;) {
1136 if ((SAB_READ(sc, SAB_STAR) & SAB_STAR_TEC) == 0)
1137 return;
1138 if (--i == 0)
1139 break;
1140 DELAY(1);
1141 }
1142 }
1143
1144 void
1145 sabtty_reset(struct sabtty_softc *sc)
1146 {
1147 /* power down */
1148 SAB_WRITE(sc, SAB_CCR0, 0);
1149
1150 /* set basic configuration */
1151 SAB_WRITE(sc, SAB_CCR0,
1152 SAB_CCR0_MCE | SAB_CCR0_SC_NRZ | SAB_CCR0_SM_ASYNC);
1153 SAB_WRITE(sc, SAB_CCR1, SAB_CCR1_ODS | SAB_CCR1_BCR | SAB_CCR1_CM_7);
1154 SAB_WRITE(sc, SAB_CCR2, SAB_CCR2_BDF | SAB_CCR2_SSEL | SAB_CCR2_TOE);
1155 SAB_WRITE(sc, SAB_CCR3, 0);
1156 SAB_WRITE(sc, SAB_CCR4, SAB_CCR4_MCK4 | SAB_CCR4_EBRG | SAB_CCR4_ICD);
1157 SAB_WRITE(sc, SAB_MODE, SAB_MODE_RTS | SAB_MODE_FCTS | SAB_MODE_RAC);
1158 SAB_WRITE(sc, SAB_RFC,
1159 SAB_RFC_DPS | SAB_RFC_RFDF | SAB_RFC_RFTH_32CHAR);
1160
1161 /* clear interrupts */
1162 sc->sc_imr0 = sc->sc_imr1 = 0xff;
1163 SAB_WRITE(sc, SAB_IMR0, sc->sc_imr0);
1164 SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1);
1165 (void)SAB_READ(sc, SAB_ISR0);
1166 (void)SAB_READ(sc, SAB_ISR1);
1167 }
1168
1169 void
1170 sabtty_flush(struct sabtty_softc *sc)
1171 {
1172 /* clear rx fifo */
1173 sabtty_cec_wait(sc);
1174 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES);
1175
1176 /* clear tx fifo */
1177 sabtty_cec_wait(sc);
1178 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XRES);
1179 }
1180
1181 int
1182 sabtty_speed(int rate)
1183 {
1184 int i, len, r;
1185
1186 if (rate == 0)
1187 return (0);
1188 len = sizeof(sabtty_baudtable)/sizeof(sabtty_baudtable[0]);
1189 for (i = 0; i < len; i++) {
1190 if (rate == sabtty_baudtable[i].baud) {
1191 r = sabtty_baudtable[i].n |
1192 (sabtty_baudtable[i].m << 6);
1193 return (r);
1194 }
1195 }
1196 return (-1);
1197 }
1198
1199 void
1200 sabtty_cnputc(struct sabtty_softc *sc, int c)
1201 {
1202 sabtty_tec_wait(sc);
1203 SAB_WRITE(sc, SAB_TIC, c);
1204 sabtty_tec_wait(sc);
1205 }
1206
1207 int
1208 sabtty_cngetc(struct sabtty_softc *sc)
1209 {
1210 uint8_t r, len;
1211
1212 again:
1213 do {
1214 r = SAB_READ(sc, SAB_STAR);
1215 } while ((r & SAB_STAR_RFNE) == 0);
1216
1217 /*
1218 * Ok, at least one byte in RFIFO, ask for permission to access RFIFO
1219 * (I hate this chip... hate hate hate).
1220 */
1221 sabtty_cec_wait(sc);
1222 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RFRD);
1223
1224 /* Wait for RFIFO to come ready */
1225 do {
1226 r = SAB_READ(sc, SAB_ISR0);
1227 } while ((r & SAB_ISR0_TCD) == 0);
1228
1229 len = SAB_READ(sc, SAB_RBCL) & (32 - 1);
1230 if (len == 0)
1231 goto again; /* Shouldn't happen... */
1232
1233 r = SAB_READ(sc, SAB_RFIFO);
1234
1235 /*
1236 * Blow away everything left in the FIFO...
1237 */
1238 sabtty_cec_wait(sc);
1239 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RMC);
1240 return (r);
1241 }
1242
1243 void
1244 sabtty_cnpollc(struct sabtty_softc *sc, int on)
1245 {
1246 uint8_t r;
1247
1248 if (on) {
1249 if (sc->sc_polling)
1250 return;
1251 SAB_WRITE(sc, SAB_IPC, SAB_READ(sc, SAB_IPC) | SAB_IPC_VIS);
1252 r = sc->sc_pollrfc = SAB_READ(sc, SAB_RFC);
1253 r &= ~(SAB_RFC_RFDF);
1254 SAB_WRITE(sc, SAB_RFC, r);
1255 sabtty_cec_wait(sc);
1256 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES);
1257 sc->sc_polling = 1;
1258 } else {
1259 if (!sc->sc_polling)
1260 return;
1261 SAB_WRITE(sc, SAB_IPC, SAB_READ(sc, SAB_IPC) & ~SAB_IPC_VIS);
1262 SAB_WRITE(sc, SAB_RFC, sc->sc_pollrfc);
1263 sabtty_cec_wait(sc);
1264 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES);
1265 sc->sc_polling = 0;
1266 }
1267 }
1268
1269 void
1270 sab_cnputc(dev_t dev, int c)
1271 {
1272 struct sabtty_softc *sc = sabtty_cons_output;
1273
1274 if (sc == NULL)
1275 return;
1276 sabtty_cnputc(sc, c);
1277 }
1278
1279 void
1280 sab_cnpollc(dev_t dev, int on)
1281 {
1282 struct sabtty_softc *sc = sabtty_cons_input;
1283
1284 sabtty_cnpollc(sc, on);
1285 }
1286
1287 int
1288 sab_cngetc(dev_t dev)
1289 {
1290 struct sabtty_softc *sc = sabtty_cons_input;
1291
1292 if (sc == NULL)
1293 return (-1);
1294 return (sabtty_cngetc(sc));
1295 }
1296
1297 void
1298 sabtty_console_flags(struct sabtty_softc *sc)
1299 {
1300 int node, channel, cookie;
1301 char buf[255];
1302
1303 node = sc->sc_parent->sc_node;
1304 channel = sc->sc_portno;
1305
1306 /* Default to channel 0 if there are no explicit prom args */
1307 cookie = 0;
1308
1309 if (node == prom_instance_to_package(prom_stdin())) {
1310 if (prom_getoption("input-device", buf, sizeof buf) == 0 &&
1311 strcmp("ttyb", buf) == 0)
1312 cookie = 1;
1313
1314 if (channel == cookie)
1315 sc->sc_flags |= SABTTYF_CONS_IN;
1316 }
1317
1318 /* Default to same channel if there are no explicit prom args */
1319
1320 if (node == prom_instance_to_package(prom_stdout())) {
1321 if (prom_getoption("output-device", buf, sizeof buf) == 0 &&
1322 strcmp("ttyb", buf) == 0)
1323 cookie = 1;
1324
1325 if (channel == cookie)
1326 sc->sc_flags |= SABTTYF_CONS_OUT;
1327 }
1328 /* Are we connected to an E250 RSC? */
1329 if (channel == prom_getpropint(node, "ssp-console", -1) ||
1330 channel == prom_getpropint(node, "ssp-control", -1))
1331 sc->sc_flags |= SABTTYF_IS_RSC;
1332 }
1333
1334 bool
1335 sabtty_shutdown(device_t dev, int how)
1336 {
1337 struct sabtty_softc *sc = device_private(dev);
1338
1339 /* Have to put the chip back into single char mode */
1340 sc->sc_flags |= SABTTYF_DONTDDB;
1341 SAB_WRITE(sc, SAB_RFC, SAB_READ(sc, SAB_RFC) & ~SAB_RFC_RFDF);
1342 sabtty_cec_wait(sc);
1343 SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES);
1344 sabtty_cec_wait(sc);
1345 return true;
1346 }
1347
1348 #ifdef KGDB
1349 static int
1350 sab_kgdb_getc(void *arg)
1351 {
1352 struct sabtty_softc *sc = arg;
1353
1354 return sabtty_cngetc(sc);
1355 }
1356
1357 static void
1358 sab_kgdb_putc(void *arg, int c)
1359 {
1360 struct sabtty_softc *sc = arg;
1361
1362 return sabtty_cnputc(sc, c);
1363 }
1364
1365 #ifndef KGDB_DEVRATE
1366 #define KGDB_DEVRATE 9600
1367 #endif
1368
1369 int
1370 sab_kgdb_check(struct sabtty_softc *sc)
1371 {
1372 return strcmp(device_xname(sc->sc_dev), KGDB_DEVNAME) == 0;
1373 }
1374
1375 void
1376 sab_kgdb_init(struct sabtty_softc *sc)
1377 {
1378 int sp;
1379 uint8_t dafo, r;
1380 extern int kgdb_break_at_attach;
1381
1382 kgdb_attach(sab_kgdb_getc, sab_kgdb_putc, sc);
1383 kgdb_dev = 123; /* not used, but checked against NODEV */
1384
1385 /*
1386 * Configure the port to speed/8n1
1387 */
1388 dafo = SAB_READ(sc, SAB_DAFO);
1389 dafo &= ~(SAB_DAFO_STOP|SAB_DAFO_CHL_CSIZE|SAB_DAFO_PARMASK);
1390 dafo |= SAB_DAFO_CHL_CS8|SAB_DAFO_PAR_NONE;
1391 SAB_WRITE(sc, SAB_DAFO, dafo);
1392 sp = sabtty_speed(KGDB_DEVRATE);
1393 SAB_WRITE(sc, SAB_BGR, sp & 0xff);
1394 r = SAB_READ(sc, SAB_CCR2);
1395 r &= ~(SAB_CCR2_BR9 | SAB_CCR2_BR8);
1396 r |= (sp >> 2) & (SAB_CCR2_BR9 | SAB_CCR2_BR8);
1397 SAB_WRITE(sc, SAB_CCR2, r);
1398
1399 /*
1400 * If we are booting with -d, break into kgdb now
1401 */
1402 if (kgdb_break_at_attach)
1403 kgdb_connect(1);
1404 }
1405 #endif
1406