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

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

1.1       nbrk        1: /*     $OpenBSD: isp_pci.c,v 1.39 2007/02/28 19:40:38 kettenis Exp $   */
                      2: /*
                      3:  * PCI specific probe and attach routines for Qlogic ISP SCSI adapters.
                      4:  *
                      5:  *---------------------------------------
                      6:  * Copyright (c) 1997, 1998, 1999 by Matthew Jacob
                      7:  * NASA/Ames Research Center
                      8:  * All rights reserved.
                      9:  *---------------------------------------
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice immediately at the beginning of the file, without modification,
                     16:  *    this list of conditions, and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
                     27:  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  *
                     35:  */
                     36:
                     37: #include <dev/ic/isp_openbsd.h>
                     38:
                     39: #include <dev/pci/pcireg.h>
                     40: #include <dev/pci/pcivar.h>
                     41: #include <dev/pci/pcidevs.h>
                     42:
                     43: #ifdef __sparc64__
                     44: #include <dev/ofw/openfirm.h>
                     45: #endif
                     46:
                     47: static u_int16_t isp_pci_rd_reg(struct ispsoftc *, int);
                     48: static void isp_pci_wr_reg(struct ispsoftc *, int, u_int16_t);
                     49: #if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
                     50: static u_int16_t isp_pci_rd_reg_1080(struct ispsoftc *, int);
                     51: static void isp_pci_wr_reg_1080(struct ispsoftc *, int, u_int16_t);
                     52: #endif
                     53: static int
                     54: isp_pci_rd_isr(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
                     55: #ifndef        ISP_DISABLE_2300_SUPPORT
                     56: static int
                     57: isp_pci_rd_isr_2300(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
                     58: #endif
                     59: static int isp_pci_mbxdma(struct ispsoftc *);
                     60: static int isp_pci_dmasetup(struct ispsoftc *, struct scsi_xfer *,
                     61:        ispreq_t *, u_int16_t *, u_int16_t);
                     62: static void
                     63: isp_pci_dmateardown (struct ispsoftc *, struct scsi_xfer *, u_int16_t);
                     64: static void isp_pci_reset1 (struct ispsoftc *);
                     65: static void isp_pci_dumpregs (struct ispsoftc *, const char *);
                     66: static int isp_pci_intr (void *);
                     67:
                     68: #ifdef ISP_COMPILE_FW
                     69: #define        ISP_COMPILE_1040_FW     1
                     70: #define        ISP_COMPILE_1080_FW     1
                     71: #define        ISP_COMPILE_12160_FW    1
                     72: #define        ISP_COMPILE_2100_FW     1
                     73: #define        ISP_COMPILE_2200_FW     1
                     74: #define        ISP_COMPILE_2300_FW     1
                     75: #endif
                     76:
                     77: #if    defined(ISP_DISABLE_1040_SUPPORT) || !defined(ISP_COMPILE_1040_FW)
                     78: #define        ISP_1040_RISC_CODE      NULL
                     79: #else
                     80: #define        ISP_1040_RISC_CODE      (u_int16_t *) isp_1040_risc_code
                     81: #include <dev/microcode/isp/asm_1040.h>
                     82: #endif
                     83:
                     84: #if    defined(ISP_DISABLE_1080_SUPPORT) || !defined(ISP_COMPILE_1080_FW)
                     85: #define        ISP_1080_RISC_CODE      NULL
                     86: #else
                     87: #define        ISP_1080_RISC_CODE      (u_int16_t *) isp_1080_risc_code
                     88: #include <dev/microcode/isp/asm_1080.h>
                     89: #endif
                     90:
                     91: #if    defined(ISP_DISABLE_12160_SUPPORT) || !defined(ISP_COMPILE_12160_FW)
                     92: #define        ISP_12160_RISC_CODE     (u_int16_t *) NULL
                     93: #else
                     94: #define        ISP_12160_RISC_CODE     (u_int16_t *) isp_12160_risc_code
                     95: #include <dev/microcode/isp/asm_12160.h>
                     96: #endif
                     97:
                     98: #if    defined(ISP_DISABLE_2100_SUPPORT) || !defined(ISP_COMPILE_2100_FW)
                     99: #define        ISP_2100_RISC_CODE      NULL
                    100: #else
                    101: #define        ISP_2100_RISC_CODE      (u_int16_t *) isp_2100_risc_code
                    102: #include <dev/microcode/isp/asm_2100.h>
                    103: #endif
                    104:
                    105: #if    defined(ISP_DISABLE_2200_SUPPORT) || !defined(ISP_COMPILE_2200_FW)
                    106: #define        ISP_2200_RISC_CODE      NULL
                    107: #else
                    108: #define        ISP_2200_RISC_CODE      (u_int16_t *) isp_2200_risc_code
                    109: #include <dev/microcode/isp/asm_2200.h>
                    110: #endif
                    111:
                    112: #if    defined(ISP_DISABLE_2300_SUPPORT) || !defined(ISP_COMPILE_2300_FW)
                    113: #define        ISP_2300_RISC_CODE      NULL
                    114: #else
                    115: #define        ISP_2300_RISC_CODE      (u_int16_t *) isp_2300_risc_code
                    116: #include <dev/microcode/isp/asm_2300.h>
                    117: #endif
                    118:
                    119: #ifndef        ISP_DISABLE_1020_SUPPORT
                    120: static struct ispmdvec mdvec = {
                    121:        isp_pci_rd_isr,
                    122:        isp_pci_rd_reg,
                    123:        isp_pci_wr_reg,
                    124:        isp_pci_mbxdma,
                    125:        isp_pci_dmasetup,
                    126:        isp_pci_dmateardown,
                    127:        NULL,
                    128:        isp_pci_reset1,
                    129:        isp_pci_dumpregs,
                    130:        ISP_1040_RISC_CODE,
                    131:        BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
                    132: };
                    133: #endif
                    134:
                    135: #ifndef        ISP_DISABLE_1080_SUPPORT
                    136: static struct ispmdvec mdvec_1080 = {
                    137:        isp_pci_rd_isr,
                    138:        isp_pci_rd_reg_1080,
                    139:        isp_pci_wr_reg_1080,
                    140:        isp_pci_mbxdma,
                    141:        isp_pci_dmasetup,
                    142:        isp_pci_dmateardown,
                    143:        NULL,
                    144:        isp_pci_reset1,
                    145:        isp_pci_dumpregs,
                    146:        ISP_1080_RISC_CODE,
                    147:        BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
                    148: };
                    149: #endif
                    150:
                    151: #ifndef        ISP_DISABLE_12160_SUPPORT
                    152: static struct ispmdvec mdvec_12160 = {
                    153:        isp_pci_rd_isr,
                    154:        isp_pci_rd_reg_1080,
                    155:        isp_pci_wr_reg_1080,
                    156:        isp_pci_mbxdma,
                    157:        isp_pci_dmasetup,
                    158:        isp_pci_dmateardown,
                    159:        NULL,
                    160:        isp_pci_reset1,
                    161:        isp_pci_dumpregs,
                    162:        ISP_12160_RISC_CODE,
                    163:        BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
                    164: };
                    165: #endif
                    166:
                    167: #ifndef        ISP_DISABLE_2100_SUPPORT
                    168: static struct ispmdvec mdvec_2100 = {
                    169:        isp_pci_rd_isr,
                    170:        isp_pci_rd_reg,
                    171:        isp_pci_wr_reg,
                    172:        isp_pci_mbxdma,
                    173:        isp_pci_dmasetup,
                    174:        isp_pci_dmateardown,
                    175:        NULL,
                    176:        isp_pci_reset1,
                    177:        isp_pci_dumpregs,
                    178:        ISP_2100_RISC_CODE
                    179: };
                    180: #endif
                    181:
                    182: #ifndef        ISP_DISABLE_2200_SUPPORT
                    183: static struct ispmdvec mdvec_2200 = {
                    184:        isp_pci_rd_isr,
                    185:        isp_pci_rd_reg,
                    186:        isp_pci_wr_reg,
                    187:        isp_pci_mbxdma,
                    188:        isp_pci_dmasetup,
                    189:        isp_pci_dmateardown,
                    190:        NULL,
                    191:        isp_pci_reset1,
                    192:        isp_pci_dumpregs,
                    193:        ISP_2200_RISC_CODE
                    194: };
                    195: #endif
                    196:
                    197: #ifndef        ISP_DISABLE_2300_SUPPORT
                    198: static struct ispmdvec mdvec_2300 = {
                    199:        isp_pci_rd_isr_2300,
                    200:        isp_pci_rd_reg,
                    201:        isp_pci_wr_reg,
                    202:        isp_pci_mbxdma,
                    203:        isp_pci_dmasetup,
                    204:        isp_pci_dmateardown,
                    205:        NULL,
                    206:        isp_pci_reset1,
                    207:        isp_pci_dumpregs,
                    208:        ISP_2300_RISC_CODE
                    209: };
                    210: #endif
                    211:
                    212: #ifndef        PCI_VENDOR_QLOGIC
                    213: #define        PCI_VENDOR_QLOGIC       0x1077
                    214: #endif
                    215:
                    216: #ifndef        PCI_PRODUCT_QLOGIC_ISP1020
                    217: #define        PCI_PRODUCT_QLOGIC_ISP1020      0x1020
                    218: #endif
                    219:
                    220: #ifndef        PCI_PRODUCT_QLOGIC_ISP1080
                    221: #define        PCI_PRODUCT_QLOGIC_ISP1080      0x1080
                    222: #endif
                    223:
                    224: #ifndef        PCI_PRODUCT_QLOGIC_ISP1240
                    225: #define        PCI_PRODUCT_QLOGIC_ISP1240      0x1240
                    226: #endif
                    227:
                    228: #ifndef        PCI_PRODUCT_QLOGIC_ISP1280
                    229: #define        PCI_PRODUCT_QLOGIC_ISP1280      0x1280
                    230: #endif
                    231:
                    232: #ifndef        PCI_PRODUCT_QLOGIC_ISP10160
                    233: #define        PCI_PRODUCT_QLOGIC_ISP10160     0x1016
                    234: #endif
                    235:
                    236: #ifndef        PCI_PRODUCT_QLOGIC_ISP12160
                    237: #define        PCI_PRODUCT_QLOGIC_ISP12160     0x1216
                    238: #endif
                    239:
                    240: #ifndef        PCI_PRODUCT_QLOGIC_ISP2100
                    241: #define        PCI_PRODUCT_QLOGIC_ISP2100      0x2100
                    242: #endif
                    243:
                    244: #ifndef        PCI_PRODUCT_QLOGIC_ISP2200
                    245: #define        PCI_PRODUCT_QLOGIC_ISP2200      0x2200
                    246: #endif
                    247:
                    248: #ifndef        PCI_PRODUCT_QLOGIC_ISP2300
                    249: #define        PCI_PRODUCT_QLOGIC_ISP2300      0x2300
                    250: #endif
                    251:
                    252: #ifndef        PCI_PRODUCT_QLOGIC_ISP2312
                    253: #define        PCI_PRODUCT_QLOGIC_ISP2312      0x2312
                    254: #endif
                    255:
                    256: #ifndef        PCI_PRODUCT_QLOGIC_ISP6312
                    257: #define        PCI_PRODUCT_QLOGIC_ISP6312      0x6312
                    258: #endif
                    259:
                    260: #define        PCI_QLOGIC_ISP  ((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC)
                    261:
                    262: #define        PCI_QLOGIC_ISP1080      \
                    263:        ((PCI_PRODUCT_QLOGIC_ISP1080 << 16) | PCI_VENDOR_QLOGIC)
                    264:
                    265: #define        PCI_QLOGIC_ISP1240      \
                    266:        ((PCI_PRODUCT_QLOGIC_ISP1240 << 16) | PCI_VENDOR_QLOGIC)
                    267:
                    268: #define        PCI_QLOGIC_ISP1280      \
                    269:        ((PCI_PRODUCT_QLOGIC_ISP1280 << 16) | PCI_VENDOR_QLOGIC)
                    270:
                    271: #define        PCI_QLOGIC_ISP10160     \
                    272:        ((PCI_PRODUCT_QLOGIC_ISP10160 << 16) | PCI_VENDOR_QLOGIC)
                    273:
                    274: #define        PCI_QLOGIC_ISP12160     \
                    275:        ((PCI_PRODUCT_QLOGIC_ISP12160 << 16) | PCI_VENDOR_QLOGIC)
                    276:
                    277: #define        PCI_QLOGIC_ISP2100      \
                    278:        ((PCI_PRODUCT_QLOGIC_ISP2100 << 16) | PCI_VENDOR_QLOGIC)
                    279:
                    280: #define        PCI_QLOGIC_ISP2200      \
                    281:        ((PCI_PRODUCT_QLOGIC_ISP2200 << 16) | PCI_VENDOR_QLOGIC)
                    282:
                    283: #define        PCI_QLOGIC_ISP2300      \
                    284:        ((PCI_PRODUCT_QLOGIC_ISP2300 << 16) | PCI_VENDOR_QLOGIC)
                    285:
                    286: #define        PCI_QLOGIC_ISP2312      \
                    287:        ((PCI_PRODUCT_QLOGIC_ISP2312 << 16) | PCI_VENDOR_QLOGIC)
                    288:
                    289: #define        PCI_QLOGIC_ISP6312      \
                    290:        ((PCI_PRODUCT_QLOGIC_ISP6312 << 16) | PCI_VENDOR_QLOGIC)
                    291:
                    292: /*
                    293:  * Odd case for some AMI raid cards... We need to *not* attach to this.
                    294:  */
                    295: #define        AMI_RAID_SUBVENDOR_ID   0x101e
                    296:
                    297:
                    298: #define IO_MAP_REG     0x10
                    299: #define MEM_MAP_REG    0x14
                    300: #define        PCIR_ROMADDR    0x30
                    301:
                    302: #define        PCI_DFLT_LTNCY  0x40
                    303: #define        PCI_DFLT_LNSZ   0x10
                    304:
                    305: #ifndef SCSI_ISP_PREFER_MEM_MAP
                    306: #ifdef __alpha__
                    307: #define SCSI_ISP_PREFER_MEM_MAP 1
                    308: #else
                    309: #define SCSI_ISP_PREFER_MEM_MAP 0
                    310: #endif
                    311: #endif
                    312:
                    313: #ifndef        BUS_DMA_COHERENT
                    314: #define        BUS_DMA_COHERENT        BUS_DMAMEM_NOSYNC
                    315: #endif
                    316:
                    317: static int isp_pci_probe (struct device *, void *, void *);
                    318: static void isp_pci_attach (struct device *, struct device *, void *);
                    319:
                    320: struct isp_pcisoftc {
                    321:        struct ispsoftc         pci_isp;
                    322:        pci_chipset_tag_t       pci_pc;
                    323:        pcitag_t                pci_tag;
                    324:        bus_space_tag_t         pci_st;
                    325:        bus_space_handle_t      pci_sh;
                    326:        bus_dmamap_t            *pci_xfer_dmap;
                    327:        void *                  pci_ih;
                    328:        int16_t                 pci_poff[_NREG_BLKS];
                    329: };
                    330:
                    331: struct cfattach isp_pci_ca = {
                    332:        sizeof (struct isp_pcisoftc), isp_pci_probe, isp_pci_attach
                    333: };
                    334:
                    335: #ifdef  DEBUG
                    336: const char vstring[] =
                    337:     "Qlogic ISP Driver, NetBSD (pci) Platform Version %d.%d Core Version %d.%d";
                    338: #endif
                    339:
                    340: const struct pci_matchid ispdev[] = {
                    341: #ifndef        ISP_DISABLE_1020_SUPPORT
                    342:        { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1020 },
                    343: #endif
                    344: #ifndef        ISP_DISABLE_1080_SUPPORT
                    345:        { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1080 },
                    346:        { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1240 },
                    347:        { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1280 },
                    348: #endif
                    349: #ifndef        ISP_DISABLE_12160_SUPPORT
                    350:        { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP10160 },
                    351:        { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP12160 },
                    352: #endif
                    353: #ifndef        ISP_DISABLE_2100_SUPPORT
                    354:        { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2100 },
                    355: #endif
                    356: #ifndef        ISP_DISABLE_2200_SUPPORT
                    357:        { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2200 },
                    358: #endif
                    359: #ifndef        ISP_DISABLE_2300_SUPPORT
                    360:        { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2300 },
                    361:        { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2312 },
                    362:        { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP6312 },
                    363: #endif
                    364:        { 0, 0 }
                    365: };
                    366:
                    367: static int
                    368: isp_pci_probe(struct device *parent, void *match, void *aux)
                    369: {
                    370:         struct pci_attach_args *pa = aux;
                    371:
                    372: #ifndef        ISP_DISABLE_12160_SUPPORT
                    373:        /*
                    374:         * Sigh. Check for subvendor id match here. Too bad we
                    375:         * can't give an exclude mask in matchbyid.
                    376:         */
                    377:         if (pa->pa_id == PCI_QLOGIC_ISP12160) {
                    378:                pcireg_t subvid =
                    379:                    pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBVEND_0);
                    380:                if (PCI_VENDOR(subvid) == AMI_RAID_SUBVENDOR_ID) {
                    381:                        return (0);
                    382:                 }
                    383:        }
                    384: #endif
                    385:        return (pci_matchbyid(pa, ispdev, sizeof(ispdev)/sizeof(ispdev[0])));
                    386: }
                    387:
                    388:
                    389: static void
                    390: isp_pci_attach(struct device *parent, struct device *self, void *aux)
                    391: {
                    392: #ifdef DEBUG
                    393:        static char oneshot = 1;
                    394: #endif
                    395:        static const char nomem[] = ": no mem for sdparam table\n";
                    396:        u_int32_t data, rev, linesz = PCI_DFLT_LNSZ;
                    397:        struct pci_attach_args *pa = aux;
                    398:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) self;
                    399:        struct ispsoftc *isp = &pcs->pci_isp;
                    400:        bus_space_tag_t st, iot, memt;
                    401:        bus_space_handle_t sh, ioh, memh;
                    402:        pci_intr_handle_t ih;
                    403:        const char *intrstr;
                    404:        int ioh_valid, memh_valid;
                    405:        bus_size_t iosize, msize;
                    406:        u_int32_t confopts = 0;
                    407:
                    408:        ioh_valid = memh_valid = 0;
                    409:
                    410: #if    SCSI_ISP_PREFER_MEM_MAP == 1
                    411:        if (pci_mapreg_map(pa, MEM_MAP_REG, PCI_MAPREG_TYPE_MEM, 0,
                    412:            &memt, &memh, NULL, &msize, 0)) {
                    413:                printf(": can't map mem space\n");
                    414:        } else  {
                    415:                st = memt;
                    416:                sh = memh;
                    417:                memh_valid = 1;
                    418:        }
                    419:        if (memh_valid == 0) {
                    420:                if (pci_mapreg_map(pa, IO_MAP_REG, PCI_MAPREG_TYPE_IO, 0,
                    421:                    &iot, &ioh, NULL, &iosize, 0)) {
                    422:                } else {
                    423:                        st = iot;
                    424:                        sh = ioh;
                    425:                        ioh_valid = 1;
                    426:                }
                    427:        }
                    428: #else
                    429:        if (pci_mapreg_map(pa, IO_MAP_REG, PCI_MAPREG_TYPE_IO, 0,
                    430:            &iot, &ioh, NULL, &iosize, 0)) {
                    431:                printf(": can't map i/o space\n");
                    432:        } else {
                    433:                st = iot;
                    434:                sh = ioh;
                    435:                ioh_valid = 1;
                    436:        }
                    437:        if (ioh_valid == 0) {
                    438:                if (pci_mapreg_map(pa, MEM_MAP_REG, PCI_MAPREG_TYPE_MEM, 0,
                    439:                    &memt, &memh, NULL, &msize, 0)) {
                    440:                        printf(": can't map mem space\n");
                    441:                } else  {
                    442:                        st = memt;
                    443:                        sh = memh;
                    444:                        memh_valid = 1;
                    445:                }
                    446:        }
                    447: #endif
                    448:        if (ioh_valid == 0 && memh_valid == 0) {
                    449:                printf(": unable to map device registers\n");
                    450:                return;
                    451:        }
                    452: #if 0
                    453:        printf("\n");
                    454: #endif
                    455:
                    456:        pcs->pci_st = st;
                    457:        pcs->pci_sh = sh;
                    458:        pcs->pci_pc = pa->pa_pc;
                    459:        pcs->pci_tag = pa->pa_tag;
                    460:        pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
                    461:        pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;
                    462:        pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;
                    463:        pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;
                    464:        pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
                    465:        rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0xff;
                    466: #ifndef        ISP_DISABLE_1020_SUPPORT
                    467:        if (pa->pa_id == PCI_QLOGIC_ISP) {
                    468:                isp->isp_mdvec = &mdvec;
                    469:                isp->isp_type = ISP_HA_SCSI_UNKNOWN;
                    470:                isp->isp_param = malloc(sizeof (sdparam), M_DEVBUF, M_NOWAIT);
                    471:                if (isp->isp_param == NULL) {
                    472:                        printf(nomem);
                    473:                        return;
                    474:                }
                    475:                bzero(isp->isp_param, sizeof (sdparam));
                    476:        }
                    477: #endif
                    478: #ifndef        ISP_DISABLE_1080_SUPPORT
                    479:        if (pa->pa_id == PCI_QLOGIC_ISP1080) {
                    480:                isp->isp_mdvec = &mdvec_1080;
                    481:                isp->isp_type = ISP_HA_SCSI_1080;
                    482:                isp->isp_param = malloc(sizeof (sdparam), M_DEVBUF, M_NOWAIT);
                    483:                if (isp->isp_param == NULL) {
                    484:                        printf(nomem);
                    485:                        return;
                    486:                }
                    487:                bzero(isp->isp_param, sizeof (sdparam));
                    488:                pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
                    489:                    ISP1080_DMA_REGS_OFF;
                    490:        }
                    491:        if (pa->pa_id == PCI_QLOGIC_ISP1240) {
                    492:                isp->isp_mdvec = &mdvec_1080;
                    493:                isp->isp_type = ISP_HA_SCSI_1240;
                    494:                isp->isp_param = malloc(2 * sizeof (sdparam),
                    495:                    M_DEVBUF, M_NOWAIT);
                    496:                if (isp->isp_param == NULL) {
                    497:                        printf(nomem);
                    498:                        return;
                    499:                }
                    500:                bzero(isp->isp_param, sizeof (sdparam));
                    501:                pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
                    502:                    ISP1080_DMA_REGS_OFF;
                    503:        }
                    504:        if (pa->pa_id == PCI_QLOGIC_ISP1280) {
                    505:                isp->isp_mdvec = &mdvec_1080;
                    506:                isp->isp_type = ISP_HA_SCSI_1280;
                    507:                isp->isp_param = malloc(2 * sizeof (sdparam),
                    508:                    M_DEVBUF, M_NOWAIT);
                    509:                if (isp->isp_param == NULL) {
                    510:                        printf(nomem);
                    511:                        return;
                    512:                }
                    513:                bzero(isp->isp_param, sizeof (sdparam));
                    514:                pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
                    515:                    ISP1080_DMA_REGS_OFF;
                    516:        }
                    517: #endif
                    518: #ifndef        ISP_DISABLE_12160_SUPPORT
                    519:        if (pa->pa_id == PCI_QLOGIC_ISP10160) {
                    520:                isp->isp_mdvec = &mdvec_12160;
                    521:                isp->isp_type = ISP_HA_SCSI_10160;
                    522:                isp->isp_param = malloc(sizeof (sdparam), M_DEVBUF, M_NOWAIT);
                    523:                if (isp->isp_param == NULL) {
                    524:                        printf(nomem);
                    525:                        return;
                    526:                }
                    527:                bzero(isp->isp_param, sizeof (sdparam));
                    528:                pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
                    529:                    ISP1080_DMA_REGS_OFF;
                    530:        }
                    531:        if (pa->pa_id == PCI_QLOGIC_ISP12160) {
                    532:                isp->isp_mdvec = &mdvec_12160;
                    533:                isp->isp_type = ISP_HA_SCSI_12160;
                    534:                isp->isp_param = malloc(2 * sizeof (sdparam),
                    535:                    M_DEVBUF, M_NOWAIT);
                    536:                if (isp->isp_param == NULL) {
                    537:                        printf(nomem);
                    538:                        return;
                    539:                }
                    540:                bzero(isp->isp_param, 2 * sizeof (sdparam));
                    541:                pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
                    542:                    ISP1080_DMA_REGS_OFF;
                    543:        }
                    544: #endif
                    545: #ifndef        ISP_DISABLE_2100_SUPPORT
                    546:        if (pa->pa_id == PCI_QLOGIC_ISP2100) {
                    547:                isp->isp_mdvec = &mdvec_2100;
                    548:                isp->isp_type = ISP_HA_FC_2100;
                    549:                isp->isp_param = malloc(sizeof (fcparam), M_DEVBUF, M_NOWAIT);
                    550:                if (isp->isp_param == NULL) {
                    551:                        printf(nomem);
                    552:                        return;
                    553:                }
                    554:                bzero(isp->isp_param, sizeof (fcparam));
                    555:                pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
                    556:                    PCI_MBOX_REGS2100_OFF;
                    557:                if (rev < 3) {
                    558:                        /*
                    559:                         * XXX: Need to get the actual revision
                    560:                         * XXX: number of the 2100 FB. At any rate,
                    561:                         * XXX: lower cache line size for early revision
                    562:                         * XXX; boards.
                    563:                         */
                    564:                        linesz = 1;
                    565:                }
                    566:        }
                    567: #endif
                    568: #ifndef        ISP_DISABLE_2200_SUPPORT
                    569:        if (pa->pa_id == PCI_QLOGIC_ISP2200) {
                    570:                isp->isp_mdvec = &mdvec_2200;
                    571:                isp->isp_type = ISP_HA_FC_2200;
                    572:                isp->isp_param = malloc(sizeof (fcparam), M_DEVBUF, M_NOWAIT);
                    573:                if (isp->isp_param == NULL) {
                    574:                        printf(nomem);
                    575:                        return;
                    576:                }
                    577:                bzero(isp->isp_param, sizeof (fcparam));
                    578:                pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
                    579:                    PCI_MBOX_REGS2100_OFF;
                    580:                data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG);
                    581: #ifdef __sparc64__
                    582:                {
                    583:                        char name[32];
                    584:
                    585:                        bzero(name, sizeof(name));
                    586:                        OF_getprop(PCITAG_NODE(pa->pa_tag),
                    587:                            "name", name, sizeof(name));
                    588:                        if (strcmp(name, "SUNW,qlc") == 0)
                    589:                                confopts |= ISP_CFG_NONVRAM;
                    590:                }
                    591: #endif
                    592:        }
                    593: #endif
                    594: #ifndef        ISP_DISABLE_2300_SUPPORT
                    595:        if (pa->pa_id == PCI_QLOGIC_ISP2300 ||
                    596:            pa->pa_id == PCI_QLOGIC_ISP2312 ||
                    597:            pa->pa_id == PCI_QLOGIC_ISP6312) {
                    598:                isp->isp_mdvec = &mdvec_2300;
                    599:                if (pa->pa_id  == PCI_QLOGIC_ISP2300) {
                    600:                        isp->isp_type = ISP_HA_FC_2300;
                    601:                } else {
                    602:                        isp->isp_type = ISP_HA_FC_2312;
                    603:                        isp->isp_port = pa->pa_function;
                    604:                }
                    605:                isp->isp_param = malloc(sizeof (fcparam), M_DEVBUF, M_NOWAIT);
                    606:                if (isp->isp_param == NULL) {
                    607:                        printf(nomem);
                    608:                        return;
                    609:                }
                    610:                bzero(isp->isp_param, sizeof (fcparam));
                    611:                pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
                    612:                    PCI_MBOX_REGS2300_OFF;
                    613:                data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG);
                    614:        }
                    615: #endif
                    616:        /*
                    617:         * Set up logging levels.
                    618:         */
                    619: #ifdef ISP_LOGDEFAULT
                    620:        isp->isp_dblev = ISP_LOGDEFAULT;
                    621: #else
                    622:        isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR;
                    623: #ifdef SCSIDEBUG
                    624:        isp->isp_dblev |= ISP_LOGDEBUG1|ISP_LOGDEBUG2;
                    625: #endif
                    626: #ifdef DEBUG
                    627:        isp->isp_dblev |= ISP_LOGDEBUG0|ISP_LOGCONFIG|ISP_LOGINFO;
                    628: #endif
                    629: #endif
                    630:
                    631: #ifdef DEBUG
                    632:        if (oneshot) {
                    633:                oneshot = 0;
                    634:                isp_prt(isp, ISP_LOGCONFIG, vstring,
                    635:                    ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,
                    636:                    ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR);
                    637:        }
                    638: #endif
                    639:
                    640:        isp->isp_dmatag = pa->pa_dmat;
                    641:        isp->isp_revision = rev;
                    642:
                    643:        /*
                    644:         * Make sure that command register set sanely.
                    645:         */
                    646:        data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
                    647:        if (IS_2300(isp)) {     /* per QLogic errata */
                    648:                data &= ~PCI_COMMAND_PARITY_ENABLE;
                    649:        }
                    650:        if (IS_23XX(isp)) {
                    651:                isp->isp_touched = 1;
                    652:        }
                    653:        data |= PCI_COMMAND_INVALIDATE_ENABLE;
                    654:
                    655:        /*
                    656:         * Not so sure about these- but I think it's important that they get
                    657:         * enabled......
                    658:         */
                    659:        data |= PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE;
                    660:        pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, data);
                    661:
                    662:        /*
                    663:         * Make sure that the latency timer, cache line size,
                    664:         * and ROM is disabled.
                    665:         */
                    666:        data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
                    667:        data &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
                    668:        data &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT);
                    669:        data |= (0x40 << PCI_LATTIMER_SHIFT);
                    670:        data |= (0x10 << PCI_CACHELINE_SHIFT);
                    671:        pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, data);
                    672:
                    673:        data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCIR_ROMADDR);
                    674:        data &= ~1;
                    675:        pci_conf_write(pa->pa_pc, pa->pa_tag, PCIR_ROMADDR, data);
                    676:
                    677:        if (pci_intr_map(pa, &ih)) {
                    678:                printf(": couldn't map interrupt\n");
                    679:                free(isp->isp_param, M_DEVBUF);
                    680:                return;
                    681:        }
                    682:        intrstr = pci_intr_string(pa->pa_pc, ih);
                    683:        if (intrstr == NULL)
                    684:                intrstr = "<I dunno>";
                    685:        pcs->pci_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, isp_pci_intr,
                    686:            isp, isp->isp_name);
                    687:        if (pcs->pci_ih == NULL) {
                    688:                printf(": couldn't establish interrupt at %s\n",
                    689:                        intrstr);
                    690:                free(isp->isp_param, M_DEVBUF);
                    691:                return;
                    692:        }
                    693:
                    694:        printf(": %s\n", intrstr);
                    695:
                    696:        if (IS_FC(isp)) {
                    697:                DEFAULT_NODEWWN(isp) = 0x400000007F000003ULL;
                    698:                DEFAULT_PORTWWN(isp) = 0x400000007F000003ULL;
                    699:        }
                    700:
                    701:        isp->isp_confopts = confopts | self->dv_cfdata->cf_flags;
                    702:        isp->isp_role = ISP_DEFAULT_ROLES;
                    703:        ISP_LOCK(isp);
                    704:        isp->isp_osinfo.no_mbox_ints = 1;
                    705:        isp_reset(isp);
                    706:        if (isp->isp_state != ISP_RESETSTATE) {
                    707:                ISP_UNLOCK(isp);
                    708:                free(isp->isp_param, M_DEVBUF);
                    709:                return;
                    710:        }
                    711:        ENABLE_INTS(isp);
                    712:        isp_init(isp);
                    713:        if (isp->isp_state != ISP_INITSTATE) {
                    714:                isp_uninit(isp);
                    715:                ISP_UNLOCK(isp);
                    716:                free(isp->isp_param, M_DEVBUF);
                    717:                return;
                    718:        }
                    719:        /*
                    720:         * Do Generic attach now.
                    721:         */
                    722:        isp_attach(isp);
                    723:        if (isp->isp_state != ISP_RUNSTATE) {
                    724:                isp_uninit(isp);
                    725:                ISP_UNLOCK(isp);
                    726:                free(isp->isp_param, M_DEVBUF);
                    727:        } else {
                    728:                ISP_UNLOCK(isp);
                    729:        }
                    730: }
                    731:
                    732: #define        IspVirt2Off(a, x)       \
                    733:        (((struct isp_pcisoftc *)a)->pci_poff[((x) & _BLK_REG_MASK) >> \
                    734:        _BLK_REG_SHFT] + ((x) & 0xff))
                    735:
                    736: #define        BXR2(pcs, off)          \
                    737:        bus_space_read_2(pcs->pci_st, pcs->pci_sh, off)
                    738: #define        BXW2(pcs, off, v)       \
                    739:        bus_space_write_2(pcs->pci_st, pcs->pci_sh, off, v)
                    740:
                    741:
                    742: static INLINE int
                    743: isp_pci_rd_debounced(struct ispsoftc *isp, int off, u_int16_t *rp)
                    744: {
                    745:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
                    746:        u_int16_t val0, val1;
                    747:        int i = 0;
                    748:
                    749:        do {
                    750:                val0 = BXR2(pcs, IspVirt2Off(isp, off));
                    751:                val1 = BXR2(pcs, IspVirt2Off(isp, off));
                    752:        } while (val0 != val1 && ++i < 1000);
                    753:        if (val0 != val1) {
                    754:                return (1);
                    755:        }
                    756:        *rp = val0;
                    757:        return (0);
                    758: }
                    759:
                    760: static int
                    761: isp_pci_rd_isr(struct ispsoftc *isp, u_int16_t *isrp,
                    762:     u_int16_t *semap, u_int16_t *mbp)
                    763: {
                    764:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
                    765:        u_int16_t isr, sema;
                    766:
                    767:        if (IS_2100(isp)) {
                    768:                if (isp_pci_rd_debounced(isp, BIU_ISR, &isr)) {
                    769:                    return (0);
                    770:                }
                    771:                if (isp_pci_rd_debounced(isp, BIU_SEMA, &sema)) {
                    772:                    return (0);
                    773:                }
                    774:        } else {
                    775:                isr = BXR2(pcs, IspVirt2Off(isp, BIU_ISR));
                    776:                sema = BXR2(pcs, IspVirt2Off(isp, BIU_SEMA));
                    777:        }
                    778:        isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema);
                    779:        isr &= INT_PENDING_MASK(isp);
                    780:        sema &= BIU_SEMA_LOCK;
                    781:        if (isr == 0 && sema == 0) {
                    782:                return (0);
                    783:        }
                    784:        *isrp = isr;
                    785:        if ((*semap = sema) != 0) {
                    786:                if (IS_2100(isp)) {
                    787:                        if (isp_pci_rd_debounced(isp, OUTMAILBOX0, mbp)) {
                    788:                                return (0);
                    789:                        }
                    790:                } else {
                    791:                        *mbp = BXR2(pcs, IspVirt2Off(isp, OUTMAILBOX0));
                    792:                }
                    793:        }
                    794:        return (1);
                    795: }
                    796:
                    797: #ifndef        ISP_DISABLE_2300_SUPPORT
                    798: static int
                    799: isp_pci_rd_isr_2300(struct ispsoftc *isp, u_int16_t *isrp,
                    800:     u_int16_t *semap, u_int16_t *mbox0p)
                    801: {
                    802:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
                    803:        u_int32_t r2hisr;
                    804:
                    805:        if (!(BXR2(pcs, IspVirt2Off(isp, BIU_ISR)) & BIU2100_ISR_RISC_INT)) {
                    806:                *isrp = 0;
                    807:                return (0);
                    808:        }
                    809:        r2hisr = bus_space_read_4(pcs->pci_st, pcs->pci_sh,
                    810:            IspVirt2Off(pcs, BIU_R2HSTSLO));
                    811:        isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
                    812:        if ((r2hisr & BIU_R2HST_INTR) == 0) {
                    813:                *isrp = 0;
                    814:                return (0);
                    815:        }
                    816:        switch (r2hisr & BIU_R2HST_ISTAT_MASK) {
                    817:        case ISPR2HST_ROM_MBX_OK:
                    818:        case ISPR2HST_ROM_MBX_FAIL:
                    819:        case ISPR2HST_MBX_OK:
                    820:        case ISPR2HST_MBX_FAIL:
                    821:        case ISPR2HST_ASYNC_EVENT:
                    822:                *isrp = r2hisr & 0xffff;
                    823:                *mbox0p = (r2hisr >> 16);
                    824:                *semap = 1;
                    825:                return (1);
                    826:        case ISPR2HST_RIO_16:
                    827:                *isrp = r2hisr & 0xffff;
                    828:                *mbox0p = ASYNC_RIO1;
                    829:                *semap = 1;
                    830:                return (1);
                    831:        case ISPR2HST_FPOST:
                    832:                *isrp = r2hisr & 0xffff;
                    833:                *mbox0p = ASYNC_CMD_CMPLT;
                    834:                *semap = 1;
                    835:                return (1);
                    836:        case ISPR2HST_FPOST_CTIO:
                    837:                *isrp = r2hisr & 0xffff;
                    838:                *mbox0p = ASYNC_CTIO_DONE;
                    839:                *semap = 1;
                    840:                return (1);
                    841:        case ISPR2HST_RSPQ_UPDATE:
                    842:                *isrp = r2hisr & 0xffff;
                    843:                *mbox0p = 0;
                    844:                *semap = 0;
                    845:                return (1);
                    846:        default:
                    847:                return (0);
                    848:        }
                    849: }
                    850: #endif
                    851:
                    852: static u_int16_t
                    853: isp_pci_rd_reg(struct ispsoftc *isp, int regoff)
                    854: {
                    855:        u_int16_t rv;
                    856:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
                    857:        int oldconf = 0;
                    858:
                    859:        if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
                    860:                /*
                    861:                 * We will assume that someone has paused the RISC processor.
                    862:                 */
                    863:                oldconf = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
                    864:                BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
                    865:                    oldconf | BIU_PCI_CONF1_SXP);
                    866:        }
                    867:        rv = BXR2(pcs, IspVirt2Off(isp, regoff));
                    868:        if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
                    869:                BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oldconf);
                    870:        }
                    871:        return (rv);
                    872: }
                    873:
                    874: static void
                    875: isp_pci_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val)
                    876: {
                    877:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
                    878:        int oldconf = 0;
                    879:
                    880:        if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
                    881:                /*
                    882:                 * We will assume that someone has paused the RISC processor.
                    883:                 */
                    884:                oldconf = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
                    885:                BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
                    886:                    oldconf | BIU_PCI_CONF1_SXP);
                    887:        }
                    888:        BXW2(pcs, IspVirt2Off(isp, regoff), val);
                    889:        if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
                    890:                BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oldconf);
                    891:        }
                    892: }
                    893:
                    894: #if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
                    895: static u_int16_t
                    896: isp_pci_rd_reg_1080(struct ispsoftc *isp, int regoff)
                    897: {
                    898:        u_int16_t rv, oc = 0;
                    899:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
                    900:
                    901:        if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
                    902:            (regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
                    903:                u_int16_t tc;
                    904:                /*
                    905:                 * We will assume that someone has paused the RISC processor.
                    906:                 */
                    907:                oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
                    908:                tc = oc & ~BIU_PCI1080_CONF1_DMA;
                    909:                if (regoff & SXP_BANK1_SELECT)
                    910:                        tc |= BIU_PCI1080_CONF1_SXP1;
                    911:                else
                    912:                        tc |= BIU_PCI1080_CONF1_SXP0;
                    913:                BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), tc);
                    914:        } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
                    915:                oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
                    916:                BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
                    917:                    oc | BIU_PCI1080_CONF1_DMA);
                    918:        }
                    919:        rv = BXR2(pcs, IspVirt2Off(isp, regoff));
                    920:        if (oc) {
                    921:                BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oc);
                    922:        }
                    923:        return (rv);
                    924: }
                    925:
                    926: static void
                    927: isp_pci_wr_reg_1080(struct ispsoftc *isp, int regoff, u_int16_t val)
                    928: {
                    929:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
                    930:        int oc = 0;
                    931:
                    932:        if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
                    933:            (regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
                    934:                u_int16_t tc;
                    935:                /*
                    936:                 * We will assume that someone has paused the RISC processor.
                    937:                 */
                    938:                oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
                    939:                tc = oc & ~BIU_PCI1080_CONF1_DMA;
                    940:                if (regoff & SXP_BANK1_SELECT)
                    941:                        tc |= BIU_PCI1080_CONF1_SXP1;
                    942:                else
                    943:                        tc |= BIU_PCI1080_CONF1_SXP0;
                    944:                BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), tc);
                    945:        } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
                    946:                oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
                    947:                BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
                    948:                    oc | BIU_PCI1080_CONF1_DMA);
                    949:        }
                    950:        BXW2(pcs, IspVirt2Off(isp, regoff), val);
                    951:        if (oc) {
                    952:                BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oc);
                    953:        }
                    954: }
                    955: #endif
                    956:
                    957: static int
                    958: isp_pci_mbxdma(struct ispsoftc *isp)
                    959: {
                    960:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
                    961:        bus_dma_tag_t dmat = isp->isp_dmatag;
                    962:        bus_dma_segment_t sg;
                    963:        bus_size_t len;
                    964:        fcparam *fcp;
                    965:        int rs, i;
                    966:
                    967:        if (isp->isp_rquest_dma)        /* been here before? */
                    968:                return (0);
                    969:
                    970:        len = isp->isp_maxcmds * sizeof (XS_T *);
                    971:        isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK);
                    972:        if (isp->isp_xflist == NULL) {
                    973:                isp_prt(isp, ISP_LOGERR, "cannot malloc xflist array");
                    974:                return (1);
                    975:        }
                    976:        bzero(isp->isp_xflist, len);
                    977:        len = isp->isp_maxcmds * sizeof (bus_dmamap_t);
                    978:        pcs->pci_xfer_dmap = (bus_dmamap_t *) malloc(len, M_DEVBUF, M_WAITOK);
                    979:        if (pcs->pci_xfer_dmap == NULL) {
                    980:                free(isp->isp_xflist, M_DEVBUF);
                    981:                isp->isp_xflist = NULL;
                    982:                isp_prt(isp, ISP_LOGERR, "cannot malloc dma map array");
                    983:                return (1);
                    984:        }
                    985:
                    986:        for (i = 0; i < isp->isp_maxcmds; i++) {
                    987:                if (bus_dmamap_create(dmat, MAXPHYS, (MAXPHYS / NBPG) + 1,
                    988:                    MAXPHYS, 0, BUS_DMA_NOWAIT, &pcs->pci_xfer_dmap[i])) {
                    989:                        isp_prt(isp, ISP_LOGERR, "cannot create dma maps");
                    990:                        break;
                    991:                }
                    992:        }
                    993:
                    994:        if (i < isp->isp_maxcmds) {
                    995:                while (--i >= 0) {
                    996:                        bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]);
                    997:                }
                    998:                free(isp->isp_xflist, M_DEVBUF);
                    999:                free(pcs->pci_xfer_dmap, M_DEVBUF);
                   1000:                isp->isp_xflist = NULL;
                   1001:                pcs->pci_xfer_dmap = NULL;
                   1002:                return (1);
                   1003:        }
                   1004:
                   1005:        /*
                   1006:         * Allocate and map the request queue.
                   1007:         */
                   1008:        len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
                   1009:        if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
                   1010:                             BUS_DMA_NOWAIT) ||
                   1011:            bus_dmamem_map(isp->isp_dmatag, &sg, rs, len,
                   1012:            (caddr_t *)&isp->isp_rquest, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
                   1013:                goto dmafail;
                   1014:        }
                   1015:
                   1016:        if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
                   1017:            &isp->isp_rqdmap) || bus_dmamap_load(dmat, isp->isp_rqdmap,
                   1018:            (caddr_t)isp->isp_rquest, len, NULL,
                   1019:            BUS_DMA_NOWAIT)) {
                   1020:                goto dmafail;
                   1021:        }
                   1022:        isp->isp_rquest_dma = isp->isp_rqdmap->dm_segs[0].ds_addr;
                   1023:
                   1024:        /*
                   1025:         * Allocate and map the result queue.
                   1026:         */
                   1027:        len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
                   1028:        if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
                   1029:                             BUS_DMA_NOWAIT) ||
                   1030:            bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&isp->isp_result,
                   1031:            BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
                   1032:                goto dmafail;
                   1033:        }
                   1034:        if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
                   1035:            &isp->isp_rsdmap) || bus_dmamap_load(isp->isp_dmatag,
                   1036:            isp->isp_rsdmap, (caddr_t)isp->isp_result, len, NULL,
                   1037:            BUS_DMA_NOWAIT)) {
                   1038:                goto dmafail;
                   1039:        }
                   1040:        isp->isp_result_dma = isp->isp_rsdmap->dm_segs[0].ds_addr;
                   1041:
                   1042:        if (IS_SCSI(isp)) {
                   1043:                return (0);
                   1044:        }
                   1045:
                   1046:        fcp = isp->isp_param;
                   1047:        len = ISP2100_SCRLEN;
                   1048:        if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
                   1049:                             BUS_DMA_NOWAIT) ||
                   1050:            bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&fcp->isp_scratch,
                   1051:            BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
                   1052:                goto dmafail;
                   1053:        }
                   1054:        if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
                   1055:            &isp->isp_scdmap) || bus_dmamap_load(dmat,
                   1056:            isp->isp_scdmap, (caddr_t)fcp->isp_scratch, len, NULL,
                   1057:            BUS_DMA_NOWAIT)) {
                   1058:                goto dmafail;
                   1059:        }
                   1060:        fcp->isp_scdma = isp->isp_scdmap->dm_segs[0].ds_addr;
                   1061:        return (0);
                   1062: dmafail:
                   1063:        isp_prt(isp, ISP_LOGERR, "mailbox dma setup failure");
                   1064:        for (i = 0; i < isp->isp_maxcmds; i++) {
                   1065:                bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]);
                   1066:        }
                   1067:        free(isp->isp_xflist, M_DEVBUF);
                   1068:        free(pcs->pci_xfer_dmap, M_DEVBUF);
                   1069:        isp->isp_xflist = NULL;
                   1070:        pcs->pci_xfer_dmap = NULL;
                   1071:        return (1);
                   1072: }
                   1073:
                   1074: static int
                   1075: isp_pci_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq,
                   1076:     u_int16_t *nxtip, u_int16_t optr)
                   1077: {
                   1078:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
                   1079:        bus_dmamap_t dmap;
                   1080:        u_int16_t starti = isp->isp_reqidx, nxti = *nxtip;
                   1081:        ispreq_t *qep;
                   1082:        int segcnt, seg, error, ovseg, seglim, drq;
                   1083:
                   1084:        qep = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, starti);
                   1085:        dmap = pcs->pci_xfer_dmap[isp_handle_index(rq->req_handle)];
                   1086:        if (xs->datalen == 0) {
                   1087:                rq->req_seg_count = 1;
                   1088:                goto mbxsync;
                   1089:        }
                   1090:
                   1091:        if (xs->flags & SCSI_DATA_IN) {
                   1092:                drq = REQFLAG_DATA_IN;
                   1093:        } else {
                   1094:                drq = REQFLAG_DATA_OUT;
                   1095:        }
                   1096:
                   1097:        if (IS_FC(isp)) {
                   1098:                seglim = ISP_RQDSEG_T2;
                   1099:                ((ispreqt2_t *)rq)->req_totalcnt = xs->datalen;
                   1100:                ((ispreqt2_t *)rq)->req_flags |= drq;
                   1101:        } else {
                   1102:                rq->req_flags |= drq;
                   1103:                if (XS_CDBLEN(xs) > 12)
                   1104:                        seglim = 0;
                   1105:                else
                   1106:                        seglim = ISP_RQDSEG;
                   1107:        }
                   1108:        error = bus_dmamap_load(isp->isp_dmatag, dmap, xs->data, xs->datalen,
                   1109:            NULL, (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
                   1110:        if (error) {
                   1111:                XS_SETERR(xs, HBA_BOTCH);
                   1112:                return (CMD_COMPLETE);
                   1113:        }
                   1114:
                   1115:        segcnt = dmap->dm_nsegs;
                   1116:
                   1117:        isp_prt(isp, ISP_LOGDEBUG2, "%d byte %s %p in %d segs",
                   1118:            xs->datalen, (xs->flags & SCSI_DATA_IN)? "read to" :
                   1119:            "write from", xs->data, segcnt);
                   1120:
                   1121:        for (seg = 0, rq->req_seg_count = 0;
                   1122:             seg < segcnt && rq->req_seg_count < seglim;
                   1123:             seg++, rq->req_seg_count++) {
                   1124:                if (isp->isp_type & ISP_HA_FC) {
                   1125:                        ispreqt2_t *rq2 = (ispreqt2_t *)rq;
                   1126:                        rq2->req_dataseg[rq2->req_seg_count].ds_count =
                   1127:                            dmap->dm_segs[seg].ds_len;
                   1128:                        rq2->req_dataseg[rq2->req_seg_count].ds_base =
                   1129:                            dmap->dm_segs[seg].ds_addr;
                   1130:                } else {
                   1131:                        rq->req_dataseg[rq->req_seg_count].ds_count =
                   1132:                            dmap->dm_segs[seg].ds_len;
                   1133:                        rq->req_dataseg[rq->req_seg_count].ds_base =
                   1134:                            dmap->dm_segs[seg].ds_addr;
                   1135:                }
                   1136:                isp_prt(isp, ISP_LOGDEBUG2, "seg0.[%d]={0x%lx,%lu}",
                   1137:                    rq->req_seg_count, (long) dmap->dm_segs[seg].ds_addr,
                   1138:                    (unsigned long) dmap->dm_segs[seg].ds_len);
                   1139:        }
                   1140:
                   1141:        if (seg == segcnt) {
                   1142:                goto dmasync;
                   1143:        }
                   1144:
                   1145:        do {
                   1146:                u_int16_t onxti;
                   1147:                ispcontreq_t *crq, *cqe, local;
                   1148:
                   1149:                crq = &local;
                   1150:
                   1151:                cqe = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
                   1152:                onxti = nxti;
                   1153:                nxti = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp));
                   1154:                if (nxti == optr) {
                   1155:                        isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++");
                   1156:                        bus_dmamap_unload(isp->isp_dmatag, dmap);
                   1157:                        XS_SETERR(xs, HBA_BOTCH);
                   1158:                        return (CMD_EAGAIN);
                   1159:                }
                   1160:                rq->req_header.rqs_entry_count++;
                   1161:                bzero((void *)crq, sizeof (*crq));
                   1162:                crq->req_header.rqs_entry_count = 1;
                   1163:                crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
                   1164:
                   1165:                for (ovseg = 0; seg < segcnt && ovseg < ISP_CDSEG;
                   1166:                    rq->req_seg_count++, seg++, ovseg++) {
                   1167:                        crq->req_dataseg[ovseg].ds_count =
                   1168:                            dmap->dm_segs[seg].ds_len;
                   1169:                        crq->req_dataseg[ovseg].ds_base =
                   1170:                            dmap->dm_segs[seg].ds_addr;
                   1171:                        isp_prt(isp, ISP_LOGDEBUG2, "seg%d.[%d]={0x%lx,%lu}",
                   1172:                            rq->req_header.rqs_entry_count - 1,
                   1173:                            rq->req_seg_count, (long)dmap->dm_segs[seg].ds_addr,
                   1174:                            (unsigned long) dmap->dm_segs[seg].ds_len);
                   1175:                }
                   1176:                isp_put_cont_req(isp, crq, cqe);
                   1177:                MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN);
                   1178:        } while (seg < segcnt);
                   1179:
                   1180: dmasync:
                   1181:        bus_dmamap_sync(isp->isp_dmatag, dmap, 0, dmap->dm_mapsize,
                   1182:            (xs->flags & SCSI_DATA_IN) ?  BUS_DMASYNC_PREREAD :
                   1183:            BUS_DMASYNC_PREWRITE);
                   1184:
                   1185: mbxsync:
                   1186:        switch (rq->req_header.rqs_entry_type) {
                   1187:        case RQSTYPE_REQUEST:
                   1188:                isp_put_request(isp, rq, qep);
                   1189:                break;
                   1190:        case RQSTYPE_CMDONLY:
                   1191:                isp_put_extended_request(isp, (ispextreq_t *)rq,
                   1192:                    (ispextreq_t *)qep);
                   1193:                break;
                   1194:        case RQSTYPE_T2RQS:
                   1195:                isp_put_request_t2(isp, (ispreqt2_t *) rq, (ispreqt2_t *) qep);
                   1196:                break;
                   1197:        }
                   1198:        *nxtip = nxti;
                   1199:        return (CMD_QUEUED);
                   1200: }
                   1201:
                   1202: static int
                   1203: isp_pci_intr(void *arg)
                   1204: {
                   1205:        u_int16_t isr, sema, mbox;
                   1206:        struct ispsoftc *isp = (struct ispsoftc *)arg;
                   1207:
                   1208:        isp->isp_intcnt++;
                   1209:        if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {
                   1210:                isp->isp_intbogus++;
                   1211:                return (0);
                   1212:        } else {
                   1213:                isp->isp_osinfo.onintstack = 1;
                   1214:                isp_intr(isp, isr, sema, mbox);
                   1215:                isp->isp_osinfo.onintstack = 0;
                   1216:                return (1);
                   1217:        }
                   1218: }
                   1219:
                   1220: static void
                   1221: isp_pci_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int16_t handle)
                   1222: {
                   1223:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
                   1224:        bus_dmamap_t dmap = pcs->pci_xfer_dmap[isp_handle_index(handle)];
                   1225:        bus_dmamap_sync(isp->isp_dmatag, dmap, 0, dmap->dm_mapsize,
                   1226:            (xs->flags & SCSI_DATA_IN)?
                   1227:            BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
                   1228:        bus_dmamap_unload(isp->isp_dmatag, dmap);
                   1229: }
                   1230:
                   1231: static void
                   1232: isp_pci_reset1(struct ispsoftc *isp)
                   1233: {
                   1234:        /* Make sure the BIOS is disabled */
                   1235:        isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
                   1236:        if (isp->isp_osinfo.no_mbox_ints == 0) {
                   1237:                ENABLE_INTS(isp);
                   1238:        }
                   1239: }
                   1240:
                   1241: static void
                   1242: isp_pci_dumpregs(struct ispsoftc *isp, const char *msg)
                   1243: {
                   1244:        struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
                   1245:        if (msg)
                   1246:                 isp_prt(isp, ISP_LOGERR, "%s", msg);
                   1247:        isp_prt(isp, ISP_LOGERR, "PCI Status Command/Status=%x\n",
                   1248:            pci_conf_read(pcs->pci_pc, pcs->pci_tag, PCI_COMMAND_STATUS_REG));
                   1249: }

CVSweb