root/dev/cardbus/puc_cardbus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. puc_cardbus_match
  2. puc_cardbus_attach
  3. puc_cardbus_intr_string
  4. puc_cardbus_intr_establish
  5. puc_cardbus_detach

    1 /*      $OpenBSD: puc_cardbus.c,v 1.2 2006/10/12 16:35:52 grange 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 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         struct cardbus_devfunc *ct = ca->ca_ct;
   60         cardbus_chipset_tag_t cc = ct->ct_cc;
   61         cardbus_function_tag_t cf = ct->ct_cf;
   62         cardbusreg_t bhlc, reg;
   63 
   64         bhlc = cardbus_conf_read(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG);
   65         if (PCI_HDRTYPE_TYPE(bhlc) != 0)
   66                 return(0);
   67 
   68         /* this one is some sort of a bridge and not a puc */
   69         if (PCI_VENDOR(ca->ca_id) == PCI_VENDOR_OXFORD2 &&
   70             PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_OXFORD2_EXSYS_EX41098)
   71                 return (0);
   72 
   73         reg = cardbus_conf_read(cc, cf, ca->ca_tag, PCI_SUBSYS_ID_REG);
   74         if (puc_find_description(PCI_VENDOR(ca->ca_id),
   75             PCI_PRODUCT(ca->ca_id), PCI_VENDOR(reg), PCI_PRODUCT(reg)))
   76                 return (10);
   77 
   78         return (0);
   79 }
   80 
   81 void
   82 puc_cardbus_attach(struct device *parent, struct device *self, void *aux)
   83 {
   84         struct puc_cardbus_softc *csc = (struct puc_cardbus_softc *)self;
   85         struct puc_softc *sc = &csc->sc_psc;
   86         struct cardbus_attach_args *ca = aux;
   87         struct cardbus_devfunc *ct = ca->ca_ct;
   88         cardbus_chipset_tag_t cc = ct->ct_cc;
   89         cardbus_function_tag_t cf = ct->ct_cf;
   90         struct puc_attach_args paa;
   91         cardbusreg_t reg;
   92         int i;
   93 
   94         Cardbus_function_enable(ct);
   95 
   96         csc->ct = ct;
   97 
   98         reg = cardbus_conf_read(cc, cf, ca->ca_tag, PCI_SUBSYS_ID_REG);
   99         sc->sc_desc = puc_find_description(PCI_VENDOR(ca->ca_id),
  100             PCI_PRODUCT(ca->ca_id), PCI_VENDOR(reg), PCI_PRODUCT(reg));
  101 
  102         puc_print_ports(sc->sc_desc);
  103 
  104         /* the fifth one is some memory we dunno */
  105         for (i = 0; i < PUC_NBARS; i++) {
  106                 cardbusreg_t type;
  107                 int bar;
  108 
  109                 sc->sc_bar_mappings[i].mapped = 0;
  110                 bar = PCI_MAPREG_START + 4 * i;
  111                 if (!cardbus_mapreg_probe(cc, cf, ca->ca_tag, bar, &type))
  112                         continue;
  113 
  114                 if (!(sc->sc_bar_mappings[i].mapped = !Cardbus_mapreg_map(ct,
  115                     bar, type, 0,
  116                     &sc->sc_bar_mappings[i].t, &sc->sc_bar_mappings[i].h,
  117                     &sc->sc_bar_mappings[i].a, &sc->sc_bar_mappings[i].s)))
  118                         printf("%s: couldn't map BAR at offset 0x%lx\n",
  119                             sc->sc_dev.dv_xname, (long)bar);
  120                 sc->sc_bar_mappings[i].type = type;
  121         }
  122 
  123         csc->intrline = ca->ca_intrline;
  124 
  125         if (cardbus_get_capability(cc, cf, ca->ca_tag, PCI_CAP_PWRMGMT, &reg,
  126             0)) {
  127                 reg = cardbus_conf_read(cc, cf, ca->ca_tag, reg + 4) & 3;
  128                 if (reg) {
  129                         printf("%s: awakening from state D%d\n",
  130                             sc->sc_dev.dv_xname, reg);
  131                         cardbus_conf_write(cc, cf, ca->ca_tag, reg + 4, 0);
  132                 }
  133         }
  134 
  135         (*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
  136         (*cf->cardbus_ctrl)(cc, CARDBUS_IO_ENABLE);
  137         (*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
  138 
  139         paa.puc = sc;
  140         paa.hwtype = COM_UART_OX16C950;         /* XXX */
  141         paa.intr_string = &puc_cardbus_intr_string;
  142         paa.intr_establish = &puc_cardbus_intr_establish;
  143         puc_common_attach(sc, &paa);
  144 }
  145 
  146 const char *
  147 puc_cardbus_intr_string(struct puc_attach_args *paa)
  148 {
  149         struct puc_cardbus_softc *sc = paa->puc;
  150         static char str[16];
  151 
  152         snprintf(str, sizeof str, "irq %d", sc->intrline);
  153         return (str);
  154 }
  155 
  156 void *
  157 puc_cardbus_intr_establish(struct puc_attach_args *paa, int type,
  158     int (*func)(void *), void *arg, char *name)
  159 {
  160         struct puc_cardbus_softc *sc = paa->puc;
  161         struct cardbus_devfunc *ct = sc->ct;
  162 
  163         return (cardbus_intr_establish(ct->ct_cc, ct->ct_cf, sc->intrline,
  164             type, func, arg, name));
  165 }
  166 
  167 int
  168 puc_cardbus_detach(struct device *self, int flags)
  169 {
  170         struct puc_cardbus_softc *csc = (struct puc_cardbus_softc *)self;
  171         struct puc_softc *sc = &csc->sc_psc;
  172         struct cardbus_devfunc *ct = csc->ct;
  173         int i, rv;
  174 
  175         for (i = PUC_MAX_PORTS; i--; )
  176                 if (sc->sc_ports[i].dev)
  177                         if ((rv = config_detach(sc->sc_ports[i].dev, flags)))
  178                                 return (rv);
  179 
  180         for (i = PUC_NBARS; i--; )
  181                 if (sc->sc_bar_mappings[i].mapped)
  182                         Cardbus_mapreg_unmap(ct, sc->sc_bar_mappings[i].type,
  183                             sc->sc_bar_mappings[i].t, sc->sc_bar_mappings[i].h,
  184                             sc->sc_bar_mappings[i].s);
  185 
  186         return (0);
  187 }

/* [<][>][^][v][top][bottom][index][help] */