[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

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