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/iwic_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: iwic_pci.c,v 1.7 2003/10/03 16:38:44 pooka Exp $       */
    2 
    3 /*
    4  * Copyright (c) 1999, 2000 Dave Boyce. 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  *      i4b_iwic - isdn4bsd Winbond W6692 driver
   30  *      ----------------------------------------
   31  *
   32  * $FreeBSD$
   33  *
   34  *      last edit-date: [Tue Jan 16 10:53:03 2001]
   35  *
   36  *---------------------------------------------------------------------------*/
   37 
   38 #include <sys/cdefs.h>
   39 __KERNEL_RCSID(0, "$NetBSD: iwic_pci.c,v 1.7 2003/10/03 16:38:44 pooka Exp $");
   40 
   41 #include <sys/param.h>
   42 #include <sys/kernel.h>
   43 #include <sys/systm.h>
   44 #include <sys/callout.h>
   45 #include <net/if.h>
   46 
   47 #include <machine/bus.h>
   48 
   49 #include <dev/pci/pcivar.h>
   50 #include <dev/pci/pcidevs.h>
   51 
   52 #include <netisdn/i4b_global.h>
   53 
   54 #include <dev/pci/iwicreg.h>
   55 #include <dev/pci/iwicvar.h>
   56 
   57 /* Winbond PCI Configuration Space */
   58 
   59 #define IWIC_PCI_IOBA (PCI_MAPREG_START+0x04)
   60 
   61 static int iwic_pci_intr(void *sc);
   62 static int iwic_pci_probe(struct device * dev, struct cfdata * match, void *aux);
   63 static void iwic_pci_attach(struct device * parent, struct device * dev, void *aux);
   64 static int iwic_pci_activate(struct device * dev, enum devact);
   65 
   66 CFATTACH_DECL(iwic_pci, sizeof(struct iwic_softc),
   67     iwic_pci_probe, iwic_pci_attach, NULL, iwic_pci_activate);
   68 
   69 static int iwic_attach_bri(struct iwic_softc * sc);
   70 
   71 /*---------------------------------------------------------------------------*
   72  * PCI ID list for ASUSCOM card got from Asuscom in March 2000:
   73  *
   74  * Vendor ID: 0675 Device ID: 1702
   75  * Vendor ID: 0675 Device ID: 1703
   76  * Vendor ID: 0675 Device ID: 1707
   77  * Vendor ID: 10CF Device ID: 105E
   78  * Vendor ID: 1043 Device ID: 0675 SubVendor: 144F SubDevice ID: 2000
   79  * Vendor ID: 1043 Device ID: 0675 SubVendor: 144F SubDevice ID: 1702
   80  * Vendor ID: 1043 Device ID: 0675 SubVendor: 144F SubDevice ID: 1707
   81  * Vendor ID: 1043 Device ID: 0675 SubVendor: 1043 SubDevice ID: 1702
   82  * Vendor ID: 1043 Device ID: 0675 SubVendor: 1043 SubDevice ID: 1707
   83  * Vendor ID: 1050 Device ID: 6692 SubVendor: 0675 SubDevice ID: 1702
   84  *---------------------------------------------------------------------------*/
   85 
   86 static struct winids {
   87         pcireg_t type;
   88         int sv;
   89         int sd;
   90         const char *desc;
   91 } win_ids[] = {
   92         {
   93                 PCI_ID_CODE(PCI_VENDOR_WINBOND,PCI_PRODUCT_WINBOND_W6692),
   94                 0x144F,
   95                 0x1707,
   96                 "Planet PCI ISDN Adapter (Model IA128P-STDV)"
   97         },
   98         {
   99                 PCI_ID_CODE(PCI_VENDOR_WINBOND,PCI_PRODUCT_WINBOND_W6692),
  100                 -1,
  101                 -1,
  102                 "Generic Winbond W6692 ISDN PCI"
  103         },
  104         {
  105                 PCI_ID_CODE(PCI_VENDOR_DYNALINK,PCI_PRODUCT_DYNALINK_IS64PH),
  106                 -1,
  107                 -1,
  108                 "ASUSCOM P-IN100-ST-D"
  109         },
  110 #if 0
  111         /* XXX */
  112         {
  113                 PCI_ID_CODE(PCI_VENDOR_DYNALINK,0x1703),
  114                 -1,
  115                 -1,
  116                 "ASUSCOM P-IN100-ST-D"
  117         },
  118         {
  119                 PCI_ID_CODE(PCI_VENDOR_DYNALINK,0x1707),
  120                 -1,
  121                 -1,
  122                 "ASUSCOM P-IN100-ST-D"
  123         },
  124         {
  125                 PCI_ID_CODE(PCI_VENDOR_CITICORP,0x105E),
  126                 -1,
  127                 -1,
  128                 "ASUSCOM P-IN100-ST-D"
  129         },
  130 #endif
  131         {
  132                 PCI_ID_CODE(PCI_VENDOR_ASUSTEK,PCI_PRODUCT_ASUSTEK_HFCPCI),
  133                 0x144F,
  134                 0x2000,
  135                 "ASUSCOM P-IN100-ST-D"
  136         },
  137         {
  138                 PCI_ID_CODE(PCI_VENDOR_ASUSTEK,PCI_PRODUCT_ASUSTEK_HFCPCI),
  139                 0x144F,
  140                 0x1702,
  141                 "ASUSCOM P-IN100-ST-D"
  142         },
  143         {
  144                 PCI_ID_CODE(PCI_VENDOR_ASUSTEK,PCI_PRODUCT_ASUSTEK_HFCPCI),
  145                 0x144F,
  146                 0x1707,
  147                 "ASUSCOM P-IN100-ST-D"
  148         },
  149         {
  150                 PCI_ID_CODE(PCI_VENDOR_ASUSTEK,PCI_PRODUCT_ASUSTEK_HFCPCI),
  151                 0x1443,
  152                 0x1702,
  153                 "ASUSCOM P-IN100-ST-D"
  154         },
  155         {
  156                 PCI_ID_CODE(PCI_VENDOR_ASUSTEK,PCI_PRODUCT_ASUSTEK_HFCPCI),
  157                 0x1443,
  158                 0x1707,
  159                 "ASUSCOM P-IN100-ST-D"
  160         },
  161         {
  162                 PCI_ID_CODE(PCI_VENDOR_ASUSTEK,PCI_PRODUCT_ASUSTEK_HFCPCI),
  163                 0x144F,
  164                 0x2000,
  165                 "ASUSCOM P-IN100-ST-D"
  166         },
  167         {
  168                 PCI_ID_CODE(PCI_VENDOR_ASUSTEK,PCI_PRODUCT_ASUSTEK_HFCPCI),
  169                 0x144F,
  170                 0x2000,
  171                 "ASUSCOM P-IN100-ST-D"
  172         },
  173         {
  174                 PCI_ID_CODE(PCI_VENDOR_ASUSTEK,PCI_PRODUCT_ASUSTEK_HFCPCI),
  175                 0x144F,
  176                 0x2000,
  177                 "ASUSCOM P-IN100-ST-D"
  178         },
  179         {
  180                 0x00000000,
  181                 0,
  182                 0,
  183                 NULL
  184         }
  185 };
  186 
  187 static const char *
  188 iwic_find_card(const struct pci_attach_args * pa)
  189 {
  190         pcireg_t type = pa->pa_id;
  191         pcireg_t reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
  192         int sv = PCI_VENDOR(reg);
  193         int sd = PCI_PRODUCT(reg);
  194         struct winids *wip = win_ids;
  195 
  196         while (wip->type) {
  197                 if (wip->type == type) {
  198                         if (((wip->sv == -1) && (wip->sd == -1)) ||
  199                             ((wip->sv == sv) && (wip->sd == sd)))
  200                                 break;
  201                 }
  202                 ++wip;
  203         }
  204 
  205         if (wip->desc)
  206                 return wip->desc;
  207 
  208         return 0;
  209 }
  210 /*---------------------------------------------------------------------------*
  211  *      iwic PCI probe
  212  *---------------------------------------------------------------------------*/
  213 static int
  214 iwic_pci_probe(struct device * dev, struct cfdata * match, void *aux)
  215 {
  216         if (iwic_find_card(aux))
  217                 return 1;
  218 
  219         return 0;
  220 }
  221 /*---------------------------------------------------------------------------*
  222  *      PCI attach
  223  *---------------------------------------------------------------------------*/
  224 static void
  225 iwic_pci_attach(struct device * parent, struct device * dev, void *aux)
  226 {
  227         struct iwic_softc *sc = (void *) dev;
  228         struct iwic_bchan *bchan;
  229         pci_intr_handle_t ih;
  230         const char *intrstr;
  231         struct pci_attach_args *pa = aux;
  232         pci_chipset_tag_t pc = pa->pa_pc;
  233 
  234         sc->sc_cardname = iwic_find_card(pa);
  235 
  236         if (!sc->sc_cardname)
  237                 return;         /* Huh? */
  238 
  239         printf(": %s\n", sc->sc_cardname);
  240 
  241         if (pci_mapreg_map(pa, IWIC_PCI_IOBA, PCI_MAPREG_TYPE_IO, 0,
  242             &sc->sc_io_bt, &sc->sc_io_bh, &sc->sc_iobase, &sc->sc_iosize)) {
  243                 printf("%s: unable to map registers\n", sc->sc_dev.dv_xname);
  244                 return;
  245         }
  246         if (pci_intr_map(pa, &ih)) {
  247                 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
  248                 return;
  249         }
  250         intrstr = pci_intr_string(pc, ih);
  251         sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, iwic_pci_intr, sc);
  252         if (sc->sc_ih == NULL) {
  253                 printf("%s: couldn't establish interrupt", sc->sc_dev.dv_xname);
  254                 if (intrstr != NULL)
  255                         printf(" at %s", intrstr);
  256                 printf("\n");
  257                 return;
  258         }
  259         sc->sc_pc = pc;
  260         printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
  261 
  262         /* disable interrupts */
  263         IWIC_WRITE(sc, IWIC_IMASK, 0xff);
  264         IWIC_READ(sc, ISTA);
  265 
  266         iwic_dchan_init(sc);
  267 
  268         bchan = &sc->sc_bchan[IWIC_BCH_A];
  269         bchan->offset = B1_CHAN_OFFSET;
  270         bchan->channel = IWIC_BCH_A;
  271         bchan->state = ST_IDLE;
  272 
  273         iwic_bchannel_setup(sc, IWIC_BCH_A, BPROT_NONE, 0);
  274 
  275         bchan = &sc->sc_bchan[IWIC_BCH_B];
  276         bchan->offset = B2_CHAN_OFFSET;
  277         bchan->channel = IWIC_BCH_B;
  278         bchan->state = ST_IDLE;
  279 
  280         iwic_bchannel_setup(sc, IWIC_BCH_B, BPROT_NONE, 0);
  281 
  282         iwic_init_linktab(sc);
  283 
  284         iwic_attach_bri(sc);
  285 }
  286 /*---------------------------------------------------------------------------*
  287  *      IRQ handler
  288  *---------------------------------------------------------------------------*/
  289 static int
  290 iwic_pci_intr(void *p)
  291 {
  292         struct iwic_softc *sc = p;
  293 
  294         while (1) {
  295                 int irq_stat = IWIC_READ(sc, ISTA);
  296 
  297                 if (irq_stat == 0)
  298                         break;
  299 
  300                 if (irq_stat & (ISTA_D_RME | ISTA_D_RMR | ISTA_D_XFR)) {
  301                         iwic_dchan_xfer_irq(sc, irq_stat);
  302                 }
  303                 if (irq_stat & ISTA_D_EXI) {
  304                         iwic_dchan_xirq(sc);
  305                 }
  306                 if (irq_stat & ISTA_B1_EXI) {
  307                         iwic_bchan_xirq(sc, 0);
  308                 }
  309                 if (irq_stat & ISTA_B2_EXI) {
  310                         iwic_bchan_xirq(sc, 1);
  311                 }
  312         }
  313 
  314         return 0;
  315 }
  316 
  317 static int
  318 iwic_pci_activate(struct device * dev, enum devact act)
  319 {
  320         int error = EOPNOTSUPP;
  321 
  322         return error;
  323 }
  324 
  325 int iwic_ph_data_req(isdn_layer1token t, struct mbuf * m, int freeflag);
  326 int iwic_ph_activate_req(isdn_layer1token t);
  327 int iwic_mph_command_req(isdn_layer1token t, int command, void *parm);
  328 
  329 struct isdn_layer1_isdnif_driver iwic_bri_driver = {
  330         iwic_ph_data_req,
  331         iwic_ph_activate_req,
  332         iwic_mph_command_req
  333 };
  334 
  335 void iwic_set_link(void *, int channel, const struct isdn_l4_driver_functions * l4_driver, void *l4_driver_softc);
  336 isdn_link_t *iwic_ret_linktab(void *, int channel);
  337 
  338 /* XXX Should be prototyped in some header, not here XXX */
  339 void n_connect_request(struct call_desc * cd);
  340 void n_connect_response(struct call_desc * cd, int response, int cause);
  341 void n_disconnect_request(struct call_desc * cd, int cause);
  342 void n_alert_request(struct call_desc * cd);
  343 void n_mgmt_command(struct isdn_l3_driver * drv, int cmd, void *parm);
  344 
  345 const struct isdn_l3_driver_functions iwic_l3_driver = {
  346         iwic_ret_linktab,
  347         iwic_set_link,
  348         n_connect_request,
  349         n_connect_response,
  350         n_disconnect_request,
  351         n_alert_request,
  352         NULL,
  353         NULL,
  354         n_mgmt_command
  355 };
  356 
  357 static int
  358 iwic_attach_bri(struct iwic_softc * sc)
  359 {
  360         struct isdn_l3_driver *drv;
  361 
  362         drv = isdn_attach_isdnif(sc->sc_dev.dv_xname, sc->sc_cardname,
  363             &sc->sc_l2, &iwic_l3_driver, NBCH_BRI);
  364 
  365         sc->sc_l3token = drv;
  366         sc->sc_l2.driver = &iwic_bri_driver;
  367         sc->sc_l2.l1_token = sc;
  368         sc->sc_l2.drv = drv;
  369 
  370         isdn_layer2_status_ind(&sc->sc_l2, drv, STI_ATTACH, 1);
  371 
  372         isdn_isdnif_ready(drv->isdnif);
  373 
  374         return 1;
  375 }
  376 
  377 int
  378 iwic_ph_data_req(isdn_layer1token t, struct mbuf * m, int freeflag)
  379 {
  380         struct iwic_softc *sc = t;
  381 
  382         return iwic_dchan_data_req(sc, m, freeflag);
  383 }
  384 
  385 int
  386 iwic_ph_activate_req(isdn_layer1token t)
  387 {
  388         struct iwic_softc *sc = t;
  389 
  390         iwic_next_state(sc, EV_PHAR);
  391 
  392         return 0;
  393 }
  394 
  395 int
  396 iwic_mph_command_req(isdn_layer1token t, int command, void *parm)
  397 {
  398         struct iwic_softc *sc = t;
  399 
  400         switch (command) {
  401         case CMR_DOPEN: /* Daemon running */
  402                 NDBGL1(L1_PRIM, "CMR_DOPEN");
  403                 IWIC_WRITE(sc, IWIC_IMASK, IMASK_XINT0 | IMASK_XINT1);
  404                 break;
  405 
  406         case CMR_DCLOSE:        /* Daemon not running */
  407                 NDBGL1(L1_PRIM, "CMR_DCLOSE");
  408                 IWIC_WRITE(sc, IWIC_IMASK, 0xff);
  409                 break;
  410 
  411         case CMR_SETTRACE:
  412                 sc->sc_trace = (int)(intptr_t)parm;
  413                 NDBGL1(L1_PRIM, "CMR_SETTRACE, parm = %d", sc->sc_trace);
  414                 break;
  415 
  416         default:
  417                 NDBGL1(L1_PRIM, "unknown command = %d", command);
  418                 break;
  419         }
  420 
  421         return 0;
  422 }
  423 
  424 isdn_link_t *
  425 iwic_ret_linktab(void *t, int channel)
  426 {
  427         struct l2_softc *l2sc = t;
  428         struct iwic_softc *sc = l2sc->l1_token;
  429         struct iwic_bchan *bchan = &sc->sc_bchan[channel];
  430 
  431         return &bchan->iwic_isdn_linktab;
  432 }
  433 
  434 void
  435 iwic_set_link(void *t, int channel, const struct isdn_l4_driver_functions * l4_driver, void *l4_driver_softc)
  436 {
  437         struct l2_softc *l2sc = t;
  438         struct iwic_softc *sc = l2sc->l1_token;
  439         struct iwic_bchan *bchan = &sc->sc_bchan[channel];
  440 
  441         bchan->l4_driver = l4_driver;
  442         bchan->l4_driver_softc = l4_driver_softc;
  443 }

Cache object: d87b9fa8996dc901a4ac2709f099a2ee


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