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/pci/isic_pci_elsa_qs1p.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 /* $NetBSD: isic_pci_elsa_qs1p.c,v 1.11 2003/05/08 21:18:42 martin Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  *---------------------------------------------------------------------------
   28  *
   29  *      isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro PCI
   30  *      =====================================================================
   31  *
   32  *---------------------------------------------------------------------------*/
   33 
   34 #include <sys/cdefs.h>
   35 __KERNEL_RCSID(0, "$NetBSD: isic_pci_elsa_qs1p.c,v 1.11 2003/05/08 21:18:42 martin Exp $");
   36 
   37 #include <sys/param.h>
   38 #include <sys/kernel.h>
   39 #include <sys/systm.h>
   40 #include <sys/mbuf.h>
   41 #include <sys/socket.h>
   42 #include <net/if.h>
   43 #include <sys/callout.h>
   44 
   45 #include <machine/bus.h>
   46 #include <sys/device.h>
   47 
   48 #include <dev/pci/pcireg.h>
   49 #include <dev/pci/pcivar.h>
   50 #include <dev/pci/pcidevs.h>
   51 
   52 #include <netisdn/i4b_debug.h>
   53 #include <netisdn/i4b_ioctl.h>
   54 #include <netisdn/i4b_global.h>
   55 #include <netisdn/i4b_debug.h>
   56 #include <netisdn/i4b_l2.h>
   57 #include <netisdn/i4b_l1l2.h>
   58 #include <netisdn/i4b_mbuf.h>
   59 
   60 #include <dev/ic/isic_l1.h>
   61 #include <dev/ic/isac.h>
   62 #include <dev/ic/hscx.h>
   63 #include <dev/ic/ipac.h>
   64 #include <dev/pci/isic_pci.h>
   65 
   66 /* masks for register encoded in base addr */
   67 
   68 #define ELSA_BASE_MASK          0x0ffff
   69 #define ELSA_OFF_MASK           0xf0000
   70 
   71 /* register id's to be encoded in base addr */
   72 
   73 #define ELSA_IDISAC             0x00000
   74 #define ELSA_IDHSCXA            0x10000
   75 #define ELSA_IDHSCXB            0x20000
   76 #define ELSA_IDIPAC             0x40000
   77 
   78 /* offsets from base address */
   79 
   80 #define ELSA_OFF_ALE            0x00
   81 #define ELSA_OFF_RW             0x01
   82 
   83 /* LED values */
   84 #define ELSA_NO_LED             0xff
   85 #define ELSA_GREEN_LED          0x40
   86 #define ELSA_YELLOW_LED         0x80
   87 
   88 #define ELSA_PORT0_MEM_MAPOFF   PCI_MAPREG_START
   89 #define ELSA_PORT0_IO_MAPOFF    PCI_MAPREG_START+4
   90 #define ELSA_PORT1_MAPOFF       PCI_MAPREG_START+12
   91 
   92 
   93 static void elsa_cmd_req(struct isic_softc *sc, int cmd, void *data);
   94 static void elsa_led_handler(void *token);
   95 
   96 /*---------------------------------------------------------------------------*
   97  *      ELSA QuickStep 1000pro/PCI ISAC get fifo routine
   98  *---------------------------------------------------------------------------*/
   99 
  100 static void
  101 eqs1pp_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
  102 {
  103         bus_space_tag_t t = sc->sc_maps[1].t;
  104         bus_space_handle_t h = sc->sc_maps[1].h;
  105         switch (what) {
  106                 case ISIC_WHAT_ISAC:
  107                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF);
  108                         bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
  109                         break;
  110                 case ISIC_WHAT_HSCXA:
  111                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF);
  112                         bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
  113                         break;
  114                 case ISIC_WHAT_HSCXB:
  115                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF);
  116                         bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
  117                         break;
  118         }
  119 }
  120 
  121 /*---------------------------------------------------------------------------*
  122  *      ELSA QuickStep 1000pro/PCI ISAC put fifo routine
  123  *---------------------------------------------------------------------------*/
  124 
  125 static void
  126 eqs1pp_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
  127 {
  128         bus_space_tag_t t = sc->sc_maps[1].t;
  129         bus_space_handle_t h = sc->sc_maps[1].h;
  130         switch (what) {
  131                 case ISIC_WHAT_ISAC:
  132                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF);
  133                         bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
  134                         break;
  135                 case ISIC_WHAT_HSCXA:
  136                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF);
  137                         bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
  138                         break;
  139                 case ISIC_WHAT_HSCXB:
  140                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF);
  141                         bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
  142                         break;
  143         }
  144 }
  145 
  146 /*---------------------------------------------------------------------------*
  147  *      ELSA QuickStep 1000pro/PCI ISAC put register routine
  148  *---------------------------------------------------------------------------*/
  149 
  150 static void
  151 eqs1pp_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
  152 {
  153         bus_space_tag_t t = sc->sc_maps[1].t;
  154         bus_space_handle_t h = sc->sc_maps[1].h;
  155         switch (what) {
  156                 case ISIC_WHAT_ISAC:
  157                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs);
  158                         bus_space_write_1(t, h, ELSA_OFF_RW, data);
  159                         break;
  160                 case ISIC_WHAT_HSCXA:
  161                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs);
  162                         bus_space_write_1(t, h, ELSA_OFF_RW, data);
  163                         break;
  164                 case ISIC_WHAT_HSCXB:
  165                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs);
  166                         bus_space_write_1(t, h, ELSA_OFF_RW, data);
  167                         break;
  168                 case ISIC_WHAT_IPAC:
  169                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs);
  170                         bus_space_write_1(t, h, ELSA_OFF_RW, data);
  171                         break;
  172         }
  173 }
  174 
  175 /*---------------------------------------------------------------------------*
  176  *      ELSA QuickStep 1000pro/PCI ISAC get register routine
  177  *---------------------------------------------------------------------------*/
  178 
  179 static u_int8_t
  180 eqs1pp_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
  181 {
  182         bus_space_tag_t t = sc->sc_maps[1].t;
  183         bus_space_handle_t h = sc->sc_maps[1].h;
  184         switch (what) {
  185                 case ISIC_WHAT_ISAC:
  186                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs);
  187                         return bus_space_read_1(t, h, ELSA_OFF_RW);
  188                 case ISIC_WHAT_HSCXA:
  189                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs);
  190                         return bus_space_read_1(t, h, ELSA_OFF_RW);
  191                 case ISIC_WHAT_HSCXB:
  192                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs);
  193                         return bus_space_read_1(t, h, ELSA_OFF_RW);
  194                 case ISIC_WHAT_IPAC:
  195                 {
  196                         bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs);
  197                         return bus_space_read_1(t, h, ELSA_OFF_RW);
  198                 }
  199         }
  200 
  201         return 0;
  202 }
  203 
  204 /*---------------------------------------------------------------------------*
  205  *      isic_attach_Eqs1pp - attach for ELSA QuickStep 1000pro/PCI
  206  *---------------------------------------------------------------------------*/
  207 
  208 void
  209 isic_attach_Eqs1pp(psc, pa)
  210         struct pci_isic_softc *psc;
  211         struct pci_attach_args *pa;
  212 {
  213         struct isic_softc *sc = &psc->sc_isic;
  214 
  215         /* setup io mappings */
  216         sc->sc_num_mappings = 2;
  217         MALLOC_MAPS(sc);
  218         sc->sc_maps[0].size = 0;
  219         if (pci_mapreg_map(pa, ELSA_PORT0_MEM_MAPOFF, PCI_MAPREG_TYPE_MEM, 0,
  220             &sc->sc_maps[0].t, &sc->sc_maps[0].h, &psc->sc_base, &psc->sc_size) != 0
  221            && pci_mapreg_map(pa, ELSA_PORT0_IO_MAPOFF, PCI_MAPREG_TYPE_IO, 0,
  222             &sc->sc_maps[0].t, &sc->sc_maps[0].h, &psc->sc_base, &psc->sc_size) != 0) {
  223                 printf("%s: can't map card registers\n", sc->sc_dev.dv_xname);
  224                 return;
  225         }
  226 
  227         /* PLX9050 Errata #1 */
  228         if (PCI_REVISION(pa->pa_class) == 1 && psc->sc_base & 0x00000080) {
  229 #ifdef DEBUG
  230                 printf("%s: no LCR access\n", sc->sc_dev.dv_xname);
  231 #endif
  232         } else
  233                 psc->flags |= PCIISIC_LCROK;
  234 
  235         sc->sc_maps[1].size = 0;
  236         if (pci_mapreg_map(pa, ELSA_PORT1_MAPOFF, PCI_MAPREG_TYPE_IO, 0,
  237             &sc->sc_maps[1].t, &sc->sc_maps[1].h, NULL, NULL)) {
  238                 printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
  239                 return;
  240         }
  241 
  242         /* setup access routines */
  243 
  244         sc->clearirq = NULL;
  245         sc->readreg = eqs1pp_read_reg;
  246         sc->writereg = eqs1pp_write_reg;
  247 
  248         sc->readfifo = eqs1pp_read_fifo;
  249         sc->writefifo = eqs1pp_write_fifo;
  250 
  251         sc->drv_command = elsa_cmd_req;
  252 
  253         /* setup card type */
  254         
  255         sc->sc_cardtyp = CARD_TYPEP_ELSAQS1PCI;
  256 
  257         /* setup IOM bus type */
  258         
  259         sc->sc_bustyp = BUS_TYPE_IOM2;
  260 
  261         /* setup chip type = IPAC ! */
  262         
  263         sc->sc_ipac = 1;
  264         sc->sc_bfifolen = IPAC_BFIFO_LEN;
  265 
  266         IPAC_WRITE(IPAC_ACFG, 0);       /* outputs are open drain */
  267         IPAC_WRITE(IPAC_AOE,            /* aux 5..2 are inputs, 7, 6 outputs */
  268                 (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
  269         IPAC_WRITE(IPAC_ATX, ELSA_NO_LED);      /* set all output lines high */
  270         callout_init(&((struct pci_isic_softc *)sc)->ledcallout);
  271 
  272         /* disable any interrupts */
  273         IPAC_WRITE(IPAC_MASK, 0xff);
  274         bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, 0x4c, 0x01);
  275 }
  276 
  277 int
  278 isic_intr_qs1p(vsc)
  279         void *vsc;
  280 {
  281         struct pci_isic_softc *psc = vsc;
  282         struct isic_softc *sc = &psc->sc_isic;
  283         u_int32_t intcsr;
  284 
  285         /*
  286          * if we are not hit by the PLX bug we can try a shortcut
  287          * (should improve speed for shared IRQs)
  288          */
  289         if (psc->flags & PCIISIC_LCROK) {
  290                 intcsr = bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h,
  291                                           0x4c /* INTCSR */);
  292                 if (!(intcsr & 0x4 /* LINTi1STAT */))
  293                         return (0);
  294         }
  295 
  296         return (isicintr(sc));
  297 }
  298 
  299 static void
  300 elsa_cmd_req(struct isic_softc *sc, int cmd, void *data)
  301 {
  302         intptr_t v;
  303         int s;
  304         struct pci_isic_softc *psc = (struct pci_isic_softc *)sc;
  305 
  306         switch (cmd) {
  307         case CMR_DOPEN:
  308                 s = splnet();
  309                 /* enable hscx/isac irq's */
  310                 IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
  311                 /* enable card interrupt */
  312                 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, 0x4c, 0x41);
  313                 splx(s);
  314                 break;
  315         case CMR_DCLOSE:
  316                 s = splnet();
  317                 callout_stop(&psc->ledcallout);
  318                 IPAC_WRITE(IPAC_ATX, ELSA_NO_LED);
  319                 IPAC_WRITE(IPAC_MASK, 0xff);
  320                 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, 0x4c, 0x01);
  321                 splx(s);
  322                 break;
  323         case CMR_SETLEDS:
  324                 v = (intptr_t)data;
  325                 callout_stop(&psc->ledcallout);
  326 
  327                 /* the magic value and keep reset off */
  328                 psc->ledstat = ELSA_NO_LED;
  329                 psc->ledblinkmask = 0;
  330                 psc->ledblinkfreq = 0;
  331 
  332                 /* now see what LEDs we want to add */
  333                 if (v & CMRLEDS_TEI)
  334                         psc->ledstat &= ~ELSA_GREEN_LED;
  335 
  336                 if (v & (CMRLEDS_B0|CMRLEDS_B1)) {
  337                         psc->ledstat &= ~ELSA_YELLOW_LED;
  338                         psc->ledblinkmask |= ELSA_YELLOW_LED;
  339                         if ((v & (CMRLEDS_B0|CMRLEDS_B1))
  340                             == (CMRLEDS_B0|CMRLEDS_B1))
  341                                 psc->ledblinkfreq = hz/4;
  342                         else
  343                                 psc->ledblinkfreq = hz;
  344                 }
  345 
  346                 elsa_led_handler(psc);
  347                 break;
  348         }
  349 }
  350 
  351 static void
  352 elsa_led_handler(void *token)
  353 {
  354         struct pci_isic_softc *psc = token;
  355         struct isic_softc *sc = token; /* XXX */
  356         int s;
  357 
  358         s = splnet();
  359         IPAC_WRITE(IPAC_ATX, psc->ledstat);
  360         splx(s);
  361         if (psc->ledblinkfreq) {
  362                 psc->ledstat ^= psc->ledblinkmask;
  363                 callout_reset(&psc->ledcallout, psc->ledblinkfreq,
  364                     elsa_led_handler, psc);
  365         }
  366 }

Cache object: f1ff367a3b793d4486a95419b8d875ca


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