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/iavc_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: iavc_pci.c,v 1.2 2003/10/03 16:38:44 pooka Exp $       */
    2 
    3 /*
    4  * Copyright (c) 2001-2003 Cubical Solutions Ltd.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  *
   28  * capi/iavc/iavc_pci.c
   29  *              The AVM ISDN controllers' PCI bus attachment handling.
   30  *
   31  * $FreeBSD: src/sys/i4b/capi/iavc/iavc_pci.c,v 1.1.2.1 2001/08/10 14:08:34 obrien Exp $
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 __KERNEL_RCSID(0, "$NetBSD: iavc_pci.c,v 1.2 2003/10/03 16:38:44 pooka 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/callout.h>
   42 #include <sys/socket.h>
   43 #include <sys/device.h>
   44 #include <net/if.h>
   45 
   46 #include <machine/bus.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_ioctl.h>
   53 #include <netisdn/i4b_l3l4.h>
   54 #include <netisdn/i4b_capi.h>
   55 
   56 #include <dev/ic/iavcvar.h>
   57 #include <dev/ic/iavcreg.h>
   58 
   59 struct iavc_pci_softc {
   60         struct iavc_softc sc_iavc;
   61 
   62         bus_addr_t mem_base;
   63         bus_size_t mem_size;
   64         bus_addr_t io_base;
   65         bus_size_t io_size;
   66 
   67         pci_chipset_tag_t sc_pc;
   68 
   69         void *sc_ih;            /* interrupt handler */
   70 };
   71 #define IAVC_PCI_IOBA   0x14
   72 #define IAVC_PCI_MMBA   0x10
   73 
   74 /* PCI driver linkage */
   75 
   76 static const struct iavc_pci_product *find_cardname(struct pci_attach_args *);
   77 
   78 static int iavc_pci_probe(struct device *, struct cfdata *, void *);
   79 static void iavc_pci_attach(struct device *, struct device *, void *);
   80 
   81 int iavc_pci_intr(void *);
   82 
   83 CFATTACH_DECL(iavc_pci, sizeof(struct iavc_softc),
   84     iavc_pci_probe, iavc_pci_attach, NULL, NULL);
   85 
   86 static const struct iavc_pci_product {
   87         pci_vendor_id_t npp_vendor;
   88         pci_product_id_t npp_product;
   89         const char *name;
   90 } iavc_pci_products[] = {
   91         { PCI_VENDOR_AVM, PCI_PRODUCT_AVM_B1, "AVM B1 PCI" },
   92         { PCI_VENDOR_AVM, PCI_PRODUCT_AVM_T1, "AVM T1 PCI" },
   93         { 0, 0, NULL },
   94 };
   95 
   96 static const struct iavc_pci_product *
   97 find_cardname(struct pci_attach_args * pa)
   98 {
   99         const struct iavc_pci_product *pp = NULL;
  100 
  101         for (pp = iavc_pci_products; pp->npp_vendor; pp++) {
  102                 if (PCI_VENDOR(pa->pa_id) == pp->npp_vendor &&
  103                     PCI_PRODUCT(pa->pa_id) == pp->npp_product)
  104                         return pp;
  105         }
  106 
  107         return NULL;
  108 }
  109 
  110 static int
  111 iavc_pci_probe(struct device * parent, struct cfdata * match, void *aux)
  112 {
  113         struct pci_attach_args *pa = aux;
  114 
  115         if (find_cardname(pa))
  116                 return 1;
  117 
  118         return 0;
  119 }
  120 
  121 static void
  122 iavc_pci_attach(struct device * parent, struct device * self, void *aux)
  123 {
  124         struct iavc_pci_softc *psc = (void *) self;
  125         struct iavc_softc *sc = (void *) self;
  126         struct pci_attach_args *pa = aux;
  127         pci_chipset_tag_t pc = pa->pa_pc;
  128         const struct iavc_pci_product *pp;
  129         pci_intr_handle_t ih;
  130         const char *intrstr;
  131         int ret;
  132 
  133         pp = find_cardname(pa);
  134         if (pp == NULL)
  135                 return;
  136 
  137         sc->sc_t1 = 0;
  138         sc->sc_dma = 0;
  139         sc->dmat = pa->pa_dmat;
  140 
  141         iavc_b1dma_reset(sc);
  142 
  143         if (pci_mapreg_map(pa, IAVC_PCI_IOBA, PCI_MAPREG_TYPE_IO, 0,
  144                 &sc->sc_io_bt, &sc->sc_io_bh, &psc->io_base, &psc->io_size)) {
  145                 aprint_error(": unable to map i/o registers\n");
  146                 return;
  147         }
  148 
  149         if (pci_mapreg_map(pa, IAVC_PCI_MMBA, PCI_MAPREG_TYPE_MEM, 0,
  150              &sc->sc_mem_bt, &sc->sc_mem_bh, &psc->mem_base, &psc->mem_size)) {
  151                 aprint_error(": unable to map mem registers\n");
  152                 return;
  153         }
  154         aprint_normal(": %s\n", pp->name);
  155 
  156         if (pp->npp_product == PCI_PRODUCT_AVM_T1) {
  157                 aprint_error("%s: sorry, PRI not yet supported\n",
  158                     sc->sc_dev.dv_xname);
  159                 return;
  160 
  161 #if 0
  162                 sc->sc_capi.card_type = CARD_TYPEC_AVM_T1_PCI;
  163                 sc->sc_capi.sc_nbch = NBCH_PRI;
  164                 ret = iavc_t1_detect(sc);
  165                 if (ret) {
  166                         if (ret < 6) {
  167                                 aprint_error("%s: no card detected?\n",
  168                                     sc->sc_dev.dv_xname);
  169                         } else {
  170                                 aprint_error("%s: black box not on\n",
  171                                     sc->sc_dev.dv_xname);
  172                         }
  173                         return;
  174                 } else {
  175                         sc->sc_dma = 1;
  176                         sc->sc_t1 = 1;
  177                 }
  178 #endif
  179 
  180         } else if (pp->npp_product == PCI_PRODUCT_AVM_B1) {
  181                 sc->sc_capi.card_type = CARD_TYPEC_AVM_B1_PCI;
  182                 sc->sc_capi.sc_nbch = NBCH_BRI;
  183                 ret = iavc_b1dma_detect(sc);
  184                 if (ret) {
  185                         ret = iavc_b1_detect(sc);
  186                         if (ret) {
  187                                 aprint_error("%s: no card detected?\n",
  188                                     sc->sc_dev.dv_xname);
  189                                 return;
  190                         }
  191                 } else {
  192                         sc->sc_dma = 1;
  193                 }
  194         }
  195         if (sc->sc_dma)
  196                 iavc_b1dma_reset(sc);
  197 
  198 #if 0
  199         /*
  200          * XXX: should really be done this way, but this freezes the card
  201          */
  202         if (sc->sc_t1)
  203                 iavc_t1_reset(sc);
  204         else
  205                 iavc_b1_reset(sc);
  206 #endif
  207 
  208         if (pci_intr_map(pa, &ih)) {
  209                 aprint_error("%s: couldn't map interrupt\n",
  210                     sc->sc_dev.dv_xname);
  211                 return;
  212         }
  213 
  214         intrstr = pci_intr_string(pc, ih);
  215         psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, iavc_pci_intr, psc);
  216         if (psc->sc_ih == NULL) {
  217                 aprint_error("%s: couldn't establish interrupt",
  218                     sc->sc_dev.dv_xname);
  219                 if (intrstr != NULL)
  220                         aprint_normal(" at %s", intrstr);
  221                 aprint_normal("\n");
  222                 return;
  223         }
  224         psc->sc_pc = pc;
  225         aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
  226 
  227         memset(&sc->sc_txq, 0, sizeof(struct ifqueue));
  228         sc->sc_txq.ifq_maxlen = sc->sc_capi.sc_nbch * 4;
  229 
  230         sc->sc_intr = 0;
  231         sc->sc_state = IAVC_DOWN;
  232         sc->sc_blocked = 0;
  233 
  234         /* setup capi link */
  235         sc->sc_capi.load = iavc_load;
  236         sc->sc_capi.reg_appl = iavc_register;
  237         sc->sc_capi.rel_appl = iavc_release;
  238         sc->sc_capi.send = iavc_send;
  239         sc->sc_capi.ctx = (void *) sc;
  240 
  241         /* lock & load DMA for TX */
  242         if ((ret = bus_dmamem_alloc(sc->dmat, IAVC_DMA_SIZE, PAGE_SIZE, 0,
  243             &sc->txseg, 1, &sc->ntxsegs, BUS_DMA_ALLOCNOW)) != 0) {
  244                 aprint_error("%s: can't allocate tx DMA memory, error = %d\n",
  245                     sc->sc_dev.dv_xname, ret);
  246                 goto fail1;
  247         }
  248 
  249         if ((ret = bus_dmamem_map(sc->dmat, &sc->txseg, sc->ntxsegs,
  250             IAVC_DMA_SIZE, &sc->sc_sendbuf, BUS_DMA_NOWAIT)) != 0) {
  251                 aprint_error("%s: can't map tx DMA memory, error = %d\n",
  252                     sc->sc_dev.dv_xname, ret);
  253                 goto fail2;
  254         }
  255 
  256         if ((ret = bus_dmamap_create(sc->dmat, IAVC_DMA_SIZE, 1,
  257             IAVC_DMA_SIZE, 0, BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT,
  258             &sc->tx_map)) != 0) {
  259                 aprint_error("%s: can't create tx DMA map, error = %d\n",
  260                     sc->sc_dev.dv_xname, ret);
  261                 goto fail3;
  262         }
  263 
  264         if ((ret = bus_dmamap_load(sc->dmat, sc->tx_map, sc->sc_sendbuf,
  265             IAVC_DMA_SIZE, NULL, BUS_DMA_WRITE | BUS_DMA_NOWAIT)) != 0) {
  266                 aprint_error("%s: can't load tx DMA map, error = %d\n",
  267                     sc->sc_dev.dv_xname, ret);
  268                 goto fail4;
  269         }
  270 
  271         /* do the same for RX */
  272         if ((ret = bus_dmamem_alloc(sc->dmat, IAVC_DMA_SIZE, PAGE_SIZE, 0,
  273             &sc->rxseg, 1, &sc->nrxsegs, BUS_DMA_ALLOCNOW)) != 0) {
  274                 aprint_error("%s: can't allocate rx DMA memory, error = %d\n",
  275                     sc->sc_dev.dv_xname, ret);
  276                 goto fail5;
  277         }
  278 
  279         if ((ret = bus_dmamem_map(sc->dmat, &sc->rxseg, sc->nrxsegs,
  280             IAVC_DMA_SIZE, &sc->sc_recvbuf, BUS_DMA_NOWAIT)) != 0) {
  281                 aprint_error("%s: can't map rx DMA memory, error = %d\n",
  282                     sc->sc_dev.dv_xname, ret);
  283                 goto fail6;
  284         }
  285 
  286         if ((ret = bus_dmamap_create(sc->dmat, IAVC_DMA_SIZE, 1, IAVC_DMA_SIZE,
  287             0, BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, &sc->rx_map)) != 0) {
  288                 aprint_error("%s: can't create rx DMA map, error = %d\n",
  289                     sc->sc_dev.dv_xname, ret);
  290                 goto fail7;
  291         }
  292 
  293         if ((ret = bus_dmamap_load(sc->dmat, sc->rx_map, sc->sc_recvbuf,
  294             IAVC_DMA_SIZE, NULL, BUS_DMA_READ | BUS_DMA_NOWAIT)) != 0) {
  295                 aprint_error("%s: can't load rx DMA map, error = %d\n",
  296                     sc->sc_dev.dv_xname, ret);
  297                 goto fail8;
  298         }
  299 
  300         if (capi_ll_attach(&sc->sc_capi, sc->sc_dev.dv_xname, pp->name)) {
  301                 aprint_error("%s: capi attach failed\n", sc->sc_dev.dv_xname);
  302                 goto fail9;
  303         }
  304         return;
  305 
  306         /* release resources in case of failed attach */
  307 fail9:
  308         bus_dmamap_unload(sc->dmat, sc->rx_map);
  309 fail8:
  310         bus_dmamap_destroy(sc->dmat, sc->rx_map);
  311 fail7:
  312         bus_dmamem_unmap(sc->dmat, sc->sc_recvbuf, IAVC_DMA_SIZE);
  313 fail6:
  314         bus_dmamem_free(sc->dmat, &sc->rxseg, sc->nrxsegs);
  315 fail5:
  316         bus_dmamap_unload(sc->dmat, sc->tx_map);
  317 fail4:
  318         bus_dmamap_destroy(sc->dmat, sc->tx_map);
  319 fail3:
  320         bus_dmamem_unmap(sc->dmat, sc->sc_sendbuf, IAVC_DMA_SIZE);
  321 fail2:
  322         bus_dmamem_free(sc->dmat, &sc->txseg, sc->ntxsegs);
  323 fail1:
  324         pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
  325 
  326         return;
  327 }
  328 
  329 int
  330 iavc_pci_intr(void *arg)
  331 {
  332         struct iavc_softc *sc = arg;
  333 
  334         return iavc_handle_intr(sc);
  335 }
  336 
  337 #if 0
  338 static int
  339 iavc_pci_detach(struct device * self, int flags)
  340 {
  341         struct iavc_pci_softc *psc = (void *) self;
  342 
  343         bus_space_unmap(psc->sc_iavc.sc_mem_bt, psc->sc_iavc.sc_mem_bh,
  344             psc->mem_size);
  345         bus_space_free(psc->sc_iavc.sc_mem_bt, psc->sc_iavc.sc_mem_bh,
  346             psc->mem_size);
  347         bus_space_unmap(psc->sc_iavc.sc_io_bt, psc->sc_iavc.sc_io_bh,
  348             psc->io_size);
  349         bus_space_free(psc->sc_iavc.sc_io_bt, psc->sc_iavc.sc_io_bh,
  350             psc->io_size);
  351 
  352         pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
  353 
  354         /* XXX: capi detach?!? */
  355 
  356         return 0;
  357 }
  358 
  359 static int
  360 iavc_pci_activate(struct device * self, enum devact act)
  361 {
  362         struct iavc_softc *psc = (struct iavc_softc *) self;
  363         int error, s;
  364 
  365         error = 0;
  366 
  367         s = splnet();
  368         switch (act) {
  369         case DVACT_ACTIVATE:
  370                 error = EOPNOTSUPP;
  371                 break;
  372         case DVACT_DEACTIVATE:
  373                 /* XXX */
  374                 break;
  375         }
  376 
  377         splx(s);
  378 
  379         return error;
  380 }
  381 #endif

Cache object: d052e89b9ccf05cf16a7200069b2a0b4


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