1 /* $OpenBSD: pccom.c,v 1.45 2003/10/03 16:44:49 miod Exp $ */
2 /* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */
3
4 /*
5 * Copyright (c) 1997 - 1999, Jason Downs. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name(s) of the author(s) nor the name OpenBSD
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31 /*-
32 * Copyright (c) 1993, 1994, 1995, 1996
33 * Charles M. Hannum. All rights reserved.
34 * Copyright (c) 1991 The Regents of the University of California.
35 * All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * @(#)com.c 7.5 (Berkeley) 5/16/91
62 */
63
64 /*
65 * PCCOM driver, uses National Semiconductor NS16450/NS16550AF UART
66 */
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/ioctl.h>
70 #include <sys/select.h>
71 #include <sys/tty.h>
72 #include <sys/proc.h>
73 #include <sys/user.h>
74 #include <sys/conf.h>
75 #include <sys/file.h>
76 #include <sys/uio.h>
77 #include <sys/kernel.h>
78 #include <sys/syslog.h>
79 #include <sys/types.h>
80 #include <sys/device.h>
81 #include <sys/vnode.h>
82 #include <sys/timeout.h>
83
84 #include <machine/bus.h>
85 #include <machine/intr.h>
86
87 #include <dev/cons.h>
88 #include <dev/isa/isavar.h>
89 #include <dev/ic/comreg.h>
90 #include <dev/ic/ns16550reg.h>
91 #ifdef COM_HAYESP
92 #include <dev/ic/hayespreg.h>
93 #endif
94 #define com_lcr com_cfcr
95 #ifdef DDB
96 #include <ddb/db_var.h>
97 #endif
98
99 #include "pccomvar.h"
100 #include "pccom.h"
101
102 /* XXX: These belong elsewhere */
103 cdev_decl(com);
104 bdev_decl(com);
105
106 static u_char tiocm_xxx2mcr(int);
107
108 void pccom_xr16850_fifo_init(bus_space_tag_t, bus_space_handle_t);
109
110 /*
111 * XXX the following two cfattach structs should be different, and possibly
112 * XXX elsewhere.
113 */
114 int comprobe(struct device *, void *, void *);
115 void comattach(struct device *, struct device *, void *);
116 void compwroff(struct com_softc *);
117
118 #if NPCCOM_ISA
119 struct cfattach pccom_isa_ca = {
120 sizeof(struct com_softc), comprobe, comattach
121 };
122 #endif
123
124 #if NPCCOM_ISAPNP
125 struct cfattach pccom_isapnp_ca = {
126 sizeof(struct com_softc), comprobe, comattach
127 };
128 #endif
129
130 #if NPCCOM_COMMULTI
131 struct cfattach pccom_commulti_ca = {
132 sizeof(struct com_softc), comprobe, comattach
133 };
134 #endif
135
136 struct cfdriver pccom_cd = {
137 NULL, "pccom", DV_TTY
138 };
139
140 void cominit(bus_space_tag_t, bus_space_handle_t, int);
141
142 #ifndef CONSPEED
143 #define CONSPEED B9600
144 #endif
145
146 #if defined(COMCONSOLE) || defined(PCCOMCONSOLE)
147 int comdefaultrate = CONSPEED; /* XXX why set default? */
148 #else
149 int comdefaultrate = TTYDEF_SPEED;
150 #endif
151 int comconsaddr;
152 int comconsinit;
153 int comconsattached;
154 bus_space_tag_t comconsiot;
155 bus_space_handle_t comconsioh;
156 tcflag_t comconscflag = TTYDEF_CFLAG;
157
158 int commajor;
159 int comsopen = 0;
160 int comevents = 0;
161
162 #ifdef KGDB
163 #include <sys/kgdb.h>
164
165 static int com_kgdb_addr;
166 static bus_space_tag_t com_kgdb_iot;
167 static bus_space_handle_t com_kgdb_ioh;
168 static int com_kgdb_attached;
169
170 int com_kgdb_getc(void *);
171 void com_kgdb_putc(void *, int);
172 #endif /* KGDB */
173
174 #define DEVUNIT(x) (minor(x) & 0x7f)
175 #define DEVCUA(x) (minor(x) & 0x80)
176
177 /* Macros for determining bus type. */
178 #if NPCCOM_ISA || NPCCOM_PCMCIA
179 #define IS_ISA(parent) \
180 (!strcmp((parent)->dv_cfdata->cf_driver->cd_name, "isa") || \
181 !strcmp((parent)->dv_cfdata->cf_driver->cd_name, "pcmcia"))
182 #elif NPCCOM_ISA
183 #define IS_ISA(parent) \
184 !strcmp((parent)->dv_cfdata->cf_driver->cd_name, "isa")
185 #elif NPCCOM_ISAPNP
186 #define IS_ISA(parent) 0
187 #endif
188
189 #if NPCCOM_ISAPNP
190 #define IS_ISAPNP(parent) \
191 !strcmp((parent)->dv_cfdata->cf_driver->cd_name, "isapnp")
192 #else
193 #define IS_ISAPNP(parent) 0
194 #endif
195
196 int
comspeed(freq,speed)197 comspeed(freq, speed)
198 long freq;
199 long speed;
200 {
201 #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
202
203 int x, err;
204
205 if (speed == 0)
206 return 0;
207 if (speed < 0)
208 return -1;
209 x = divrnd((freq / 16), speed);
210 if (x <= 0)
211 return -1;
212 err = divrnd((freq / 16) * 1000, speed * x) - 1000;
213 if (err < 0)
214 err = -err;
215 if (err > COM_TOLERANCE)
216 return -1;
217 return x;
218
219 #undef divrnd
220 }
221
222 int
comprobe1(iot,ioh)223 comprobe1(iot, ioh)
224 bus_space_tag_t iot;
225 bus_space_handle_t ioh;
226 {
227 int i, k;
228
229 /* force access to id reg */
230 bus_space_write_1(iot, ioh, com_lcr, 0);
231 bus_space_write_1(iot, ioh, com_iir, 0);
232 for (i = 0; i < 32; i++) {
233 k = bus_space_read_1(iot, ioh, com_iir);
234 if (k & 0x38) {
235 bus_space_read_1(iot, ioh, com_data); /* cleanup */
236 } else
237 break;
238 }
239 if (i >= 32)
240 return 0;
241
242 return 1;
243 }
244
245 #ifdef COM_HAYESP
246 int
comprobeHAYESP(hayespioh,sc)247 comprobeHAYESP(hayespioh, sc)
248 bus_space_handle_t hayespioh;
249 struct com_softc *sc;
250 {
251 char val, dips;
252 int combaselist[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
253 bus_space_tag_t iot = sc->sc_iot;
254
255 /*
256 * Hayes ESP cards have two iobases. One is for compatibility with
257 * 16550 serial chips, and at the same ISA PC base addresses. The
258 * other is for ESP-specific enhanced features, and lies at a
259 * different addressing range entirely (0x140, 0x180, 0x280, or 0x300).
260 */
261
262 /* Test for ESP signature */
263 if ((bus_space_read_1(iot, hayespioh, 0) & 0xf3) == 0)
264 return 0;
265
266 /*
267 * ESP is present at ESP enhanced base address; unknown com port
268 */
269
270 /* Get the dip-switch configurations */
271 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETDIPS);
272 dips = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1);
273
274 /* Determine which com port this ESP card services: bits 0,1 of */
275 /* dips is the port # (0-3); combaselist[val] is the com_iobase */
276 if (sc->sc_iobase != combaselist[dips & 0x03])
277 return 0;
278
279 printf(": ESP");
280
281 /* Check ESP Self Test bits. */
282 /* Check for ESP version 2.0: bits 4,5,6 == 010 */
283 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETTEST);
284 val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1); /* Clear reg 1 */
285 val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS2);
286 if ((val & 0x70) < 0x20) {
287 printf("-old (%o)", val & 0x70);
288 /* we do not support the necessary features */
289 return 0;
290 }
291
292 /* Check for ability to emulate 16550: bit 8 == 1 */
293 if ((dips & 0x80) == 0) {
294 printf(" slave");
295 /* XXX Does slave really mean no 16550 support?? */
296 return 0;
297 }
298
299 /*
300 * If we made it this far, we are a full-featured ESP v2.0 (or
301 * better), at the correct com port address.
302 */
303
304 SET(sc->sc_hwflags, COM_HW_HAYESP);
305 printf(", 1024 byte fifo\n");
306 return 1;
307 }
308 #endif
309
310 int
comprobe(parent,match,aux)311 comprobe(parent, match, aux)
312 struct device *parent;
313 void *match, *aux;
314 {
315 bus_space_tag_t iot;
316 bus_space_handle_t ioh;
317 int iobase, needioh;
318 int rv = 1;
319
320 /*
321 * XXX should be broken out into functions for isa probe and
322 * XXX for commulti probe, with a helper function that contains
323 * XXX most of the interesting stuff.
324 */
325 /* #if NPCCOM_ISA || NPCCOM_PCMCIA || NPCCOM_ISAPNP */
326 #if NPCCOM_ISA || NPCCOM_ISAPNP
327 if (IS_ISA(parent) || IS_ISAPNP(parent)) {
328 struct isa_attach_args *ia = aux;
329
330 iot = ia->ia_iot;
331 iobase = ia->ia_iobase;
332 if (IS_ISAPNP(parent)) {
333 ioh = ia->ia_ioh;
334 needioh = 0;
335 } else
336 needioh = 1;
337 } else
338 #endif
339 #if NPCCOM_COMMULTI
340 if (1) {
341 struct cfdata *cf = match;
342 struct commulti_attach_args *ca = aux;
343
344 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ca->ca_slave)
345 return (0);
346
347 iot = ca->ca_iot;
348 iobase = ca->ca_iobase;
349 ioh = ca->ca_ioh;
350 needioh = 0;
351 } else
352 #endif
353 return(0); /* This cannot happen */
354
355 #ifdef KGDB
356 if (iobase == com_kgdb_addr)
357 goto out;
358 #endif /* KGDB */
359
360 /* if it's in use as console, it's there. */
361 if (iobase == comconsaddr && !comconsattached)
362 goto out;
363
364 if (needioh && bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh)) {
365 rv = 0;
366 goto out;
367 }
368 rv = comprobe1(iot, ioh);
369 if (needioh)
370 bus_space_unmap(iot, ioh, COM_NPORTS);
371
372 out:
373 /* #if NPCCOM_ISA || NPCCOM_PCMCIA */
374 #if NPCCOM_ISA
375 if (rv) {
376 struct isa_attach_args *ia = aux;
377
378 ia->ia_iosize = COM_NPORTS;
379 ia->ia_msize = 0;
380 }
381 #endif
382 return (rv);
383 }
384
385 void
comattach(parent,self,aux)386 comattach(parent, self, aux)
387 struct device *parent, *self;
388 void *aux;
389 {
390 struct com_softc *sc = (void *)self;
391 int iobase, irq;
392 bus_space_tag_t iot;
393 bus_space_handle_t ioh;
394 #ifdef COM_HAYESP
395 int hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 };
396 int *hayespp;
397 #endif
398 u_int8_t lcr;
399
400 /*
401 * XXX should be broken out into functions for isa attach and
402 * XXX for commulti attach, with a helper function that contains
403 * XXX most of the interesting stuff.
404 */
405 sc->sc_hwflags = 0;
406 sc->sc_swflags = 0;
407 /* #if NPCCOM_ISA || NPCCOM_PCMCIA || NPCCOM_ISAPNP */
408 #if NPCCOM_ISA || NPCCOM_ISAPNP
409 if (IS_ISA(parent) || IS_ISAPNP(parent)) {
410 struct isa_attach_args *ia = aux;
411
412 /*
413 * We're living on an isa.
414 */
415 iobase = ia->ia_iobase;
416 iot = ia->ia_iot;
417 if (IS_ISAPNP(parent)) {
418 /* No console support! */
419 ioh = ia->ia_ioh;
420 } else {
421 #ifdef KGDB
422 if ((iobase != comconsaddr) &&
423 (iobase != com_kgdb_addr)) {
424 #else
425 if (iobase != comconsaddr) {
426 #endif /* KGDB */
427 if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh))
428 panic("comattach: io mapping failed");
429 } else
430 #ifdef KGDB
431 if (iobase == comconsaddr) {
432 ioh = comconsioh;
433 } else {
434 ioh = com_kgdb_ioh;
435 }
436 #else
437 ioh = comconsioh;
438 #endif /* KGDB */
439 }
440 irq = ia->ia_irq;
441 } else
442 #endif
443 #if NPCCOM_COMMULTI
444 if (1) {
445 struct commulti_attach_args *ca = aux;
446
447 /*
448 * We're living on a commulti.
449 */
450 iobase = ca->ca_iobase;
451 iot = ca->ca_iot;
452 ioh = ca->ca_ioh;
453 irq = IRQUNK;
454
455 if (ca->ca_noien)
456 SET(sc->sc_hwflags, COM_HW_NOIEN);
457 } else
458 #endif
459 panic("comattach: impossible");
460
461 sc->sc_iot = iot;
462 sc->sc_ioh = ioh;
463 sc->sc_iobase = iobase;
464 sc->sc_frequency = COM_FREQ;
465
466 timeout_set(&sc->sc_dtr_tmo, com_raisedtr, sc);
467 timeout_set(&sc->sc_diag_tmo, comdiag, sc);
468
469 if (iobase == comconsaddr) {
470 comconsattached = 1;
471
472 /*
473 * Need to reset baud rate, etc. of next print so reset
474 * comconsinit. Also make sure console is always "hardwired".
475 */
476 delay(1000); /* wait for output to finish */
477 comconsinit = 0;
478 SET(sc->sc_hwflags, COM_HW_CONSOLE);
479 SET(sc->sc_swflags, COM_SW_SOFTCAR);
480 }
481
482 #ifdef COM_HAYESP
483 /* Look for a Hayes ESP board. */
484 for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) {
485 bus_space_handle_t hayespioh;
486
487 #define HAYESP_NPORTS 8 /* XXX XXX XXX ??? ??? ??? */
488 if (bus_space_map(iot, *hayespp, HAYESP_NPORTS, 0, &hayespioh))
489 continue;
490 if (comprobeHAYESP(hayespioh, sc)) {
491 sc->sc_hayespbase = *hayespp;
492 sc->sc_hayespioh = hayespioh;
493 sc->sc_fifolen = 1024;
494 break;
495 }
496 bus_space_unmap(iot, hayespioh, HAYESP_NPORTS);
497 }
498 /* No ESP; look for other things. */
499 if (*hayespp == 0) {
500 #endif
501
502 /*
503 * Probe for all known forms of UART.
504 */
505 lcr = bus_space_read_1(iot, ioh, com_lcr);
506
507 bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
508 bus_space_write_1(iot, ioh, com_efr, 0);
509 bus_space_write_1(iot, ioh, com_lcr, 0);
510
511 bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
512 delay(100);
513
514 switch(bus_space_read_1(iot, ioh, com_iir) >> 6) {
515 case 0:
516 sc->sc_uarttype = COM_UART_16450;
517 break;
518 case 2:
519 sc->sc_uarttype = COM_UART_16550;
520 break;
521 case 3:
522 sc->sc_uarttype = COM_UART_16550A;
523 break;
524 default:
525 sc->sc_uarttype = COM_UART_UNKNOWN;
526 break;
527 }
528
529 if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */
530 bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
531 if (bus_space_read_1(iot, ioh, com_efr) == 0) {
532 sc->sc_uarttype = COM_UART_ST16650;
533 } else {
534 bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
535 if (bus_space_read_1(iot, ioh, com_efr) == 0)
536 sc->sc_uarttype = COM_UART_ST16650V2;
537 }
538 }
539
540 if (sc->sc_uarttype == COM_UART_ST16650V2) { /* Probe for XR16850s */
541 u_int8_t dlbl, dlbh;
542
543 /* Enable latch access and get the current values. */
544 bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
545 dlbl = bus_space_read_1(iot, ioh, com_dlbl);
546 dlbh = bus_space_read_1(iot, ioh, com_dlbh);
547
548 /* Zero out the latch divisors */
549 bus_space_write_1(iot, ioh, com_dlbl, 0);
550 bus_space_write_1(iot, ioh, com_dlbh, 0);
551
552 if (bus_space_read_1(iot, ioh, com_dlbh) == 0x10) {
553 sc->sc_uarttype = COM_UART_XR16850;
554 sc->sc_uartrev = bus_space_read_1(iot, ioh, com_dlbl);
555 }
556
557 /* Reset to original. */
558 bus_space_write_1(iot, ioh, com_dlbl, dlbl);
559 bus_space_write_1(iot, ioh, com_dlbh, dlbh);
560 }
561
562 if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for TI16750s */
563 bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
564 bus_space_write_1(iot, ioh, com_fifo,
565 FIFO_ENABLE | FIFO_ENABLE_64BYTE);
566 if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 7) {
567 #if 0
568 bus_space_write_1(iot, ioh, com_lcr, 0);
569 if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 6)
570 #endif
571 sc->sc_uarttype = COM_UART_TI16750;
572 }
573 bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
574 }
575
576 /* Reset the LCR (latch access is probably enabled). */
577 bus_space_write_1(iot, ioh, com_lcr, lcr);
578 if (sc->sc_uarttype == COM_UART_16450) { /* Probe for 8250 */
579 u_int8_t scr0, scr1, scr2;
580
581 scr0 = bus_space_read_1(iot, ioh, com_scratch);
582 bus_space_write_1(iot, ioh, com_scratch, 0xa5);
583 scr1 = bus_space_read_1(iot, ioh, com_scratch);
584 bus_space_write_1(iot, ioh, com_scratch, 0x5a);
585 scr2 = bus_space_read_1(iot, ioh, com_scratch);
586 bus_space_write_1(iot, ioh, com_scratch, scr0);
587
588 if ((scr1 != 0xa5) || (scr2 != 0x5a))
589 sc->sc_uarttype = COM_UART_8250;
590 }
591
592 /*
593 * Print UART type and initialize ourself.
594 */
595 sc->sc_fifolen = 1; /* default */
596 switch (sc->sc_uarttype) {
597 case COM_UART_UNKNOWN:
598 printf(": unknown uart\n");
599 break;
600 case COM_UART_8250:
601 printf(": ns8250, no fifo\n");
602 break;
603 case COM_UART_16450:
604 printf(": ns16450, no fifo\n");
605 break;
606 case COM_UART_16550:
607 printf(": ns16550, no working fifo\n");
608 break;
609 case COM_UART_16550A:
610 printf(": ns16550a, 16 byte fifo\n");
611 SET(sc->sc_hwflags, COM_HW_FIFO);
612 sc->sc_fifolen = 16;
613 break;
614 case COM_UART_ST16650:
615 printf(": st16650, no working fifo\n");
616 break;
617 case COM_UART_ST16650V2:
618 printf(": st16650, 32 byte fifo\n");
619 SET(sc->sc_hwflags, COM_HW_FIFO);
620 sc->sc_fifolen = 32;
621 break;
622 case COM_UART_TI16750:
623 printf(": ti16750, 64 byte fifo\n");
624 SET(sc->sc_hwflags, COM_HW_FIFO);
625 sc->sc_fifolen = 64;
626 break;
627 case COM_UART_XR16850:
628 printf(": xr16850 (rev %d), 128 byte fifo\n", sc->sc_uartrev);
629 SET(sc->sc_hwflags, COM_HW_FIFO);
630 sc->sc_fifolen = 128;
631 break;
632 default:
633 panic("comattach: bad fifo type");
634 }
635
636 /* clear and disable fifo */
637 bus_space_write_1(iot, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST);
638 (void)bus_space_read_1(iot, ioh, com_data);
639 bus_space_write_1(iot, ioh, com_fifo, 0);
640 #ifdef COM_HAYESP
641 }
642 #endif
643
644 /* disable interrupts */
645 bus_space_write_1(iot, ioh, com_ier, 0);
646 bus_space_write_1(iot, ioh, com_mcr, 0);
647
648 if (irq != IRQUNK) {
649 /* #if NPCCOM_ISA || NPCCOM_PCMCIA || NPCCOM_ISAPNP */
650 #if NPCCOM_ISA || NPCCOM_ISAPNP
651 if (IS_ISA(parent) || IS_ISAPNP(parent)) {
652 struct isa_attach_args *ia = aux;
653
654 #ifdef KGDB
655 if (iobase == com_kgdb_addr) {
656 sc->sc_ih = isa_intr_establish(ia->ia_ic, irq,
657 IST_EDGE, IPL_HIGH, kgdbintr, sc,
658 sc->sc_dev.dv_xname);
659 } else {
660 sc->sc_ih = isa_intr_establish(ia->ia_ic, irq,
661 IST_EDGE, IPL_HIGH, comintr, sc,
662 sc->sc_dev.dv_xname);
663 }
664 #else
665 sc->sc_ih = isa_intr_establish(ia->ia_ic, irq,
666 IST_EDGE, IPL_HIGH, comintr, sc,
667 sc->sc_dev.dv_xname);
668 #endif /* KGDB */
669 } else
670 #endif
671 panic("comattach: IRQ but can't have one");
672 }
673
674 #ifdef KGDB
675 /*
676 * Allow kgdb to "take over" this port. If this is
677 * the kgdb device, it has exclusive use.
678 */
679
680 if (iot == com_kgdb_iot && iobase == com_kgdb_addr &&
681 !ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
682 printf("%s: kgdb\n", sc->sc_dev.dv_xname);
683 SET(sc->sc_hwflags, COM_HW_KGDB);
684 com_enable_debugport(sc);
685 com_kgdb_attached = 1;
686 }
687 #endif /* KGDB */
688
689 /* XXX maybe move up some? */
690 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
691 printf("%s: console\n", sc->sc_dev.dv_xname);
692
693 /*
694 * If there are no enable/disable functions, assume the device
695 * is always enabled.
696 */
697 #ifdef notyet
698 if (!sc->enable)
699 #endif
700 sc->enabled = 1;
701 }
702
703 #ifdef KGDB
704 void
com_enable_debugport(sc)705 com_enable_debugport(sc)
706 struct com_softc *sc;
707 {
708 int s;
709
710 /* Turn on line break interrupt, set carrier. */
711 s = splhigh();
712 SET(sc->sc_ier, IER_ERXRDY);
713 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
714 SET(sc->sc_mcr, MCR_DTR | MCR_RTS | MCR_IENABLE);
715 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
716
717 splx(s);
718 }
719 #endif /* KGDB */
720
721 int
com_detach(self,flags)722 com_detach(self, flags)
723 struct device *self;
724 int flags;
725 {
726 struct com_softc *sc = (struct com_softc *)self;
727 int maj, mn;
728
729 /* locate the major number */
730 for (maj = 0; maj < nchrdev; maj++)
731 if (cdevsw[maj].d_open == comopen)
732 break;
733
734 /* Nuke the vnodes for any open instances. */
735 mn = self->dv_unit;
736 vdevgone(maj, mn, mn, VCHR);
737
738 /* XXX a symbolic constant for the cua bit would be nicer. */
739 mn |= 0x80;
740 vdevgone(maj, mn, mn, VCHR);
741
742 /* Detach and free the tty. */
743 if (sc->sc_tty) {
744 ttyfree(sc->sc_tty);
745 }
746
747 timeout_del(&sc->sc_dtr_tmo);
748 timeout_del(&sc->sc_diag_tmo);
749
750 return (0);
751 }
752
753 int
com_activate(self,act)754 com_activate(self, act)
755 struct device *self;
756 enum devact act;
757 {
758 struct com_softc *sc = (struct com_softc *)self;
759 int s, rv = 0;
760
761 /* XXX splserial, when we get that. */
762 s = spltty();
763 switch (act) {
764 case DVACT_ACTIVATE:
765 rv = EOPNOTSUPP;
766 break;
767
768 case DVACT_DEACTIVATE:
769 #ifdef KGDB
770 if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB)) {
771 #else
772 if (sc->sc_hwflags & COM_HW_CONSOLE) {
773 #endif /* KGDB */
774 rv = EBUSY;
775 break;
776 }
777
778 if (sc->disable != NULL && sc->enabled != 0) {
779 (*sc->disable)(sc);
780 sc->enabled = 0;
781 }
782 break;
783 }
784 splx(s);
785 return (rv);
786 }
787
788 int
comopen(dev,flag,mode,p)789 comopen(dev, flag, mode, p)
790 dev_t dev;
791 int flag, mode;
792 struct proc *p;
793 {
794 int unit = DEVUNIT(dev);
795 struct com_softc *sc;
796 bus_space_tag_t iot;
797 bus_space_handle_t ioh;
798 struct tty *tp;
799 int s;
800 int error = 0;
801
802 if (unit >= pccom_cd.cd_ndevs)
803 return ENXIO;
804 sc = pccom_cd.cd_devs[unit];
805 if (!sc)
806 return ENXIO;
807
808 #ifdef KGDB
809 /*
810 * If this is the kgdb port, no other use is permitted.
811 */
812 if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
813 return (EBUSY);
814 #endif /* KGDB */
815
816 s = spltty();
817 if (!sc->sc_tty) {
818 tp = sc->sc_tty = ttymalloc();
819 } else
820 tp = sc->sc_tty;
821 splx(s);
822
823 tp->t_oproc = comstart;
824 tp->t_param = comparam;
825 tp->t_hwiflow = comhwiflow;
826 tp->t_dev = dev;
827 if (!ISSET(tp->t_state, TS_ISOPEN)) {
828 SET(tp->t_state, TS_WOPEN);
829 ttychars(tp);
830 tp->t_iflag = TTYDEF_IFLAG;
831 tp->t_oflag = TTYDEF_OFLAG;
832 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
833 tp->t_cflag = comconscflag;
834 else
835 tp->t_cflag = TTYDEF_CFLAG;
836 if (ISSET(sc->sc_swflags, COM_SW_CLOCAL))
837 SET(tp->t_cflag, CLOCAL);
838 if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS))
839 SET(tp->t_cflag, CRTSCTS);
840 if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
841 SET(tp->t_cflag, MDMBUF);
842 tp->t_lflag = TTYDEF_LFLAG;
843 tp->t_ispeed = tp->t_ospeed = comdefaultrate;
844
845 s = spltty();
846
847 iot = sc->sc_iot;
848 ioh = sc->sc_ioh;
849
850 /*
851 * Wake up the sleepy heads.
852 */
853 switch (sc->sc_uarttype) {
854 case COM_UART_ST16650:
855 case COM_UART_ST16650V2:
856 case COM_UART_XR16850:
857 bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
858 bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
859 bus_space_write_1(iot, ioh, com_ier, 0);
860 bus_space_write_1(iot, ioh, com_efr, 0);
861 bus_space_write_1(iot, ioh, com_lcr, 0);
862 break;
863 case COM_UART_TI16750:
864 bus_space_write_1(iot, ioh, com_ier, 0);
865 break;
866 }
867
868 sc->sc_initialize = 1;
869 comparam(tp, &tp->t_termios);
870 ttsetwater(tp);
871
872 sc->sc_rxput = sc->sc_rxget = sc->sc_tbc = 0;
873
874 #ifdef COM_HAYESP
875 /* Setup the ESP board */
876 if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
877 bus_space_handle_t hayespioh = sc->sc_hayespioh;
878
879 bus_space_write_1(iot, ioh, com_fifo,
880 FIFO_DMA_MODE|FIFO_ENABLE|
881 FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_8);
882
883 /* Set 16550 compatibility mode */
884 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETMODE);
885 bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
886 HAYESP_MODE_FIFO|HAYESP_MODE_RTS|
887 HAYESP_MODE_SCALE);
888
889 /* Set RTS/CTS flow control */
890 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETFLOWTYPE);
891 bus_space_write_1(iot, hayespioh, HAYESP_CMD2, HAYESP_FLOW_RTS);
892 bus_space_write_1(iot, hayespioh, HAYESP_CMD2, HAYESP_FLOW_CTS);
893
894 /* Set flow control levels */
895 bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_SETRXFLOW);
896 bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
897 HAYESP_HIBYTE(HAYESP_RXHIWMARK));
898 bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
899 HAYESP_LOBYTE(HAYESP_RXHIWMARK));
900 bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
901 HAYESP_HIBYTE(HAYESP_RXLOWMARK));
902 bus_space_write_1(iot, hayespioh, HAYESP_CMD2,
903 HAYESP_LOBYTE(HAYESP_RXLOWMARK));
904 } else
905 #endif
906 if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
907 u_int8_t fifo = FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST;
908 u_int8_t lcr = 0;
909
910 switch (sc->sc_uarttype) {
911 case COM_UART_ST16650V2:
912 if (tp->t_ispeed <= 1200)
913 fifo |= FIFO_RCV_TRIGGER_8|FIFO_XMT_TRIGGER_8; /* XXX */
914 else
915 fifo |= FIFO_RCV_TRIGGER_28|FIFO_XMT_TRIGGER_30;
916 break;
917 case COM_UART_XR16850:
918 pccom_xr16850_fifo_init(iot, ioh);
919 if (tp->t_ispeed <= 1200)
920 fifo |= FIFO_RCV3_TRIGGER_8|FIFO_XMT3_TRIGGER_8; /* XXX */
921 else
922 fifo |= FIFO_RCV3_TRIGGER_60|FIFO_XMT3_TRIGGER_56;
923 break;
924 case COM_UART_TI16750:
925 fifo |= FIFO_ENABLE_64BYTE;
926 lcr = bus_space_read_1(iot, ioh, com_lcr);
927 bus_space_write_1(iot, ioh, com_lcr,
928 lcr | LCR_DLAB);
929 default:
930 if (tp->t_ispeed <= 1200)
931 fifo |= FIFO_TRIGGER_1;
932 else
933 fifo |= FIFO_TRIGGER_8;
934 }
935
936 /*
937 * (Re)enable and drain FIFOs.
938 *
939 * Certain SMC chips cause problems if the FIFOs are
940 * enabled while input is ready. Turn off the FIFO
941 * if necessary to clear the input. Test the input
942 * ready bit after enabling the FIFOs to handle races
943 * between enabling and fresh input.
944 *
945 * Set the FIFO threshold based on the receive speed.
946 */
947 for (;;) {
948 bus_space_write_1(iot, ioh, com_fifo, 0);
949 delay(100);
950 (void) bus_space_read_1(iot, ioh, com_data);
951 bus_space_write_1(iot, ioh, com_fifo, fifo |
952 FIFO_RCV_RST | FIFO_XMT_RST);
953 delay(100);
954 if(!ISSET(bus_space_read_1(iot, ioh,
955 com_lsr), LSR_RXRDY))
956 break;
957 }
958 if (sc->sc_uarttype == COM_UART_TI16750)
959 bus_space_write_1(iot, ioh, com_lcr, lcr);
960 }
961
962 /* flush any pending I/O */
963 while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
964 (void) bus_space_read_1(iot, ioh, com_data);
965 /* you turn me on, baby */
966 sc->sc_mcr = MCR_DTR | MCR_RTS;
967 if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
968 SET(sc->sc_mcr, MCR_IENABLE);
969 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
970 sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
971 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
972
973 sc->sc_msr = bus_space_read_1(iot, ioh, com_msr);
974 if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || DEVCUA(dev) ||
975 ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF))
976 SET(tp->t_state, TS_CARR_ON);
977 else
978 CLR(tp->t_state, TS_CARR_ON);
979 } else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0)
980 return EBUSY;
981 else
982 s = spltty();
983
984 if (DEVCUA(dev)) {
985 if (ISSET(tp->t_state, TS_ISOPEN)) {
986 /* Ah, but someone already is dialed in... */
987 splx(s);
988 return EBUSY;
989 }
990 sc->sc_cua = 1; /* We go into CUA mode */
991 } else {
992 /* tty (not cua) device; wait for carrier if necessary */
993 if (ISSET(flag, O_NONBLOCK)) {
994 if (sc->sc_cua) {
995 /* Opening TTY non-blocking... but the CUA is busy */
996 splx(s);
997 return EBUSY;
998 }
999 } else {
1000 while (sc->sc_cua ||
1001 (!ISSET(tp->t_cflag, CLOCAL) &&
1002 !ISSET(tp->t_state, TS_CARR_ON))) {
1003 SET(tp->t_state, TS_WOPEN);
1004 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
1005 /*
1006 * If TS_WOPEN has been reset, that means the cua device
1007 * has been closed. We don't want to fail in that case,
1008 * so just go around again.
1009 */
1010 if (error && ISSET(tp->t_state, TS_WOPEN)) {
1011 CLR(tp->t_state, TS_WOPEN);
1012 if (!sc->sc_cua && !ISSET(tp->t_state, TS_ISOPEN))
1013 compwroff(sc);
1014 splx(s);
1015 return error;
1016 }
1017 }
1018 }
1019 }
1020 splx(s);
1021 return (*linesw[tp->t_line].l_open)(dev, tp);
1022 }
1023
1024 int
comclose(dev,flag,mode,p)1025 comclose(dev, flag, mode, p)
1026 dev_t dev;
1027 int flag, mode;
1028 struct proc *p;
1029 {
1030 int unit = DEVUNIT(dev);
1031 struct com_softc *sc = pccom_cd.cd_devs[unit];
1032 bus_space_tag_t iot = sc->sc_iot;
1033 bus_space_handle_t ioh = sc->sc_ioh;
1034 struct tty *tp = sc->sc_tty;
1035 int s;
1036
1037 /* XXX This is for cons.c. */
1038 if (!ISSET(tp->t_state, TS_ISOPEN))
1039 return 0;
1040
1041 (*linesw[tp->t_line].l_close)(tp, flag);
1042 s = spltty();
1043 if (ISSET(tp->t_state, TS_WOPEN)) {
1044 /* tty device is waiting for carrier; drop dtr then re-raise */
1045 CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
1046 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1047 timeout_add(&sc->sc_dtr_tmo, hz * 2);
1048 } else {
1049 /* no one else waiting; turn off the uart */
1050 compwroff(sc);
1051 }
1052 CLR(tp->t_state, TS_BUSY | TS_FLUSH);
1053 sc->sc_cua = 0;
1054 splx(s);
1055 ttyclose(tp);
1056
1057 #ifdef notyet /* XXXX */
1058 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
1059 ttyfree(tp);
1060 sc->sc_tty = 0;
1061 }
1062 #endif
1063 return 0;
1064 }
1065
1066 void
compwroff(sc)1067 compwroff(sc)
1068 struct com_softc *sc;
1069 {
1070 bus_space_tag_t iot = sc->sc_iot;
1071 bus_space_handle_t ioh = sc->sc_ioh;
1072 struct tty *tp = sc->sc_tty;
1073
1074 CLR(sc->sc_lcr, LCR_SBREAK);
1075 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
1076 bus_space_write_1(iot, ioh, com_ier, 0);
1077 if (ISSET(tp->t_cflag, HUPCL) &&
1078 !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
1079 /* XXX perhaps only clear DTR */
1080 sc->sc_mcr = 0;
1081 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1082 }
1083
1084 /*
1085 * Turn FIFO off; enter sleep mode if possible.
1086 */
1087 bus_space_write_1(iot, ioh, com_fifo, 0);
1088 delay(100);
1089 (void) bus_space_read_1(iot, ioh, com_data);
1090 delay(100);
1091 bus_space_write_1(iot, ioh, com_fifo,
1092 FIFO_RCV_RST | FIFO_XMT_RST);
1093
1094 switch (sc->sc_uarttype) {
1095 case COM_UART_ST16650:
1096 case COM_UART_ST16650V2:
1097 case COM_UART_XR16850:
1098 bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
1099 bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
1100 bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
1101 bus_space_write_1(iot, ioh, com_lcr, 0);
1102 break;
1103 case COM_UART_TI16750:
1104 bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
1105 break;
1106 }
1107 }
1108
1109 void
com_raisedtr(arg)1110 com_raisedtr(arg)
1111 void *arg;
1112 {
1113 struct com_softc *sc = arg;
1114
1115 SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
1116 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
1117 }
1118
1119 int
comread(dev,uio,flag)1120 comread(dev, uio, flag)
1121 dev_t dev;
1122 struct uio *uio;
1123 int flag;
1124 {
1125 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)];
1126 struct tty *tp = sc->sc_tty;
1127
1128 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
1129 }
1130
1131 int
comwrite(dev,uio,flag)1132 comwrite(dev, uio, flag)
1133 dev_t dev;
1134 struct uio *uio;
1135 int flag;
1136 {
1137 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)];
1138 struct tty *tp = sc->sc_tty;
1139
1140 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
1141 }
1142
1143 struct tty *
comtty(dev)1144 comtty(dev)
1145 dev_t dev;
1146 {
1147 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)];
1148 struct tty *tp = sc->sc_tty;
1149
1150 return (tp);
1151 }
1152
1153 static u_char
tiocm_xxx2mcr(data)1154 tiocm_xxx2mcr(data)
1155 int data;
1156 {
1157 u_char m = 0;
1158
1159 if (ISSET(data, TIOCM_DTR))
1160 SET(m, MCR_DTR);
1161 if (ISSET(data, TIOCM_RTS))
1162 SET(m, MCR_RTS);
1163 return m;
1164 }
1165
1166 int
comioctl(dev,cmd,data,flag,p)1167 comioctl(dev, cmd, data, flag, p)
1168 dev_t dev;
1169 u_long cmd;
1170 caddr_t data;
1171 int flag;
1172 struct proc *p;
1173 {
1174 int unit = DEVUNIT(dev);
1175 struct com_softc *sc = pccom_cd.cd_devs[unit];
1176 struct tty *tp = sc->sc_tty;
1177 bus_space_tag_t iot = sc->sc_iot;
1178 bus_space_handle_t ioh = sc->sc_ioh;
1179 int error;
1180
1181 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1182 if (error >= 0)
1183 return error;
1184 error = ttioctl(tp, cmd, data, flag, p);
1185 if (error >= 0)
1186 return error;
1187
1188 switch (cmd) {
1189 case TIOCSBRK:
1190 SET(sc->sc_lcr, LCR_SBREAK);
1191 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
1192 break;
1193 case TIOCCBRK:
1194 CLR(sc->sc_lcr, LCR_SBREAK);
1195 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
1196 break;
1197 case TIOCSDTR:
1198 SET(sc->sc_mcr, sc->sc_dtr);
1199 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1200 break;
1201 case TIOCCDTR:
1202 CLR(sc->sc_mcr, sc->sc_dtr);
1203 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1204 break;
1205 case TIOCMSET:
1206 CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
1207 case TIOCMBIS:
1208 SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
1209 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1210 break;
1211 case TIOCMBIC:
1212 CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
1213 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1214 break;
1215 case TIOCMGET: {
1216 u_char m;
1217 int bits = 0;
1218
1219 m = sc->sc_mcr;
1220 if (ISSET(m, MCR_DTR))
1221 SET(bits, TIOCM_DTR);
1222 if (ISSET(m, MCR_RTS))
1223 SET(bits, TIOCM_RTS);
1224 m = sc->sc_msr;
1225 if (ISSET(m, MSR_DCD))
1226 SET(bits, TIOCM_CD);
1227 if (ISSET(m, MSR_CTS))
1228 SET(bits, TIOCM_CTS);
1229 if (ISSET(m, MSR_DSR))
1230 SET(bits, TIOCM_DSR);
1231 if (ISSET(m, MSR_RI | MSR_TERI))
1232 SET(bits, TIOCM_RI);
1233 if (bus_space_read_1(iot, ioh, com_ier))
1234 SET(bits, TIOCM_LE);
1235 *(int *)data = bits;
1236 break;
1237 }
1238 case TIOCGFLAGS: {
1239 int driverbits, userbits = 0;
1240
1241 driverbits = sc->sc_swflags;
1242 if (ISSET(driverbits, COM_SW_SOFTCAR))
1243 SET(userbits, TIOCFLAG_SOFTCAR);
1244 if (ISSET(driverbits, COM_SW_CLOCAL))
1245 SET(userbits, TIOCFLAG_CLOCAL);
1246 if (ISSET(driverbits, COM_SW_CRTSCTS))
1247 SET(userbits, TIOCFLAG_CRTSCTS);
1248 if (ISSET(driverbits, COM_SW_MDMBUF))
1249 SET(userbits, TIOCFLAG_MDMBUF);
1250
1251 *(int *)data = userbits;
1252 break;
1253 }
1254 case TIOCSFLAGS: {
1255 int userbits, driverbits = 0;
1256
1257 error = suser(p, 0);
1258 if (error != 0)
1259 return(EPERM);
1260
1261 userbits = *(int *)data;
1262 if (ISSET(userbits, TIOCFLAG_SOFTCAR) ||
1263 ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
1264 SET(driverbits, COM_SW_SOFTCAR);
1265 if (ISSET(userbits, TIOCFLAG_CLOCAL))
1266 SET(driverbits, COM_SW_CLOCAL);
1267 if (ISSET(userbits, TIOCFLAG_CRTSCTS))
1268 SET(driverbits, COM_SW_CRTSCTS);
1269 if (ISSET(userbits, TIOCFLAG_MDMBUF))
1270 SET(driverbits, COM_SW_MDMBUF);
1271
1272 sc->sc_swflags = driverbits;
1273 break;
1274 }
1275 default:
1276 return ENOTTY;
1277 }
1278
1279 return 0;
1280 }
1281
1282 int
comparam(tp,t)1283 comparam(tp, t)
1284 struct tty *tp;
1285 struct termios *t;
1286 {
1287 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
1288 bus_space_tag_t iot = sc->sc_iot;
1289 bus_space_handle_t ioh = sc->sc_ioh;
1290 int ospeed = comspeed(sc->sc_frequency, t->c_ospeed);
1291 u_int8_t lcr;
1292 tcflag_t oldcflag;
1293 int s;
1294
1295 /* check requested parameters */
1296 if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
1297 return EINVAL;
1298
1299 lcr = ISSET(sc->sc_lcr, LCR_SBREAK);
1300
1301 switch (ISSET(t->c_cflag, CSIZE)) {
1302 case CS5:
1303 SET(lcr, LCR_5BITS);
1304 break;
1305 case CS6:
1306 SET(lcr, LCR_6BITS);
1307 break;
1308 case CS7:
1309 SET(lcr, LCR_7BITS);
1310 break;
1311 case CS8:
1312 SET(lcr, LCR_8BITS);
1313 break;
1314 }
1315 if (ISSET(t->c_cflag, PARENB)) {
1316 SET(lcr, LCR_PENAB);
1317 if (!ISSET(t->c_cflag, PARODD))
1318 SET(lcr, LCR_PEVEN);
1319 }
1320 if (ISSET(t->c_cflag, CSTOPB))
1321 SET(lcr, LCR_STOPB);
1322
1323 sc->sc_lcr = lcr;
1324
1325 s = spltty();
1326
1327 if (ospeed == 0) {
1328 CLR(sc->sc_mcr, MCR_DTR);
1329 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1330 }
1331
1332 /*
1333 * Set the FIFO threshold based on the receive speed, if we are
1334 * changing it.
1335 */
1336 if (sc->sc_initialize || (tp->t_ispeed != t->c_ispeed)) {
1337 sc->sc_initialize = 0;
1338
1339 if (ospeed != 0) {
1340 /*
1341 * Make sure the transmit FIFO is empty before
1342 * proceeding. If we don't do this, some revisions
1343 * of the UART will hang. Interestingly enough,
1344 * even if we do this while the last character is
1345 * still being pushed out, they don't hang. This
1346 * seems good enough.
1347 */
1348 while (ISSET(tp->t_state, TS_BUSY)) {
1349 int error;
1350
1351 ++sc->sc_halt;
1352 error = ttysleep(tp, &tp->t_outq,
1353 TTOPRI | PCATCH, "comprm", 0);
1354 --sc->sc_halt;
1355 if (error) {
1356 splx(s);
1357 comstart(tp);
1358 return (error);
1359 }
1360 }
1361
1362 bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
1363 bus_space_write_1(iot, ioh, com_dlbl, ospeed);
1364 bus_space_write_1(iot, ioh, com_dlbh, ospeed >> 8);
1365 bus_space_write_1(iot, ioh, com_lcr, lcr);
1366 SET(sc->sc_mcr, MCR_DTR);
1367 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1368 } else
1369 bus_space_write_1(iot, ioh, com_lcr, lcr);
1370
1371 if (!ISSET(sc->sc_hwflags, COM_HW_HAYESP) &&
1372 ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
1373 u_int8_t fifo = FIFO_ENABLE;
1374 u_int8_t lcr2 = 0;
1375
1376 switch (sc->sc_uarttype) {
1377 case COM_UART_ST16650V2:
1378 if (t->c_ispeed <= 1200)
1379 fifo |= FIFO_RCV_TRIGGER_8|FIFO_XMT_TRIGGER_8; /* XXX */
1380 else
1381 fifo |= FIFO_RCV_TRIGGER_28|FIFO_XMT_TRIGGER_30;
1382 break;
1383 case COM_UART_XR16850:
1384 if (t->c_ispeed <= 1200)
1385 fifo |= FIFO_RCV3_TRIGGER_8|FIFO_XMT3_TRIGGER_8; /* XXX */
1386 else
1387 fifo |= FIFO_RCV3_TRIGGER_60|FIFO_XMT3_TRIGGER_56;
1388 break;
1389 case COM_UART_TI16750:
1390 fifo |= FIFO_ENABLE_64BYTE;
1391 lcr2 = bus_space_read_1(iot, ioh, com_lcr);
1392 bus_space_write_1(iot, ioh, com_lcr,
1393 lcr2 | LCR_DLAB);
1394 default:
1395 if (t->c_ispeed <= 1200)
1396 fifo |= FIFO_TRIGGER_1;
1397 else
1398 fifo |= FIFO_TRIGGER_8;
1399 }
1400 bus_space_write_1(iot, ioh, com_fifo, fifo);
1401
1402 if (sc->sc_uarttype == COM_UART_TI16750)
1403 bus_space_write_1(iot, ioh, com_lcr, lcr2);
1404 }
1405 } else
1406 bus_space_write_1(iot, ioh, com_lcr, lcr);
1407
1408 /* When not using CRTSCTS, RTS follows DTR. */
1409 if (!ISSET(t->c_cflag, CRTSCTS)) {
1410 if (ISSET(sc->sc_mcr, MCR_DTR)) {
1411 if (!ISSET(sc->sc_mcr, MCR_RTS)) {
1412 SET(sc->sc_mcr, MCR_RTS);
1413 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1414 }
1415 } else {
1416 if (ISSET(sc->sc_mcr, MCR_RTS)) {
1417 CLR(sc->sc_mcr, MCR_RTS);
1418 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1419 }
1420 }
1421 sc->sc_dtr = MCR_DTR | MCR_RTS;
1422 } else
1423 sc->sc_dtr = MCR_DTR;
1424
1425 /* and copy to tty */
1426 tp->t_ispeed = t->c_ispeed;
1427 tp->t_ospeed = t->c_ospeed;
1428 oldcflag = tp->t_cflag;
1429 tp->t_cflag = t->c_cflag;
1430
1431 /*
1432 * If DCD is off and MDMBUF is changed, ask the tty layer if we should
1433 * stop the device.
1434 */
1435 if (!ISSET(sc->sc_msr, MSR_DCD) &&
1436 !ISSET(sc->sc_swflags, COM_SW_SOFTCAR) &&
1437 ISSET(oldcflag, MDMBUF) != ISSET(tp->t_cflag, MDMBUF) &&
1438 (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
1439 CLR(sc->sc_mcr, sc->sc_dtr);
1440 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1441 }
1442
1443 /* Just to be sure... */
1444 splx(s);
1445 comstart(tp);
1446 return 0;
1447 }
1448
1449 /*
1450 * (un)block input via hw flowcontrol
1451 */
1452 int
comhwiflow(tp,block)1453 comhwiflow(tp, block)
1454 struct tty *tp;
1455 int block;
1456 {
1457 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
1458 bus_space_tag_t iot = sc->sc_iot;
1459 bus_space_handle_t ioh = sc->sc_ioh;
1460 int s;
1461
1462 /*
1463 * XXX
1464 * Is spltty needed at all ? sc->sc_mcr is only in comsoft() not comintr()
1465 */
1466 s = spltty();
1467 if (block) {
1468 /* When not using CRTSCTS, RTS follows DTR. */
1469 if (ISSET(tp->t_cflag, MDMBUF)) {
1470 CLR(sc->sc_mcr, (MCR_DTR | MCR_RTS));
1471 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1472 }
1473 else {
1474 CLR(sc->sc_mcr, MCR_RTS);
1475 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1476 }
1477 }
1478 else {
1479 /* When not using CRTSCTS, RTS follows DTR. */
1480 if (ISSET(tp->t_cflag, MDMBUF)) {
1481 SET(sc->sc_mcr, (MCR_DTR | MCR_RTS));
1482 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1483 }
1484 else {
1485 SET(sc->sc_mcr, MCR_RTS);
1486 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1487 }
1488 }
1489 splx(s);
1490 return 1;
1491 }
1492
1493 void
comstart(tp)1494 comstart(tp)
1495 struct tty *tp;
1496 {
1497 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
1498 bus_space_tag_t iot = sc->sc_iot;
1499 bus_space_handle_t ioh = sc->sc_ioh;
1500 int s, count;
1501
1502 s = spltty();
1503 if (ISSET(tp->t_state, TS_BUSY))
1504 goto out;
1505 if (ISSET(tp->t_state, TS_TIMEOUT | TS_TTSTOP) || sc->sc_halt > 0)
1506 goto stopped;
1507 if (ISSET(tp->t_cflag, CRTSCTS) && !ISSET(sc->sc_msr, MSR_CTS))
1508 goto stopped;
1509 if (tp->t_outq.c_cc <= tp->t_lowat) {
1510 if (ISSET(tp->t_state, TS_ASLEEP)) {
1511 CLR(tp->t_state, TS_ASLEEP);
1512 wakeup((caddr_t)&tp->t_outq);
1513 }
1514 selwakeup(&tp->t_wsel);
1515 }
1516 count = ndqb(&tp->t_outq, 0);
1517 splhigh();
1518 if (count > 0) {
1519 int n;
1520
1521 SET(tp->t_state, TS_BUSY);
1522 if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
1523 SET(sc->sc_ier, IER_ETXRDY);
1524 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1525 }
1526 n = sc->sc_fifolen;
1527 if (n > count)
1528 n = count;
1529 sc->sc_tba = tp->t_outq.c_cf;
1530 while (--n >= 0) {
1531 bus_space_write_1(iot, ioh, com_data, *sc->sc_tba++);
1532 --count;
1533 }
1534 sc->sc_tbc = count;
1535 goto out;
1536 }
1537 stopped:
1538 if (ISSET(sc->sc_ier, IER_ETXRDY)) {
1539 CLR(sc->sc_ier, IER_ETXRDY);
1540 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1541 }
1542 out:
1543 splx(s);
1544 return;
1545 }
1546
1547 /*
1548 * Stop output on a line.
1549 */
1550 int
comstop(tp,flag)1551 comstop(tp, flag)
1552 struct tty *tp;
1553 int flag;
1554 {
1555 int s;
1556 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
1557
1558 s = splhigh();
1559 if (ISSET(tp->t_state, TS_BUSY)) {
1560 sc->sc_tbc = 0;
1561 if (!ISSET(tp->t_state, TS_TTSTOP))
1562 SET(tp->t_state, TS_FLUSH);
1563 }
1564 splx(s);
1565 return 0;
1566 }
1567
1568 void
comdiag(arg)1569 comdiag(arg)
1570 void *arg;
1571 {
1572 struct com_softc *sc = arg;
1573 int overflows;
1574 int s;
1575
1576 s = spltty();
1577 overflows = sc->sc_overflows;
1578 sc->sc_overflows = 0;
1579 splx(s);
1580
1581 if (overflows)
1582 log(LOG_WARNING, "%s: %d silo overflow%s\n",
1583 sc->sc_dev.dv_xname, overflows, overflows == 1 ? "" : "s");
1584 }
1585
1586 #ifdef PCCOM_DEBUG
1587 int maxcc = 0;
1588 #endif
1589
1590 void
comsoft()1591 comsoft()
1592 {
1593 struct com_softc *sc;
1594 struct tty *tp;
1595 struct linesw *line;
1596 int unit, s, c;
1597 u_int rxget;
1598 static int lsrmap[8] = {
1599 0, TTY_PE,
1600 TTY_FE, TTY_PE|TTY_FE,
1601 TTY_FE, TTY_PE|TTY_FE,
1602 TTY_FE, TTY_PE|TTY_FE
1603 };
1604
1605 for (unit = 0; unit < pccom_cd.cd_ndevs; unit++) {
1606 sc = pccom_cd.cd_devs[unit];
1607 if (sc == NULL)
1608 continue;
1609 tp = sc->sc_tty;
1610 /*
1611 * XXX only use (tp == NULL) ???
1612 */
1613 if (tp == NULL || !ISSET(tp->t_state, TS_ISOPEN | TS_WOPEN))
1614 continue;
1615 line = &linesw[tp->t_line];
1616 /*
1617 * XXX where do we _really_ need spltty(), if at all ???
1618 */
1619 s = spltty();
1620 rxget = sc->sc_rxget;
1621 while (rxget != sc->sc_rxput) {
1622 u_int8_t lsr;
1623
1624 lsr = sc->sc_rxbuf[rxget];
1625 rxget = (rxget + 1) & RBUFMASK;
1626 if (ISSET(lsr, LSR_RCV_MASK)) {
1627 if (ISSET(lsr, LSR_BI)) {
1628 #ifdef DDB
1629 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
1630 if (db_console)
1631 Debugger();
1632 rxget = (rxget + 1) & RBUFMASK;
1633 continue;
1634 }
1635 #endif
1636 c = 0;
1637 }
1638 else
1639 c = sc->sc_rxbuf[rxget];
1640 if (ISSET(lsr, LSR_OE)) {
1641 sc->sc_overflows++;
1642 if (sc->sc_errors++ == 0)
1643 timeout_add(&sc->sc_diag_tmo, 60 * hz);
1644 }
1645 rxget = (rxget + 1) & RBUFMASK;
1646 c |= lsrmap[(lsr & (LSR_BI|LSR_FE|LSR_PE)) >> 2];
1647 line->l_rint(c, tp);
1648 }
1649 else if (ISSET(lsr, LSR_TXRDY)) {
1650 CLR(tp->t_state, TS_BUSY);
1651 if (ISSET(tp->t_state, TS_FLUSH))
1652 CLR(tp->t_state, TS_FLUSH);
1653 else
1654 ndflush(&tp->t_outq,
1655 (int)(sc->sc_tba - tp->t_outq.c_cf));
1656 if (sc->sc_halt > 0)
1657 wakeup(&tp->t_outq);
1658 line->l_start(tp);
1659 }
1660 else if (lsr == 0) {
1661 u_int8_t msr;
1662
1663 msr = sc->sc_rxbuf[rxget];
1664 rxget = (rxget + 1) & RBUFMASK;
1665 if (ISSET(msr, MSR_DDCD) &&
1666 !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
1667 if (ISSET(msr, MSR_DCD))
1668 line->l_modem(tp, 1);
1669 else if (line->l_modem(tp, 0) == 0) {
1670 CLR(sc->sc_mcr, sc->sc_dtr);
1671 bus_space_write_1(sc->sc_iot,
1672 sc->sc_ioh,
1673 com_mcr,
1674 sc->sc_mcr);
1675 }
1676 }
1677 if (ISSET(msr, MSR_DCTS) &&
1678 ISSET(msr, MSR_CTS) &&
1679 ISSET(tp->t_cflag, CRTSCTS))
1680 line->l_start(tp);
1681 }
1682 }
1683 sc->sc_rxget = rxget;
1684 /*
1685 * XXX this is the place where we could unblock the input
1686 */
1687 splx(s);
1688 }
1689 }
1690
1691 #ifdef KGDB
1692
1693 /*
1694 * If a line break is set, or data matches one of the characters
1695 * gdb uses to signal a connection, then start up kgdb. Just gobble
1696 * any other data. Done in a stand alone function because comintr
1697 * does tty stuff and we don't have one.
1698 */
1699
1700 int
kgdbintr(arg)1701 kgdbintr(arg)
1702 void *arg;
1703 {
1704 struct com_softc *sc = arg;
1705 bus_space_tag_t iot = sc->sc_iot;
1706 bus_space_handle_t ioh = sc->sc_ioh;
1707 u_char lsr, data, msr, delta;
1708
1709 if (!ISSET(sc->sc_hwflags, COM_HW_KGDB))
1710 return(0);
1711
1712 for (;;) {
1713 lsr = bus_space_read_1(iot, ioh, com_lsr);
1714 if (ISSET(lsr, LSR_RXRDY)) {
1715 do {
1716 data = bus_space_read_1(iot, ioh, com_data);
1717 if (data == 3 || data == '$' || data == '+' ||
1718 ISSET(lsr, LSR_BI)) {
1719 kgdb_connect(1);
1720 data = 0;
1721 }
1722 lsr = bus_space_read_1(iot, ioh, com_lsr);
1723 } while (ISSET(lsr, LSR_RXRDY));
1724
1725 }
1726 if (ISSET(lsr, LSR_BI|LSR_FE|LSR_PE|LSR_OE))
1727 printf("weird lsr %02x\n", lsr);
1728
1729 msr = bus_space_read_1(iot, ioh, com_msr);
1730
1731 if (msr != sc->sc_msr) {
1732 delta = msr ^ sc->sc_msr;
1733 sc->sc_msr = msr;
1734 if (ISSET(delta, MSR_DCD)) {
1735 if (!ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
1736 CLR(sc->sc_mcr, sc->sc_dtr);
1737 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1738 }
1739 }
1740 }
1741 if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1742 return (1);
1743 }
1744 }
1745 #endif /* KGDB */
1746
1747 int
comintr(arg)1748 comintr(arg)
1749 void *arg;
1750 {
1751 struct com_softc *sc = arg;
1752 struct tty *tp = sc->sc_tty;
1753 bus_space_tag_t iot = sc->sc_iot;
1754 bus_space_handle_t ioh = sc->sc_ioh;
1755 u_int8_t lsr;
1756 u_int rxput;
1757
1758 if (!sc->sc_tty)
1759 return (0); /* can't do squat. */
1760
1761 if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1762 return (0);
1763
1764 rxput = sc->sc_rxput;
1765 do {
1766 u_int8_t msr, delta;
1767
1768 for (;;) {
1769 lsr = bus_space_read_1(iot, ioh, com_lsr);
1770 if (!ISSET(lsr, LSR_RCV_MASK))
1771 break;
1772 sc->sc_rxbuf[rxput] = lsr;
1773 rxput = (rxput + 1) & RBUFMASK;
1774 sc->sc_rxbuf[rxput] = bus_space_read_1(iot, ioh, com_data);
1775 rxput = (rxput + 1) & RBUFMASK;
1776 }
1777 msr = bus_space_read_1(iot, ioh, com_msr);
1778 delta = msr ^ sc->sc_msr;
1779 if (!ISSET(delta, MSR_DCD | MSR_CTS | MSR_RI | MSR_DSR))
1780 continue;
1781 sc->sc_msr = msr;
1782 /*
1783 * stop output straight away if CTS drops and RTS/CTS flowcontrol is used
1784 * XXX what about DTR/DCD flowcontrol (ISSET(t_cflag, MDMBUF))
1785 */
1786 msr = (msr & 0xf0) | (delta >> 4);
1787 if (ISSET(tp->t_cflag, CRTSCTS) && ISSET(msr, MSR_DCTS)) {
1788 if (!ISSET(msr, MSR_CTS))
1789 sc->sc_tbc = 0;
1790 }
1791 sc->sc_rxbuf[rxput] = 0;
1792 rxput = (rxput + 1) & RBUFMASK;
1793 sc->sc_rxbuf[rxput] = msr;
1794 rxput = (rxput + 1) & RBUFMASK;
1795 } while (!ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND));
1796 if (ISSET(lsr, LSR_TXRDY)) {
1797 if (sc->sc_tbc > 0) {
1798 int n;
1799
1800 n = sc->sc_fifolen;
1801 if (n > sc->sc_tbc)
1802 n = sc->sc_tbc;
1803 while (--n >= 0) {
1804 bus_space_write_1(iot, ioh, com_data, *sc->sc_tba++);
1805 --sc->sc_tbc;
1806 }
1807 }
1808 else if (ISSET(tp->t_state, TS_BUSY)) {
1809 sc->sc_rxbuf[rxput] = lsr;
1810 rxput = (rxput + 1) & RBUFMASK;
1811 }
1812 }
1813 if (sc->sc_rxput != rxput) {
1814 /*
1815 * XXX
1816 * This is the place to do input flow control by dropping RTS or DTR.
1817 * However, 115200 bps transfers get maxcc only up to 112 while there's
1818 * room for 512 so should we bother ?
1819 */
1820 #ifdef PCCOM_DEBUG
1821 int cc;
1822
1823 cc = rxput - sc->sc_rxget;
1824 if (cc < 0)
1825 cc += RBUFSIZE;
1826 if (cc > maxcc)
1827 maxcc = cc;
1828 #endif
1829 sc->sc_rxput = rxput;
1830 setsofttty();
1831 }
1832 return 1;
1833 }
1834
1835 void
pccom_xr16850_fifo_init(iot,ioh)1836 pccom_xr16850_fifo_init(iot, ioh)
1837 bus_space_tag_t iot;
1838 bus_space_handle_t ioh;
1839 {
1840 u_int8_t lcr, efr, fctl;
1841
1842 lcr = bus_space_read_1(iot, ioh, com_lcr);
1843 bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
1844 efr = bus_space_read_1(iot, ioh, com_efr);
1845 bus_space_write_1(iot, ioh, com_efr, efr | EFR_ECB);
1846 fctl = bus_space_read_1(iot, ioh, com_fctl);
1847 bus_space_write_1(iot, ioh, com_fctl, fctl | FCTL_TRIGGER3);
1848 bus_space_write_1(iot, ioh, com_lcr, lcr);
1849 }
1850
1851 /*
1852 * Following are all routines needed for PCCOM to act as console
1853 */
1854
1855 void
comcnprobe(cp)1856 comcnprobe(cp)
1857 struct consdev *cp;
1858 {
1859 /* XXX NEEDS TO BE FIXED XXX */
1860 bus_space_tag_t iot = 0;
1861 bus_space_handle_t ioh;
1862 int found;
1863
1864 if (bus_space_map(iot, CONADDR, COM_NPORTS, 0, &ioh)) {
1865 cp->cn_pri = CN_DEAD;
1866 return;
1867 }
1868 found = comprobe1(iot, ioh);
1869 bus_space_unmap(iot, ioh, COM_NPORTS);
1870 if (!found) {
1871 cp->cn_pri = CN_DEAD;
1872 return;
1873 }
1874
1875 /* locate the major number */
1876 for (commajor = 0; commajor < nchrdev; commajor++)
1877 if (cdevsw[commajor].d_open == comopen)
1878 break;
1879
1880 /* initialize required fields */
1881 cp->cn_dev = makedev(commajor, CONUNIT);
1882 #if defined(COMCONSOLE) || defined(PCCOMCONSOLE)
1883 cp->cn_pri = CN_REMOTE; /* Force a serial port console */
1884 #else
1885 cp->cn_pri = CN_NORMAL;
1886 #endif
1887 }
1888
1889 /*
1890 * The following functions are polled getc and putc routines, shared
1891 * by the console and kgdb glue.
1892 */
1893
1894 int
com_common_getc(iot,ioh)1895 com_common_getc(iot, ioh)
1896 bus_space_tag_t iot;
1897 bus_space_handle_t ioh;
1898 {
1899 int s = splhigh();
1900 u_char stat, c;
1901
1902 /* block until a character becomes available */
1903 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
1904 continue;
1905
1906 c = bus_space_read_1(iot, ioh, com_data);
1907 /* clear any interrupts generated by this transmission */
1908 stat = bus_space_read_1(iot, ioh, com_iir);
1909 splx(s);
1910 return (c);
1911 }
1912
1913 void
com_common_putc(iot,ioh,c)1914 com_common_putc(iot, ioh, c)
1915 bus_space_tag_t iot;
1916 bus_space_handle_t ioh;
1917 int c;
1918 {
1919 int s = splhigh();
1920 int timo;
1921
1922 /* wait for any pending transmission to finish */
1923 timo = 150000;
1924 while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
1925 continue;
1926
1927 bus_space_write_1(iot, ioh, com_data, c);
1928
1929 /* wait for this transmission to complete */
1930 timo = 1500000;
1931 while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
1932 continue;
1933
1934 splx(s);
1935 }
1936
1937 /*
1938 * Following are all routines needed for COM to act as console
1939 */
1940
1941 void
comcninit(cp)1942 comcninit(cp)
1943 struct consdev *cp;
1944 {
1945
1946 #if 0
1947 XXX NEEDS TO BE FIXED XXX
1948 comconsiot = ???;
1949 #endif
1950 comconsaddr = CONADDR;
1951
1952 if (bus_space_map(comconsiot, comconsaddr, COM_NPORTS, 0, &comconsioh))
1953 panic("comcninit: mapping failed");
1954
1955 cominit(comconsiot, comconsioh, comdefaultrate);
1956 comconsinit = 0;
1957 }
1958
1959 void
cominit(iot,ioh,rate)1960 cominit(iot, ioh, rate)
1961 bus_space_tag_t iot;
1962 bus_space_handle_t ioh;
1963 int rate;
1964 {
1965 int s = splhigh();
1966 u_int8_t stat;
1967
1968 bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB);
1969 rate = comspeed(COM_FREQ, rate); /* XXX not comdefaultrate? */
1970 bus_space_write_1(iot, ioh, com_dlbl, rate);
1971 bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
1972 bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS);
1973 bus_space_write_1(iot, ioh, com_mcr, MCR_DTR | MCR_RTS);
1974 bus_space_write_1(iot, ioh, com_ier, IER_ERXRDY | IER_ETXRDY);
1975 bus_space_write_1(iot, ioh, com_fifo,
1976 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_4);
1977 stat = bus_space_read_1(iot, ioh, com_iir);
1978 splx(s);
1979 }
1980
1981 int
comcngetc(dev)1982 comcngetc(dev)
1983 dev_t dev;
1984 {
1985 return (com_common_getc(comconsiot, comconsioh));
1986 }
1987
1988 /*
1989 * Console kernel output character routine.
1990 */
1991 void
comcnputc(dev,c)1992 comcnputc(dev, c)
1993 dev_t dev;
1994 int c;
1995 {
1996 #if 0
1997 /* XXX not needed? */
1998 bus_space_tag_t iot = comconsiot;
1999 bus_space_handle_t ioh = comconsioh;
2000
2001 if (comconsinit == 0) {
2002 cominit(iot, ioh, comdefaultrate);
2003 comconsinit = 1;
2004 }
2005 #endif
2006 com_common_putc(comconsiot, comconsioh, c);
2007 }
2008
2009 void
comcnpollc(dev,on)2010 comcnpollc(dev, on)
2011 dev_t dev;
2012 int on;
2013 {
2014
2015 }
2016
2017 #ifdef KGDB
2018 int
com_kgdb_attach(iot,iobase,rate,frequency,cflag)2019 com_kgdb_attach(iot, iobase, rate, frequency, cflag)
2020 bus_space_tag_t iot;
2021 int iobase;
2022 int rate, frequency;
2023 tcflag_t cflag;
2024 {
2025 if (iot == comconsiot && iobase == comconsaddr) {
2026 return (EBUSY); /* cannot share with console */
2027 }
2028
2029 com_kgdb_iot = iot;
2030 com_kgdb_addr = iobase;
2031
2032 if (bus_space_map(com_kgdb_iot, com_kgdb_addr, COM_NPORTS, 0,
2033 &com_kgdb_ioh))
2034 panic("com_kgdb_attach: mapping failed");
2035
2036 /* XXX We currently don't respect KGDBMODE? */
2037 cominit(com_kgdb_iot, com_kgdb_ioh, rate);
2038
2039 kgdb_attach(com_kgdb_getc, com_kgdb_putc, NULL);
2040 kgdb_dev = 123; /* unneeded, only to satisfy some tests */
2041
2042 return (0);
2043 }
2044
2045 /* ARGSUSED */
2046 int
com_kgdb_getc(arg)2047 com_kgdb_getc(arg)
2048 void *arg;
2049 {
2050
2051 return (com_common_getc(com_kgdb_iot, com_kgdb_ioh));
2052 }
2053
2054 /* ARGSUSED */
2055 void
com_kgdb_putc(arg,c)2056 com_kgdb_putc(arg, c)
2057 void *arg;
2058 int c;
2059 {
2060
2061 return (com_common_putc(com_kgdb_iot, com_kgdb_ioh, c));
2062 }
2063 #endif /* KGDB */
2064