The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/stallion.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*****************************************************************************/
    2 
    3 /*
    4  * stallion.c  -- stallion multiport serial driver.
    5  *
    6  * Copyright (c) 1995-1996 Greg Ungerer (gerg@stallion.oz.au).
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   19  *      This product includes software developed by Greg Ungerer.
   20  * 4. Neither the name of the author nor the names of any co-contributors
   21  *    may be used to endorse or promote products derived from this software
   22  *    without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  *
   36  * $FreeBSD: releng/5.0/sys/i386/isa/stallion.c 102412 2002-08-25 13:23:09Z charnier $
   37  */
   38 
   39 /*****************************************************************************/
   40 
   41 #define TTYDEFCHARS     1
   42 
   43 #include "opt_compat.h"
   44 
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/kernel.h>
   48 #include <sys/malloc.h>
   49 #include <sys/tty.h>
   50 #include <sys/conf.h>
   51 #include <sys/fcntl.h>
   52 #include <sys/bus.h>
   53 #include <i386/isa/isa_device.h>
   54 #include <i386/isa/ic/scd1400.h>
   55 #include <machine/comstats.h>
   56 
   57 #warning "The stallion pci attachment is broken and not compiled"
   58 #define NPCI 0
   59 #if NPCI > 0
   60 #ifndef COMPAT_OLDPCI
   61 #error "The stallion pci driver requires the old pci compatibility shims"
   62 #endif
   63 #include <pci/pcivar.h>
   64 #include <pci/pcireg.h>
   65 #endif
   66 
   67 /*****************************************************************************/
   68 
   69 /*
   70  *      Define the version level of the kernel - so we can compile in the
   71  *      appropriate bits of code. By default this will compile for a 2.1
   72  *      level kernel.
   73  */
   74 #define VFREEBSD        220
   75 
   76 #if VFREEBSD >= 220
   77 #define STATIC          static
   78 #else
   79 #define STATIC
   80 #endif
   81 
   82 /*****************************************************************************/
   83 
   84 /*
   85  *      Define different board types. At the moment I have only declared
   86  *      those boards that this driver supports. But I will use the standard
   87  *      "assigned" board numbers. In the future this driver will support
   88  *      some of the other Stallion boards. Currently supported boards are
   89  *      abbreviated as EIO = EasyIO and ECH = EasyConnection 8/32.
   90  */
   91 #define BRD_EASYIO      20
   92 #define BRD_ECH         21
   93 #define BRD_ECHMC       22
   94 #define BRD_ECHPCI      26
   95 
   96 /*
   97  *      When using the BSD "config" stuff there is no easy way to specifiy
   98  *      a secondary IO address region. So it is hard wired here. Also the
   99  *      shared interrupt information is hard wired here...
  100  */
  101 static unsigned int     stl_ioshared = 0x280;
  102 static unsigned int     stl_irqshared = 0;
  103 
  104 /*****************************************************************************/
  105 
  106 /*
  107  *      Define important driver limitations.
  108  */
  109 #define STL_MAXBRDS             8
  110 #define STL_MAXPANELS           4
  111 #define STL_PORTSPERPANEL       16
  112 #define STL_PORTSPERBRD         64
  113 
  114 /*
  115  *      Define the important minor number break down bits. These have been
  116  *      chosen to be "compatible" with the standard sio driver minor numbers.
  117  *      Extra high bits are used to distinguish between boards.
  118  */
  119 #define STL_CALLOUTDEV          0x80
  120 #define STL_CTRLLOCK            0x40
  121 #define STL_CTRLINIT            0x20
  122 #define STL_CTRLDEV             (STL_CTRLLOCK | STL_CTRLINIT)
  123 
  124 #define STL_MEMDEV      0x07000000
  125 
  126 #define STL_DEFSPEED    TTYDEF_SPEED
  127 #define STL_DEFCFLAG    (CS8 | CREAD | HUPCL)
  128 
  129 /*
  130  *      I haven't really decided (or measured) what buffer sizes give
  131  *      a good balance between performance and memory usage. These seem
  132  *      to work pretty well...
  133  */
  134 #define STL_RXBUFSIZE           2048
  135 #define STL_TXBUFSIZE           2048
  136 
  137 #define STL_TXBUFLOW            (STL_TXBUFSIZE / 4)
  138 #define STL_RXBUFHIGH           (3 * STL_RXBUFSIZE / 4)
  139 
  140 /*****************************************************************************/
  141 
  142 /*
  143  *      Define our local driver identity first. Set up stuff to deal with
  144  *      all the local structures required by a serial tty driver.
  145  */
  146 static const char       stl_drvname[] = "stl";
  147 static const char       stl_longdrvname[] = "Stallion Multiport Serial Driver";
  148 static const char       stl_drvversion[] = "1.0.0";
  149 static int              stl_brdprobed[STL_MAXBRDS];
  150 
  151 static int              stl_nrbrds = 0;
  152 static int              stl_doingtimeout = 0;
  153 
  154 static const char       __file__[] = /*__FILE__*/ "stallion.c";
  155 
  156 /*
  157  *      Define global stats structures. Not used often, and can be
  158  *      re-used for each stats call.
  159  */
  160 static combrd_t         stl_brdstats;
  161 static comstats_t       stl_comstats;
  162 
  163 /*****************************************************************************/
  164 
  165 /*
  166  *      Define a set of structures to hold all the board/panel/port info
  167  *      for our ports. These will be dynamically allocated as required.
  168  */
  169 
  170 /*
  171  *      Define a ring queue structure for each port. This will hold the
  172  *      TX data waiting to be output. Characters are fed into this buffer
  173  *      from the line discipline (or even direct from user space!) and
  174  *      then fed into the UARTs during interrupts. Will use a clasic ring
  175  *      queue here for this. The good thing about this type of ring queue
  176  *      is that the head and tail pointers can be updated without interrupt
  177  *      protection - since "write" code only needs to change the head, and
  178  *      interrupt code only needs to change the tail.
  179  */
  180 typedef struct {
  181         char    *buf;
  182         char    *endbuf;
  183         char    *head;
  184         char    *tail;
  185 } stlrq_t;
  186 
  187 /*
  188  *      Port, panel and board structures to hold status info about each.
  189  *      The board structure contains pointers to structures for each panel
  190  *      connected to it, and in turn each panel structure contains pointers
  191  *      for each port structure for each port on that panel. Note that
  192  *      the port structure also contains the board and panel number that it
  193  *      is associated with, this makes it (fairly) easy to get back to the
  194  *      board/panel info for a port. Also note that the tty struct is at
  195  *      the top of the structure, this is important, since the code uses
  196  *      this fact to get the port struct pointer from the tty struct
  197  *      pointer!
  198  */
  199 typedef struct {
  200         struct tty      tty;
  201         int             portnr;
  202         int             panelnr;
  203         int             brdnr;
  204         int             ioaddr;
  205         int             uartaddr;
  206         int             pagenr;
  207         int             callout;
  208         int             brklen;
  209         int             dtrwait;
  210         int             dotimestamp;
  211         int             waitopens;
  212         int             hotchar;
  213         unsigned int    state;
  214         unsigned int    hwid;
  215         unsigned int    sigs;
  216         unsigned int    rxignoremsk;
  217         unsigned int    rxmarkmsk;
  218         unsigned long   clk;
  219         struct termios  initintios;
  220         struct termios  initouttios;
  221         struct termios  lockintios;
  222         struct termios  lockouttios;
  223         struct timeval  timestamp;
  224         comstats_t      stats;
  225         stlrq_t         tx;
  226         stlrq_t         rx;
  227         stlrq_t         rxstatus;
  228 } stlport_t;
  229 
  230 typedef struct {
  231         int             panelnr;
  232         int             brdnr;
  233         int             pagenr;
  234         int             nrports;
  235         int             iobase;
  236         unsigned int    hwid;
  237         unsigned int    ackmask;
  238         stlport_t       *ports[STL_PORTSPERPANEL];
  239 } stlpanel_t;
  240 
  241 typedef struct {
  242         int             brdnr;
  243         int             brdtype;
  244         int             unitid;
  245         int             state;
  246         int             nrpanels;
  247         int             nrports;
  248         int             irq;
  249         int             irqtype;
  250         unsigned int    ioaddr1;
  251         unsigned int    ioaddr2;
  252         unsigned int    iostatus;
  253         unsigned int    ioctrl;
  254         unsigned int    ioctrlval;
  255         unsigned int    hwid;
  256         unsigned long   clk;
  257         stlpanel_t      *panels[STL_MAXPANELS];
  258         stlport_t       *ports[STL_PORTSPERBRD];
  259 } stlbrd_t;
  260 
  261 static stlbrd_t         *stl_brds[STL_MAXBRDS];
  262 
  263 /*
  264  *      Per board state flags. Used with the state field of the board struct.
  265  *      Not really much here yet!
  266  */
  267 #define BRD_FOUND       0x1
  268 
  269 /*
  270  *      Define the port structure state flags. These set of flags are
  271  *      modified at interrupt time - so setting and reseting them needs
  272  *      to be atomic.
  273  */
  274 #define ASY_TXLOW       0x1
  275 #define ASY_RXDATA      0x2
  276 #define ASY_DCDCHANGE   0x4
  277 #define ASY_DTRWAIT     0x8
  278 #define ASY_RTSFLOW     0x10
  279 #define ASY_RTSFLOWMODE 0x20
  280 #define ASY_CTSFLOWMODE 0x40
  281 
  282 #define ASY_ACTIVE      (ASY_TXLOW | ASY_RXDATA | ASY_DCDCHANGE)
  283 
  284 /*
  285  *      Define an array of board names as printable strings. Handy for
  286  *      referencing boards when printing trace and stuff.
  287  */
  288 static char     *stl_brdnames[] = {
  289         (char *) NULL,
  290         (char *) NULL,
  291         (char *) NULL,
  292         (char *) NULL,
  293         (char *) NULL,
  294         (char *) NULL,
  295         (char *) NULL,
  296         (char *) NULL,
  297         (char *) NULL,
  298         (char *) NULL,
  299         (char *) NULL,
  300         (char *) NULL,
  301         (char *) NULL,
  302         (char *) NULL,
  303         (char *) NULL,
  304         (char *) NULL,
  305         (char *) NULL,
  306         (char *) NULL,
  307         (char *) NULL,
  308         (char *) NULL,
  309         "EasyIO",
  310         "EC8/32-AT",
  311         "EC8/32-MC",
  312         (char *) NULL,
  313         (char *) NULL,
  314         (char *) NULL,
  315         "EC8/32-PCI",
  316 };
  317 
  318 /*****************************************************************************/
  319 
  320 /*
  321  *      Hardware ID bits for the EasyIO and ECH boards. These defines apply
  322  *      to the directly accessible io ports of these boards (not the cd1400
  323  *      uarts - they are in scd1400.h).
  324  */
  325 #define EIO_8PORTRS     0x04
  326 #define EIO_4PORTRS     0x05
  327 #define EIO_8PORTDI     0x00
  328 #define EIO_8PORTM      0x06
  329 #define EIO_IDBITMASK   0x07
  330 #define EIO_INTRPEND    0x08
  331 #define EIO_INTEDGE     0x00
  332 #define EIO_INTLEVEL    0x08
  333 
  334 #define ECH_ID          0xa0
  335 #define ECH_IDBITMASK   0xe0
  336 #define ECH_BRDENABLE   0x08
  337 #define ECH_BRDDISABLE  0x00
  338 #define ECH_INTENABLE   0x01
  339 #define ECH_INTDISABLE  0x00
  340 #define ECH_INTLEVEL    0x02
  341 #define ECH_INTEDGE     0x00
  342 #define ECH_INTRPEND    0x01
  343 #define ECH_BRDRESET    0x01
  344 
  345 #define ECHMC_INTENABLE 0x01
  346 #define ECHMC_BRDRESET  0x02
  347 
  348 #define ECH_PNLSTATUS   2
  349 #define ECH_PNL16PORT   0x20
  350 #define ECH_PNLIDMASK   0x07
  351 #define ECH_PNLINTRPEND 0x80
  352 #define ECH_ADDR2MASK   0x1e0
  353 
  354 #define EIO_CLK         25000000
  355 #define EIO_CLK8M       20000000
  356 #define ECH_CLK         EIO_CLK
  357 
  358 /*
  359  *      Define the offsets within the register bank for all io registers.
  360  *      These io address offsets are common to both the EIO and ECH.
  361  */
  362 #define EREG_ADDR       0
  363 #define EREG_DATA       4
  364 #define EREG_RXACK      5
  365 #define EREG_TXACK      6
  366 #define EREG_MDACK      7
  367 
  368 #define EREG_BANKSIZE   8
  369 
  370 /*
  371  *      Define the PCI vendor and device id for ECH8/32-PCI.
  372  */
  373 #define STL_PCIDEVID    0xd001100b
  374 
  375 /*
  376  *      Define the vector mapping bits for the programmable interrupt board
  377  *      hardware. These bits encode the interrupt for the board to use - it
  378  *      is software selectable (except the EIO-8M).
  379  */
  380 static unsigned char    stl_vecmap[] = {
  381         0xff, 0xff, 0xff, 0x04, 0x06, 0x05, 0xff, 0x07,
  382         0xff, 0xff, 0x00, 0x02, 0x01, 0xff, 0xff, 0x03
  383 };
  384 
  385 /*
  386  *      Set up enable and disable macros for the ECH boards. They require
  387  *      the secondary io address space to be activated and deactivated.
  388  *      This way all ECH boards can share their secondary io region.
  389  *      If this is an ECH-PCI board then also need to set the page pointer
  390  *      to point to the correct page.
  391  */
  392 #define BRDENABLE(brdnr,pagenr)                                         \
  393         if (stl_brds[(brdnr)]->brdtype == BRD_ECH)                      \
  394                 outb(stl_brds[(brdnr)]->ioctrl,                         \
  395                         (stl_brds[(brdnr)]->ioctrlval | ECH_BRDENABLE));\
  396         else if (stl_brds[(brdnr)]->brdtype == BRD_ECHPCI)              \
  397                 outb(stl_brds[(brdnr)]->ioctrl, (pagenr));
  398 
  399 #define BRDDISABLE(brdnr)                                               \
  400         if (stl_brds[(brdnr)]->brdtype == BRD_ECH)                      \
  401                 outb(stl_brds[(brdnr)]->ioctrl,                         \
  402                         (stl_brds[(brdnr)]->ioctrlval | ECH_BRDDISABLE));
  403 
  404 /*
  405  *      Define the cd1400 baud rate clocks. These are used when calculating
  406  *      what clock and divisor to use for the required baud rate. Also
  407  *      define the maximum baud rate allowed, and the default base baud.
  408  */
  409 static int      stl_cd1400clkdivs[] = {
  410         CD1400_CLK0, CD1400_CLK1, CD1400_CLK2, CD1400_CLK3, CD1400_CLK4
  411 };
  412 
  413 #define STL_MAXBAUD     230400
  414 
  415 /*****************************************************************************/
  416 
  417 /*
  418  *      Define macros to extract a brd and port number from a minor number.
  419  *      This uses the extended minor number range in the upper 2 bytes of
  420  *      the device number. This gives us plenty of minor numbers to play
  421  *      with...
  422  */
  423 #define MKDEV2BRD(m)    ((minor(m) & 0x00700000) >> 20)
  424 #define MKDEV2PORT(m)   ((minor(m) & 0x1f) | ((minor(m) & 0x00010000) >> 11))
  425 
  426 /*
  427  *      Define some handy local macros...
  428  */
  429 #ifndef MIN
  430 #define MIN(a,b)        (((a) <= (b)) ? (a) : (b))
  431 #endif
  432 
  433 /*****************************************************************************/
  434 
  435 /*
  436  *      Declare all those functions in this driver!  First up is the set of
  437  *      externally visible functions.
  438  */
  439 
  440 static int      stlprobe(struct isa_device *idp);
  441 static int      stlattach(struct isa_device *idp);
  442 
  443 STATIC  d_open_t        stlopen;
  444 STATIC  d_close_t       stlclose;
  445 STATIC  d_ioctl_t       stlioctl;
  446 
  447 /*
  448  *      Internal function prototypes.
  449  */
  450 static stlport_t *stl_dev2port(dev_t dev);
  451 static int      stl_findfreeunit(void);
  452 static int      stl_rawopen(stlport_t *portp);
  453 static int      stl_rawclose(stlport_t *portp);
  454 static int      stl_param(struct tty *tp, struct termios *tiosp);
  455 static void     stl_start(struct tty *tp);
  456 static void     stl_stop(struct tty *tp, int);
  457 static void     stl_ttyoptim(stlport_t *portp, struct termios *tiosp);
  458 static void     stl_dotimeout(void);
  459 static void     stl_poll(void *arg);
  460 static void     stl_rxprocess(stlport_t *portp);
  461 static void     stl_dtrwakeup(void *arg);
  462 static int      stl_brdinit(stlbrd_t *brdp);
  463 static int      stl_initeio(stlbrd_t *brdp);
  464 static int      stl_initech(stlbrd_t *brdp);
  465 static int      stl_initports(stlbrd_t *brdp, stlpanel_t *panelp);
  466 static ointhand2_t      stlintr;
  467 static __inline void    stl_txisr(stlpanel_t *panelp, int ioaddr);
  468 static __inline void    stl_rxisr(stlpanel_t *panelp, int ioaddr);
  469 static __inline void    stl_mdmisr(stlpanel_t *panelp, int ioaddr);
  470 static void     stl_setreg(stlport_t *portp, int regnr, int value);
  471 static int      stl_getreg(stlport_t *portp, int regnr);
  472 static int      stl_updatereg(stlport_t *portp, int regnr, int value);
  473 static int      stl_getsignals(stlport_t *portp);
  474 static void     stl_setsignals(stlport_t *portp, int dtr, int rts);
  475 static void     stl_flowcontrol(stlport_t *portp, int hw, int sw);
  476 static void     stl_ccrwait(stlport_t *portp);
  477 static void     stl_enablerxtx(stlport_t *portp, int rx, int tx);
  478 static void     stl_startrxtx(stlport_t *portp, int rx, int tx);
  479 static void     stl_disableintrs(stlport_t *portp);
  480 static void     stl_sendbreak(stlport_t *portp, long len);
  481 static void     stl_flush(stlport_t *portp, int flag);
  482 static int      stl_memioctl(dev_t dev, unsigned long cmd, caddr_t data,
  483                         int flag, struct thread *td);
  484 static int      stl_getbrdstats(caddr_t data);
  485 static int      stl_getportstats(stlport_t *portp, caddr_t data);
  486 static int      stl_clrportstats(stlport_t *portp, caddr_t data);
  487 static stlport_t *stl_getport(int brdnr, int panelnr, int portnr);
  488 
  489 #if NPCI > 0
  490 static const char *stlpciprobe(pcici_t tag, pcidi_t type);
  491 static void     stlpciattach(pcici_t tag, int unit);
  492 static void     stlpciintr(void * arg);
  493 #endif
  494 
  495 /*****************************************************************************/
  496 
  497 /*
  498  *      Declare the driver isa structure.
  499  */
  500 struct isa_driver       stldriver = {
  501         INTR_TYPE_TTY,
  502         stlprobe,
  503         stlattach,
  504         "stl"
  505 };
  506 COMPAT_ISA_DRIVER(stl, stldriver);
  507 
  508 /*****************************************************************************/
  509 
  510 #if NPCI > 0
  511 
  512 /*
  513  *      Declare the driver pci structure.
  514  */
  515 static unsigned long    stl_count;
  516 
  517 static struct pci_device        stlpcidriver = {
  518         "stl",
  519         stlpciprobe,
  520         stlpciattach,
  521         &stl_count,
  522         NULL,
  523 };
  524 
  525 COMPAT_PCI_DRIVER (stlpci, stlpcidriver);
  526 
  527 #endif
  528 
  529 /*****************************************************************************/
  530 
  531 #if VFREEBSD >= 220
  532 
  533 /*
  534  *      FreeBSD-2.2+ kernel linkage.
  535  */
  536 
  537 #define CDEV_MAJOR      72
  538 static struct cdevsw stl_cdevsw = {
  539         /* open */      stlopen,
  540         /* close */     stlclose,
  541         /* read */      ttyread,
  542         /* write */     ttywrite,
  543         /* ioctl */     stlioctl,
  544         /* poll */      ttypoll,
  545         /* mmap */      nommap,
  546         /* strategy */  nostrategy,
  547         /* name */      "stl",
  548         /* maj */       CDEV_MAJOR,
  549         /* dump */      nodump,
  550         /* psize */     nopsize,
  551         /* flags */     D_TTY | D_KQFILTER,
  552         /* kqfilter */  ttykqfilter,
  553 };
  554 
  555 static void stl_drvinit(void *unused)
  556 {
  557 
  558         cdevsw_add(&stl_cdevsw);
  559 }
  560 
  561 SYSINIT(sidev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,stl_drvinit,NULL)
  562 
  563 #endif
  564 
  565 /*****************************************************************************/
  566 
  567 /*
  568  *      Probe for some type of EasyIO or EasyConnection 8/32 board at
  569  *      the supplied address. All we do is check if we can find the
  570  *      board ID for the board... (Note, PCI boards not checked here,
  571  *      they are done in the stlpciprobe() routine).
  572  */
  573 
  574 static int stlprobe(struct isa_device *idp)
  575 {
  576         unsigned int    status;
  577 
  578 #if DEBUG
  579         printf("stlprobe(idp=%x): unit=%d iobase=%x\n", (int) idp,
  580                 idp->id_unit, idp->id_iobase);
  581 #endif
  582 
  583         if (idp->id_unit > STL_MAXBRDS)
  584                 return(0);
  585 
  586         status = inb(idp->id_iobase + 1);
  587         if ((status & ECH_IDBITMASK) == ECH_ID) {
  588                 stl_brdprobed[idp->id_unit] = BRD_ECH;
  589                 return(1);
  590         }
  591 
  592         status = inb(idp->id_iobase + 2);
  593         switch (status & EIO_IDBITMASK) {
  594         case EIO_8PORTRS:
  595         case EIO_8PORTM:
  596         case EIO_8PORTDI:
  597         case EIO_4PORTRS:
  598                 stl_brdprobed[idp->id_unit] = BRD_EASYIO;
  599                 return(1);
  600         default:
  601                 break;
  602         }
  603         
  604         return(0);
  605 }
  606 
  607 /*****************************************************************************/
  608 
  609 /*
  610  *      Find an available internal board number (unit number). The problem
  611  *      is that the same unit numbers can be assigned to different boards
  612  *      detected during the ISA and PCI initialization phases.
  613  */
  614 
  615 static int stl_findfreeunit()
  616 {
  617         int     i;
  618 
  619         for (i = 0; (i < STL_MAXBRDS); i++)
  620                 if (stl_brds[i] == (stlbrd_t *) NULL)
  621                         break;
  622         return((i >= STL_MAXBRDS) ? -1 : i);
  623 }
  624 
  625 /*****************************************************************************/
  626 
  627 /*
  628  *      Allocate resources for and initialize the specified board.
  629  */
  630 
  631 static int stlattach(struct isa_device *idp)
  632 {
  633         stlbrd_t        *brdp;
  634 
  635 #if DEBUG
  636         printf("stlattach(idp=%p): unit=%d iobase=%x\n", (void *) idp,
  637                 idp->id_unit, idp->id_iobase);
  638 #endif
  639 
  640         idp->id_ointr = stlintr;
  641 
  642         brdp = (stlbrd_t *) malloc(sizeof(stlbrd_t), M_TTYS, M_NOWAIT | M_ZERO);
  643         if (brdp == (stlbrd_t *) NULL) {
  644                 printf("STALLION: failed to allocate memory (size=%d)\n",
  645                         sizeof(stlbrd_t));
  646                 return(0);
  647         }
  648 
  649         if ((brdp->brdnr = stl_findfreeunit()) < 0) {
  650                 printf("STALLION: too many boards found, max=%d\n",
  651                         STL_MAXBRDS);
  652                 return(0);
  653         }
  654         if (brdp->brdnr >= stl_nrbrds)
  655                 stl_nrbrds = brdp->brdnr + 1;
  656 
  657         brdp->unitid = idp->id_unit;
  658         brdp->brdtype = stl_brdprobed[idp->id_unit];
  659         brdp->ioaddr1 = idp->id_iobase;
  660         brdp->ioaddr2 = stl_ioshared;
  661         brdp->irq = ffs(idp->id_irq) - 1;
  662         brdp->irqtype = stl_irqshared;
  663         stl_brdinit(brdp);
  664 
  665         return(1);
  666 }
  667 
  668 /*****************************************************************************/
  669 
  670 #if NPCI > 0
  671 
  672 /*
  673  *      Probe specifically for the PCI boards. We need to be a little
  674  *      carefull here, since it looks sort like a Nat Semi IDE chip...
  675  */
  676 
  677 static const char *stlpciprobe(pcici_t tag, pcidi_t type)
  678 {
  679         unsigned long   class;
  680 
  681 #if DEBUG
  682         printf("stlpciprobe(tag=%x,type=%x)\n", (int) &tag, (int) type);
  683 #endif
  684 
  685         switch (type) {
  686         case STL_PCIDEVID:
  687                 break;
  688         default:
  689                 return((char *) NULL);
  690         }
  691 
  692         class = pci_conf_read(tag, PCI_CLASS_REG);
  693         if ((class & PCI_CLASS_MASK) == PCI_CLASS_MASS_STORAGE)
  694                 return((char *) NULL);
  695 
  696         return("Stallion EasyConnection 8/32-PCI");
  697 }
  698 
  699 /*****************************************************************************/
  700 
  701 /*
  702  *      Allocate resources for and initialize the specified PCI board.
  703  */
  704 
  705 void stlpciattach(pcici_t tag, int unit)
  706 {
  707         stlbrd_t        *brdp;
  708 
  709 #if DEBUG
  710         printf("stlpciattach(tag=%x,unit=%x)\n", (int) &tag, unit);
  711 #endif
  712 
  713         brdp = (stlbrd_t *) malloc(sizeof(stlbrd_t), M_TTYS, M_NOWAIT | M_ZERO);
  714         if (brdp == (stlbrd_t *) NULL) {
  715                 printf("STALLION: failed to allocate memory (size=%d)\n",
  716                         sizeof(stlbrd_t));
  717                 return;
  718         }
  719 
  720         if ((unit < 0) || (unit > STL_MAXBRDS)) {
  721                 printf("STALLION: bad PCI board unit number=%d\n", unit);
  722                 return;
  723         }
  724 
  725 /*
  726  *      Allocate us a new driver unique unit number.
  727  */
  728         if ((brdp->brdnr = stl_findfreeunit()) < 0) {
  729                 printf("STALLION: too many boards found, max=%d\n",
  730                         STL_MAXBRDS);
  731                 return;
  732         }
  733         if (brdp->brdnr >= stl_nrbrds)
  734                 stl_nrbrds = brdp->brdnr + 1;
  735 
  736         brdp->unitid = 0;
  737         brdp->brdtype = BRD_ECHPCI;
  738         brdp->ioaddr1 = ((unsigned int) pci_conf_read(tag, 0x14)) & 0xfffc;
  739         brdp->ioaddr2 = ((unsigned int) pci_conf_read(tag, 0x10)) & 0xfffc;
  740         brdp->irq = ((int) pci_conf_read(tag, 0x3c)) & 0xff;
  741         brdp->irqtype = 0;
  742         if (pci_map_int(tag, stlpciintr, (void *) NULL, &tty_imask) == 0) {
  743                 printf("STALLION: failed to map interrupt irq=%d for unit=%d\n",
  744                         brdp->irq, brdp->brdnr);
  745                 return;
  746         }
  747 
  748 #if 0
  749         printf("%s(%d): ECH-PCI iobase=%x iopage=%x irq=%d\n", __file__,                         __LINE__, brdp->ioaddr2, brdp->ioaddr1, brdp->irq);
  750 #endif
  751         stl_brdinit(brdp);
  752 }
  753 
  754 #endif
  755 
  756 /*****************************************************************************/
  757 
  758 STATIC int stlopen(dev_t dev, int flag, int mode, struct thread *td)
  759 {
  760         struct tty      *tp;
  761         stlport_t       *portp;
  762         int             error, callout, x;
  763 
  764 #if DEBUG
  765         printf("stlopen(dev=%x,flag=%x,mode=%x,p=%x)\n", (int) dev, flag,
  766                 mode, (int) td);
  767 #endif
  768 
  769 /*
  770  *      Firstly check if the supplied device number is a valid device.
  771  */
  772         if (minor(dev) & STL_MEMDEV)
  773                 return(0);
  774 
  775         portp = stl_dev2port(dev);
  776         if (portp == (stlport_t *) NULL)
  777                 return(ENXIO);
  778         tp = &portp->tty;
  779         dev->si_tty = tp;
  780         callout = minor(dev) & STL_CALLOUTDEV;
  781         error = 0;
  782 
  783         x = spltty();
  784 
  785 stlopen_restart:
  786 /*
  787  *      Wait here for the DTR drop timeout period to expire.
  788  */
  789         while (portp->state & ASY_DTRWAIT) {
  790                 error = tsleep(&portp->dtrwait, (TTIPRI | PCATCH),
  791                         "stldtr", 0);
  792                 if (error)
  793                         goto stlopen_end;
  794         }
  795         
  796 /*
  797  *      We have a valid device, so now we check if it is already open.
  798  *      If not then initialize the port hardware and set up the tty
  799  *      struct as required.
  800  */
  801         if ((tp->t_state & TS_ISOPEN) == 0) {
  802                 tp->t_oproc = stl_start;
  803                 tp->t_stop = stl_stop;
  804                 tp->t_param = stl_param;
  805                 tp->t_dev = dev;
  806                 tp->t_termios = callout ? portp->initouttios :
  807                         portp->initintios;
  808                 stl_rawopen(portp);
  809                 if ((portp->sigs & TIOCM_CD) || callout)
  810                         (*linesw[tp->t_line].l_modem)(tp, 1);
  811         } else {
  812                 if (callout) {
  813                         if (portp->callout == 0) {
  814                                 error = EBUSY;
  815                                 goto stlopen_end;
  816                         }
  817                 } else {
  818                         if (portp->callout != 0) {
  819                                 if (flag & O_NONBLOCK) {
  820                                         error = EBUSY;
  821                                         goto stlopen_end;
  822                                 }
  823                                 error = tsleep(&portp->callout,
  824                                         (TTIPRI | PCATCH), "stlcall", 0);
  825                                 if (error)
  826                                         goto stlopen_end;
  827                                 goto stlopen_restart;
  828                         }
  829                 }
  830                 if ((tp->t_state & TS_XCLUDE) &&
  831                     suser(td)) {
  832                         error = EBUSY;
  833                         goto stlopen_end;
  834                 }
  835         }
  836 
  837 /*
  838  *      If this port is not the callout device and we do not have carrier
  839  *      then we need to sleep, waiting for it to be asserted.
  840  */
  841         if (((tp->t_state & TS_CARR_ON) == 0) && !callout &&
  842                         ((tp->t_cflag & CLOCAL) == 0) &&
  843                         ((flag & O_NONBLOCK) == 0)) {
  844                 portp->waitopens++;
  845                 error = tsleep(TSA_CARR_ON(tp), (TTIPRI | PCATCH), "stldcd", 0);
  846                 portp->waitopens--;
  847                 if (error)
  848                         goto stlopen_end;
  849                 goto stlopen_restart;
  850         }
  851 
  852 /*
  853  *      Open the line discipline.
  854  */
  855         error = (*linesw[tp->t_line].l_open)(dev, tp);
  856         stl_ttyoptim(portp, &tp->t_termios);
  857         if ((tp->t_state & TS_ISOPEN) && callout)
  858                 portp->callout = 1;
  859 
  860 /*
  861  *      If for any reason we get to here and the port is not actually
  862  *      open then close of the physical hardware - no point leaving it
  863  *      active when the open failed...
  864  */
  865 stlopen_end:
  866         splx(x);
  867         if (((tp->t_state & TS_ISOPEN) == 0) && (portp->waitopens == 0))
  868                 stl_rawclose(portp);
  869 
  870         return(error);
  871 }
  872 
  873 /*****************************************************************************/
  874 
  875 STATIC int stlclose(dev_t dev, int flag, int mode, struct thread *td)
  876 {
  877         struct tty      *tp;
  878         stlport_t       *portp;
  879         int             x;
  880 
  881 #if DEBUG
  882         printf("stlclose(dev=%s,flag=%x,mode=%x,p=%p)\n", devtoname(dev),
  883                 flag, mode, (void *) td);
  884 #endif
  885 
  886         if (minor(dev) & STL_MEMDEV)
  887                 return(0);
  888 
  889         portp = stl_dev2port(dev);
  890         if (portp == (stlport_t *) NULL)
  891                 return(ENXIO);
  892         tp = &portp->tty;
  893 
  894         x = spltty();
  895         (*linesw[tp->t_line].l_close)(tp, flag);
  896         stl_ttyoptim(portp, &tp->t_termios);
  897         stl_rawclose(portp);
  898         ttyclose(tp);
  899         splx(x);
  900         return(0);
  901 }
  902 
  903 /*****************************************************************************/
  904 
  905 #if VFREEBSD >= 220
  906 
  907 STATIC void stl_stop(struct tty *tp, int rw)
  908 {
  909 #if DEBUG
  910         printf("stl_stop(tp=%x,rw=%x)\n", (int) tp, rw);
  911 #endif
  912 
  913         stl_flush((stlport_t *) tp, rw);
  914 }
  915 
  916 #else
  917 
  918 STATIC int stlstop(struct tty *tp, int rw)
  919 {
  920 #if DEBUG
  921         printf("stlstop(tp=%x,rw=%x)\n", (int) tp, rw);
  922 #endif
  923 
  924         stl_flush((stlport_t *) tp, rw);
  925         return(0);
  926 }
  927 
  928 #endif
  929 
  930 /*****************************************************************************/
  931 
  932 STATIC int stlioctl(dev_t dev, unsigned long cmd, caddr_t data, int flag,
  933                     struct thread *td)
  934 {
  935         struct termios  *newtios, *localtios;
  936         struct tty      *tp;
  937         stlport_t       *portp;
  938         int             error, i, x;
  939 
  940 #if DEBUG
  941         printf("stlioctl(dev=%s,cmd=%lx,data=%p,flag=%x,p=%p)\n",
  942                 devtoname(dev), cmd, (void *) data, flag, (void *) td);
  943 #endif
  944 
  945         if (minor(dev) & STL_MEMDEV)
  946                 return(stl_memioctl(dev, cmd, data, flag, td));
  947 
  948         portp = stl_dev2port(dev);
  949         if (portp == (stlport_t *) NULL)
  950                 return(ENODEV);
  951         tp = &portp->tty;
  952         error = 0;
  953         
  954 /*
  955  *      First up handle ioctls on the control devices.
  956  */
  957         if (minor(dev) & STL_CTRLDEV) {
  958                 if ((minor(dev) & STL_CTRLDEV) == STL_CTRLINIT)
  959                         localtios = (minor(dev) & STL_CALLOUTDEV) ?
  960                                 &portp->initouttios : &portp->initintios;
  961                 else if ((minor(dev) & STL_CTRLDEV) == STL_CTRLLOCK)
  962                         localtios = (minor(dev) & STL_CALLOUTDEV) ?
  963                                 &portp->lockouttios : &portp->lockintios;
  964                 else
  965                         return(ENODEV);
  966 
  967                 switch (cmd) {
  968                 case TIOCSETA:
  969                         if ((error = suser(td)) == 0)
  970                                 *localtios = *((struct termios *) data);
  971                         break;
  972                 case TIOCGETA:
  973                         *((struct termios *) data) = *localtios;
  974                         break;
  975                 case TIOCGETD:
  976                         *((int *) data) = TTYDISC;
  977                         break;
  978                 case TIOCGWINSZ:
  979                         bzero(data, sizeof(struct winsize));
  980                         break;
  981                 default:
  982                         error = ENOTTY;
  983                         break;
  984                 }
  985                 return(error);
  986         }
  987 
  988 /*
  989  *      Deal with 4.3 compatibility issues if we have too...
  990  */
  991 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
  992         if (1) {
  993                 struct termios  tios;
  994                 unsigned long   oldcmd;
  995 
  996                 tios = tp->t_termios;
  997                 oldcmd = cmd;
  998                 if ((error = ttsetcompat(tp, &cmd, data, &tios)))
  999                         return(error);
 1000                 if (cmd != oldcmd)
 1001                         data = (caddr_t) &tios;
 1002         }
 1003 #endif
 1004 
 1005 /*
 1006  *      Carry out some pre-cmd processing work first...
 1007  *      Hmmm, not so sure we want this, disable for now...
 1008  */
 1009         if ((cmd == TIOCSETA) || (cmd == TIOCSETAW) || (cmd == TIOCSETAF)) {
 1010                 newtios = (struct termios *) data;
 1011                 localtios = (minor(dev) & STL_CALLOUTDEV) ? 
 1012                         &portp->lockouttios : &portp->lockintios;
 1013 
 1014                 newtios->c_iflag = (tp->t_iflag & localtios->c_iflag) |
 1015                         (newtios->c_iflag & ~localtios->c_iflag);
 1016                 newtios->c_oflag = (tp->t_oflag & localtios->c_oflag) |
 1017                         (newtios->c_oflag & ~localtios->c_oflag);
 1018                 newtios->c_cflag = (tp->t_cflag & localtios->c_cflag) |
 1019                         (newtios->c_cflag & ~localtios->c_cflag);
 1020                 newtios->c_lflag = (tp->t_lflag & localtios->c_lflag) |
 1021                         (newtios->c_lflag & ~localtios->c_lflag);
 1022                 for (i = 0; (i < NCCS); i++) {
 1023                         if (localtios->c_cc[i] != 0)
 1024                                 newtios->c_cc[i] = tp->t_cc[i];
 1025                 }
 1026                 if (localtios->c_ispeed != 0)
 1027                         newtios->c_ispeed = tp->t_ispeed;
 1028                 if (localtios->c_ospeed != 0)
 1029                         newtios->c_ospeed = tp->t_ospeed;
 1030         }
 1031 
 1032 /*
 1033  *      Call the line discipline and the common command processing to
 1034  *      process this command (if they can).
 1035  */
 1036         error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td);
 1037         if (error != ENOIOCTL)
 1038                 return(error);
 1039 
 1040         x = spltty();
 1041         error = ttioctl(tp, cmd, data, flag);
 1042         stl_ttyoptim(portp, &tp->t_termios);
 1043         if (error != ENOIOCTL) {
 1044                 splx(x);
 1045                 return(error);
 1046         }
 1047 
 1048         error = 0;
 1049 
 1050 /*
 1051  *      Process local commands here. These are all commands that only we
 1052  *      can take care of (they all rely on actually doing something special
 1053  *      to the actual hardware).
 1054  */
 1055         switch (cmd) {
 1056         case TIOCSBRK:
 1057                 stl_sendbreak(portp, -1);
 1058                 break;
 1059         case TIOCCBRK:
 1060                 stl_sendbreak(portp, -2);
 1061                 break;
 1062         case TIOCSDTR:
 1063                 stl_setsignals(portp, 1, -1);
 1064                 break;
 1065         case TIOCCDTR:
 1066                 stl_setsignals(portp, 0, -1);
 1067                 break;
 1068         case TIOCMSET:
 1069                 i = *((int *) data);
 1070                 stl_setsignals(portp, ((i & TIOCM_DTR) ? 1 : 0),
 1071                         ((i & TIOCM_RTS) ? 1 : 0));
 1072                 break;
 1073         case TIOCMBIS:
 1074                 i = *((int *) data);
 1075                 stl_setsignals(portp, ((i & TIOCM_DTR) ? 1 : -1),
 1076                         ((i & TIOCM_RTS) ? 1 : -1));
 1077                 break;
 1078         case TIOCMBIC:
 1079                 i = *((int *) data);
 1080                 stl_setsignals(portp, ((i & TIOCM_DTR) ? 0 : -1),
 1081                         ((i & TIOCM_RTS) ? 0 : -1));
 1082                 break;
 1083         case TIOCMGET:
 1084                 *((int *) data) = (stl_getsignals(portp) | TIOCM_LE);
 1085                 break;
 1086         case TIOCMSDTRWAIT:
 1087                 if ((error = suser(td)) == 0)
 1088                         portp->dtrwait = *((int *) data) * hz / 100;
 1089                 break;
 1090         case TIOCMGDTRWAIT:
 1091                 *((int *) data) = portp->dtrwait * 100 / hz;
 1092                 break;
 1093         case TIOCTIMESTAMP:
 1094                 portp->dotimestamp = 1;
 1095                 *((struct timeval *) data) = portp->timestamp;
 1096                 break;
 1097         default:
 1098                 error = ENOTTY;
 1099                 break;
 1100         }
 1101         splx(x);
 1102 
 1103         return(error);
 1104 }
 1105 
 1106 /*****************************************************************************/
 1107 
 1108 /*
 1109  *      Convert the specified minor device number into a port struct
 1110  *      pointer. Return NULL if the device number is not a valid port.
 1111  */
 1112 
 1113 STATIC stlport_t *stl_dev2port(dev_t dev)
 1114 {
 1115         stlbrd_t        *brdp;
 1116 
 1117         brdp = stl_brds[MKDEV2BRD(dev)];
 1118         if (brdp == (stlbrd_t *) NULL)
 1119                 return((stlport_t *) NULL);
 1120         return(brdp->ports[MKDEV2PORT(dev)]);
 1121 }
 1122 
 1123 /*****************************************************************************/
 1124 
 1125 /*
 1126  *      Initialize the port hardware. This involves enabling the transmitter
 1127  *      and receiver, setting the port configuration, and setting the initial
 1128  *      signal state.
 1129  */
 1130 
 1131 static int stl_rawopen(stlport_t *portp)
 1132 {
 1133 #if DEBUG
 1134         printf("stl_rawopen(portp=%p): brdnr=%d panelnr=%d portnr=%d\n",
 1135                 (void *) portp, portp->brdnr, portp->panelnr, portp->portnr);
 1136 #endif
 1137         stl_param(&portp->tty, &portp->tty.t_termios);
 1138         portp->sigs = stl_getsignals(portp);
 1139         stl_setsignals(portp, 1, 1);
 1140         stl_enablerxtx(portp, 1, 1);
 1141         stl_startrxtx(portp, 1, 0);
 1142         return(0);
 1143 }
 1144 
 1145 /*****************************************************************************/
 1146 
 1147 /*
 1148  *      Shutdown the hardware of a port. Disable its transmitter and
 1149  *      receiver, and maybe drop signals if appropriate.
 1150  */
 1151 
 1152 static int stl_rawclose(stlport_t *portp)
 1153 {
 1154         struct tty      *tp;
 1155 
 1156 #if DEBUG
 1157         printf("stl_rawclose(portp=%p): brdnr=%d panelnr=%d portnr=%d\n",
 1158                 (void *) portp, portp->brdnr, portp->panelnr, portp->portnr);
 1159 #endif
 1160 
 1161         tp = &portp->tty;
 1162         stl_disableintrs(portp);
 1163         stl_enablerxtx(portp, 0, 0);
 1164         stl_flush(portp, (FWRITE | FREAD));
 1165         if (tp->t_cflag & HUPCL) {
 1166                 stl_setsignals(portp, 0, 0);
 1167                 if (portp->dtrwait != 0) {
 1168                         portp->state |= ASY_DTRWAIT;
 1169                         timeout(stl_dtrwakeup, portp, portp->dtrwait);
 1170                 }
 1171         }
 1172         portp->callout = 0;
 1173         portp->brklen = 0;
 1174         portp->state &= ~(ASY_ACTIVE | ASY_RTSFLOW);
 1175         wakeup(&portp->callout);
 1176         wakeup(TSA_CARR_ON(tp));
 1177         return(0);
 1178 }
 1179 
 1180 /*****************************************************************************/
 1181 
 1182 /*
 1183  *      Clear the DTR waiting flag, and wake up any sleepers waiting for
 1184  *      DTR wait period to finish.
 1185  */
 1186 
 1187 static void stl_dtrwakeup(void *arg)
 1188 {
 1189         stlport_t       *portp;
 1190 
 1191         portp = (stlport_t *) arg;
 1192         portp->state &= ~ASY_DTRWAIT;
 1193         wakeup(&portp->dtrwait);
 1194 }
 1195 
 1196 /*****************************************************************************/
 1197 
 1198 /*
 1199  *      Start (or continue) the transfer of TX data on this port. If the
 1200  *      port is not currently busy then load up the interrupt ring queue
 1201  *      buffer and kick of the transmitter. If the port is running low on
 1202  *      TX data then refill the ring queue. This routine is also used to
 1203  *      activate input flow control!
 1204  */
 1205 
 1206 static void stl_start(struct tty *tp)
 1207 {
 1208         stlport_t       *portp;
 1209         unsigned int    len, stlen;
 1210         char            *head, *tail;
 1211         int             count, x;
 1212 
 1213         portp = (stlport_t *) tp;
 1214 
 1215 #if DEBUG
 1216         printf("stl_start(tp=%x): brdnr=%d portnr=%d\n", (int) tp, 
 1217                 portp->brdnr, portp->portnr);
 1218 #endif
 1219 
 1220         x = spltty();
 1221 
 1222 /*
 1223  *      Check if the ports input has been blocked, and take appropriate action.
 1224  *      Not very often do we really need to do anything, so make it quick.
 1225  */
 1226         if (tp->t_state & TS_TBLOCK) {
 1227                 if ((portp->state & ASY_RTSFLOW) == 0)
 1228                         stl_flowcontrol(portp, 0, -1);
 1229         } else {
 1230                 if (portp->state & ASY_RTSFLOW)
 1231                         stl_flowcontrol(portp, 1, -1);
 1232         }
 1233 
 1234 #if VFREEBSD == 205
 1235 /*
 1236  *      Check if the output cooked clist buffers are near empty, wake up
 1237  *      the line discipline to fill it up.
 1238  */
 1239         if (tp->t_outq.c_cc <= tp->t_lowat) {
 1240                 if (tp->t_state & TS_ASLEEP) {
 1241                         tp->t_state &= ~TS_ASLEEP;
 1242                         wakeup(&tp->t_outq);
 1243                 }
 1244                 selwakeup(&tp->t_wsel);
 1245         }
 1246 #endif
 1247 
 1248         if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
 1249                 splx(x);
 1250                 return;
 1251         }
 1252 
 1253 /*
 1254  *      Copy data from the clists into the interrupt ring queue. This will
 1255  *      require at most 2 copys... What we do is calculate how many chars
 1256  *      can fit into the ring queue, and how many can fit in 1 copy. If after
 1257  *      the first copy there is still more room then do the second copy. 
 1258  *      The beauty of this type of ring queue is that we do not need to
 1259  *      spl protect our-selves, since we only ever update the head pointer,
 1260  *      and the interrupt routine only ever updates the tail pointer.
 1261  */
 1262         if (tp->t_outq.c_cc != 0) {
 1263                 head = portp->tx.head;
 1264                 tail = portp->tx.tail;
 1265                 if (head >= tail) {
 1266                         len = STL_TXBUFSIZE - (head - tail) - 1;
 1267                         stlen = portp->tx.endbuf - head;
 1268                 } else {
 1269                         len = tail - head - 1;
 1270                         stlen = len;
 1271                 }
 1272 
 1273                 if (len > 0) {
 1274                         stlen = MIN(len, stlen);
 1275                         count = q_to_b(&tp->t_outq, head, stlen);
 1276                         len -= count;
 1277                         head += count;
 1278                         if (head >= portp->tx.endbuf) {
 1279                                 head = portp->tx.buf;
 1280                                 if (len > 0) {
 1281                                         stlen = q_to_b(&tp->t_outq, head, len);
 1282                                         head += stlen;
 1283                                         count += stlen;
 1284                                 }
 1285                         }
 1286                         portp->tx.head = head;
 1287                         if (count > 0)
 1288                                 stl_startrxtx(portp, -1, 1);
 1289                 }
 1290 
 1291 /*
 1292  *              If we sent something, make sure we are called again.
 1293  */
 1294                 tp->t_state |= TS_BUSY;
 1295         }
 1296 
 1297 #if VFREEBSD != 205
 1298 /*
 1299  *      Do any writer wakeups.
 1300  */
 1301         ttwwakeup(tp);
 1302 #endif
 1303 
 1304         splx(x);
 1305 }
 1306 
 1307 /*****************************************************************************/
 1308 
 1309 static void stl_flush(stlport_t *portp, int flag)
 1310 {
 1311         char    *head, *tail;
 1312         int     len, x;
 1313 
 1314 #if DEBUG
 1315         printf("stl_flush(portp=%x,flag=%x)\n", (int) portp, flag);
 1316 #endif
 1317 
 1318         if (portp == (stlport_t *) NULL)
 1319                 return;
 1320 
 1321         x = spltty();
 1322 
 1323         if (flag & FWRITE) {
 1324                 BRDENABLE(portp->brdnr, portp->pagenr);
 1325                 stl_setreg(portp, CAR, (portp->portnr & 0x03));
 1326                 stl_ccrwait(portp);
 1327                 stl_setreg(portp, CCR, CCR_TXFLUSHFIFO);
 1328                 stl_ccrwait(portp);
 1329                 portp->tx.tail = portp->tx.head;
 1330                 BRDDISABLE(portp->brdnr);
 1331         }
 1332 
 1333 /*
 1334  *      The only thing to watch out for when flushing the read side is
 1335  *      the RX status buffer. The interrupt code relys on the status
 1336  *      bytes as being zeroed all the time (it does not bother setting
 1337  *      a good char status to 0, it expects that it already will be).
 1338  *      We also need to un-flow the RX channel if flow control was
 1339  *      active.
 1340  */
 1341         if (flag & FREAD) {
 1342                 head = portp->rx.head;
 1343                 tail = portp->rx.tail;
 1344                 if (head != tail) {
 1345                         if (head >= tail) {
 1346                                 len = head - tail;
 1347                         } else {
 1348                                 len = portp->rx.endbuf - tail;
 1349                                 bzero(portp->rxstatus.buf,
 1350                                         (head - portp->rx.buf));
 1351                         }
 1352                         bzero((tail + STL_RXBUFSIZE), len);
 1353                         portp->rx.tail = head;
 1354                 }
 1355 
 1356                 if ((portp->state & ASY_RTSFLOW) &&
 1357                                 ((portp->tty.t_state & TS_TBLOCK) == 0))
 1358                         stl_flowcontrol(portp, 1, -1);
 1359         }
 1360 
 1361         splx(x);
 1362 }
 1363 
 1364 /*****************************************************************************/
 1365 
 1366 /*
 1367  *      These functions get/set/update the registers of the cd1400 UARTs.
 1368  *      Access to the cd1400 registers is via an address/data io port pair.
 1369  *      (Maybe should make this inline...)
 1370  */
 1371 
 1372 static int stl_getreg(stlport_t *portp, int regnr)
 1373 {
 1374         outb(portp->ioaddr, (regnr + portp->uartaddr));
 1375         return(inb(portp->ioaddr + EREG_DATA));
 1376 }
 1377 
 1378 /*****************************************************************************/
 1379 
 1380 static void stl_setreg(stlport_t *portp, int regnr, int value)
 1381 {
 1382         outb(portp->ioaddr, (regnr + portp->uartaddr));
 1383         outb((portp->ioaddr + EREG_DATA), value);
 1384 }
 1385 
 1386 /*****************************************************************************/
 1387 
 1388 static int stl_updatereg(stlport_t *portp, int regnr, int value)
 1389 {
 1390         outb(portp->ioaddr, (regnr + portp->uartaddr));
 1391         if (inb(portp->ioaddr + EREG_DATA) != value) {
 1392                 outb((portp->ioaddr + EREG_DATA), value);
 1393                 return(1);
 1394         }
 1395         return(0);
 1396 }
 1397 
 1398 /*****************************************************************************/
 1399 
 1400 /*
 1401  *      Wait for the command register to be ready. We will poll this, since
 1402  *      it won't usually take too long to be ready, and it is only really
 1403  *      used for non-critical actions.
 1404  */
 1405 
 1406 static void stl_ccrwait(stlport_t *portp)
 1407 {
 1408         int     i;
 1409 
 1410         for (i = 0; (i < CCR_MAXWAIT); i++) {
 1411                 if (stl_getreg(portp, CCR) == 0) {
 1412                         return;
 1413                 }
 1414         }
 1415 
 1416         printf("STALLION: cd1400 device not responding, brd=%d panel=%d"
 1417                 "port=%d\n", portp->brdnr, portp->panelnr, portp->portnr);
 1418 }
 1419 
 1420 /*****************************************************************************/
 1421 
 1422 /*
 1423  *      Transmit interrupt handler. This has gotta be fast!  Handling TX
 1424  *      chars is pretty simple, stuff as many as possible from the TX buffer
 1425  *      into the cd1400 FIFO. Must also handle TX breaks here, since they
 1426  *      are embedded as commands in the data stream. Oh no, had to use a goto!
 1427  *      This could be optimized more, will do when I get time...
 1428  *      In practice it is possible that interrupts are enabled but that the
 1429  *      port has been hung up. Need to handle not having any TX buffer here,
 1430  *      this is done by using the side effect that head and tail will also
 1431  *      be NULL if the buffer has been freed.
 1432  */
 1433 
 1434 static __inline void stl_txisr(stlpanel_t *panelp, int ioaddr)
 1435 {
 1436         stlport_t       *portp;
 1437         int             len, stlen;
 1438         char            *head, *tail;
 1439         unsigned char   ioack, srer;
 1440 
 1441 #if DEBUG
 1442         printf("stl_txisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
 1443 #endif
 1444 
 1445         ioack = inb(ioaddr + EREG_TXACK);
 1446         if (((ioack & panelp->ackmask) != 0) ||
 1447                         ((ioack & ACK_TYPMASK) != ACK_TYPTX)) {
 1448                 printf("STALLION: bad TX interrupt ack value=%x\n", ioack);
 1449                 return;
 1450         }
 1451         portp = panelp->ports[(ioack >> 3)];
 1452 
 1453 /*
 1454  *      Unfortunately we need to handle breaks in the data stream, since
 1455  *      this is the only way to generate them on the cd1400. Do it now if
 1456  *      a break is to be sent. Some special cases here: brklen is -1 then
 1457  *      start sending an un-timed break, if brklen is -2 then stop sending
 1458  *      an un-timed break, if brklen is -3 then we have just sent an
 1459  *      un-timed break and do not want any data to go out, if brklen is -4
 1460  *      then a break has just completed so clean up the port settings.
 1461  */
 1462         if (portp->brklen != 0) {
 1463                 if (portp->brklen >= -1) {
 1464                         outb(ioaddr, (TDR + portp->uartaddr));
 1465                         outb((ioaddr + EREG_DATA), ETC_CMD);
 1466                         outb((ioaddr + EREG_DATA), ETC_STARTBREAK);
 1467                         if (portp->brklen > 0) {
 1468                                 outb((ioaddr + EREG_DATA), ETC_CMD);
 1469                                 outb((ioaddr + EREG_DATA), ETC_DELAY);
 1470                                 outb((ioaddr + EREG_DATA), portp->brklen);
 1471                                 outb((ioaddr + EREG_DATA), ETC_CMD);
 1472                                 outb((ioaddr + EREG_DATA), ETC_STOPBREAK);
 1473                                 portp->brklen = -4;
 1474                         } else {
 1475                                 portp->brklen = -3;
 1476                         }
 1477                 } else if (portp->brklen == -2) {
 1478                         outb(ioaddr, (TDR + portp->uartaddr));
 1479                         outb((ioaddr + EREG_DATA), ETC_CMD);
 1480                         outb((ioaddr + EREG_DATA), ETC_STOPBREAK);
 1481                         portp->brklen = -4;
 1482                 } else if (portp->brklen == -3) {
 1483                         outb(ioaddr, (SRER + portp->uartaddr));
 1484                         srer = inb(ioaddr + EREG_DATA);
 1485                         srer &= ~(SRER_TXDATA | SRER_TXEMPTY);
 1486                         outb((ioaddr + EREG_DATA), srer);
 1487                 } else {
 1488                         outb(ioaddr, (COR2 + portp->uartaddr));
 1489                         outb((ioaddr + EREG_DATA),
 1490                                 (inb(ioaddr + EREG_DATA) & ~COR2_ETC));
 1491                         portp->brklen = 0;
 1492                 }
 1493                 goto stl_txalldone;
 1494         }
 1495 
 1496         head = portp->tx.head;
 1497         tail = portp->tx.tail;
 1498         len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
 1499         if ((len == 0) || ((len < STL_TXBUFLOW) &&
 1500                         ((portp->state & ASY_TXLOW) == 0))) {
 1501                 portp->state |= ASY_TXLOW;
 1502                 stl_dotimeout();
 1503         }
 1504 
 1505         if (len == 0) {
 1506                 outb(ioaddr, (SRER + portp->uartaddr));
 1507                 srer = inb(ioaddr + EREG_DATA);
 1508                 if (srer & SRER_TXDATA) {
 1509                         srer = (srer & ~SRER_TXDATA) | SRER_TXEMPTY;
 1510                 } else {
 1511                         srer &= ~(SRER_TXDATA | SRER_TXEMPTY);
 1512                         portp->tty.t_state &= ~TS_BUSY;
 1513                 }
 1514                 outb((ioaddr + EREG_DATA), srer);
 1515         } else {
 1516                 len = MIN(len, CD1400_TXFIFOSIZE);
 1517                 portp->stats.txtotal += len;
 1518                 stlen = MIN(len, (portp->tx.endbuf - tail));
 1519                 outb(ioaddr, (TDR + portp->uartaddr));
 1520                 outsb((ioaddr + EREG_DATA), tail, stlen);
 1521                 len -= stlen;
 1522                 tail += stlen;
 1523                 if (tail >= portp->tx.endbuf)
 1524                         tail = portp->tx.buf;
 1525                 if (len > 0) {
 1526                         outsb((ioaddr + EREG_DATA), tail, len);
 1527                         tail += len;
 1528                 }
 1529                 portp->tx.tail = tail;
 1530         }
 1531 
 1532 stl_txalldone:
 1533         outb(ioaddr, (EOSRR + portp->uartaddr));
 1534         outb((ioaddr + EREG_DATA), 0);
 1535 }
 1536 
 1537 /*****************************************************************************/
 1538 
 1539 /*
 1540  *      Receive character interrupt handler. Determine if we have good chars
 1541  *      or bad chars and then process appropriately. Good chars are easy
 1542  *      just shove the lot into the RX buffer and set all status bytes to 0.
 1543  *      If a bad RX char then process as required. This routine needs to be
 1544  *      fast!
 1545  */
 1546 
 1547 static __inline void stl_rxisr(stlpanel_t *panelp, int ioaddr)
 1548 {
 1549         stlport_t       *portp;
 1550         struct tty      *tp;
 1551         unsigned int    ioack, len, buflen, stlen;
 1552         unsigned char   status;
 1553         char            ch;
 1554         char            *head, *tail;
 1555         static char     unwanted[CD1400_RXFIFOSIZE];
 1556 
 1557 #if DEBUG
 1558         printf("stl_rxisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
 1559 #endif
 1560 
 1561         ioack = inb(ioaddr + EREG_RXACK);
 1562         if ((ioack & panelp->ackmask) != 0) {
 1563                 printf("STALLION: bad RX interrupt ack value=%x\n", ioack);
 1564                 return;
 1565         }
 1566         portp = panelp->ports[(ioack >> 3)];
 1567         tp = &portp->tty;
 1568 
 1569 /*
 1570  *      First up, caluclate how much room there is in the RX ring queue.
 1571  *      We also want to keep track of the longest possible copy length,
 1572  *      this has to allow for the wrapping of the ring queue.
 1573  */
 1574         head = portp->rx.head;
 1575         tail = portp->rx.tail;
 1576         if (head >= tail) {
 1577                 buflen = STL_RXBUFSIZE - (head - tail) - 1;
 1578                 stlen = portp->rx.endbuf - head;
 1579         } else {
 1580                 buflen = tail - head - 1;
 1581                 stlen = buflen;
 1582         }
 1583 
 1584 /*
 1585  *      Check if the input buffer is near full. If so then we should take
 1586  *      some flow control action... It is very easy to do hardware and
 1587  *      software flow control from here since we have the port selected on
 1588  *      the UART.
 1589  */
 1590         if (buflen <= (STL_RXBUFSIZE - STL_RXBUFHIGH)) {
 1591                 if (((portp->state & ASY_RTSFLOW) == 0) &&
 1592                                 (portp->state & ASY_RTSFLOWMODE)) {
 1593                         portp->state |= ASY_RTSFLOW;
 1594                         stl_setreg(portp, MCOR1,
 1595                                 (stl_getreg(portp, MCOR1) & 0xf0));
 1596                         stl_setreg(portp, MSVR2, 0);
 1597                         portp->stats.rxrtsoff++;
 1598                 }
 1599         }
 1600 
 1601 /*
 1602  *      OK we are set, process good data... If the RX ring queue is full
 1603  *      just chuck the chars - don't leave them in the UART.
 1604  */
 1605         if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
 1606                 outb(ioaddr, (RDCR + portp->uartaddr));
 1607                 len = inb(ioaddr + EREG_DATA);
 1608                 if (buflen == 0) {
 1609                         outb(ioaddr, (RDSR + portp->uartaddr));
 1610                         insb((ioaddr + EREG_DATA), &unwanted[0], len);
 1611                         portp->stats.rxlost += len;
 1612                         portp->stats.rxtotal += len;
 1613                 } else {
 1614                         len = MIN(len, buflen);
 1615                         portp->stats.rxtotal += len;
 1616                         stlen = MIN(len, stlen);
 1617                         if (len > 0) {
 1618                                 outb(ioaddr, (RDSR + portp->uartaddr));
 1619                                 insb((ioaddr + EREG_DATA), head, stlen);
 1620                                 head += stlen;
 1621                                 if (head >= portp->rx.endbuf) {
 1622                                         head = portp->rx.buf;
 1623                                         len -= stlen;
 1624                                         insb((ioaddr + EREG_DATA), head, len);
 1625                                         head += len;
 1626                                 }
 1627                         }
 1628                 }
 1629         } else if ((ioack & ACK_TYPMASK) == ACK_TYPRXBAD) {
 1630                 outb(ioaddr, (RDSR + portp->uartaddr));
 1631                 status = inb(ioaddr + EREG_DATA);
 1632                 ch = inb(ioaddr + EREG_DATA);
 1633                 if (status & ST_BREAK)
 1634                         portp->stats.rxbreaks++;
 1635                 if (status & ST_FRAMING)
 1636                         portp->stats.rxframing++;
 1637                 if (status & ST_PARITY)
 1638                         portp->stats.rxparity++;
 1639                 if (status & ST_OVERRUN)
 1640                         portp->stats.rxoverrun++;
 1641                 if (status & ST_SCHARMASK) {
 1642                         if ((status & ST_SCHARMASK) == ST_SCHAR1)
 1643                                 portp->stats.txxon++;
 1644                         if ((status & ST_SCHARMASK) == ST_SCHAR2)
 1645                                 portp->stats.txxoff++;
 1646                         goto stl_rxalldone;
 1647                 }
 1648                 if ((portp->rxignoremsk & status) == 0) {
 1649                         if ((tp->t_state & TS_CAN_BYPASS_L_RINT) &&
 1650                             ((status & ST_FRAMING) ||
 1651                             ((status & ST_PARITY) && (tp->t_iflag & INPCK))))
 1652                                 ch = 0;
 1653                         if ((portp->rxmarkmsk & status) == 0)
 1654                                 status = 0;
 1655                         *(head + STL_RXBUFSIZE) = status;
 1656                         *head++ = ch;
 1657                         if (head >= portp->rx.endbuf)
 1658                                 head = portp->rx.buf;
 1659                 }
 1660         } else {
 1661                 printf("STALLION: bad RX interrupt ack value=%x\n", ioack);
 1662                 return;
 1663         }
 1664 
 1665         portp->rx.head = head;
 1666         portp->state |= ASY_RXDATA;
 1667         stl_dotimeout();
 1668 
 1669 stl_rxalldone:
 1670         outb(ioaddr, (EOSRR + portp->uartaddr));
 1671         outb((ioaddr + EREG_DATA), 0);
 1672 }
 1673 
 1674 /*****************************************************************************/
 1675 
 1676 /*
 1677  *      Modem interrupt handler. The is called when the modem signal line
 1678  *      (DCD) has changed state. Leave most of the work to the off-level
 1679  *      processing routine.
 1680  */
 1681 
 1682 static __inline void stl_mdmisr(stlpanel_t *panelp, int ioaddr)
 1683 {
 1684         stlport_t       *portp;
 1685         unsigned int    ioack;
 1686         unsigned char   misr;
 1687 
 1688 #if DEBUG
 1689         printf("stl_mdmisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
 1690 #endif
 1691 
 1692         ioack = inb(ioaddr + EREG_MDACK);
 1693         if (((ioack & panelp->ackmask) != 0) ||
 1694                         ((ioack & ACK_TYPMASK) != ACK_TYPMDM)) {
 1695                 printf("STALLION: bad MODEM interrupt ack value=%x\n", ioack);
 1696                 return;
 1697         }
 1698         portp = panelp->ports[(ioack >> 3)];
 1699 
 1700         outb(ioaddr, (MISR + portp->uartaddr));
 1701         misr = inb(ioaddr + EREG_DATA);
 1702         if (misr & MISR_DCD) {
 1703                 portp->state |= ASY_DCDCHANGE;
 1704                 portp->stats.modem++;
 1705                 stl_dotimeout();
 1706         }
 1707 
 1708         outb(ioaddr, (EOSRR + portp->uartaddr));
 1709         outb((ioaddr + EREG_DATA), 0);
 1710 }
 1711 
 1712 /*****************************************************************************/
 1713 
 1714 /*
 1715  *      Interrupt handler for EIO and ECH boards. This code ain't all that
 1716  *      pretty, but the idea is to make it as fast as possible. This code is
 1717  *      well suited to be assemblerized :-)  We don't use the general purpose
 1718  *      register access functions here, for speed we will go strait to the
 1719  *      io register.
 1720  */
 1721 
 1722 static void stlintr(int unit)
 1723 {
 1724         stlbrd_t        *brdp;
 1725         stlpanel_t      *panelp;
 1726         unsigned char   svrtype;
 1727         int             i, panelnr, iobase;
 1728         int             cnt;
 1729 
 1730 #if DEBUG
 1731         printf("stlintr(unit=%d)\n", unit);
 1732 #endif
 1733 
 1734         cnt = 0;
 1735         panelp = (stlpanel_t *) NULL;
 1736         for (i = 0; (i < stl_nrbrds); ) {
 1737                 if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) {
 1738                         i++;
 1739                         continue;
 1740                 }
 1741                 if (brdp->state == 0) {
 1742                         i++;
 1743                         continue;
 1744                 }
 1745 /*
 1746  *              The following section of code handles the subtle differences
 1747  *              between board types. It is sort of similar, but different
 1748  *              enough to handle each separately.
 1749  */
 1750                 if (brdp->brdtype == BRD_EASYIO) {
 1751                         if ((inb(brdp->iostatus) & EIO_INTRPEND) == 0) {
 1752                                 i++;
 1753                                 continue;
 1754                         }
 1755                         panelp = brdp->panels[0];
 1756                         iobase = panelp->iobase;
 1757                         outb(iobase, SVRR);
 1758                         svrtype = inb(iobase + EREG_DATA);
 1759                         if (brdp->nrports > 4) {
 1760                                 outb(iobase, (SVRR + 0x80));
 1761                                 svrtype |= inb(iobase + EREG_DATA);
 1762                         }
 1763                 } else if (brdp->brdtype == BRD_ECH) {
 1764                         if ((inb(brdp->iostatus) & ECH_INTRPEND) == 0) {
 1765                                 i++;
 1766                                 continue;
 1767                         }
 1768                         outb(brdp->ioctrl, (brdp->ioctrlval | ECH_BRDENABLE));
 1769                         for (panelnr = 0; (panelnr < brdp->nrpanels); panelnr++) {
 1770                                 panelp = brdp->panels[panelnr];
 1771                                 iobase = panelp->iobase;
 1772                                 if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
 1773                                         break;
 1774                                 if (panelp->nrports > 8) {
 1775                                         iobase += 0x8;
 1776                                         if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
 1777                                                 break;
 1778                                 }
 1779                         }       
 1780                         if (panelnr >= brdp->nrpanels) {
 1781                                 i++;
 1782                                 continue;
 1783                         }
 1784                         outb(iobase, SVRR);
 1785                         svrtype = inb(iobase + EREG_DATA);
 1786                         outb(iobase, (SVRR + 0x80));
 1787                         svrtype |= inb(iobase + EREG_DATA);
 1788                 } else if (brdp->brdtype == BRD_ECHPCI) {
 1789                         iobase = brdp->ioaddr2;
 1790                         for (panelnr = 0; (panelnr < brdp->nrpanels); panelnr++) {
 1791                                 panelp = brdp->panels[panelnr];
 1792                                 outb(brdp->ioctrl, panelp->pagenr);
 1793                                 if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
 1794                                         break;
 1795                                 if (panelp->nrports > 8) {
 1796                                         outb(brdp->ioctrl, (panelp->pagenr + 1));
 1797                                         if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
 1798                                                 break;
 1799                                 }
 1800                         }       
 1801                         if (panelnr >= brdp->nrpanels) {
 1802                                 i++;
 1803                                 continue;
 1804                         }
 1805                         outb(iobase, SVRR);
 1806                         svrtype = inb(iobase + EREG_DATA);
 1807                         outb(iobase, (SVRR + 0x80));
 1808                         svrtype |= inb(iobase + EREG_DATA);
 1809                 } else if (brdp->brdtype == BRD_ECHMC) {
 1810                         if ((inb(brdp->iostatus) & ECH_INTRPEND) == 0) {
 1811                                 i++;
 1812                                 continue;
 1813                         }
 1814                         for (panelnr = 0; (panelnr < brdp->nrpanels); panelnr++) {
 1815                                 panelp = brdp->panels[panelnr];
 1816                                 iobase = panelp->iobase;
 1817                                 if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
 1818                                         break;
 1819                                 if (panelp->nrports > 8) {
 1820                                         iobase += 0x8;
 1821                                         if (inb(iobase + ECH_PNLSTATUS) & ECH_PNLINTRPEND)
 1822                                                 break;
 1823                                 }
 1824                         }       
 1825                         if (panelnr >= brdp->nrpanels) {
 1826                                 i++;
 1827                                 continue;
 1828                         }
 1829                         outb(iobase, SVRR);
 1830                         svrtype = inb(iobase + EREG_DATA);
 1831                         outb(iobase, (SVRR + 0x80));
 1832                         svrtype |= inb(iobase + EREG_DATA);
 1833                 } else {
 1834                         printf("STALLION: unknown board type=%x\n", brdp->brdtype);
 1835                         i++;
 1836                         continue;
 1837                 }
 1838 
 1839 /*
 1840  *              We have determined what type of service is required for a
 1841  *              port. From here on in the service of a port is the same no
 1842  *              matter what the board type...
 1843  */
 1844                 if (svrtype & SVRR_RX)
 1845                         stl_rxisr(panelp, iobase);
 1846                 if (svrtype & SVRR_TX)
 1847                         stl_txisr(panelp, iobase);
 1848                 if (svrtype & SVRR_MDM)
 1849                         stl_mdmisr(panelp, iobase);
 1850 
 1851                 if (brdp->brdtype == BRD_ECH)
 1852                         outb(brdp->ioctrl, (brdp->ioctrlval | ECH_BRDDISABLE));
 1853         }
 1854 }
 1855 
 1856 /*****************************************************************************/
 1857 
 1858 #if NPCI > 0
 1859 
 1860 static void stlpciintr(void *arg)
 1861 {
 1862         stlintr(0);
 1863 }
 1864 
 1865 #endif
 1866 
 1867 /*****************************************************************************/
 1868 
 1869 /*
 1870  *      If we haven't scheduled a timeout then do it, some port needs high
 1871  *      level processing.
 1872  */
 1873 
 1874 static void stl_dotimeout()
 1875 {
 1876 #if DEBUG
 1877         printf("stl_dotimeout()\n");
 1878 #endif
 1879 
 1880         if (stl_doingtimeout == 0) {
 1881                 timeout(stl_poll, 0, 1);
 1882                 stl_doingtimeout++;
 1883         }
 1884 }
 1885 
 1886 /*****************************************************************************/
 1887 
 1888 /*
 1889  *      Service "software" level processing. Too slow or painfull to be done
 1890  *      at real hardware interrupt time. This way we might also be able to
 1891  *      do some service on other waiting ports as well...
 1892  */
 1893 
 1894 static void stl_poll(void *arg)
 1895 {
 1896         stlbrd_t        *brdp;
 1897         stlport_t       *portp;
 1898         struct tty      *tp;
 1899         int             brdnr, portnr, rearm, x;
 1900 
 1901 #if DEBUG
 1902         printf("stl_poll()\n");
 1903 #endif
 1904 
 1905         stl_doingtimeout = 0;
 1906         rearm = 0;
 1907 
 1908         x = spltty();
 1909         for (brdnr = 0; (brdnr < stl_nrbrds); brdnr++) {
 1910                 if ((brdp = stl_brds[brdnr]) == (stlbrd_t *) NULL)
 1911                         continue;
 1912                 for (portnr = 0; (portnr < brdp->nrports); portnr++) {
 1913                         if ((portp = brdp->ports[portnr]) == (stlport_t *) NULL)
 1914                                 continue;
 1915                         if ((portp->state & ASY_ACTIVE) == 0)
 1916                                 continue;
 1917                         tp = &portp->tty;
 1918 
 1919                         if (portp->state & ASY_RXDATA)
 1920                                 stl_rxprocess(portp);
 1921                         if (portp->state & ASY_DCDCHANGE) {
 1922                                 portp->state &= ~ASY_DCDCHANGE;
 1923                                 portp->sigs = stl_getsignals(portp);
 1924                                 (*linesw[tp->t_line].l_modem)(tp,
 1925                                         (portp->sigs & TIOCM_CD));
 1926                         }
 1927                         if (portp->state & ASY_TXLOW) {
 1928                                 portp->state &= ~ASY_TXLOW;
 1929                                 (*linesw[tp->t_line].l_start)(tp);
 1930                         }
 1931 
 1932                         if (portp->state & ASY_ACTIVE)
 1933                                 rearm++;
 1934                 }
 1935         }
 1936         splx(x);
 1937 
 1938         if (rearm)
 1939                 stl_dotimeout();
 1940 }
 1941 
 1942 /*****************************************************************************/
 1943 
 1944 /*
 1945  *      Process the RX data that has been buffered up in the RX ring queue.
 1946  */
 1947 
 1948 static void stl_rxprocess(stlport_t *portp)
 1949 {
 1950         struct tty      *tp;
 1951         unsigned int    len, stlen, lostlen;
 1952         char            *head, *tail;
 1953         char            status;
 1954         int             ch;
 1955 
 1956 #if DEBUG
 1957         printf("stl_rxprocess(portp=%x): brdnr=%d portnr=%d\n", (int) portp, 
 1958                 portp->brdnr, portp->portnr);
 1959 #endif
 1960 
 1961         tp = &portp->tty;
 1962         portp->state &= ~ASY_RXDATA;
 1963 
 1964         if ((tp->t_state & TS_ISOPEN) == 0) {
 1965                 stl_flush(portp, FREAD);
 1966                 return;
 1967         }
 1968 
 1969 /*
 1970  *      Calculate the amount of data in the RX ring queue. Also calculate
 1971  *      the largest single copy size...
 1972  */
 1973         head = portp->rx.head;
 1974         tail = portp->rx.tail;
 1975         if (head >= tail) {
 1976                 len = head - tail;
 1977                 stlen = len;
 1978         } else {
 1979                 len = STL_RXBUFSIZE - (tail - head);
 1980                 stlen = portp->rx.endbuf - tail;
 1981         }
 1982 
 1983         if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
 1984                 if (len > 0) {
 1985                         if (((tp->t_rawq.c_cc + len) >= TTYHOG) &&
 1986                                         ((portp->state & ASY_RTSFLOWMODE) ||
 1987                                         (tp->t_iflag & IXOFF)) &&
 1988                                         ((tp->t_state & TS_TBLOCK) == 0)) {
 1989                                 ch = TTYHOG - tp->t_rawq.c_cc - 1;
 1990                                 len = (ch > 0) ? ch : 0;
 1991                                 stlen = MIN(stlen, len);
 1992                                 ttyblock(tp);
 1993                         }
 1994                         lostlen = b_to_q(tail, stlen, &tp->t_rawq);
 1995                         tail += stlen;
 1996                         len -= stlen;
 1997                         if (tail >= portp->rx.endbuf) {
 1998                                 tail = portp->rx.buf;
 1999                                 lostlen += b_to_q(tail, len, &tp->t_rawq);
 2000                                 tail += len;
 2001                         }
 2002                         portp->stats.rxlost += lostlen;
 2003                         ttwakeup(tp);
 2004                         portp->rx.tail = tail;
 2005                 }
 2006         } else {
 2007                 while (portp->rx.tail != head) {
 2008                         ch = (unsigned char) *(portp->rx.tail);
 2009                         status = *(portp->rx.tail + STL_RXBUFSIZE);
 2010                         if (status) {
 2011                                 *(portp->rx.tail + STL_RXBUFSIZE) = 0;
 2012                                 if (status & ST_BREAK)
 2013                                         ch |= TTY_BI;
 2014                                 if (status & ST_FRAMING)
 2015                                         ch |= TTY_FE;
 2016                                 if (status & ST_PARITY)
 2017                                         ch |= TTY_PE;
 2018                                 if (status & ST_OVERRUN)
 2019                                         ch |= TTY_OE;
 2020                         }
 2021                         (*linesw[tp->t_line].l_rint)(ch, tp);
 2022                         if (portp->rx.tail == head)
 2023                                 break;
 2024 
 2025                         if (++(portp->rx.tail) >= portp->rx.endbuf)
 2026                                 portp->rx.tail = portp->rx.buf;
 2027                 }
 2028         }
 2029 
 2030         if (head != portp->rx.tail)
 2031                 portp->state |= ASY_RXDATA;
 2032 
 2033 /*
 2034  *      If we where flow controled then maybe the buffer is low enough that
 2035  *      we can re-activate it.
 2036  */
 2037         if ((portp->state & ASY_RTSFLOW) && ((tp->t_state & TS_TBLOCK) == 0))
 2038                 stl_flowcontrol(portp, 1, -1);
 2039 }
 2040 
 2041 /*****************************************************************************/
 2042 
 2043 /*
 2044  *      Set up the cd1400 registers for a port based on the termios port
 2045  *      settings.
 2046  */
 2047 
 2048 static int stl_param(struct tty *tp, struct termios *tiosp)
 2049 {
 2050         stlport_t       *portp;
 2051         unsigned int    clkdiv;
 2052         unsigned char   cor1, cor2, cor3;
 2053         unsigned char   cor4, cor5, ccr;
 2054         unsigned char   srer, sreron, sreroff;
 2055         unsigned char   mcor1, mcor2, rtpr;
 2056         unsigned char   clk, div;
 2057         int             x;
 2058 
 2059         portp = (stlport_t *) tp;
 2060 
 2061 #if DEBUG
 2062         printf("stl_param(tp=%x,tiosp=%x): brdnr=%d portnr=%d\n", (int) tp, 
 2063                 (int) tiosp, portp->brdnr, portp->portnr);
 2064 #endif
 2065 
 2066         cor1 = 0;
 2067         cor2 = 0;
 2068         cor3 = 0;
 2069         cor4 = 0;
 2070         cor5 = 0;
 2071         ccr = 0;
 2072         rtpr = 0;
 2073         clk = 0;
 2074         div = 0;
 2075         mcor1 = 0;
 2076         mcor2 = 0;
 2077         sreron = 0;
 2078         sreroff = 0;
 2079 
 2080 /*
 2081  *      Set up the RX char ignore mask with those RX error types we
 2082  *      can ignore. We could have used some special modes of the cd1400
 2083  *      UART to help, but it is better this way because we can keep stats
 2084  *      on the number of each type of RX exception event.
 2085  */
 2086         portp->rxignoremsk = 0;
 2087         if (tiosp->c_iflag & IGNPAR)
 2088                 portp->rxignoremsk |= (ST_PARITY | ST_FRAMING | ST_OVERRUN);
 2089         if (tiosp->c_iflag & IGNBRK)
 2090                 portp->rxignoremsk |= ST_BREAK;
 2091 
 2092         portp->rxmarkmsk = ST_OVERRUN;
 2093         if (tiosp->c_iflag & (INPCK | PARMRK))
 2094                 portp->rxmarkmsk |= (ST_PARITY | ST_FRAMING);
 2095         if (tiosp->c_iflag & BRKINT)
 2096                 portp->rxmarkmsk |= ST_BREAK;
 2097 
 2098 /*
 2099  *      Go through the char size, parity and stop bits and set all the
 2100  *      option registers appropriately.
 2101  */
 2102         switch (tiosp->c_cflag & CSIZE) {
 2103         case CS5:
 2104                 cor1 |= COR1_CHL5;
 2105                 break;
 2106         case CS6:
 2107                 cor1 |= COR1_CHL6;
 2108                 break;
 2109         case CS7:
 2110                 cor1 |= COR1_CHL7;
 2111                 break;
 2112         default:
 2113                 cor1 |= COR1_CHL8;
 2114                 break;
 2115         }
 2116 
 2117         if (tiosp->c_cflag & CSTOPB)
 2118                 cor1 |= COR1_STOP2;
 2119         else
 2120                 cor1 |= COR1_STOP1;
 2121 
 2122         if (tiosp->c_cflag & PARENB) {
 2123                 if (tiosp->c_cflag & PARODD)
 2124                         cor1 |= (COR1_PARENB | COR1_PARODD);
 2125                 else
 2126                         cor1 |= (COR1_PARENB | COR1_PAREVEN);
 2127         } else {
 2128                 cor1 |= COR1_PARNONE;
 2129         }
 2130 
 2131         if (tiosp->c_iflag & ISTRIP)
 2132                 cor5 |= COR5_ISTRIP;
 2133 
 2134 /*
 2135  *      Set the RX FIFO threshold at 6 chars. This gives a bit of breathing
 2136  *      space for hardware flow control and the like. This should be set to
 2137  *      VMIN. Also here we will set the RX data timeout to 10ms - this should
 2138  *      really be based on VTIME...
 2139  */
 2140         cor3 |= FIFO_RXTHRESHOLD;
 2141         rtpr = 2;
 2142 
 2143 /*
 2144  *      Calculate the baud rate timers. For now we will just assume that
 2145  *      the input and output baud are the same. Could have used a baud
 2146  *      table here, but this way we can generate virtually any baud rate
 2147  *      we like!
 2148  */
 2149         if (tiosp->c_ispeed == 0)
 2150                 tiosp->c_ispeed = tiosp->c_ospeed;
 2151         if ((tiosp->c_ospeed < 0) || (tiosp->c_ospeed > STL_MAXBAUD))
 2152                 return(EINVAL);
 2153 
 2154         if (tiosp->c_ospeed > 0) {
 2155                 for (clk = 0; (clk < CD1400_NUMCLKS); clk++) {
 2156                         clkdiv = ((portp->clk / stl_cd1400clkdivs[clk]) /
 2157                                 tiosp->c_ospeed);
 2158                         if (clkdiv < 0x100)
 2159                                 break;
 2160                 }
 2161                 div = (unsigned char) clkdiv;
 2162         }
 2163 
 2164 /*
 2165  *      Check what form of modem signaling is required and set it up.
 2166  */
 2167         if ((tiosp->c_cflag & CLOCAL) == 0) {
 2168                 mcor1 |= MCOR1_DCD;
 2169                 mcor2 |= MCOR2_DCD;
 2170                 sreron |= SRER_MODEM;
 2171         }
 2172 
 2173 /*
 2174  *      Setup cd1400 enhanced modes if we can. In particular we want to
 2175  *      handle as much of the flow control as possbile automatically. As
 2176  *      well as saving a few CPU cycles it will also greatly improve flow
 2177  *      control reliablilty.
 2178  */
 2179         if (tiosp->c_iflag & IXON) {
 2180                 cor2 |= COR2_TXIBE;
 2181                 cor3 |= COR3_SCD12;
 2182                 if (tiosp->c_iflag & IXANY)
 2183                         cor2 |= COR2_IXM;
 2184         }
 2185 
 2186         if (tiosp->c_cflag & CCTS_OFLOW)
 2187                 cor2 |= COR2_CTSAE;
 2188         if (tiosp->c_cflag & CRTS_IFLOW)
 2189                 mcor1 |= FIFO_RTSTHRESHOLD;
 2190 
 2191 /*
 2192  *      All cd1400 register values calculated so go through and set them
 2193  *      all up.
 2194  */
 2195 #if DEBUG
 2196         printf("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", portp->portnr,
 2197                 portp->panelnr, portp->brdnr);
 2198         printf("    cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n", cor1, cor2,
 2199                 cor3, cor4, cor5);
 2200         printf("    mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n",
 2201                 mcor1, mcor2, rtpr, sreron, sreroff);
 2202         printf("    tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div);
 2203         printf("    schr1=%x schr2=%x schr3=%x schr4=%x\n",
 2204                 tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], tiosp->c_cc[VSTART],
 2205                 tiosp->c_cc[VSTOP]);
 2206 #endif
 2207 
 2208         x = spltty();
 2209         BRDENABLE(portp->brdnr, portp->pagenr);
 2210         stl_setreg(portp, CAR, (portp->portnr & 0x3));
 2211         srer = stl_getreg(portp, SRER);
 2212         stl_setreg(portp, SRER, 0);
 2213         ccr += stl_updatereg(portp, COR1, cor1);
 2214         ccr += stl_updatereg(portp, COR2, cor2);
 2215         ccr += stl_updatereg(portp, COR3, cor3);
 2216         if (ccr) {
 2217                 stl_ccrwait(portp);
 2218                 stl_setreg(portp, CCR, CCR_CORCHANGE);
 2219         }
 2220         stl_setreg(portp, COR4, cor4);
 2221         stl_setreg(portp, COR5, cor5);
 2222         stl_setreg(portp, MCOR1, mcor1);
 2223         stl_setreg(portp, MCOR2, mcor2);
 2224         if (tiosp->c_ospeed == 0) {
 2225                 stl_setreg(portp, MSVR1, 0);
 2226         } else {
 2227                 stl_setreg(portp, MSVR1, MSVR1_DTR);
 2228                 stl_setreg(portp, TCOR, clk);
 2229                 stl_setreg(portp, TBPR, div);
 2230                 stl_setreg(portp, RCOR, clk);
 2231                 stl_setreg(portp, RBPR, div);
 2232         }
 2233         stl_setreg(portp, SCHR1, tiosp->c_cc[VSTART]);
 2234         stl_setreg(portp, SCHR2, tiosp->c_cc[VSTOP]);
 2235         stl_setreg(portp, SCHR3, tiosp->c_cc[VSTART]);
 2236         stl_setreg(portp, SCHR4, tiosp->c_cc[VSTOP]);
 2237         stl_setreg(portp, RTPR, rtpr);
 2238         mcor1 = stl_getreg(portp, MSVR1);
 2239         if (mcor1 & MSVR1_DCD)
 2240                 portp->sigs |= TIOCM_CD;
 2241         else
 2242                 portp->sigs &= ~TIOCM_CD;
 2243         stl_setreg(portp, SRER, ((srer & ~sreroff) | sreron));
 2244         BRDDISABLE(portp->brdnr);
 2245         portp->state &= ~(ASY_RTSFLOWMODE | ASY_CTSFLOWMODE);
 2246         portp->state |= ((tiosp->c_cflag & CRTS_IFLOW) ? ASY_RTSFLOWMODE : 0);
 2247         portp->state |= ((tiosp->c_cflag & CCTS_OFLOW) ? ASY_CTSFLOWMODE : 0);
 2248         stl_ttyoptim(portp, tiosp);
 2249         splx(x);
 2250 
 2251         return(0);
 2252 }
 2253 
 2254 /*****************************************************************************/
 2255 
 2256 /*
 2257  *      Action the flow control as required. The hw and sw args inform the
 2258  *      routine what flow control methods it should try.
 2259  */
 2260 
 2261 static void stl_flowcontrol(stlport_t *portp, int hw, int sw)
 2262 {
 2263         unsigned char   *head, *tail;
 2264         int             len, hwflow, x;
 2265 
 2266 #if DEBUG
 2267         printf("stl_flowcontrol(portp=%x,hw=%d,sw=%d)\n", (int) portp, hw, sw);
 2268 #endif
 2269 
 2270         hwflow = -1;
 2271 
 2272         if (portp->state & ASY_RTSFLOWMODE) {
 2273                 if (hw == 0) {
 2274                         if ((portp->state & ASY_RTSFLOW) == 0)
 2275                                 hwflow = 0;
 2276                 } else if (hw > 0) {
 2277                         if (portp->state & ASY_RTSFLOW) {
 2278                                 head = portp->rx.head;
 2279                                 tail = portp->rx.tail;
 2280                                 len = (head >= tail) ? (head - tail) :
 2281                                         (STL_RXBUFSIZE - (tail - head));
 2282                                 if (len < STL_RXBUFHIGH)
 2283                                         hwflow = 1;
 2284                         }
 2285                 }
 2286         }
 2287 
 2288 /*
 2289  *      We have worked out what to do, if anything. So now apply it to the
 2290  *      UART port.
 2291  */
 2292         if (hwflow >= 0) {
 2293                 x = spltty();
 2294                 BRDENABLE(portp->brdnr, portp->pagenr);
 2295                 stl_setreg(portp, CAR, (portp->portnr & 0x03));
 2296                 if (hwflow == 0) {
 2297                         portp->state |= ASY_RTSFLOW;
 2298                         stl_setreg(portp, MCOR1,
 2299                                 (stl_getreg(portp, MCOR1) & 0xf0));
 2300                         stl_setreg(portp, MSVR2, 0);
 2301                         portp->stats.rxrtsoff++;
 2302                 } else if (hwflow > 0) {
 2303                         portp->state &= ~ASY_RTSFLOW;
 2304                         stl_setreg(portp, MSVR2, MSVR2_RTS);
 2305                         stl_setreg(portp, MCOR1,
 2306                                 (stl_getreg(portp, MCOR1) | FIFO_RTSTHRESHOLD));
 2307                         portp->stats.rxrtson++;
 2308                 }
 2309                 BRDDISABLE(portp->brdnr);
 2310                 splx(x);
 2311         }
 2312 }
 2313 
 2314 
 2315 /*****************************************************************************/
 2316 
 2317 /*
 2318  *      Set the state of the DTR and RTS signals.
 2319  */
 2320 
 2321 static void stl_setsignals(stlport_t *portp, int dtr, int rts)
 2322 {
 2323         unsigned char   msvr1, msvr2;
 2324         int             x;
 2325 
 2326 #if DEBUG
 2327         printf("stl_setsignals(portp=%x,dtr=%d,rts=%d)\n", (int) portp,
 2328                 dtr, rts);
 2329 #endif
 2330 
 2331         msvr1 = 0;
 2332         msvr2 = 0;
 2333         if (dtr > 0)
 2334                 msvr1 = MSVR1_DTR;
 2335         if (rts > 0)
 2336                 msvr2 = MSVR2_RTS;
 2337 
 2338         x = spltty();
 2339         BRDENABLE(portp->brdnr, portp->pagenr);
 2340         stl_setreg(portp, CAR, (portp->portnr & 0x03));
 2341         if (rts >= 0)
 2342                 stl_setreg(portp, MSVR2, msvr2);
 2343         if (dtr >= 0)
 2344                 stl_setreg(portp, MSVR1, msvr1);
 2345         BRDDISABLE(portp->brdnr);
 2346         splx(x);
 2347 }
 2348 
 2349 /*****************************************************************************/
 2350 
 2351 /*
 2352  *      Get the state of the signals.
 2353  */
 2354 
 2355 static int stl_getsignals(stlport_t *portp)
 2356 {
 2357         unsigned char   msvr1, msvr2;
 2358         int             sigs, x;
 2359 
 2360 #if DEBUG
 2361         printf("stl_getsignals(portp=%x)\n", (int) portp);
 2362 #endif
 2363 
 2364         x = spltty();
 2365         BRDENABLE(portp->brdnr, portp->pagenr);
 2366         stl_setreg(portp, CAR, (portp->portnr & 0x3));
 2367         msvr1 = stl_getreg(portp, MSVR1);
 2368         msvr2 = stl_getreg(portp, MSVR2);
 2369         BRDDISABLE(portp->brdnr);
 2370         splx(x);
 2371 
 2372         sigs = 0;
 2373         sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0;
 2374         sigs |= (msvr1 & MSVR1_CTS) ? TIOCM_CTS : 0;
 2375         sigs |= (msvr1 & MSVR1_RI) ? TIOCM_RI : 0;
 2376         sigs |= (msvr1 & MSVR1_DSR) ? TIOCM_DSR : 0;
 2377         sigs |= (msvr1 & MSVR1_DTR) ? TIOCM_DTR : 0;
 2378         sigs |= (msvr2 & MSVR2_RTS) ? TIOCM_RTS : 0;
 2379         return(sigs);
 2380 }
 2381 
 2382 /*****************************************************************************/
 2383 
 2384 /*
 2385  *      Enable or disable the Transmitter and/or Receiver.
 2386  */
 2387 
 2388 static void stl_enablerxtx(stlport_t *portp, int rx, int tx)
 2389 {
 2390         unsigned char   ccr;
 2391         int             x;
 2392 
 2393 #if DEBUG
 2394         printf("stl_enablerxtx(portp=%x,rx=%d,tx=%d)\n", (int) portp, rx, tx);
 2395 #endif
 2396 
 2397         ccr = 0;
 2398         if (tx == 0)
 2399                 ccr |= CCR_TXDISABLE;
 2400         else if (tx > 0)
 2401                 ccr |= CCR_TXENABLE;
 2402         if (rx == 0)
 2403                 ccr |= CCR_RXDISABLE;
 2404         else if (rx > 0)
 2405                 ccr |= CCR_RXENABLE;
 2406 
 2407         x = spltty();
 2408         BRDENABLE(portp->brdnr, portp->pagenr);
 2409         stl_setreg(portp, CAR, (portp->portnr & 0x03));
 2410         stl_ccrwait(portp);
 2411         stl_setreg(portp, CCR, ccr);
 2412         stl_ccrwait(portp);
 2413         BRDDISABLE(portp->brdnr);
 2414         splx(x);
 2415 }
 2416 
 2417 /*****************************************************************************/
 2418 
 2419 /*
 2420  *      Start or stop the Transmitter and/or Receiver.
 2421  */
 2422 
 2423 static void stl_startrxtx(stlport_t *portp, int rx, int tx)
 2424 {
 2425         unsigned char   sreron, sreroff;
 2426         int             x;
 2427 
 2428 #if DEBUG
 2429         printf("stl_startrxtx(portp=%x,rx=%d,tx=%d)\n", (int) portp, rx, tx);
 2430 #endif
 2431 
 2432         sreron = 0;
 2433         sreroff = 0;
 2434         if (tx == 0)
 2435                 sreroff |= (SRER_TXDATA | SRER_TXEMPTY);
 2436         else if (tx == 1)
 2437                 sreron |= SRER_TXDATA;
 2438         else if (tx >= 2)
 2439                 sreron |= SRER_TXEMPTY;
 2440         if (rx == 0)
 2441                 sreroff |= SRER_RXDATA;
 2442         else if (rx > 0)
 2443                 sreron |= SRER_RXDATA;
 2444 
 2445         x = spltty();
 2446         BRDENABLE(portp->brdnr, portp->pagenr);
 2447         stl_setreg(portp, CAR, (portp->portnr & 0x3));
 2448         stl_setreg(portp, SRER,
 2449                 ((stl_getreg(portp, SRER) & ~sreroff) | sreron));
 2450         BRDDISABLE(portp->brdnr);
 2451         if (tx > 0)
 2452                 portp->tty.t_state |= TS_BUSY;
 2453         splx(x);
 2454 }
 2455 
 2456 /*****************************************************************************/
 2457 
 2458 /*
 2459  *      Disable all interrupts from this port.
 2460  */
 2461 
 2462 static void stl_disableintrs(stlport_t *portp)
 2463 {
 2464         int     x;
 2465 
 2466 #if DEBUG
 2467         printf("stl_disableintrs(portp=%x)\n", (int) portp);
 2468 #endif
 2469 
 2470         x = spltty();
 2471         BRDENABLE(portp->brdnr, portp->pagenr);
 2472         stl_setreg(portp, CAR, (portp->portnr & 0x3));
 2473         stl_setreg(portp, SRER, 0);
 2474         BRDDISABLE(portp->brdnr);
 2475         splx(x);
 2476 }
 2477 
 2478 /*****************************************************************************/
 2479 
 2480 static void stl_sendbreak(stlport_t *portp, long len)
 2481 {
 2482         int     x;
 2483 
 2484 #if DEBUG
 2485         printf("stl_sendbreak(portp=%x,len=%d)\n", (int) portp, (int) len);
 2486 #endif
 2487 
 2488         x = spltty();
 2489         BRDENABLE(portp->brdnr, portp->pagenr);
 2490         stl_setreg(portp, CAR, (portp->portnr & 0x3));
 2491         stl_setreg(portp, COR2, (stl_getreg(portp, COR2) | COR2_ETC));
 2492         stl_setreg(portp, SRER,
 2493                 ((stl_getreg(portp, SRER) & ~SRER_TXDATA) | SRER_TXEMPTY));
 2494         BRDDISABLE(portp->brdnr);
 2495         if (len > 0) {
 2496                 len = len / 5;
 2497                 portp->brklen = (len > 255) ? 255 : len;
 2498         } else {
 2499                 portp->brklen = len;
 2500         }
 2501         splx(x);
 2502         portp->stats.txbreaks++;
 2503 }
 2504 
 2505 /*****************************************************************************/
 2506 
 2507 /*
 2508  *      Enable l_rint processing bypass mode if tty modes allow it.
 2509  */
 2510 
 2511 static void stl_ttyoptim(stlport_t *portp, struct termios *tiosp)
 2512 {
 2513         struct tty      *tp;
 2514 
 2515         tp = &portp->tty;
 2516         if (((tiosp->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR)) == 0) &&
 2517             (((tiosp->c_iflag & BRKINT) == 0) || (tiosp->c_iflag & IGNBRK)) &&
 2518             (((tiosp->c_iflag & PARMRK) == 0) ||
 2519                 ((tiosp->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))) &&
 2520             ((tiosp->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN)) ==0) &&
 2521             (linesw[tp->t_line].l_rint == ttyinput))
 2522                 tp->t_state |= TS_CAN_BYPASS_L_RINT;
 2523         else
 2524                 tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
 2525         portp->hotchar = linesw[tp->t_line].l_hotchar;
 2526 }
 2527 
 2528 /*****************************************************************************/
 2529 
 2530 /*
 2531  *      Try and find and initialize all the ports on a panel. We don't care
 2532  *      what sort of board these ports are on - since the port io registers
 2533  *      are almost identical when dealing with ports.
 2534  */
 2535 
 2536 static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
 2537 {
 2538         stlport_t       *portp;
 2539         unsigned int    chipmask;
 2540         unsigned int    gfrcr;
 2541         int             nrchips, uartaddr, ioaddr;
 2542         int             i, j;
 2543 
 2544 #if DEBUG
 2545         printf("stl_initports(panelp=%x)\n", (int) panelp);
 2546 #endif
 2547 
 2548         BRDENABLE(panelp->brdnr, panelp->pagenr);
 2549 
 2550 /*
 2551  *      Check that each chip is present and started up OK.
 2552  */
 2553         chipmask = 0;
 2554         nrchips = panelp->nrports / CD1400_PORTS;
 2555         for (i = 0; (i < nrchips); i++) {
 2556                 if (brdp->brdtype == BRD_ECHPCI) {
 2557                         outb(brdp->ioctrl, (panelp->pagenr + (i >> 1)));
 2558                         ioaddr = panelp->iobase;
 2559                 } else {
 2560                         ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1));
 2561                 }
 2562                 uartaddr = (i & 0x01) ? 0x080 : 0;
 2563                 outb(ioaddr, (GFRCR + uartaddr));
 2564                 outb((ioaddr + EREG_DATA), 0);
 2565                 outb(ioaddr, (CCR + uartaddr));
 2566                 outb((ioaddr + EREG_DATA), CCR_RESETFULL);
 2567                 outb((ioaddr + EREG_DATA), CCR_RESETFULL);
 2568                 outb(ioaddr, (GFRCR + uartaddr));
 2569                 for (j = 0; (j < CCR_MAXWAIT); j++) {
 2570                         gfrcr = inb(ioaddr + EREG_DATA);
 2571                         if ((gfrcr > 0x40) && (gfrcr < 0x60))
 2572                                 break;
 2573                 }
 2574                 if (j >= CCR_MAXWAIT) {
 2575                         printf("STALLION: cd1400 not responding, brd=%d "
 2576                                 "panel=%d chip=%d\n", panelp->brdnr,
 2577                                 panelp->panelnr, i);
 2578                         continue;
 2579                 }
 2580                 chipmask |= (0x1 << i);
 2581                 outb(ioaddr, (PPR + uartaddr));
 2582                 outb((ioaddr + EREG_DATA), PPR_SCALAR);
 2583         }
 2584 
 2585 /*
 2586  *      All cd1400's are initialized (if found!). Now go through and setup
 2587  *      each ports data structures. Also init the LIVR register of cd1400
 2588  *      for each port.
 2589  */
 2590         ioaddr = panelp->iobase;
 2591         for (i = 0; (i < panelp->nrports); i++) {
 2592                 if (brdp->brdtype == BRD_ECHPCI) {
 2593                         outb(brdp->ioctrl, (panelp->pagenr + (i >> 3)));
 2594                         ioaddr = panelp->iobase;
 2595                 } else {
 2596                         ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 3));
 2597                 }
 2598                 if ((chipmask & (0x1 << (i / 4))) == 0)
 2599                         continue;
 2600                 portp = (stlport_t *) malloc(sizeof(stlport_t), M_TTYS,
 2601                         M_NOWAIT | M_ZERO);
 2602                 if (portp == (stlport_t *) NULL) {
 2603                         printf("STALLION: failed to allocate port memory "
 2604                                 "(size=%d)\n", sizeof(stlport_t));
 2605                         break;
 2606                 }
 2607 
 2608                 portp->portnr = i;
 2609                 portp->brdnr = panelp->brdnr;
 2610                 portp->panelnr = panelp->panelnr;
 2611                 portp->clk = brdp->clk;
 2612                 portp->ioaddr = ioaddr;
 2613                 portp->uartaddr = (i & 0x4) << 5;
 2614                 portp->pagenr = panelp->pagenr + (i >> 3);
 2615                 portp->hwid = stl_getreg(portp, GFRCR);
 2616                 stl_setreg(portp, CAR, (i & 0x3));
 2617                 stl_setreg(portp, LIVR, (i << 3));
 2618                 panelp->ports[i] = portp;
 2619 
 2620                 j = STL_TXBUFSIZE + (2 * STL_RXBUFSIZE);
 2621                 portp->tx.buf = (char *) malloc(j, M_TTYS, M_NOWAIT);
 2622                 if (portp->tx.buf == (char *) NULL) {
 2623                         printf("STALLION: failed to allocate buffer memory "
 2624                                 "(size=%d)\n", j);
 2625                         break;
 2626                 }
 2627                 portp->tx.endbuf = portp->tx.buf + STL_TXBUFSIZE;
 2628                 portp->tx.head = portp->tx.buf;
 2629                 portp->tx.tail = portp->tx.buf;
 2630                 portp->rx.buf = portp->tx.buf + STL_TXBUFSIZE;
 2631                 portp->rx.endbuf = portp->rx.buf + STL_RXBUFSIZE;
 2632                 portp->rx.head = portp->rx.buf;
 2633                 portp->rx.tail = portp->rx.buf;
 2634                 portp->rxstatus.buf = portp->rx.buf + STL_RXBUFSIZE;
 2635                 portp->rxstatus.endbuf = portp->rxstatus.buf + STL_RXBUFSIZE;
 2636                 portp->rxstatus.head = portp->rxstatus.buf;
 2637                 portp->rxstatus.tail = portp->rxstatus.buf;
 2638                 bzero(portp->rxstatus.head, STL_RXBUFSIZE);
 2639 
 2640                 portp->initintios.c_ispeed = STL_DEFSPEED;
 2641                 portp->initintios.c_ospeed = STL_DEFSPEED;
 2642                 portp->initintios.c_cflag = STL_DEFCFLAG;
 2643                 portp->initintios.c_iflag = 0;
 2644                 portp->initintios.c_oflag = 0;
 2645                 portp->initintios.c_lflag = 0;
 2646                 bcopy(&ttydefchars[0], &portp->initintios.c_cc[0],
 2647                         sizeof(portp->initintios.c_cc));
 2648                 portp->initouttios = portp->initintios;
 2649                 portp->dtrwait = 3 * hz;
 2650         }
 2651 
 2652         BRDDISABLE(panelp->brdnr);
 2653         return(0);
 2654 }
 2655 
 2656 /*****************************************************************************/
 2657 
 2658 /*
 2659  *      Try to find and initialize an EasyIO board.
 2660  */
 2661 
 2662 static int stl_initeio(stlbrd_t *brdp)
 2663 {
 2664         stlpanel_t      *panelp;
 2665         unsigned int    status;
 2666 
 2667 #if DEBUG
 2668         printf("stl_initeio(brdp=%x)\n", (int) brdp);
 2669 #endif
 2670 
 2671         brdp->ioctrl = brdp->ioaddr1 + 1;
 2672         brdp->iostatus = brdp->ioaddr1 + 2;
 2673         brdp->clk = EIO_CLK;
 2674 
 2675         status = inb(brdp->iostatus);
 2676         switch (status & EIO_IDBITMASK) {
 2677         case EIO_8PORTM:
 2678                 brdp->clk = EIO_CLK8M;
 2679                 /* FALLTHROUGH */
 2680         case EIO_8PORTRS:
 2681         case EIO_8PORTDI:
 2682                 brdp->nrports = 8;
 2683                 break;
 2684         case EIO_4PORTRS:
 2685                 brdp->nrports = 4;
 2686                 break;
 2687         default:
 2688                 return(ENODEV);
 2689         }
 2690 
 2691 /*
 2692  *      Check that the supplied IRQ is good and then use it to setup the
 2693  *      programmable interrupt bits on EIO board. Also set the edge/level
 2694  *      triggered interrupt bit.
 2695  */
 2696         if ((brdp->irq < 0) || (brdp->irq > 15) ||
 2697                         (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
 2698                 printf("STALLION: invalid irq=%d for brd=%d\n", brdp->irq,
 2699                         brdp->brdnr);
 2700                 return(EINVAL);
 2701         }
 2702         outb(brdp->ioctrl, (stl_vecmap[brdp->irq] |
 2703                 ((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)));
 2704 
 2705         panelp = (stlpanel_t *) malloc(sizeof(stlpanel_t), M_TTYS,
 2706                 M_NOWAIT | M_ZERO);
 2707         if (panelp == (stlpanel_t *) NULL) {
 2708                 printf("STALLION: failed to allocate memory (size=%d)\n",
 2709                         sizeof(stlpanel_t));
 2710                 return(ENOMEM);
 2711         }
 2712 
 2713         panelp->brdnr = brdp->brdnr;
 2714         panelp->panelnr = 0;
 2715         panelp->nrports = brdp->nrports;
 2716         panelp->iobase = brdp->ioaddr1;
 2717         panelp->hwid = status;
 2718         brdp->panels[0] = panelp;
 2719         brdp->nrpanels = 1;
 2720         brdp->hwid = status;
 2721         brdp->state |= BRD_FOUND;
 2722         return(0);
 2723 }
 2724 
 2725 /*****************************************************************************/
 2726 
 2727 /*
 2728  *      Try to find an ECH board and initialize it. This code is capable of
 2729  *      dealing with all types of ECH board.
 2730  */
 2731 
 2732 static int stl_initech(stlbrd_t *brdp)
 2733 {
 2734         stlpanel_t      *panelp;
 2735         unsigned int    status, nxtid;
 2736         int             panelnr, ioaddr, i;
 2737 
 2738 #if DEBUG
 2739         printf("stl_initech(brdp=%x)\n", (int) brdp);
 2740 #endif
 2741 
 2742 /*
 2743  *      Set up the initial board register contents for boards. This varys a
 2744  *      bit between the different board types. So we need to handle each
 2745  *      separately. Also do a check that the supplied IRQ is good.
 2746  */
 2747         if (brdp->brdtype == BRD_ECH) {
 2748                 brdp->ioctrl = brdp->ioaddr1 + 1;
 2749                 brdp->iostatus = brdp->ioaddr1 + 1;
 2750                 status = inb(brdp->iostatus);
 2751                 if ((status & ECH_IDBITMASK) != ECH_ID)
 2752                         return(ENODEV);
 2753                 brdp->hwid = status;
 2754 
 2755                 if ((brdp->irq < 0) || (brdp->irq > 15) ||
 2756                                 (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
 2757                         printf("STALLION: invalid irq=%d for brd=%d\n",
 2758                                 brdp->irq, brdp->brdnr);
 2759                         return(EINVAL);
 2760                 }
 2761                 status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1);
 2762                 status |= (stl_vecmap[brdp->irq] << 1);
 2763                 outb(brdp->ioaddr1, (status | ECH_BRDRESET));
 2764                 brdp->ioctrlval = ECH_INTENABLE |
 2765                         ((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE);
 2766                 outb(brdp->ioctrl, (brdp->ioctrlval | ECH_BRDENABLE));
 2767                 outb(brdp->ioaddr1, status);
 2768         } else if (brdp->brdtype == BRD_ECHMC) {
 2769                 brdp->ioctrl = brdp->ioaddr1 + 0x20;
 2770                 brdp->iostatus = brdp->ioctrl;
 2771                 status = inb(brdp->iostatus);
 2772                 if ((status & ECH_IDBITMASK) != ECH_ID)
 2773                         return(ENODEV);
 2774                 brdp->hwid = status;
 2775 
 2776                 if ((brdp->irq < 0) || (brdp->irq > 15) ||
 2777                                 (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
 2778                         printf("STALLION: invalid irq=%d for brd=%d\n",
 2779                                 brdp->irq, brdp->brdnr);
 2780                         return(EINVAL);
 2781                 }
 2782                 outb(brdp->ioctrl, ECHMC_BRDRESET);
 2783                 outb(brdp->ioctrl, ECHMC_INTENABLE);
 2784         } else if (brdp->brdtype == BRD_ECHPCI) {
 2785                 brdp->ioctrl = brdp->ioaddr1 + 2;
 2786         }
 2787 
 2788         brdp->clk = ECH_CLK;
 2789 
 2790 /*
 2791  *      Scan through the secondary io address space looking for panels.
 2792  *      As we find'em allocate and initialize panel structures for each.
 2793  */
 2794         ioaddr = brdp->ioaddr2;
 2795         panelnr = 0;
 2796         nxtid = 0;
 2797 
 2798         for (i = 0; (i < STL_MAXPANELS); i++) {
 2799                 if (brdp->brdtype == BRD_ECHPCI) {
 2800                         outb(brdp->ioctrl, nxtid);
 2801                         ioaddr = brdp->ioaddr2;
 2802                 }
 2803                 status = inb(ioaddr + ECH_PNLSTATUS);
 2804                 if ((status & ECH_PNLIDMASK) != nxtid)
 2805                         break;
 2806                 panelp = (stlpanel_t *) malloc(sizeof(stlpanel_t), M_TTYS,
 2807                         M_NOWAIT | M_ZERO);
 2808                 if (panelp == (stlpanel_t *) NULL) {
 2809                         printf("STALLION: failed to allocate memory"
 2810                                 "(size=%d)\n", sizeof(stlpanel_t));
 2811                         break;
 2812                 }
 2813                 panelp->brdnr = brdp->brdnr;
 2814                 panelp->panelnr = panelnr;
 2815                 panelp->iobase = ioaddr;
 2816                 panelp->pagenr = nxtid;
 2817                 panelp->hwid = status;
 2818                 if (status & ECH_PNL16PORT) {
 2819                         if ((brdp->nrports + 16) > 32)
 2820                                 break;
 2821                         panelp->nrports = 16;
 2822                         panelp->ackmask = 0x80;
 2823                         brdp->nrports += 16;
 2824                         ioaddr += (EREG_BANKSIZE * 2);
 2825                         nxtid += 2;
 2826                 } else {
 2827                         panelp->nrports = 8;
 2828                         panelp->ackmask = 0xc0;
 2829                         brdp->nrports += 8;
 2830                         ioaddr += EREG_BANKSIZE;
 2831                         nxtid++;
 2832                 }
 2833                 brdp->panels[panelnr++] = panelp;
 2834                 brdp->nrpanels++;
 2835                 if (ioaddr >= (brdp->ioaddr2 + 0x20))
 2836                         break;
 2837         }
 2838 
 2839         if (brdp->brdtype == BRD_ECH)
 2840                 outb(brdp->ioctrl, (brdp->ioctrlval | ECH_BRDDISABLE));
 2841 
 2842         brdp->state |= BRD_FOUND;
 2843         return(0);
 2844 }
 2845 
 2846 /*****************************************************************************/
 2847 
 2848 /*
 2849  *      Initialize and configure the specified board. This firstly probes
 2850  *      for the board, if it is found then the board is initialized and
 2851  *      then all its ports are initialized as well.
 2852  */
 2853 
 2854 static int stl_brdinit(stlbrd_t *brdp)
 2855 {
 2856         stlpanel_t      *panelp;
 2857         int             i, j, k;
 2858 
 2859 #if DEBUG
 2860         printf("stl_brdinit(brdp=%x): unit=%d type=%d io1=%x io2=%x irq=%d\n",
 2861                 (int) brdp, brdp->brdnr, brdp->brdtype, brdp->ioaddr1,
 2862                 brdp->ioaddr2, brdp->irq);
 2863 #endif
 2864 
 2865         switch (brdp->brdtype) {
 2866         case BRD_EASYIO:
 2867                 stl_initeio(brdp);
 2868                 break;
 2869         case BRD_ECH:
 2870         case BRD_ECHMC:
 2871         case BRD_ECHPCI:
 2872                 stl_initech(brdp);
 2873                 break;
 2874         default:
 2875                 printf("STALLION: unit=%d is unknown board type=%d\n",
 2876                         brdp->brdnr, brdp->brdtype);
 2877                 return(ENODEV);
 2878         }
 2879 
 2880         stl_brds[brdp->brdnr] = brdp;
 2881         if ((brdp->state & BRD_FOUND) == 0) {
 2882 #if 0
 2883                 printf("STALLION: %s board not found, unit=%d io=%x irq=%d\n",
 2884                         stl_brdnames[brdp->brdtype], brdp->brdnr,
 2885                         brdp->ioaddr1, brdp->irq);
 2886 #endif
 2887                 return(ENODEV);
 2888         }
 2889 
 2890         for (i = 0, k = 0; (i < STL_MAXPANELS); i++) {
 2891                 panelp = brdp->panels[i];
 2892                 if (panelp != (stlpanel_t *) NULL) {
 2893                         stl_initports(brdp, panelp);
 2894                         for (j = 0; (j < panelp->nrports); j++)
 2895                                 brdp->ports[k++] = panelp->ports[j];
 2896                 }
 2897         }
 2898 
 2899         printf("stl%d: %s (driver version %s) unit=%d nrpanels=%d nrports=%d\n",
 2900                 brdp->unitid, stl_brdnames[brdp->brdtype], stl_drvversion,
 2901                 brdp->brdnr, brdp->nrpanels, brdp->nrports);
 2902         return(0);
 2903 }
 2904 
 2905 /*****************************************************************************/
 2906 
 2907 /*
 2908  *      Return the board stats structure to user app.
 2909  */
 2910 
 2911 static int stl_getbrdstats(caddr_t data)
 2912 {
 2913         stlbrd_t        *brdp;
 2914         stlpanel_t      *panelp;
 2915         int             i;
 2916 
 2917         stl_brdstats = *((combrd_t *) data);
 2918         if (stl_brdstats.brd >= STL_MAXBRDS)
 2919                 return(-ENODEV);
 2920         brdp = stl_brds[stl_brdstats.brd];
 2921         if (brdp == (stlbrd_t *) NULL)
 2922                 return(-ENODEV);
 2923 
 2924         bzero(&stl_brdstats, sizeof(combrd_t));
 2925         stl_brdstats.brd = brdp->brdnr;
 2926         stl_brdstats.type = brdp->brdtype;
 2927         stl_brdstats.hwid = brdp->hwid;
 2928         stl_brdstats.state = brdp->state;
 2929         stl_brdstats.ioaddr = brdp->ioaddr1;
 2930         stl_brdstats.ioaddr2 = brdp->ioaddr2;
 2931         stl_brdstats.irq = brdp->irq;
 2932         stl_brdstats.nrpanels = brdp->nrpanels;
 2933         stl_brdstats.nrports = brdp->nrports;
 2934         for (i = 0; (i < brdp->nrpanels); i++) {
 2935                 panelp = brdp->panels[i];
 2936                 stl_brdstats.panels[i].panel = i;
 2937                 stl_brdstats.panels[i].hwid = panelp->hwid;
 2938                 stl_brdstats.panels[i].nrports = panelp->nrports;
 2939         }
 2940 
 2941         *((combrd_t *) data) = stl_brdstats;;
 2942         return(0);
 2943 }
 2944 
 2945 /*****************************************************************************/
 2946 
 2947 /*
 2948  *      Resolve the referenced port number into a port struct pointer.
 2949  */
 2950 
 2951 static stlport_t *stl_getport(int brdnr, int panelnr, int portnr)
 2952 {
 2953         stlbrd_t        *brdp;
 2954         stlpanel_t      *panelp;
 2955 
 2956         if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
 2957                 return((stlport_t *) NULL);
 2958         brdp = stl_brds[brdnr];
 2959         if (brdp == (stlbrd_t *) NULL)
 2960                 return((stlport_t *) NULL);
 2961         if ((panelnr < 0) || (panelnr >= brdp->nrpanels))
 2962                 return((stlport_t *) NULL);
 2963         panelp = brdp->panels[panelnr];
 2964         if (panelp == (stlpanel_t *) NULL)
 2965                 return((stlport_t *) NULL);
 2966         if ((portnr < 0) || (portnr >= panelp->nrports))
 2967                 return((stlport_t *) NULL);
 2968         return(panelp->ports[portnr]);
 2969 }
 2970 
 2971 /*****************************************************************************/
 2972 
 2973 /*
 2974  *      Return the port stats structure to user app. A NULL port struct
 2975  *      pointer passed in means that we need to find out from the app
 2976  *      what port to get stats for (used through board control device).
 2977  */
 2978 
 2979 static int stl_getportstats(stlport_t *portp, caddr_t data)
 2980 {
 2981         unsigned char   *head, *tail;
 2982 
 2983         if (portp == (stlport_t *) NULL) {
 2984                 stl_comstats = *((comstats_t *) data);
 2985                 portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
 2986                         stl_comstats.port);
 2987                 if (portp == (stlport_t *) NULL)
 2988                         return(-ENODEV);
 2989         }
 2990 
 2991         portp->stats.state = portp->state;
 2992         /*portp->stats.flags = portp->flags;*/
 2993         portp->stats.hwid = portp->hwid;
 2994         portp->stats.ttystate = portp->tty.t_state;
 2995         portp->stats.cflags = portp->tty.t_cflag;
 2996         portp->stats.iflags = portp->tty.t_iflag;
 2997         portp->stats.oflags = portp->tty.t_oflag;
 2998         portp->stats.lflags = portp->tty.t_lflag;
 2999 
 3000         head = portp->tx.head;
 3001         tail = portp->tx.tail;
 3002         portp->stats.txbuffered = ((head >= tail) ? (head - tail) :
 3003                 (STL_TXBUFSIZE - (tail - head)));
 3004 
 3005         head = portp->rx.head;
 3006         tail = portp->rx.tail;
 3007         portp->stats.rxbuffered = (head >= tail) ? (head - tail) :
 3008                 (STL_RXBUFSIZE - (tail - head));
 3009 
 3010         portp->stats.signals = (unsigned long) stl_getsignals(portp);
 3011 
 3012         *((comstats_t *) data) = portp->stats;
 3013         return(0);
 3014 }
 3015 
 3016 /*****************************************************************************/
 3017 
 3018 /*
 3019  *      Clear the port stats structure. We also return it zeroed out...
 3020  */
 3021 
 3022 static int stl_clrportstats(stlport_t *portp, caddr_t data)
 3023 {
 3024         if (portp == (stlport_t *) NULL) {
 3025                 stl_comstats = *((comstats_t *) data);
 3026                 portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
 3027                         stl_comstats.port);
 3028                 if (portp == (stlport_t *) NULL)
 3029                         return(-ENODEV);
 3030         }
 3031 
 3032         bzero(&portp->stats, sizeof(comstats_t));
 3033         portp->stats.brd = portp->brdnr;
 3034         portp->stats.panel = portp->panelnr;
 3035         portp->stats.port = portp->portnr;
 3036         *((comstats_t *) data) = stl_comstats;
 3037         return(0);
 3038 }
 3039 
 3040 /*****************************************************************************/
 3041 
 3042 /*
 3043  *      The "staliomem" device is used for stats collection in this driver.
 3044  */
 3045 
 3046 static int stl_memioctl(dev_t dev, unsigned long cmd, caddr_t data, int flag,
 3047                         struct thread *td)
 3048 {
 3049         stlbrd_t        *brdp;
 3050         int             brdnr, rc;
 3051 
 3052 #if DEBUG
 3053         printf("stl_memioctl(dev=%s,cmd=%lx,data=%p,flag=%x)\n",
 3054                 devtoname(dev), cmd, (void *) data, flag);
 3055 #endif
 3056 
 3057         brdnr = minor(dev) & 0x7;
 3058         brdp = stl_brds[brdnr];
 3059         if (brdp == (stlbrd_t *) NULL)
 3060                 return(ENODEV);
 3061         if (brdp->state == 0)
 3062                 return(ENODEV);
 3063 
 3064         rc = 0;
 3065 
 3066         switch (cmd) {
 3067         case COM_GETPORTSTATS:
 3068                 rc = stl_getportstats((stlport_t *) NULL, data);
 3069                 break;
 3070         case COM_CLRPORTSTATS:
 3071                 rc = stl_clrportstats((stlport_t *) NULL, data);
 3072                 break;
 3073         case COM_GETBRDSTATS:
 3074                 rc = stl_getbrdstats(data);
 3075                 break;
 3076         default:
 3077                 rc = ENOTTY;
 3078                 break;
 3079         }
 3080 
 3081         return(rc);
 3082 }
 3083 
 3084 /*****************************************************************************/

Cache object: 4a7c33acfa4eee994f54c6652aadffa3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.