summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1997-01-29 21:50:02 +0000
committerbde <bde@FreeBSD.org>1997-01-29 21:50:02 +0000
commit637e1706b92463dec23a7206b05852bd855c8e65 (patch)
tree27edb743b3549d96470e672acd632a1d700e8513 /sys
parent369e45d4cb610285a37059682f90b3f95cbd8cf2 (diff)
downloadFreeBSD-src-637e1706b92463dec23a7206b05852bd855c8e65.zip
FreeBSD-src-637e1706b92463dec23a7206b05852bd855c8e65.tar.gz
Fixes and workarounds for Hayes ESP:
- don't uselessly initialize the fifo "DMA" bit at attach time. - initialize the fifo "DMA" bit at open time. Without this, the device interrupts for every character received, reducing input performance to that of an 8250. - don't uselessly initialize the fifo trigger level to 8 (scaled to 256) at attach time. - don't scale the fifo trigger level to 512 bytes. The driver's pseudo- dma buffer has size 256, so it can't handle bursts of size 512 or 256. It should be able to handle the second lowest ftl (2 scaled to 64). - don't reset the fifos in siostop(). Reset triggers a hardware bug involving wedging of the output interrupt bit This workaround unfortunately requires ESP support to be configured.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/sio/sio.c32
-rw-r--r--sys/i386/isa/sio.c32
-rw-r--r--sys/isa/sio.c32
3 files changed, 75 insertions, 21 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c
index fe3c204..1f09168 100644
--- a/sys/dev/sio/sio.c
+++ b/sys/dev/sio/sio.c
@@ -899,14 +899,15 @@ sioattach(isdp)
}
#ifdef COM_ESP
if (com->esp) {
- outb(iobase + com_fifo,
- FIFO_DMA_MODE | FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST
- | FIFO_RX_MEDH);
-
- /* Set 16550 compatibility mode. */
+ /*
+ * Set 16550 compatibility mode.
+ * We don't use the ESP_MODE_SCALE bit to increase the
+ * fifo trigger levels because we can't handle large
+ * bursts of input.
+ * XXX flow control should be set in comparam(), not here.
+ */
outb(com->esp_port + ESP_CMD1, ESP_SETMODE);
- outb(com->esp_port + ESP_CMD2,
- ESP_MODE_SCALE | ESP_MODE_RTS | ESP_MODE_FIFO);
+ outb(com->esp_port + ESP_CMD2, ESP_MODE_RTS | ESP_MODE_FIFO);
/* Set RTS/CTS flow control. */
outb(com->esp_port + ESP_CMD1, ESP_SETFLOWTYPE);
@@ -1918,6 +1919,15 @@ comparam(tp, t)
*/
com->fifo_image = t->c_ospeed <= 4800
? FIFO_ENABLE : FIFO_ENABLE | FIFO_RX_HIGH;
+#ifdef COM_ESP
+ /*
+ * The Hayes ESP card needs the fifo DMA mode bit set
+ * in compatibility mode. If not, it will interrupt
+ * for each character received.
+ */
+ if (com->esp)
+ com->fifo_image |= FIFO_DMA_MODE;
+#endif
outb(iobase + com_fifo, com->fifo_image);
}
@@ -2128,6 +2138,10 @@ siostop(tp, rw)
disable_intr();
if (rw & FWRITE) {
if (com->hasfifo)
+#ifdef COM_ESP
+ /* XXX avoid h/w bug. */
+ if (!com->esp)
+#endif
/* XXX does this flush everything? */
outb(com->iobase + com_fifo,
FIFO_XMT_RST | com->fifo_image);
@@ -2140,6 +2154,10 @@ siostop(tp, rw)
}
if (rw & FREAD) {
if (com->hasfifo)
+#ifdef COM_ESP
+ /* XXX avoid h/w bug. */
+ if (!com->esp)
+#endif
/* XXX does this flush everything? */
outb(com->iobase + com_fifo,
FIFO_RCV_RST | com->fifo_image);
diff --git a/sys/i386/isa/sio.c b/sys/i386/isa/sio.c
index fe3c204..1f09168 100644
--- a/sys/i386/isa/sio.c
+++ b/sys/i386/isa/sio.c
@@ -899,14 +899,15 @@ sioattach(isdp)
}
#ifdef COM_ESP
if (com->esp) {
- outb(iobase + com_fifo,
- FIFO_DMA_MODE | FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST
- | FIFO_RX_MEDH);
-
- /* Set 16550 compatibility mode. */
+ /*
+ * Set 16550 compatibility mode.
+ * We don't use the ESP_MODE_SCALE bit to increase the
+ * fifo trigger levels because we can't handle large
+ * bursts of input.
+ * XXX flow control should be set in comparam(), not here.
+ */
outb(com->esp_port + ESP_CMD1, ESP_SETMODE);
- outb(com->esp_port + ESP_CMD2,
- ESP_MODE_SCALE | ESP_MODE_RTS | ESP_MODE_FIFO);
+ outb(com->esp_port + ESP_CMD2, ESP_MODE_RTS | ESP_MODE_FIFO);
/* Set RTS/CTS flow control. */
outb(com->esp_port + ESP_CMD1, ESP_SETFLOWTYPE);
@@ -1918,6 +1919,15 @@ comparam(tp, t)
*/
com->fifo_image = t->c_ospeed <= 4800
? FIFO_ENABLE : FIFO_ENABLE | FIFO_RX_HIGH;
+#ifdef COM_ESP
+ /*
+ * The Hayes ESP card needs the fifo DMA mode bit set
+ * in compatibility mode. If not, it will interrupt
+ * for each character received.
+ */
+ if (com->esp)
+ com->fifo_image |= FIFO_DMA_MODE;
+#endif
outb(iobase + com_fifo, com->fifo_image);
}
@@ -2128,6 +2138,10 @@ siostop(tp, rw)
disable_intr();
if (rw & FWRITE) {
if (com->hasfifo)
+#ifdef COM_ESP
+ /* XXX avoid h/w bug. */
+ if (!com->esp)
+#endif
/* XXX does this flush everything? */
outb(com->iobase + com_fifo,
FIFO_XMT_RST | com->fifo_image);
@@ -2140,6 +2154,10 @@ siostop(tp, rw)
}
if (rw & FREAD) {
if (com->hasfifo)
+#ifdef COM_ESP
+ /* XXX avoid h/w bug. */
+ if (!com->esp)
+#endif
/* XXX does this flush everything? */
outb(com->iobase + com_fifo,
FIFO_RCV_RST | com->fifo_image);
diff --git a/sys/isa/sio.c b/sys/isa/sio.c
index fe3c204..1f09168 100644
--- a/sys/isa/sio.c
+++ b/sys/isa/sio.c
@@ -899,14 +899,15 @@ sioattach(isdp)
}
#ifdef COM_ESP
if (com->esp) {
- outb(iobase + com_fifo,
- FIFO_DMA_MODE | FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST
- | FIFO_RX_MEDH);
-
- /* Set 16550 compatibility mode. */
+ /*
+ * Set 16550 compatibility mode.
+ * We don't use the ESP_MODE_SCALE bit to increase the
+ * fifo trigger levels because we can't handle large
+ * bursts of input.
+ * XXX flow control should be set in comparam(), not here.
+ */
outb(com->esp_port + ESP_CMD1, ESP_SETMODE);
- outb(com->esp_port + ESP_CMD2,
- ESP_MODE_SCALE | ESP_MODE_RTS | ESP_MODE_FIFO);
+ outb(com->esp_port + ESP_CMD2, ESP_MODE_RTS | ESP_MODE_FIFO);
/* Set RTS/CTS flow control. */
outb(com->esp_port + ESP_CMD1, ESP_SETFLOWTYPE);
@@ -1918,6 +1919,15 @@ comparam(tp, t)
*/
com->fifo_image = t->c_ospeed <= 4800
? FIFO_ENABLE : FIFO_ENABLE | FIFO_RX_HIGH;
+#ifdef COM_ESP
+ /*
+ * The Hayes ESP card needs the fifo DMA mode bit set
+ * in compatibility mode. If not, it will interrupt
+ * for each character received.
+ */
+ if (com->esp)
+ com->fifo_image |= FIFO_DMA_MODE;
+#endif
outb(iobase + com_fifo, com->fifo_image);
}
@@ -2128,6 +2138,10 @@ siostop(tp, rw)
disable_intr();
if (rw & FWRITE) {
if (com->hasfifo)
+#ifdef COM_ESP
+ /* XXX avoid h/w bug. */
+ if (!com->esp)
+#endif
/* XXX does this flush everything? */
outb(com->iobase + com_fifo,
FIFO_XMT_RST | com->fifo_image);
@@ -2140,6 +2154,10 @@ siostop(tp, rw)
}
if (rw & FREAD) {
if (com->hasfifo)
+#ifdef COM_ESP
+ /* XXX avoid h/w bug. */
+ if (!com->esp)
+#endif
/* XXX does this flush everything? */
outb(com->iobase + com_fifo,
FIFO_RCV_RST | com->fifo_image);
OpenPOWER on IntegriCloud