Subject: HAyes ESP diffs
To: None <port-i386@NetBSD.ORG>
From: Robert Dobbs <banshee@gabriella.resort.com>
List: port-i386
Date: 08/24/1995 02:30:38
I've modified the com.c v1.61 driver to support the Hayes ESP card in
16550 compatibility mode. This mode has two advantages: 1024 byte FIFOs
and scaled Rx FIFO interrupt levels. The larger FIFOs virtually eliminate
and chance of silo overflows. The scaled interrupt level means that the
card signals an interrupt every 256 characters rather than every 8.
The driver has been modified to intialize the card, and to send 1024 bytes
rather than 16 in comstart().
The full file is available from: ftp.resort.com/pub/netbsd/com.c.esp
Here are the diffs.
*** com.c-july4 Wed Aug 9 01:23:30 1995
--- com.c Wed Aug 23 23:36:22 1995
***************
*** 62,68 ****
#include <dev/isa/comreg.h>
#include <dev/ic/ns16550reg.h>
! #define COM_IBUFSIZE (2 * 256)
#define COM_IHIGHWATER ((3 * COM_IBUFSIZE) / 4)
struct com_softc {
--- 62,70 ----
#include <dev/isa/comreg.h>
#include <dev/ic/ns16550reg.h>
! #define ESP_PORT 0x140 /* IO Address for ESP (jumpered on card) */
!
! #define COM_IBUFSIZE (2 * 512)
#define COM_IHIGHWATER ((3 * COM_IBUFSIZE) / 4)
struct com_softc {
***************
*** 78,83 ****
--- 80,86 ----
u_char sc_hwflags;
#define COM_HW_NOIEN 0x01
#define COM_HW_FIFO 0x02
+ #define COM_HW_ESP 0x04
#define COM_HW_CONSOLE 0x40
u_char sc_swflags;
#define COM_SW_SOFTCAR 0x01
***************
*** 169,174 ****
--- 172,220 ----
return 1;
}
+ void comprobeESP(iobase, sc)
+ int iobase;
+ struct com_softc *sc;
+ {
+ char val;
+
+ /* Test for ESP signature */
+ if ((inb(iobase) & 0xf3) == 0)
+ return;
+
+ #define ESP_GETTEST 0x01
+ #define ESP_GETDIPS 0x02
+ #define ESP_CMD1 4
+ #define ESP_STATUS1 4
+ #define ESP_STATUS2 5
+
+ /* Check for ESP version 2.0: bits 4,5,6 == 010 */
+ outb(iobase + ESP_CMD1, ESP_GETTEST);
+ val = inb(iobase + ESP_STATUS1); /* Clear reg 1 */
+ val = inb(iobase + ESP_STATUS2);
+ if ((val & 0x70) < 0x20) {
+ printf(": old ESP(%o)", val & 0x70);
+ return;
+ }
+
+ /* Check for ability to emulate 16550: bit 8 == 1 */
+ outb(iobase + ESP_CMD1, ESP_GETDIPS);
+ val = inb(iobase + ESP_STATUS1);
+ if ((val & 0x80) == 0) {
+ printf(": ESP slave");
+ return;
+ }
+
+ /* Determine which com port this ESP card services: bits 0,1 */
+ val &= 0x03; /* Mask off all but bits 0,1 */
+
+ /* sc->sc_dev.dv_unit is the com port: 0..3 */
+ if (sc->sc_dev.dv_unit == val) {
+ sc->sc_hwflags |= COM_HW_ESP;
+ printf(": ESP");
+ }
+ }
+
int
comprobe(parent, match, aux)
struct device *parent;
***************
*** 203,208 ****
--- 249,257 ----
if (sc->sc_dev.dv_unit == comconsole)
delay(1000);
+ /* look for a Hayes ESP board at ESP_PORT */
+ comprobeESP(ESP_PORT, sc);
+
/* look for a NS 16550AF UART with FIFOs */
outb(iobase + com_fifo,
FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14);
***************
*** 311,316 ****
--- 360,389 ----
sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE;
iobase = sc->sc_iobase;
+ /* Setup the ESP board */
+ if (sc->sc_hwflags & COM_HW_ESP) {
+ outb(iobase + com_fifo,
+ FIFO_DMA_MODE | FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_8);
+ #define ESP_SETMODE 0x10
+ #define ESP_CMD2 5
+ /* Set 16550 compatibility mode */
+ outb(ESP_PORT + ESP_CMD1, ESP_SETMODE);
+ outb(ESP_PORT + ESP_CMD2, 0x80 | 0x04 | 0x02);
+ #define ESP_SETFLOWTYPE 0x0A
+ /* Set RTS/CTS flow control */
+ outb(ESP_PORT + ESP_CMD1, ESP_SETFLOWTYPE);
+ outb(ESP_PORT + ESP_CMD2, 0x04);
+ outb(ESP_PORT + ESP_CMD2, 0x10);
+ #define ESP_SETRXFLOW 0x0A
+ #define HIBYTE(w) ((char)(((short)(w) >> 8) & 0xff))
+ #define LOBYTE(w) ((char)(w))
+ /* Set flow control levels */
+ outb(ESP_PORT + ESP_CMD1, ESP_SETRXFLOW);
+ outb(ESP_PORT + ESP_CMD2, HIBYTE(768));
+ outb(ESP_PORT + ESP_CMD2, LOBYTE(768));
+ outb(ESP_PORT + ESP_CMD2, HIBYTE(512));
+ outb(ESP_PORT + ESP_CMD2, LOBYTE(512));
+ } else
/* Set the FIFO threshold based on the receive speed. */
if (sc->sc_hwflags & COM_HW_FIFO)
outb(iobase + com_fifo,
***************
*** 674,679 ****
--- 747,759 ----
selwakeup(&tp->t_wsel);
}
tp->t_state |= TS_BUSY;
+ if (sc->sc_hwflags & COM_HW_ESP) {
+ u_char buffer[1024], *cp = buffer;
+ int n = q_to_b(&tp->t_outq, cp, sizeof buffer);
+ do {
+ outb(iobase + com_data, *cp++);
+ } while (--n);
+ } else
if (sc->sc_hwflags & COM_HW_FIFO) {
u_char buffer[16], *cp = buffer;
int n = q_to_b(&tp->t_outq, cp, sizeof buffer);
--end--