[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     ! 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