[BACK]Return to ppb.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/ppb.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ppb.c,v 1.19 2007/05/21 22:10:45 kettenis Exp $       */
                      2: /*     $NetBSD: ppb.c,v 1.16 1997/06/06 23:48:05 thorpej Exp $ */
                      3:
                      4: /*
                      5:  * Copyright (c) 1996 Christopher G. Demetriou.  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:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *      This product includes software developed by Christopher G. Demetriou
                     18:  *     for the NetBSD Project.
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  */
                     33:
                     34: #include <sys/param.h>
                     35: #include <sys/systm.h>
                     36: #include <sys/kernel.h>
                     37: #include <sys/device.h>
                     38:
                     39: #include <dev/pci/pcireg.h>
                     40: #include <dev/pci/pcivar.h>
                     41: #include <dev/pci/pcidevs.h>
                     42: #include <dev/pci/ppbreg.h>
                     43:
                     44: struct ppb_softc {
                     45:        struct device sc_dev;           /* generic device glue */
                     46:        pci_chipset_tag_t sc_pc;        /* our PCI chipset... */
                     47:        pcitag_t sc_tag;                /* ...and tag. */
                     48:        pci_intr_handle_t sc_ih[4];
                     49: };
                     50:
                     51: int    ppbmatch(struct device *, void *, void *);
                     52: void   ppbattach(struct device *, struct device *, void *);
                     53:
                     54: struct cfattach ppb_ca = {
                     55:        sizeof(struct ppb_softc), ppbmatch, ppbattach
                     56: };
                     57:
                     58: struct cfdriver ppb_cd = {
                     59:        NULL, "ppb", DV_DULL
                     60: };
                     61:
                     62: int    ppbprint(void *, const char *pnp);
                     63:
                     64: int
                     65: ppbmatch(struct device *parent, void *match, void *aux)
                     66: {
                     67:        struct pci_attach_args *pa = aux;
                     68:
                     69:        /*
                     70:         * This device is mislabeled.  It is not a PCI bridge.
                     71:         */
                     72:        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VIATECH &&
                     73:            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT82C586_PWR)
                     74:                return (0);
                     75:        /*
                     76:         * Check the ID register to see that it's a PCI bridge.
                     77:         * If it is, we assume that we can deal with it; it _should_
                     78:         * work in a standardized way...
                     79:         */
                     80:        if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
                     81:            PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_PCI)
                     82:                return (1);
                     83:
                     84:        return (0);
                     85: }
                     86:
                     87: void
                     88: ppbattach(struct device *parent, struct device *self, void *aux)
                     89: {
                     90:        struct ppb_softc *sc = (void *) self;
                     91:        struct pci_attach_args *pa = aux;
                     92:        pci_chipset_tag_t pc = pa->pa_pc;
                     93:        struct pcibus_attach_args pba;
                     94:        pcireg_t busdata;
                     95:        int pin;
                     96:
                     97:        printf("\n");
                     98:
                     99:        sc->sc_pc = pc;
                    100:        sc->sc_tag = pa->pa_tag;
                    101:
                    102:        busdata = pci_conf_read(pc, pa->pa_tag, PPB_REG_BUSINFO);
                    103:
                    104:        if (PPB_BUSINFO_SECONDARY(busdata) == 0) {
                    105:                printf("%s: not configured by system firmware\n",
                    106:                    self->dv_xname);
                    107:                return;
                    108:        }
                    109:
                    110:        for (pin = PCI_INTERRUPT_PIN_A; pin <= PCI_INTERRUPT_PIN_D; pin++) {
                    111:                pa->pa_intrpin = pa->pa_rawintrpin = pin;
                    112:                pa->pa_intrline = 0;
                    113:                pci_intr_map(pa, &sc->sc_ih[pin - PCI_INTERRUPT_PIN_A]);
                    114:        }
                    115:
                    116: #if 0
                    117:        /*
                    118:         * XXX can't do this, because we're not given our bus number
                    119:         * (we shouldn't need it), and because we've no way to
                    120:         * decompose our tag.
                    121:         */
                    122:        /* sanity check. */
                    123:        if (pa->pa_bus != PPB_BUSINFO_PRIMARY(busdata))
                    124:                panic("ppbattach: bus in tag (%d) != bus in reg (%d)",
                    125:                    pa->pa_bus, PPB_BUSINFO_PRIMARY(busdata));
                    126: #endif
                    127:
                    128:        /*
                    129:         * Attach the PCI bus that hangs off of it.
                    130:         *
                    131:         * XXX Don't pass-through Memory Read Multiple.  Should we?
                    132:         * XXX Consult the spec...
                    133:         */
                    134:        pba.pba_busname = "pci";
                    135:        pba.pba_iot = pa->pa_iot;
                    136:        pba.pba_memt = pa->pa_memt;
                    137:        pba.pba_dmat = pa->pa_dmat;
                    138:        pba.pba_pc = pc;
                    139: #if 0
                    140:        pba.pba_flags = pa->pa_flags & ~PCI_FLAGS_MRM_OKAY;
                    141: #endif
                    142:        pba.pba_domain = pa->pa_domain;
                    143:        pba.pba_bus = PPB_BUSINFO_SECONDARY(busdata);
                    144:        pba.pba_bridgeih = sc->sc_ih;
                    145:        pba.pba_bridgetag = &sc->sc_tag;
                    146:        pba.pba_intrswiz = pa->pa_intrswiz;
                    147:        pba.pba_intrtag = pa->pa_intrtag;
                    148:
                    149:        config_found(self, &pba, ppbprint);
                    150: }
                    151:
                    152: int
                    153: ppbprint(void *aux, const char *pnp)
                    154: {
                    155:        struct pcibus_attach_args *pba = aux;
                    156:
                    157:        /* only PCIs can attach to PPBs; easy. */
                    158:        if (pnp)
                    159:                printf("pci at %s", pnp);
                    160:        printf(" bus %d", pba->pba_bus);
                    161:        return (UNCONF);
                    162: }

CVSweb