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

Cache object: ec6ae8c1e5207c28495529d81e0db5df


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