summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2005-09-26 22:32:07 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2005-09-26 22:32:07 +0000
commit6e2b42bd89bd45b8441c9c3b19f2deea36837b82 (patch)
treeb19c2bfb430a61a41aca890a54bc33cafacb9bfb /sys/dev
parent2a98855f6e6d38369b257c2f999103d445922b14 (diff)
Share com probe code between com and pccom; allows us to get rid of awkward
code duplication in cardbus, pcmcia and puc attachments. Joint effort with fgs@; blessed deraadt@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/cardbus/com_cardbus.c184
-rw-r--r--sys/dev/ic/com.c239
-rw-r--r--sys/dev/ic/com_subr.c378
-rw-r--r--sys/dev/pcmcia/com_pcmcia.c182
-rw-r--r--sys/dev/puc/com_puc.c174
5 files changed, 401 insertions, 756 deletions
diff --git a/sys/dev/cardbus/com_cardbus.c b/sys/dev/cardbus/com_cardbus.c
index 0c9a7fdb3b9..0690e63492f 100644
--- a/sys/dev/cardbus/com_cardbus.c
+++ b/sys/dev/cardbus/com_cardbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: com_cardbus.c,v 1.17 2005/07/25 01:38:15 pascoe Exp $ */
+/* $OpenBSD: com_cardbus.c,v 1.18 2005/09/26 22:32:06 miod Exp $ */
/* $NetBSD: com_cardbus.c,v 1.4 2000/04/17 09:21:59 joda Exp $ */
/*
@@ -101,7 +101,6 @@ void com_cardbus_disable(struct com_softc *);
struct csdev *com_cardbus_find_csdev(struct cardbus_attach_args *);
int com_cardbus_gofigure(struct cardbus_attach_args *,
struct com_cardbus_softc *);
-void com_cardbus_attach2(struct com_softc *, u_char);
#if NCOM_CARDBUS
struct cfattach com_cardbus_ca = {
@@ -276,9 +275,6 @@ com_cardbus_attach(struct device *parent, struct device *self, void *aux)
sc->sc_iobase = csc->cc_addr;
sc->sc_frequency = COM_FREQ;
- timeout_set(&sc->sc_dtr_tmo, com_raisedtr, sc);
- timeout_set(&sc->sc_diag_tmo, comdiag, sc);
-
sc->enable = com_cardbus_enable;
sc->disable = com_cardbus_disable;
sc->enabled = 0;
@@ -292,7 +288,14 @@ com_cardbus_attach(struct device *parent, struct device *self, void *aux)
if (com_cardbus_enable(sc))
printf(": function enable failed\n");
sc->enabled = 1;
- com_cardbus_attach2(sc, csc->cc_bug);
+
+ sc->sc_hwflags = 0;
+ sc->sc_swflags = 0;
+
+ if (csc->cc_bug & BUG_BROADCOM)
+ sc->sc_fifolen = 15;
+
+ com_attach_subr(sc);
}
void
@@ -384,172 +387,3 @@ com_cardbus_detach(struct device *self, int flags)
return (0);
}
-
-
-/*
- * XXX This should be handled by a generic attach
- */
-void
-com_cardbus_attach2(struct com_softc *sc, u_char bug)
-{
- bus_space_tag_t iot = sc->sc_iot;
- bus_space_handle_t ioh = sc->sc_ioh;
- u_int8_t lcr;
-
- sc->sc_hwflags = 0;
- sc->sc_swflags = 0;
-
- /*
- * Probe for all known forms of UART.
- */
- lcr = bus_space_read_1(iot, ioh, com_lcr);
-
- bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
- bus_space_write_1(iot, ioh, com_efr, 0);
- bus_space_write_1(iot, ioh, com_lcr, 0);
-
- bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
- delay(100);
-
- switch(bus_space_read_1(iot, ioh, com_iir) >> 6) {
- case 0:
- sc->sc_uarttype = COM_UART_16450;
- break;
- case 2:
- sc->sc_uarttype = COM_UART_16550;
- break;
- case 3:
- sc->sc_uarttype = COM_UART_16550A;
- break;
- default:
- sc->sc_uarttype = COM_UART_UNKNOWN;
- break;
- }
-
- if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */
- bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
- if (bus_space_read_1(iot, ioh, com_efr) == 0) {
- sc->sc_uarttype = COM_UART_ST16650;
- } else {
- bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
- if (bus_space_read_1(iot, ioh, com_efr) == 0)
- sc->sc_uarttype = COM_UART_ST16650V2;
- }
- }
-
- if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for TI16750s */
- bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
- bus_space_write_1(iot, ioh, com_fifo,
- FIFO_ENABLE | FIFO_ENABLE_64BYTE);
- if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 7) {
-#if 0
- bus_space_write_1(iot, ioh, com_lcr, 0);
- if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 6)
-#endif
- sc->sc_uarttype = COM_UART_TI16750;
- }
- bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
- }
-
-#if NPCCOM > 0
-#ifdef i386
- if (sc->sc_uarttype == COM_UART_ST16650V2) { /* Probe for XR16850s */
- u_int8_t dlbl, dlbh;
-
- /* Enable latch access and get the current values. */
- bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
- dlbl = bus_space_read_1(iot, ioh, com_dlbl);
- dlbh = bus_space_read_1(iot, ioh, com_dlbh);
-
- /* Zero out the latch divisors */
- bus_space_write_1(iot, ioh, com_dlbl, 0);
- bus_space_write_1(iot, ioh, com_dlbh, 0);
-
- if (bus_space_read_1(iot, ioh, com_dlbh) == 0x10) {
- sc->sc_uarttype = COM_UART_XR16850;
- sc->sc_uartrev = bus_space_read_1(iot, ioh, com_dlbl);
- }
-
- /* Reset to original. */
- bus_space_write_1(iot, ioh, com_dlbl, dlbl);
- bus_space_write_1(iot, ioh, com_dlbh, dlbh);
- }
-#endif
-#endif
-
- /* Reset the LCR (latch access is probably enabled). */
- bus_space_write_1(iot, ioh, com_lcr, lcr);
- if (sc->sc_uarttype == COM_UART_16450) { /* Probe for 8250 */
- u_int8_t scr0, scr1, scr2;
-
- scr0 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, 0xa5);
- scr1 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, 0x5a);
- scr2 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, scr0);
-
- if ((scr1 != 0xa5) || (scr2 != 0x5a))
- sc->sc_uarttype = COM_UART_8250;
- }
-
- /*
- * Print UART type and initialize ourself.
- */
- sc->sc_fifolen = 1; /* default */
- printf(" ");
- switch (sc->sc_uarttype) {
- case COM_UART_UNKNOWN:
- printf("unknown uart\n");
- break;
- case COM_UART_8250:
- printf("ns8250, no fifo\n");
- break;
- case COM_UART_16450:
- printf("ns16450, no fifo\n");
- break;
- case COM_UART_16550:
- printf("ns16550, no working fifo\n");
- break;
- case COM_UART_16550A:
- if (bug & BUG_BROADCOM) {
- printf("Broadcom ns16550a, 15 byte fifo\n");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 15;
- break;
- }
- printf("ns16550a, 16 byte fifo\n");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 16;
- break;
- case COM_UART_ST16650:
- printf("st16650, no working fifo\n");
- break;
- case COM_UART_ST16650V2:
- printf("st16650, 32 byte fifo\n");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 32;
- break;
- case COM_UART_TI16750:
- printf("ti16750, 64 byte fifo\n");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 64;
- break;
-#if NPCCOM > 0
-#ifdef i386
- case COM_UART_XR16850:
- printf("xr16850 (rev %d), 128 byte fifo\n", sc->sc_uartrev);
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 128;
- break;
-#endif
-#endif
- default:
- panic("comattach: bad fifo type");
- }
-
- /* clear and disable fifo */
- bus_space_write_1(iot, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST);
- (void)bus_space_read_1(iot, ioh, com_data);
- bus_space_write_1(iot, ioh, com_fifo, 0);
-}
diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c
index 658f1216fa8..36599ede3cf 100644
--- a/sys/dev/ic/com.c
+++ b/sys/dev/ic/com.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: com.c,v 1.105 2005/07/18 16:18:28 deraadt Exp $ */
+/* $OpenBSD: com.c,v 1.106 2005/09/26 22:32:06 miod Exp $ */
/* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */
/*
@@ -111,7 +111,6 @@ cdev_decl(com);
static u_char tiocm_xxx2mcr(int);
void compwroff(struct com_softc *);
-void com_enable_debugport(struct com_softc *);
void cominit(bus_space_tag_t, bus_space_handle_t, int, int);
int com_is_console(bus_space_tag_t, bus_addr_t);
@@ -200,238 +199,6 @@ comprobe1(iot, ioh)
}
#endif
-void
-com_attach_subr(sc)
- struct com_softc *sc;
-{
- bus_space_tag_t iot = sc->sc_iot;
- bus_space_handle_t ioh = sc->sc_ioh;
- u_int8_t lcr;
-
- sc->sc_ier = 0;
-#ifdef COM_PXA2X0
- if (sc->sc_uarttype == COM_UART_PXA2X0)
- sc->sc_ier |= IER_EUART;
-#endif
- /* disable interrupts */
- bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
-
-#ifdef COM_CONSOLE
- if (sc->sc_iobase == comconsaddr) {
- comconsattached = 1;
-
- /*
- * Need to reset baud rate, etc. of next print so reset
- * comconsinit. Also make sure console is always "hardwired".
- */
- delay(10000); /* wait for output to finish */
- SET(sc->sc_hwflags, COM_HW_CONSOLE);
- SET(sc->sc_swflags, COM_SW_SOFTCAR);
- }
-#endif
-
- /*
- * Probe for all known forms of UART.
- */
- lcr = bus_space_read_1(iot, ioh, com_lcr);
- bus_space_write_1(iot, ioh, com_lcr, 0xbf);
- bus_space_write_1(iot, ioh, com_efr, 0);
- bus_space_write_1(iot, ioh, com_lcr, 0);
-
- bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
- delay(100);
-
-#ifdef COM_PXA2X0
- /* Attachment driver presets COM_UART_PXA2X0. */
- if (sc->sc_uarttype != COM_UART_PXA2X0)
-#endif
- switch(bus_space_read_1(iot, ioh, com_iir) >> 6) {
- case 0:
- sc->sc_uarttype = COM_UART_16450;
- break;
- case 2:
- sc->sc_uarttype = COM_UART_16550;
- break;
- case 3:
- sc->sc_uarttype = COM_UART_16550A;
- break;
- default:
- sc->sc_uarttype = COM_UART_UNKNOWN;
- break;
- }
-
- if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */
- bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
- if (bus_space_read_1(iot, ioh, com_efr) == 0) {
- sc->sc_uarttype = COM_UART_ST16650;
- } else {
- bus_space_write_1(iot, ioh, com_lcr, 0xbf);
- if (bus_space_read_1(iot, ioh, com_efr) == 0)
- sc->sc_uarttype = COM_UART_ST16650V2;
- }
- }
-
- if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for TI16750s */
- bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
- bus_space_write_1(iot, ioh, com_fifo,
- FIFO_ENABLE | FIFO_ENABLE_64BYTE);
- if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 7) {
-#if 0
- bus_space_write_1(iot, ioh, com_lcr, 0);
- if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 6)
-#endif
- sc->sc_uarttype = COM_UART_TI16750;
- }
- bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
- }
- bus_space_write_1(iot, ioh, com_lcr, lcr);
- if (sc->sc_uarttype == COM_UART_16450) { /* Probe for 8250 */
- u_int8_t scr0, scr1, scr2;
-
- scr0 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, 0xa5);
- scr1 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, 0x5a);
- scr2 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, scr0);
-
- if ((scr1 != 0xa5) || (scr2 != 0x5a))
- sc->sc_uarttype = COM_UART_8250;
- }
-
- /*
- * Print UART type and initialize ourself.
- */
- sc->sc_fifolen = 1; /* default */
- switch (sc->sc_uarttype) {
- case COM_UART_UNKNOWN:
- printf(": unknown uart\n");
- break;
- case COM_UART_8250:
- printf(": ns8250, no fifo\n");
- break;
- case COM_UART_16450:
- printf(": ns16450, no fifo\n");
- break;
- case COM_UART_16550:
- printf(": ns16550, no working fifo\n");
- break;
- case COM_UART_16550A:
- printf(": ns16550a, 16 byte fifo\n");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 16;
- break;
-#ifdef COM_PXA2X0
- case COM_UART_PXA2X0:
- printf(": pxa2x0, 32 byte fifo");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 32;
- if (sc->sc_iobase == comsiraddr) {
- SET(sc->sc_hwflags, COM_HW_SIR);
- printf(" (SIR)");
- }
- printf("\n");
- break;
-#endif
- case COM_UART_ST16650:
- printf(": st16650, no working fifo\n");
- break;
- case COM_UART_ST16650V2:
- printf(": st16650, 32 byte fifo\n");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 32;
- break;
- case COM_UART_TI16750:
- printf(": ti16750, 64 byte fifo\n");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 64;
- break;
- default:
- panic("comattach: bad fifo type");
- }
-
- /* clear and disable fifo */
- bus_space_write_1(iot, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST);
- (void)bus_space_read_1(iot, ioh, com_data);
- bus_space_write_1(iot, ioh, com_fifo, 0);
-
- sc->sc_mcr = 0;
- bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
-
-#ifdef KGDB
- /*
- * Allow kgdb to "take over" this port. If this is
- * the kgdb device, it has exclusive use.
- */
-
- if (iot == com_kgdb_iot && sc->sc_iobase == com_kgdb_addr &&
- !ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
- printf("%s: kgdb\n", sc->sc_dev.dv_xname);
- SET(sc->sc_hwflags, COM_HW_KGDB);
- }
-#endif /* KGDB */
-
-#ifdef COM_CONSOLE
- if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
- int maj;
-
- /* locate the major number */
- for (maj = 0; maj < nchrdev; maj++)
- if (cdevsw[maj].d_open == comopen)
- break;
-
- if (maj < nchrdev && cn_tab->cn_dev == NODEV)
- cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
-
- printf("%s: console\n", sc->sc_dev.dv_xname);
- }
-#endif
-
- timeout_set(&sc->sc_diag_tmo, comdiag, sc);
- timeout_set(&sc->sc_dtr_tmo, com_raisedtr, sc);
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
- sc->sc_si = softintr_establish(IPL_TTY, comsoft, sc);
- if (sc->sc_si == NULL)
- panic("%s: can't establish soft interrupt.", sc->sc_dev.dv_xname);
-#else
- timeout_set(&sc->sc_comsoft_tmo, comsoft, sc);
-#endif
-
- /*
- * If there are no enable/disable functions, assume the device
- * is always enabled.
- */
- if (!sc->enable)
- sc->enabled = 1;
-
-#if defined(COM_CONSOLE) || defined(KGDB)
- if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE|COM_HW_KGDB))
- com_enable_debugport(sc);
-#endif
-}
-
-void
-com_enable_debugport(sc)
- struct com_softc *sc;
-{
- int s;
-
- /* Turn on line break interrupt, set carrier. */
- s = splhigh();
-#ifdef KGDB
- SET(sc->sc_ier, IER_ERXRDY);
-#ifdef COM_PXA2X0
- if (sc->sc_uarttype == COM_UART_PXA2X0)
- sc->sc_ier |= IER_EUART | IER_ERXTOUT;
-#endif
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
-#endif
- SET(sc->sc_mcr, MCR_DTR | MCR_RTS | MCR_IENABLE);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
-
- splx(s);
-}
-
int
com_detach(self, flags)
struct device *self;
@@ -584,7 +351,7 @@ comopen(dev, flag, mode, p)
switch (sc->sc_uarttype) {
case COM_UART_ST16650:
case COM_UART_ST16650V2:
- bus_space_write_1(iot, ioh, com_lcr, 0xbf);
+ bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
bus_space_write_1(iot, ioh, com_ier, 0);
bus_space_write_1(iot, ioh, com_efr, 0);
@@ -795,7 +562,7 @@ compwroff(sc)
switch (sc->sc_uarttype) {
case COM_UART_ST16650:
case COM_UART_ST16650V2:
- bus_space_write_1(iot, ioh, com_lcr, 0xbf);
+ bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
bus_space_write_1(iot, ioh, com_lcr, 0);
diff --git a/sys/dev/ic/com_subr.c b/sys/dev/ic/com_subr.c
new file mode 100644
index 00000000000..57c6e683109
--- /dev/null
+++ b/sys/dev/ic/com_subr.c
@@ -0,0 +1,378 @@
+/* $OpenBSD: com_subr.c,v 1.1 2005/09/26 22:32:06 miod Exp $ */
+
+/*
+ * Copyright (c) 1997 - 1999, Jason Downs. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*-
+ * Copyright (c) 1993, 1994, 1995, 1996
+ * Charles M. Hannum. All rights reserved.
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)com.c 7.5 (Berkeley) 5/16/91
+ */
+
+/*
+ * COM driver, based on HP dca driver
+ * uses National Semiconductor NS16450/NS16550AF UART
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/tty.h>
+
+#include "com.h"
+#ifdef i386
+#include "pccom.h"
+#else
+#define NPCCOM 0
+#endif
+
+#include <machine/bus.h>
+#if defined(__sparc64__) || !defined(__sparc__)
+#include <machine/intr.h>
+#endif
+
+#if !defined(__sparc__) || defined(__sparc64__)
+#define COM_CONSOLE
+#include <dev/cons.h>
+#endif
+
+#include <dev/ic/comreg.h>
+#include <dev/ic/ns16550reg.h>
+#define com_lcr com_cfcr
+
+#if NCOM > 0
+#include <dev/ic/comvar.h>
+#endif
+#if NPCCOM > 0
+#include <dev/isa/isavar.h>
+#include <i386/isa/pccomvar.h>
+#endif
+
+#ifdef COM_PXA2X0
+#define com_isr 8
+#define ISR_SEND (ISR_RXPL | ISR_XMODE | ISR_XMITIR)
+#define ISR_RECV (ISR_RXPL | ISR_XMODE | ISR_RCVEIR)
+#endif
+
+#ifdef COM_CONSOLE
+#include <sys/conf.h>
+cdev_decl(com);
+#endif
+
+void com_enable_debugport(struct com_softc *);
+
+#if defined(COM_CONSOLE) || defined(KGDB)
+void
+com_enable_debugport(sc)
+ struct com_softc *sc;
+{
+ int s;
+
+ /* Turn on line break interrupt, set carrier. */
+ s = splhigh();
+#ifdef KGDB
+ SET(sc->sc_ier, IER_ERXRDY);
+#ifdef COM_PXA2X0
+ if (sc->sc_uarttype == COM_UART_PXA2X0)
+ sc->sc_ier |= IER_EUART | IER_ERXTOUT;
+#endif
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
+#endif
+ SET(sc->sc_mcr, MCR_DTR | MCR_RTS | MCR_IENABLE);
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
+
+ splx(s);
+}
+#endif /* COM_CONSOLED || KGDB */
+
+void
+com_attach_subr(sc)
+ struct com_softc *sc;
+{
+ bus_space_tag_t iot = sc->sc_iot;
+ bus_space_handle_t ioh = sc->sc_ioh;
+ u_int8_t lcr;
+
+ sc->sc_ier = 0;
+#ifdef COM_PXA2X0
+ if (sc->sc_uarttype == COM_UART_PXA2X0)
+ sc->sc_ier |= IER_EUART;
+#endif
+ /* disable interrupts */
+ bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
+
+#ifdef COM_CONSOLE
+ if (sc->sc_iobase == comconsaddr) {
+ comconsattached = 1;
+ delay(10000); /* wait for output to finish */
+ SET(sc->sc_hwflags, COM_HW_CONSOLE);
+ SET(sc->sc_swflags, COM_SW_SOFTCAR);
+ }
+#endif
+
+ /*
+ * Probe for all known forms of UART.
+ */
+ lcr = bus_space_read_1(iot, ioh, com_lcr);
+ bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
+ bus_space_write_1(iot, ioh, com_efr, 0);
+ bus_space_write_1(iot, ioh, com_lcr, 0);
+
+ bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
+ delay(100);
+
+#ifdef COM_PXA2X0
+ /* Attachment driver presets COM_UART_PXA2X0. */
+ if (sc->sc_uarttype != COM_UART_PXA2X0)
+#endif
+ switch(bus_space_read_1(iot, ioh, com_iir) >> 6) {
+ case 0:
+ sc->sc_uarttype = COM_UART_16450;
+ break;
+ case 2:
+ sc->sc_uarttype = COM_UART_16550;
+ break;
+ case 3:
+ sc->sc_uarttype = COM_UART_16550A;
+ break;
+ default:
+ sc->sc_uarttype = COM_UART_UNKNOWN;
+ break;
+ }
+
+ if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */
+ bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
+ if (bus_space_read_1(iot, ioh, com_efr) == 0) {
+ sc->sc_uarttype = COM_UART_ST16650;
+ } else {
+ bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
+ if (bus_space_read_1(iot, ioh, com_efr) == 0)
+ sc->sc_uarttype = COM_UART_ST16650V2;
+ }
+ }
+
+#if NPCCOM > 0 /* until com works with large FIFOs */
+ if (sc->sc_uarttype == COM_UART_ST16650V2) { /* Probe for XR16850s */
+ u_int8_t dlbl, dlbh;
+
+ /* Enable latch access and get the current values. */
+ bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
+ dlbl = bus_space_read_1(iot, ioh, com_dlbl);
+ dlbh = bus_space_read_1(iot, ioh, com_dlbh);
+
+ /* Zero out the latch divisors */
+ bus_space_write_1(iot, ioh, com_dlbl, 0);
+ bus_space_write_1(iot, ioh, com_dlbh, 0);
+
+ if (bus_space_read_1(iot, ioh, com_dlbh) == 0x10) {
+ sc->sc_uarttype = COM_UART_XR16850;
+ sc->sc_uartrev = bus_space_read_1(iot, ioh, com_dlbl);
+ }
+
+ /* Reset to original. */
+ bus_space_write_1(iot, ioh, com_dlbl, dlbl);
+ bus_space_write_1(iot, ioh, com_dlbh, dlbh);
+ }
+#endif
+
+ if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for TI16750s */
+ bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
+ bus_space_write_1(iot, ioh, com_fifo,
+ FIFO_ENABLE | FIFO_ENABLE_64BYTE);
+ if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 7) {
+#if 0
+ bus_space_write_1(iot, ioh, com_lcr, 0);
+ if ((bus_space_read_1(iot, ioh, com_iir) >> 5) == 6)
+#endif
+ sc->sc_uarttype = COM_UART_TI16750;
+ }
+ bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
+ }
+
+ /* Reset the LCR (latch access is probably enabled). */
+ bus_space_write_1(iot, ioh, com_lcr, lcr);
+ if (sc->sc_uarttype == COM_UART_16450) { /* Probe for 8250 */
+ u_int8_t scr0, scr1, scr2;
+
+ scr0 = bus_space_read_1(iot, ioh, com_scratch);
+ bus_space_write_1(iot, ioh, com_scratch, 0xa5);
+ scr1 = bus_space_read_1(iot, ioh, com_scratch);
+ bus_space_write_1(iot, ioh, com_scratch, 0x5a);
+ scr2 = bus_space_read_1(iot, ioh, com_scratch);
+ bus_space_write_1(iot, ioh, com_scratch, scr0);
+
+ if ((scr1 != 0xa5) || (scr2 != 0x5a))
+ sc->sc_uarttype = COM_UART_8250;
+ }
+
+ /*
+ * Print UART type and initialize ourself.
+ */
+ switch (sc->sc_uarttype) {
+ case COM_UART_UNKNOWN:
+ printf(": unknown uart\n");
+ break;
+ case COM_UART_8250:
+ printf(": ns8250, no fifo\n");
+ break;
+ case COM_UART_16450:
+ printf(": ns16450, no fifo\n");
+ break;
+ case COM_UART_16550:
+ printf(": ns16550, no working fifo\n");
+ break;
+ case COM_UART_16550A:
+ if (sc->sc_fifolen == 0)
+ sc->sc_fifolen = 16;
+ printf(": ns16550a, %d byte fifo\n", sc->sc_fifolen);
+ SET(sc->sc_hwflags, COM_HW_FIFO);
+ break;
+#ifdef COM_PXA2X0
+ case COM_UART_PXA2X0:
+ printf(": pxa2x0, 32 byte fifo");
+ SET(sc->sc_hwflags, COM_HW_FIFO);
+ sc->sc_fifolen = 32;
+ if (sc->sc_iobase == comsiraddr) {
+ SET(sc->sc_hwflags, COM_HW_SIR);
+ printf(" (SIR)");
+ }
+ printf("\n");
+ break;
+#endif
+ case COM_UART_ST16650:
+ printf(": st16650, no working fifo\n");
+ break;
+ case COM_UART_ST16650V2:
+ if (sc->sc_fifolen == 0)
+ sc->sc_fifolen = 32;
+ printf(": st16650, %d byte fifo\n", sc->sc_fifolen);
+ SET(sc->sc_hwflags, COM_HW_FIFO);
+ break;
+ case COM_UART_TI16750:
+ printf(": ti16750, 64 byte fifo\n");
+ SET(sc->sc_hwflags, COM_HW_FIFO);
+ sc->sc_fifolen = 64;
+ break;
+#if NPCCOM > 0
+ case COM_UART_XR16850:
+ printf(": xr16850 (rev %d), 128 byte fifo\n", sc->sc_uartrev);
+ SET(sc->sc_hwflags, COM_HW_FIFO);
+ sc->sc_fifolen = 128;
+ break;
+#endif
+ default:
+ panic("comattach: bad fifo type");
+ }
+ if (sc->sc_fifolen == 0)
+ sc->sc_fifolen = 1; /* default */
+
+ /* clear and disable fifo */
+ bus_space_write_1(iot, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST);
+ (void)bus_space_read_1(iot, ioh, com_data);
+ bus_space_write_1(iot, ioh, com_fifo, 0);
+
+ sc->sc_mcr = 0;
+ bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
+
+#ifdef KGDB
+ /*
+ * Allow kgdb to "take over" this port. If this is
+ * the kgdb device, it has exclusive use.
+ */
+
+ if (iot == com_kgdb_iot && sc->sc_iobase == com_kgdb_addr &&
+ !ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
+ printf("%s: kgdb\n", sc->sc_dev.dv_xname);
+ SET(sc->sc_hwflags, COM_HW_KGDB);
+ }
+#endif /* KGDB */
+
+#ifdef COM_CONSOLE
+ if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
+ int maj;
+
+ /* locate the major number */
+ for (maj = 0; maj < nchrdev; maj++)
+ if (cdevsw[maj].d_open == comopen)
+ break;
+
+ if (maj < nchrdev && cn_tab->cn_dev == NODEV)
+ cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
+
+ printf("%s: console\n", sc->sc_dev.dv_xname);
+ }
+#endif
+
+ timeout_set(&sc->sc_diag_tmo, comdiag, sc);
+ timeout_set(&sc->sc_dtr_tmo, com_raisedtr, sc);
+#if NCOM > 0
+#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
+ sc->sc_si = softintr_establish(IPL_TTY, comsoft, sc);
+ if (sc->sc_si == NULL)
+ panic("%s: can't establish soft interrupt",
+ sc->sc_dev.dv_xname);
+#else
+ timeout_set(&sc->sc_comsoft_tmo, comsoft, sc);
+#endif
+#endif /* NCOM */
+
+ /*
+ * If there are no enable/disable functions, assume the device
+ * is always enabled.
+ */
+ if (!sc->enable)
+ sc->enabled = 1;
+
+#if defined(COM_CONSOLE) || defined(KGDB)
+ if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE|COM_HW_KGDB))
+ com_enable_debugport(sc);
+#endif
+}
diff --git a/sys/dev/pcmcia/com_pcmcia.c b/sys/dev/pcmcia/com_pcmcia.c
index f4b08663141..af370b32839 100644
--- a/sys/dev/pcmcia/com_pcmcia.c
+++ b/sys/dev/pcmcia/com_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: com_pcmcia.c,v 1.41 2005/08/10 21:19:54 fgsch Exp $ */
+/* $OpenBSD: com_pcmcia.c,v 1.42 2005/09/26 22:32:06 miod Exp $ */
/* $NetBSD: com_pcmcia.c,v 1.15 1998/08/22 17:47:58 msaitoh Exp $ */
/*
@@ -154,8 +154,6 @@ void com_pcmcia_disable(struct com_softc *);
int com_pcmcia_enable1(struct com_softc *);
void com_pcmcia_disable1(struct com_softc *);
-void com_pcmcia_attach2(struct com_softc *);
-
struct com_pcmcia_softc {
struct com_softc sc_com; /* real "com" softc */
@@ -326,9 +324,15 @@ found:
sc->disable = com_pcmcia_disable;
sc->sc_frequency = COM_FREQ;
-#ifdef notyet
+ sc->sc_hwflags = 0;
+ sc->sc_swflags = 0;
+
+ if (psc->sc_pf->sc->card.manufacturer == PCMCIA_VENDOR_AUDIOVOX &&
+ psc->sc_pf->sc->card.product == PCMCIA_PRODUCT_AUDIOVOX_RTM8000)
+ sc->sc_fifolen = 16;
+
com_attach_subr(sc);
-#endif
+
/* establish the interrupt. */
psc->sc_ih = pcmcia_intr_establish(pa->pf, IPL_TTY, comintr, sc,
sc->sc_dev.dv_xname);
@@ -336,8 +340,6 @@ found:
if (*intrstr)
printf(", %s", intrstr);
- com_pcmcia_attach2(sc);
-
#ifdef notyet
sc->enabled = 0;
@@ -428,169 +430,3 @@ com_pcmcia_disable1(sc)
pcmcia_function_disable(psc->sc_pf);
}
-
-/*
- * XXX This should be handled by a generic attach
- */
-void
-com_pcmcia_attach2(sc)
- struct com_softc *sc;
-{
- struct com_pcmcia_softc *psc = (struct com_pcmcia_softc *) sc;
- bus_space_tag_t iot = sc->sc_iot;
- bus_space_handle_t ioh = sc->sc_ioh;
- u_int8_t lcr;
-
- sc->sc_hwflags = 0;
- sc->sc_swflags = 0;
-
- /*
- * Probe for all known forms of UART.
- */
- lcr = bus_space_read_1(iot, ioh, com_lcr);
-
- bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
- bus_space_write_1(iot, ioh, com_efr, 0);
- bus_space_write_1(iot, ioh, com_lcr, 0);
-
- bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
- delay(100);
-
- switch(bus_space_read_1(iot, ioh, com_iir) >> 6) {
- case 0:
- sc->sc_uarttype = COM_UART_16450;
- break;
- case 2:
- sc->sc_uarttype = COM_UART_16550;
- break;
- case 3:
- sc->sc_uarttype = COM_UART_16550A;
- break;
- default:
- sc->sc_uarttype = COM_UART_UNKNOWN;
- break;
- }
-
- if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */
- bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
- if (bus_space_read_1(iot, ioh, com_efr) == 0) {
- sc->sc_uarttype = COM_UART_ST16650;
- } else {
- bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
- if (bus_space_read_1(iot, ioh, com_efr) == 0)
- sc->sc_uarttype = COM_UART_ST16650V2;
- }
- }
-
-#if NPCCOM > 0
-#ifdef i386
- if (sc->sc_uarttype == COM_UART_ST16650V2) { /* Probe for XR16850s */
- u_int8_t dlbl, dlbh;
-
- /* Enable latch access and get the current values. */
- bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
- dlbl = bus_space_read_1(iot, ioh, com_dlbl);
- dlbh = bus_space_read_1(iot, ioh, com_dlbh);
-
- /* Zero out the latch divisors */
- bus_space_write_1(iot, ioh, com_dlbl, 0);
- bus_space_write_1(iot, ioh, com_dlbh, 0);
-
- if (bus_space_read_1(iot, ioh, com_dlbh) == 0x10) {
- sc->sc_uarttype = COM_UART_XR16850;
- sc->sc_uartrev = bus_space_read_1(iot, ioh, com_dlbl);
- }
-
- /* Reset to original. */
- bus_space_write_1(iot, ioh, com_dlbl, dlbl);
- bus_space_write_1(iot, ioh, com_dlbh, dlbh);
- }
-#endif
-#endif
-
- /* Reset the LCR (latch access is probably enabled). */
- bus_space_write_1(iot, ioh, com_lcr, lcr);
- if (sc->sc_uarttype == COM_UART_16450) { /* Probe for 8250 */
- u_int8_t scr0, scr1, scr2;
-
- scr0 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, 0xa5);
- scr1 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, 0x5a);
- scr2 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, scr0);
-
- if ((scr1 != 0xa5) || (scr2 != 0x5a))
- sc->sc_uarttype = COM_UART_8250;
- }
-
- /*
- * Print UART type and initialize ourself.
- */
- sc->sc_fifolen = 1; /* default */
- switch (sc->sc_uarttype) {
- case COM_UART_UNKNOWN:
- printf(": unknown uart\n");
- break;
- case COM_UART_8250:
- printf(": ns8250, no fifo\n");
- break;
- case COM_UART_16450:
- printf(": ns16450, no fifo\n");
- break;
- case COM_UART_16550:
- printf(": ns16550, no working fifo\n");
- break;
- case COM_UART_16550A:
- printf(": ns16550a, 16 byte fifo\n");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 16;
- break;
- case COM_UART_ST16650:
- printf(": st16650, no working fifo\n");
- break;
- case COM_UART_ST16650V2:
- if (psc->sc_pf->sc->card.manufacturer ==
- PCMCIA_VENDOR_AUDIOVOX &&
- psc->sc_pf->sc->card.product ==
- PCMCIA_PRODUCT_AUDIOVOX_RTM8000)
- sc->sc_fifolen = 16;
- else
- sc->sc_fifolen = 32;
- printf(": st16650, %d byte fifo\n", sc->sc_fifolen);
- SET(sc->sc_hwflags, COM_HW_FIFO);
- break;
-#if NPCCOM > 0
-#ifdef i386
- case COM_UART_XR16850:
- printf(": xr16850 (rev %d), 128 byte fifo\n", sc->sc_uartrev);
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 128;
- break;
-#endif
-#endif
- default:
- panic("comattach: bad fifo type");
- }
-
- /* clear and disable fifo */
- bus_space_write_1(iot, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST);
- (void)bus_space_read_1(iot, ioh, com_data);
- bus_space_write_1(iot, ioh, com_fifo, 0);
-
- sc->sc_mcr = 0;
- bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
-
- timeout_set(&sc->sc_diag_tmo, comdiag, sc);
- timeout_set(&sc->sc_dtr_tmo, com_raisedtr, sc);
-
-#if NCOM > 0
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
- sc->sc_si = softintr_establish(IPL_TTY, comsoft, sc);
- if (sc->sc_si == NULL)
- panic("%s: can't establish soft interrupt.", sc->sc_dev.dv_xname);
-#else
- timeout_set(&sc->sc_comsoft_tmo, comsoft, sc);
-#endif
-#endif
-}
diff --git a/sys/dev/puc/com_puc.c b/sys/dev/puc/com_puc.c
index 35c4ee9423f..4a81caa0afd 100644
--- a/sys/dev/puc/com_puc.c
+++ b/sys/dev/puc/com_puc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: com_puc.c,v 1.8 2005/07/18 17:51:48 miod Exp $ */
+/* $OpenBSD: com_puc.c,v 1.9 2005/09/26 22:32:06 miod Exp $ */
/*
* Copyright (c) 1997 - 1999, Jason Downs. All rights reserved.
@@ -84,8 +84,6 @@ struct cfattach pccom_puc_ca = {
};
#endif
-void com_puc_attach2(struct com_softc *);
-
int
com_puc_match(parent, match, aux)
struct device *parent;
@@ -130,176 +128,8 @@ com_puc_attach(parent, self, aux)
if (pa->flags)
sc->sc_frequency = pa->flags & PUC_COM_CLOCKMASK;
- com_puc_attach2(sc);
-}
-
-/*
- * XXX This should be handled by a generic attach
- */
-void
-com_puc_attach2(sc)
- struct com_softc *sc;
-{
- bus_space_tag_t iot = sc->sc_iot;
- bus_space_handle_t ioh = sc->sc_ioh;
- u_int8_t lcr;
-
sc->sc_hwflags = 0;
sc->sc_swflags = 0;
- /*
- * Probe for all known forms of UART.
- */
- lcr = bus_space_read_1(iot, ioh, com_lcr);
-
- bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
- bus_space_write_1(iot, ioh, com_efr, 0);
- bus_space_write_1(iot, ioh, com_lcr, 0);
-
- bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE);
- delay(100);
-
- switch(bus_space_read_1(iot, ioh, com_iir) >> 6) {
- case 0:
- sc->sc_uarttype = COM_UART_16450;
- break;
- case 2:
- sc->sc_uarttype = COM_UART_16550;
- break;
- case 3:
- sc->sc_uarttype = COM_UART_16550A;
- break;
- default:
- sc->sc_uarttype = COM_UART_UNKNOWN;
- break;
- }
-
- if (sc->sc_uarttype == COM_UART_16550A) { /* Probe for ST16650s */
- bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
- if (bus_space_read_1(iot, ioh, com_efr) == 0) {
- sc->sc_uarttype = COM_UART_ST16650;
- } else {
- bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
- if (bus_space_read_1(iot, ioh, com_efr) == 0)
- sc->sc_uarttype = COM_UART_ST16650V2;
- }
- }
-
-#if NPCCOM > 0
-#ifdef i386
- if (sc->sc_uarttype == COM_UART_ST16650V2) { /* Probe for XR16850s */
- u_int8_t dlbl, dlbh;
-
- /* Enable latch access and get the current values. */
- bus_space_write_1(iot, ioh, com_lcr, lcr | LCR_DLAB);
- dlbl = bus_space_read_1(iot, ioh, com_dlbl);
- dlbh = bus_space_read_1(iot, ioh, com_dlbh);
-
- /* Zero out the latch divisors */
- bus_space_write_1(iot, ioh, com_dlbl, 0);
- bus_space_write_1(iot, ioh, com_dlbh, 0);
-
- if (bus_space_read_1(iot, ioh, com_dlbh) == 0x10) {
- sc->sc_uarttype = COM_UART_XR16850;
- sc->sc_uartrev = bus_space_read_1(iot, ioh, com_dlbl);
- }
-
- /* Reset to original. */
- bus_space_write_1(iot, ioh, com_dlbl, dlbl);
- bus_space_write_1(iot, ioh, com_dlbh, dlbh);
- }
-#endif
-#endif
-
- /* Reset the LCR (latch access is probably enabled). */
- bus_space_write_1(iot, ioh, com_lcr, lcr);
- if (sc->sc_uarttype == COM_UART_16450) { /* Probe for 8250 */
- u_int8_t scr0, scr1, scr2;
-
- scr0 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, 0xa5);
- scr1 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, 0x5a);
- scr2 = bus_space_read_1(iot, ioh, com_scratch);
- bus_space_write_1(iot, ioh, com_scratch, scr0);
-
- if ((scr1 != 0xa5) || (scr2 != 0x5a))
- sc->sc_uarttype = COM_UART_8250;
- }
-
- /*
- * Print UART type and initialize ourself.
- */
- sc->sc_fifolen = 1; /* default */
- switch (sc->sc_uarttype) {
- case COM_UART_UNKNOWN:
- printf(": unknown uart\n");
- break;
- case COM_UART_8250:
- printf(": ns8250, no fifo\n");
- break;
- case COM_UART_16450:
- printf(": ns16450, no fifo\n");
- break;
- case COM_UART_16550:
- printf(": ns16550, no working fifo\n");
- break;
- case COM_UART_16550A:
- printf(": ns16550a, 16 byte fifo\n");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 16;
- break;
- case COM_UART_ST16650:
- printf(": st16650, no working fifo\n");
- break;
- case COM_UART_ST16650V2:
- printf(": st16650, 32 byte fifo\n");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 32;
- break;
- case COM_UART_TI16750:
- printf(": ti16750, 64 byte fifo\n");
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 64;
- break;
-#if NPCCOM > 0
-#ifdef i386
- case COM_UART_XR16850:
- printf(": xr16850 (rev %d), 128 byte fifo\n", sc->sc_uartrev);
- SET(sc->sc_hwflags, COM_HW_FIFO);
- sc->sc_fifolen = 128;
- break;
-#endif
-#endif
- default:
- panic("com_puc_attach2: bad fifo type");
- }
-
- /* clear and disable fifo */
- bus_space_write_1(iot, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST);
- (void)bus_space_read_1(iot, ioh, com_data);
- bus_space_write_1(iot, ioh, com_fifo, 0);
-
- sc->sc_mcr = 0;
- bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
-
- timeout_set(&sc->sc_diag_tmo, comdiag, sc);
- timeout_set(&sc->sc_dtr_tmo, com_raisedtr, sc);
-#if NCOM > 0
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
- sc->sc_si = softintr_establish(IPL_TTY, comsoft, sc);
- if (sc->sc_si == NULL)
- panic("%s: can't establish soft interrupt.",
- sc->sc_dev.dv_xname);
-#else
- timeout_set(&sc->sc_comsoft_tmo, comsoft, sc);
-#endif
-#endif
-
- /*
- * If there are no enable/disable functions, assume the device
- * is always enabled.
- */
- if (!sc->enable)
- sc->enabled = 1;
+ com_attach_subr(sc);
}