uart_dev_ns8250.c revision 158849
1/*-
2 * Copyright (c) 2003 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/dev/uart/uart_dev_ns8250.c 158849 2006-05-23 06:04:45Z benno $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/conf.h>
34#include <machine/bus.h>
35
36#include <dev/uart/uart.h>
37#include <dev/uart/uart_cpu.h>
38#include <dev/uart/uart_bus.h>
39
40#include <dev/ic/ns16550.h>
41
42#include "uart_if.h"
43
44#define	DEFAULT_RCLK	1843200
45
46/*
47 * Clear pending interrupts. THRE is cleared by reading IIR. Data
48 * that may have been received gets lost here.
49 */
50static void
51ns8250_clrint(struct uart_bas *bas)
52{
53	uint8_t iir;
54
55	iir = uart_getreg(bas, REG_IIR);
56	while ((iir & IIR_NOPEND) == 0) {
57		iir &= IIR_IMASK;
58		if (iir == IIR_RLS)
59			(void)uart_getreg(bas, REG_LSR);
60		else if (iir == IIR_RXRDY || iir == IIR_RXTOUT)
61			(void)uart_getreg(bas, REG_DATA);
62		else if (iir == IIR_MLSC)
63			(void)uart_getreg(bas, REG_MSR);
64		uart_barrier(bas);
65		iir = uart_getreg(bas, REG_IIR);
66	}
67}
68
69static int
70ns8250_delay(struct uart_bas *bas)
71{
72	int divisor;
73	u_char lcr;
74
75	lcr = uart_getreg(bas, REG_LCR);
76	uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
77	uart_barrier(bas);
78	divisor = uart_getreg(bas, REG_DLL) | (uart_getreg(bas, REG_DLH) << 8);
79	uart_barrier(bas);
80	uart_setreg(bas, REG_LCR, lcr);
81	uart_barrier(bas);
82
83	/* 1/10th the time to transmit 1 character (estimate). */
84	return (16000000 * divisor / bas->rclk);
85}
86
87static int
88ns8250_divisor(int rclk, int baudrate)
89{
90	int actual_baud, divisor;
91	int error;
92
93	if (baudrate == 0)
94		return (0);
95
96	divisor = (rclk / (baudrate << 3) + 1) >> 1;
97	if (divisor == 0 || divisor >= 65536)
98		return (0);
99	actual_baud = rclk / (divisor << 4);
100
101	/* 10 times error in percent: */
102	error = ((actual_baud - baudrate) * 2000 / baudrate + 1) >> 1;
103
104	/* 3.0% maximum error tolerance: */
105	if (error < -30 || error > 30)
106		return (0);
107
108	return (divisor);
109}
110
111static int
112ns8250_drain(struct uart_bas *bas, int what)
113{
114	int delay, limit;
115
116	delay = ns8250_delay(bas);
117
118	if (what & UART_DRAIN_TRANSMITTER) {
119		/*
120		 * Pick an arbitrary high limit to avoid getting stuck in
121		 * an infinite loop when the hardware is broken. Make the
122		 * limit high enough to handle large FIFOs.
123		 */
124		limit = 10*1024;
125		while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit)
126			DELAY(delay);
127		if (limit == 0) {
128			/* printf("ns8250: transmitter appears stuck... "); */
129			return (EIO);
130		}
131	}
132
133	if (what & UART_DRAIN_RECEIVER) {
134		/*
135		 * Pick an arbitrary high limit to avoid getting stuck in
136		 * an infinite loop when the hardware is broken. Make the
137		 * limit high enough to handle large FIFOs and integrated
138		 * UARTs. The HP rx2600 for example has 3 UARTs on the
139		 * management board that tend to get a lot of data send
140		 * to it when the UART is first activated.
141		 */
142		limit=10*4096;
143		while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) && --limit) {
144			(void)uart_getreg(bas, REG_DATA);
145			uart_barrier(bas);
146			DELAY(delay << 2);
147		}
148		if (limit == 0) {
149			/* printf("ns8250: receiver appears broken... "); */
150			return (EIO);
151		}
152	}
153
154	return (0);
155}
156
157/*
158 * We can only flush UARTs with FIFOs. UARTs without FIFOs should be
159 * drained. WARNING: this function clobbers the FIFO setting!
160 */
161static void
162ns8250_flush(struct uart_bas *bas, int what)
163{
164	uint8_t fcr;
165
166	fcr = FCR_ENABLE;
167	if (what & UART_FLUSH_TRANSMITTER)
168		fcr |= FCR_XMT_RST;
169	if (what & UART_FLUSH_RECEIVER)
170		fcr |= FCR_RCV_RST;
171	uart_setreg(bas, REG_FCR, fcr);
172	uart_barrier(bas);
173}
174
175static int
176ns8250_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
177    int parity)
178{
179	int divisor;
180	uint8_t lcr;
181
182	lcr = 0;
183	if (databits >= 8)
184		lcr |= LCR_8BITS;
185	else if (databits == 7)
186		lcr |= LCR_7BITS;
187	else if (databits == 6)
188		lcr |= LCR_6BITS;
189	else
190		lcr |= LCR_5BITS;
191	if (stopbits > 1)
192		lcr |= LCR_STOPB;
193	lcr |= parity << 3;
194
195	/* Set baudrate. */
196	if (baudrate > 0) {
197		divisor = ns8250_divisor(bas->rclk, baudrate);
198		if (divisor == 0)
199			return (EINVAL);
200		uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
201		uart_barrier(bas);
202		uart_setreg(bas, REG_DLL, divisor & 0xff);
203		uart_setreg(bas, REG_DLH, (divisor >> 8) & 0xff);
204		uart_barrier(bas);
205	}
206
207	/* Set LCR and clear DLAB. */
208	uart_setreg(bas, REG_LCR, lcr);
209	uart_barrier(bas);
210	return (0);
211}
212
213/*
214 * Low-level UART interface.
215 */
216static int ns8250_probe(struct uart_bas *bas);
217static void ns8250_init(struct uart_bas *bas, int, int, int, int);
218static void ns8250_term(struct uart_bas *bas);
219static void ns8250_putc(struct uart_bas *bas, int);
220static int ns8250_poll(struct uart_bas *bas);
221static int ns8250_getc(struct uart_bas *bas, struct mtx *);
222
223struct uart_ops uart_ns8250_ops = {
224	.probe = ns8250_probe,
225	.init = ns8250_init,
226	.term = ns8250_term,
227	.putc = ns8250_putc,
228	.poll = ns8250_poll,
229	.getc = ns8250_getc,
230};
231
232static int
233ns8250_probe(struct uart_bas *bas)
234{
235	u_char val;
236
237	/* Check known 0 bits that don't depend on DLAB. */
238	val = uart_getreg(bas, REG_IIR);
239	if (val & 0x30)
240		return (ENXIO);
241	val = uart_getreg(bas, REG_MCR);
242	if (val & 0xe0)
243		return (ENXIO);
244
245	return (0);
246}
247
248static void
249ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
250    int parity)
251{
252	u_char	ier;
253
254	if (bas->rclk == 0)
255		bas->rclk = DEFAULT_RCLK;
256	ns8250_param(bas, baudrate, databits, stopbits, parity);
257
258	/* Disable all interrupt sources. */
259	ier = uart_getreg(bas, REG_IER) & 0xf0;
260	uart_setreg(bas, REG_IER, ier);
261	uart_barrier(bas);
262
263	/* Disable the FIFO (if present). */
264	uart_setreg(bas, REG_FCR, 0);
265	uart_barrier(bas);
266
267	/* Set RTS & DTR. */
268	uart_setreg(bas, REG_MCR, MCR_IE | MCR_RTS | MCR_DTR);
269	uart_barrier(bas);
270
271	ns8250_clrint(bas);
272}
273
274static void
275ns8250_term(struct uart_bas *bas)
276{
277
278	/* Clear RTS & DTR. */
279	uart_setreg(bas, REG_MCR, MCR_IE);
280	uart_barrier(bas);
281}
282
283static void
284ns8250_putc(struct uart_bas *bas, int c)
285{
286	int delay, limit;
287
288	/* 1/10th the time to transmit 1 character (estimate). */
289	delay = ns8250_delay(bas);
290
291	limit = 20;
292	while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0 && --limit)
293		DELAY(delay);
294	uart_setreg(bas, REG_DATA, c);
295	uart_barrier(bas);
296	limit = 40;
297	while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit)
298		DELAY(delay);
299}
300
301static int
302ns8250_poll(struct uart_bas *bas)
303{
304
305	if (uart_getreg(bas, REG_LSR) & LSR_RXRDY)
306		return (uart_getreg(bas, REG_DATA));
307	return (-1);
308}
309
310static int
311ns8250_getc(struct uart_bas *bas, struct mtx *hwmtx)
312{
313	int c, delay;
314
315	uart_lock(hwmtx);
316
317	/* 1/10th the time to transmit 1 character (estimate). */
318	delay = ns8250_delay(bas);
319
320	while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) == 0) {
321		uart_unlock(hwmtx);
322		DELAY(delay);
323		uart_lock(hwmtx);
324	}
325
326	c = uart_getreg(bas, REG_DATA);
327
328	uart_unlock(hwmtx);
329
330	return (c);
331}
332
333/*
334 * High-level UART interface.
335 */
336struct ns8250_softc {
337	struct uart_softc base;
338	uint8_t		fcr;
339	uint8_t		ier;
340	uint8_t		mcr;
341};
342
343static int ns8250_bus_attach(struct uart_softc *);
344static int ns8250_bus_detach(struct uart_softc *);
345static int ns8250_bus_flush(struct uart_softc *, int);
346static int ns8250_bus_getsig(struct uart_softc *);
347static int ns8250_bus_ioctl(struct uart_softc *, int, intptr_t);
348static int ns8250_bus_ipend(struct uart_softc *);
349static int ns8250_bus_param(struct uart_softc *, int, int, int, int);
350static int ns8250_bus_probe(struct uart_softc *);
351static int ns8250_bus_receive(struct uart_softc *);
352static int ns8250_bus_setsig(struct uart_softc *, int);
353static int ns8250_bus_transmit(struct uart_softc *);
354
355static kobj_method_t ns8250_methods[] = {
356	KOBJMETHOD(uart_attach,		ns8250_bus_attach),
357	KOBJMETHOD(uart_detach,		ns8250_bus_detach),
358	KOBJMETHOD(uart_flush,		ns8250_bus_flush),
359	KOBJMETHOD(uart_getsig,		ns8250_bus_getsig),
360	KOBJMETHOD(uart_ioctl,		ns8250_bus_ioctl),
361	KOBJMETHOD(uart_ipend,		ns8250_bus_ipend),
362	KOBJMETHOD(uart_param,		ns8250_bus_param),
363	KOBJMETHOD(uart_probe,		ns8250_bus_probe),
364	KOBJMETHOD(uart_receive,	ns8250_bus_receive),
365	KOBJMETHOD(uart_setsig,		ns8250_bus_setsig),
366	KOBJMETHOD(uart_transmit,	ns8250_bus_transmit),
367	{ 0, 0 }
368};
369
370struct uart_class uart_ns8250_class = {
371	"ns8250 class",
372	ns8250_methods,
373	sizeof(struct ns8250_softc),
374	.uc_range = 8,
375	.uc_rclk = DEFAULT_RCLK
376};
377
378#define	SIGCHG(c, i, s, d)				\
379	if (c) {					\
380		i |= (i & s) ? s : s | d;		\
381	} else {					\
382		i = (i & s) ? (i & ~s) | d : i;		\
383	}
384
385static int
386ns8250_bus_attach(struct uart_softc *sc)
387{
388	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
389	struct uart_bas *bas;
390
391	bas = &sc->sc_bas;
392
393	ns8250->mcr = uart_getreg(bas, REG_MCR);
394	ns8250->fcr = FCR_ENABLE | FCR_RX_MEDH;
395	uart_setreg(bas, REG_FCR, ns8250->fcr);
396	uart_barrier(bas);
397	ns8250_bus_flush(sc, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
398
399	if (ns8250->mcr & MCR_DTR)
400		sc->sc_hwsig |= SER_DTR;
401	if (ns8250->mcr & MCR_RTS)
402		sc->sc_hwsig |= SER_RTS;
403	ns8250_bus_getsig(sc);
404
405	ns8250_clrint(bas);
406	ns8250->ier = uart_getreg(bas, REG_IER) & 0xf0;
407	ns8250->ier |= IER_EMSC | IER_ERLS | IER_ERXRDY;
408	uart_setreg(bas, REG_IER, ns8250->ier);
409	uart_barrier(bas);
410	return (0);
411}
412
413static int
414ns8250_bus_detach(struct uart_softc *sc)
415{
416	struct uart_bas *bas;
417	u_char ier;
418
419	bas = &sc->sc_bas;
420	ier = uart_getreg(bas, REG_IER) & 0xf0;
421	uart_setreg(bas, REG_IER, ier);
422	uart_barrier(bas);
423	ns8250_clrint(bas);
424	return (0);
425}
426
427static int
428ns8250_bus_flush(struct uart_softc *sc, int what)
429{
430	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
431	struct uart_bas *bas;
432	int error;
433
434	bas = &sc->sc_bas;
435	uart_lock(sc->sc_hwmtx);
436	if (sc->sc_rxfifosz > 1) {
437		ns8250_flush(bas, what);
438		uart_setreg(bas, REG_FCR, ns8250->fcr);
439		uart_barrier(bas);
440		error = 0;
441	} else
442		error = ns8250_drain(bas, what);
443	uart_unlock(sc->sc_hwmtx);
444	return (error);
445}
446
447static int
448ns8250_bus_getsig(struct uart_softc *sc)
449{
450	uint32_t new, old, sig;
451	uint8_t msr;
452
453	do {
454		old = sc->sc_hwsig;
455		sig = old;
456		uart_lock(sc->sc_hwmtx);
457		msr = uart_getreg(&sc->sc_bas, REG_MSR);
458		uart_unlock(sc->sc_hwmtx);
459		SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR);
460		SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS);
461		SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD);
462		SIGCHG(msr & MSR_RI,  sig, SER_RI,  SER_DRI);
463		new = sig & ~SER_MASK_DELTA;
464	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
465	return (sig);
466}
467
468static int
469ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
470{
471	struct uart_bas *bas;
472	int baudrate, divisor, error;
473	uint8_t efr, lcr;
474
475	bas = &sc->sc_bas;
476	error = 0;
477	uart_lock(sc->sc_hwmtx);
478	switch (request) {
479	case UART_IOCTL_BREAK:
480		lcr = uart_getreg(bas, REG_LCR);
481		if (data)
482			lcr |= LCR_SBREAK;
483		else
484			lcr &= ~LCR_SBREAK;
485		uart_setreg(bas, REG_LCR, lcr);
486		uart_barrier(bas);
487		break;
488	case UART_IOCTL_IFLOW:
489		lcr = uart_getreg(bas, REG_LCR);
490		uart_barrier(bas);
491		uart_setreg(bas, REG_LCR, 0xbf);
492		uart_barrier(bas);
493		efr = uart_getreg(bas, REG_EFR);
494		if (data)
495			efr |= EFR_RTS;
496		else
497			efr &= ~EFR_RTS;
498		uart_setreg(bas, REG_EFR, efr);
499		uart_barrier(bas);
500		uart_setreg(bas, REG_LCR, lcr);
501		uart_barrier(bas);
502		break;
503	case UART_IOCTL_OFLOW:
504		lcr = uart_getreg(bas, REG_LCR);
505		uart_barrier(bas);
506		uart_setreg(bas, REG_LCR, 0xbf);
507		uart_barrier(bas);
508		efr = uart_getreg(bas, REG_EFR);
509		if (data)
510			efr |= EFR_CTS;
511		else
512			efr &= ~EFR_CTS;
513		uart_setreg(bas, REG_EFR, efr);
514		uart_barrier(bas);
515		uart_setreg(bas, REG_LCR, lcr);
516		uart_barrier(bas);
517		break;
518	case UART_IOCTL_BAUD:
519		lcr = uart_getreg(bas, REG_LCR);
520		uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
521		uart_barrier(bas);
522		divisor = uart_getreg(bas, REG_DLL) |
523		    (uart_getreg(bas, REG_DLH) << 8);
524		uart_barrier(bas);
525		uart_setreg(bas, REG_LCR, lcr);
526		uart_barrier(bas);
527		baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0;
528		if (baudrate > 0)
529			*(int*)data = baudrate;
530		else
531			error = ENXIO;
532		break;
533	default:
534		error = EINVAL;
535		break;
536	}
537	uart_unlock(sc->sc_hwmtx);
538	return (error);
539}
540
541static int
542ns8250_bus_ipend(struct uart_softc *sc)
543{
544	struct uart_bas *bas;
545	int ipend;
546	uint8_t iir, lsr;
547
548	bas = &sc->sc_bas;
549	uart_lock(sc->sc_hwmtx);
550	iir = uart_getreg(bas, REG_IIR);
551	if (iir & IIR_NOPEND) {
552		uart_unlock(sc->sc_hwmtx);
553		return (0);
554	}
555	ipend = 0;
556	if (iir & IIR_RXRDY) {
557		lsr = uart_getreg(bas, REG_LSR);
558		uart_unlock(sc->sc_hwmtx);
559		if (lsr & LSR_OE)
560			ipend |= SER_INT_OVERRUN;
561		if (lsr & LSR_BI)
562			ipend |= SER_INT_BREAK;
563		if (lsr & LSR_RXRDY)
564			ipend |= SER_INT_RXREADY;
565	} else {
566		uart_unlock(sc->sc_hwmtx);
567		if (iir & IIR_TXRDY)
568			ipend |= SER_INT_TXIDLE;
569		else
570			ipend |= SER_INT_SIGCHG;
571	}
572	return ((sc->sc_leaving) ? 0 : ipend);
573}
574
575static int
576ns8250_bus_param(struct uart_softc *sc, int baudrate, int databits,
577    int stopbits, int parity)
578{
579	struct uart_bas *bas;
580	int error;
581
582	bas = &sc->sc_bas;
583	uart_lock(sc->sc_hwmtx);
584	error = ns8250_param(bas, baudrate, databits, stopbits, parity);
585	uart_unlock(sc->sc_hwmtx);
586	return (error);
587}
588
589static int
590ns8250_bus_probe(struct uart_softc *sc)
591{
592	struct uart_bas *bas;
593	int count, delay, error, limit;
594	uint8_t lsr, mcr, ier;
595
596	bas = &sc->sc_bas;
597
598	error = ns8250_probe(bas);
599	if (error)
600		return (error);
601
602	mcr = MCR_IE;
603	if (sc->sc_sysdev == NULL) {
604		/* By using ns8250_init() we also set DTR and RTS. */
605		ns8250_init(bas, 115200, 8, 1, UART_PARITY_NONE);
606	} else
607		mcr |= MCR_DTR | MCR_RTS;
608
609	error = ns8250_drain(bas, UART_DRAIN_TRANSMITTER);
610	if (error)
611		return (error);
612
613	/*
614	 * Set loopback mode. This avoids having garbage on the wire and
615	 * also allows us send and receive data. We set DTR and RTS to
616	 * avoid the possibility that automatic flow-control prevents
617	 * any data from being sent.
618	 */
619	uart_setreg(bas, REG_MCR, MCR_LOOPBACK | MCR_IE | MCR_DTR | MCR_RTS);
620	uart_barrier(bas);
621
622	/*
623	 * Enable FIFOs. And check that the UART has them. If not, we're
624	 * done. Since this is the first time we enable the FIFOs, we reset
625	 * them.
626	 */
627	uart_setreg(bas, REG_FCR, FCR_ENABLE);
628	uart_barrier(bas);
629	if (!(uart_getreg(bas, REG_IIR) & IIR_FIFO_MASK)) {
630		/*
631		 * NS16450 or INS8250. We don't bother to differentiate
632		 * between them. They're too old to be interesting.
633		 */
634		uart_setreg(bas, REG_MCR, mcr);
635		uart_barrier(bas);
636		sc->sc_rxfifosz = sc->sc_txfifosz = 1;
637		device_set_desc(sc->sc_dev, "8250 or 16450 or compatible");
638		return (0);
639	}
640
641	uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST);
642	uart_barrier(bas);
643
644	count = 0;
645	delay = ns8250_delay(bas);
646
647	/* We have FIFOs. Drain the transmitter and receiver. */
648	error = ns8250_drain(bas, UART_DRAIN_RECEIVER|UART_DRAIN_TRANSMITTER);
649	if (error) {
650		uart_setreg(bas, REG_MCR, mcr);
651		uart_setreg(bas, REG_FCR, 0);
652		uart_barrier(bas);
653		goto describe;
654	}
655
656	/*
657	 * We should have a sufficiently clean "pipe" to determine the
658	 * size of the FIFOs. We send as much characters as is reasonable
659	 * and wait for the the overflow bit in the LSR register to be
660	 * asserted, counting the characters as we send them. Based on
661	 * that count we know the FIFO size.
662	 */
663	do {
664		uart_setreg(bas, REG_DATA, 0);
665		uart_barrier(bas);
666		count++;
667
668		limit = 30;
669		lsr = 0;
670		/*
671		 * LSR bits are cleared upon read, so we must accumulate
672		 * them to be able to test LSR_OE below.
673		 */
674		while (((lsr |= uart_getreg(bas, REG_LSR)) & LSR_TEMT) == 0 &&
675		    --limit)
676			DELAY(delay);
677		if (limit == 0) {
678			ier = uart_getreg(bas, REG_IER) & 0xf0;
679			uart_setreg(bas, REG_IER, ier);
680			uart_setreg(bas, REG_MCR, mcr);
681			uart_setreg(bas, REG_FCR, 0);
682			uart_barrier(bas);
683			count = 0;
684			goto describe;
685		}
686	} while ((lsr & LSR_OE) == 0 && count < 130);
687	count--;
688
689	uart_setreg(bas, REG_MCR, mcr);
690
691	/* Reset FIFOs. */
692	ns8250_flush(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
693
694 describe:
695	if (count >= 14 && count <= 16) {
696		sc->sc_rxfifosz = 16;
697		device_set_desc(sc->sc_dev, "16550 or compatible");
698	} else if (count >= 28 && count <= 32) {
699		sc->sc_rxfifosz = 32;
700		device_set_desc(sc->sc_dev, "16650 or compatible");
701	} else if (count >= 56 && count <= 64) {
702		sc->sc_rxfifosz = 64;
703		device_set_desc(sc->sc_dev, "16750 or compatible");
704	} else if (count >= 112 && count <= 128) {
705		sc->sc_rxfifosz = 128;
706		device_set_desc(sc->sc_dev, "16950 or compatible");
707	} else {
708		sc->sc_rxfifosz = 16;
709		device_set_desc(sc->sc_dev,
710		    "Non-standard ns8250 class UART with FIFOs");
711	}
712
713	/*
714	 * Force the Tx FIFO size to 16 bytes for now. We don't program the
715	 * Tx trigger. Also, we assume that all data has been sent when the
716	 * interrupt happens.
717	 */
718	sc->sc_txfifosz = 16;
719
720#if 0
721	/*
722	 * XXX there are some issues related to hardware flow control and
723	 * it's likely that uart(4) is the cause. This basicly needs more
724	 * investigation, but we avoid using for hardware flow control
725	 * until then.
726	 */
727	/* 16650s or higher have automatic flow control. */
728	if (sc->sc_rxfifosz > 16) {
729		sc->sc_hwiflow = 1;
730		sc->sc_hwoflow = 1;
731	}
732#endif
733
734	return (0);
735}
736
737static int
738ns8250_bus_receive(struct uart_softc *sc)
739{
740	struct uart_bas *bas;
741	int xc;
742	uint8_t lsr;
743
744	bas = &sc->sc_bas;
745	uart_lock(sc->sc_hwmtx);
746	lsr = uart_getreg(bas, REG_LSR);
747	while (lsr & LSR_RXRDY) {
748		if (uart_rx_full(sc)) {
749			sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
750			break;
751		}
752		xc = uart_getreg(bas, REG_DATA);
753		if (lsr & LSR_FE)
754			xc |= UART_STAT_FRAMERR;
755		if (lsr & LSR_PE)
756			xc |= UART_STAT_PARERR;
757		uart_rx_put(sc, xc);
758		lsr = uart_getreg(bas, REG_LSR);
759	}
760	/* Discard everything left in the Rx FIFO. */
761	while (lsr & LSR_RXRDY) {
762		(void)uart_getreg(bas, REG_DATA);
763		uart_barrier(bas);
764		lsr = uart_getreg(bas, REG_LSR);
765	}
766	uart_unlock(sc->sc_hwmtx);
767 	return (0);
768}
769
770static int
771ns8250_bus_setsig(struct uart_softc *sc, int sig)
772{
773	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
774	struct uart_bas *bas;
775	uint32_t new, old;
776
777	bas = &sc->sc_bas;
778	do {
779		old = sc->sc_hwsig;
780		new = old;
781		if (sig & SER_DDTR) {
782			SIGCHG(sig & SER_DTR, new, SER_DTR,
783			    SER_DDTR);
784		}
785		if (sig & SER_DRTS) {
786			SIGCHG(sig & SER_RTS, new, SER_RTS,
787			    SER_DRTS);
788		}
789	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
790	uart_lock(sc->sc_hwmtx);
791	ns8250->mcr &= ~(MCR_DTR|MCR_RTS);
792	if (new & SER_DTR)
793		ns8250->mcr |= MCR_DTR;
794	if (new & SER_RTS)
795		ns8250->mcr |= MCR_RTS;
796	uart_setreg(bas, REG_MCR, ns8250->mcr);
797	uart_barrier(bas);
798	uart_unlock(sc->sc_hwmtx);
799	return (0);
800}
801
802static int
803ns8250_bus_transmit(struct uart_softc *sc)
804{
805	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
806	struct uart_bas *bas;
807	int i;
808
809	bas = &sc->sc_bas;
810	uart_lock(sc->sc_hwmtx);
811	while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0)
812		;
813	uart_setreg(bas, REG_IER, ns8250->ier | IER_ETXRDY);
814	uart_barrier(bas);
815	for (i = 0; i < sc->sc_txdatasz; i++) {
816		uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]);
817		uart_barrier(bas);
818	}
819	sc->sc_txbusy = 1;
820	uart_unlock(sc->sc_hwmtx);
821	return (0);
822}
823