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/dev/cx/csigma.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  * Low-level subroutines for Cronyx-Sigma adapter.
    3  *
    4  * Copyright (C) 1994-2000 Cronyx Engineering.
    5  * Author: Serge Vakulenko, <vak@cronyx.ru>
    6  *
    7  * This software is distributed with NO WARRANTIES, not even the implied
    8  * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    9  *
   10  * Authors grant any other persons or organisations permission to use
   11  * or modify this software as long as this message is kept with the software,
   12  * all derivative works or modified versions.
   13  *
   14  * Cronyx Id: csigma.c,v 1.1.2.1 2003/11/12 17:13:41 rik Exp $
   15  * $FreeBSD: releng/9.0/sys/dev/cx/csigma.c 139749 2005-01-06 01:43:34Z imp $
   16  */
   17 #include <dev/cx/machdep.h>
   18 #include <dev/cx/cxddk.h>
   19 #include <dev/cx/cxreg.h>
   20 #include <dev/cx/cronyxfw.h>
   21 
   22 #define DMA_MASK        0xd4    /* DMA mask register */
   23 #define DMA_MASK_CLEAR  0x04    /* DMA clear mask */
   24 #define DMA_MODE        0xd6    /* DMA mode register */
   25 #define DMA_MODE_MASTER 0xc0    /* DMA master mode */
   26 
   27 #define BYTE *(unsigned char*)&
   28 
   29 static unsigned char irqmask [] = {
   30         BCR0_IRQ_DIS,   BCR0_IRQ_DIS,   BCR0_IRQ_DIS,   BCR0_IRQ_3,
   31         BCR0_IRQ_DIS,   BCR0_IRQ_5,     BCR0_IRQ_DIS,   BCR0_IRQ_7,
   32         BCR0_IRQ_DIS,   BCR0_IRQ_DIS,   BCR0_IRQ_10,    BCR0_IRQ_11,
   33         BCR0_IRQ_12,    BCR0_IRQ_DIS,   BCR0_IRQ_DIS,   BCR0_IRQ_15,
   34 };
   35 
   36 static unsigned char dmamask [] = {
   37         BCR0_DMA_DIS,   BCR0_DMA_DIS,   BCR0_DMA_DIS,   BCR0_DMA_DIS,
   38         BCR0_DMA_DIS,   BCR0_DMA_5,     BCR0_DMA_6,     BCR0_DMA_7,
   39 };
   40 
   41 /* standard base port set */
   42 static short porttab [] = {
   43         0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0,
   44         0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0
   45 };
   46 
   47 /* valid IRQs and DRQs */
   48 static short irqtab [] = { 3, 5, 7, 10, 11, 12, 15, 0 };
   49 static short dmatab [] = { 5, 6, 7, 0 };
   50 
   51 static int valid (short value, short *list)
   52 {
   53         while (*list)
   54                 if (value == *list++)
   55                         return 1;
   56         return 0;
   57 }
   58 
   59 long cx_rxbaud = 9600;          /* receiver baud rate */
   60 long cx_txbaud = 9600;          /* transmitter baud rate */
   61 
   62 int cx_univ_mode = M_HDLC;      /* univ. chan. mode: async or sync */
   63 int cx_sync_mode = M_HDLC;      /* sync. chan. mode: HDLC, Bisync or X.21 */
   64 int cx_iftype = 0;              /* univ. chan. interface: upper/lower */
   65 
   66 static int cx_probe_chip (port_t base);
   67 static void cx_setup_chip (cx_chan_t *c);
   68 
   69 /*
   70  * Wait for CCR to clear.
   71  */
   72 void cx_cmd (port_t base, int cmd)
   73 {
   74         port_t port = CCR(base);
   75         int count;
   76 
   77         /* Wait 10 msec for the previous command to complete. */
   78         for (count=0; inb(port) && count<20000; ++count)
   79                 continue;
   80 
   81         /* Issue the command. */
   82         outb (port, cmd);
   83 
   84         /* Wait 10 msec for the command to complete. */
   85         for (count=0; inb(port) && count<20000; ++count)
   86                 continue;
   87 }
   88 
   89 /*
   90  * Reset the chip.
   91  */
   92 static int cx_reset (port_t port)
   93 {
   94         int count;
   95 
   96         /* Wait up to 10 msec for revision code to appear after reset. */
   97         for (count=0; count<20000; ++count)
   98                 if (inb(GFRCR(port)) != 0)
   99                         break;
  100 
  101         cx_cmd (port, CCR_RSTALL);
  102 
  103         /* Firmware revision code should clear imediately. */
  104         /* Wait up to 10 msec for revision code to appear again. */
  105         for (count=0; count<20000; ++count)
  106                 if (inb(GFRCR(port)) != 0)
  107                         return (1);
  108 
  109         /* Reset failed. */
  110         return (0);
  111 }
  112 
  113 int cx_download (port_t port, const unsigned char *firmware, long bits,
  114         const cr_dat_tst_t *tst)
  115 {
  116         unsigned char cr2, sr;
  117         long i, n, maxn = (bits + 7) / 8;
  118         int v, b;
  119 
  120         inb (BDET(port));
  121         for (i=n=0; n<maxn; ++n) {
  122                 v = ((firmware[n] ^ ' ') << 1) | (firmware[n] >> 7 & 1);
  123                 for (b=0; b<7; b+=2, i+=2) {
  124                         if (i >= bits)
  125                                 break;
  126                         cr2 = 0;
  127                         if (v >> b & 1) cr2 |= BCR2_TMS;
  128                         if (v >> b & 2) cr2 |= BCR2_TDI;
  129                         outb (BCR2(port), cr2);
  130                         sr = inb (BSR(port));
  131                         outb (BCR0(port), BCR0800_TCK);
  132                         outb (BCR0(port), 0);
  133                         if (i >= tst->end)
  134                                 ++tst;
  135                         if (i >= tst->start && (sr & BSR800_LERR))
  136                                 return (0);
  137                 }
  138         }
  139         return (1);
  140 }
  141 
  142 /*
  143  * Check if the Sigma-XXX board is present at the given base port.
  144  */
  145 static int cx_probe_chained_board (port_t port, int *c0, int *c1)
  146 {
  147         int rev, i;
  148 
  149         /* Read and check the board revision code. */
  150         rev = inb (BSR(port));
  151         *c0 = *c1 = 0;
  152         switch (rev & BSR_VAR_MASK) {
  153         case CRONYX_100:        *c0 = 1;        break;
  154         case CRONYX_400:        *c1 = 1;        break;
  155         case CRONYX_500:        *c0 = *c1 = 1;  break;
  156         case CRONYX_410:        *c0 = 1;        break;
  157         case CRONYX_810:        *c0 = *c1 = 1;  break;
  158         case CRONYX_410s:       *c0 = 1;        break;
  159         case CRONYX_810s:       *c0 = *c1 = 1;  break;
  160         case CRONYX_440:        *c0 = 1;        break;
  161         case CRONYX_840:        *c0 = *c1 = 1;  break;
  162         case CRONYX_401:        *c0 = 1;        break;
  163         case CRONYX_801:        *c0 = *c1 = 1;  break;
  164         case CRONYX_401s:       *c0 = 1;        break;
  165         case CRONYX_801s:       *c0 = *c1 = 1;  break;
  166         case CRONYX_404:        *c0 = 1;        break;
  167         case CRONYX_703:        *c0 = *c1 = 1;  break;
  168         default:                return (0);     /* invalid variant code */
  169         }
  170 
  171         switch (rev & BSR_OSC_MASK) {
  172         case BSR_OSC_20:        /* 20 MHz */
  173         case BSR_OSC_18432:     /* 18.432 MHz */
  174                 break;
  175         default:
  176                 return (0);     /* oscillator frequency does not match */
  177         }
  178 
  179         for (i=2; i<0x10; i+=2)
  180                 if ((inb (BSR(port)+i) & BSR_REV_MASK) != (rev & BSR_REV_MASK))
  181                         return (0);     /* status changed? */
  182         return (1);
  183 }
  184 
  185 /*
  186  * Check if the Sigma-800 board is present at the given base port.
  187  * Read board status register 1 and check identification bits
  188  * which should invert every next read.
  189  */
  190 static int cx_probe_800_chained_board (port_t port)
  191 {
  192         unsigned char det, odet;
  193         int i;
  194 
  195         odet = inb (BDET(port));
  196         if ((odet & (BDET_IB | BDET_IB_NEG)) != BDET_IB &&
  197             (odet & (BDET_IB | BDET_IB_NEG)) != BDET_IB_NEG)
  198                 return (0);
  199         for (i=0; i<100; ++i) {
  200                 det = inb (BDET(port));
  201                 if (((det ^ odet) & (BDET_IB | BDET_IB_NEG)) !=
  202                     (BDET_IB | BDET_IB_NEG))
  203                         return (0);
  204                 odet = det;
  205         }
  206         /* Reset the controller. */
  207         outb (BCR0(port), 0);
  208         outb (BCR1(port), 0);
  209         outb (BCR2(port), 0);
  210         return (1);
  211 }
  212 
  213 /*
  214  * Check if the Sigma-2x board is present at the given base port.
  215  */
  216 static int cx_probe_2x_board (port_t port)
  217 {
  218         int rev, i;
  219 
  220         /* Read and check the board revision code. */
  221         rev = inb (BSR(port));
  222         if ((rev & BSR2X_VAR_MASK) != CRONYX_22 &&
  223             (rev & BSR2X_VAR_MASK) != CRONYX_24)
  224                 return (0);             /* invalid variant code */
  225 
  226         for (i=2; i<0x10; i+=2)
  227                 if ((inb (BSR(port)+i) & BSR2X_REV_MASK) !=
  228                     (rev & BSR2X_REV_MASK))
  229                         return (0);     /* status changed? */
  230         return (1);
  231 }
  232 
  233 /*
  234  * Check if the Cronyx-Sigma board is present at the given base port.
  235  */
  236 int cx_probe_board (port_t port, int irq, int dma)
  237 {
  238         int c0, c1, c2=0, c3=0, result;
  239 
  240         if (! valid (port, porttab))
  241                 return 0;
  242 
  243         if (irq > 0 && ! valid (irq, irqtab))
  244                 return 0;
  245 
  246         if (dma > 0 && ! valid (dma, dmatab))
  247                 return 0;
  248 
  249         if (cx_probe_800_chained_board (port)) {
  250                 /* Sigma-800 detected. */
  251                 if (! (inb (BSR(port)) & BSR_NOCHAIN)) {
  252                         /* chained board attached */
  253                         if (! cx_probe_800_chained_board (port+0x10))
  254                                 /* invalid chained board? */
  255                                 return (0);
  256                         if (! (inb (BSR(port+0x10)) & BSR_NOCHAIN))
  257                                 /* invalid chained board flag? */
  258                                 return (0);
  259                 }
  260                 return 1;
  261         }
  262         if (cx_probe_chained_board (port, &c0, &c1)) {
  263                 /* Sigma-XXX detected. */
  264                 if (! (inb (BSR(port)) & BSR_NOCHAIN)) {
  265                         /* chained board attached */
  266                         if (! cx_probe_chained_board (port+0x10, &c2, &c3))
  267                                 /* invalid chained board? */
  268                                 return (0);
  269                         if (! (inb (BSR(port+0x10)) & BSR_NOCHAIN))
  270                                 /* invalid chained board flag? */
  271                                 return (0);
  272                 }
  273         } else if (cx_probe_2x_board (port)) {
  274                 c0 = 1;         /* Sigma-2x detected. */
  275                 c1 = 0;
  276         } else
  277                 return (0);     /* no board detected */
  278 
  279         /* Turn off the reset bit. */
  280         outb (BCR0(port), BCR0_NORESET);
  281         if (c2 || c3)
  282                 outb (BCR0(port + 0x10), BCR0_NORESET);
  283 
  284         result = 1;
  285         if (c0 && ! cx_probe_chip (CS0(port)))
  286                 result = 0;     /* no CD2400 chip here */
  287         else if (c1 && ! cx_probe_chip (CS1A(port)) &&
  288             ! cx_probe_chip (CS1(port)))
  289                 result = 0;     /* no second CD2400 chip */
  290         else if (c2 && ! cx_probe_chip (CS0(port + 0x10)))
  291                 result = 0;     /* no CD2400 chip on the slave board */
  292         else if (c3 && ! cx_probe_chip (CS1(port + 0x10)))
  293                 result = 0;     /* no second CD2400 chip on the slave board */
  294 
  295         /* Reset the controller. */
  296         outb (BCR0(port), 0);
  297         if (c2 || c3)
  298                 outb (BCR0(port + 0x10), 0);
  299 
  300         /* Yes, we really have valid Sigma board. */
  301         return (result);
  302 }
  303 
  304 /*
  305  * Check if the CD2400 chip is present at the given base port.
  306  */
  307 static int cx_probe_chip (port_t base)
  308 {
  309         int rev, newrev, count;
  310 
  311         /* Wait up to 10 msec for revision code to appear after reset. */
  312         rev = 0;
  313         for (count=0; rev==0; ++count) {
  314                 if (count >= 20000)
  315                         return (0); /* reset failed */
  316                 rev = inb (GFRCR(base));
  317         }
  318 
  319         /* Read and check the global firmware revision code. */
  320         if (! (rev>=REVCL_MIN && rev<=REVCL_MAX) &&
  321             ! (rev>=REVCL31_MIN && rev<=REVCL31_MAX))
  322                 return (0);     /* CD2400/2431 revision does not match */
  323 
  324         /* Reset the chip. */
  325         if (! cx_reset (base))
  326                 return (0);
  327 
  328         /* Read and check the new global firmware revision code. */
  329         newrev = inb (GFRCR(base));
  330         if (newrev != rev)
  331                 return (0);     /* revision changed */
  332 
  333         /* Yes, we really have CD2400/2431 chip here. */
  334         return (1);
  335 }
  336 
  337 /*
  338  * Check that the irq is functional.
  339  * irq>0  - activate the interrupt from the adapter (irq=on)
  340  * irq<0  - deactivate the interrupt (irq=off)
  341  * irq==0 - free the interrupt line (irq=tri-state)
  342  * Return the interrupt mask _before_ activating irq.
  343  */
  344 int cx_probe_irq (cx_board_t *b, int irq)
  345 {
  346         int mask, rev;
  347         port_t port;
  348 
  349         rev = inb (BSR(b->port));
  350         port = ((rev & BSR_VAR_MASK) != CRONYX_400) ? CS0(b->port) : CS1(b->port);
  351 
  352         outb (0x20, 0x0a);
  353         mask = inb (0x20);
  354         outb (0xa0, 0x0a);
  355         mask |= inb (0xa0) << 8;
  356 
  357         if (irq > 0) {
  358                 outb (BCR0(b->port), BCR0_NORESET | irqmask[irq]);
  359                 outb (CAR(port), 0);
  360                 cx_cmd (port, CCR_CLRCH);
  361                 outb (CMR(port), CMR_HDLC);
  362                 outb (TCOR(port), 0);
  363                 outb (TBPR(port), 1);
  364                 cx_cmd (port, CCR_INITCH | CCR_ENTX);
  365                 outb (IER(port), IER_TXMPTY);
  366         } else if (irq < 0) {
  367                 cx_reset (port);
  368                 if (-irq > 7) {
  369                         outb (0xa0, 0x60 | ((-irq) & 7));
  370                         outb (0x20, 0x62);
  371                 } else
  372                         outb (0x20, 0x60 | (-irq));
  373         } else
  374                 outb (BCR0(b->port), 0);
  375         return mask;
  376 }
  377 
  378 static int cx_chip_revision (port_t port, int rev)
  379 {
  380         int count;
  381 
  382         /* Model 400 has no first chip. */
  383         port = ((rev & BSR_VAR_MASK) != CRONYX_400) ? CS0(port) : CS1(port);
  384 
  385         /* Wait up to 10 msec for revision code to appear after reset. */
  386         for (count=0; inb(GFRCR(port))==0; ++count)
  387                 if (count >= 20000)
  388                         return (0); /* reset failed */
  389 
  390         return inb (GFRCR (port));
  391 }
  392 
  393 /*
  394  * Probe and initialize the board structure.
  395  */
  396 void cx_init (cx_board_t *b, int num, port_t port, int irq, int dma)
  397 {
  398         int gfrcr, rev, chain, mod = 0, rev2 = 0, mod2 = 0;
  399 
  400         rev = inb (BSR(port));
  401         chain = ! (rev & BSR_NOCHAIN);
  402         if (cx_probe_800_chained_board (port)) {
  403                 cx_init_800 (b, num, port, irq, dma, chain);
  404                 return;
  405         }
  406         if ((rev & BSR2X_VAR_MASK) == CRONYX_22 ||
  407             (rev & BSR2X_VAR_MASK) == CRONYX_24) {
  408                 cx_init_2x (b, num, port, irq, dma,
  409                         (rev & BSR2X_VAR_MASK), (rev & BSR2X_OSC_33));
  410                 return;
  411         }
  412 
  413         outb (BCR0(port), BCR0_NORESET);
  414         if (chain)
  415                 outb (BCR0(port+0x10), BCR0_NORESET);
  416         gfrcr = cx_chip_revision (port, rev);
  417         if (gfrcr >= REVCL31_MIN && gfrcr <= REVCL31_MAX)
  418                 mod = 1;
  419         if (chain) {
  420                 rev2 = inb (BSR(port+0x10));
  421                 gfrcr = cx_chip_revision (port+0x10, rev2);
  422                 if (gfrcr >= REVCL31_MIN && gfrcr <= REVCL31_MAX)
  423                         mod2 = 1;
  424                 outb (BCR0(port+0x10), 0);
  425         }
  426         outb (BCR0(port), 0);
  427 
  428         cx_init_board (b, num, port, irq, dma, chain,
  429                 (rev & BSR_VAR_MASK), (rev & BSR_OSC_MASK), mod,
  430                 (rev2 & BSR_VAR_MASK), (rev2 & BSR_OSC_MASK), mod2);
  431 }
  432 
  433 /*
  434  * Initialize the board structure, given the type of the board.
  435  */
  436 void cx_init_board (cx_board_t *b, int num, port_t port, int irq, int dma,
  437         int chain, int rev, int osc, int mod, int rev2, int osc2, int mod2)
  438 {
  439         cx_chan_t *c;
  440         char *type;
  441         int i;
  442 
  443         /* Initialize board structure. */
  444         b->port = port;
  445         b->num = num;
  446         b->irq = irq;
  447         b->dma = dma;
  448         b->opt = board_opt_dflt;
  449 
  450         b->type = B_SIGMA_XXX;
  451         b->if0type = b->if8type = cx_iftype;
  452 
  453         /* Set channels 0 and 8 mode, set DMA and IRQ. */
  454         b->bcr0 = b->bcr0b = BCR0_NORESET | dmamask[b->dma] | irqmask[b->irq];
  455 
  456         /* Clear DTR[0..3] and DTR[8..12]. */
  457         b->bcr1 = b->bcr1b = 0;
  458 
  459         /*------------------ Master board -------------------*/
  460 
  461         /* Read and check the board revision code. */
  462         strcpy (b->name, mod ? "m" : "");
  463         switch (rev) {
  464         default:          type = "";     break;
  465         case CRONYX_100:  type = "100";  break;
  466         case CRONYX_400:  type = "400";  break;
  467         case CRONYX_500:  type = "500";  break;
  468         case CRONYX_410:  type = "410";  break;
  469         case CRONYX_810:  type = "810";  break;
  470         case CRONYX_410s: type = "410s"; break;
  471         case CRONYX_810s: type = "810s"; break;
  472         case CRONYX_440:  type = "440";  break;
  473         case CRONYX_840:  type = "840";  break;
  474         case CRONYX_401:  type = "401";  break;
  475         case CRONYX_801:  type = "801";  break;
  476         case CRONYX_401s: type = "401s"; break;
  477         case CRONYX_801s: type = "801s"; break;
  478         case CRONYX_404:  type = "404";  break;
  479         case CRONYX_703:  type = "703";  break;
  480         }
  481         strcat (b->name, type);
  482 
  483         switch (osc) {
  484         default:
  485         case BSR_OSC_20: /* 20 MHz */
  486                 b->chan[0].oscfreq = b->chan[1].oscfreq =
  487                 b->chan[2].oscfreq = b->chan[3].oscfreq =
  488                 b->chan[4].oscfreq = b->chan[5].oscfreq =
  489                 b->chan[6].oscfreq = b->chan[7].oscfreq =
  490                         mod ? 33000000L : 20000000L;
  491                 strcat (b->name, "a");
  492                 break;
  493         case BSR_OSC_18432: /* 18.432 MHz */
  494                 b->chan[0].oscfreq = b->chan[1].oscfreq =
  495                 b->chan[2].oscfreq = b->chan[3].oscfreq =
  496                 b->chan[4].oscfreq = b->chan[5].oscfreq =
  497                 b->chan[6].oscfreq = b->chan[7].oscfreq =
  498                         mod ? 20000000L : 18432000L;
  499                 strcat (b->name, "b");
  500                 break;
  501         }
  502 
  503         /*------------------ Slave board -------------------*/
  504 
  505         if (chain) {
  506                 /* Read and check the board revision code. */
  507                 strcat (b->name, mod2 ? "/m" : "/");
  508                 switch (rev2) {
  509                 default:          type = "";     break;
  510                 case CRONYX_100:  type = "100";  break;
  511                 case CRONYX_400:  type = "400";  break;
  512                 case CRONYX_500:  type = "500";  break;
  513                 case CRONYX_410:  type = "410";  break;
  514                 case CRONYX_810:  type = "810";  break;
  515                 case CRONYX_410s: type = "410s"; break;
  516                 case CRONYX_810s: type = "810s"; break;
  517                 case CRONYX_440:  type = "440";  break;
  518                 case CRONYX_840:  type = "840";  break;
  519                 case CRONYX_401:  type = "401";  break;
  520                 case CRONYX_801:  type = "801";  break;
  521                 case CRONYX_401s: type = "401s"; break;
  522                 case CRONYX_801s: type = "801s"; break;
  523                 case CRONYX_404:  type = "404";  break;
  524                 case CRONYX_703:  type = "703";  break;
  525                 }
  526                 strcat (b->name, type);
  527 
  528                 switch (osc2) {
  529                 default:
  530                 case BSR_OSC_20: /* 20 MHz */
  531                         b->chan[8].oscfreq = b->chan[9].oscfreq =
  532                         b->chan[10].oscfreq = b->chan[11].oscfreq =
  533                         b->chan[12].oscfreq = b->chan[13].oscfreq =
  534                         b->chan[14].oscfreq = b->chan[15].oscfreq =
  535                                 mod2 ? 33000000L : 20000000L;
  536                         strcat (b->name, "a");
  537                         break;
  538                 case BSR_OSC_18432: /* 18.432 MHz */
  539                         b->chan[8].oscfreq = b->chan[9].oscfreq =
  540                         b->chan[10].oscfreq = b->chan[11].oscfreq =
  541                         b->chan[12].oscfreq = b->chan[13].oscfreq =
  542                         b->chan[14].oscfreq = b->chan[15].oscfreq =
  543                                 mod2 ? 20000000L : 18432000L;
  544                         strcat (b->name, "b");
  545                         break;
  546                 }
  547         }
  548 
  549         /* Initialize channel structures. */
  550         for (i=0; i<4; ++i) {
  551                 b->chan[i+0].port  = CS0(port);
  552                 b->chan[i+4].port  = cx_probe_chip (CS1A(port)) ?
  553                         CS1A(port) : CS1(port);
  554                 b->chan[i+8].port  = CS0(port+0x10);
  555                 b->chan[i+12].port = CS1(port+0x10);
  556         }
  557         for (c=b->chan; c<b->chan+NCHAN; ++c) {
  558                 c->board = b;
  559                 c->num = c - b->chan;
  560                 c->type = T_NONE;
  561         }
  562 
  563         /*------------------ Master board -------------------*/
  564 
  565         switch (rev) {
  566         case CRONYX_400:
  567                 for (i=4; i<8; ++i)
  568                         b->chan[i].type = T_UNIV_RS232;
  569                 break;
  570         case CRONYX_100:
  571                 b->chan[0].type = T_UNIV_RS232;
  572                 break;
  573         case CRONYX_500:
  574                 b->chan[0].type = T_UNIV_RS232;
  575                 for (i=4; i<8; ++i)
  576                         b->chan[i].type = T_UNIV_RS232;
  577                 break;
  578         case CRONYX_410:
  579                 b->chan[0].type = T_UNIV_V35;
  580                 for (i=1; i<4; ++i)
  581                         b->chan[i].type = T_UNIV_RS232;
  582                 break;
  583         case CRONYX_810:
  584                 b->chan[0].type = T_UNIV_V35;
  585                 for (i=1; i<8; ++i)
  586                         b->chan[i].type = T_UNIV_RS232;
  587                 break;
  588         case CRONYX_410s:
  589                 b->chan[0].type = T_UNIV_V35;
  590                 for (i=1; i<4; ++i)
  591                         b->chan[i].type = T_SYNC_RS232;
  592                 break;
  593         case CRONYX_810s:
  594                 b->chan[0].type = T_UNIV_V35;
  595                 for (i=1; i<4; ++i)
  596                         b->chan[i].type = T_SYNC_RS232;
  597                 for (i=4; i<8; ++i)
  598                         b->chan[i].type = T_UNIV_RS232;
  599                 break;
  600         case CRONYX_440:
  601                 b->chan[0].type = T_UNIV_V35;
  602                 for (i=1; i<4; ++i)
  603                         b->chan[i].type = T_SYNC_V35;
  604                 break;
  605         case CRONYX_840:
  606                 b->chan[0].type = T_UNIV_V35;
  607                 for (i=1; i<4; ++i)
  608                         b->chan[i].type = T_SYNC_V35;
  609                 for (i=4; i<8; ++i)
  610                         b->chan[i].type = T_UNIV_RS232;
  611                 break;
  612         case CRONYX_401:
  613                 b->chan[0].type = T_UNIV_RS449;
  614                 for (i=1; i<4; ++i)
  615                         b->chan[i].type = T_UNIV_RS232;
  616                 break;
  617         case CRONYX_801:
  618                 b->chan[0].type = T_UNIV_RS449;
  619                 for (i=1; i<8; ++i)
  620                         b->chan[i].type = T_UNIV_RS232;
  621                 break;
  622         case CRONYX_401s:
  623                 b->chan[0].type = T_UNIV_RS449;
  624                 for (i=1; i<4; ++i)
  625                         b->chan[i].type = T_SYNC_RS232;
  626                 break;
  627         case CRONYX_801s:
  628                 b->chan[0].type = T_UNIV_RS449;
  629                 for (i=1; i<4; ++i)
  630                         b->chan[i].type = T_SYNC_RS232;
  631                 for (i=4; i<8; ++i)
  632                         b->chan[i].type = T_UNIV_RS232;
  633                 break;
  634         case CRONYX_404:
  635                 b->chan[0].type = T_UNIV_RS449;
  636                 for (i=1; i<4; ++i)
  637                         b->chan[i].type = T_SYNC_RS449;
  638                 break;
  639         case CRONYX_703:
  640                 b->chan[0].type = T_UNIV_RS449;
  641                 for (i=1; i<3; ++i)
  642                         b->chan[i].type = T_SYNC_RS449;
  643                 for (i=4; i<8; ++i)
  644                         b->chan[i].type = T_UNIV_RS232;
  645                 break;
  646         }
  647 
  648         /*------------------ Slave board -------------------*/
  649 
  650         if (chain) {
  651                 switch (rev2) {
  652                 case CRONYX_400:
  653                         break;
  654                 case CRONYX_100:
  655                         b->chan[8].type = T_UNIV_RS232;
  656                         break;
  657                 case CRONYX_500:
  658                         b->chan[8].type = T_UNIV_RS232;
  659                         for (i=12; i<16; ++i)
  660                                 b->chan[i].type = T_UNIV_RS232;
  661                         break;
  662                 case CRONYX_410:
  663                         b->chan[8].type = T_UNIV_V35;
  664                         for (i=9; i<12; ++i)
  665                                 b->chan[i].type = T_UNIV_RS232;
  666                         break;
  667                 case CRONYX_810:
  668                         b->chan[8].type = T_UNIV_V35;
  669                         for (i=9; i<16; ++i)
  670                                 b->chan[i].type = T_UNIV_RS232;
  671                         break;
  672                 case CRONYX_410s:
  673                         b->chan[8].type = T_UNIV_V35;
  674                         for (i=9; i<12; ++i)
  675                                 b->chan[i].type = T_SYNC_RS232;
  676                         break;
  677                 case CRONYX_810s:
  678                         b->chan[8].type = T_UNIV_V35;
  679                         for (i=9; i<12; ++i)
  680                                 b->chan[i].type = T_SYNC_RS232;
  681                         for (i=12; i<16; ++i)
  682                                 b->chan[i].type = T_UNIV_RS232;
  683                         break;
  684                 case CRONYX_440:
  685                         b->chan[8].type = T_UNIV_V35;
  686                         for (i=9; i<12; ++i)
  687                                 b->chan[i].type = T_SYNC_V35;
  688                         break;
  689                 case CRONYX_840:
  690                         b->chan[8].type = T_UNIV_V35;
  691                         for (i=9; i<12; ++i)
  692                                 b->chan[i].type = T_SYNC_V35;
  693                         for (i=12; i<16; ++i)
  694                                 b->chan[i].type = T_UNIV_RS232;
  695                         break;
  696                 case CRONYX_401:
  697                         b->chan[8].type = T_UNIV_RS449;
  698                         for (i=9; i<12; ++i)
  699                                 b->chan[i].type = T_UNIV_RS232;
  700                         break;
  701                 case CRONYX_801:
  702                         b->chan[8].type = T_UNIV_RS449;
  703                         for (i=9; i<16; ++i)
  704                                 b->chan[i].type = T_UNIV_RS232;
  705                         break;
  706                 case CRONYX_401s:
  707                         b->chan[8].type = T_UNIV_RS449;
  708                         for (i=9; i<12; ++i)
  709                                 b->chan[i].type = T_UNIV_RS232;
  710                         break;
  711                 case CRONYX_801s:
  712                         b->chan[8].type = T_UNIV_RS449;
  713                         for (i=9; i<12; ++i)
  714                                 b->chan[i].type = T_SYNC_RS232;
  715                         for (i=12; i<16; ++i)
  716                                 b->chan[i].type = T_UNIV_RS232;
  717                         break;
  718                 case CRONYX_404:
  719                         b->chan[8].type = T_UNIV_RS449;
  720                         for (i=9; i<12; ++i)
  721                                 b->chan[i].type = T_SYNC_RS449;
  722                         break;
  723                 case CRONYX_703:
  724                         b->chan[8].type = T_UNIV_RS449;
  725                         for (i=9; i<11; ++i)
  726                                 b->chan[i].type = T_SYNC_RS449;
  727                         for (i=12; i<16; ++i)
  728                                 b->chan[i].type = T_UNIV_RS232;
  729                         break;
  730                 }
  731         }
  732 
  733         b->nuniv = b->nsync = b->nasync = 0;
  734         for (c=b->chan; c<b->chan+NCHAN; ++c)
  735                 switch (c->type) {
  736                 case T_ASYNC:      ++b->nasync; break;
  737                 case T_UNIV:
  738                 case T_UNIV_RS232:
  739                 case T_UNIV_RS449:
  740                 case T_UNIV_V35:   ++b->nuniv;  break;
  741                 case T_SYNC_RS232:
  742                 case T_SYNC_V35:
  743                 case T_SYNC_RS449: ++b->nsync;  break;
  744                 }
  745 
  746         cx_reinit_board (b);
  747 }
  748 
  749 /*
  750  * Initialize the Sigma-800 board structure.
  751  */
  752 void cx_init_800 (cx_board_t *b, int num, port_t port, int irq, int dma,
  753         int chain)
  754 {
  755         cx_chan_t *c;
  756         int i;
  757 
  758         /* Initialize board structure. */
  759         b->port = port;
  760         b->num = num;
  761         b->irq = irq;
  762         b->dma = dma;
  763         b->opt = board_opt_dflt;
  764         b->type = B_SIGMA_800;
  765 
  766         /* Set channels 0 and 8 mode, set DMA and IRQ. */
  767         b->bcr0 = b->bcr0b = dmamask[b->dma] | irqmask[b->irq];
  768 
  769         /* Clear DTR[0..7] and DTR[8..15]. */
  770         b->bcr1 = b->bcr1b = 0;
  771 
  772         strcpy (b->name, "800");
  773         if (chain)
  774                 strcat (b->name, "/800");
  775 
  776         /* Initialize channel structures. */
  777         for (i=0; i<4; ++i) {
  778                 b->chan[i+0].port  = CS0(port);
  779                 b->chan[i+4].port  = cx_probe_chip (CS1A(port)) ?
  780                         CS1A(port) : CS1(port);
  781                 b->chan[i+8].port  = CS0(port+0x10);
  782                 b->chan[i+12].port = CS1(port+0x10);
  783         }
  784         for (c=b->chan; c<b->chan+NCHAN; ++c) {
  785                 c->board = b;
  786                 c->num = c - b->chan;
  787                 c->oscfreq = 33000000L;
  788                 c->type = (c->num < 8 || chain) ? T_UNIV_RS232 : T_NONE;
  789         }
  790 
  791         b->nuniv = b->nsync = b->nasync = 0;
  792         for (c=b->chan; c<b->chan+NCHAN; ++c)
  793                 switch (c->type) {
  794                 case T_ASYNC:      ++b->nasync; break;
  795                 case T_UNIV:
  796                 case T_UNIV_RS232:
  797                 case T_UNIV_RS449:
  798                 case T_UNIV_V35:   ++b->nuniv;  break;
  799                 case T_SYNC_RS232:
  800                 case T_SYNC_V35:
  801                 case T_SYNC_RS449: ++b->nsync;  break;
  802                 }
  803 
  804         cx_reinit_board (b);
  805 }
  806 
  807 /*
  808  * Initialize the Sigma-2x board structure.
  809  */
  810 void cx_init_2x (cx_board_t *b, int num, port_t port, int irq, int dma,
  811         int rev, int osc)
  812 {
  813         cx_chan_t *c;
  814         int i;
  815 
  816         /* Initialize board structure. */
  817         b->port = port;
  818         b->num = num;
  819         b->irq = irq;
  820         b->dma = dma;
  821         b->opt = board_opt_dflt;
  822 
  823         b->type = B_SIGMA_2X;
  824 
  825         /* Set channels 0 and 8 mode, set DMA and IRQ. */
  826         b->bcr0 = BCR0_NORESET | dmamask[b->dma] | irqmask[b->irq];
  827         if (b->type == B_SIGMA_2X && b->opt.fast)
  828                 b->bcr0 |= BCR02X_FAST;
  829 
  830         /* Clear DTR[0..3] and DTR[8..12]. */
  831         b->bcr1 = 0;
  832 
  833         /* Initialize channel structures. */
  834         for (i=0; i<4; ++i) {
  835                 b->chan[i+0].port  = CS0(port);
  836                 b->chan[i+4].port  = CS1(port);
  837                 b->chan[i+8].port  = CS0(port+0x10);
  838                 b->chan[i+12].port = CS1(port+0x10);
  839         }
  840         for (c=b->chan; c<b->chan+NCHAN; ++c) {
  841                 c->board = b;
  842                 c->num = c - b->chan;
  843                 c->type = T_NONE;
  844                 c->oscfreq = (osc & BSR2X_OSC_33) ? 33000000L : 20000000L;
  845         }
  846 
  847         /* Check the board revision code. */
  848         strcpy (b->name, "22");
  849         b->chan[0].type = T_UNIV;
  850         b->chan[1].type = T_UNIV;
  851         b->nsync = b->nasync = 0;
  852         b->nuniv = 2;
  853         if (rev == CRONYX_24) {
  854                 strcpy (b->name, "24");
  855                 b->chan[2].type = T_UNIV;
  856                 b->chan[3].type = T_UNIV;
  857                 b->nuniv += 2;
  858         }
  859         strcat (b->name, (osc & BSR2X_OSC_33) ? "c" : "a");
  860         cx_reinit_board (b);
  861 }
  862 
  863 /*
  864  * Reinitialize all channels, using new options and baud rate.
  865  */
  866 void cx_reinit_board (cx_board_t *b)
  867 {
  868         cx_chan_t *c;
  869 
  870         b->opt = board_opt_dflt;
  871         if (b->type == B_SIGMA_2X) {
  872                 b->bcr0 &= ~BCR02X_FAST;
  873                 if (b->opt.fast)
  874                         b->bcr0 |= BCR02X_FAST;
  875         } else
  876                 b->if0type = b->if8type = cx_iftype;
  877         for (c=b->chan; c<b->chan+NCHAN; ++c) {
  878                 switch (c->type) {
  879                 default:
  880                 case T_NONE:
  881                         continue;
  882                 case T_UNIV:
  883                 case T_UNIV_RS232:
  884                 case T_UNIV_RS449:
  885                 case T_UNIV_V35:
  886                         c->mode = (cx_univ_mode == M_ASYNC) ?
  887                                 M_ASYNC : cx_sync_mode;
  888                         break;
  889                 case T_SYNC_RS232:
  890                 case T_SYNC_V35:
  891                 case T_SYNC_RS449:
  892                         c->mode = cx_sync_mode;
  893                         break;
  894                 case T_ASYNC:
  895                         c->mode = M_ASYNC;
  896                         break;
  897                 }
  898                 c->rxbaud = cx_rxbaud;
  899                 c->txbaud = cx_txbaud;
  900                 c->opt = chan_opt_dflt;
  901                 c->aopt = opt_async_dflt;
  902                 c->hopt = opt_hdlc_dflt;
  903         }
  904 }
  905 
  906 /*
  907  * Set up the board.
  908  */
  909 int cx_setup_board (cx_board_t *b, const unsigned char *firmware,
  910         long bits, const cr_dat_tst_t *tst)
  911 {
  912         int i;
  913 #ifndef NDIS_MINIPORT_DRIVER
  914         /* Disable DMA channel. */
  915         outb (DMA_MASK, (b->dma & 3) | DMA_MASK_CLEAR);
  916 #endif
  917         /* Reset the controller. */
  918         outb (BCR0(b->port), 0);
  919         if (b->chan[8].type || b->chan[12].type)
  920                 outb (BCR0(b->port+0x10), 0);
  921 
  922         /* Load the firmware. */
  923         if (b->type == B_SIGMA_800) {
  924                 /* Reset the controllers. */
  925                 outb (BCR2(b->port), BCR2_TMS);
  926                 if (b->chan[8].type || b->chan[12].type)
  927                         outb (BCR2(b->port+0x10), BCR2_TMS);
  928                 outb (BCR2(b->port), 0);
  929                 if (b->chan[8].type || b->chan[12].type)
  930                         outb (BCR2(b->port+0x10), 0);
  931 
  932                 if (firmware &&
  933                     (! cx_download (b->port, firmware, bits, tst) ||
  934                     ((b->chan[8].type || b->chan[12].type) &&
  935                     ! cx_download (b->port+0x10, firmware, bits, tst))))
  936                         return (0);
  937         }
  938 
  939         /*
  940          * Set channels 0 and 8 to RS232 async. mode.
  941          * Enable DMA and IRQ.
  942          */
  943         outb (BCR0(b->port), b->bcr0);
  944         if (b->chan[8].type || b->chan[12].type)
  945                 outb (BCR0(b->port+0x10), b->bcr0b);
  946 
  947         /* Clear DTR[0..3] and DTR[8..12]. */
  948         outw (BCR1(b->port), b->bcr1);
  949         if (b->chan[8].type || b->chan[12].type)
  950                 outw (BCR1(b->port+0x10), b->bcr1b);
  951 
  952         if (b->type == B_SIGMA_800)
  953                 outb (BCR2(b->port), b->opt.fast &
  954                         (BCR2_BUS0 | BCR2_BUS1));
  955 
  956         /* Initialize all controllers. */
  957         for (i=0; i<NCHAN; i+=4)
  958                 if (b->chan[i].type != T_NONE)
  959                         cx_setup_chip (b->chan + i);
  960 #ifndef NDIS_MINIPORT_DRIVER
  961         /* Set up DMA channel to master mode. */
  962         outb (DMA_MODE, (b->dma & 3) | DMA_MODE_MASTER);
  963 
  964         /* Enable DMA channel. */
  965         outb (DMA_MASK, b->dma & 3);
  966 #endif
  967         /* Initialize all channels. */
  968         for (i=0; i<NCHAN; ++i)
  969                 if (b->chan[i].type != T_NONE)
  970                         cx_setup_chan (b->chan + i);
  971         return (1);
  972 }
  973 
  974 /*
  975  * Initialize the board.
  976  */
  977 static void cx_setup_chip (cx_chan_t *c)
  978 {
  979         /* Reset the chip. */
  980         cx_reset (c->port);
  981 
  982         /*
  983          * Set all interrupt level registers to the same value.
  984          * This enables the internal CD2400 priority scheme.
  985          */
  986         outb (RPILR(c->port), BRD_INTR_LEVEL);
  987         outb (TPILR(c->port), BRD_INTR_LEVEL);
  988         outb (MPILR(c->port), BRD_INTR_LEVEL);
  989 
  990         /* Set bus error count to zero. */
  991         outb (BERCNT(c->port), 0);
  992 
  993         /* Set 16-bit DMA mode. */
  994         outb (DMR(c->port), 0);
  995 
  996         /* Set timer period register to 1 msec (approximately). */
  997         outb (TPR(c->port), 10);
  998 }
  999 
 1000 /*
 1001  * Initialize the CD2400 channel.
 1002  */
 1003 void cx_update_chan (cx_chan_t *c)
 1004 {
 1005         int clock, period;
 1006 
 1007         if (c->board->type == B_SIGMA_XXX)
 1008                 switch (c->num) {
 1009                 case 0:
 1010                         c->board->bcr0 &= ~BCR0_UMASK;
 1011                         if (c->mode != M_ASYNC)
 1012                                 c->board->bcr0 |= BCR0_UM_SYNC;
 1013                         if (c->board->if0type &&
 1014                             (c->type==T_UNIV_RS449 || c->type==T_UNIV_V35))
 1015                                 c->board->bcr0 |= BCR0_UI_RS449;
 1016                         outb (BCR0(c->board->port), c->board->bcr0);
 1017                         break;
 1018                 case 8:
 1019                         c->board->bcr0b &= ~BCR0_UMASK;
 1020                         if (c->mode != M_ASYNC)
 1021                                 c->board->bcr0b |= BCR0_UM_SYNC;
 1022                         if (c->board->if8type &&
 1023                             (c->type==T_UNIV_RS449 || c->type==T_UNIV_V35))
 1024                                 c->board->bcr0b |= BCR0_UI_RS449;
 1025                         outb (BCR0(c->board->port+0x10), c->board->bcr0b);
 1026                         break;
 1027                 }
 1028 
 1029         /* set current channel number */
 1030         outb (CAR(c->port), c->num & 3);
 1031 
 1032         switch (c->mode) {      /* initialize the channel mode */
 1033         case M_ASYNC:
 1034                 /* set receiver timeout register */
 1035                 outw (RTPR(c->port), 10);          /* 10 msec, see TPR */
 1036                 c->opt.rcor.encod = ENCOD_NRZ;
 1037 
 1038                 outb (CMR(c->port), CMR_RXDMA | CMR_TXDMA | CMR_ASYNC);
 1039                 outb (COR1(c->port), BYTE c->aopt.cor1);
 1040                 outb (COR2(c->port), BYTE c->aopt.cor2);
 1041                 outb (COR3(c->port), BYTE c->aopt.cor3);
 1042                 outb (COR6(c->port), BYTE c->aopt.cor6);
 1043                 outb (COR7(c->port), BYTE c->aopt.cor7);
 1044                 outb (SCHR1(c->port), c->aopt.schr1);
 1045                 outb (SCHR2(c->port), c->aopt.schr2);
 1046                 outb (SCHR3(c->port), c->aopt.schr3);
 1047                 outb (SCHR4(c->port), c->aopt.schr4);
 1048                 outb (SCRL(c->port), c->aopt.scrl);
 1049                 outb (SCRH(c->port), c->aopt.scrh);
 1050                 outb (LNXT(c->port), c->aopt.lnxt);
 1051                 break;
 1052         case M_HDLC:
 1053                 outb (CMR(c->port), CMR_RXDMA | CMR_TXDMA | CMR_HDLC);
 1054                 outb (COR1(c->port), BYTE c->hopt.cor1);
 1055                 outb (COR2(c->port), BYTE c->hopt.cor2);
 1056                 outb (COR3(c->port), BYTE c->hopt.cor3);
 1057                 outb (RFAR1(c->port), c->hopt.rfar1);
 1058                 outb (RFAR2(c->port), c->hopt.rfar2);
 1059                 outb (RFAR3(c->port), c->hopt.rfar3);
 1060                 outb (RFAR4(c->port), c->hopt.rfar4);
 1061                 outb (CPSR(c->port), c->hopt.cpsr);
 1062                 break;
 1063         }
 1064 
 1065         /* set mode-independent options */
 1066         outb (COR4(c->port), BYTE c->opt.cor4);
 1067         outb (COR5(c->port), BYTE c->opt.cor5);
 1068 
 1069         /* set up receiver clock values */
 1070         if (c->mode == M_ASYNC || c->opt.rcor.dpll || c->opt.tcor.llm) {
 1071                 cx_clock (c->oscfreq, c->rxbaud, &clock, &period);
 1072                 c->opt.rcor.clk = clock;
 1073         } else {
 1074                 c->opt.rcor.clk = CLK_EXT;
 1075                 period = 1;
 1076         }
 1077         outb (RCOR(c->port), BYTE c->opt.rcor);
 1078         outb (RBPR(c->port), period);
 1079 
 1080         /* set up transmitter clock values */
 1081         if (c->mode == M_ASYNC || !c->opt.tcor.ext1x) {
 1082                 unsigned ext1x = c->opt.tcor.ext1x;
 1083                 c->opt.tcor.ext1x = 0;
 1084                 cx_clock (c->oscfreq, c->txbaud, &clock, &period);
 1085                 c->opt.tcor.clk = clock;
 1086                 c->opt.tcor.ext1x = ext1x;
 1087         } else {
 1088                 c->opt.tcor.clk = CLK_EXT;
 1089                 period = 1;
 1090         }
 1091         outb (TCOR(c->port), BYTE c->opt.tcor);
 1092         outb (TBPR(c->port), period);
 1093 }
 1094 
 1095 /*
 1096  * Initialize the CD2400 channel.
 1097  */
 1098 void cx_setup_chan (cx_chan_t *c)
 1099 {
 1100         /* set current channel number */
 1101         outb (CAR(c->port), c->num & 3);
 1102 
 1103         /* reset the channel */
 1104         cx_cmd (c->port, CCR_CLRCH);
 1105 
 1106         /* set LIVR to contain the board and channel numbers */
 1107         outb (LIVR(c->port), c->board->num << 6 | c->num << 2);
 1108 
 1109         /* clear DTR, RTS, set TXCout/DTR pin */
 1110         outb (MSVR_RTS(c->port), 0);
 1111         outb (MSVR_DTR(c->port), c->mode==M_ASYNC ? 0 : MSV_TXCOUT);
 1112 
 1113         /* set receiver A buffer physical address */
 1114         outw (ARBADRU(c->port), (unsigned short) (c->arphys>>16));
 1115         outw (ARBADRL(c->port), (unsigned short) c->arphys);
 1116 
 1117         /* set receiver B buffer physical address */
 1118         outw (BRBADRU(c->port), (unsigned short) (c->brphys>>16));
 1119         outw (BRBADRL(c->port), (unsigned short) c->brphys);
 1120 
 1121         /* set transmitter A buffer physical address */
 1122         outw (ATBADRU(c->port), (unsigned short) (c->atphys>>16));
 1123         outw (ATBADRL(c->port), (unsigned short) c->atphys);
 1124 
 1125         /* set transmitter B buffer physical address */
 1126         outw (BTBADRU(c->port), (unsigned short) (c->btphys>>16));
 1127         outw (BTBADRL(c->port), (unsigned short) c->btphys);
 1128 
 1129         c->dtr = 0;
 1130         c->rts = 0;
 1131 
 1132         cx_update_chan (c);
 1133 }
 1134 
 1135 /*
 1136  * Control DTR signal for the channel.
 1137  * Turn it on/off.
 1138  */
 1139 void cx_set_dtr (cx_chan_t *c, int on)
 1140 {
 1141         cx_board_t *b = c->board;
 1142 
 1143         c->dtr = on ? 1 : 0;
 1144 
 1145         if (b->type == B_SIGMA_2X) {
 1146                 if (on) b->bcr1 |= BCR1_DTR(c->num);
 1147                 else    b->bcr1 &= ~BCR1_DTR(c->num);
 1148                 outw (BCR1(b->port), b->bcr1);
 1149                 return;
 1150         }
 1151         if (b->type == B_SIGMA_800) {
 1152                 if (c->num >= 8) {
 1153                         if (on) b->bcr1b |= BCR1800_DTR(c->num);
 1154                         else    b->bcr1b &= ~BCR1800_DTR(c->num);
 1155                         outb (BCR1(b->port+0x10), b->bcr1b);
 1156                 } else {
 1157                         if (on) b->bcr1 |= BCR1800_DTR(c->num);
 1158                         else    b->bcr1 &= ~BCR1800_DTR(c->num);
 1159                         outb (BCR1(b->port), b->bcr1);
 1160                 }
 1161                 return;
 1162         }
 1163         if (c->mode == M_ASYNC) {
 1164                 outb (CAR(c->port), c->num & 3);
 1165                 outb (MSVR_DTR(c->port), on ? MSV_DTR : 0);
 1166                 return;
 1167         }
 1168 
 1169         switch (c->num) {
 1170         default:
 1171                 /* Channels 4..7 and 12..15 in syncronous mode
 1172                  * have no DTR signal. */
 1173                 break;
 1174 
 1175         case 1: case 2:  case 3:
 1176                 if (c->type == T_UNIV_RS232)
 1177                         break;
 1178         case 0:
 1179                 if (on) b->bcr1 |= BCR1_DTR(c->num);
 1180                 else    b->bcr1 &= ~BCR1_DTR(c->num);
 1181                 outw (BCR1(b->port), b->bcr1);
 1182                 break;
 1183 
 1184         case 9: case 10: case 11:
 1185                 if (c->type == T_UNIV_RS232)
 1186                         break;
 1187         case 8:
 1188                 if (on) b->bcr1b |= BCR1_DTR(c->num & 3);
 1189                 else    b->bcr1b &= ~BCR1_DTR(c->num & 3);
 1190                 outw (BCR1(b->port+0x10), b->bcr1b);
 1191                 break;
 1192         }
 1193 }
 1194 
 1195 /*
 1196  * Control RTS signal for the channel.
 1197  * Turn it on/off.
 1198  */
 1199 void cx_set_rts (cx_chan_t *c, int on)
 1200 {
 1201         c->rts = on ? 1 : 0;
 1202         outb (CAR(c->port), c->num & 3);
 1203         outb (MSVR_RTS(c->port), on ? MSV_RTS : 0);
 1204 }
 1205 
 1206 /*
 1207  * Get the state of DSR signal of the channel.
 1208  */
 1209 int cx_get_dsr (cx_chan_t *c)
 1210 {
 1211         unsigned char sigval;
 1212 
 1213         if (c->board->type == B_SIGMA_2X ||
 1214             c->board->type == B_SIGMA_800 ||
 1215             c->mode == M_ASYNC) {
 1216                 outb (CAR(c->port), c->num & 3);
 1217                 return (inb (MSVR(c->port)) & MSV_DSR ? 1 : 0);
 1218         }
 1219 
 1220         /*
 1221          * Channels 4..7 and 12..15 don't have DSR signal available.
 1222          */
 1223         switch (c->num) {
 1224         default:
 1225                 return (1);
 1226 
 1227         case 1: case 2:  case 3:
 1228                 if (c->type == T_UNIV_RS232)
 1229                         return (1);
 1230         case 0:
 1231                 sigval = inw (BSR(c->board->port)) >> 8;
 1232                 break;
 1233 
 1234         case 9: case 10: case 11:
 1235                 if (c->type == T_UNIV_RS232)
 1236                         return (1);
 1237         case 8:
 1238                 sigval = inw (BSR(c->board->port+0x10)) >> 8;
 1239                 break;
 1240         }
 1241         return (~sigval >> (c->num & 3) & 1);
 1242 }
 1243 
 1244 /*
 1245  * Get the state of CARRIER signal of the channel.
 1246  */
 1247 int cx_get_cd (cx_chan_t *c)
 1248 {
 1249         unsigned char sigval;
 1250 
 1251         if (c->board->type == B_SIGMA_2X ||
 1252             c->board->type == B_SIGMA_800 ||
 1253             c->mode == M_ASYNC) {
 1254                 outb (CAR(c->port), c->num & 3);
 1255                 return (inb (MSVR(c->port)) & MSV_CD ? 1 : 0);
 1256         }
 1257 
 1258         /*
 1259          * Channels 4..7 and 12..15 don't have CD signal available.
 1260          */
 1261         switch (c->num) {
 1262         default:
 1263                 return (1);
 1264 
 1265         case 1: case 2:  case 3:
 1266                 if (c->type == T_UNIV_RS232)
 1267                         return (1);
 1268         case 0:
 1269                 sigval = inw (BSR(c->board->port)) >> 8;
 1270                 break;
 1271 
 1272         case 9: case 10: case 11:
 1273                 if (c->type == T_UNIV_RS232)
 1274                         return (1);
 1275         case 8:
 1276                 sigval = inw (BSR(c->board->port+0x10)) >> 8;
 1277                 break;
 1278         }
 1279         return (~sigval >> 4 >> (c->num & 3) & 1);
 1280 }
 1281 
 1282 /*
 1283  * Get the state of CTS signal of the channel.
 1284  */
 1285 int cx_get_cts (cx_chan_t *c)
 1286 {
 1287         outb (CAR(c->port), c->num & 3);
 1288         return (inb (MSVR(c->port)) & MSV_CTS ? 1 : 0);
 1289 }
 1290 
 1291 /*
 1292  * Compute CD2400 clock values.
 1293  */
 1294 void cx_clock (long hz, long ba, int *clk, int *div)
 1295 {
 1296         static short clocktab[] = { 8, 32, 128, 512, 2048, 0 };
 1297 
 1298         for (*clk=0; clocktab[*clk]; ++*clk) {
 1299                 long c = ba * clocktab[*clk];
 1300                 if (hz <= c*256) {
 1301                         *div = (2 * hz + c) / (2 * c) - 1;
 1302                         return;
 1303                 }
 1304         }
 1305         /* Incorrect baud rate.  Return some meaningful values. */
 1306         *clk = 0;
 1307         *div = 255;
 1308 }
 1309 
 1310 /*
 1311  * Turn LED on/off.
 1312  */
 1313 void cx_led (cx_board_t *b, int on)
 1314 {
 1315         switch (b->type) {
 1316         case B_SIGMA_2X:
 1317                 if (on) b->bcr0 |= BCR02X_LED;
 1318                 else    b->bcr0 &= ~BCR02X_LED;
 1319                 outb (BCR0(b->port), b->bcr0);
 1320                 break;
 1321         }
 1322 }
 1323 
 1324 void cx_disable_dma (cx_board_t *b)
 1325 {
 1326 #ifndef NDIS_MINIPORT_DRIVER
 1327         /* Disable DMA channel. */
 1328         outb (DMA_MASK, (b->dma & 3) | DMA_MASK_CLEAR);
 1329 #endif
 1330 }
 1331 
 1332 cx_board_opt_t board_opt_dflt = { /* board options */
 1333         BUS_NORMAL,             /* normal bus master timing */
 1334 };
 1335 
 1336 cx_chan_opt_t chan_opt_dflt = { /* mode-independent options */
 1337         {                       /* cor4 */
 1338                 7,              /* FIFO threshold, odd is better */
 1339                 0,
 1340                 0,              /* don't detect 1 to 0 on CTS */
 1341                 1,              /* detect 1 to 0 on CD */
 1342                 0,              /* detect 1 to 0 on DSR */
 1343         },
 1344         {                       /* cor5 */
 1345                 0,              /* receive flow control FIFO threshold */
 1346                 0,
 1347                 0,              /* don't detect 0 to 1 on CTS */
 1348                 1,              /* detect 0 to 1 on CD */
 1349                 0,              /* detect 0 to 1 on DSR */
 1350         },
 1351         {                       /* rcor */
 1352                 0,              /* dummy clock source */
 1353                 ENCOD_NRZ,      /* NRZ mode */
 1354                 0,              /* disable DPLL */
 1355                 0,
 1356                 0,              /* transmit line value */
 1357         },
 1358         {                       /* tcor */
 1359                 0,
 1360                 0,              /* local loopback mode */
 1361                 0,
 1362                 1,              /* external 1x clock mode */
 1363                 0,
 1364                 0,              /* dummy transmit clock source */
 1365         },
 1366 };
 1367 
 1368 cx_opt_async_t opt_async_dflt = { /* default async options */
 1369         {                       /* cor1 */
 1370                 8-1,            /* 8-bit char length */
 1371                 0,              /* don't ignore parity */
 1372                 PARM_NOPAR,     /* no parity */
 1373                 PAR_EVEN,       /* even parity */
 1374         },
 1375         {                       /* cor2 */
 1376                 0,              /* disable automatic DSR */
 1377                 1,              /* enable automatic CTS */
 1378                 0,              /* disable automatic RTS */
 1379                 0,              /* no remote loopback */
 1380                 0,
 1381                 0,              /* disable embedded cmds */
 1382                 0,              /* disable XON/XOFF */
 1383                 0,              /* disable XANY */
 1384         },
 1385         {                       /* cor3 */
 1386                 STOPB_1,        /* 1 stop bit */
 1387                 0,
 1388                 0,              /* disable special char detection */
 1389                 FLOWCC_PASS,    /* pass flow ctl chars to the host */
 1390                 0,              /* range detect disable */
 1391                 0,              /* disable extended spec. char detect */
 1392         },
 1393         {                       /* cor6 */
 1394                 PERR_INTR,      /* generate exception on parity errors */
 1395                 BRK_INTR,       /* generate exception on break condition */
 1396                 0,              /* don't translate NL to CR on input */
 1397                 0,              /* don't translate CR to NL on input */
 1398                 0,              /* don't discard CR on input */
 1399         },
 1400         {                       /* cor7 */
 1401                 0,              /* don't translate CR to NL on output */
 1402                 0,              /* don't translate NL to CR on output */
 1403                 0,
 1404                 0,              /* don't process flow ctl err chars */
 1405                 0,              /* disable LNext option */
 1406                 0,              /* don't strip 8 bit on input */
 1407         },
 1408         0, 0, 0, 0, 0, 0, 0,    /* clear schr1-4, scrl, scrh, lnxt */
 1409 };
 1410 
 1411 cx_opt_hdlc_t opt_hdlc_dflt = { /* default hdlc options */
 1412         {                       /* cor1 */
 1413                 2,              /* 2 inter-frame flags */
 1414                 0,              /* no-address mode */
 1415                 CLRDET_DISABLE, /* disable clear detect */
 1416                 AFLO_1OCT,      /* 1-byte address field length */
 1417         },
 1418         {                       /* cor2 */
 1419                 0,              /* disable automatic DSR */
 1420                 0,              /* disable automatic CTS */
 1421                 0,              /* disable automatic RTS */
 1422                 0,
 1423                 CRC_INVERT,     /* use CRC V.41 */
 1424                 0,
 1425                 FCS_NOTPASS,    /* don't pass received CRC to the host */
 1426                 0,
 1427         },
 1428         {                       /* cor3 */
 1429                 0,              /* 0 pad characters sent */
 1430                 IDLE_FLAG,      /* idle in flag */
 1431                 0,              /* enable FCS */
 1432                 FCSP_ONES,      /* FCS preset to all ones (V.41) */
 1433                 SYNC_AA,        /* use AAh as sync char */
 1434                 0,              /* disable pad characters */
 1435         },
 1436         0, 0, 0, 0,             /* clear rfar1-4 */
 1437         POLY_V41,               /* use V.41 CRC polynomial */
 1438 };

Cache object: 4d3575f926acdb7c48a08e2d3441f4ba


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