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

Cache object: f964112834e97f0e06d80a58f48fdbd2


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