Subject: Hayes Enhanced Serial Port (ESP) card & NetBSD
To: Bill Sommerfeld <sommerfeld@orchard.arlington.ma.us>
From: Brian Stark <bstark@uswest.net>
List: port-i386
Date: 11/27/1999 18:51:46
On Fri, 26 Nov 1999, Bill Sommerfeld wrote:

> Out of curiosity, what functionality is missing?

Hello Bill,

In /usr/src/sys/dev/ic/com.c (revision 1.159.2.1), function
com_attach_subr defines a list of the enhanced I/O port addresses. This
list is defined as follows:

#ifdef COM_HAYESP
        int     hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 };
        int     *hayespp;
#endif      

However, the Hayes Enhanced Serial Interface document specifies the
following as a list of valid base addresses:

  0x100, 0x140, 0x180, 0x200, 0x240, 0x280, 0x300, 0x380

So, NetBSD only has support for half of these addresses. When the Hayes
ESP card is operated in memory-mapped I/O mode the following addresses
become valid:

  (I/O base)+0x0, (I/O base)+0x4000, (I/O base)+0x8000, (I/O base)+0xC000

But, NetBSD does not appear to support the enhanced memory-mapped I/O mode 
of the card.

From /usr/src/sys/dev/ic/hayespreg.h I see support for only the following
commands for a Hayes ESP card:

#define HAYESP_GETTEST          0x01    /* self-test command (1b+extras) */
#define HAYESP_GETDIPS          0x02    /* get on-board DIP switches (1b) */
#define HAYESP_SETFLOWTYPE      0x08    /* set type of flow-control (2b) */
#define HAYESP_SETRXFLOW        0x0a    /* set Rx FIFO " levels (4b) */
#define HAYESP_SETMODE          0x10    /* set board mode (1b) */

However, the Hayes Enhanced Serial Interface document specifies that the
following commands exist:

  General Commands
  ----------------
  reset (0x0)
  get self test results (0x2)
  get compatibility mode address dip switches (0x02)
  
  Setup Commands
  --------------
  set enhanced IRQ/DMA level (0x4)
  set DMA timeout (0x5)
  set IRQ mask (0x6)
  set error status mask (0x7)
  set flow control (0x8)
  set flow control characters (0x9)
  set receive FIFO flow control levels (0xa)
  set fifo trigger levels (0xb)
  set receive character timeout (0xc)
  set flow off timeout (0xd)
  set mode (0x10)
  set enhanced interrupt (0x1f)
  set re-interrupt timeout (0x20)
  set UART clock prescaler (0x23)

  Operating Commands
  ------------------
  get error status (0x12)  
  get receive bytes available (0x14)
  get transmit space available (0x15)
  initiate DMA receive (0x16)
  initiate DMA transmit (0x17)
  flow off local transmitter (0x18)
  flow on local transmitter (0x19)
  issue line break (0x1a)
  flush receive FIFO (0x1b)
  flush transmit FIFO (0x1c)
  get mode (0x1e)
  get service ID mask (0x21)
  get receive error count (0x22)

  UART Commands 
  -------------
  write to UART register (0xe)
  read from UART register (0xf)
  get UART status (0x13)
  set UART baud rate (0x1d)  

The Hayes ESP card also supports several modes of operation:

  Compatibility Mode
  ------------------
    * basic compatibility mode
    * 16450/16550 compatibility mode
    * 16450/16550 FIFO enhanced compatibility mode with hardware flow
      control

   Enhanced Mode
   -------------
     * enhanced IRQ
     * programmed I/O
     * memory mapped I/O
     * DMA mode

However, NetBSD appears to only use the 16450/16550 FIFO enhanced
compatibility mode, as explained by the comment in function com_config():

#ifdef COM_HAYESP
        /* Look for a Hayes ESP board. */
        if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
                sc->sc_fifolen = 1024;
        
                /* Set 16550 compatibility mode */
                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
                                  HAYESP_SETMODE);
                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
                                  HAYESP_MODE_FIFO|HAYESP_MODE_RTS|
                                  HAYESP_MODE_SCALE);
  
                /* Set RTS/CTS flow control */ 
                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
                                  HAYESP_SETFLOWTYPE);
                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
                                  HAYESP_FLOW_RTS);
                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
                                  HAYESP_FLOW_CTS);

My notes are based on a copy of the Hayes Enhanced Serial Interface (ESI)
document I received from Hayes in 1994.

Brian Stark
bstark@uswest.net