summaryrefslogtreecommitdiff
path: root/sys/dev/ic/com.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ic/com.c')
-rw-r--r--sys/dev/ic/com.c217
1 files changed, 130 insertions, 87 deletions
diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c
index 846d5f518f5..ffc8c7f1547 100644
--- a/sys/dev/ic/com.c
+++ b/sys/dev/ic/com.c
@@ -1,4 +1,5 @@
-/* $NetBSD: com.c,v 1.62 1995/10/15 19:43:04 mycroft Exp $ */
+/* $OpenBSD: com.c,v 1.7 1996/03/08 16:42:51 niklas Exp $ */
+/* $NetBSD: com.c,v 1.65 1996/02/10 20:23:18 christos Exp $ */
/*-
* Copyright (c) 1993, 1994, 1995 Charles M. Hannum. All rights reserved.
@@ -61,10 +62,12 @@
#include <dev/isa/isavar.h>
#include <dev/isa/comreg.h>
#include <dev/ic/ns16550reg.h>
-#include <dev/ic/espreg.h>
+#ifdef COM_HAYESP
+#include <dev/ic/hayespreg.h>
+#endif
#define com_lcr com_cfcr
-#define COM_IBUFSIZE (2 * 256)
+#define COM_IBUFSIZE (2 * 512)
#define COM_IHIGHWATER ((3 * COM_IBUFSIZE) / 4)
struct com_softc {
@@ -77,11 +80,13 @@ struct com_softc {
int sc_errors;
int sc_iobase;
- int sc_espbase;
+#ifdef COM_HAYESP
+ int sc_hayespbase;
+#endif
u_char sc_hwflags;
#define COM_HW_NOIEN 0x01
#define COM_HW_FIFO 0x02
-#define COM_HW_ESP 0x04
+#define COM_HW_HAYESP 0x04
#define COM_HW_CONSOLE 0x40
u_char sc_swflags;
#define COM_SW_SOFTCAR 0x01
@@ -226,64 +231,84 @@ comprobe1(iobase)
return 1;
}
+#ifdef COM_HAYESP
int
-comprobe(parent, match, aux)
- struct device *parent;
- void *match, *aux;
+comprobeHAYESP(iobase, sc)
+ int iobase;
+ struct com_softc *sc;
{
- struct isa_attach_args *ia = aux;
- int iobase = ia->ia_iobase;
+ char val, dips;
+ int combaselist[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
- if (!comprobe1(iobase))
- return 0;
+ /*
+ * Hayes ESP cards have two iobases. One is for compatibility with
+ * 16550 serial chips, and at the same ISA PC base addresses. The
+ * other is for ESP-specific enhanced features, and lies at a
+ * different addressing range entirely (0x140, 0x180, 0x280, or 0x300).
+ */
- ia->ia_iosize = COM_NPORTS;
- ia->ia_msize = 0;
- return 1;
-}
+ /* Test for ESP signature */
+ if ((inb(iobase) & 0xf3) == 0)
+ return 0;
-int
-comprobeESP(esp_port, sc)
- int esp_port;
- struct com_softc *sc;
-{
- char val, dips;
- int com_base_list[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+ /*
+ * ESP is present at ESP enhanced base address; unknown com port
+ */
- /* Test for ESP signature at the ESP i/o port. */
- if ((inb(esp_port) & 0xf3) == 0)
- return(0);
+ /* Get the dip-switch configurations */
+ outb(iobase + HAYESP_CMD1, HAYESP_GETDIPS);
+ dips = inb(iobase + HAYESP_STATUS1);
- /* Check compatibility mode settings */
- outb(esp_port + ESP_CMD1, ESP_GETDIPS);
- dips = inb(esp_port + ESP_STATUS1);
+ /* Determine which com port this ESP card services: bits 0,1 of */
+ /* dips is the port # (0-3); combaselist[val] is the com_iobase */
+ if (sc->sc_iobase != combaselist[dips & 0x03])
+ return 0;
- /* Does this ESP board service this com port?: Bits 0,1 == COM0..3 */
- if (sc->sc_iobase != com_base_list[(dips & 0x03)]) {
- return(0);
- }
printf(": ESP");
- /* Check ESP Self Test bits. */
+ /* Check ESP Self Test bits. */
/* Check for ESP version 2.0: bits 4,5,6 == 010 */
- outb(esp_port + ESP_CMD1, ESP_GETTEST);
- val = inb(esp_port + ESP_STATUS1); /* Always 0x00 */
- val = inb(esp_port + ESP_STATUS2);
+ outb(iobase + HAYESP_CMD1, HAYESP_GETTEST);
+ val = inb(iobase + HAYESP_STATUS1); /* Clear reg 1 */
+ val = inb(iobase + HAYESP_STATUS2);
if ((val & 0x70) < 0x20) {
printf("-old (%o)", val & 0x70);
- return(0);
+ /* we do not support the necessary features */
+ return 0;
}
- /* Check for ability to emulate 16550: bit 7 set */
- if (ISSET(dips, 0x80) == 0) {
+ /* Check for ability to emulate 16550: bit 8 == 1 */
+ if ((dips & 0x80) == 0) {
printf(" slave");
- return(0);
+ /* XXX Does slave really mean no 16550 support?? */
+ return 0;
}
- /* We're a full featured ESP card at the right com port. */
- SET(sc->sc_hwflags, COM_HW_ESP);
- printf(", 1024 byte fifo\n");
- return(1);
+ /*
+ * If we made it this far, we are a full-featured ESP v2.0 (or
+ * better), at the correct com port address.
+ */
+
+ SET(sc->sc_hwflags, COM_HW_HAYESP);
+ printf(", 1024k fifo\n");
+ return 1;
+}
+#endif
+
+int
+comprobe(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct isa_attach_args *ia = aux;
+ int iobase = ia->ia_iobase;
+
+ if (!comprobe1(iobase))
+ return 0;
+
+ ia->ia_iosize = COM_NPORTS;
+ ia->ia_msize = 0;
+ return 1;
}
void
@@ -296,8 +321,10 @@ comattach(parent, self, aux)
struct cfdata *cf = sc->sc_dev.dv_cfdata;
int iobase = ia->ia_iobase;
struct tty *tp;
- int esp_ports[] = { 0x140, 0x180, 0x280, 0 };
- int *espp;
+#ifdef COM_HAYESP
+ int hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 };
+ int *hayespp;
+#endif
sc->sc_iobase = iobase;
sc->sc_hwflags = ISSET(cf->cf_flags, COM_HW_NOIEN);
@@ -306,29 +333,33 @@ comattach(parent, self, aux)
if (sc->sc_dev.dv_unit == comconsole)
delay(1000);
+#ifdef COM_HAYESP
/* Look for a Hayes ESP board. */
- for (espp = esp_ports; *espp != 0; espp++)
- if (comprobeESP(*espp, sc)) {
- sc->sc_espbase = *espp;
+ for (hayespp = hayesp_ports; *hayespp != 0; hayespp++)
+ if (comprobeHAYESP(*hayespp, sc)) {
+ sc->sc_hayespbase = *hayespp;
break;
}
/* No ESP; look for other things. */
- if (*espp == 0) {
- /* look for a NS 16550AF UART with FIFOs */
- outb(iobase + com_fifo,
- FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14);
- delay(100);
- if (ISSET(inb(iobase + com_iir), IIR_FIFO_MASK) == IIR_FIFO_MASK)
- if (ISSET(inb(iobase + com_fifo), FIFO_TRIGGER_14) ==
- FIFO_TRIGGER_14) {
- SET(sc->sc_hwflags, COM_HW_FIFO);
- printf(": ns16550a, working fifo\n");
- } else
- printf(": ns16550, broken fifo\n");
- else
- printf(": ns8250 or ns16450, no fifo\n");
- outb(iobase + com_fifo, 0);
+ if (*hayespp == 0) {
+#endif
+
+ /* look for a NS 16550AF UART with FIFOs */
+ outb(iobase + com_fifo,
+ FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14);
+ delay(100);
+ if (ISSET(inb(iobase + com_iir), IIR_FIFO_MASK) == IIR_FIFO_MASK)
+ if (ISSET(inb(iobase + com_fifo), FIFO_TRIGGER_14) == FIFO_TRIGGER_14) {
+ SET(sc->sc_hwflags, COM_HW_FIFO);
+ printf(": ns16550a, working fifo\n");
+ } else
+ printf(": ns16550, broken fifo\n");
+ else
+ printf(": ns8250 or ns16450, no fifo\n");
+ outb(iobase + com_fifo, 0);
+#ifdef COM_HAYESP
}
+#endif
/* disable interrupts */
outb(iobase + com_ier, 0);
@@ -424,32 +455,39 @@ comopen(dev, flag, mode, p)
sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE;
iobase = sc->sc_iobase;
+#ifdef COM_HAYESP
+ /* Setup the ESP board */
+ if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
+ int hayespbase = sc->sc_hayespbase;
- /* Set up the ESP board */
- if (ISSET(sc->sc_hwflags, COM_HW_ESP)) {
outb(iobase + com_fifo,
- /* XXX - bug in ESP requires DMA flag set */
- FIFO_DMA_MODE |
- FIFO_ENABLE | FIFO_RCV_RST |
- FIFO_XMT_RST | FIFO_TRIGGER_8);
+ FIFO_DMA_MODE|FIFO_ENABLE|
+ FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_8);
/* Set 16550 compatibility mode */
- outb(sc->sc_espbase + ESP_CMD1, ESP_SETMODE);
- outb(sc->sc_espbase + ESP_CMD2,
- ESP_MODE_FIFO | ESP_MODE_RTS | ESP_MODE_SCALE);
+ outb(hayespbase + HAYESP_CMD1, HAYESP_SETMODE);
+ outb(hayespbase + HAYESP_CMD2,
+ HAYESP_MODE_FIFO|HAYESP_MODE_RTS|
+ HAYESP_MODE_SCALE);
/* Set RTS/CTS flow control */
- outb(sc->sc_espbase + ESP_CMD1, ESP_SETFLOWTYPE);
- outb(sc->sc_espbase + ESP_CMD2, ESP_FLOW_RTS);
- outb(sc->sc_espbase + ESP_CMD2, ESP_FLOW_CTS);
+ outb(hayespbase + HAYESP_CMD1, HAYESP_SETFLOWTYPE);
+ outb(hayespbase + HAYESP_CMD2, HAYESP_FLOW_RTS);
+ outb(hayespbase + HAYESP_CMD2, HAYESP_FLOW_CTS);
/* Set flow control levels */
- outb(sc->sc_espbase + ESP_CMD1, ESP_SETRXFLOW);
- outb(sc->sc_espbase + ESP_CMD2, HIBYTE(RXHIGHWATER));
- outb(sc->sc_espbase + ESP_CMD2, LOBYTE(RXHIGHWATER));
- outb(sc->sc_espbase + ESP_CMD2, HIBYTE(RXLOWWATER));
- outb(sc->sc_espbase + ESP_CMD2, LOBYTE(RXLOWWATER));
- } else if (ISSET(sc->sc_hwflags, COM_HW_FIFO))
+ outb(hayespbase + HAYESP_CMD1, HAYESP_SETRXFLOW);
+ outb(hayespbase + HAYESP_CMD2,
+ HAYESP_HIBYTE(HAYESP_RXHIWMARK));
+ outb(hayespbase + HAYESP_CMD2,
+ HAYESP_LOBYTE(HAYESP_RXHIWMARK));
+ outb(hayespbase + HAYESP_CMD2,
+ HAYESP_HIBYTE(HAYESP_RXLOWMARK));
+ outb(hayespbase + HAYESP_CMD2,
+ HAYESP_LOBYTE(HAYESP_RXLOWMARK));
+ } else
+#endif
+ if (ISSET(sc->sc_hwflags, COM_HW_FIFO))
/* Set the FIFO threshold based on the receive speed. */
outb(iobase + com_fifo,
FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST |
@@ -829,13 +867,18 @@ comstart(tp)
selwakeup(&tp->t_wsel);
}
SET(tp->t_state, TS_BUSY);
- if (ISSET(sc->sc_hwflags, COM_HW_ESP)) {
+
+#ifdef COM_HAYESP
+ if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
u_char buffer[1024], *cp = buffer;
int n = q_to_b(&tp->t_outq, cp, sizeof buffer);
- do {
+ do
outb(iobase + com_data, *cp++);
- } while (--n);
- } else if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
+ while (--n);
+ }
+ else
+#endif
+ if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
u_char buffer[16], *cp = buffer;
int n = q_to_b(&tp->t_outq, cp, sizeof buffer);
do {