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--