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

Cache object: b7249beed7d814920690314ad229eb02


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