[BACK]Return to isp_sbus.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc / dev

Annotation of sys/arch/sparc/dev/isp_sbus.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: isp_sbus.c,v 1.24 2004/09/29 07:35:11 miod Exp $      */
        !             2: /*
        !             3:  * SBus specific probe and attach routines for Qlogic ISP SCSI adapters.
        !             4:  *
        !             5:  * Copyright (c) 1997, 2000 by Matthew Jacob
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice immediately at the beginning of the file, without modification,
        !            13:  *    this list of conditions, and the following disclaimer.
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 2. The name of the author may not be used to endorse or promote products
        !            16:  *    derived from this software without specific prior written permission.
        !            17:  *
        !            18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !            19:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            20:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            21:  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
        !            22:  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            23:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            24:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            25:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            26:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            27:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            28:  * SUCH DAMAGE.
        !            29:  *
        !            30:  */
        !            31:
        !            32: #include <sys/param.h>
        !            33: #include <sys/systm.h>
        !            34: #include <sys/device.h>
        !            35: #include <sys/kernel.h>
        !            36: #include <sys/malloc.h>
        !            37: #include <sys/queue.h>
        !            38:
        !            39: #include <machine/autoconf.h>
        !            40: #include <machine/cpu.h>
        !            41: #include <machine/param.h>
        !            42: #include <machine/vmparam.h>
        !            43: #include <sparc/sparc/cpuvar.h>
        !            44:
        !            45: #include <dev/ic/isp_openbsd.h>
        !            46: #if    defined(ISP_COMPILE_FW) || defined(ISP_COMPILE_1000_FW)
        !            47: #include <dev/microcode/isp/asm_sbus.h>
        !            48: #endif
        !            49:
        !            50: #define ISP_SBUSIFY_ISPHDR(isp, hdrp)                                  \
        !            51:        ISP_SWAP8((hdrp)->rqs_entry_count, (hdrp)->rqs_entry_type);     \
        !            52:        ISP_SWAP8((hdrp)->rqs_flags, (hdrp)->rqs_seqno);
        !            53:
        !            54: #define        ISP_SWIZZLE_REQUEST(a, b)                               \
        !            55:        ISP_SBUSIFY_ISPHDR(a, &(b)->req_header);                \
        !            56:         ISP_SWAP8((b)->req_target, (b)->req_lun_trn)
        !            57:
        !            58:
        !            59: static int
        !            60: isp_sbus_rd_isr(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
        !            61: static u_int16_t isp_sbus_rd_reg(struct ispsoftc *, int);
        !            62: static void isp_sbus_wr_reg(struct ispsoftc *, int, u_int16_t);
        !            63: static int isp_sbus_mbxdma(struct ispsoftc *);
        !            64: static int isp_sbus_dmasetup(struct ispsoftc *, struct scsi_xfer *,
        !            65:        ispreq_t *, u_int16_t *, u_int16_t);
        !            66: static void
        !            67: isp_sbus_dmateardown(struct ispsoftc *, struct scsi_xfer *, u_int16_t);
        !            68: static int isp_sbus_intr(void *);
        !            69:
        !            70: #ifndef        ISP_1000_RISC_CODE
        !            71: #define        ISP_1000_RISC_CODE      NULL
        !            72: #endif
        !            73:
        !            74: static struct ispmdvec mdvec = {
        !            75:        isp_sbus_rd_isr,
        !            76:        isp_sbus_rd_reg,
        !            77:        isp_sbus_wr_reg,
        !            78:        isp_sbus_mbxdma,
        !            79:        isp_sbus_dmasetup,
        !            80:        isp_sbus_dmateardown,
        !            81:        NULL,
        !            82:        NULL,
        !            83:        NULL,
        !            84:        (u_int16_t *) ISP_1000_RISC_CODE,
        !            85:        BIU_BURST_ENABLE|BIU_SBUS_CONF1_FIFO_32
        !            86: };
        !            87:
        !            88: struct isp_sbussoftc {
        !            89:        struct ispsoftc sbus_isp;
        !            90:        sdparam         sbus_dev;
        !            91:        struct intrhand sbus_ih;
        !            92:        volatile u_int16_t *sbus_reg;
        !            93:        int             sbus_node;
        !            94:        int             sbus_pri;
        !            95:        struct ispmdvec sbus_mdvec;
        !            96:        int16_t         sbus_poff[_NREG_BLKS];
        !            97:        vaddr_t         *sbus_kdma_allocs;
        !            98: };
        !            99:
        !           100:
        !           101: static int isp_match(struct device *, void *, void *);
        !           102: static void isp_sbus_attach(struct device *, struct device *, void *);
        !           103: struct cfattach isp_sbus_ca = {
        !           104:        sizeof (struct isp_sbussoftc), isp_match, isp_sbus_attach
        !           105: };
        !           106:
        !           107: static int
        !           108: isp_match(struct device *parent, void *cfarg, void *aux)
        !           109: {
        !           110:        int rv;
        !           111:        struct cfdata *cf = cfarg;
        !           112: #ifdef DEBUG
        !           113:        static int oneshot = 1;
        !           114: #endif
        !           115:        struct confargs *ca = aux;
        !           116:        struct romaux *ra = &ca->ca_ra;
        !           117:
        !           118:        rv = (strcmp(cf->cf_driver->cd_name, ra->ra_name) == 0 ||
        !           119:                strcmp("PTI,ptisp", ra->ra_name) == 0 ||
        !           120:                strcmp("ptisp", ra->ra_name) == 0 ||
        !           121:                strcmp("SUNW,isp", ra->ra_name) == 0 ||
        !           122:                strcmp("QLGC,isp", ra->ra_name) == 0);
        !           123:        if (rv == 0)
        !           124:                return (rv);
        !           125: #ifdef DEBUG
        !           126:        if (rv && oneshot) {
        !           127:                oneshot = 0;
        !           128:                printf("Qlogic ISP Driver, OpenBSD (sbus) Platform Version "
        !           129:                    "%d.%d Core Version %d.%d\n",
        !           130:                    ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,
        !           131:                    ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR);
        !           132:        }
        !           133: #endif
        !           134:        if (ca->ca_bustype == BUS_SBUS)
        !           135:                return (1);
        !           136:        ra->ra_len = NBPG;
        !           137:        return (probeget(ra->ra_vaddr, 1) != -1);
        !           138: }
        !           139:
        !           140: static void
        !           141: isp_sbus_attach(struct device *parent, struct device *self, void *aux)
        !           142: {
        !           143:        int freq, storebp = 0;
        !           144:        struct confargs *ca = aux;
        !           145:        struct bootpath *bp;
        !           146:        struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) self;
        !           147:        struct ispsoftc *isp = &sbc->sbus_isp;
        !           148:
        !           149:        if (ca->ca_ra.ra_nintr != 1) {
        !           150:                printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
        !           151:                return;
        !           152:        }
        !           153:
        !           154:        printf("\n");
        !           155:
        !           156:        sbc->sbus_pri = ca->ca_ra.ra_intr[0].int_pri;
        !           157:        sbc->sbus_mdvec = mdvec;
        !           158:
        !           159:        if (ca->ca_ra.ra_vaddr) {
        !           160:                sbc->sbus_reg = (volatile u_int16_t *) ca->ca_ra.ra_vaddr;
        !           161:        } else {
        !           162:                sbc->sbus_reg = (volatile u_int16_t *)
        !           163:                        mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
        !           164:        }
        !           165:        sbc->sbus_node = ca->ca_ra.ra_node;
        !           166:
        !           167:        freq = getpropint(ca->ca_ra.ra_node, "clock-frequency", 0);
        !           168:        if (freq) {
        !           169:                /*
        !           170:                 * Convert from HZ to MHz, rounding up.
        !           171:                 */
        !           172:                freq = (freq + 500000)/1000000;
        !           173: #if    0
        !           174:                printf("%s: %d MHz\n", self->dv_xname, freq);
        !           175: #endif
        !           176:        }
        !           177:        sbc->sbus_mdvec.dv_clock = freq;
        !           178:
        !           179:        if ((bp = ca->ca_ra.ra_bp) != NULL) {
        !           180:                if (bp->val[0] == ca->ca_slot &&
        !           181:                    bp->val[1] == ca->ca_offset) {
        !           182:                        if (strcmp("isp", bp->name) == 0 ||
        !           183:                            strcmp("QLGC,isp", bp->name) == 0 ||
        !           184:                            strcmp("PTI,isp", bp->name) == 0 ||
        !           185:                            strcmp("ptisp", bp->name) == 0) {
        !           186:                                storebp = 1;
        !           187:                        }
        !           188:                }
        !           189:        }
        !           190:
        !           191:        /*
        !           192:         * XXX: Now figure out what the proper burst sizes, etc., to use.
        !           193:         */
        !           194:        sbc->sbus_mdvec.dv_conf1 |= BIU_SBUS_CONF1_FIFO_8;
        !           195:
        !           196:        /*
        !           197:         * Some early versions of the PTI SBus adapter
        !           198:         * would fail in trying to download (via poking)
        !           199:         * FW. We give up on them.
        !           200:         */
        !           201:        if (strcmp("PTI,ptisp", ca->ca_ra.ra_name) == 0 ||
        !           202:            strcmp("ptisp", ca->ca_ra.ra_name) == 0) {
        !           203:                sbc->sbus_mdvec.dv_ispfw = NULL;
        !           204:        }
        !           205:
        !           206:        isp->isp_mdvec = &sbc->sbus_mdvec;
        !           207:        isp->isp_bustype = ISP_BT_SBUS;
        !           208:        isp->isp_type = ISP_HA_SCSI_UNKNOWN;
        !           209:        isp->isp_param = &sbc->sbus_dev;
        !           210:        bzero(isp->isp_param, sizeof (sdparam));
        !           211:
        !           212:        sbc->sbus_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
        !           213:        sbc->sbus_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = SBUS_MBOX_REGS_OFF;
        !           214:        sbc->sbus_poff[SXP_BLOCK >> _BLK_REG_SHFT] = SBUS_SXP_REGS_OFF;
        !           215:        sbc->sbus_poff[RISC_BLOCK >> _BLK_REG_SHFT] = SBUS_RISC_REGS_OFF;
        !           216:        sbc->sbus_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
        !           217:
        !           218:        /* Establish interrupt channel */
        !           219:        sbc->sbus_ih.ih_fun = (void *) isp_sbus_intr;
        !           220:        sbc->sbus_ih.ih_arg = sbc;
        !           221:        intr_establish(sbc->sbus_pri, &sbc->sbus_ih, IPL_BIO, self->dv_xname);
        !           222:
        !           223:        /*
        !           224:         * Set up logging levels.
        !           225:         */
        !           226: #ifdef ISP_LOGDEFAULT
        !           227:        isp->isp_dblev = ISP_LOGDEFAULT;
        !           228: #else
        !           229:        isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR;
        !           230: #ifdef SCSIDEBUG
        !           231:        isp->isp_dblev |= ISP_LOGDEBUG1|ISP_LOGDEBUG2;
        !           232: #endif
        !           233: #ifdef DEBUG
        !           234:        isp->isp_dblev |= ISP_LOGDEBUG0|ISP_LOGCONFIG|ISP_LOGINFO;
        !           235: #endif
        !           236: #endif
        !           237:        isp->isp_confopts = self->dv_cfdata->cf_flags;
        !           238:        isp->isp_role = ISP_DEFAULT_ROLES;
        !           239:
        !           240:        ISP_LOCK(isp);
        !           241:        isp->isp_osinfo.no_mbox_ints = 1;
        !           242:        isp_reset(isp);
        !           243:        if (isp->isp_state != ISP_RESETSTATE) {
        !           244:                ISP_UNLOCK(isp);
        !           245:                return;
        !           246:        }
        !           247:        ENABLE_INTS(isp);
        !           248:        isp_init(isp);
        !           249:        if (isp->isp_state != ISP_INITSTATE) {
        !           250:                isp_uninit(isp);
        !           251:                ISP_UNLOCK(isp);
        !           252:                return;
        !           253:        }
        !           254:
        !           255:        /*
        !           256:         * do generic attach.
        !           257:         */
        !           258:        if (storebp) {
        !           259:                /*
        !           260:                 * We're the booting HBA.
        !           261:                 *
        !           262:                 * Override the bootpath name with our driver name
        !           263:                 * so we will do the correct matching and and store
        !           264:                 * the next component's boot path entry, also so a
        !           265:                 * successful match will occur.
        !           266:                 */
        !           267:                bcopy("isp", bp->name, 4);
        !           268:                bp++;
        !           269:                bootpath_store(1, bp);
        !           270:        }
        !           271:        isp_attach(isp);
        !           272:        if (isp->isp_state != ISP_RUNSTATE) {
        !           273:                isp_uninit(isp);
        !           274:        }
        !           275:        if (storebp) {
        !           276:                bootpath_store(1, NULL);
        !           277:        }
        !           278:        ISP_UNLOCK(isp);
        !           279: }
        !           280:
        !           281: #define        IspVirt2Off(a, x)       \
        !           282:        (((struct isp_sbussoftc *)a)->sbus_poff[((x) & _BLK_REG_MASK) >> \
        !           283:        _BLK_REG_SHFT] + ((x) & 0xff))
        !           284:
        !           285: #define        BXR2(pcs, off)          (sbc->sbus_reg[off >> 1])
        !           286:
        !           287: static int
        !           288: isp_sbus_rd_isr(struct ispsoftc *isp, u_int16_t *isrp,
        !           289:     u_int16_t *semap, u_int16_t *mbp)
        !           290: {
        !           291:        struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
        !           292:        volatile u_int16_t isr, sema;
        !           293:
        !           294:        isr = BXR2(pcs, IspVirt2Off(isp, BIU_ISR));
        !           295:        sema = BXR2(pcs, IspVirt2Off(isp, BIU_SEMA));
        !           296:        isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema);
        !           297:        isr &= INT_PENDING_MASK(isp);
        !           298:        sema &= BIU_SEMA_LOCK;
        !           299:        if (isr == 0 && sema == 0) {
        !           300:                return (0);
        !           301:        }
        !           302:        *isrp = isr;
        !           303:        if ((*semap = sema) != 0) {
        !           304:                *mbp = BXR2(pcs, IspVirt2Off(isp, OUTMAILBOX0));
        !           305:        }
        !           306:        return (1);
        !           307: }
        !           308:
        !           309: static u_int16_t
        !           310: isp_sbus_rd_reg(struct ispsoftc *isp, int regoff)
        !           311: {
        !           312:        struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
        !           313:        int offset = sbc->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
        !           314:        offset += (regoff & 0xff);
        !           315:        return ((u_int16_t) sbc->sbus_reg[offset >> 1]);
        !           316: }
        !           317:
        !           318: static void
        !           319: isp_sbus_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val)
        !           320: {
        !           321:        struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
        !           322:        int offset = sbc->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
        !           323:        offset += (regoff & 0xff);
        !           324:        sbc->sbus_reg[offset >> 1] = val;
        !           325: }
        !           326:
        !           327:
        !           328: static int
        !           329: isp_sbus_mbxdma(struct ispsoftc *isp)
        !           330: {
        !           331:        struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
        !           332:        size_t len;
        !           333:
        !           334:        if (isp->isp_rquest_dma)        /* been here before? */
        !           335:                return (0);
        !           336:
        !           337:        /*
        !           338:         * NOTE: Since most Sun machines aren't I/O coherent,
        !           339:         * map the mailboxes through kdvma space to force them
        !           340:         * to be uncached.
        !           341:         */
        !           342:
        !           343:        len = isp->isp_maxcmds * sizeof (XS_T);
        !           344:        isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK);
        !           345:        bzero(isp->isp_xflist, len);
        !           346:        len = isp->isp_maxcmds * sizeof (vaddr_t);
        !           347:        sbc->sbus_kdma_allocs = (vaddr_t *) malloc(len, M_DEVBUF, M_WAITOK);
        !           348:        bzero(sbc->sbus_kdma_allocs, len);
        !           349:
        !           350:        /*
        !           351:         * Allocate and map the request queue.
        !           352:         */
        !           353:        len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
        !           354:        isp->isp_rquest = (volatile caddr_t)malloc(len, M_DEVBUF, M_NOWAIT);
        !           355:        if (isp->isp_rquest == 0) {
        !           356:                printf("%s: cannot allocate request queue\n", isp->isp_name);
        !           357:                return (1);
        !           358:        }
        !           359:        isp->isp_rquest_dma = (u_int32_t)
        !           360:            kdvma_mapin((caddr_t)isp->isp_rquest, len, 0);
        !           361:        if (isp->isp_rquest_dma == 0) {
        !           362:                printf("%s: could not mapin request queue\n", isp->isp_name);
        !           363:                return (1);
        !           364:        }
        !           365:
        !           366:        /*
        !           367:         * Allocate and map the result queue.
        !           368:         */
        !           369:        len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
        !           370:        isp->isp_result = (volatile caddr_t)malloc(len, M_DEVBUF, M_NOWAIT);
        !           371:        if (isp->isp_result == 0) {
        !           372:                printf("%s: cannot allocate result queue\n", isp->isp_name);
        !           373:                return (1);
        !           374:        }
        !           375:        isp->isp_result_dma = (u_int32_t)
        !           376:            kdvma_mapin((caddr_t)isp->isp_result, len, 0);
        !           377:        if (isp->isp_result_dma == 0) {
        !           378:                printf("%s: could not mapin result queue\n", isp->isp_name);
        !           379:                return (1);
        !           380:        }
        !           381:        return (0);
        !           382: }
        !           383:
        !           384: /*
        !           385:  * TODO: If kdvma_mapin fails, try using multiple smaller chunks..
        !           386:  */
        !           387:
        !           388: static int
        !           389: isp_sbus_dmasetup(struct ispsoftc *isp, struct scsi_xfer *xs, ispreq_t *rq,
        !           390:     u_int16_t *iptrp, u_int16_t optr)
        !           391: {
        !           392:        struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
        !           393:        ispreq_t *qe;
        !           394:        ispcontreq_t *crq;
        !           395:        vaddr_t kdvma;
        !           396:        int dosleep = (xs->flags & SCSI_NOSLEEP) != 0;
        !           397:
        !           398:        qe = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx);
        !           399:        if (xs->datalen == 0) {
        !           400:                rq->req_seg_count = 1;
        !           401:                goto mbxsync;
        !           402:        }
        !           403:        if (CPU_ISSUN4M) {
        !           404:                kdvma = (vaddr_t)
        !           405:                        kdvma_mapin((caddr_t)xs->data, xs->datalen, dosleep);
        !           406:                if (kdvma == (vaddr_t) 0) {
        !           407:                        XS_SETERR(xs, HBA_BOTCH);
        !           408:                        return (CMD_COMPLETE);
        !           409:                }
        !           410:        } else {
        !           411:                kdvma = (vaddr_t) xs->data;
        !           412:        }
        !           413:
        !           414:        if (sbc->sbus_kdma_allocs[isp_handle_index(rq->req_handle)] != 0) {
        !           415:                panic("%s: kdma handle already allocated", isp->isp_name);
        !           416:                /* NOTREACHED */
        !           417:        }
        !           418:        if (XS_CDBLEN(xs) > 12) {
        !           419:                crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp);
        !           420:                *iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN(isp));
        !           421:                if (*iptrp == optr) {
        !           422:                        printf("%s: Request Queue Overflow++\n", isp->isp_name);
        !           423:                        if (CPU_ISSUN4M) {
        !           424:                                dvma_mapout(kdvma,
        !           425:                                    (vaddr_t) xs->data, xs->datalen);
        !           426:                        }
        !           427:                        XS_SETERR(xs, HBA_BOTCH);
        !           428:                        return (CMD_EAGAIN);
        !           429:                }
        !           430:        } else {
        !           431:                crq = NULL;
        !           432:        }
        !           433:        sbc->sbus_kdma_allocs[isp_handle_index(rq->req_handle)] = kdvma;
        !           434:        if (xs->flags & SCSI_DATA_IN) {
        !           435:                rq->req_flags |= REQFLAG_DATA_IN;
        !           436:        } else {
        !           437:                rq->req_flags |= REQFLAG_DATA_OUT;
        !           438:        }
        !           439:        if (crq) {
        !           440:                rq->req_seg_count = 2;
        !           441:                rq->req_dataseg[0].ds_count = 0;
        !           442:                rq->req_dataseg[0].ds_base =  0;
        !           443:                bzero((void *)crq, sizeof (*crq));
        !           444:                crq->req_header.rqs_entry_count = 1;
        !           445:                crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
        !           446:                crq->req_dataseg[0].ds_count = xs->datalen;
        !           447:                crq->req_dataseg[0].ds_base =  (u_int32_t) kdvma;
        !           448:                 ISP_SBUSIFY_ISPHDR(isp, &crq->req_header)
        !           449:        } else {
        !           450:                rq->req_dataseg[0].ds_count = xs->datalen;
        !           451:                rq->req_dataseg[0].ds_base =  (u_int32_t) kdvma;
        !           452:                rq->req_seg_count = 1;
        !           453:        }
        !           454:
        !           455: mbxsync:
        !           456:        ISP_SWIZZLE_REQUEST(isp, rq);
        !           457:        bcopy(rq, qe, sizeof (ispreq_t));
        !           458:        return (CMD_QUEUED);
        !           459: }
        !           460:
        !           461: static void
        !           462: isp_sbus_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int16_t handle)
        !           463: {
        !           464:        struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
        !           465:        vaddr_t kdvma;
        !           466:
        !           467:        if (xs->flags & SCSI_DATA_IN) {
        !           468:                cpuinfo.cache_flush(xs->data, xs->datalen - xs->resid);
        !           469:        }
        !           470:        if (sbc->sbus_kdma_allocs[isp_handle_index(handle)] == (vaddr_t) 0) {
        !           471:                panic("%s: kdma handle not already allocated", isp->isp_name);
        !           472:                /* NOTREACHED */
        !           473:        }
        !           474:        kdvma = sbc->sbus_kdma_allocs[isp_handle_index(handle)];
        !           475:        sbc->sbus_kdma_allocs[isp_handle_index(handle)] = (vaddr_t) 0;
        !           476:        if (CPU_ISSUN4M) {
        !           477:                dvma_mapout(kdvma, (vaddr_t) xs->data, xs->datalen);
        !           478:        }
        !           479: }
        !           480:
        !           481: static int
        !           482: isp_sbus_intr(void *arg)
        !           483: {
        !           484:        u_int16_t isr, sema, mbox;
        !           485:        struct ispsoftc *isp = (struct ispsoftc *)arg;
        !           486:
        !           487:        isp->isp_intcnt++;
        !           488:        if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {
        !           489:                isp->isp_intbogus++;
        !           490:                return (0);
        !           491:        } else {
        !           492:                isp->isp_osinfo.onintstack = 1;
        !           493:                isp_intr(isp, isr, sema, mbox);
        !           494:                isp->isp_osinfo.onintstack = 0;
        !           495:                return (1);
        !           496:        }
        !           497: }

CVSweb