xref: /netbsd-src/sys/arch/evbarm/dev/plcom.c (revision cd22f25e6f6d1cc1f197fe8c5468a80f51d1c4e1)
1 /*	$NetBSD: plcom.c,v 1.27 2008/04/28 20:23:16 martin Exp $	*/
2 
3 /*-
4  * Copyright (c) 2001 ARM Ltd
5  * 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. The name of the company may not be used to endorse or promote
16  *    products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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)
26  * HOWEVER 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  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
32  * All rights reserved.
33  *
34  * This code is derived from software contributed to The NetBSD Foundation
35  * by Charles M. Hannum.
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  *
46  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
47  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
48  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
50  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
51  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
52  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
53  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
54  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56  * POSSIBILITY OF SUCH DAMAGE.
57  */
58 
59 /*
60  * Copyright (c) 1991 The Regents of the University of California.
61  * All rights reserved.
62  *
63  * Redistribution and use in source and binary forms, with or without
64  * modification, are permitted provided that the following conditions
65  * are met:
66  * 1. Redistributions of source code must retain the above copyright
67  *    notice, this list of conditions and the following disclaimer.
68  * 2. Redistributions in binary form must reproduce the above copyright
69  *    notice, this list of conditions and the following disclaimer in the
70  *    documentation and/or other materials provided with the distribution.
71  * 3. Neither the name of the University nor the names of its contributors
72  *    may be used to endorse or promote products derived from this software
73  *    without specific prior written permission.
74  *
75  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
76  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
77  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
78  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
79  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
80  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
81  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
82  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
83  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
84  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85  * SUCH DAMAGE.
86  *
87  *	@(#)com.c	7.5 (Berkeley) 5/16/91
88  */
89 
90 /*
91  * COM driver for the Prime Cell PL010 UART, which is similar to the 16C550,
92  * but has a completely different programmer's model.
93  * Derived from the NS16550AF com driver.
94  */
95 
96 #include <sys/cdefs.h>
97 __KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.27 2008/04/28 20:23:16 martin Exp $");
98 
99 #include "opt_plcom.h"
100 #include "opt_ddb.h"
101 #include "opt_kgdb.h"
102 #include "opt_lockdebug.h"
103 #include "opt_multiprocessor.h"
104 
105 #include "rnd.h"
106 #if NRND > 0 && defined(RND_COM)
107 #include <sys/rnd.h>
108 #endif
109 
110 /*
111  * Override cnmagic(9) macro before including <sys/systm.h>.
112  * We need to know if cn_check_magic triggered debugger, so set a flag.
113  * Callers of cn_check_magic must declare int cn_trapped = 0;
114  * XXX: this is *ugly*!
115  */
116 #define cn_trap()				\
117 	do {					\
118 		console_debugger();		\
119 		cn_trapped = 1;			\
120 	} while (/* CONSTCOND */ 0)
121 
122 #include <sys/param.h>
123 #include <sys/systm.h>
124 #include <sys/ioctl.h>
125 #include <sys/select.h>
126 #include <sys/tty.h>
127 #include <sys/proc.h>
128 #include <sys/user.h>
129 #include <sys/conf.h>
130 #include <sys/file.h>
131 #include <sys/uio.h>
132 #include <sys/kernel.h>
133 #include <sys/syslog.h>
134 #include <sys/types.h>
135 #include <sys/device.h>
136 #include <sys/malloc.h>
137 #include <sys/timepps.h>
138 #include <sys/vnode.h>
139 #include <sys/kauth.h>
140 #include <sys/intr.h>
141 #include <sys/bus.h>
142 
143 #include <evbarm/dev/plcomreg.h>
144 #include <evbarm/dev/plcomvar.h>
145 
146 #include <dev/cons.h>
147 
148 static void plcom_enable_debugport (struct plcom_softc *);
149 
150 void	plcom_config	(struct plcom_softc *);
151 void	plcom_shutdown	(struct plcom_softc *);
152 int	plcomspeed	(long, long);
153 static	u_char	cflag2lcr (tcflag_t);
154 int	plcomparam	(struct tty *, struct termios *);
155 void	plcomstart	(struct tty *);
156 int	plcomhwiflow	(struct tty *, int);
157 
158 void	plcom_loadchannelregs (struct plcom_softc *);
159 void	plcom_hwiflow	(struct plcom_softc *);
160 void	plcom_break	(struct plcom_softc *, int);
161 void	plcom_modem	(struct plcom_softc *, int);
162 void	tiocm_to_plcom	(struct plcom_softc *, u_long, int);
163 int	plcom_to_tiocm	(struct plcom_softc *);
164 void	plcom_iflush	(struct plcom_softc *);
165 
166 int	plcom_common_getc (dev_t, bus_space_tag_t, bus_space_handle_t);
167 void	plcom_common_putc (dev_t, bus_space_tag_t, bus_space_handle_t, int);
168 
169 int	plcominit	(bus_space_tag_t, bus_addr_t, int, int, tcflag_t,
170 			    bus_space_handle_t *);
171 
172 dev_type_open(plcomopen);
173 dev_type_close(plcomclose);
174 dev_type_read(plcomread);
175 dev_type_write(plcomwrite);
176 dev_type_ioctl(plcomioctl);
177 dev_type_stop(plcomstop);
178 dev_type_tty(plcomtty);
179 dev_type_poll(plcompoll);
180 
181 int	plcomcngetc	(dev_t);
182 void	plcomcnputc	(dev_t, int);
183 void	plcomcnpollc	(dev_t, int);
184 
185 #define	integrate	static inline
186 void 	plcomsoft	(void *);
187 integrate void plcom_rxsoft	(struct plcom_softc *, struct tty *);
188 integrate void plcom_txsoft	(struct plcom_softc *, struct tty *);
189 integrate void plcom_stsoft	(struct plcom_softc *, struct tty *);
190 integrate void plcom_schedrx	(struct plcom_softc *);
191 void	plcomdiag		(void *);
192 
193 extern struct cfdriver plcom_cd;
194 
195 const struct cdevsw plcom_cdevsw = {
196 	plcomopen, plcomclose, plcomread, plcomwrite, plcomioctl,
197 	plcomstop, plcomtty, plcompoll, nommap, ttykqfilter, D_TTY
198 };
199 
200 /*
201  * Make this an option variable one can patch.
202  * But be warned:  this must be a power of 2!
203  */
204 u_int plcom_rbuf_size = PLCOM_RING_SIZE;
205 
206 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
207 u_int plcom_rbuf_hiwat = (PLCOM_RING_SIZE * 1) / 4;
208 u_int plcom_rbuf_lowat = (PLCOM_RING_SIZE * 3) / 4;
209 
210 static int	plcomconsunit = -1;
211 static bus_space_tag_t plcomconstag;
212 static bus_space_handle_t plcomconsioh;
213 static int	plcomconsattached;
214 static int plcomconsrate;
215 static tcflag_t plcomconscflag;
216 static struct cnm_state plcom_cnm_state;
217 
218 static int ppscap =
219 	PPS_TSFMT_TSPEC |
220 	PPS_CAPTUREASSERT |
221 	PPS_CAPTURECLEAR |
222 #ifdef  PPS_SYNC
223 	PPS_HARDPPSONASSERT | PPS_HARDPPSONCLEAR |
224 #endif	/* PPS_SYNC */
225 	PPS_OFFSETASSERT | PPS_OFFSETCLEAR;
226 
227 #ifdef KGDB
228 #include <sys/kgdb.h>
229 
230 static int plcom_kgdb_unit;
231 static bus_space_tag_t plcom_kgdb_iot;
232 static bus_space_handle_t plcom_kgdb_ioh;
233 static int plcom_kgdb_attached;
234 
235 int	plcom_kgdb_getc (void *);
236 void	plcom_kgdb_putc (void *, int);
237 #endif /* KGDB */
238 
239 #define	PLCOMUNIT_MASK	0x7ffff
240 #define	PLCOMDIALOUT_MASK	0x80000
241 
242 #define	PLCOMUNIT(x)	(minor(x) & PLCOMUNIT_MASK)
243 #define	PLCOMDIALOUT(x)	(minor(x) & PLCOMDIALOUT_MASK)
244 
245 #define	PLCOM_ISALIVE(sc)	((sc)->enabled != 0 && \
246 				 device_is_active(&(sc)->sc_dev))
247 
248 #define	BR	BUS_SPACE_BARRIER_READ
249 #define	BW	BUS_SPACE_BARRIER_WRITE
250 #define PLCOM_BARRIER(t, h, f) bus_space_barrier((t), (h), 0, PLCOM_UART_SIZE, (f))
251 
252 #define PLCOM_LOCK(sc) simple_lock(&(sc)->sc_lock)
253 #define PLCOM_UNLOCK(sc) simple_unlock(&(sc)->sc_lock)
254 
255 int
256 plcomspeed(long speed, long frequency)
257 {
258 #define	divrnd(n, q)	(((n)*2/(q)+1)/2)	/* divide and round off */
259 
260 	int x, err;
261 
262 #if 0
263 	if (speed == 0)
264 		return 0;
265 #endif
266 	if (speed <= 0)
267 		return -1;
268 	x = divrnd(frequency / 16, speed);
269 	if (x <= 0)
270 		return -1;
271 	err = divrnd(((quad_t)frequency) * 1000 / 16, speed * x) - 1000;
272 	if (err < 0)
273 		err = -err;
274 	if (err > PLCOM_TOLERANCE)
275 		return -1;
276 	return x;
277 
278 #undef	divrnd
279 }
280 
281 #ifdef PLCOM_DEBUG
282 int	plcom_debug = 0;
283 
284 void plcomstatus (struct plcom_softc *, char *);
285 void
286 plcomstatus(struct plcom_softc *sc, char *str)
287 {
288 	struct tty *tp = sc->sc_tty;
289 
290 	printf("%s: %s %sclocal  %sdcd %sts_carr_on %sdtr %stx_stopped\n",
291 	    sc->sc_dev.dv_xname, str,
292 	    ISSET(tp->t_cflag, CLOCAL) ? "+" : "-",
293 	    ISSET(sc->sc_msr, MSR_DCD) ? "+" : "-",
294 	    ISSET(tp->t_state, TS_CARR_ON) ? "+" : "-",
295 	    ISSET(sc->sc_mcr, MCR_DTR) ? "+" : "-",
296 	    sc->sc_tx_stopped ? "+" : "-");
297 
298 	printf("%s: %s %scrtscts %scts %sts_ttstop  %srts %xrx_flags\n",
299 	    sc->sc_dev.dv_xname, str,
300 	    ISSET(tp->t_cflag, CRTSCTS) ? "+" : "-",
301 	    ISSET(sc->sc_msr, MSR_CTS) ? "+" : "-",
302 	    ISSET(tp->t_state, TS_TTSTOP) ? "+" : "-",
303 	    ISSET(sc->sc_mcr, MCR_RTS) ? "+" : "-",
304 	    sc->sc_rx_flags);
305 }
306 #endif
307 
308 int
309 plcomprobe1(bus_space_tag_t iot, bus_space_handle_t ioh)
310 {
311 	int data;
312 
313 	/* Disable the UART.  */
314 	bus_space_write_1(iot, ioh, plcom_cr, 0);
315 	/* Make sure the FIFO is off.  */
316 	bus_space_write_1(iot, ioh, plcom_lcr, LCR_8BITS);
317 	/* Disable interrupts.  */
318 	bus_space_write_1(iot, ioh, plcom_iir, 0);
319 
320 	/* Make sure we swallow anything in the receiving register.  */
321 	data = bus_space_read_1(iot, ioh, plcom_dr);
322 
323 	if (bus_space_read_1(iot, ioh, plcom_lcr) != LCR_8BITS)
324 		return 0;
325 
326 	data = bus_space_read_1(iot, ioh, plcom_fr) & (FR_RXFF | FR_RXFE);
327 
328 	if (data != FR_RXFE)
329 		return 0;
330 
331 	return 1;
332 }
333 
334 static void
335 plcom_enable_debugport(struct plcom_softc *sc)
336 {
337 	int s;
338 
339 	/* Turn on line break interrupt, set carrier. */
340 	s = splserial();
341 	PLCOM_LOCK(sc);
342 	sc->sc_cr = CR_RIE | CR_RTIE | CR_UARTEN;
343 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
344 	SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
345 	/* XXX device_unit() abuse */
346 	sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(&sc->sc_dev),
347 	    sc->sc_mcr);
348 	PLCOM_UNLOCK(sc);
349 	splx(s);
350 }
351 
352 void
353 plcom_attach_subr(struct plcom_softc *sc)
354 {
355 	int unit = sc->sc_iounit;
356 	bus_space_tag_t iot = sc->sc_iot;
357 	bus_space_handle_t ioh = sc->sc_ioh;
358 	struct tty *tp;
359 
360 	callout_init(&sc->sc_diag_callout, 0);
361 	simple_lock_init(&sc->sc_lock);
362 
363 	/* Disable interrupts before configuring the device. */
364 	sc->sc_cr = 0;
365 
366 	if (plcomconstag && unit == plcomconsunit) {
367 		plcomconsattached = 1;
368 
369 		plcomconstag = iot;
370 		plcomconsioh = ioh;
371 
372 		/* Make sure the console is always "hardwired". */
373 		delay(1000);			/* wait for output to finish */
374 		SET(sc->sc_hwflags, PLCOM_HW_CONSOLE);
375 		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
376 		/* Must re-enable the console immediately, or we will
377 		   hang when trying to print.  */
378 		sc->sc_cr = CR_UARTEN;
379 	}
380 
381 	bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
382 
383 	/* The PL010 has a 16-byte fifo, but the tx interrupt triggers when
384 	   there is space for 8 more bytes.  */
385 	sc->sc_fifolen = 8;
386 	printf("\n");
387 
388 	if (ISSET(sc->sc_hwflags, PLCOM_HW_TXFIFO_DISABLE)) {
389 		sc->sc_fifolen = 1;
390 		printf("%s: txfifo disabled\n", sc->sc_dev.dv_xname);
391 	}
392 
393 	if (sc->sc_fifolen > 1)
394 		SET(sc->sc_hwflags, PLCOM_HW_FIFO);
395 
396 	tp = ttymalloc();
397 	tp->t_oproc = plcomstart;
398 	tp->t_param = plcomparam;
399 	tp->t_hwiflow = plcomhwiflow;
400 
401 	sc->sc_tty = tp;
402 	sc->sc_rbuf = malloc(plcom_rbuf_size << 1, M_DEVBUF, M_NOWAIT);
403 	sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
404 	sc->sc_rbavail = plcom_rbuf_size;
405 	if (sc->sc_rbuf == NULL) {
406 		printf("%s: unable to allocate ring buffer\n",
407 		    sc->sc_dev.dv_xname);
408 		return;
409 	}
410 	sc->sc_ebuf = sc->sc_rbuf + (plcom_rbuf_size << 1);
411 
412 	tty_attach(tp);
413 
414 	if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) {
415 		int maj;
416 
417 		/* locate the major number */
418 		maj = cdevsw_lookup_major(&plcom_cdevsw);
419 
420 		cn_tab->cn_dev = makedev(maj, device_unit(&sc->sc_dev));
421 
422 		printf("%s: console\n", sc->sc_dev.dv_xname);
423 	}
424 
425 #ifdef KGDB
426 	/*
427 	 * Allow kgdb to "take over" this port.  If this is
428 	 * the kgdb device, it has exclusive use.
429 	 */
430 	if (iot == plcom_kgdb_iot && unit == plcom_kgdb_unit) {
431 		plcom_kgdb_attached = 1;
432 
433 		SET(sc->sc_hwflags, PLCOM_HW_KGDB);
434 		printf("%s: kgdb\n", sc->sc_dev.dv_xname);
435 	}
436 #endif
437 
438 	sc->sc_si = softint_establish(SOFTINT_SERIAL, plcomsoft, sc);
439 
440 #if NRND > 0 && defined(RND_COM)
441 	rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
442 			  RND_TYPE_TTY, 0);
443 #endif
444 
445 	/* if there are no enable/disable functions, assume the device
446 	   is always enabled */
447 	if (!sc->enable)
448 		sc->enabled = 1;
449 
450 	plcom_config(sc);
451 
452 	SET(sc->sc_hwflags, PLCOM_HW_DEV_OK);
453 }
454 
455 void
456 plcom_config(struct plcom_softc *sc)
457 {
458 	bus_space_tag_t iot = sc->sc_iot;
459 	bus_space_handle_t ioh = sc->sc_ioh;
460 
461 	/* Disable interrupts before configuring the device. */
462 	sc->sc_cr = 0;
463 	bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
464 
465 	if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE|PLCOM_HW_KGDB))
466 		plcom_enable_debugport(sc);
467 }
468 
469 int
470 plcom_detach(self, flags)
471 	struct device *self;
472 	int flags;
473 {
474 	struct plcom_softc *sc = (struct plcom_softc *)self;
475 	int maj, mn;
476 
477 	/* locate the major number */
478 	maj = cdevsw_lookup_major(&plcom_cdevsw);
479 
480 	/* Nuke the vnodes for any open instances. */
481 	mn = device_unit(self);
482 	vdevgone(maj, mn, mn, VCHR);
483 
484 	mn |= PLCOMDIALOUT_MASK;
485 	vdevgone(maj, mn, mn, VCHR);
486 
487 	/* Free the receive buffer. */
488 	free(sc->sc_rbuf, M_DEVBUF);
489 
490 	/* Detach and free the tty. */
491 	tty_detach(sc->sc_tty);
492 	ttyfree(sc->sc_tty);
493 
494 	/* Unhook the soft interrupt handler. */
495 	softint_disestablish(sc->sc_si);
496 
497 #if NRND > 0 && defined(RND_COM)
498 	/* Unhook the entropy source. */
499 	rnd_detach_source(&sc->rnd_source);
500 #endif
501 
502 	return 0;
503 }
504 
505 int
506 plcom_activate(struct device *self, enum devact act)
507 {
508 	struct plcom_softc *sc = (struct plcom_softc *)self;
509 	int s, rv = 0;
510 
511 	s = splserial();
512 	PLCOM_LOCK(sc);
513 	switch (act) {
514 	case DVACT_ACTIVATE:
515 		rv = EOPNOTSUPP;
516 		break;
517 
518 	case DVACT_DEACTIVATE:
519 		if (sc->sc_hwflags & (PLCOM_HW_CONSOLE|PLCOM_HW_KGDB)) {
520 			rv = EBUSY;
521 			break;
522 		}
523 
524 		if (sc->disable != NULL && sc->enabled != 0) {
525 			(*sc->disable)(sc);
526 			sc->enabled = 0;
527 		}
528 		break;
529 	}
530 
531 	PLCOM_UNLOCK(sc);
532 	splx(s);
533 	return rv;
534 }
535 
536 void
537 plcom_shutdown(struct plcom_softc *sc)
538 {
539 	struct tty *tp = sc->sc_tty;
540 	int s;
541 
542 	s = splserial();
543 	PLCOM_LOCK(sc);
544 
545 	/* If we were asserting flow control, then deassert it. */
546 	SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
547 	plcom_hwiflow(sc);
548 
549 	/* Clear any break condition set with TIOCSBRK. */
550 	plcom_break(sc, 0);
551 
552 	/* Turn off PPS capture on last close. */
553 	mutex_spin_enter(&timecounter_lock);
554 	sc->sc_ppsmask = 0;
555 	sc->ppsparam.mode = 0;
556 	mutex_spin_exit(&timecounter_lock);
557 
558 	/*
559 	 * Hang up if necessary.  Wait a bit, so the other side has time to
560 	 * notice even if we immediately open the port again.
561 	 * Avoid tsleeping above splhigh().
562 	 */
563 	if (ISSET(tp->t_cflag, HUPCL)) {
564 		plcom_modem(sc, 0);
565 		PLCOM_UNLOCK(sc);
566 		splx(s);
567 		/* XXX tsleep will only timeout */
568 		(void) tsleep(sc, TTIPRI, ttclos, hz);
569 		s = splserial();
570 		PLCOM_LOCK(sc);
571 	}
572 
573 	/* Turn off interrupts. */
574 	if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE))
575 		/* interrupt on break */
576 		sc->sc_cr = CR_RIE | CR_RTIE | CR_UARTEN;
577 	else
578 		sc->sc_cr = 0;
579 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
580 
581 	if (sc->disable) {
582 #ifdef DIAGNOSTIC
583 		if (!sc->enabled)
584 			panic("plcom_shutdown: not enabled?");
585 #endif
586 		(*sc->disable)(sc);
587 		sc->enabled = 0;
588 	}
589 	PLCOM_UNLOCK(sc);
590 	splx(s);
591 }
592 
593 int
594 plcomopen(dev_t dev, int flag, int mode, struct lwp *l)
595 {
596 	struct plcom_softc *sc;
597 	struct tty *tp;
598 	int s, s2;
599 	int error;
600 
601 	sc = device_lookup(&plcom_cd, PLCOMUNIT(dev));
602 	if (sc == NULL || !ISSET(sc->sc_hwflags, PLCOM_HW_DEV_OK) ||
603 		sc->sc_rbuf == NULL)
604 		return ENXIO;
605 
606 	if (!device_is_active(&sc->sc_dev))
607 		return ENXIO;
608 
609 #ifdef KGDB
610 	/*
611 	 * If this is the kgdb port, no other use is permitted.
612 	 */
613 	if (ISSET(sc->sc_hwflags, PLCOM_HW_KGDB))
614 		return EBUSY;
615 #endif
616 
617 	tp = sc->sc_tty;
618 
619 	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
620 		return (EBUSY);
621 
622 	s = spltty();
623 
624 	/*
625 	 * Do the following iff this is a first open.
626 	 */
627 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
628 		struct termios t;
629 
630 		tp->t_dev = dev;
631 
632 		s2 = splserial();
633 		PLCOM_LOCK(sc);
634 
635 		if (sc->enable) {
636 			if ((*sc->enable)(sc)) {
637 				PLCOM_UNLOCK(sc);
638 				splx(s2);
639 				splx(s);
640 				printf("%s: device enable failed\n",
641 				       sc->sc_dev.dv_xname);
642 				return EIO;
643 			}
644 			sc->enabled = 1;
645 			plcom_config(sc);
646 		}
647 
648 		/* Turn on interrupts. */
649 		/* IER_ERXRDY | IER_ERLS | IER_EMSC;  */
650 		sc->sc_cr = CR_RIE | CR_RTIE | CR_MSIE | CR_UARTEN;
651 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
652 
653 		/* Fetch the current modem control status, needed later. */
654 		sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, plcom_fr);
655 
656 		/* Clear PPS capture state on first open. */
657 
658 		mutex_spin_enter(&timecounter_lock);
659 		sc->sc_ppsmask = 0;
660 		sc->ppsparam.mode = 0;
661 		mutex_spin_exit(&timecounter_lock);
662 
663 		PLCOM_UNLOCK(sc);
664 		splx(s2);
665 
666 		/*
667 		 * Initialize the termios status to the defaults.  Add in the
668 		 * sticky bits from TIOCSFLAGS.
669 		 */
670 		t.c_ispeed = 0;
671 		if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) {
672 			t.c_ospeed = plcomconsrate;
673 			t.c_cflag = plcomconscflag;
674 		} else {
675 			t.c_ospeed = TTYDEF_SPEED;
676 			t.c_cflag = TTYDEF_CFLAG;
677 		}
678 		if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
679 			SET(t.c_cflag, CLOCAL);
680 		if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
681 			SET(t.c_cflag, CRTSCTS);
682 		if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
683 			SET(t.c_cflag, MDMBUF);
684 		/* Make sure plcomparam() will do something. */
685 		tp->t_ospeed = 0;
686 		(void) plcomparam(tp, &t);
687 		tp->t_iflag = TTYDEF_IFLAG;
688 		tp->t_oflag = TTYDEF_OFLAG;
689 		tp->t_lflag = TTYDEF_LFLAG;
690 		ttychars(tp);
691 		ttsetwater(tp);
692 
693 		s2 = splserial();
694 		PLCOM_LOCK(sc);
695 
696 		/*
697 		 * Turn on DTR.  We must always do this, even if carrier is not
698 		 * present, because otherwise we'd have to use TIOCSDTR
699 		 * immediately after setting CLOCAL, which applications do not
700 		 * expect.  We always assert DTR while the device is open
701 		 * unless explicitly requested to deassert it.
702 		 */
703 		plcom_modem(sc, 1);
704 
705 		/* Clear the input ring, and unblock. */
706 		sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
707 		sc->sc_rbavail = plcom_rbuf_size;
708 		plcom_iflush(sc);
709 		CLR(sc->sc_rx_flags, RX_ANY_BLOCK);
710 		plcom_hwiflow(sc);
711 
712 #ifdef PLCOM_DEBUG
713 		if (plcom_debug)
714 			plcomstatus(sc, "plcomopen  ");
715 #endif
716 
717 		PLCOM_UNLOCK(sc);
718 		splx(s2);
719 	}
720 
721 	splx(s);
722 
723 	error = ttyopen(tp, PLCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK));
724 	if (error)
725 		goto bad;
726 
727 	error = (*tp->t_linesw->l_open)(dev, tp);
728 	if (error)
729 		goto bad;
730 
731 	return 0;
732 
733 bad:
734 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
735 		/*
736 		 * We failed to open the device, and nobody else had it opened.
737 		 * Clean up the state as appropriate.
738 		 */
739 		plcom_shutdown(sc);
740 	}
741 
742 	return error;
743 }
744 
745 int
746 plcomclose(dev_t dev, int flag, int mode, struct lwp *l)
747 {
748 	struct plcom_softc *sc = device_lookup(&plcom_cd, PLCOMUNIT(dev));
749 	struct tty *tp = sc->sc_tty;
750 
751 	/* XXX This is for cons.c. */
752 	if (!ISSET(tp->t_state, TS_ISOPEN))
753 		return 0;
754 
755 	(*tp->t_linesw->l_close)(tp, flag);
756 	ttyclose(tp);
757 
758 	if (PLCOM_ISALIVE(sc) == 0)
759 		return 0;
760 
761 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
762 		/*
763 		 * Although we got a last close, the device may still be in
764 		 * use; e.g. if this was the dialout node, and there are still
765 		 * processes waiting for carrier on the non-dialout node.
766 		 */
767 		plcom_shutdown(sc);
768 	}
769 
770 	return 0;
771 }
772 
773 int
774 plcomread(dev_t dev, struct uio *uio, int flag)
775 {
776 	struct plcom_softc *sc = device_lookup(&plcom_cd, PLCOMUNIT(dev));
777 	struct tty *tp = sc->sc_tty;
778 
779 	if (PLCOM_ISALIVE(sc) == 0)
780 		return EIO;
781 
782 	return (*tp->t_linesw->l_read)(tp, uio, flag);
783 }
784 
785 int
786 plcomwrite(dev_t dev, struct uio *uio, int flag)
787 {
788 	struct plcom_softc *sc = device_lookup(&plcom_cd, PLCOMUNIT(dev));
789 	struct tty *tp = sc->sc_tty;
790 
791 	if (PLCOM_ISALIVE(sc) == 0)
792 		return EIO;
793 
794 	return (*tp->t_linesw->l_write)(tp, uio, flag);
795 }
796 
797 int
798 plcompoll(dev_t dev, int events, struct lwp *l)
799 {
800 	struct plcom_softc *sc = device_lookup(&plcom_cd, PLCOMUNIT(dev));
801 	struct tty *tp = sc->sc_tty;
802 
803 	if (PLCOM_ISALIVE(sc) == 0)
804 		return EIO;
805 
806 	return (*tp->t_linesw->l_poll)(tp, events, l);
807 }
808 
809 struct tty *
810 plcomtty(dev_t dev)
811 {
812 	struct plcom_softc *sc = device_lookup(&plcom_cd, PLCOMUNIT(dev));
813 	struct tty *tp = sc->sc_tty;
814 
815 	return tp;
816 }
817 
818 int
819 plcomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
820 {
821 	struct plcom_softc *sc = device_lookup(&plcom_cd, PLCOMUNIT(dev));
822 	struct tty *tp = sc->sc_tty;
823 	int error;
824 	int s;
825 
826 	if (PLCOM_ISALIVE(sc) == 0)
827 		return EIO;
828 
829 	error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l);
830 	if (error != EPASSTHROUGH)
831 		return error;
832 
833 	error = ttioctl(tp, cmd, data, flag, l);
834 	if (error != EPASSTHROUGH)
835 		return error;
836 
837 	error = 0;
838 
839 	s = splserial();
840 	PLCOM_LOCK(sc);
841 
842 	switch (cmd) {
843 	case TIOCSBRK:
844 		plcom_break(sc, 1);
845 		break;
846 
847 	case TIOCCBRK:
848 		plcom_break(sc, 0);
849 		break;
850 
851 	case TIOCSDTR:
852 		plcom_modem(sc, 1);
853 		break;
854 
855 	case TIOCCDTR:
856 		plcom_modem(sc, 0);
857 		break;
858 
859 	case TIOCGFLAGS:
860 		*(int *)data = sc->sc_swflags;
861 		break;
862 
863 	case TIOCSFLAGS:
864 		error = kauth_authorize_device_tty(l->l_cred,
865 		    KAUTH_DEVICE_TTY_PRIVSET, tp);
866 		if (error)
867 			break;
868 		sc->sc_swflags = *(int *)data;
869 		break;
870 
871 	case TIOCMSET:
872 	case TIOCMBIS:
873 	case TIOCMBIC:
874 		tiocm_to_plcom(sc, cmd, *(int *)data);
875 		break;
876 
877 	case TIOCMGET:
878 		*(int *)data = plcom_to_tiocm(sc);
879 		break;
880 
881 	case PPS_IOC_CREATE:
882 		break;
883 
884 	case PPS_IOC_DESTROY:
885 		break;
886 
887 	case PPS_IOC_GETPARAMS: {
888 		pps_params_t *pp;
889 		pp = (pps_params_t *)data;
890 		mutex_spin_enter(&timecounter_lock);
891 		*pp = sc->ppsparam;
892 		mutex_spin_exit(&timecounter_lock);
893 		break;
894 	}
895 
896 	case PPS_IOC_SETPARAMS: {
897 	  	pps_params_t *pp;
898 		int mode;
899 		pp = (pps_params_t *)data;
900 		mutex_spin_enter(&timecounter_lock);
901 		if (pp->mode & ~ppscap) {
902 			error = EINVAL;
903 			mutex_spin_exit(&timecounter_lock);
904 			break;
905 		}
906 		sc->ppsparam = *pp;
907 	 	/*
908 		 * Compute msr masks from user-specified timestamp state.
909 		 */
910 		mode = sc->ppsparam.mode;
911 #ifdef	PPS_SYNC
912 		if (mode & PPS_HARDPPSONASSERT) {
913 			mode |= PPS_CAPTUREASSERT;
914 			/* XXX revoke any previous HARDPPS source */
915 		}
916 		if (mode & PPS_HARDPPSONCLEAR) {
917 			mode |= PPS_CAPTURECLEAR;
918 			/* XXX revoke any previous HARDPPS source */
919 		}
920 #endif	/* PPS_SYNC */
921 		switch (mode & PPS_CAPTUREBOTH) {
922 		case 0:
923 			sc->sc_ppsmask = 0;
924 			break;
925 
926 		case PPS_CAPTUREASSERT:
927 			sc->sc_ppsmask = MSR_DCD;
928 			sc->sc_ppsassert = MSR_DCD;
929 			sc->sc_ppsclear = -1;
930 			break;
931 
932 		case PPS_CAPTURECLEAR:
933 			sc->sc_ppsmask = MSR_DCD;
934 			sc->sc_ppsassert = -1;
935 			sc->sc_ppsclear = 0;
936 			break;
937 
938 		case PPS_CAPTUREBOTH:
939 			sc->sc_ppsmask = MSR_DCD;
940 			sc->sc_ppsassert = MSR_DCD;
941 			sc->sc_ppsclear = 0;
942 			break;
943 
944 		default:
945 			error = EINVAL;
946 			break;
947 		}
948 		mutex_spin_exit(&timecounter_lock);
949 		break;
950 	}
951 
952 	case PPS_IOC_GETCAP:
953 		*(int*)data = ppscap;
954 		break;
955 
956 	case PPS_IOC_FETCH: {
957 		pps_info_t *pi;
958 		pi = (pps_info_t *)data;
959 		mutex_spin_enter(&timecounter_lock);
960 		*pi = sc->ppsinfo;
961 		mutex_spin_exit(&timecounter_lock);
962 		break;
963 	}
964 
965 	case TIOCDCDTIMESTAMP:	/* XXX old, overloaded  API used by xntpd v3 */
966 		/*
967 		 * Some GPS clocks models use the falling rather than
968 		 * rising edge as the on-the-second signal.
969 		 * The old API has no way to specify PPS polarity.
970 		 */
971 		mutex_spin_enter(&timecounter_lock);
972 		sc->sc_ppsmask = MSR_DCD;
973 #ifndef PPS_TRAILING_EDGE
974 		sc->sc_ppsassert = MSR_DCD;
975 		sc->sc_ppsclear = -1;
976 		TIMESPEC_TO_TIMEVAL((struct timeval *)data,
977 		    &sc->ppsinfo.assert_timestamp);
978 #else
979 		sc->sc_ppsassert = -1
980 		sc->sc_ppsclear = 0;
981 		TIMESPEC_TO_TIMEVAL((struct timeval *)data,
982 		    &sc->ppsinfo.clear_timestamp);
983 #endif
984 		mutex_spin_exit(&timecounter_lock);
985 		break;
986 
987 	default:
988 		error = EPASSTHROUGH;
989 		break;
990 	}
991 
992 	PLCOM_UNLOCK(sc);
993 	splx(s);
994 
995 #ifdef PLCOM_DEBUG
996 	if (plcom_debug)
997 		plcomstatus(sc, "plcomioctl ");
998 #endif
999 
1000 	return error;
1001 }
1002 
1003 integrate void
1004 plcom_schedrx(struct plcom_softc *sc)
1005 {
1006 
1007 	sc->sc_rx_ready = 1;
1008 
1009 	/* Wake up the poller. */
1010 	softint_schedule(sc->sc_si);
1011 }
1012 
1013 void
1014 plcom_break(struct plcom_softc *sc, int onoff)
1015 {
1016 
1017 	if (onoff)
1018 		SET(sc->sc_lcr, LCR_BRK);
1019 	else
1020 		CLR(sc->sc_lcr, LCR_BRK);
1021 
1022 	if (!sc->sc_heldchange) {
1023 		if (sc->sc_tx_busy) {
1024 			sc->sc_heldtbc = sc->sc_tbc;
1025 			sc->sc_tbc = 0;
1026 			sc->sc_heldchange = 1;
1027 		} else
1028 			plcom_loadchannelregs(sc);
1029 	}
1030 }
1031 
1032 void
1033 plcom_modem(struct plcom_softc *sc, int onoff)
1034 {
1035 
1036 	if (sc->sc_mcr_dtr == 0)
1037 		return;
1038 
1039 	if (onoff)
1040 		SET(sc->sc_mcr, sc->sc_mcr_dtr);
1041 	else
1042 		CLR(sc->sc_mcr, sc->sc_mcr_dtr);
1043 
1044 	if (!sc->sc_heldchange) {
1045 		if (sc->sc_tx_busy) {
1046 			sc->sc_heldtbc = sc->sc_tbc;
1047 			sc->sc_tbc = 0;
1048 			sc->sc_heldchange = 1;
1049 		} else
1050 			plcom_loadchannelregs(sc);
1051 	}
1052 }
1053 
1054 void
1055 tiocm_to_plcom(struct plcom_softc *sc, u_long how, int ttybits)
1056 {
1057 	u_char plcombits;
1058 
1059 	plcombits = 0;
1060 	if (ISSET(ttybits, TIOCM_DTR))
1061 		SET(plcombits, MCR_DTR);
1062 	if (ISSET(ttybits, TIOCM_RTS))
1063 		SET(plcombits, MCR_RTS);
1064 
1065 	switch (how) {
1066 	case TIOCMBIC:
1067 		CLR(sc->sc_mcr, plcombits);
1068 		break;
1069 
1070 	case TIOCMBIS:
1071 		SET(sc->sc_mcr, plcombits);
1072 		break;
1073 
1074 	case TIOCMSET:
1075 		CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
1076 		SET(sc->sc_mcr, plcombits);
1077 		break;
1078 	}
1079 
1080 	if (!sc->sc_heldchange) {
1081 		if (sc->sc_tx_busy) {
1082 			sc->sc_heldtbc = sc->sc_tbc;
1083 			sc->sc_tbc = 0;
1084 			sc->sc_heldchange = 1;
1085 		} else
1086 			plcom_loadchannelregs(sc);
1087 	}
1088 }
1089 
1090 int
1091 plcom_to_tiocm(struct plcom_softc *sc)
1092 {
1093 	u_char plcombits;
1094 	int ttybits = 0;
1095 
1096 	plcombits = sc->sc_mcr;
1097 	if (ISSET(plcombits, MCR_DTR))
1098 		SET(ttybits, TIOCM_DTR);
1099 	if (ISSET(plcombits, MCR_RTS))
1100 		SET(ttybits, TIOCM_RTS);
1101 
1102 	plcombits = sc->sc_msr;
1103 	if (ISSET(plcombits, MSR_DCD))
1104 		SET(ttybits, TIOCM_CD);
1105 	if (ISSET(plcombits, MSR_CTS))
1106 		SET(ttybits, TIOCM_CTS);
1107 	if (ISSET(plcombits, MSR_DSR))
1108 		SET(ttybits, TIOCM_DSR);
1109 
1110 	if (sc->sc_cr != 0)
1111 		SET(ttybits, TIOCM_LE);
1112 
1113 	return ttybits;
1114 }
1115 
1116 static u_char
1117 cflag2lcr(tcflag_t cflag)
1118 {
1119 	u_char lcr = 0;
1120 
1121 	switch (ISSET(cflag, CSIZE)) {
1122 	case CS5:
1123 		SET(lcr, LCR_5BITS);
1124 		break;
1125 	case CS6:
1126 		SET(lcr, LCR_6BITS);
1127 		break;
1128 	case CS7:
1129 		SET(lcr, LCR_7BITS);
1130 		break;
1131 	case CS8:
1132 		SET(lcr, LCR_8BITS);
1133 		break;
1134 	}
1135 	if (ISSET(cflag, PARENB)) {
1136 		SET(lcr, LCR_PEN);
1137 		if (!ISSET(cflag, PARODD))
1138 			SET(lcr, LCR_EPS);
1139 	}
1140 	if (ISSET(cflag, CSTOPB))
1141 		SET(lcr, LCR_STP2);
1142 
1143 	return lcr;
1144 }
1145 
1146 int
1147 plcomparam(struct tty *tp, struct termios *t)
1148 {
1149 	struct plcom_softc *sc = device_lookup(&plcom_cd, PLCOMUNIT(tp->t_dev));
1150 	int ospeed;
1151 	u_char lcr;
1152 	int s;
1153 
1154 	if (PLCOM_ISALIVE(sc) == 0)
1155 		return EIO;
1156 
1157 	ospeed = plcomspeed(t->c_ospeed, sc->sc_frequency);
1158 
1159 	/* Check requested parameters. */
1160 	if (ospeed < 0)
1161 		return EINVAL;
1162 	if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
1163 		return EINVAL;
1164 
1165 	/*
1166 	 * For the console, always force CLOCAL and !HUPCL, so that the port
1167 	 * is always active.
1168 	 */
1169 	if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) ||
1170 	    ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) {
1171 		SET(t->c_cflag, CLOCAL);
1172 		CLR(t->c_cflag, HUPCL);
1173 	}
1174 
1175 	/*
1176 	 * If there were no changes, don't do anything.  This avoids dropping
1177 	 * input and improves performance when all we did was frob things like
1178 	 * VMIN and VTIME.
1179 	 */
1180 	if (tp->t_ospeed == t->c_ospeed &&
1181 	    tp->t_cflag == t->c_cflag)
1182 		return 0;
1183 
1184 	lcr = ISSET(sc->sc_lcr, LCR_BRK) | cflag2lcr(t->c_cflag);
1185 
1186 	s = splserial();
1187 	PLCOM_LOCK(sc);
1188 
1189 	sc->sc_lcr = lcr;
1190 
1191 	/*
1192 	 * PL010 has a fixed-length FIFO trigger point.
1193 	 */
1194 	if (ISSET(sc->sc_hwflags, PLCOM_HW_FIFO))
1195 		sc->sc_fifo = 1;
1196 	else
1197 		sc->sc_fifo = 0;
1198 
1199 	if (sc->sc_fifo)
1200 		SET(sc->sc_lcr, LCR_FEN);
1201 
1202 	/*
1203 	 * If we're not in a mode that assumes a connection is present, then
1204 	 * ignore carrier changes.
1205 	 */
1206 	if (ISSET(t->c_cflag, CLOCAL | MDMBUF))
1207 		sc->sc_msr_dcd = 0;
1208 	else
1209 		sc->sc_msr_dcd = MSR_DCD;
1210 	/*
1211 	 * Set the flow control pins depending on the current flow control
1212 	 * mode.
1213 	 */
1214 	if (ISSET(t->c_cflag, CRTSCTS)) {
1215 		sc->sc_mcr_dtr = MCR_DTR;
1216 		sc->sc_mcr_rts = MCR_RTS;
1217 		sc->sc_msr_cts = MSR_CTS;
1218 	} else if (ISSET(t->c_cflag, MDMBUF)) {
1219 		/*
1220 		 * For DTR/DCD flow control, make sure we don't toggle DTR for
1221 		 * carrier detection.
1222 		 */
1223 		sc->sc_mcr_dtr = 0;
1224 		sc->sc_mcr_rts = MCR_DTR;
1225 		sc->sc_msr_cts = MSR_DCD;
1226 	} else {
1227 		/*
1228 		 * If no flow control, then always set RTS.  This will make
1229 		 * the other side happy if it mistakenly thinks we're doing
1230 		 * RTS/CTS flow control.
1231 		 */
1232 		sc->sc_mcr_dtr = MCR_DTR | MCR_RTS;
1233 		sc->sc_mcr_rts = 0;
1234 		sc->sc_msr_cts = 0;
1235 		if (ISSET(sc->sc_mcr, MCR_DTR))
1236 			SET(sc->sc_mcr, MCR_RTS);
1237 		else
1238 			CLR(sc->sc_mcr, MCR_RTS);
1239 	}
1240 	sc->sc_msr_mask = sc->sc_msr_cts | sc->sc_msr_dcd;
1241 
1242 #if 0
1243 	if (ospeed == 0)
1244 		CLR(sc->sc_mcr, sc->sc_mcr_dtr);
1245 	else
1246 		SET(sc->sc_mcr, sc->sc_mcr_dtr);
1247 #endif
1248 
1249 	sc->sc_dlbl = ospeed;
1250 	sc->sc_dlbh = ospeed >> 8;
1251 
1252 	/* And copy to tty. */
1253 	tp->t_ispeed = 0;
1254 	tp->t_ospeed = t->c_ospeed;
1255 	tp->t_cflag = t->c_cflag;
1256 
1257 	if (!sc->sc_heldchange) {
1258 		if (sc->sc_tx_busy) {
1259 			sc->sc_heldtbc = sc->sc_tbc;
1260 			sc->sc_tbc = 0;
1261 			sc->sc_heldchange = 1;
1262 		} else
1263 			plcom_loadchannelregs(sc);
1264 	}
1265 
1266 	if (!ISSET(t->c_cflag, CHWFLOW)) {
1267 		/* Disable the high water mark. */
1268 		sc->sc_r_hiwat = 0;
1269 		sc->sc_r_lowat = 0;
1270 		if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
1271 			CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1272 			plcom_schedrx(sc);
1273 		}
1274 		if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
1275 			CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
1276 			plcom_hwiflow(sc);
1277 		}
1278 	} else {
1279 		sc->sc_r_hiwat = plcom_rbuf_hiwat;
1280 		sc->sc_r_lowat = plcom_rbuf_lowat;
1281 	}
1282 
1283 	PLCOM_UNLOCK(sc);
1284 	splx(s);
1285 
1286 	/*
1287 	 * Update the tty layer's idea of the carrier bit, in case we changed
1288 	 * CLOCAL or MDMBUF.  We don't hang up here; we only do that by
1289 	 * explicit request.
1290 	 */
1291 	(void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, MSR_DCD));
1292 
1293 #ifdef PLCOM_DEBUG
1294 	if (plcom_debug)
1295 		plcomstatus(sc, "plcomparam ");
1296 #endif
1297 
1298 	if (!ISSET(t->c_cflag, CHWFLOW)) {
1299 		if (sc->sc_tx_stopped) {
1300 			sc->sc_tx_stopped = 0;
1301 			plcomstart(tp);
1302 		}
1303 	}
1304 
1305 	return 0;
1306 }
1307 
1308 void
1309 plcom_iflush(struct plcom_softc *sc)
1310 {
1311 	bus_space_tag_t iot = sc->sc_iot;
1312 	bus_space_handle_t ioh = sc->sc_ioh;
1313 #ifdef DIAGNOSTIC
1314 	int reg;
1315 #endif
1316 	int timo;
1317 
1318 #ifdef DIAGNOSTIC
1319 	reg = 0xffff;
1320 #endif
1321 	timo = 50000;
1322 	/* flush any pending I/O */
1323 	while (! ISSET(bus_space_read_1(iot, ioh, plcom_fr), FR_RXFE)
1324 	    && --timo)
1325 #ifdef DIAGNOSTIC
1326 		reg =
1327 #else
1328 		    (void)
1329 #endif
1330 		    bus_space_read_1(iot, ioh, plcom_dr);
1331 #ifdef DIAGNOSTIC
1332 	if (!timo)
1333 		printf("%s: plcom_iflush timeout %02x\n", sc->sc_dev.dv_xname,
1334 		       reg);
1335 #endif
1336 }
1337 
1338 void
1339 plcom_loadchannelregs(struct plcom_softc *sc)
1340 {
1341 	bus_space_tag_t iot = sc->sc_iot;
1342 	bus_space_handle_t ioh = sc->sc_ioh;
1343 
1344 	/* XXXXX necessary? */
1345 	plcom_iflush(sc);
1346 
1347 	bus_space_write_1(iot, ioh, plcom_cr, 0);
1348 
1349 	bus_space_write_1(iot, ioh, plcom_dlbl, sc->sc_dlbl);
1350 	bus_space_write_1(iot, ioh, plcom_dlbh, sc->sc_dlbh);
1351 	bus_space_write_1(iot, ioh, plcom_lcr, sc->sc_lcr);
1352 	/* XXX device_unit() abuse */
1353 	sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(&sc->sc_dev),
1354 	    sc->sc_mcr_active = sc->sc_mcr);
1355 
1356 	bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
1357 }
1358 
1359 int
1360 plcomhwiflow(struct tty *tp, int block)
1361 {
1362 	struct plcom_softc *sc = device_lookup(&plcom_cd, PLCOMUNIT(tp->t_dev));
1363 	int s;
1364 
1365 	if (PLCOM_ISALIVE(sc) == 0)
1366 		return 0;
1367 
1368 	if (sc->sc_mcr_rts == 0)
1369 		return 0;
1370 
1371 	s = splserial();
1372 	PLCOM_LOCK(sc);
1373 
1374 	if (block) {
1375 		if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1376 			SET(sc->sc_rx_flags, RX_TTY_BLOCKED);
1377 			plcom_hwiflow(sc);
1378 		}
1379 	} else {
1380 		if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
1381 			CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1382 			plcom_schedrx(sc);
1383 		}
1384 		if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1385 			CLR(sc->sc_rx_flags, RX_TTY_BLOCKED);
1386 			plcom_hwiflow(sc);
1387 		}
1388 	}
1389 
1390 	PLCOM_UNLOCK(sc);
1391 	splx(s);
1392 	return 1;
1393 }
1394 
1395 /*
1396  * (un)block input via hw flowcontrol
1397  */
1398 void
1399 plcom_hwiflow(struct plcom_softc *sc)
1400 {
1401 	if (sc->sc_mcr_rts == 0)
1402 		return;
1403 
1404 	if (ISSET(sc->sc_rx_flags, RX_ANY_BLOCK)) {
1405 		CLR(sc->sc_mcr, sc->sc_mcr_rts);
1406 		CLR(sc->sc_mcr_active, sc->sc_mcr_rts);
1407 	} else {
1408 		SET(sc->sc_mcr, sc->sc_mcr_rts);
1409 		SET(sc->sc_mcr_active, sc->sc_mcr_rts);
1410 	}
1411 	/* XXX device_unit() abuse */
1412 	sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(&sc->sc_dev),
1413 	    sc->sc_mcr_active);
1414 }
1415 
1416 
1417 void
1418 plcomstart(struct tty *tp)
1419 {
1420 	struct plcom_softc *sc = device_lookup(&plcom_cd, PLCOMUNIT(tp->t_dev));
1421 	bus_space_tag_t iot = sc->sc_iot;
1422 	bus_space_handle_t ioh = sc->sc_ioh;
1423 	int s;
1424 
1425 	if (PLCOM_ISALIVE(sc) == 0)
1426 		return;
1427 
1428 	s = spltty();
1429 	if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
1430 		goto out;
1431 	if (sc->sc_tx_stopped)
1432 		goto out;
1433 
1434 	if (!ttypull(tp))
1435 		goto out;
1436 
1437 	/* Grab the first contiguous region of buffer space. */
1438 	{
1439 		u_char *tba;
1440 		int tbc;
1441 
1442 		tba = tp->t_outq.c_cf;
1443 		tbc = ndqb(&tp->t_outq, 0);
1444 
1445 		(void)splserial();
1446 		PLCOM_LOCK(sc);
1447 
1448 		sc->sc_tba = tba;
1449 		sc->sc_tbc = tbc;
1450 	}
1451 
1452 	SET(tp->t_state, TS_BUSY);
1453 	sc->sc_tx_busy = 1;
1454 
1455 	/* Enable transmit completion interrupts if necessary. */
1456 	if (!ISSET(sc->sc_cr, CR_TIE)) {
1457 		SET(sc->sc_cr, CR_TIE);
1458 		bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
1459 	}
1460 
1461 	/* Output the first chunk of the contiguous buffer. */
1462 	{
1463 		int n;
1464 
1465 		n = sc->sc_tbc;
1466 		if (n > sc->sc_fifolen)
1467 			n = sc->sc_fifolen;
1468 		bus_space_write_multi_1(iot, ioh, plcom_dr, sc->sc_tba, n);
1469 		sc->sc_tbc -= n;
1470 		sc->sc_tba += n;
1471 	}
1472 	PLCOM_UNLOCK(sc);
1473 out:
1474 	splx(s);
1475 	return;
1476 }
1477 
1478 /*
1479  * Stop output on a line.
1480  */
1481 void
1482 plcomstop(struct tty *tp, int flag)
1483 {
1484 	struct plcom_softc *sc = device_lookup(&plcom_cd, PLCOMUNIT(tp->t_dev));
1485 	int s;
1486 
1487 	s = splserial();
1488 	PLCOM_LOCK(sc);
1489 	if (ISSET(tp->t_state, TS_BUSY)) {
1490 		/* Stop transmitting at the next chunk. */
1491 		sc->sc_tbc = 0;
1492 		sc->sc_heldtbc = 0;
1493 		if (!ISSET(tp->t_state, TS_TTSTOP))
1494 			SET(tp->t_state, TS_FLUSH);
1495 	}
1496 	PLCOM_UNLOCK(sc);
1497 	splx(s);
1498 }
1499 
1500 void
1501 plcomdiag(void *arg)
1502 {
1503 	struct plcom_softc *sc = arg;
1504 	int overflows, floods;
1505 	int s;
1506 
1507 	s = splserial();
1508 	PLCOM_LOCK(sc);
1509 	overflows = sc->sc_overflows;
1510 	sc->sc_overflows = 0;
1511 	floods = sc->sc_floods;
1512 	sc->sc_floods = 0;
1513 	sc->sc_errors = 0;
1514 	PLCOM_UNLOCK(sc);
1515 	splx(s);
1516 
1517 	log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
1518 	    sc->sc_dev.dv_xname,
1519 	    overflows, overflows == 1 ? "" : "s",
1520 	    floods, floods == 1 ? "" : "s");
1521 }
1522 
1523 integrate void
1524 plcom_rxsoft(struct plcom_softc *sc, struct tty *tp)
1525 {
1526 	int (*rint) (int, struct tty *) = tp->t_linesw->l_rint;
1527 	u_char *get, *end;
1528 	u_int cc, scc;
1529 	u_char rsr;
1530 	int code;
1531 	int s;
1532 
1533 	end = sc->sc_ebuf;
1534 	get = sc->sc_rbget;
1535 	scc = cc = plcom_rbuf_size - sc->sc_rbavail;
1536 
1537 	if (cc == plcom_rbuf_size) {
1538 		sc->sc_floods++;
1539 		if (sc->sc_errors++ == 0)
1540 			callout_reset(&sc->sc_diag_callout, 60 * hz,
1541 			    plcomdiag, sc);
1542 	}
1543 
1544 	while (cc) {
1545 		code = get[0];
1546 		rsr = get[1];
1547 		if (ISSET(rsr, RSR_OE | RSR_BE | RSR_FE | RSR_PE)) {
1548 			if (ISSET(rsr, RSR_OE)) {
1549 				sc->sc_overflows++;
1550 				if (sc->sc_errors++ == 0)
1551 					callout_reset(&sc->sc_diag_callout,
1552 					    60 * hz, plcomdiag, sc);
1553 			}
1554 			if (ISSET(rsr, RSR_BE | RSR_FE))
1555 				SET(code, TTY_FE);
1556 			if (ISSET(rsr, RSR_PE))
1557 				SET(code, TTY_PE);
1558 		}
1559 		if ((*rint)(code, tp) == -1) {
1560 			/*
1561 			 * The line discipline's buffer is out of space.
1562 			 */
1563 			if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
1564 				/*
1565 				 * We're either not using flow control, or the
1566 				 * line discipline didn't tell us to block for
1567 				 * some reason.  Either way, we have no way to
1568 				 * know when there's more space available, so
1569 				 * just drop the rest of the data.
1570 				 */
1571 				get += cc << 1;
1572 				if (get >= end)
1573 					get -= plcom_rbuf_size << 1;
1574 				cc = 0;
1575 			} else {
1576 				/*
1577 				 * Don't schedule any more receive processing
1578 				 * until the line discipline tells us there's
1579 				 * space available (through plcomhwiflow()).
1580 				 * Leave the rest of the data in the input
1581 				 * buffer.
1582 				 */
1583 				SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
1584 			}
1585 			break;
1586 		}
1587 		get += 2;
1588 		if (get >= end)
1589 			get = sc->sc_rbuf;
1590 		cc--;
1591 	}
1592 
1593 	if (cc != scc) {
1594 		sc->sc_rbget = get;
1595 		s = splserial();
1596 		PLCOM_LOCK(sc);
1597 
1598 		cc = sc->sc_rbavail += scc - cc;
1599 		/* Buffers should be ok again, release possible block. */
1600 		if (cc >= sc->sc_r_lowat) {
1601 			if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
1602 				CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
1603 				SET(sc->sc_cr, CR_RIE | CR_RTIE);
1604 				bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
1605 			}
1606 			if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
1607 				CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
1608 				plcom_hwiflow(sc);
1609 			}
1610 		}
1611 		PLCOM_UNLOCK(sc);
1612 		splx(s);
1613 	}
1614 }
1615 
1616 integrate void
1617 plcom_txsoft(struct plcom_softc *sc, struct tty *tp)
1618 {
1619 
1620 	CLR(tp->t_state, TS_BUSY);
1621 	if (ISSET(tp->t_state, TS_FLUSH))
1622 		CLR(tp->t_state, TS_FLUSH);
1623 	else
1624 		ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
1625 	(*tp->t_linesw->l_start)(tp);
1626 }
1627 
1628 integrate void
1629 plcom_stsoft(struct plcom_softc *sc, struct tty *tp)
1630 {
1631 	u_char msr, delta;
1632 	int s;
1633 
1634 	s = splserial();
1635 	PLCOM_LOCK(sc);
1636 	msr = sc->sc_msr;
1637 	delta = sc->sc_msr_delta;
1638 	sc->sc_msr_delta = 0;
1639 	PLCOM_UNLOCK(sc);
1640 	splx(s);
1641 
1642 	if (ISSET(delta, sc->sc_msr_dcd)) {
1643 		/*
1644 		 * Inform the tty layer that carrier detect changed.
1645 		 */
1646 		(void) (*tp->t_linesw->l_modem)(tp, ISSET(msr, MSR_DCD));
1647 	}
1648 
1649 	if (ISSET(delta, sc->sc_msr_cts)) {
1650 		/* Block or unblock output according to flow control. */
1651 		if (ISSET(msr, sc->sc_msr_cts)) {
1652 			sc->sc_tx_stopped = 0;
1653 			(*tp->t_linesw->l_start)(tp);
1654 		} else {
1655 			sc->sc_tx_stopped = 1;
1656 		}
1657 	}
1658 
1659 #ifdef PLCOM_DEBUG
1660 	if (plcom_debug)
1661 		plcomstatus(sc, "plcom_stsoft");
1662 #endif
1663 }
1664 
1665 void
1666 plcomsoft(void *arg)
1667 {
1668 	struct plcom_softc *sc = arg;
1669 	struct tty *tp;
1670 
1671 	if (PLCOM_ISALIVE(sc) == 0)
1672 		return;
1673 
1674 	tp = sc->sc_tty;
1675 
1676 	if (sc->sc_rx_ready) {
1677 		sc->sc_rx_ready = 0;
1678 		plcom_rxsoft(sc, tp);
1679 	}
1680 
1681 	if (sc->sc_st_check) {
1682 		sc->sc_st_check = 0;
1683 		plcom_stsoft(sc, tp);
1684 	}
1685 
1686 	if (sc->sc_tx_done) {
1687 		sc->sc_tx_done = 0;
1688 		plcom_txsoft(sc, tp);
1689 	}
1690 }
1691 
1692 int
1693 plcomintr(void *arg)
1694 {
1695 	struct plcom_softc *sc = arg;
1696 	bus_space_tag_t iot = sc->sc_iot;
1697 	bus_space_handle_t ioh = sc->sc_ioh;
1698 	u_char *put, *end;
1699 	u_int cc;
1700 	u_char rsr, iir;
1701 
1702 	if (PLCOM_ISALIVE(sc) == 0)
1703 		return 0;
1704 
1705 	PLCOM_LOCK(sc);
1706 	iir = bus_space_read_1(iot, ioh, plcom_iir);
1707 	if (! ISSET(iir, IIR_IMASK)) {
1708 		PLCOM_UNLOCK(sc);
1709 		return 0;
1710 	}
1711 
1712 	end = sc->sc_ebuf;
1713 	put = sc->sc_rbput;
1714 	cc = sc->sc_rbavail;
1715 
1716 	do {
1717 		u_char	msr, delta, fr;
1718 
1719 		fr = bus_space_read_1(iot, ioh, plcom_fr);
1720 
1721 		if (!ISSET(fr, FR_RXFE) &&
1722 		    !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
1723 			while (cc > 0) {
1724 				int cn_trapped = 0;
1725 				put[0] = bus_space_read_1(iot, ioh,
1726 				    plcom_dr);
1727 				rsr = bus_space_read_1(iot, ioh, plcom_rsr);
1728 				/* Clear any error status.  */
1729 				if (ISSET(rsr,
1730 				    (RSR_BE | RSR_OE | RSR_PE | RSR_FE)))
1731 					bus_space_write_1(iot, ioh, plcom_ecr,
1732 					    0);
1733 				if (ISSET(rsr, RSR_BE)) {
1734 					cn_trapped = 0;
1735 					cn_check_magic(sc->sc_tty->t_dev,
1736 					    CNC_BREAK, plcom_cnm_state);
1737 					if (cn_trapped)
1738 						continue;
1739 #if defined(KGDB)
1740 					if (ISSET(sc->sc_hwflags,
1741 					    PLCOM_HW_KGDB)) {
1742 						kgdb_connect(1);
1743 						continue;
1744 					}
1745 #endif
1746 				}
1747 
1748 				put[1] = rsr;
1749 				cn_trapped = 0;
1750 				cn_check_magic(sc->sc_tty->t_dev,
1751 					       put[0], plcom_cnm_state);
1752 				if (cn_trapped) {
1753 					fr = bus_space_read_1(iot, ioh,
1754 					    plcom_fr);
1755 					if (ISSET(fr, FR_RXFE))
1756 						break;
1757 
1758 					continue;
1759 				}
1760 				put += 2;
1761 				if (put >= end)
1762 					put = sc->sc_rbuf;
1763 				cc--;
1764 
1765 				fr = bus_space_read_1(iot, ioh, plcom_fr);
1766 				if (ISSET(fr, FR_RXFE))
1767 					break;
1768 			}
1769 
1770 			/*
1771 			 * Current string of incoming characters ended because
1772 			 * no more data was available or we ran out of space.
1773 			 * Schedule a receive event if any data was received.
1774 			 * If we're out of space, turn off receive interrupts.
1775 			 */
1776 			sc->sc_rbput = put;
1777 			sc->sc_rbavail = cc;
1778 			if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
1779 				sc->sc_rx_ready = 1;
1780 
1781 			/*
1782 			 * See if we are in danger of overflowing a buffer. If
1783 			 * so, use hardware flow control to ease the pressure.
1784 			 */
1785 			if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) &&
1786 			    cc < sc->sc_r_hiwat) {
1787 				SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
1788 				plcom_hwiflow(sc);
1789 			}
1790 
1791 			/*
1792 			 * If we're out of space, disable receive interrupts
1793 			 * until the queue has drained a bit.
1794 			 */
1795 			if (!cc) {
1796 				SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
1797 				CLR(sc->sc_cr, CR_RIE | CR_RTIE);
1798 				bus_space_write_1(iot, ioh, plcom_cr,
1799 				    sc->sc_cr);
1800 			}
1801 		} else {
1802 			if (ISSET(iir, IIR_RIS)) {
1803 				bus_space_write_1(iot, ioh, plcom_cr, 0);
1804 				delay(10);
1805 				bus_space_write_1(iot, ioh, plcom_cr,
1806 				    sc->sc_cr);
1807 				continue;
1808 			}
1809 		}
1810 
1811 		msr = bus_space_read_1(iot, ioh, plcom_fr);
1812 		delta = msr ^ sc->sc_msr;
1813 		sc->sc_msr = msr;
1814 		/* Clear any pending modem status interrupt.  */
1815 		if (iir & IIR_MIS)
1816 			bus_space_write_1(iot, ioh, plcom_icr, 0);
1817 		/*
1818 		 * Pulse-per-second (PSS) signals on edge of DCD?
1819 		 * Process these even if line discipline is ignoring DCD.
1820 		 */
1821 		if (delta & sc->sc_ppsmask) {
1822 			struct timeval tv;
1823 			mutex_spin_enter(&timecounter_lock);
1824 		    	if ((msr & sc->sc_ppsmask) == sc->sc_ppsassert) {
1825 				/* XXX nanotime() */
1826 				microtime(&tv);
1827 				TIMEVAL_TO_TIMESPEC(&tv,
1828 				    &sc->ppsinfo.assert_timestamp);
1829 				if (sc->ppsparam.mode & PPS_OFFSETASSERT) {
1830 					timespecadd(&sc->ppsinfo.assert_timestamp,
1831 					    &sc->ppsparam.assert_offset,
1832 						    &sc->ppsinfo.assert_timestamp);
1833 				}
1834 
1835 #ifdef PPS_SYNC
1836 				if (sc->ppsparam.mode & PPS_HARDPPSONASSERT)
1837 					hardpps(&tv, tv.tv_usec);
1838 #endif
1839 				sc->ppsinfo.assert_sequence++;
1840 				sc->ppsinfo.current_mode = sc->ppsparam.mode;
1841 
1842 			} else if ((msr & sc->sc_ppsmask) == sc->sc_ppsclear) {
1843 				/* XXX nanotime() */
1844 				microtime(&tv);
1845 				TIMEVAL_TO_TIMESPEC(&tv,
1846 				    &sc->ppsinfo.clear_timestamp);
1847 				if (sc->ppsparam.mode & PPS_OFFSETCLEAR) {
1848 					timespecadd(&sc->ppsinfo.clear_timestamp,
1849 					    &sc->ppsparam.clear_offset,
1850 					    &sc->ppsinfo.clear_timestamp);
1851 				}
1852 
1853 #ifdef PPS_SYNC
1854 				if (sc->ppsparam.mode & PPS_HARDPPSONCLEAR)
1855 					hardpps(&tv, tv.tv_usec);
1856 #endif
1857 				sc->ppsinfo.clear_sequence++;
1858 				sc->ppsinfo.current_mode = sc->ppsparam.mode;
1859 			}
1860 			mutex_spin_exit(&timecounter_lock);
1861 		}
1862 
1863 		/*
1864 		 * Process normal status changes
1865 		 */
1866 		if (ISSET(delta, sc->sc_msr_mask)) {
1867 			SET(sc->sc_msr_delta, delta);
1868 
1869 			/*
1870 			 * Stop output immediately if we lose the output
1871 			 * flow control signal or carrier detect.
1872 			 */
1873 			if (ISSET(~msr, sc->sc_msr_mask)) {
1874 				sc->sc_tbc = 0;
1875 				sc->sc_heldtbc = 0;
1876 #ifdef PLCOM_DEBUG
1877 				if (plcom_debug)
1878 					plcomstatus(sc, "plcomintr  ");
1879 #endif
1880 			}
1881 
1882 			sc->sc_st_check = 1;
1883 		}
1884 
1885 		/*
1886 		 * Done handling any receive interrupts. See if data
1887 		 * can be * transmitted as well. Schedule tx done
1888 		 * event if no data left * and tty was marked busy.
1889 		 */
1890 		if (ISSET(iir, IIR_TIS)) {
1891 			/*
1892 			 * If we've delayed a parameter change, do it
1893 			 * now, and restart * output.
1894 			 */
1895 			if (sc->sc_heldchange) {
1896 				plcom_loadchannelregs(sc);
1897 				sc->sc_heldchange = 0;
1898 				sc->sc_tbc = sc->sc_heldtbc;
1899 				sc->sc_heldtbc = 0;
1900 			}
1901 
1902 			/*
1903 			 * Output the next chunk of the contiguous
1904 			 * buffer, if any.
1905 			 */
1906 			if (sc->sc_tbc > 0) {
1907 				int n;
1908 
1909 				n = sc->sc_tbc;
1910 				if (n > sc->sc_fifolen)
1911 					n = sc->sc_fifolen;
1912 				bus_space_write_multi_1(iot, ioh, plcom_dr,
1913 				    sc->sc_tba, n);
1914 				sc->sc_tbc -= n;
1915 				sc->sc_tba += n;
1916 			} else {
1917 				/*
1918 				 * Disable transmit plcompletion
1919 				 * interrupts if necessary.
1920 				 */
1921 				if (ISSET(sc->sc_cr, CR_TIE)) {
1922 					CLR(sc->sc_cr, CR_TIE);
1923 					bus_space_write_1(iot, ioh, plcom_cr,
1924 					    sc->sc_cr);
1925 				}
1926 				if (sc->sc_tx_busy) {
1927 					sc->sc_tx_busy = 0;
1928 					sc->sc_tx_done = 1;
1929 				}
1930 			}
1931 		}
1932 	} while (ISSET((iir = bus_space_read_1(iot, ioh, plcom_iir)),
1933 	    IIR_IMASK));
1934 
1935 	PLCOM_UNLOCK(sc);
1936 
1937 	/* Wake up the poller. */
1938 	softint_schedule(sc->sc_si);
1939 
1940 #if NRND > 0 && defined(RND_COM)
1941 	rnd_add_uint32(&sc->rnd_source, iir | rsr);
1942 #endif
1943 
1944 	return 1;
1945 }
1946 
1947 /*
1948  * The following functions are polled getc and putc routines, shared
1949  * by the console and kgdb glue.
1950  *
1951  * The read-ahead code is so that you can detect pending in-band
1952  * cn_magic in polled mode while doing output rather than having to
1953  * wait until the kernel decides it needs input.
1954  */
1955 
1956 #define MAX_READAHEAD	20
1957 static int plcom_readahead[MAX_READAHEAD];
1958 static int plcom_readaheadcount = 0;
1959 
1960 int
1961 plcom_common_getc(dev_t dev, bus_space_tag_t iot, bus_space_handle_t ioh)
1962 {
1963 	int s = splserial();
1964 	u_char stat, c;
1965 
1966 	/* got a character from reading things earlier */
1967 	if (plcom_readaheadcount > 0) {
1968 		int i;
1969 
1970 		c = plcom_readahead[0];
1971 		for (i = 1; i < plcom_readaheadcount; i++) {
1972 			plcom_readahead[i-1] = plcom_readahead[i];
1973 		}
1974 		plcom_readaheadcount--;
1975 		splx(s);
1976 		return c;
1977 	}
1978 
1979 	/* block until a character becomes available */
1980 	while (ISSET(stat = bus_space_read_1(iot, ioh, plcom_fr), FR_RXFE))
1981 		;
1982 
1983 	c = bus_space_read_1(iot, ioh, plcom_dr);
1984 	stat = bus_space_read_1(iot, ioh, plcom_iir);
1985 	{
1986 		int cn_trapped = 0; /* unused */
1987 #ifdef DDB
1988 		extern int db_active;
1989 		if (!db_active)
1990 #endif
1991 			cn_check_magic(dev, c, plcom_cnm_state);
1992 	}
1993 	splx(s);
1994 	return c;
1995 }
1996 
1997 void
1998 plcom_common_putc(dev_t dev, bus_space_tag_t iot, bus_space_handle_t ioh,
1999     int c)
2000 {
2001 	int s = splserial();
2002 	int timo;
2003 
2004 	int cin, stat;
2005 	if (plcom_readaheadcount < MAX_READAHEAD
2006 	     && !ISSET(stat = bus_space_read_1(iot, ioh, plcom_fr), FR_RXFE)) {
2007 		int cn_trapped = 0;
2008 		cin = bus_space_read_1(iot, ioh, plcom_dr);
2009 		stat = bus_space_read_1(iot, ioh, plcom_iir);
2010 		cn_check_magic(dev, cin, plcom_cnm_state);
2011 		plcom_readahead[plcom_readaheadcount++] = cin;
2012 	}
2013 
2014 	/* wait for any pending transmission to finish */
2015 	timo = 150000;
2016 	while (!ISSET(bus_space_read_1(iot, ioh, plcom_fr), FR_TXFE) && --timo)
2017 		continue;
2018 
2019 	bus_space_write_1(iot, ioh, plcom_dr, c);
2020 	PLCOM_BARRIER(iot, ioh, BR | BW);
2021 
2022 	/* wait for this transmission to complete */
2023 	timo = 1500000;
2024 	while (!ISSET(bus_space_read_1(iot, ioh, plcom_fr), FR_TXFE) && --timo)
2025 		continue;
2026 
2027 	splx(s);
2028 }
2029 
2030 /*
2031  * Initialize UART for use as console or KGDB line.
2032  */
2033 int
2034 plcominit(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency,
2035     tcflag_t cflag, bus_space_handle_t *iohp)
2036 {
2037 	bus_space_handle_t ioh;
2038 
2039 	if (bus_space_map(iot, iobase, PLCOM_UART_SIZE, 0, &ioh))
2040 		return ENOMEM; /* ??? */
2041 
2042 	rate = plcomspeed(rate, frequency);
2043 	bus_space_write_1(iot, ioh, plcom_cr, 0);
2044 	bus_space_write_1(iot, ioh, plcom_dlbl, rate);
2045 	bus_space_write_1(iot, ioh, plcom_dlbh, rate >> 8);
2046 	bus_space_write_1(iot, ioh, plcom_lcr, cflag2lcr(cflag) | LCR_FEN);
2047 	bus_space_write_1(iot, ioh, plcom_cr, CR_UARTEN);
2048 
2049 #if 0
2050 	/* Ought to do something like this, but we have no sc to
2051 	   dereference. */
2052 	/* XXX device_unit() abuse */
2053 	sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(&sc->sc_dev),
2054 	    MCR_DTR | MCR_RTS);
2055 #endif
2056 
2057 	*iohp = ioh;
2058 	return 0;
2059 }
2060 
2061 /*
2062  * Following are all routines needed for PLCOM to act as console
2063  */
2064 struct consdev plcomcons = {
2065 	NULL, NULL, plcomcngetc, plcomcnputc, plcomcnpollc, NULL,
2066 	NULL, NULL, NODEV, CN_NORMAL
2067 };
2068 
2069 
2070 int
2071 plcomcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency,
2072     tcflag_t cflag, int unit)
2073 {
2074 	int res;
2075 
2076 	res = plcominit(iot, iobase, rate, frequency, cflag, &plcomconsioh);
2077 	if (res)
2078 		return res;
2079 
2080 	cn_tab = &plcomcons;
2081 	cn_init_magic(&plcom_cnm_state);
2082 	cn_set_magic("\047\001"); /* default magic is BREAK */
2083 
2084 	plcomconstag = iot;
2085 	plcomconsunit = unit;
2086 	plcomconsrate = rate;
2087 	plcomconscflag = cflag;
2088 
2089 	return 0;
2090 }
2091 
2092 void
2093 plcomcndetach(void)
2094 {
2095 	bus_space_unmap(plcomconstag, plcomconsioh, PLCOM_UART_SIZE);
2096 	plcomconstag = NULL;
2097 
2098 	cn_tab = NULL;
2099 }
2100 
2101 int
2102 plcomcngetc(dev_t dev)
2103 {
2104 	return plcom_common_getc(dev, plcomconstag, plcomconsioh);
2105 }
2106 
2107 /*
2108  * Console kernel output character routine.
2109  */
2110 void
2111 plcomcnputc(dev_t dev, int c)
2112 {
2113 	plcom_common_putc(dev, plcomconstag, plcomconsioh, c);
2114 }
2115 
2116 void
2117 plcomcnpollc(dev_t dev, int on)
2118 {
2119 
2120 }
2121 
2122 #ifdef KGDB
2123 int
2124 plcom_kgdb_attach(bus_space_tag_t iot, bus_addr_t iobase, int rate,
2125    int frequency, tcflag_t cflag, int unit)
2126 {
2127 	int res;
2128 
2129 	if (iot == plcomconstag && iobase == plcomconsunit)
2130 		return EBUSY; /* cannot share with console */
2131 
2132 	res = plcominit(iot, iobase, rate, frequency, cflag, &plcom_kgdb_ioh);
2133 	if (res)
2134 		return res;
2135 
2136 	kgdb_attach(plcom_kgdb_getc, plcom_kgdb_putc, NULL);
2137 	kgdb_dev = 123; /* unneeded, only to satisfy some tests */
2138 
2139 	plcom_kgdb_iot = iot;
2140 	plcom_kgdb_unit = unit;
2141 
2142 	return 0;
2143 }
2144 
2145 /* ARGSUSED */
2146 int
2147 plcom_kgdb_getc(void *arg)
2148 {
2149 	return plcom_common_getc(NODEV, plcom_kgdb_iot, plcom_kgdb_ioh);
2150 }
2151 
2152 /* ARGSUSED */
2153 void
2154 plcom_kgdb_putc(void *arg, int c)
2155 {
2156 	plcom_common_putc(NODEV, plcom_kgdb_iot, plcom_kgdb_ioh, c);
2157 }
2158 #endif /* KGDB */
2159 
2160 /* helper function to identify the plcom ports used by
2161  console or KGDB (and not yet autoconf attached) */
2162 int
2163 plcom_is_console(bus_space_tag_t iot, int unit,
2164     bus_space_handle_t *ioh)
2165 {
2166 	bus_space_handle_t help;
2167 
2168 	if (!plcomconsattached &&
2169 	    iot == plcomconstag && unit == plcomconsunit)
2170 		help = plcomconsioh;
2171 #ifdef KGDB
2172 	else if (!plcom_kgdb_attached &&
2173 	    iot == plcom_kgdb_iot && unit == plcom_kgdb_unit)
2174 		help = plcom_kgdb_ioh;
2175 #endif
2176 	else
2177 		return 0;
2178 
2179 	if (ioh)
2180 		*ioh = help;
2181 	return 1;
2182 }
2183