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.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.c,v 1.20 2003/12/04 13:57:31 keihan Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2002 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Martin Husemann <martin@NetBSD.org>.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: isic_pci.c,v 1.20 2003/12/04 13:57:31 keihan Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/errno.h>
   44 #include <sys/syslog.h>
   45 #include <sys/device.h>
   46 #include <sys/socket.h>
   47 #include <net/if.h>
   48 #include <sys/systm.h>
   49 #include <sys/malloc.h>
   50 #include <sys/callout.h>
   51 
   52 #include <machine/cpu.h>
   53 #include <machine/intr.h>
   54 #include <machine/bus.h>
   55 
   56 
   57 #include <machine/bus.h>
   58 #include <machine/intr.h>
   59 #include <dev/pci/pcireg.h>
   60 #include <dev/pci/pcivar.h>
   61 #include <dev/pci/pcidevs.h>
   62 
   63 #include <netisdn/i4b_ioctl.h>
   64 #include <netisdn/i4b_global.h>
   65 #include <netisdn/i4b_debug.h>
   66 #include <netisdn/i4b_trace.h>
   67 #include <netisdn/i4b_l2.h>
   68 #include <netisdn/i4b_l1l2.h>
   69 
   70 #include <dev/ic/isic_l1.h>
   71 #include <dev/ic/ipac.h>
   72 #include <dev/ic/isac.h>
   73 #include <dev/ic/hscx.h>
   74 #include <dev/pci/isic_pci.h>
   75 
   76 extern const struct isdn_layer1_isdnif_driver isic_std_driver;
   77 
   78 static int isic_pci_match __P((struct device *, struct cfdata *, void *));
   79 static void isic_pci_attach __P((struct device *, struct device *, void *));
   80 static const struct isic_pci_product * find_matching_card __P((struct pci_attach_args *pa));
   81 
   82 static void isic_pci_isdn_attach __P((struct pci_isic_softc *psc, struct pci_attach_args *pa, const char *cardname));
   83 static int isic_pci_detach(struct device *self, int flags);
   84 static int isic_pci_activate(struct device *self, enum devact act);
   85 
   86 CFATTACH_DECL(isic_pci, sizeof(struct pci_isic_softc),
   87     isic_pci_match, isic_pci_attach, isic_pci_detach, isic_pci_activate);
   88 
   89 static const struct isic_pci_product {
   90         pci_vendor_id_t npp_vendor;
   91         pci_product_id_t npp_product;
   92         int cardtype;
   93         const char * name;
   94         void (*attach)(struct pci_isic_softc *psc, struct pci_attach_args *pa);
   95         void (*pciattach)(struct pci_isic_softc *psc, struct pci_attach_args *pa, const char *cardname);
   96 } isic_pci_products[] = {
   97         { PCI_VENDOR_ELSA, PCI_PRODUCT_ELSA_QS1PCI,
   98           CARD_TYPEP_ELSAQS1PCI,
   99           "ELSA QuickStep 1000pro/PCI",
  100           isic_attach_Eqs1pp,   /* card specific initialization */
  101           isic_pci_isdn_attach  /* generic setup for ISAC/HSCX or IPAC boards */
  102          },
  103         { 0, 0, 0, NULL, NULL },
  104 };
  105 
  106 static const struct isic_pci_product * find_matching_card(pa)
  107         struct pci_attach_args *pa;
  108 {
  109         const struct isic_pci_product * pp = NULL;
  110 
  111         for (pp = isic_pci_products; pp->npp_vendor; pp++) 
  112                 if (PCI_VENDOR(pa->pa_id) == pp->npp_vendor &&
  113                     PCI_PRODUCT(pa->pa_id) == pp->npp_product)
  114                         return pp;
  115 
  116         return NULL;
  117 }
  118 
  119 /*
  120  * Match card
  121  */
  122 static int
  123 isic_pci_match(parent, match, aux)
  124         struct device *parent;
  125         struct cfdata *match;
  126         void *aux;
  127 {
  128         struct pci_attach_args *pa = aux;
  129 
  130         if (!find_matching_card(pa))
  131                 return 0;
  132 
  133         return 1;
  134 }
  135 
  136 /*
  137  * Attach the card
  138  */
  139 static void
  140 isic_pci_attach(parent, self, aux)
  141         struct device *parent, *self;
  142         void *aux;
  143 {
  144         struct pci_isic_softc *psc = (void*) self;
  145         struct isic_softc *sc = &psc->sc_isic;
  146         struct pci_attach_args *pa = aux;
  147         const struct isic_pci_product * prod;
  148 
  149         /* Redo probe */
  150         prod = find_matching_card(pa);
  151         if (prod == NULL) return; /* oops - not found?!? */
  152 
  153         printf(": %s\n", prod->name);
  154 
  155         callout_init(&sc->sc_T3_callout);
  156         callout_init(&sc->sc_T4_callout);
  157 
  158         /* card initilization and sc setup */
  159         prod->attach(psc, pa);
  160 
  161         /* generic setup, if needed for this card */
  162         if (prod->pciattach) prod->pciattach(psc, pa, prod->name);
  163 }
  164 
  165 /*---------------------------------------------------------------------------*
  166  *      isic - pci device driver attach routine
  167  *---------------------------------------------------------------------------*/
  168 static void
  169 isic_pci_isdn_attach(psc, pa, cardname)
  170         struct pci_isic_softc *psc;
  171         struct pci_attach_args *pa;
  172         const char *cardname;
  173 {
  174         struct isic_softc *sc = &psc->sc_isic;
  175         pci_chipset_tag_t pc = pa->pa_pc;
  176         pci_intr_handle_t ih;
  177         const char *intrstr;
  178 
  179         static char *ISACversion[] = {
  180                 "2085 Version A1/A2 or 2086/2186 Version 1.1",
  181                 "2085 Version B1",
  182                 "2085 Version B2",
  183                 "2085 Version V2.3 (B3)",
  184                 "Unknown Version"
  185         };
  186 
  187         static char *HSCXversion[] = {
  188                 "82525 Version A1",
  189                 "Unknown (0x01)",
  190                 "82525 Version A2",
  191                 "Unknown (0x03)",
  192                 "82525 Version A3",
  193                 "82525 or 21525 Version 2.1",
  194                 "Unknown Version"
  195         };
  196 
  197         sc->sc_isac_version = 0;
  198         sc->sc_hscx_version = 0;
  199         
  200         if(sc->sc_ipac)
  201         {
  202                 u_int ret = IPAC_READ(IPAC_ID);
  203 
  204                 switch(ret)
  205                 {
  206                         case 0x01:
  207                                 printf("%s: IPAC PSB2115 Version 1.1\n", sc->sc_dev.dv_xname);
  208                                 break;
  209 
  210                         case 0x02:
  211                                 printf("%s: IPAC PSB2115 Version 1.2\n", sc->sc_dev.dv_xname);
  212                                 break;
  213         
  214                         default:
  215                                 printf("%s: Error, IPAC version %d unknown!\n",
  216                                         sc->sc_dev.dv_xname, ret);
  217                                 return;
  218                 }
  219         }
  220         else
  221         {
  222                 sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03;
  223         
  224                 switch(sc->sc_isac_version)
  225                 {
  226                         case ISAC_VA:
  227                         case ISAC_VB1:
  228                         case ISAC_VB2:
  229                         case ISAC_VB3:
  230                                 printf("%s: ISAC %s (IOM-%c)\n",
  231                                         sc->sc_dev.dv_xname,
  232                                         ISACversion[sc->sc_isac_version],
  233                                         sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
  234                                 break;
  235         
  236                         default:
  237                                 printf("%s: Error, ISAC version %d unknown!\n",
  238                                         sc->sc_dev.dv_xname, sc->sc_isac_version);
  239                                 return;
  240                 }
  241         
  242                 sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf;
  243         
  244                 switch(sc->sc_hscx_version)
  245                 {
  246                         case HSCX_VA1:
  247                         case HSCX_VA2:
  248                         case HSCX_VA3:
  249                         case HSCX_V21:
  250                                 printf("%s: HSCX %s\n",
  251                                         sc->sc_dev.dv_xname,
  252                                         HSCXversion[sc->sc_hscx_version]);
  253                                 break;
  254                                 
  255                         default:
  256                                 printf("%s: Error, HSCX version %d unknown!\n",
  257                                         sc->sc_dev.dv_xname, sc->sc_hscx_version);
  258                                 return;
  259                 }
  260         }
  261         
  262         /* Map and establish the interrupt. */
  263         if (pci_intr_map(pa, &ih)) {
  264                 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
  265                 return;
  266         }
  267         intrstr = pci_intr_string(pc, ih);
  268         psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, isic_intr_qs1p, psc);
  269         if (psc->sc_ih == NULL) {
  270                 printf("%s: couldn't establish interrupt",
  271                     sc->sc_dev.dv_xname);
  272                 if (intrstr != NULL)
  273                         printf(" at %s", intrstr);
  274                 printf("\n");
  275                 return;
  276         }
  277         psc->sc_pc = pc;
  278         printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
  279 
  280         sc->sc_intr_valid = ISIC_INTR_DISABLED;
  281  
  282         /* HSCX setup */
  283 
  284         isic_bchannel_setup(sc, HSCX_CH_A, BPROT_NONE, 0);
  285         
  286         isic_bchannel_setup(sc, HSCX_CH_B, BPROT_NONE, 0);
  287 
  288         /* setup linktab */
  289 
  290         isic_init_linktab(sc);
  291 
  292         /* set trace level */
  293 
  294         sc->sc_trace = TRACE_OFF;
  295 
  296         sc->sc_state = ISAC_IDLE;
  297 
  298         sc->sc_ibuf = NULL;
  299         sc->sc_ib = NULL;
  300         sc->sc_ilen = 0;
  301 
  302         sc->sc_obuf = NULL;
  303         sc->sc_op = NULL;
  304         sc->sc_ol = 0;
  305         sc->sc_freeflag = 0;
  306 
  307         sc->sc_obuf2 = NULL;
  308         sc->sc_freeflag2 = 0;
  309 
  310         /* init higher protocol layers */
  311         isic_attach_bri(sc, cardname, &isic_std_driver);
  312 }
  313 
  314 
  315 static int
  316 isic_pci_detach(self, flags)
  317         struct device *self;
  318         int flags;
  319 {
  320         struct pci_isic_softc *psc = (struct pci_isic_softc *)self;
  321 
  322         bus_space_unmap(psc->sc_isic.sc_maps[0].t, psc->sc_isic.sc_maps[0].h, psc->sc_size);
  323         bus_space_free(psc->sc_isic.sc_maps[0].t, psc->sc_isic.sc_maps[0].h, psc->sc_size);
  324         pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
  325 
  326         return (0);
  327 }
  328 
  329 static int
  330 isic_pci_activate(self, act)
  331         struct device *self;
  332         enum devact act;
  333 {
  334         struct pci_isic_softc *psc = (struct pci_isic_softc *)self;
  335         int error = 0, s;
  336 
  337         s = splnet();
  338         switch (act) {
  339         case DVACT_ACTIVATE:
  340                 error = EOPNOTSUPP;
  341                 break;
  342 
  343         case DVACT_DEACTIVATE:
  344                 psc->sc_isic.sc_intr_valid = ISIC_INTR_DYING;
  345                 isic_detach_bri(&psc->sc_isic);
  346                 break;
  347         }
  348         splx(s);
  349         return (error);
  350 }

Cache object: 98adfea10aac47b119aa996f7e46c636


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