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

Annotation of sys/dev/pci/siop_pci_common.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: siop_pci_common.c,v 1.15 2006/04/20 20:31:12 miod Exp $ */
        !             2: /*     $NetBSD: siop_pci_common.c,v 1.25 2005/06/28 00:28:42 thorpej Exp $ */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 2000 Manuel Bouyer.
        !             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 Manuel Bouyer.
        !            18:  * 4. The name of the author may not be used to endorse or promote products
        !            19:  *    derived from this software without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            31:  */
        !            32:
        !            33: /* SYM53c8xx PCI-SCSI I/O Processors driver: PCI front-end */
        !            34:
        !            35: #include <sys/param.h>
        !            36: #include <sys/systm.h>
        !            37: #include <sys/device.h>
        !            38: #include <sys/malloc.h>
        !            39: #include <sys/buf.h>
        !            40: #include <sys/kernel.h>
        !            41:
        !            42: #include <machine/endian.h>
        !            43:
        !            44: #include <dev/pci/pcireg.h>
        !            45: #include <dev/pci/pcivar.h>
        !            46: #include <dev/pci/pcidevs.h>
        !            47:
        !            48: #include <scsi/scsi_all.h>
        !            49: #include <scsi/scsiconf.h>
        !            50:
        !            51: #include <dev/ic/siopreg.h>
        !            52: #include <dev/ic/siopvar_common.h>
        !            53: #include <dev/pci/siop_pci_common.h>
        !            54:
        !            55: /* List (array, really :) of chips we know how to handle */
        !            56: const struct siop_product_desc siop_products[] = {
        !            57:        { PCI_PRODUCT_SYMBIOS_810,
        !            58:        0x00,
        !            59:        SF_PCI_RL | SF_CHIP_LS,
        !            60:        4, 8, 3, 250, 0
        !            61:        },
        !            62:        { PCI_PRODUCT_SYMBIOS_810,
        !            63:        0x10,
        !            64:        SF_PCI_RL | SF_PCI_BOF | SF_CHIP_PF | SF_CHIP_LS,
        !            65:        4, 8, 3, 250, 0
        !            66:        },
        !            67:        { PCI_PRODUCT_SYMBIOS_815,
        !            68:        0x00,
        !            69:        SF_PCI_RL | SF_PCI_BOF,
        !            70:        4, 8, 3, 250, 0
        !            71:        },
        !            72:        { PCI_PRODUCT_SYMBIOS_820,
        !            73:        0x00,
        !            74:        SF_PCI_RL | SF_CHIP_LS | SF_BUS_WIDE,
        !            75:        4, 8, 3, 250, 0
        !            76:        },
        !            77:        { PCI_PRODUCT_SYMBIOS_825,
        !            78:        0x00,
        !            79:        SF_PCI_RL | SF_PCI_BOF | SF_BUS_WIDE,
        !            80:        4, 8, 3, 250, 0
        !            81:        },
        !            82:        { PCI_PRODUCT_SYMBIOS_825,
        !            83:        0x10,
        !            84:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !            85:        SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_LS | SF_CHIP_10REGS |
        !            86:        SF_BUS_WIDE,
        !            87:        7, 8, 3, 250, 4096
        !            88:        },
        !            89:        { PCI_PRODUCT_SYMBIOS_860,
        !            90:        0x00,
        !            91:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !            92:        SF_CHIP_PF | SF_CHIP_LS |
        !            93:        SF_BUS_ULTRA,
        !            94:        4, 8, 5, 125, 0
        !            95:        },
        !            96:        { PCI_PRODUCT_SYMBIOS_875,
        !            97:        0x00,
        !            98:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !            99:        SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_LS | SF_CHIP_10REGS |
        !           100:        SF_BUS_ULTRA | SF_BUS_WIDE,
        !           101:        7, 16, 5, 125, 4096
        !           102:        },
        !           103:        { PCI_PRODUCT_SYMBIOS_875,
        !           104:        0x02,
        !           105:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !           106:        SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_DBLR |
        !           107:        SF_CHIP_LS | SF_CHIP_10REGS |
        !           108:        SF_BUS_ULTRA | SF_BUS_WIDE,
        !           109:        7, 16, 5, 125, 4096
        !           110:        },
        !           111:        { PCI_PRODUCT_SYMBIOS_875J,
        !           112:        0x00,
        !           113:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !           114:        SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_DBLR |
        !           115:        SF_CHIP_LS | SF_CHIP_10REGS |
        !           116:        SF_BUS_ULTRA | SF_BUS_WIDE,
        !           117:        7, 16, 5, 125, 4096
        !           118:        },
        !           119:        { PCI_PRODUCT_SYMBIOS_885,
        !           120:        0x00,
        !           121:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !           122:        SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_DBLR |
        !           123:        SF_CHIP_LS | SF_CHIP_10REGS |
        !           124:        SF_BUS_ULTRA | SF_BUS_WIDE,
        !           125:        7, 16, 5, 125, 4096
        !           126:        },
        !           127:        { PCI_PRODUCT_SYMBIOS_895,
        !           128:        0x00,
        !           129:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !           130:        SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
        !           131:        SF_CHIP_LS | SF_CHIP_10REGS |
        !           132:        SF_BUS_ULTRA2 | SF_BUS_WIDE,
        !           133:        7, 31, 7, 62, 4096
        !           134:        },
        !           135:        { PCI_PRODUCT_SYMBIOS_896,
        !           136:        0x00,
        !           137:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !           138:        SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
        !           139:        SF_CHIP_LS | SF_CHIP_10REGS |
        !           140:        SF_BUS_ULTRA2 | SF_BUS_WIDE,
        !           141:        7, 31, 7, 62, 8192
        !           142:        },
        !           143:        { PCI_PRODUCT_SYMBIOS_895A,
        !           144:        0x00,
        !           145:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !           146:        SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
        !           147:        SF_CHIP_LS | SF_CHIP_10REGS |
        !           148:        SF_BUS_ULTRA2 | SF_BUS_WIDE,
        !           149:        7, 31, 7, 62, 8192
        !           150:        },
        !           151:        { PCI_PRODUCT_SYMBIOS_1010,
        !           152:        0x00,
        !           153:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !           154:        SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM |
        !           155:        SF_CHIP_LS | SF_CHIP_10REGS | SF_CHIP_DFBC | SF_CHIP_DBLR |
        !           156:        SF_CHIP_GEBUG |
        !           157:        SF_BUS_ULTRA3 | SF_BUS_WIDE,
        !           158:        7, 31, 0, 62, 8192
        !           159:        },
        !           160:        { PCI_PRODUCT_SYMBIOS_1010,
        !           161:        0x01,
        !           162:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !           163:        SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM |
        !           164:        SF_CHIP_LS | SF_CHIP_10REGS | SF_CHIP_DFBC | SF_CHIP_DBLR | SF_CHIP_DT |
        !           165:        SF_CHIP_GEBUG |
        !           166:        SF_BUS_ULTRA3 | SF_BUS_WIDE,
        !           167:        7, 62, 0, 62, 8192
        !           168:        },
        !           169:        { PCI_PRODUCT_SYMBIOS_1010_2,
        !           170:        0x00,
        !           171:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !           172:        SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM |
        !           173:        SF_CHIP_LS | SF_CHIP_10REGS | SF_CHIP_DFBC | SF_CHIP_DBLR | SF_CHIP_DT |
        !           174:        SF_CHIP_AAIP |
        !           175:        SF_BUS_ULTRA3 | SF_BUS_WIDE,
        !           176:        7, 62, 0, 62, 8192
        !           177:        },
        !           178:        { PCI_PRODUCT_SYMBIOS_1510D,
        !           179:        0x00,
        !           180:        SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
        !           181:        SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
        !           182:        SF_CHIP_LS | SF_CHIP_10REGS |
        !           183:        SF_BUS_ULTRA2 | SF_BUS_WIDE,
        !           184:        7, 31, 7, 62, 4096
        !           185:        },
        !           186:        { 0,
        !           187:        0x00,
        !           188:        0x00,
        !           189:        0, 0, 0, 0, 0
        !           190:        },
        !           191: };
        !           192:
        !           193: const struct siop_product_desc *
        !           194: siop_lookup_product(u_int32_t id, int rev)
        !           195: {
        !           196:        const struct siop_product_desc *pp;
        !           197:        const struct siop_product_desc *rp = NULL;
        !           198:
        !           199:        if (PCI_VENDOR(id) != PCI_VENDOR_SYMBIOS)
        !           200:                return NULL;
        !           201:
        !           202:        for (pp = siop_products; pp->product != 0; pp++) {
        !           203:                if (PCI_PRODUCT(id) == pp->product && pp->revision <= rev)
        !           204:                        if (rp == NULL || pp->revision > rp->revision)
        !           205:                                rp = pp;
        !           206:        }
        !           207:        return rp;
        !           208: }
        !           209:
        !           210: int
        !           211: siop_pci_attach_common(struct siop_pci_common_softc *pci_sc,
        !           212:     struct siop_common_softc *siop_sc, struct pci_attach_args *pa,
        !           213:     int (*intr)(void*))
        !           214: {
        !           215:        pci_chipset_tag_t pc = pa->pa_pc;
        !           216:        pcitag_t tag = pa->pa_tag;
        !           217:        const char *intrstr;
        !           218:        pci_intr_handle_t intrhandle;
        !           219:        bus_space_tag_t iot, memt;
        !           220:        bus_space_handle_t ioh, memh;
        !           221:        pcireg_t memtype;
        !           222:        int memh_valid, ioh_valid;
        !           223:        bus_addr_t ioaddr, memaddr;
        !           224:        bus_size_t memsize, iosize;
        !           225:
        !           226:        pci_sc->sc_pp =
        !           227:            siop_lookup_product(pa->pa_id, PCI_REVISION(pa->pa_class));
        !           228:        if (pci_sc->sc_pp == NULL) {
        !           229:                printf(": broken match/attach!\n");
        !           230:                return 0;
        !           231:        }
        !           232:        /* copy interesting infos about the chip */
        !           233:        siop_sc->features = pci_sc->sc_pp->features;
        !           234: #ifdef SIOP_SYMLED    /* XXX Should be a devprop! */
        !           235:        siop_sc->features |= SF_CHIP_LED0;
        !           236: #endif
        !           237:        siop_sc->maxburst = pci_sc->sc_pp->maxburst;
        !           238:        siop_sc->maxoff = pci_sc->sc_pp->maxoff;
        !           239:        siop_sc->clock_div = pci_sc->sc_pp->clock_div;
        !           240:        siop_sc->clock_period = pci_sc->sc_pp->clock_period;
        !           241:        siop_sc->ram_size = pci_sc->sc_pp->ram_size;
        !           242:
        !           243:        siop_sc->sc_reset = siop_pci_reset;
        !           244:        pci_sc->sc_pc = pc;
        !           245:        pci_sc->sc_tag = tag;
        !           246:        siop_sc->sc_dmat = pa->pa_dmat;
        !           247:
        !           248:        memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, 0x14);
        !           249:        switch (memtype) {
        !           250:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
        !           251:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
        !           252:                memh_valid = (pci_mapreg_map(pa, 0x14, memtype, 0,
        !           253:                    &memt, &memh, &memaddr, NULL, 0) == 0);
        !           254:                break;
        !           255:        default:
        !           256:                memh_valid = 0;
        !           257:        }
        !           258:
        !           259:        ioh_valid = (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0,
        !           260:            &iot, &ioh, &ioaddr, &iosize, 0) == 0);
        !           261:
        !           262:        if (memh_valid) {
        !           263:                siop_sc->sc_rt = memt;
        !           264:                siop_sc->sc_rh = memh;
        !           265:                siop_sc->sc_raddr = memaddr;
        !           266:        } else if (ioh_valid) {
        !           267:                siop_sc->sc_rt = iot;
        !           268:                siop_sc->sc_rh = ioh;
        !           269:                siop_sc->sc_raddr = ioaddr;
        !           270:        } else {
        !           271:                printf(": unable to map device registers\n");
        !           272:                return 0;
        !           273:        }
        !           274:
        !           275:        if (pci_intr_map(pa, &intrhandle) != 0) {
        !           276:                printf(": couldn't map interrupt\n");
        !           277:                bus_space_unmap(siop_sc->sc_rt, siop_sc->sc_rh, iosize);
        !           278:                return 0;
        !           279:        }
        !           280:        intrstr = pci_intr_string(pa->pa_pc, intrhandle);
        !           281:        pci_sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO,
        !           282:            intr, siop_sc, siop_sc->sc_dev.dv_xname);
        !           283:        if (pci_sc->sc_ih != NULL) {
        !           284:                printf(": %s",
        !           285:                    intrstr ? intrstr : "?");
        !           286:        } else {
        !           287:                printf(": couldn't establish interrupt");
        !           288:                if (intrstr != NULL)
        !           289:                        printf(" at %s", intrstr);
        !           290:                printf("\n");
        !           291:                bus_space_unmap(siop_sc->sc_rt, siop_sc->sc_rh, iosize);
        !           292:                return 0;
        !           293:        }
        !           294:
        !           295:        if (siop_sc->features & SF_CHIP_RAM) {
        !           296:                int bar;
        !           297:                switch (memtype) {
        !           298:                case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
        !           299:                        bar = 0x18;
        !           300:                        break;
        !           301:                case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
        !           302:                        bar = 0x1c;
        !           303:                        break;
        !           304:                default:
        !           305:                        printf(": invalid memory type %d\n", memtype);
        !           306:                        return 0;
        !           307:                }
        !           308:                if (pci_mapreg_map(pa, bar, memtype, 0,
        !           309:                     &siop_sc->sc_ramt, &siop_sc->sc_ramh,
        !           310:                    &siop_sc->sc_scriptaddr, &memsize, 0) == 0) {
        !           311:                        printf(", using %luK of on-board RAM",
        !           312:                            (u_long)memsize / 1024);
        !           313:                } else {
        !           314:                        printf(", can't map on-board RAM");
        !           315:                        siop_sc->features &= ~SF_CHIP_RAM;
        !           316:                }
        !           317:        }
        !           318:
        !           319:        printf("\n");
        !           320:
        !           321:        return 1;
        !           322: }
        !           323:
        !           324: void
        !           325: siop_pci_reset(struct siop_common_softc *sc)
        !           326: {
        !           327:        int dmode;
        !           328:
        !           329:        dmode = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_DMODE);
        !           330:        if (sc->features & SF_PCI_RL)
        !           331:                dmode |= DMODE_ERL;
        !           332:        if (sc->features & SF_PCI_RM)
        !           333:                dmode |= DMODE_ERMP;
        !           334:        if (sc->features & SF_PCI_BOF)
        !           335:                dmode |= DMODE_BOF;
        !           336:        if (sc->features & SF_PCI_CLS)
        !           337:                bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_DCNTL,
        !           338:                    bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_DCNTL) |
        !           339:                    DCNTL_CLSE);
        !           340:        if (sc->features & SF_PCI_WRI)
        !           341:                bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST3,
        !           342:                    bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST3) |
        !           343:                    CTEST3_WRIE);
        !           344:        if (sc->maxburst) {
        !           345:                int ctest5 = bus_space_read_1(sc->sc_rt, sc->sc_rh,
        !           346:                    SIOP_CTEST5);
        !           347:                bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4,
        !           348:                    bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4) &
        !           349:                    ~CTEST4_BDIS);
        !           350:                dmode &= ~DMODE_BL_MASK;
        !           351:                dmode |= ((sc->maxburst - 1) << DMODE_BL_SHIFT) & DMODE_BL_MASK;
        !           352:                ctest5 &= ~CTEST5_BBCK;
        !           353:                ctest5 |= (sc->maxburst - 1) & CTEST5_BBCK;
        !           354:                bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST5, ctest5);
        !           355:        } else {
        !           356:                bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4,
        !           357:                    bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4) |
        !           358:                    CTEST4_BDIS);
        !           359:        }
        !           360:        bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_DMODE, dmode);
        !           361: }

CVSweb