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/cardbus/puc_cardbus.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 /*      $OpenBSD: puc_cardbus.c,v 1.9 2022/04/06 18:59:28 naddy Exp $   */
    2 
    3 /*
    4  * Copyright (c) 2006 Michael Shalayeff
    5  * All rights reserved.
    6  *
    7  * Permission to use, copy, modify, and distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
   16  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
   17  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  */
   19 
   20 #include <sys/param.h>
   21 #include <sys/systm.h>
   22 #include <sys/device.h>
   23 #include <sys/tty.h>
   24 
   25 #include <machine/bus.h>
   26 #include <dev/ic/comvar.h>
   27 
   28 #include <dev/pci/pcireg.h>
   29 #include <dev/pci/pcivar.h>
   30 #include <dev/pci/pcidevs.h>
   31 #include <dev/cardbus/cardbusvar.h>
   32 
   33 #include <dev/pci/pucvar.h>
   34 
   35 struct puc_cardbus_softc {
   36         struct puc_softc sc_psc;
   37 
   38         struct cardbus_devfunc *ct;
   39         int intrline;
   40 };
   41 
   42 int     puc_cardbus_match(struct device *, void *, void *);
   43 void    puc_cardbus_attach(struct device *, struct device *, void *);
   44 int     puc_cardbus_detach(struct device *, int);
   45 
   46 const char *puc_cardbus_intr_string(struct puc_attach_args *);
   47 void *puc_cardbus_intr_establish(struct puc_attach_args *, int,
   48     int (*)(void *), void *, char *);
   49 
   50 const struct cfattach puc_cardbus_ca = {
   51         sizeof(struct puc_cardbus_softc), puc_cardbus_match,
   52         puc_cardbus_attach, puc_cardbus_detach
   53 };
   54 
   55 int
   56 puc_cardbus_match(struct device *parent, void *match, void *aux)
   57 {
   58         struct cardbus_attach_args *ca = aux;
   59         pci_chipset_tag_t pc = ca->ca_pc;
   60         pcireg_t bhlc, reg;
   61 
   62         bhlc = pci_conf_read(pc, ca->ca_tag, PCI_BHLC_REG);
   63         if (PCI_HDRTYPE_TYPE(bhlc) != 0)
   64                 return(0);
   65 
   66         /* this one is some sort of a bridge and not a puc */
   67         if (PCI_VENDOR(ca->ca_id) == PCI_VENDOR_OXFORD2 &&
   68             PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_OXFORD2_EXSYS_EX41098)
   69                 return (0);
   70 
   71         reg = pci_conf_read(pc, ca->ca_tag, PCI_SUBSYS_ID_REG);
   72         if (puc_find_description(PCI_VENDOR(ca->ca_id),
   73             PCI_PRODUCT(ca->ca_id), PCI_VENDOR(reg), PCI_PRODUCT(reg)))
   74                 return (10);
   75 
   76         return (0);
   77 }
   78 
   79 void
   80 puc_cardbus_attach(struct device *parent, struct device *self, void *aux)
   81 {
   82         struct puc_cardbus_softc *csc = (struct puc_cardbus_softc *)self;
   83         struct puc_softc *sc = &csc->sc_psc;
   84         struct cardbus_attach_args *ca = aux;
   85         struct cardbus_devfunc *ct = ca->ca_ct;
   86         cardbus_chipset_tag_t cc = ct->ct_cc;
   87         pci_chipset_tag_t pc = ca->ca_pc;
   88         cardbus_function_tag_t cf = ct->ct_cf;
   89         struct puc_attach_args paa;
   90         pcireg_t reg;
   91         int i;
   92 
   93         Cardbus_function_enable(ct);
   94 
   95         csc->ct = ct;
   96 
   97         reg = pci_conf_read(pc, ca->ca_tag, PCI_SUBSYS_ID_REG);
   98         sc->sc_desc = puc_find_description(PCI_VENDOR(ca->ca_id),
   99             PCI_PRODUCT(ca->ca_id), PCI_VENDOR(reg), PCI_PRODUCT(reg));
  100 
  101         puc_print_ports(sc->sc_desc);
  102 
  103         /* the fifth one is some memory we dunno */
  104         for (i = 0; i < PUC_NBARS; i++) {
  105                 pcireg_t type;
  106                 int bar;
  107 
  108                 sc->sc_bar_mappings[i].mapped = 0;
  109                 bar = PCI_MAPREG_START + 4 * i;
  110                 if (!pci_mapreg_probe(pc, ca->ca_tag, bar, &type))
  111                         continue;
  112 
  113                 if (!(sc->sc_bar_mappings[i].mapped = !Cardbus_mapreg_map(ct,
  114                     bar, type, 0,
  115                     &sc->sc_bar_mappings[i].t, &sc->sc_bar_mappings[i].h,
  116                     &sc->sc_bar_mappings[i].a, &sc->sc_bar_mappings[i].s)))
  117                         printf("%s: couldn't map BAR at offset 0x%lx\n",
  118                             sc->sc_dev.dv_xname, (long)bar);
  119                 sc->sc_bar_mappings[i].type = type;
  120         }
  121 
  122         csc->intrline = ca->ca_intrline;
  123 
  124         if (pci_get_capability(pc, ca->ca_tag, PCI_CAP_PWRMGMT, &reg,
  125             0)) {
  126                 reg = pci_conf_read(pc, ca->ca_tag, reg + 4) & 3;
  127                 if (reg) {
  128                         printf("%s: awakening from state D%d\n",
  129                             sc->sc_dev.dv_xname, reg);
  130                         pci_conf_write(pc, ca->ca_tag, reg + 4, 0);
  131                 }
  132         }
  133 
  134         (*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
  135         (*cf->cardbus_ctrl)(cc, CARDBUS_IO_ENABLE);
  136         (*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
  137 
  138         paa.puc = sc;
  139         paa.intr_string = &puc_cardbus_intr_string;
  140         paa.intr_establish = &puc_cardbus_intr_establish;
  141 
  142         puc_common_attach(sc, &paa);
  143 }
  144 
  145 const char *
  146 puc_cardbus_intr_string(struct puc_attach_args *paa)
  147 {
  148         struct puc_cardbus_softc *sc = paa->puc;
  149         static char str[16];
  150 
  151         snprintf(str, sizeof str, "irq %d", sc->intrline);
  152         return (str);
  153 }
  154 
  155 void *
  156 puc_cardbus_intr_establish(struct puc_attach_args *paa, int type,
  157     int (*func)(void *), void *arg, char *name)
  158 {
  159         struct puc_cardbus_softc *sc = paa->puc;
  160         struct puc_softc *psc = &sc->sc_psc;
  161         struct cardbus_devfunc *ct = sc->ct;
  162 
  163         psc->sc_ports[paa->port].intrhand =
  164             cardbus_intr_establish(ct->ct_cc, ct->ct_cf, sc->intrline,
  165                 type, func, arg, name);
  166 
  167         return (psc->sc_ports[paa->port].intrhand);
  168 }
  169 
  170 int
  171 puc_cardbus_detach(struct device *self, int flags)
  172 {
  173         struct puc_cardbus_softc *sc = (struct puc_cardbus_softc *)self;
  174         struct puc_softc *psc = &sc->sc_psc;
  175         struct cardbus_devfunc *ct = sc->ct;
  176         int i, rv;
  177 
  178         for (i = PUC_MAX_PORTS; i--; ) {
  179                 if (psc->sc_ports[i].intrhand)
  180                         cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf,
  181                             psc->sc_ports[i].intrhand);
  182                 if (psc->sc_ports[i].dev)
  183                         if ((rv = config_detach(psc->sc_ports[i].dev, flags)))
  184                                 return (rv);
  185         }
  186 
  187         for (i = PUC_NBARS; i--; )
  188                 if (psc->sc_bar_mappings[i].mapped)
  189                         Cardbus_mapreg_unmap(ct, psc->sc_bar_mappings[i].type,
  190                             psc->sc_bar_mappings[i].t,
  191                             psc->sc_bar_mappings[i].h,
  192                             psc->sc_bar_mappings[i].s);
  193 
  194         return (0);
  195 }

Cache object: 9ae4ce2c684925dad6ca969b78692464


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