This source file includes following definitions.
- comspeed
- comprobe1
- comprobe
- comattach
- com_detach
- com_activate
- comopen
- comclose
- compwroff
- com_raisedtr
- comread
- comwrite
- comtty
- tiocm_xxx2mcr
- comioctl
- comparam
- comhwiflow
- comstart
- comstop
- comdiag
- comsoft
- kgdbintr
- comintr
- pccom_xr16850_fifo_init
- comcnprobe
- com_common_getc
- com_common_putc
- comcninit
- cominit
- comcngetc
- comcnputc
- comcnpollc
- com_kgdb_attach
- com_kgdb_getc
- com_kgdb_putc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/ioctl.h>
70 #include <sys/selinfo.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 #define com_lcr com_cfcr
92 #ifdef DDB
93 #include <ddb/db_var.h>
94 #endif
95
96 #include "pccomvar.h"
97 #include "pccom.h"
98
99
100 cdev_decl(com);
101
102 static u_char tiocm_xxx2mcr(int);
103
104 void pccom_xr16850_fifo_init(bus_space_tag_t, bus_space_handle_t);
105
106
107
108
109
110 int comprobe(struct device *, void *, void *);
111 void comattach(struct device *, struct device *, void *);
112 void compwroff(struct com_softc *);
113
114 #if NPCCOM_ISA
115 struct cfattach pccom_isa_ca = {
116 sizeof(struct com_softc), comprobe, comattach
117 };
118 #endif
119
120 #if NPCCOM_ISAPNP
121 struct cfattach pccom_isapnp_ca = {
122 sizeof(struct com_softc), comprobe, comattach
123 };
124 #endif
125
126 #if NPCCOM_COMMULTI
127 struct cfattach pccom_commulti_ca = {
128 sizeof(struct com_softc), comprobe, comattach
129 };
130 #endif
131
132 struct cfdriver pccom_cd = {
133 NULL, "pccom", DV_TTY
134 };
135
136 void cominit(bus_space_tag_t, bus_space_handle_t, int);
137
138 #ifndef CONSPEED
139 #define CONSPEED B9600
140 #endif
141
142 #if defined(COMCONSOLE) || defined(PCCOMCONSOLE)
143 int comdefaultrate = CONSPEED;
144 #else
145 int comdefaultrate = TTYDEF_SPEED;
146 #endif
147 bus_addr_t comconsaddr;
148 int comconsinit;
149 int comconsattached;
150 bus_space_tag_t comconsiot;
151 bus_space_handle_t comconsioh;
152 tcflag_t comconscflag = TTYDEF_CFLAG;
153
154 int commajor;
155 int comsopen = 0;
156
157 #ifdef KGDB
158 #include <sys/kgdb.h>
159
160 bus_addr_t com_kgdb_addr;
161 bus_space_tag_t com_kgdb_iot;
162 bus_space_handle_t com_kgdb_ioh;
163
164 int com_kgdb_getc(void *);
165 void com_kgdb_putc(void *, int);
166 #endif
167
168 #define DEVUNIT(x) (minor(x) & 0x7f)
169 #define DEVCUA(x) (minor(x) & 0x80)
170
171
172 #if NPCCOM_ISA || NPCCOM_PCMCIA
173 #define IS_ISA(parent) \
174 (!strcmp((parent)->dv_cfdata->cf_driver->cd_name, "isa") || \
175 !strcmp((parent)->dv_cfdata->cf_driver->cd_name, "pcmcia"))
176 #elif NPCCOM_ISA
177 #define IS_ISA(parent) \
178 !strcmp((parent)->dv_cfdata->cf_driver->cd_name, "isa")
179 #elif NPCCOM_ISAPNP
180 #define IS_ISA(parent) 0
181 #endif
182
183 #if NPCCOM_ISAPNP
184 #define IS_ISAPNP(parent) \
185 !strcmp((parent)->dv_cfdata->cf_driver->cd_name, "isapnp")
186 #else
187 #define IS_ISAPNP(parent) 0
188 #endif
189
190 int
191 comspeed(long freq, long speed)
192 {
193 #define divrnd(n, q) (((n)*2/(q)+1)/2)
194
195 int x, err;
196
197 if (speed == 0)
198 return 0;
199 if (speed < 0)
200 return -1;
201 x = divrnd((freq / 16), speed);
202 if (x <= 0)
203 return -1;
204 err = divrnd((quad_t)freq * 1000 / 16, speed * x) - 1000;
205 if (err < 0)
206 err = -err;
207 if (err > COM_TOLERANCE)
208 return -1;
209 return x;
210
211 #undef divrnd
212 }
213
214 int
215 comprobe1(bus_space_tag_t iot, bus_space_handle_t ioh)
216 {
217 int i, k;
218
219
220 bus_space_write_1(iot, ioh, com_lcr, 0);
221 bus_space_write_1(iot, ioh, com_iir, 0);
222 for (i = 0; i < 32; i++) {
223 k = bus_space_read_1(iot, ioh, com_iir);
224 if (k & 0x38) {
225 bus_space_read_1(iot, ioh, com_data);
226 } else
227 break;
228 }
229 if (i >= 32)
230 return 0;
231
232 return 1;
233 }
234
235 int
236 comprobe(struct device *parent, void *match, void *aux)
237 {
238 bus_space_tag_t iot;
239 bus_space_handle_t ioh;
240 int iobase, needioh;
241 int rv = 1;
242
243
244
245
246
247
248
249 #if NPCCOM_ISA || NPCCOM_ISAPNP
250 if (IS_ISA(parent) || IS_ISAPNP(parent)) {
251 struct isa_attach_args *ia = aux;
252
253 iot = ia->ia_iot;
254 iobase = ia->ia_iobase;
255 if (IS_ISAPNP(parent)) {
256 ioh = ia->ia_ioh;
257 needioh = 0;
258 } else
259 needioh = 1;
260 } else
261 #endif
262 #if NPCCOM_COMMULTI
263 if (1) {
264 struct cfdata *cf = match;
265 struct commulti_attach_args *ca = aux;
266
267 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ca->ca_slave)
268 return (0);
269
270 iot = ca->ca_iot;
271 iobase = ca->ca_iobase;
272 ioh = ca->ca_ioh;
273 needioh = 0;
274 } else
275 #endif
276 return(0);
277
278 #ifdef KGDB
279 if (iobase == com_kgdb_addr)
280 goto out;
281 #endif
282
283
284 if (iobase == comconsaddr && !comconsattached)
285 goto out;
286
287 if (needioh && bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh)) {
288 rv = 0;
289 goto out;
290 }
291 rv = comprobe1(iot, ioh);
292 if (needioh)
293 bus_space_unmap(iot, ioh, COM_NPORTS);
294
295 out:
296
297 #if NPCCOM_ISA
298 if (rv) {
299 struct isa_attach_args *ia = aux;
300
301 ia->ia_iosize = COM_NPORTS;
302 ia->ia_msize = 0;
303 }
304 #endif
305 return (rv);
306 }
307
308 void
309 comattach(struct device *parent, struct device *self, void *aux)
310 {
311 struct com_softc *sc = (void *)self;
312 bus_addr_t iobase;
313 bus_space_tag_t iot;
314 bus_space_handle_t ioh;
315 int irq;
316
317
318
319
320
321
322
323 #if NPCCOM_ISA || NPCCOM_ISAPNP
324 if (IS_ISA(parent) || IS_ISAPNP(parent)) {
325 struct isa_attach_args *ia = aux;
326
327
328
329
330 iobase = ia->ia_iobase;
331 iot = ia->ia_iot;
332 if (IS_ISAPNP(parent)) {
333
334 ioh = ia->ia_ioh;
335 } else {
336 #ifdef KGDB
337 if ((iobase != comconsaddr) &&
338 (iobase != com_kgdb_addr)) {
339 #else
340 if (iobase != comconsaddr) {
341 #endif
342 if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh))
343 panic("comattach: io mapping failed");
344 } else
345 #ifdef KGDB
346 if (iobase == comconsaddr) {
347 ioh = comconsioh;
348 } else {
349 ioh = com_kgdb_ioh;
350 }
351 #else
352 ioh = comconsioh;
353 #endif
354 }
355 irq = ia->ia_irq;
356 } else
357 #endif
358 #if NPCCOM_COMMULTI
359 if (1) {
360 struct commulti_attach_args *ca = aux;
361
362
363
364
365 iobase = ca->ca_iobase;
366 iot = ca->ca_iot;
367 ioh = ca->ca_ioh;
368 irq = IRQUNK;
369
370 if (ca->ca_noien)
371 SET(sc->sc_hwflags, COM_HW_NOIEN);
372 } else
373 #endif
374 panic("comattach: impossible");
375
376 sc->sc_iot = iot;
377 sc->sc_ioh = ioh;
378 sc->sc_iobase = iobase;
379 sc->sc_frequency = COM_FREQ;
380
381 sc->sc_hwflags = 0;
382 sc->sc_swflags = 0;
383
384 if (irq != IRQUNK) {
385
386 bus_space_write_1(iot, ioh, com_ier, 0);
387
388
389 #if NPCCOM_ISA || NPCCOM_ISAPNP
390 if (IS_ISA(parent) || IS_ISAPNP(parent)) {
391 struct isa_attach_args *ia = aux;
392
393 #ifdef KGDB
394 if (iobase == com_kgdb_addr) {
395 sc->sc_ih = isa_intr_establish(ia->ia_ic, irq,
396 IST_EDGE, IPL_HIGH, kgdbintr, sc,
397 sc->sc_dev.dv_xname);
398 } else {
399 sc->sc_ih = isa_intr_establish(ia->ia_ic, irq,
400 IST_EDGE, IPL_HIGH, comintr, sc,
401 sc->sc_dev.dv_xname);
402 }
403 #else
404 sc->sc_ih = isa_intr_establish(ia->ia_ic, irq,
405 IST_EDGE, IPL_HIGH, comintr, sc,
406 sc->sc_dev.dv_xname);
407 #endif
408 } else
409 #endif
410 panic("comattach: IRQ but can't have one");
411 }
412
413 com_attach_subr(sc);
414 }
415
416 int
417 com_detach(struct device *self, int flags)
418 {
419 struct com_softc *sc = (struct com_softc *)self;
420 int maj, mn;
421
422
423 for (maj = 0; maj < nchrdev; maj++)
424 if (cdevsw[maj].d_open == comopen)
425 break;
426
427
428 mn = self->dv_unit;
429 vdevgone(maj, mn, mn, VCHR);
430
431
432 mn |= 0x80;
433 vdevgone(maj, mn, mn, VCHR);
434
435
436 if (sc->sc_tty) {
437 ttyfree(sc->sc_tty);
438 }
439
440 timeout_del(&sc->sc_dtr_tmo);
441 timeout_del(&sc->sc_diag_tmo);
442
443 return (0);
444 }
445
446 int
447 com_activate(struct device *self, enum devact act)
448 {
449 struct com_softc *sc = (struct com_softc *)self;
450 int s, rv = 0;
451
452
453 s = spltty();
454 switch (act) {
455 case DVACT_ACTIVATE:
456 break;
457
458 case DVACT_DEACTIVATE:
459 #ifdef KGDB
460 if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB)) {
461 #else
462 if (sc->sc_hwflags & COM_HW_CONSOLE) {
463 #endif
464 rv = EBUSY;
465 break;
466 }
467
468 if (sc->disable != NULL && sc->enabled != 0) {
469 (*sc->disable)(sc);
470 sc->enabled = 0;
471 }
472 break;
473 }
474 splx(s);
475 return (rv);
476 }
477
478 int
479 comopen(dev_t dev, int flag, int mode, struct proc *p)
480 {
481 int unit = DEVUNIT(dev);
482 struct com_softc *sc;
483 bus_space_tag_t iot;
484 bus_space_handle_t ioh;
485 struct tty *tp;
486 int s;
487 int error = 0;
488
489 if (unit >= pccom_cd.cd_ndevs)
490 return ENXIO;
491 sc = pccom_cd.cd_devs[unit];
492 if (!sc)
493 return ENXIO;
494
495 #ifdef KGDB
496
497
498
499 if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
500 return (EBUSY);
501 #endif
502
503 s = spltty();
504 if (!sc->sc_tty) {
505 tp = sc->sc_tty = ttymalloc();
506 } else
507 tp = sc->sc_tty;
508 splx(s);
509
510 tp->t_oproc = comstart;
511 tp->t_param = comparam;
512 tp->t_hwiflow = comhwiflow;
513 tp->t_dev = dev;
514 if (!ISSET(tp->t_state, TS_ISOPEN)) {
515 SET(tp->t_state, TS_WOPEN);
516 ttychars(tp);
517 tp->t_iflag = TTYDEF_IFLAG;
518 tp->t_oflag = TTYDEF_OFLAG;
519 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
520 tp->t_cflag = comconscflag;
521 else
522 tp->t_cflag = TTYDEF_CFLAG;
523 if (ISSET(sc->sc_swflags, COM_SW_CLOCAL))
524 SET(tp->t_cflag, CLOCAL);
525 if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS))
526 SET(tp->t_cflag, CRTSCTS);
527 if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
528 SET(tp->t_cflag, MDMBUF);
529 tp->t_lflag = TTYDEF_LFLAG;
530 tp->t_ispeed = tp->t_ospeed = comdefaultrate;
531
532 s = spltty();
533
534 iot = sc->sc_iot;
535 ioh = sc->sc_ioh;
536
537
538
539
540 switch (sc->sc_uarttype) {
541 case COM_UART_ST16650:
542 case COM_UART_ST16650V2:
543 case COM_UART_ST16C654:
544 case COM_UART_XR16850:
545 case COM_UART_OX16C950:
546 bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
547 bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
548 bus_space_write_1(iot, ioh, com_ier, 0);
549 bus_space_write_1(iot, ioh, com_efr, 0);
550 bus_space_write_1(iot, ioh, com_lcr, 0);
551 break;
552 case COM_UART_TI16750:
553 bus_space_write_1(iot, ioh, com_ier, 0);
554 break;
555 }
556
557 sc->sc_initialize = 1;
558 comparam(tp, &tp->t_termios);
559 ttsetwater(tp);
560
561 sc->sc_rxput = sc->sc_rxget = sc->sc_tbc = 0;
562
563 if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
564 u_int8_t fifo = FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST;
565 u_int8_t lcr;
566
567 switch (sc->sc_uarttype) {
568 case COM_UART_ST16650V2:
569 if (tp->t_ispeed <= 1200)
570 fifo |= FIFO_RCV_TRIGGER_8|FIFO_XMT_TRIGGER_8;
571 else
572 fifo |= FIFO_RCV_TRIGGER_28|FIFO_XMT_TRIGGER_30;
573 break;
574 case COM_UART_ST16C654:
575 if (tp->t_ispeed <= 1200)
576 fifo |= FIFO_RCV3_TRIGGER_8|FIFO_XMT3_TRIGGER_8;
577 else
578 fifo |= FIFO_RCV3_TRIGGER_60|FIFO_XMT3_TRIGGER_56;
579 break;
580 case COM_UART_XR16850:
581 case COM_UART_OX16C950:
582 pccom_xr16850_fifo_init(iot, ioh);
583 if (tp->t_ispeed <= 1200)
584 fifo |= FIFO_RCV3_TRIGGER_8|FIFO_XMT3_TRIGGER_8;
585 else
586 fifo |= FIFO_RCV3_TRIGGER_60|FIFO_XMT3_TRIGGER_56;
587 break;
588 case COM_UART_TI16750:
589 fifo |= FIFO_ENABLE_64BYTE;
590 lcr = bus_space_read_1(iot, ioh, com_lcr);
591 bus_space_write_1(iot, ioh, com_lcr,
592 lcr | LCR_DLAB);
593 default:
594 if (tp->t_ispeed <= 1200)
595 fifo |= FIFO_TRIGGER_1;
596 else
597 fifo |= FIFO_TRIGGER_8;
598 }
599
600
601
602
603
604
605
606
607
608
609
610
611 for (;;) {
612 bus_space_write_1(iot, ioh, com_fifo, 0);
613 delay(100);
614 (void) bus_space_read_1(iot, ioh, com_data);
615 bus_space_write_1(iot, ioh, com_fifo, fifo |
616 FIFO_RCV_RST | FIFO_XMT_RST);
617 delay(100);
618 if(!ISSET(bus_space_read_1(iot, ioh,
619 com_lsr), LSR_RXRDY))
620 break;
621 }
622 if (sc->sc_uarttype == COM_UART_TI16750)
623 bus_space_write_1(iot, ioh, com_lcr, lcr);
624 }
625
626
627 while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
628 (void) bus_space_read_1(iot, ioh, com_data);
629
630 sc->sc_mcr = MCR_DTR | MCR_RTS;
631 if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
632 SET(sc->sc_mcr, MCR_IENABLE);
633 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
634 sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
635 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
636
637 sc->sc_msr = bus_space_read_1(iot, ioh, com_msr);
638 if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || DEVCUA(dev) ||
639 ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF))
640 SET(tp->t_state, TS_CARR_ON);
641 else
642 CLR(tp->t_state, TS_CARR_ON);
643 } else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0)
644 return EBUSY;
645 else
646 s = spltty();
647
648 if (DEVCUA(dev)) {
649 if (ISSET(tp->t_state, TS_ISOPEN)) {
650
651 splx(s);
652 return EBUSY;
653 }
654 sc->sc_cua = 1;
655 } else {
656
657 if (ISSET(flag, O_NONBLOCK)) {
658 if (sc->sc_cua) {
659
660 splx(s);
661 return EBUSY;
662 }
663 } else {
664 while (sc->sc_cua ||
665 (!ISSET(tp->t_cflag, CLOCAL) &&
666 !ISSET(tp->t_state, TS_CARR_ON))) {
667 SET(tp->t_state, TS_WOPEN);
668 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
669
670
671
672
673
674 if (error && ISSET(tp->t_state, TS_WOPEN)) {
675 CLR(tp->t_state, TS_WOPEN);
676 if (!sc->sc_cua && !ISSET(tp->t_state, TS_ISOPEN))
677 compwroff(sc);
678 splx(s);
679 return error;
680 }
681 }
682 }
683 }
684 splx(s);
685 return (*linesw[tp->t_line].l_open)(dev, tp);
686 }
687
688 int
689 comclose(dev_t dev, int flag, int mode, struct proc *p)
690 {
691 int unit = DEVUNIT(dev);
692 struct com_softc *sc = pccom_cd.cd_devs[unit];
693 bus_space_tag_t iot = sc->sc_iot;
694 bus_space_handle_t ioh = sc->sc_ioh;
695 struct tty *tp = sc->sc_tty;
696 int s;
697
698
699 if (!ISSET(tp->t_state, TS_ISOPEN))
700 return 0;
701
702 (*linesw[tp->t_line].l_close)(tp, flag);
703 s = spltty();
704 if (ISSET(tp->t_state, TS_WOPEN)) {
705
706 CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
707 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
708 timeout_add(&sc->sc_dtr_tmo, hz * 2);
709 } else {
710
711 compwroff(sc);
712 }
713 CLR(tp->t_state, TS_BUSY | TS_FLUSH);
714 sc->sc_cua = 0;
715 splx(s);
716 ttyclose(tp);
717
718 #ifdef notyet
719 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
720 ttyfree(tp);
721 sc->sc_tty = 0;
722 }
723 #endif
724 return 0;
725 }
726
727 void
728 compwroff(struct com_softc *sc)
729 {
730 bus_space_tag_t iot = sc->sc_iot;
731 bus_space_handle_t ioh = sc->sc_ioh;
732 struct tty *tp = sc->sc_tty;
733
734 CLR(sc->sc_lcr, LCR_SBREAK);
735 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
736 bus_space_write_1(iot, ioh, com_ier, 0);
737 if (ISSET(tp->t_cflag, HUPCL) &&
738 !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
739
740 sc->sc_mcr = 0;
741 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
742 }
743
744
745
746
747 bus_space_write_1(iot, ioh, com_fifo, 0);
748 delay(100);
749 (void) bus_space_read_1(iot, ioh, com_data);
750 delay(100);
751 bus_space_write_1(iot, ioh, com_fifo,
752 FIFO_RCV_RST | FIFO_XMT_RST);
753
754 switch (sc->sc_uarttype) {
755 case COM_UART_ST16650:
756 case COM_UART_ST16650V2:
757 case COM_UART_ST16C654:
758 case COM_UART_XR16850:
759 case COM_UART_OX16C950:
760 bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
761 bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
762 bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
763 bus_space_write_1(iot, ioh, com_lcr, 0);
764 break;
765 case COM_UART_TI16750:
766 bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
767 break;
768 }
769 }
770
771 void
772 com_raisedtr(void *arg)
773 {
774 struct com_softc *sc = arg;
775
776 SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
777 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
778 }
779
780 int
781 comread(dev_t dev, struct uio *uio, int flag)
782 {
783 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)];
784 struct tty *tp = sc->sc_tty;
785
786 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
787 }
788
789 int
790 comwrite(dev_t dev, struct uio *uio, int flag)
791 {
792 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)];
793 struct tty *tp = sc->sc_tty;
794
795 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
796 }
797
798 struct tty *
799 comtty(dev_t dev)
800 {
801 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)];
802 struct tty *tp = sc->sc_tty;
803
804 return (tp);
805 }
806
807 static u_char
808 tiocm_xxx2mcr(int data)
809 {
810 u_char m = 0;
811
812 if (ISSET(data, TIOCM_DTR))
813 SET(m, MCR_DTR);
814 if (ISSET(data, TIOCM_RTS))
815 SET(m, MCR_RTS);
816 return m;
817 }
818
819 int
820 comioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
821 {
822 int unit = DEVUNIT(dev);
823 struct com_softc *sc = pccom_cd.cd_devs[unit];
824 struct tty *tp = sc->sc_tty;
825 bus_space_tag_t iot = sc->sc_iot;
826 bus_space_handle_t ioh = sc->sc_ioh;
827 int error;
828
829 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
830 if (error >= 0)
831 return error;
832 error = ttioctl(tp, cmd, data, flag, p);
833 if (error >= 0)
834 return error;
835
836 switch (cmd) {
837 case TIOCSBRK:
838 SET(sc->sc_lcr, LCR_SBREAK);
839 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
840 break;
841 case TIOCCBRK:
842 CLR(sc->sc_lcr, LCR_SBREAK);
843 bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
844 break;
845 case TIOCSDTR:
846 SET(sc->sc_mcr, sc->sc_dtr);
847 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
848 break;
849 case TIOCCDTR:
850 CLR(sc->sc_mcr, sc->sc_dtr);
851 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
852 break;
853 case TIOCMSET:
854 CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
855 case TIOCMBIS:
856 SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
857 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
858 break;
859 case TIOCMBIC:
860 CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
861 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
862 break;
863 case TIOCMGET: {
864 u_char m;
865 int bits = 0;
866
867 m = sc->sc_mcr;
868 if (ISSET(m, MCR_DTR))
869 SET(bits, TIOCM_DTR);
870 if (ISSET(m, MCR_RTS))
871 SET(bits, TIOCM_RTS);
872 m = sc->sc_msr;
873 if (ISSET(m, MSR_DCD))
874 SET(bits, TIOCM_CD);
875 if (ISSET(m, MSR_CTS))
876 SET(bits, TIOCM_CTS);
877 if (ISSET(m, MSR_DSR))
878 SET(bits, TIOCM_DSR);
879 if (ISSET(m, MSR_RI | MSR_TERI))
880 SET(bits, TIOCM_RI);
881 if (bus_space_read_1(iot, ioh, com_ier))
882 SET(bits, TIOCM_LE);
883 *(int *)data = bits;
884 break;
885 }
886 case TIOCGFLAGS: {
887 int driverbits, userbits = 0;
888
889 driverbits = sc->sc_swflags;
890 if (ISSET(driverbits, COM_SW_SOFTCAR))
891 SET(userbits, TIOCFLAG_SOFTCAR);
892 if (ISSET(driverbits, COM_SW_CLOCAL))
893 SET(userbits, TIOCFLAG_CLOCAL);
894 if (ISSET(driverbits, COM_SW_CRTSCTS))
895 SET(userbits, TIOCFLAG_CRTSCTS);
896 if (ISSET(driverbits, COM_SW_MDMBUF))
897 SET(userbits, TIOCFLAG_MDMBUF);
898
899 *(int *)data = userbits;
900 break;
901 }
902 case TIOCSFLAGS: {
903 int userbits, driverbits = 0;
904
905 error = suser(p, 0);
906 if (error != 0)
907 return(EPERM);
908
909 userbits = *(int *)data;
910 if (ISSET(userbits, TIOCFLAG_SOFTCAR) ||
911 ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
912 SET(driverbits, COM_SW_SOFTCAR);
913 if (ISSET(userbits, TIOCFLAG_CLOCAL))
914 SET(driverbits, COM_SW_CLOCAL);
915 if (ISSET(userbits, TIOCFLAG_CRTSCTS))
916 SET(driverbits, COM_SW_CRTSCTS);
917 if (ISSET(userbits, TIOCFLAG_MDMBUF))
918 SET(driverbits, COM_SW_MDMBUF);
919
920 sc->sc_swflags = driverbits;
921 break;
922 }
923 default:
924 return ENOTTY;
925 }
926
927 return 0;
928 }
929
930 int
931 comparam(struct tty *tp, struct termios *t)
932 {
933 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
934 bus_space_tag_t iot = sc->sc_iot;
935 bus_space_handle_t ioh = sc->sc_ioh;
936 int ospeed = comspeed(sc->sc_frequency, t->c_ospeed);
937 u_int8_t lcr;
938 tcflag_t oldcflag;
939 int s;
940
941
942 if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
943 return EINVAL;
944
945 lcr = ISSET(sc->sc_lcr, LCR_SBREAK);
946
947 switch (ISSET(t->c_cflag, CSIZE)) {
948 case CS5:
949 SET(lcr, LCR_5BITS);
950 break;
951 case CS6:
952 SET(lcr, LCR_6BITS);
953 break;
954 case CS7:
955 SET(lcr, LCR_7BITS);
956 break;
957 case CS8:
958 SET(lcr, LCR_8BITS);
959 break;
960 }
961 if (ISSET(t->c_cflag, PARENB)) {
962 SET(lcr, LCR_PENAB);
963 if (!ISSET(t->c_cflag, PARODD))
964 SET(lcr, LCR_PEVEN);
965 }
966 if (ISSET(t->c_cflag, CSTOPB))
967 SET(lcr, LCR_STOPB);
968
969 sc->sc_lcr = lcr;
970
971 s = spltty();
972
973 if (ospeed == 0) {
974 CLR(sc->sc_mcr, MCR_DTR);
975 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
976 }
977
978
979
980
981
982 if (sc->sc_initialize || (tp->t_ispeed != t->c_ispeed)) {
983 sc->sc_initialize = 0;
984
985 if (ospeed != 0) {
986
987
988
989
990
991
992
993
994 while (ISSET(tp->t_state, TS_BUSY)) {
995 int error;
996
997 ++sc->sc_halt;
998 error = ttysleep(tp, &tp->t_outq,
999 TTOPRI | PCATCH, "comprm", 0);
1000 --sc->sc_halt;
1001 if (error) {
1002 splx(s);
1003 comstart(tp);
1004 return (error);
1005 }
1006 }
1007
1008 bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
1009 bus_space_write_1(iot, ioh, com_dlbl, ospeed);
1010 bus_space_write_1(iot, ioh, com_dlbh, ospeed >> 8);
1011 bus_space_write_1(iot, ioh, com_lcr, lcr);
1012 SET(sc->sc_mcr, MCR_DTR);
1013 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1014 } else
1015 bus_space_write_1(iot, ioh, com_lcr, lcr);
1016
1017 if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
1018 u_int8_t fifo = FIFO_ENABLE;
1019 u_int8_t lcr2;
1020
1021 switch (sc->sc_uarttype) {
1022 case COM_UART_ST16650V2:
1023 if (t->c_ispeed <= 1200)
1024 fifo |= FIFO_RCV_TRIGGER_8|FIFO_XMT_TRIGGER_8;
1025 else
1026 fifo |= FIFO_RCV_TRIGGER_28|FIFO_XMT_TRIGGER_30;
1027 break;
1028 case COM_UART_ST16C654:
1029 case COM_UART_XR16850:
1030 case COM_UART_OX16C950:
1031 if (t->c_ispeed <= 1200)
1032 fifo |= FIFO_RCV3_TRIGGER_8|FIFO_XMT3_TRIGGER_8;
1033 else
1034 fifo |= FIFO_RCV3_TRIGGER_60|FIFO_XMT3_TRIGGER_56;
1035 break;
1036 case COM_UART_TI16750:
1037 fifo |= FIFO_ENABLE_64BYTE;
1038 lcr2 = bus_space_read_1(iot, ioh, com_lcr);
1039 bus_space_write_1(iot, ioh, com_lcr,
1040 lcr2 | LCR_DLAB);
1041 default:
1042 if (t->c_ispeed <= 1200)
1043 fifo |= FIFO_TRIGGER_1;
1044 else
1045 fifo |= FIFO_TRIGGER_8;
1046 }
1047 bus_space_write_1(iot, ioh, com_fifo, fifo);
1048
1049 if (sc->sc_uarttype == COM_UART_TI16750)
1050 bus_space_write_1(iot, ioh, com_lcr, lcr2);
1051 }
1052 } else
1053 bus_space_write_1(iot, ioh, com_lcr, lcr);
1054
1055
1056 if (!ISSET(t->c_cflag, CRTSCTS)) {
1057 if (ISSET(sc->sc_mcr, MCR_DTR)) {
1058 if (!ISSET(sc->sc_mcr, MCR_RTS)) {
1059 SET(sc->sc_mcr, MCR_RTS);
1060 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1061 }
1062 } else {
1063 if (ISSET(sc->sc_mcr, MCR_RTS)) {
1064 CLR(sc->sc_mcr, MCR_RTS);
1065 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1066 }
1067 }
1068 sc->sc_dtr = MCR_DTR | MCR_RTS;
1069 } else
1070 sc->sc_dtr = MCR_DTR;
1071
1072
1073 tp->t_ispeed = t->c_ispeed;
1074 tp->t_ospeed = t->c_ospeed;
1075 oldcflag = tp->t_cflag;
1076 tp->t_cflag = t->c_cflag;
1077
1078
1079
1080
1081
1082 if (!ISSET(sc->sc_msr, MSR_DCD) &&
1083 !ISSET(sc->sc_swflags, COM_SW_SOFTCAR) &&
1084 ISSET(oldcflag, MDMBUF) != ISSET(tp->t_cflag, MDMBUF) &&
1085 (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
1086 CLR(sc->sc_mcr, sc->sc_dtr);
1087 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1088 }
1089
1090
1091 splx(s);
1092 comstart(tp);
1093 return 0;
1094 }
1095
1096
1097
1098
1099 int
1100 comhwiflow(struct tty *tp, int block)
1101 {
1102 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
1103 bus_space_tag_t iot = sc->sc_iot;
1104 bus_space_handle_t ioh = sc->sc_ioh;
1105 int s;
1106
1107
1108
1109
1110
1111 s = spltty();
1112 if (block) {
1113
1114 if (ISSET(tp->t_cflag, MDMBUF)) {
1115 CLR(sc->sc_mcr, (MCR_DTR | MCR_RTS));
1116 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1117 }
1118 else {
1119 CLR(sc->sc_mcr, MCR_RTS);
1120 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1121 }
1122 }
1123 else {
1124
1125 if (ISSET(tp->t_cflag, MDMBUF)) {
1126 SET(sc->sc_mcr, (MCR_DTR | MCR_RTS));
1127 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1128 }
1129 else {
1130 SET(sc->sc_mcr, MCR_RTS);
1131 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1132 }
1133 }
1134 splx(s);
1135 return 1;
1136 }
1137
1138 void
1139 comstart(struct tty *tp)
1140 {
1141 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
1142 bus_space_tag_t iot = sc->sc_iot;
1143 bus_space_handle_t ioh = sc->sc_ioh;
1144 int s, count;
1145
1146 s = spltty();
1147 if (ISSET(tp->t_state, TS_BUSY))
1148 goto out;
1149 if (ISSET(tp->t_state, TS_TIMEOUT | TS_TTSTOP) || sc->sc_halt > 0)
1150 goto stopped;
1151 if (ISSET(tp->t_cflag, CRTSCTS) && !ISSET(sc->sc_msr, MSR_CTS))
1152 goto stopped;
1153 if (tp->t_outq.c_cc <= tp->t_lowat) {
1154 if (ISSET(tp->t_state, TS_ASLEEP)) {
1155 CLR(tp->t_state, TS_ASLEEP);
1156 wakeup((caddr_t)&tp->t_outq);
1157 }
1158 selwakeup(&tp->t_wsel);
1159 }
1160 count = ndqb(&tp->t_outq, 0);
1161 splhigh();
1162 if (count > 0) {
1163 int n;
1164
1165 SET(tp->t_state, TS_BUSY);
1166 if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
1167 SET(sc->sc_ier, IER_ETXRDY);
1168 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1169 }
1170 n = sc->sc_fifolen;
1171 if (n > count)
1172 n = count;
1173 sc->sc_tba = tp->t_outq.c_cf;
1174 while (--n >= 0) {
1175 bus_space_write_1(iot, ioh, com_data, *sc->sc_tba++);
1176 --count;
1177 }
1178 sc->sc_tbc = count;
1179 goto out;
1180 }
1181 stopped:
1182 if (ISSET(sc->sc_ier, IER_ETXRDY)) {
1183 CLR(sc->sc_ier, IER_ETXRDY);
1184 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1185 }
1186 out:
1187 splx(s);
1188 return;
1189 }
1190
1191
1192
1193
1194 int
1195 comstop(struct tty *tp, int flag)
1196 {
1197 int s;
1198 struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)];
1199
1200 s = splhigh();
1201 if (ISSET(tp->t_state, TS_BUSY)) {
1202 sc->sc_tbc = 0;
1203 if (!ISSET(tp->t_state, TS_TTSTOP))
1204 SET(tp->t_state, TS_FLUSH);
1205 }
1206 splx(s);
1207 return 0;
1208 }
1209
1210 void
1211 comdiag(void *arg)
1212 {
1213 struct com_softc *sc = arg;
1214 int overflows;
1215 int s;
1216
1217 s = spltty();
1218 overflows = sc->sc_overflows;
1219 sc->sc_overflows = 0;
1220 splx(s);
1221
1222 if (overflows)
1223 log(LOG_WARNING, "%s: %d silo overflow%s\n",
1224 sc->sc_dev.dv_xname, overflows, overflows == 1 ? "" : "s");
1225 }
1226
1227 #ifdef PCCOM_DEBUG
1228 int maxcc = 0;
1229 #endif
1230
1231 void
1232 comsoft(void)
1233 {
1234 struct com_softc *sc;
1235 struct tty *tp;
1236 struct linesw *line;
1237 int unit, s, c;
1238 u_int rxget;
1239 static int lsrmap[8] = {
1240 0, TTY_PE,
1241 TTY_FE, TTY_PE|TTY_FE,
1242 TTY_FE, TTY_PE|TTY_FE,
1243 TTY_FE, TTY_PE|TTY_FE
1244 };
1245
1246 for (unit = 0; unit < pccom_cd.cd_ndevs; unit++) {
1247 sc = pccom_cd.cd_devs[unit];
1248 if (sc == NULL)
1249 continue;
1250 tp = sc->sc_tty;
1251
1252
1253
1254 if (tp == NULL || !ISSET(tp->t_state, TS_ISOPEN | TS_WOPEN))
1255 continue;
1256 line = &linesw[tp->t_line];
1257
1258
1259
1260 s = spltty();
1261 rxget = sc->sc_rxget;
1262 while (rxget != sc->sc_rxput) {
1263 u_int8_t lsr;
1264
1265 lsr = sc->sc_rxbuf[rxget];
1266 rxget = (rxget + 1) & RBUFMASK;
1267 if (ISSET(lsr, LSR_RCV_MASK)) {
1268 c = sc->sc_rxbuf[rxget];
1269 if (ISSET(lsr, LSR_OE)) {
1270 sc->sc_overflows++;
1271 if (sc->sc_errors++ == 0)
1272 timeout_add(&sc->sc_diag_tmo, 60 * hz);
1273 }
1274 rxget = (rxget + 1) & RBUFMASK;
1275 c |= lsrmap[(lsr & (LSR_BI|LSR_FE|LSR_PE)) >> 2];
1276 line->l_rint(c, tp);
1277 }
1278 else if (ISSET(lsr, LSR_TXRDY)) {
1279 CLR(tp->t_state, TS_BUSY);
1280 if (ISSET(tp->t_state, TS_FLUSH))
1281 CLR(tp->t_state, TS_FLUSH);
1282 else
1283 ndflush(&tp->t_outq,
1284 (int)(sc->sc_tba - tp->t_outq.c_cf));
1285 if (sc->sc_halt > 0)
1286 wakeup(&tp->t_outq);
1287 line->l_start(tp);
1288 }
1289 else if (lsr == 0) {
1290 u_int8_t msr;
1291
1292 msr = sc->sc_rxbuf[rxget];
1293 rxget = (rxget + 1) & RBUFMASK;
1294 if (ISSET(msr, MSR_DDCD) &&
1295 !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
1296 if (ISSET(msr, MSR_DCD))
1297 line->l_modem(tp, 1);
1298 else if (line->l_modem(tp, 0) == 0) {
1299 CLR(sc->sc_mcr, sc->sc_dtr);
1300 bus_space_write_1(sc->sc_iot,
1301 sc->sc_ioh,
1302 com_mcr,
1303 sc->sc_mcr);
1304 }
1305 }
1306 if (ISSET(msr, MSR_DCTS) &&
1307 ISSET(msr, MSR_CTS) &&
1308 ISSET(tp->t_cflag, CRTSCTS))
1309 line->l_start(tp);
1310 }
1311 }
1312 sc->sc_rxget = rxget;
1313
1314
1315
1316 splx(s);
1317 }
1318 }
1319
1320 #ifdef KGDB
1321
1322
1323
1324
1325
1326
1327
1328
1329 int
1330 kgdbintr(void *arg)
1331 {
1332 struct com_softc *sc = arg;
1333 bus_space_tag_t iot = sc->sc_iot;
1334 bus_space_handle_t ioh = sc->sc_ioh;
1335 u_char lsr, data, msr, delta;
1336
1337 if (!ISSET(sc->sc_hwflags, COM_HW_KGDB))
1338 return(0);
1339
1340 for (;;) {
1341 lsr = bus_space_read_1(iot, ioh, com_lsr);
1342 if (ISSET(lsr, LSR_RXRDY)) {
1343 do {
1344 data = bus_space_read_1(iot, ioh, com_data);
1345 if (data == 3 || data == '$' || data == '+' ||
1346 ISSET(lsr, LSR_BI)) {
1347 kgdb_connect(1);
1348 data = 0;
1349 }
1350 lsr = bus_space_read_1(iot, ioh, com_lsr);
1351 } while (ISSET(lsr, LSR_RXRDY));
1352
1353 }
1354 if (ISSET(lsr, LSR_BI|LSR_FE|LSR_PE|LSR_OE))
1355 printf("weird lsr %02x\n", lsr);
1356
1357 msr = bus_space_read_1(iot, ioh, com_msr);
1358
1359 if (msr != sc->sc_msr) {
1360 delta = msr ^ sc->sc_msr;
1361 sc->sc_msr = msr;
1362 if (ISSET(delta, MSR_DCD)) {
1363 if (!ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
1364 CLR(sc->sc_mcr, sc->sc_dtr);
1365 bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
1366 }
1367 }
1368 }
1369 if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1370 return (1);
1371 }
1372 }
1373 #endif
1374
1375 int
1376 comintr(void *arg)
1377 {
1378 struct com_softc *sc = arg;
1379 struct tty *tp = sc->sc_tty;
1380 bus_space_tag_t iot = sc->sc_iot;
1381 bus_space_handle_t ioh = sc->sc_ioh;
1382 u_int8_t lsr, c;
1383 u_int rxput;
1384
1385 if (!sc->sc_tty)
1386 return (0);
1387
1388 if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))
1389 return (0);
1390
1391 rxput = sc->sc_rxput;
1392 do {
1393 u_int8_t msr, delta;
1394
1395 for (;;) {
1396 lsr = bus_space_read_1(iot, ioh, com_lsr);
1397 if (!ISSET(lsr, LSR_RCV_MASK))
1398 break;
1399 c = bus_space_read_1(iot, ioh, com_data);
1400 if (ISSET(lsr, LSR_BI)) {
1401 #ifdef DDB
1402 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
1403 if (db_console)
1404 Debugger();
1405 continue;
1406 }
1407 #endif
1408 c = 0;
1409 }
1410
1411 sc->sc_rxbuf[rxput] = lsr;
1412 rxput = (rxput + 1) & RBUFMASK;
1413 sc->sc_rxbuf[rxput] = c;
1414 rxput = (rxput + 1) & RBUFMASK;
1415 }
1416 msr = bus_space_read_1(iot, ioh, com_msr);
1417 delta = msr ^ sc->sc_msr;
1418
1419 ttytstamp(tp, sc->sc_msr & MSR_CTS, msr & MSR_CTS,
1420 sc->sc_msr & MSR_DCD, msr & MSR_DCD);
1421
1422 if (!ISSET(delta, MSR_DCD | MSR_CTS | MSR_RI | MSR_DSR))
1423 continue;
1424 sc->sc_msr = msr;
1425
1426
1427
1428
1429 msr = (msr & 0xf0) | (delta >> 4);
1430 if (ISSET(tp->t_cflag, CRTSCTS) && ISSET(msr, MSR_DCTS)) {
1431 if (!ISSET(msr, MSR_CTS))
1432 sc->sc_tbc = 0;
1433 }
1434 sc->sc_rxbuf[rxput] = 0;
1435 rxput = (rxput + 1) & RBUFMASK;
1436 sc->sc_rxbuf[rxput] = msr;
1437 rxput = (rxput + 1) & RBUFMASK;
1438 } while (!ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND));
1439 if (ISSET(lsr, LSR_TXRDY)) {
1440 if (sc->sc_tbc > 0) {
1441 int n;
1442
1443 n = sc->sc_fifolen;
1444 if (n > sc->sc_tbc)
1445 n = sc->sc_tbc;
1446 while (--n >= 0) {
1447 bus_space_write_1(iot, ioh, com_data, *sc->sc_tba++);
1448 --sc->sc_tbc;
1449 }
1450 }
1451 else if (ISSET(tp->t_state, TS_BUSY)) {
1452 sc->sc_rxbuf[rxput] = lsr;
1453 rxput = (rxput + 1) & RBUFMASK;
1454 }
1455 }
1456 if (sc->sc_rxput != rxput) {
1457
1458
1459
1460
1461
1462
1463 #ifdef PCCOM_DEBUG
1464 int cc;
1465
1466 cc = rxput - sc->sc_rxget;
1467 if (cc < 0)
1468 cc += RBUFSIZE;
1469 if (cc > maxcc)
1470 maxcc = cc;
1471 #endif
1472 sc->sc_rxput = rxput;
1473 setsofttty();
1474 }
1475 return 1;
1476 }
1477
1478 void
1479 pccom_xr16850_fifo_init(bus_space_tag_t iot, bus_space_handle_t ioh)
1480 {
1481 u_int8_t lcr, efr, fctl;
1482
1483 lcr = bus_space_read_1(iot, ioh, com_lcr);
1484 bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
1485 efr = bus_space_read_1(iot, ioh, com_efr);
1486 bus_space_write_1(iot, ioh, com_efr, efr | EFR_ECB);
1487 fctl = bus_space_read_1(iot, ioh, com_fctl);
1488 bus_space_write_1(iot, ioh, com_fctl, fctl | FCTL_TRIGGER3);
1489 bus_space_write_1(iot, ioh, com_lcr, lcr);
1490 }
1491
1492
1493
1494
1495
1496 void
1497 comcnprobe(struct consdev *cp)
1498 {
1499
1500 bus_space_tag_t iot = 0;
1501 bus_space_handle_t ioh;
1502 int found;
1503
1504 if (bus_space_map(iot, CONADDR, COM_NPORTS, 0, &ioh))
1505 return;
1506 found = comprobe1(iot, ioh);
1507 bus_space_unmap(iot, ioh, COM_NPORTS);
1508 if (!found)
1509 return;
1510
1511
1512 for (commajor = 0; commajor < nchrdev; commajor++)
1513 if (cdevsw[commajor].d_open == comopen)
1514 break;
1515
1516
1517 cp->cn_dev = makedev(commajor, CONUNIT);
1518 #if defined(COMCONSOLE) || defined(PCCOMCONSOLE)
1519 cp->cn_pri = CN_REMOTE;
1520 #else
1521 cp->cn_pri = CN_NORMAL;
1522 #endif
1523 }
1524
1525
1526
1527
1528
1529
1530 int
1531 com_common_getc(bus_space_tag_t iot, bus_space_handle_t ioh)
1532 {
1533 int s = splhigh();
1534 u_char stat, c;
1535
1536
1537 while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
1538 continue;
1539
1540 c = bus_space_read_1(iot, ioh, com_data);
1541
1542 stat = bus_space_read_1(iot, ioh, com_iir);
1543 splx(s);
1544 return (c);
1545 }
1546
1547 void
1548 com_common_putc(bus_space_tag_t iot, bus_space_handle_t ioh, int c)
1549 {
1550 int s = splhigh();
1551 int timo;
1552
1553
1554 timo = 150000;
1555 while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
1556 continue;
1557
1558 bus_space_write_1(iot, ioh, com_data, c);
1559
1560
1561 timo = 1500000;
1562 while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
1563 continue;
1564
1565 splx(s);
1566 }
1567
1568
1569
1570
1571
1572 void
1573 comcninit(struct consdev *cp)
1574 {
1575
1576 #if 0
1577 XXX NEEDS TO BE FIXED XXX
1578 comconsiot = ???;
1579 #endif
1580
1581 #ifdef CONADDR_OVERRIDE
1582 comconsaddr = CONADDR;
1583 #else
1584 const int comports[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
1585 int unit = minor(cp->cn_dev);
1586
1587 if (unit >= 0 && unit < 4)
1588 comconsaddr = comports[unit];
1589 else
1590 comconsaddr = CONADDR;
1591 #endif
1592
1593 if (bus_space_map(comconsiot, comconsaddr, COM_NPORTS, 0, &comconsioh))
1594 panic("comcninit: mapping failed");
1595
1596 cominit(comconsiot, comconsioh, comdefaultrate);
1597 comconsinit = 0;
1598 }
1599
1600 void
1601 cominit(bus_space_tag_t iot, bus_space_handle_t ioh, int rate)
1602 {
1603 int s = splhigh();
1604 u_int8_t stat;
1605
1606 bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB);
1607 rate = comspeed(COM_FREQ, rate);
1608 bus_space_write_1(iot, ioh, com_dlbl, rate);
1609 bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
1610 bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS);
1611 bus_space_write_1(iot, ioh, com_mcr, MCR_DTR | MCR_RTS);
1612 bus_space_write_1(iot, ioh, com_ier, IER_ERXRDY | IER_ETXRDY);
1613 bus_space_write_1(iot, ioh, com_fifo,
1614 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_4);
1615 stat = bus_space_read_1(iot, ioh, com_iir);
1616 splx(s);
1617 }
1618
1619 int
1620 comcngetc(dev_t dev)
1621 {
1622 return (com_common_getc(comconsiot, comconsioh));
1623 }
1624
1625
1626
1627
1628 void
1629 comcnputc(dev_t dev, int c)
1630 {
1631 #if 0
1632
1633 bus_space_tag_t iot = comconsiot;
1634 bus_space_handle_t ioh = comconsioh;
1635
1636 if (comconsinit == 0) {
1637 cominit(iot, ioh, comdefaultrate);
1638 comconsinit = 1;
1639 }
1640 #endif
1641 com_common_putc(comconsiot, comconsioh, c);
1642 }
1643
1644 void
1645 comcnpollc(dev_t dev, int on)
1646 {
1647
1648 }
1649
1650 #ifdef KGDB
1651 int
1652 com_kgdb_attach(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency,
1653 tcflag_t cflag)
1654 {
1655 if (iot == comconsiot && iobase == comconsaddr) {
1656 return (EBUSY);
1657 }
1658
1659 com_kgdb_iot = iot;
1660 com_kgdb_addr = iobase;
1661
1662 if (bus_space_map(com_kgdb_iot, com_kgdb_addr, COM_NPORTS, 0,
1663 &com_kgdb_ioh))
1664 panic("com_kgdb_attach: mapping failed");
1665
1666
1667 cominit(com_kgdb_iot, com_kgdb_ioh, rate);
1668
1669 kgdb_attach(com_kgdb_getc, com_kgdb_putc, NULL);
1670 kgdb_dev = 123;
1671
1672 return (0);
1673 }
1674
1675
1676 int
1677 com_kgdb_getc(void *arg)
1678 {
1679
1680 return (com_common_getc(com_kgdb_iot, com_kgdb_ioh));
1681 }
1682
1683
1684 void
1685 com_kgdb_putc(void *arg, int c)
1686 {
1687
1688 return (com_common_putc(com_kgdb_iot, com_kgdb_ioh, c));
1689 }
1690 #endif