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

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

1.1       nbrk        1: /*     $OpenBSD: ahd_pci.c,v 1.15 2006/10/19 10:55:56 tom Exp $        */
                      2:
                      3: /*
                      4:  * Copyright (c) 2004 Milos Urbanek, Kenneth R. Westerback & Marco Peereboom
                      5:  * 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:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
                     17:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     18:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     19:  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
                     20:  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     21:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     22:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     24:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     25:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     26:  * SUCH DAMAGE.
                     27:  *
                     28:  */
                     29:
                     30: /*
                     31:  * Product specific probe and attach routines for:
                     32:  *     aic7901 and aic7902 SCSI controllers
                     33:  *
                     34:  * Copyright (c) 1994-2001 Justin T. Gibbs.
                     35:  * Copyright (c) 2000-2002 Adaptec Inc.
                     36:  * All rights reserved.
                     37:  *
                     38:  * Redistribution and use in source and binary forms, with or without
                     39:  * modification, are permitted provided that the following conditions
                     40:  * are met:
                     41:  * 1. Redistributions of source code must retain the above copyright
                     42:  *    notice, this list of conditions, and the following disclaimer,
                     43:  *    without modification.
                     44:  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
                     45:  *    substantially similar to the "NO WARRANTY" disclaimer below
                     46:  *    ("Disclaimer") and any redistribution must be conditioned upon
                     47:  *    including a substantially similar Disclaimer requirement for further
                     48:  *    binary redistribution.
                     49:  * 3. Neither the names of the above-listed copyright holders nor the names
                     50:  *    of any contributors may be used to endorse or promote products derived
                     51:  *    from this software without specific prior written permission.
                     52:  *
                     53:  * Alternatively, this software may be distributed under the terms of the
                     54:  * GNU General Public License ("GPL") version 2 as published by the Free
                     55:  * Software Foundation.
                     56:  *
                     57:  * NO WARRANTY
                     58:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
                     59:  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
                     60:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
                     61:  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
                     62:  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     63:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     64:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     65:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     66:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
                     67:  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     68:  * POSSIBILITY OF SUCH DAMAGES.
                     69:  *
                     70:  */
                     71:
                     72: #include <sys/cdefs.h>
                     73: /*
                     74: __FBSDID("$FreeBSD: src/sys/dev/aic7xxx/aic79xx_pci.c,v 1.18 2004/02/04 16:38:38 gibbs Exp $");
                     75: */
                     76:
                     77: #include <dev/ic/aic79xx_openbsd.h>
                     78: #include <dev/ic/aic79xx_inline.h>
                     79: #include <dev/ic/aic79xx.h>
                     80:
                     81: #include <dev/pci/pcivar.h>
                     82:
                     83: __inline uint64_t ahd_compose_id(u_int, u_int, u_int, u_int);
                     84: __inline uint64_t
                     85: ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
                     86: {
                     87:        uint64_t id;
                     88:
                     89:        id = subvendor
                     90:           | (subdevice << 16)
                     91:           | ((uint64_t)vendor << 32)
                     92:           | ((uint64_t)device << 48);
                     93:
                     94:        return (id);
                     95: }
                     96:
                     97: #define ID_ALL_MASK                    0xFFFFFFFFFFFFFFFFull
                     98: #define ID_ALL_IROC_MASK               0xFF7FFFFFFFFFFFFFull
                     99: #define ID_DEV_VENDOR_MASK             0xFFFFFFFF00000000ull
                    100: #define ID_9005_GENERIC_MASK           0xFFF0FFFF00000000ull
                    101: #define ID_9005_GENERIC_IROC_MASK      0xFF70FFFF00000000ull
                    102:
                    103: #define ID_AIC7901                     0x800F9005FFFF9005ull
                    104: #define ID_AHA_29320A                  0x8000900500609005ull
                    105: #define ID_AHA_29320ALP                        0x8017900500449005ull
                    106:
                    107: #define ID_AIC7901A                    0x801E9005FFFF9005ull
                    108: #define ID_AHA_29320LP                 0x8014900500449005ull
                    109:
                    110: #define ID_AIC7902                     0x801F9005FFFF9005ull
                    111: #define ID_AIC7902_B                   0x801D9005FFFF9005ull
                    112: #define ID_AHA_39320                   0x8010900500409005ull
                    113: #define ID_AHA_29320                   0x8012900500429005ull
                    114: #define ID_AHA_29320B                  0x8013900500439005ull
                    115: #define ID_AHA_39320_B                 0x8015900500409005ull
                    116: #define ID_AHA_39320_B_DELL            0x8015900501681028ull
                    117: #define ID_AHA_39320A                  0x8016900500409005ull
                    118: #define ID_AHA_39320D                  0x8011900500419005ull
                    119: #define ID_AHA_39320D_B                        0x801C900500419005ull
                    120: #define ID_AHA_39320D_HP               0x8011900500AC0E11ull
                    121: #define ID_AHA_39320D_B_HP             0x801C900500AC0E11ull
                    122: #define ID_AIC7902_PCI_REV_A4          0x3
                    123: #define ID_AIC7902_PCI_REV_B0          0x10
                    124: #define SUBID_HP                       0x0E11
                    125:
                    126: #define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
                    127:
                    128: #define DEVID_9005_TYPE(id) ((id) & 0xF)
                    129: #define                DEVID_9005_TYPE_HBA             0x0     /* Standard Card */
                    130: #define                DEVID_9005_TYPE_HBA_2EXT        0x1     /* 2 External Ports */
                    131: #define                DEVID_9005_TYPE_MB              0xF     /* On Motherboard */
                    132:
                    133: #define DEVID_9005_MFUNC(id) ((id) & 0x10)
                    134:
                    135: #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
                    136:
                    137: #define SUBID_9005_TYPE(id) ((id) & 0xF)
                    138: #define                SUBID_9005_TYPE_HBA             0x0     /* Standard Card */
                    139: #define                SUBID_9005_TYPE_MB              0xF     /* On Motherboard */
                    140:
                    141: #define SUBID_9005_AUTOTERM(id)        (((id) & 0x10) == 0)
                    142:
                    143: #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
                    144:
                    145: #define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6)
                    146: #define                SUBID_9005_SEEPTYPE_NONE        0x0
                    147: #define                SUBID_9005_SEEPTYPE_4K          0x1
                    148:
                    149: ahd_device_setup_t ahd_aic7901_setup;
                    150: ahd_device_setup_t ahd_aic7901A_setup;
                    151: ahd_device_setup_t ahd_aic7902_setup;
                    152: ahd_device_setup_t ahd_aic790X_setup;
                    153:
                    154: struct ahd_pci_identity ahd_pci_ident_table [] =
                    155: {
                    156:        /* aic7901 based controllers */
                    157:        {
                    158:                ID_AHA_29320A,
                    159:                ID_ALL_MASK,
                    160:                ahd_aic7901_setup
                    161:        },
                    162:        {
                    163:                ID_AHA_29320ALP,
                    164:                ID_ALL_MASK,
                    165:                ahd_aic7901_setup
                    166:        },
                    167:        /* aic7901A based controllers */
                    168:        {
                    169:                ID_AHA_29320LP,
                    170:                ID_ALL_MASK,
                    171:                ahd_aic7901A_setup
                    172:        },
                    173:        /* aic7902 based controllers */
                    174:        {
                    175:                ID_AHA_29320,
                    176:                ID_ALL_MASK,
                    177:                ahd_aic7902_setup
                    178:        },
                    179:        {
                    180:                ID_AHA_29320B,
                    181:                ID_ALL_MASK,
                    182:                ahd_aic7902_setup
                    183:        },
                    184:        {
                    185:                ID_AHA_39320,
                    186:                ID_ALL_MASK,
                    187:                ahd_aic7902_setup
                    188:        },
                    189:        {
                    190:                ID_AHA_39320_B,
                    191:                ID_ALL_MASK,
                    192:                ahd_aic7902_setup
                    193:        },
                    194:        {
                    195:                ID_AHA_39320_B_DELL,
                    196:                ID_ALL_MASK,
                    197:                ahd_aic7902_setup
                    198:        },
                    199:        {
                    200:                ID_AHA_39320A,
                    201:                ID_ALL_MASK,
                    202:                ahd_aic7902_setup
                    203:        },
                    204:        {
                    205:                ID_AHA_39320D,
                    206:                ID_ALL_MASK,
                    207:                ahd_aic7902_setup
                    208:        },
                    209:        {
                    210:                ID_AHA_39320D_HP,
                    211:                ID_ALL_MASK,
                    212:                ahd_aic7902_setup
                    213:        },
                    214:        {
                    215:                ID_AHA_39320D_B,
                    216:                ID_ALL_MASK,
                    217:                ahd_aic7902_setup
                    218:        },
                    219:        {
                    220:                ID_AHA_39320D_B_HP,
                    221:                ID_ALL_MASK,
                    222:                ahd_aic7902_setup
                    223:        },
                    224:        /* Generic chip probes for devices we don't know 'exactly' */
                    225:        {
                    226:                ID_AIC7901 & ID_9005_GENERIC_MASK,
                    227:                ID_9005_GENERIC_MASK,
                    228:                ahd_aic7901_setup
                    229:        },
                    230:        {
                    231:                ID_AIC7901A & ID_DEV_VENDOR_MASK,
                    232:                ID_DEV_VENDOR_MASK,
                    233:                ahd_aic7901A_setup
                    234:        },
                    235:        {
                    236:                ID_AIC7902 & ID_9005_GENERIC_MASK,
                    237:                ID_9005_GENERIC_MASK,
                    238:                ahd_aic7902_setup
                    239:        }
                    240: };
                    241:
                    242: const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
                    243:
                    244: #define                        DEVCONFIG               0x40
                    245: #define                        PCIXINITPAT             0x0000E000ul
                    246: #define                        PCIXINIT_PCI33_66       0x0000E000ul
                    247: #define                        PCIXINIT_PCIX50_66      0x0000C000ul
                    248: #define                        PCIXINIT_PCIX66_100     0x0000A000ul
                    249: #define                        PCIXINIT_PCIX100_133    0x00008000ul
                    250: #define        PCI_BUS_MODES_INDEX(devconfig)  \
                    251:        (((devconfig) & PCIXINITPAT) >> 13)
                    252:
                    253: static const char *pci_bus_modes[] =
                    254: {
                    255:        "PCI bus mode unknown",
                    256:        "PCI bus mode unknown",
                    257:        "PCI bus mode unknown",
                    258:        "PCI bus mode unknown",
                    259:        "PCI-X 101-133MHz",
                    260:        "PCI-X 67-100MHz",
                    261:        "PCI-X 50-66MHz",
                    262:        "PCI 33 or 66MHz"
                    263: };
                    264:
                    265: #define                TESTMODE        0x00000800ul
                    266: #define                IRDY_RST        0x00000200ul
                    267: #define                FRAME_RST       0x00000100ul
                    268: #define                PCI64BIT        0x00000080ul
                    269: #define                MRDCEN          0x00000040ul
                    270: #define                ENDIANSEL       0x00000020ul
                    271: #define                MIXQWENDIANEN   0x00000008ul
                    272: #define                DACEN           0x00000004ul
                    273: #define                STPWLEVEL       0x00000002ul
                    274: #define                QWENDIANSEL     0x00000001ul
                    275:
                    276: #define        DEVCONFIG1              0x44
                    277: #define                PREQDIS         0x01
                    278:
                    279: #define        CSIZE_LATTIME           0x0c
                    280: #define                CACHESIZE       0x000000fful
                    281: #define                LATTIME         0x0000ff00ul
                    282:
                    283: int    ahd_pci_probe(struct device *, void *, void *);
                    284: void   ahd_pci_attach(struct device *, struct device *, void *);
                    285:
                    286: struct cfattach ahd_pci_ca = {
                    287:                sizeof(struct ahd_softc), ahd_pci_probe, ahd_pci_attach
                    288: };
                    289:
                    290: int    ahd_check_extport(struct ahd_softc *ahd);
                    291: void   ahd_configure_termination(struct ahd_softc *ahd,
                    292:                                          u_int adapter_control);
                    293: void   ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
                    294:
                    295: const struct ahd_pci_identity *
                    296: ahd_find_pci_device(pcireg_t id, pcireg_t subid)
                    297: {
                    298:        const struct ahd_pci_identity *entry;
                    299:        u_int64_t full_id;
                    300:        u_int i;
                    301:
                    302:        full_id = ahd_compose_id(PCI_PRODUCT(id), PCI_VENDOR(id),
                    303:            PCI_PRODUCT(subid), PCI_VENDOR(subid));
                    304:
                    305:        /*
                    306:         * If we are configured to attach to HostRAID
                    307:         * controllers, mask out the IROC/HostRAID bit
                    308:         * in the
                    309:         */
                    310:        if (ahd_attach_to_HostRAID_controllers)
                    311:                full_id &= ID_ALL_IROC_MASK;
                    312:
                    313:        for (i = 0; i < ahd_num_pci_devs; i++) {
                    314:                entry = &ahd_pci_ident_table[i];
                    315:                if (entry->full_id == (full_id & entry->id_mask)) {
                    316:                        return (entry);
                    317:                }
                    318:        }
                    319:        return (NULL);
                    320: }
                    321:
                    322: int
                    323: ahd_pci_probe(struct device *parent, void *match, void *aux)
                    324: {
                    325:        const struct ahd_pci_identity *entry;
                    326:        struct pci_attach_args *pa = aux;
                    327:        pcireg_t subid;
                    328:
                    329:        subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
                    330:        entry = ahd_find_pci_device(pa->pa_id, subid);
                    331:        return entry != NULL ? 1 : 0;
                    332: }
                    333:
                    334: void
                    335: ahd_pci_attach(struct device *parent, struct device *self, void *aux)
                    336: {
                    337:        const struct ahd_pci_identity *entry;
                    338:        struct pci_attach_args *pa = aux;
                    339:        struct ahd_softc *ahd = (void *)self;
                    340:        pci_intr_handle_t ih;
                    341:        const char *intrstr;
                    342:        pcireg_t devconfig, memtype, reg, subid;
                    343:        uint16_t device, subvendor;
                    344:        int error, ioh_valid, ioh2_valid, l, memh_valid, offset;
                    345:
                    346:        ahd->dev_softc = pa;
                    347:        ahd->parent_dmat = pa->pa_dmat;
                    348:
                    349:        if (ahd_alloc(ahd, ahd->sc_dev.dv_xname) == NULL)
                    350:                return;
                    351:
                    352:        subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
                    353:        entry = ahd_find_pci_device(pa->pa_id, subid);
                    354:        if (entry == NULL)
                    355:                return;
                    356:
                    357:        /*
                    358:         * Record if this is a HostRAID board.
                    359:         */
                    360:        device = PCI_PRODUCT(pa->pa_id);
                    361:        if (DEVID_9005_HOSTRAID(device))
                    362:                ahd->flags |= AHD_HOSTRAID_BOARD;
                    363:
                    364:        /*
                    365:         * Record if this is an HP board.
                    366:         */
                    367:        subvendor = PCI_VENDOR(subid);
                    368:        if (subvendor == SUBID_HP)
                    369:                ahd->flags |= AHD_HP_BOARD;
                    370:
                    371:        error = entry->setup(ahd, pa);
                    372:        if (error != 0)
                    373:                return;
                    374:
                    375:        /* XXX ahc on sparc64 needs this twice */
                    376:        devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
                    377:
                    378:        if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
                    379:                ahd->chip |= AHD_PCI;
                    380:                /* Disable PCIX workarounds when running in PCI mode. */
                    381:                ahd->bugs &= ~AHD_PCIX_BUG_MASK;
                    382:        } else {
                    383:                ahd->chip |= AHD_PCIX;
                    384:        }
                    385:        ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
                    386:
                    387:        memh_valid = ioh_valid = ioh2_valid = 0;
                    388:
                    389:        if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIX,
                    390:            &ahd->pcix_off, NULL)) {
                    391:                if (ahd->chip & AHD_PCIX)
                    392:                        printf("%s: warning: can't find PCI-X capability\n",
                    393:                            ahd_name(ahd));
                    394:                ahd->chip &= ~AHD_PCIX;
                    395:                ahd->chip |= AHD_PCI;
                    396:                ahd->bugs &= ~AHD_PCIX_BUG_MASK;
                    397:        }
                    398:
                    399:        /*
                    400:         * Map PCI registers
                    401:         */
                    402:        if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) == 0) {
                    403:                memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag,
                    404:                    AHD_PCI_MEMADDR);
                    405:                switch (memtype) {
                    406:                case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
                    407:                case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
                    408:                        memh_valid = (pci_mapreg_map(pa, AHD_PCI_MEMADDR,
                    409:                            memtype, 0, &ahd->tags[0], &ahd->bshs[0], NULL,
                    410:                            NULL, 0) == 0);
                    411:                        if (memh_valid) {
                    412:                                ahd->tags[1] = ahd->tags[0];
                    413:                                bus_space_subregion(ahd->tags[0], ahd->bshs[0],
                    414:                                    /*offset*/0x100, /*size*/0x100,
                    415:                                    &ahd->bshs[1]);
                    416:                                if (ahd_pci_test_register_access(ahd) != 0)
                    417:                                        memh_valid = 0;
                    418:                        }
                    419:                        break;
                    420:                default:
                    421:                        memh_valid = 0;
                    422:                        printf("%s: unknown memory type: 0x%x\n",
                    423:                        ahd_name(ahd), memtype);
                    424:                        break;
                    425:                }
                    426:
                    427: #ifdef AHD_DEBUG
                    428:                printf("%s: doing memory mapping tag0 0x%x, tag1 0x%x, shs0 "
                    429:                    "0x%lx, shs1 0x%lx\n", ahd_name(ahd), ahd->tags[0],
                    430:                    ahd->tags[1], ahd->bshs[0], ahd->bshs[1]);
                    431: #endif
                    432:        }
                    433:
                    434:        if (!memh_valid) {
                    435:                /* First BAR */
                    436:                ioh_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR,
                    437:                    PCI_MAPREG_TYPE_IO, 0, &ahd->tags[0], &ahd->bshs[0], NULL,
                    438:                    NULL, 0) == 0);
                    439:
                    440:                /* 2nd BAR */
                    441:                ioh2_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR1,
                    442:                    PCI_MAPREG_TYPE_IO, 0, &ahd->tags[1], &ahd->bshs[1], NULL,
                    443:                    NULL, 0) == 0);
                    444:
                    445: #ifdef AHD_DEBUG
                    446:                printf("%s: doing io mapping tag0 0x%x, tag1 0x%x, shs0 0x%lx, "
                    447:                    "shs1 0x%lx\n", ahd_name(ahd), ahd->tags[0], ahd->tags[1],
                    448:                    ahd->bshs[0], ahd->bshs[1]);
                    449: #endif
                    450:        }
                    451:
                    452:        if (memh_valid == 0 && (ioh_valid == 0 || ioh2_valid == 0)) {
                    453:                printf("%s: unable to map registers\n", ahd_name(ahd));
                    454:                return;
                    455:        }
                    456:
                    457:        /*
                    458:         * Set Power State D0.
                    459:         */
                    460:        if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT, &offset,
                    461:            NULL)) {
                    462:                /* Increment offset from cap register to csr register. */
                    463:                offset += 4;
                    464:                reg = pci_conf_read(pa->pa_pc, pa->pa_tag, offset);
                    465:                if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0) {
                    466:                        pci_conf_write(pa->pa_pc, pa->pa_tag, offset,
                    467:                            (reg & ~PCI_PMCSR_STATE_MASK) | PCI_PMCSR_STATE_D0);
                    468:                }
                    469:        }
                    470:
                    471:        /*
                    472:         * Should we bother disabling 39Bit addressing
                    473:         * based on installed memory?
                    474:         */
                    475:        if (sizeof(bus_addr_t) > 4)
                    476:                ahd->flags |= AHD_39BIT_ADDRESSING;
                    477:
                    478:        /*
                    479:         * If we need to support high memory, enable dual
                    480:         * address cycles.  This bit must be set to enable
                    481:         * high address bit generation even if we are on a
                    482:         * 64bit bus (PCI64BIT set in devconfig).
                    483:         */
                    484:        if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
                    485:                pcireg_t devconfig;
                    486:
                    487:                if (bootverbose)
                    488:                        printf("%s: Enabling 39Bit Addressing\n",
                    489:                               ahd_name(ahd));
                    490:                devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
                    491:                devconfig |= DACEN;
                    492:                pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG, devconfig);
                    493:        }
                    494:
                    495:        ahd_softc_init(ahd);
                    496:
                    497:        /*
                    498:         * Map the interrupts routines
                    499:         */
                    500:        ahd->bus_intr = ahd_pci_intr;
                    501:
                    502:        error = ahd_reset(ahd, /*reinit*/FALSE);
                    503:        if (error != 0) {
                    504:                ahd_free(ahd);
                    505:                return;
                    506:        }
                    507:
                    508:        if (pci_intr_map(pa, &ih)) {
                    509:                printf("%s: couldn't map interrupt\n", ahd_name(ahd));
                    510:                ahd_free(ahd);
                    511:                return;
                    512:        }
                    513:        intrstr = pci_intr_string(pa->pa_pc, ih);
                    514:        ahd->ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
                    515:        ahd_platform_intr, ahd, ahd->sc_dev.dv_xname);
                    516:        if (ahd->ih == NULL) {
                    517:                printf("%s: couldn't establish interrupt", ahd_name(ahd));
                    518:                if (intrstr != NULL)
                    519:                        printf(" at %s", intrstr);
                    520:                printf("\n");
                    521:                ahd_free(ahd);
                    522:                return;
                    523:        }
                    524:        if (intrstr != NULL)
                    525:                printf(": %s\n", intrstr);
                    526:
                    527:        /* Get the size of the cache */
                    528:        ahd->pci_cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
                    529:        ahd->pci_cachesize *= 4;
                    530:
                    531:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                    532:        /* See if we have a SEEPROM and perform auto-term */
                    533:        error = ahd_check_extport(ahd);
                    534:        if (error != 0)
                    535:                return;
                    536:
                    537:        /* Core initialization */
                    538:        error = ahd_init(ahd);
                    539:        if (error != 0)
                    540:                return;
                    541:
                    542:        ahd_list_lock(&l);
                    543:        /*
                    544:         * Link this softc in with all other ahd instances.
                    545:         */
                    546:        ahd_softc_insert(ahd);
                    547:        ahd_list_unlock(&l);
                    548:
                    549:        /* complete the attach */
                    550:        ahd_attach(ahd);
                    551: }
                    552:
                    553: /*
                    554:  * Perform some simple tests that should catch situations where
                    555:  * our registers are invalidly mapped.
                    556:  */
                    557: int
                    558: ahd_pci_test_register_access(struct ahd_softc *ahd)
                    559: {
                    560:        const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
                    561:        const pcitag_t tag = ahd->dev_softc->pa_tag;
                    562:        pcireg_t cmd;
                    563:        u_int    targpcistat;
                    564:        pcireg_t pci_status1;
                    565:        int      error;
                    566:        uint8_t  hcntrl;
                    567:
                    568:        error = EIO;
                    569:
                    570:        /*
                    571:         * Enable PCI error interrupt status, but suppress NMIs
                    572:         * generated by SERR raised due to target aborts.
                    573:         */
                    574:        cmd = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
                    575:        pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
                    576:            cmd & ~PCI_COMMAND_SERR_ENABLE);
                    577:
                    578:        /*
                    579:         * First a simple test to see if any
                    580:         * registers can be read.  Reading
                    581:         * HCNTRL has no side effects and has
                    582:         * at least one bit that is guaranteed to
                    583:         * be zero so it is a good register to
                    584:         * use for this test.
                    585:         */
                    586:        hcntrl = ahd_inb(ahd, HCNTRL);
                    587:        if (hcntrl == 0xFF)
                    588:                goto fail;
                    589:
                    590:        /*
                    591:         * Next create a situation where write combining
                    592:         * or read prefetching could be initiated by the
                    593:         * CPU or host bridge.  Our device does not support
                    594:         * either, so look for data corruption and/or flaged
                    595:         * PCI errors.  First pause without causing another
                    596:         * chip reset.
                    597:         */
                    598:        hcntrl &= ~CHIPRST;
                    599:        ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
                    600:        while (ahd_is_paused(ahd) == 0)
                    601:                ;
                    602:
                    603:        /* Clear any PCI errors that occurred before our driver attached. */
                    604:        ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                    605:        targpcistat = ahd_inb(ahd, TARGPCISTAT);
                    606:        ahd_outb(ahd, TARGPCISTAT, targpcistat);
                    607:        pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
                    608:        pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, pci_status1);
                    609:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                    610:        ahd_outb(ahd, CLRINT, CLRPCIINT);
                    611:
                    612:        ahd_outb(ahd, SEQCTL0, PERRORDIS);
                    613:        ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
                    614:        if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
                    615:                goto fail;
                    616:
                    617:        if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
                    618:                u_int targpcistat;
                    619:
                    620:                ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                    621:                targpcistat = ahd_inb(ahd, TARGPCISTAT);
                    622:                if ((targpcistat & STA) != 0)
                    623:                        goto fail;
                    624:        }
                    625:
                    626:        error = 0;
                    627:
                    628: fail:
                    629:        if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
                    630:
                    631:                ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                    632:                targpcistat = ahd_inb(ahd, TARGPCISTAT);
                    633:
                    634:                /* Silently clear any latched errors. */
                    635:                ahd_outb(ahd, TARGPCISTAT, targpcistat);
                    636:                pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
                    637:                pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, pci_status1);
                    638:                ahd_outb(ahd, CLRINT, CLRPCIINT);
                    639:        }
                    640:        ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
                    641:        pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmd);
                    642:        return (error);
                    643: }
                    644:
                    645: /*
                    646:  * Check the external port logic for a serial eeprom
                    647:  * and termination/cable detection contrls.
                    648:  */
                    649: int
                    650: ahd_check_extport(struct ahd_softc *ahd)
                    651: {
                    652:        struct  vpd_config vpd;
                    653:        struct  seeprom_config *sc;
                    654:        u_int   adapter_control;
                    655:        int     have_seeprom;
                    656:        int     error;
                    657:
                    658:        sc = ahd->seep_config;
                    659:        have_seeprom = ahd_acquire_seeprom(ahd);
                    660:        if (have_seeprom) {
                    661:                u_int start_addr;
                    662:
                    663:                /*
                    664:                 * Fetch VPD for this function and parse it.
                    665:                 */
                    666:                if (bootverbose)
                    667:                        printf("%s: Reading VPD from SEEPROM...",
                    668:                               ahd_name(ahd));
                    669:
                    670:                /* Address is always in units of 16bit words */
                    671:                start_addr = ((2 * sizeof(*sc))
                    672:                            + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
                    673:
                    674:                error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
                    675:                                         start_addr, sizeof(vpd)/2,
                    676:                                         /*bytestream*/TRUE);
                    677:                if (error == 0)
                    678:                        error = ahd_parse_vpddata(ahd, &vpd);
                    679:                if (bootverbose)
                    680:                        printf("%s: VPD parsing %s\n",
                    681:                               ahd_name(ahd),
                    682:                               error == 0 ? "successful" : "failed");
                    683:
                    684:                if (bootverbose)
                    685:                        printf("%s: Reading SEEPROM...", ahd_name(ahd));
                    686:
                    687:                /* Address is always in units of 16bit words */
                    688:                start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
                    689:
                    690:                error = ahd_read_seeprom(ahd, (uint16_t *)sc,
                    691:                                         start_addr, sizeof(*sc)/2,
                    692:                                         /*bytestream*/FALSE);
                    693:
                    694:                if (error != 0) {
                    695:                        printf("Unable to read SEEPROM\n");
                    696:                        have_seeprom = 0;
                    697:                } else {
                    698:                        have_seeprom = ahd_verify_cksum(sc);
                    699:
                    700:                        if (bootverbose) {
                    701:                                if (have_seeprom == 0)
                    702:                                        printf ("checksum error\n");
                    703:                                else
                    704:                                        printf ("done.\n");
                    705:                        }
                    706:                }
                    707:                ahd_release_seeprom(ahd);
                    708:        }
                    709:
                    710:        if (!have_seeprom) {
                    711:                u_int     nvram_scb;
                    712:
                    713:                /*
                    714:                 * Pull scratch ram settings and treat them as
                    715:                 * if they are the contents of an seeprom if
                    716:                 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
                    717:                 * in SCB 0xFF.  We manually compose the data as 16bit
                    718:                 * values to avoid endian issues.
                    719:                 */
                    720:                ahd_set_scbptr(ahd, 0xFF);
                    721:                nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
                    722:                if (nvram_scb != 0xFF
                    723:                 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
                    724:                   && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
                    725:                   && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
                    726:                   && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
                    727:                  || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
                    728:                   && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
                    729:                   && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
                    730:                   && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
                    731:                  || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
                    732:                   && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
                    733:                   && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
                    734:                   && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
                    735:                        uint16_t *sc_data;
                    736:                        int       i;
                    737:
                    738:                        ahd_set_scbptr(ahd, nvram_scb);
                    739:                        sc_data = (uint16_t *)sc;
                    740:                        for (i = 0; i < 64; i += 2)
                    741:                                *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
                    742:                        have_seeprom = ahd_verify_cksum(sc);
                    743:                        if (have_seeprom)
                    744:                                ahd->flags |= AHD_SCB_CONFIG_USED;
                    745:                }
                    746:        }
                    747:
                    748: #ifdef AHD_DEBUG
                    749:        if (have_seeprom != 0
                    750:         && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
                    751:                uint16_t *sc_data;
                    752:                int       i;
                    753:
                    754:                printf("%s: Seeprom Contents:", ahd_name(ahd));
                    755:                sc_data = (uint16_t *)sc;
                    756:                for (i = 0; i < (sizeof(*sc)); i += 2)
                    757:                        printf("\n\t0x%.4x", sc_data[i]);
                    758:                printf("\n");
                    759:        }
                    760: #endif
                    761:
                    762:        if (!have_seeprom) {
                    763:                if (bootverbose)
                    764:                        printf("%s: No SEEPROM available.\n", ahd_name(ahd));
                    765:                ahd->flags |= AHD_USEDEFAULTS;
                    766:                error = ahd_default_config(ahd);
                    767:                adapter_control = CFAUTOTERM|CFSEAUTOTERM;
                    768:                free(ahd->seep_config, M_DEVBUF);
                    769:                ahd->seep_config = NULL;
                    770:        } else {
                    771:                error = ahd_parse_cfgdata(ahd, sc);
                    772:                adapter_control = sc->adapter_control;
                    773:        }
                    774:        if (error != 0)
                    775:                return (error);
                    776:
                    777:        ahd_configure_termination(ahd, adapter_control);
                    778:
                    779:        return (0);
                    780: }
                    781:
                    782: void
                    783: ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
                    784: {
                    785:        const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
                    786:        const pcitag_t tag = ahd->dev_softc->pa_tag;
                    787:        int      error;
                    788:        u_int    sxfrctl1;
                    789:        uint8_t  termctl;
                    790:        pcireg_t devconfig;
                    791:
                    792:        devconfig = pci_conf_read(pc, tag, DEVCONFIG);
                    793:        devconfig &= ~STPWLEVEL;
                    794:        if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
                    795:                devconfig |= STPWLEVEL;
                    796:        if (bootverbose)
                    797:                printf("%s: STPWLEVEL is %s\n",
                    798:                       ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
                    799:        pci_conf_write(pc, tag, DEVCONFIG, devconfig);
                    800:
                    801:        /* Make sure current sensing is off. */
                    802:        if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
                    803:                (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
                    804:        }
                    805:
                    806:        /*
                    807:         * Read to sense.  Write to set.
                    808:         */
                    809:        error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
                    810:        if ((adapter_control & CFAUTOTERM) == 0) {
                    811:                if (bootverbose)
                    812:                        printf("%s: Manual Primary Termination\n",
                    813:                               ahd_name(ahd));
                    814:                termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
                    815:                if ((adapter_control & CFSTERM) != 0)
                    816:                        termctl |= FLX_TERMCTL_ENPRILOW;
                    817:                if ((adapter_control & CFWSTERM) != 0)
                    818:                        termctl |= FLX_TERMCTL_ENPRIHIGH;
                    819:        } else if (error != 0) {
                    820:                printf("%s: Primary Auto-Term Sensing failed! "
                    821:                       "Using Defaults.\n", ahd_name(ahd));
                    822:                termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
                    823:        }
                    824:
                    825:        if ((adapter_control & CFSEAUTOTERM) == 0) {
                    826:                if (bootverbose)
                    827:                        printf("%s: Manual Secondary Termination\n",
                    828:                               ahd_name(ahd));
                    829:                termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
                    830:                if ((adapter_control & CFSELOWTERM) != 0)
                    831:                        termctl |= FLX_TERMCTL_ENSECLOW;
                    832:                if ((adapter_control & CFSEHIGHTERM) != 0)
                    833:                        termctl |= FLX_TERMCTL_ENSECHIGH;
                    834:        } else if (error != 0) {
                    835:                printf("%s: Secondary Auto-Term Sensing failed! "
                    836:                       "Using Defaults.\n", ahd_name(ahd));
                    837:                termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
                    838:        }
                    839:
                    840:        /*
                    841:         * Now set the termination based on what we found.
                    842:         */
                    843:        sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
                    844:        ahd->flags &= ~AHD_TERM_ENB_A;
                    845:        if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
                    846:                ahd->flags |= AHD_TERM_ENB_A;
                    847:                sxfrctl1 |= STPWEN;
                    848:        }
                    849:        /* Must set the latch once in order to be effective. */
                    850:        ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
                    851:        ahd_outb(ahd, SXFRCTL1, sxfrctl1);
                    852:
                    853:        error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
                    854:        if (error != 0) {
                    855:                printf("%s: Unable to set termination settings!\n",
                    856:                       ahd_name(ahd));
                    857:        } else if (bootverbose) {
                    858:                printf("%s: Primary High byte termination %sabled\n",
                    859:                       ahd_name(ahd),
                    860:                       (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
                    861:
                    862:                printf("%s: Primary Low byte termination %sabled\n",
                    863:                       ahd_name(ahd),
                    864:                       (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
                    865:
                    866:                printf("%s: Secondary High byte termination %sabled\n",
                    867:                       ahd_name(ahd),
                    868:                       (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
                    869:
                    870:                printf("%s: Secondary Low byte termination %sabled\n",
                    871:                       ahd_name(ahd),
                    872:                       (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
                    873:        }
                    874:        return;
                    875: }
                    876:
                    877: #define        DPE     0x80
                    878: #define SSE    0x40
                    879: #define        RMA     0x20
                    880: #define        RTA     0x10
                    881: #define STA    0x08
                    882: #define DPR    0x01
                    883:
                    884: static const char *split_status_source[] =
                    885: {
                    886:        "DFF0",
                    887:        "DFF1",
                    888:        "OVLY",
                    889:        "CMC",
                    890: };
                    891:
                    892: static const char *pci_status_source[] =
                    893: {
                    894:        "DFF0",
                    895:        "DFF1",
                    896:        "SG",
                    897:        "CMC",
                    898:        "OVLY",
                    899:        "NONE",
                    900:        "MSI",
                    901:        "TARG"
                    902: };
                    903:
                    904: static const char *split_status_strings[] =
                    905: {
                    906:        "%s: Received split response in %s.\n",
                    907:        "%s: Received split completion error message in %s\n",
                    908:        "%s: Receive overrun in %s\n",
                    909:        "%s: Count not complete in %s\n",
                    910:        "%s: Split completion data bucket in %s\n",
                    911:        "%s: Split completion address error in %s\n",
                    912:        "%s: Split completion byte count error in %s\n",
                    913:        "%s: Signaled Target-abort to early terminate a split in %s\n"
                    914: };
                    915:
                    916: static const char *pci_status_strings[] =
                    917: {
                    918:        "%s: Data Parity Error has been reported via PERR# in %s\n",
                    919:        "%s: Target initial wait state error in %s\n",
                    920:        "%s: Split completion read data parity error in %s\n",
                    921:        "%s: Split completion address attribute parity error in %s\n",
                    922:        "%s: Received a Target Abort in %s\n",
                    923:        "%s: Received a Master Abort in %s\n",
                    924:        "%s: Signal System Error Detected in %s\n",
                    925:        "%s: Address or Write Phase Parity Error Detected in %s.\n"
                    926: };
                    927:
                    928: void
                    929: ahd_pci_intr(struct ahd_softc *ahd)
                    930: {
                    931:        const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
                    932:        const pcitag_t tag = ahd->dev_softc->pa_tag;
                    933:        uint8_t         pci_status[8];
                    934:        ahd_mode_state  saved_modes;
                    935:        pcireg_t        pci_status1;
                    936:        u_int           intstat;
                    937:        u_int           i;
                    938:        u_int           reg;
                    939:
                    940:        intstat = ahd_inb(ahd, INTSTAT);
                    941:
                    942:        if ((intstat & SPLTINT) != 0)
                    943:                ahd_pci_split_intr(ahd, intstat);
                    944:
                    945:        if ((intstat & PCIINT) == 0)
                    946:                return;
                    947:
                    948:        printf("%s: PCI error Interrupt\n", ahd_name(ahd));
                    949:        saved_modes = ahd_save_modes(ahd);
                    950:        ahd_dump_card_state(ahd);
                    951:        ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                    952:        for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
                    953:
                    954:                if (i == 5)
                    955:                        continue;
                    956:                pci_status[i] = ahd_inb(ahd, reg);
                    957:                /* Clear latched errors.  So our interrupt deasserts. */
                    958:                ahd_outb(ahd, reg, pci_status[i]);
                    959:        }
                    960:
                    961:        for (i = 0; i < 8; i++) {
                    962:                u_int bit;
                    963:
                    964:                if (i == 5)
                    965:                        continue;
                    966:
                    967:                for (bit = 0; bit < 8; bit++) {
                    968:
                    969:                        if ((pci_status[i] & (0x1 << bit)) != 0) {
                    970:                                static const char *s;
                    971:
                    972:                                s = pci_status_strings[bit];
                    973:                                if (i == 7/*TARG*/ && bit == 3)
                    974:                                        s = "%s: Signaled Target Abort\n";
                    975:                                printf(s, ahd_name(ahd), pci_status_source[i]);
                    976:                        }
                    977:                }
                    978:        }
                    979:        pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
                    980:        pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG , pci_status1);
                    981:
                    982:        ahd_restore_modes(ahd, saved_modes);
                    983:        ahd_outb(ahd, CLRINT, CLRPCIINT);
                    984:        ahd_unpause(ahd);
                    985:
                    986:        return;
                    987: }
                    988:
                    989: void
                    990: ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
                    991: {
                    992:        const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
                    993:        const pcitag_t tag = ahd->dev_softc->pa_tag;
                    994:        uint8_t         split_status[4];
                    995:        uint8_t         split_status1[4];
                    996:        uint8_t         sg_split_status[2];
                    997:        uint8_t         sg_split_status1[2];
                    998:        ahd_mode_state  saved_modes;
                    999:        u_int           i;
                   1000:        pcireg_t        pcix_status;
                   1001:
                   1002:        /*
                   1003:         * Check for splits in all modes.  Modes 0 and 1
                   1004:         * additionally have SG engine splits to look at.
                   1005:         */
                   1006:        pcix_status = pci_conf_read(pc, tag, ahd->pcix_off + 0x04);
                   1007:        printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
                   1008:               ahd_name(ahd), pcix_status);
                   1009:
                   1010:        saved_modes = ahd_save_modes(ahd);
                   1011:        for (i = 0; i < 4; i++) {
                   1012:                ahd_set_modes(ahd, i, i);
                   1013:
                   1014:                split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
                   1015:                split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
                   1016:                /* Clear latched errors.  So our interrupt deasserts. */
                   1017:                ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
                   1018:                ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
                   1019:                if (i > 1)
                   1020:                        continue;
                   1021:                sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
                   1022:                sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
                   1023:                /* Clear latched errors.  So our interrupt deasserts. */
                   1024:                ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
                   1025:                ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
                   1026:        }
                   1027:
                   1028:        for (i = 0; i < 4; i++) {
                   1029:                u_int bit;
                   1030:
                   1031:                for (bit = 0; bit < 8; bit++) {
                   1032:
                   1033:                        if ((split_status[i] & (0x1 << bit)) != 0) {
                   1034:                                static const char *s;
                   1035:
                   1036:                                s = split_status_strings[bit];
                   1037:                                printf(s, ahd_name(ahd),
                   1038:                                       split_status_source[i]);
                   1039:                        }
                   1040:
                   1041:                        if (i > 1)
                   1042:                                continue;
                   1043:
                   1044:                        if ((sg_split_status[i] & (0x1 << bit)) != 0) {
                   1045:                                static const char *s;
                   1046:
                   1047:                                s = split_status_strings[bit];
                   1048:                                printf(s, ahd_name(ahd), "SG");
                   1049:                        }
                   1050:                }
                   1051:        }
                   1052:        /*
                   1053:         * Clear PCI-X status bits.
                   1054:         */
                   1055:        pci_conf_write(pc, tag, ahd->pcix_off + 0x04, pcix_status);
                   1056:        ahd_outb(ahd, CLRINT, CLRSPLTINT);
                   1057:        ahd_restore_modes(ahd, saved_modes);
                   1058: }
                   1059:
                   1060: int
                   1061: ahd_aic7901_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
                   1062: {
                   1063:
                   1064:        ahd->chip = AHD_AIC7901;
                   1065:        ahd->features = AHD_AIC7901_FE;
                   1066:        return (ahd_aic790X_setup(ahd, pa));
                   1067: }
                   1068:
                   1069: int
                   1070: ahd_aic7901A_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
                   1071: {
                   1072:
                   1073:        ahd->chip = AHD_AIC7901A;
                   1074:        ahd->features = AHD_AIC7901A_FE;
                   1075:        return (ahd_aic790X_setup(ahd, pa));
                   1076: }
                   1077:
                   1078: int
                   1079: ahd_aic7902_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
                   1080: {
                   1081:        ahd->chip = AHD_AIC7902;
                   1082:        ahd->features = AHD_AIC7902_FE;
                   1083:        return (ahd_aic790X_setup(ahd, pa));
                   1084: }
                   1085:
                   1086: int
                   1087: ahd_aic790X_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
                   1088: {
                   1089:        u_int rev;
                   1090:
                   1091:        rev = PCI_REVISION(pa->pa_class);
                   1092: #ifdef AHD_DEBUG
                   1093:        printf("\n%s: aic7902 chip revision 0x%x\n", ahd_name(ahd), rev);
                   1094: #endif
                   1095:        if (rev < ID_AIC7902_PCI_REV_A4) {
                   1096:                printf("%s: Unable to attach to unsupported chip revision %d\n",
                   1097:                       ahd_name(ahd), rev);
                   1098:                pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 0);
                   1099:                return (ENXIO);
                   1100:        }
                   1101:
                   1102:        ahd->channel = (pa->pa_function == 1) ? 'B' : 'A';
                   1103:        if (rev < ID_AIC7902_PCI_REV_B0) {
                   1104:                /*
                   1105:                 * Enable A series workarounds.
                   1106:                 */
                   1107:                ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
                   1108:                          |  AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
                   1109:                          |  AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
                   1110:                          |  AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
                   1111:                          |  AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
                   1112:                          |  AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
                   1113:                          |  AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
                   1114:                          |  AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
                   1115:                          |  AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
                   1116:                          |  AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
                   1117:                          |  AHD_FAINT_LED_BUG;
                   1118:
                   1119:                /*
                   1120:                 * IO Cell parameter setup.
                   1121:                 */
                   1122:                AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
                   1123:
                   1124:                if ((ahd->flags & AHD_HP_BOARD) == 0)
                   1125:                        AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
                   1126:        } else {
                   1127:                pcireg_t devconfig1;
                   1128:
                   1129:                ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
                   1130:                              |  AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
                   1131:                ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG
                   1132:                          |  AHD_BUSFREEREV_BUG;
                   1133:
                   1134:                /*
                   1135:                 * Some issues have been resolved in the 7901B.
                   1136:                 */
                   1137:                if ((ahd->features & AHD_MULTI_FUNC) != 0)
                   1138:                        ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
                   1139:
                   1140:                /*
                   1141:                 * IO Cell parameter setup.
                   1142:                 */
                   1143:                AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
                   1144:                AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
                   1145:                AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
                   1146:
                   1147:                /*
                   1148:                 * Set the PREQDIS bit for H2B which disables some workaround
                   1149:                 * that doesn't work on regular PCI busses.
                   1150:                 * XXX - Find out exactly what this does from the hardware
                   1151:                 *       folks!
                   1152:                 */
                   1153:                devconfig1 = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG1);
                   1154:                pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG1, devconfig1|PREQDIS);
                   1155:                devconfig1 = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG1);
                   1156:        }
                   1157:
                   1158:        return (0);
                   1159: }

CVSweb