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

Annotation of sys/dev/ic/adw.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: adw.c,v 1.31 2006/11/28 23:59:45 dlg Exp $ */
        !             2: /* $NetBSD: adw.c,v 1.23 2000/05/27 18:24:50 dante Exp $        */
        !             3:
        !             4: /*
        !             5:  * Generic driver for the Advanced Systems Inc. SCSI controllers
        !             6:  *
        !             7:  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
        !             8:  * All rights reserved.
        !             9:  *
        !            10:  * Author: Baldassare Dante Profeta <dante@mclink.it>
        !            11:  *
        !            12:  * Redistribution and use in source and binary forms, with or without
        !            13:  * modification, are permitted provided that the following conditions
        !            14:  * are met:
        !            15:  * 1. Redistributions of source code must retain the above copyright
        !            16:  *    notice, 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. All advertising materials mentioning features or use of this software
        !            21:  *    must display the following acknowledgement:
        !            22:  *        This product includes software developed by the NetBSD
        !            23:  *        Foundation, Inc. and its contributors.
        !            24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            25:  *    contributors may be used to endorse or promote products derived
        !            26:  *    from this software without specific prior written permission.
        !            27:  *
        !            28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            38:  * POSSIBILITY OF SUCH DAMAGE.
        !            39:  */
        !            40:
        !            41: #include <sys/types.h>
        !            42: #include <sys/param.h>
        !            43: #include <sys/systm.h>
        !            44: #include <sys/kernel.h>
        !            45: #include <sys/errno.h>
        !            46: #include <sys/ioctl.h>
        !            47: #include <sys/device.h>
        !            48: #include <sys/malloc.h>
        !            49: #include <sys/buf.h>
        !            50: #include <sys/proc.h>
        !            51: #include <sys/user.h>
        !            52: #include <sys/timeout.h>
        !            53:
        !            54: #include <machine/bus.h>
        !            55: #include <machine/intr.h>
        !            56:
        !            57: #include <scsi/scsi_all.h>
        !            58: #include <scsi/scsiconf.h>
        !            59:
        !            60: #include <dev/ic/adwlib.h>
        !            61: #include <dev/microcode/adw/adwmcode.h>
        !            62: #include <dev/ic/adw.h>
        !            63:
        !            64: #ifndef DDB
        !            65: #define        Debugger()      panic("should call debugger here (adw.c)")
        !            66: #endif                         /* ! DDB */
        !            67:
        !            68: /******************************************************************************/
        !            69:
        !            70:
        !            71: void adw_enqueue(ADW_SOFTC *, struct scsi_xfer *, int);
        !            72: struct scsi_xfer *adw_dequeue(ADW_SOFTC *);
        !            73:
        !            74: int adw_alloc_controls(ADW_SOFTC *);
        !            75: int adw_alloc_carriers(ADW_SOFTC *);
        !            76: int adw_create_ccbs(ADW_SOFTC *, ADW_CCB *, int);
        !            77: void adw_free_ccb(ADW_SOFTC *, ADW_CCB *);
        !            78: void adw_reset_ccb(ADW_CCB *);
        !            79: int adw_init_ccb(ADW_SOFTC *, ADW_CCB *);
        !            80: ADW_CCB *adw_get_ccb(ADW_SOFTC *, int);
        !            81: int adw_queue_ccb(ADW_SOFTC *, ADW_CCB *, int);
        !            82:
        !            83: int adw_scsi_cmd(struct scsi_xfer *);
        !            84: int adw_build_req(struct scsi_xfer *, ADW_CCB *, int);
        !            85: void adw_build_sglist(ADW_CCB *, ADW_SCSI_REQ_Q *, ADW_SG_BLOCK *);
        !            86: void adw_minphys(struct buf *);
        !            87: void adw_isr_callback(ADW_SOFTC *, ADW_SCSI_REQ_Q *);
        !            88: void adw_async_callback(ADW_SOFTC *, u_int8_t);
        !            89:
        !            90: void adw_print_info(ADW_SOFTC *, int);
        !            91:
        !            92: int adw_poll(ADW_SOFTC *, struct scsi_xfer *, int);
        !            93: void adw_timeout(void *);
        !            94: void adw_reset_bus(ADW_SOFTC *);
        !            95:
        !            96:
        !            97: /******************************************************************************/
        !            98:
        !            99:
        !           100: struct cfdriver adw_cd = {
        !           101:        NULL, "adw", DV_DULL
        !           102: };
        !           103:
        !           104: /* the below structure is so we have a default dev struct for our link struct */
        !           105: struct scsi_device adw_dev =
        !           106: {
        !           107:        NULL,                   /* Use default error handler */
        !           108:        NULL,                   /* have a queue, served by this */
        !           109:        NULL,                   /* have no async handler */
        !           110:        NULL,                   /* Use default 'done' routine */
        !           111: };
        !           112:
        !           113:
        !           114: /******************************************************************************/
        !           115: /* scsi_xfer queue routines                                                   */
        !           116: /******************************************************************************/
        !           117:
        !           118: /*
        !           119:  * Insert a scsi_xfer into the software queue.  We overload xs->free_list
        !           120:  * to avoid having to allocate additional resources (since we're used
        !           121:  * only during resource shortages anyhow.
        !           122:  */
        !           123: void
        !           124: adw_enqueue(sc, xs, infront)
        !           125:        ADW_SOFTC      *sc;
        !           126:        struct scsi_xfer *xs;
        !           127:        int             infront;
        !           128: {
        !           129:
        !           130:        if (infront || LIST_EMPTY(&sc->sc_queue)) {
        !           131:                if (LIST_EMPTY(&sc->sc_queue))
        !           132:                        sc->sc_queuelast = xs;
        !           133:                LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
        !           134:                return;
        !           135:        }
        !           136:        LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
        !           137:        sc->sc_queuelast = xs;
        !           138: }
        !           139:
        !           140:
        !           141: /*
        !           142:  * Pull a scsi_xfer off the front of the software queue.
        !           143:  */
        !           144: struct scsi_xfer *
        !           145: adw_dequeue(sc)
        !           146:        ADW_SOFTC      *sc;
        !           147: {
        !           148:        struct scsi_xfer *xs;
        !           149:
        !           150:        xs = LIST_FIRST(&sc->sc_queue);
        !           151:        LIST_REMOVE(xs, free_list);
        !           152:
        !           153:        if (LIST_EMPTY(&sc->sc_queue))
        !           154:                sc->sc_queuelast = NULL;
        !           155:
        !           156:        return (xs);
        !           157: }
        !           158:
        !           159: /******************************************************************************/
        !           160: /*                       DMA Mapping for Control Blocks                       */
        !           161: /******************************************************************************/
        !           162:
        !           163:
        !           164: int
        !           165: adw_alloc_controls(sc)
        !           166:        ADW_SOFTC      *sc;
        !           167: {
        !           168:        bus_dma_segment_t seg;
        !           169:        int             error, rseg;
        !           170:
        !           171:        /*
        !           172:          * Allocate the control structure.
        !           173:          */
        !           174:        if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct adw_control),
        !           175:                           NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
        !           176:                printf("%s: unable to allocate control structures,"
        !           177:                       " error = %d\n", sc->sc_dev.dv_xname, error);
        !           178:                return (error);
        !           179:        }
        !           180:        if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
        !           181:                   sizeof(struct adw_control), (caddr_t *) & sc->sc_control,
        !           182:                                 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
        !           183:                printf("%s: unable to map control structures, error = %d\n",
        !           184:                       sc->sc_dev.dv_xname, error);
        !           185:                return (error);
        !           186:        }
        !           187:
        !           188:        /*
        !           189:          * Create and load the DMA map used for the control blocks.
        !           190:          */
        !           191:        if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct adw_control),
        !           192:                           1, sizeof(struct adw_control), 0, BUS_DMA_NOWAIT,
        !           193:                                       &sc->sc_dmamap_control)) != 0) {
        !           194:                printf("%s: unable to create control DMA map, error = %d\n",
        !           195:                       sc->sc_dev.dv_xname, error);
        !           196:                return (error);
        !           197:        }
        !           198:        if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
        !           199:                           sc->sc_control, sizeof(struct adw_control), NULL,
        !           200:                                     BUS_DMA_NOWAIT)) != 0) {
        !           201:                printf("%s: unable to load control DMA map, error = %d\n",
        !           202:                       sc->sc_dev.dv_xname, error);
        !           203:                return (error);
        !           204:        }
        !           205:
        !           206:        return (0);
        !           207: }
        !           208:
        !           209:
        !           210: int
        !           211: adw_alloc_carriers(sc)
        !           212:        ADW_SOFTC      *sc;
        !           213: {
        !           214:        bus_dma_segment_t seg;
        !           215:        int             error, rseg;
        !           216:
        !           217:        /*
        !           218:          * Allocate the control structure.
        !           219:          */
        !           220:        sc->sc_control->carriers =
        !           221:                malloc(sizeof(ADW_CARRIER) * ADW_MAX_CARRIER, M_DEVBUF,
        !           222:                       M_NOWAIT);
        !           223:        if (sc->sc_control->carriers == NULL)
        !           224:                return (ENOMEM);
        !           225:
        !           226:
        !           227:        if ((error = bus_dmamem_alloc(sc->sc_dmat,
        !           228:                        sizeof(ADW_CARRIER) * ADW_MAX_CARRIER,
        !           229:                        0x10, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
        !           230:                printf("%s: unable to allocate carrier structures,"
        !           231:                       " error = %d\n", sc->sc_dev.dv_xname, error);
        !           232:                return (error);
        !           233:        }
        !           234:        if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
        !           235:                        sizeof(ADW_CARRIER) * ADW_MAX_CARRIER,
        !           236:                        (caddr_t *) &sc->sc_control->carriers,
        !           237:                        BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
        !           238:                printf("%s: unable to map carrier structures,"
        !           239:                        " error = %d\n", sc->sc_dev.dv_xname, error);
        !           240:                return (error);
        !           241:        }
        !           242:
        !           243:        /*
        !           244:          * Create and load the DMA map used for the control blocks.
        !           245:          */
        !           246:        if ((error = bus_dmamap_create(sc->sc_dmat,
        !           247:                        sizeof(ADW_CARRIER) * ADW_MAX_CARRIER, 1,
        !           248:                        sizeof(ADW_CARRIER) * ADW_MAX_CARRIER, 0,BUS_DMA_NOWAIT,
        !           249:                        &sc->sc_dmamap_carrier)) != 0) {
        !           250:                printf("%s: unable to create carriers DMA map,"
        !           251:                        " error = %d\n", sc->sc_dev.dv_xname, error);
        !           252:                return (error);
        !           253:        }
        !           254:        if ((error = bus_dmamap_load(sc->sc_dmat,
        !           255:                        sc->sc_dmamap_carrier, sc->sc_control->carriers,
        !           256:                        sizeof(ADW_CARRIER) * ADW_MAX_CARRIER, NULL,
        !           257:                        BUS_DMA_NOWAIT)) != 0) {
        !           258:                printf("%s: unable to load carriers DMA map,"
        !           259:                        " error = %d\n", sc->sc_dev.dv_xname, error);
        !           260:                return (error);
        !           261:        }
        !           262:
        !           263:        return (0);
        !           264: }
        !           265:
        !           266:
        !           267: /******************************************************************************/
        !           268: /*                           Control Blocks routines                          */
        !           269: /******************************************************************************/
        !           270:
        !           271:
        !           272: /*
        !           273:  * Create a set of ccbs and add them to the free list.  Called once
        !           274:  * by adw_init().  We return the number of CCBs successfully created.
        !           275:  */
        !           276: int
        !           277: adw_create_ccbs(sc, ccbstore, count)
        !           278:        ADW_SOFTC      *sc;
        !           279:        ADW_CCB        *ccbstore;
        !           280:        int             count;
        !           281: {
        !           282:        ADW_CCB        *ccb;
        !           283:        int             i, error;
        !           284:
        !           285:        for (i = 0; i < count; i++) {
        !           286:                ccb = &ccbstore[i];
        !           287:                if ((error = adw_init_ccb(sc, ccb)) != 0) {
        !           288:                        printf("%s: unable to initialize ccb, error = %d\n",
        !           289:                               sc->sc_dev.dv_xname, error);
        !           290:                        return (i);
        !           291:                }
        !           292:                TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
        !           293:        }
        !           294:
        !           295:        return (i);
        !           296: }
        !           297:
        !           298:
        !           299: /*
        !           300:  * A ccb is put onto the free list.
        !           301:  */
        !           302: void
        !           303: adw_free_ccb(sc, ccb)
        !           304:        ADW_SOFTC      *sc;
        !           305:        ADW_CCB        *ccb;
        !           306: {
        !           307:        int             s;
        !           308:
        !           309:        s = splbio();
        !           310:
        !           311:        adw_reset_ccb(ccb);
        !           312:        TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
        !           313:
        !           314:        /*
        !           315:          * If there were none, wake anybody waiting for one to come free,
        !           316:          * starting with queued entries.
        !           317:          */
        !           318:        if (TAILQ_NEXT(ccb, chain) == NULL)
        !           319:                wakeup(&sc->sc_free_ccb);
        !           320:
        !           321:        splx(s);
        !           322: }
        !           323:
        !           324:
        !           325: void
        !           326: adw_reset_ccb(ccb)
        !           327:        ADW_CCB        *ccb;
        !           328: {
        !           329:
        !           330:        ccb->flags = 0;
        !           331: }
        !           332:
        !           333:
        !           334: int
        !           335: adw_init_ccb(sc, ccb)
        !           336:        ADW_SOFTC      *sc;
        !           337:        ADW_CCB        *ccb;
        !           338: {
        !           339:        int     hashnum, error;
        !           340:
        !           341:        /*
        !           342:          * Create the DMA map for this CCB.
        !           343:          */
        !           344:        error = bus_dmamap_create(sc->sc_dmat,
        !           345:                                  (ADW_MAX_SG_LIST - 1) * PAGE_SIZE,
        !           346:                         ADW_MAX_SG_LIST, (ADW_MAX_SG_LIST - 1) * PAGE_SIZE,
        !           347:                   0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer);
        !           348:        if (error) {
        !           349:                printf("%s: unable to create CCB DMA map, error = %d\n",
        !           350:                       sc->sc_dev.dv_xname, error);
        !           351:                return (error);
        !           352:        }
        !           353:
        !           354:        /*
        !           355:         * put in the phystokv hash table
        !           356:         * Never gets taken out.
        !           357:         */
        !           358:        ccb->hashkey = sc->sc_dmamap_control->dm_segs[0].ds_addr +
        !           359:            ADW_CCB_OFF(ccb);
        !           360:        hashnum = CCB_HASH(ccb->hashkey);
        !           361:        ccb->nexthash = sc->sc_ccbhash[hashnum];
        !           362:        sc->sc_ccbhash[hashnum] = ccb;
        !           363:        adw_reset_ccb(ccb);
        !           364:        return (0);
        !           365: }
        !           366:
        !           367:
        !           368: /*
        !           369:  * Get a free ccb
        !           370:  *
        !           371:  * If there are none, see if we can allocate a new one
        !           372:  */
        !           373: ADW_CCB *
        !           374: adw_get_ccb(sc, flags)
        !           375:        ADW_SOFTC      *sc;
        !           376:        int             flags;
        !           377: {
        !           378:        ADW_CCB        *ccb = 0;
        !           379:        int             s;
        !           380:
        !           381:        s = splbio();
        !           382:
        !           383:        /*
        !           384:          * If we can and have to, sleep waiting for one to come free
        !           385:          * but only if we can't allocate a new one.
        !           386:          */
        !           387:        for (;;) {
        !           388:                ccb = TAILQ_FIRST(&sc->sc_free_ccb);
        !           389:                if (ccb) {
        !           390:                        TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
        !           391:                        break;
        !           392:                }
        !           393:                if ((flags & SCSI_NOSLEEP) != 0)
        !           394:                        goto out;
        !           395:
        !           396:                tsleep(&sc->sc_free_ccb, PRIBIO, "adwccb", 0);
        !           397:        }
        !           398:
        !           399:        ccb->flags |= CCB_ALLOC;
        !           400:
        !           401: out:
        !           402:        splx(s);
        !           403:        return (ccb);
        !           404: }
        !           405:
        !           406:
        !           407: /*
        !           408:  * Given a physical address, find the ccb that it corresponds to.
        !           409:  */
        !           410: ADW_CCB *
        !           411: adw_ccb_phys_kv(sc, ccb_phys)
        !           412:        ADW_SOFTC       *sc;
        !           413:        u_int32_t       ccb_phys;
        !           414: {
        !           415:        int hashnum = CCB_HASH(ccb_phys);
        !           416:        ADW_CCB *ccb = sc->sc_ccbhash[hashnum];
        !           417:
        !           418:        while (ccb) {
        !           419:                if (ccb->hashkey == ccb_phys)
        !           420:                        break;
        !           421:                ccb = ccb->nexthash;
        !           422:        }
        !           423:        return (ccb);
        !           424: }
        !           425:
        !           426:
        !           427: /*
        !           428:  * Queue a CCB to be sent to the controller, and send it if possible.
        !           429:  */
        !           430: int
        !           431: adw_queue_ccb(sc, ccb, retry)
        !           432:        ADW_SOFTC      *sc;
        !           433:        ADW_CCB        *ccb;
        !           434:        int             retry;
        !           435: {
        !           436:        int             errcode = ADW_SUCCESS;
        !           437:
        !           438:        if(!retry) {
        !           439:                TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
        !           440:        }
        !           441:
        !           442:        while ((ccb = TAILQ_FIRST(&sc->sc_waiting_ccb)) != NULL) {
        !           443:
        !           444:                errcode = AdwExeScsiQueue(sc, &ccb->scsiq);
        !           445:                switch(errcode) {
        !           446:                case ADW_SUCCESS:
        !           447:                        break;
        !           448:
        !           449:                case ADW_BUSY:
        !           450:                        printf("ADW_BUSY\n");
        !           451:                        return(ADW_BUSY);
        !           452:
        !           453:                case ADW_ERROR:
        !           454:                        printf("ADW_ERROR\n");
        !           455:                        TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
        !           456:                        return(ADW_ERROR);
        !           457:                }
        !           458:
        !           459:                TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
        !           460:                TAILQ_INSERT_TAIL(&sc->sc_pending_ccb, ccb, chain);
        !           461:
        !           462:                /* ALWAYS initialize stimeout, lest it contain garbage! */
        !           463:                timeout_set(&ccb->xs->stimeout, adw_timeout, ccb);
        !           464:                if ((ccb->xs->flags & SCSI_POLL) == 0)
        !           465:                        timeout_add(&ccb->xs->stimeout, (ccb->timeout * hz) / 1000);
        !           466:        }
        !           467:
        !           468:        return(errcode);
        !           469: }
        !           470:
        !           471:
        !           472: /******************************************************************************/
        !           473: /*                       SCSI layer interfacing routines                      */
        !           474: /******************************************************************************/
        !           475:
        !           476:
        !           477: int
        !           478: adw_init(sc)
        !           479:        ADW_SOFTC      *sc;
        !           480: {
        !           481:        u_int16_t       warn_code;
        !           482:
        !           483:
        !           484:        sc->cfg.lib_version = (ADW_LIB_VERSION_MAJOR << 8) |
        !           485:                ADW_LIB_VERSION_MINOR;
        !           486:        sc->cfg.chip_version =
        !           487:                ADW_GET_CHIP_VERSION(sc->sc_iot, sc->sc_ioh, sc->bus_type);
        !           488:
        !           489:        /*
        !           490:         * Reset the chip to start and allow register writes.
        !           491:         */
        !           492:        if (ADW_FIND_SIGNATURE(sc->sc_iot, sc->sc_ioh) == 0) {
        !           493:                panic("adw_init: adw_find_signature failed");
        !           494:        } else {
        !           495:                AdwResetChip(sc->sc_iot, sc->sc_ioh);
        !           496:
        !           497:                warn_code = AdwInitFromEEPROM(sc);
        !           498:
        !           499:                if (warn_code & ADW_WARN_EEPROM_CHKSUM)
        !           500:                        printf("%s: Bad checksum found. "
        !           501:                               "Setting default values\n",
        !           502:                               sc->sc_dev.dv_xname);
        !           503:                if (warn_code & ADW_WARN_EEPROM_TERMINATION)
        !           504:                        printf("%s: Bad bus termination setting."
        !           505:                               "Using automatic termination.\n",
        !           506:                               sc->sc_dev.dv_xname);
        !           507:        }
        !           508:
        !           509:        sc->isr_callback = (ADW_CALLBACK) adw_isr_callback;
        !           510:        sc->async_callback = (ADW_CALLBACK) adw_async_callback;
        !           511:
        !           512:        return 0;
        !           513: }
        !           514:
        !           515:
        !           516: void
        !           517: adw_attach(sc)
        !           518:        ADW_SOFTC      *sc;
        !           519: {
        !           520:        struct scsibus_attach_args      saa;
        !           521:        int                             i, error;
        !           522:
        !           523:
        !           524:        TAILQ_INIT(&sc->sc_free_ccb);
        !           525:        TAILQ_INIT(&sc->sc_waiting_ccb);
        !           526:        TAILQ_INIT(&sc->sc_pending_ccb);
        !           527:        LIST_INIT(&sc->sc_queue);
        !           528:
        !           529:
        !           530:        /*
        !           531:          * Allocate the Control Blocks.
        !           532:          */
        !           533:        error = adw_alloc_controls(sc);
        !           534:        if (error)
        !           535:                return; /* (error) */ ;
        !           536:
        !           537:        bzero(sc->sc_control, sizeof(struct adw_control));
        !           538:
        !           539:        /*
        !           540:         * Create and initialize the Control Blocks.
        !           541:         */
        !           542:        i = adw_create_ccbs(sc, sc->sc_control->ccbs, ADW_MAX_CCB);
        !           543:        if (i == 0) {
        !           544:                printf("%s: unable to create Control Blocks\n",
        !           545:                       sc->sc_dev.dv_xname);
        !           546:                return; /* (ENOMEM) */ ;
        !           547:        } else if (i != ADW_MAX_CCB) {
        !           548:                printf("%s: WARNING: only %d of %d Control Blocks"
        !           549:                       " created\n",
        !           550:                       sc->sc_dev.dv_xname, i, ADW_MAX_CCB);
        !           551:        }
        !           552:
        !           553:        /*
        !           554:         * Create and initialize the Carriers.
        !           555:         */
        !           556:        error = adw_alloc_carriers(sc);
        !           557:        if (error)
        !           558:                return; /* (error) */ ;
        !           559:
        !           560:        /*
        !           561:         * Zero's the freeze_device status
        !           562:         */
        !           563:         bzero(sc->sc_freeze_dev, sizeof(sc->sc_freeze_dev));
        !           564:
        !           565:        /*
        !           566:         * Initialize the adapter
        !           567:         */
        !           568:        switch (AdwInitDriver(sc)) {
        !           569:        case ADW_IERR_BIST_PRE_TEST:
        !           570:                panic("%s: BIST pre-test error",
        !           571:                      sc->sc_dev.dv_xname);
        !           572:                break;
        !           573:
        !           574:        case ADW_IERR_BIST_RAM_TEST:
        !           575:                panic("%s: BIST RAM test error",
        !           576:                      sc->sc_dev.dv_xname);
        !           577:                break;
        !           578:
        !           579:        case ADW_IERR_MCODE_CHKSUM:
        !           580:                panic("%s: Microcode checksum error",
        !           581:                      sc->sc_dev.dv_xname);
        !           582:                break;
        !           583:
        !           584:        case ADW_IERR_ILLEGAL_CONNECTION:
        !           585:                panic("%s: All three connectors are in use",
        !           586:                      sc->sc_dev.dv_xname);
        !           587:                break;
        !           588:
        !           589:        case ADW_IERR_REVERSED_CABLE:
        !           590:                panic("%s: Cable is reversed",
        !           591:                      sc->sc_dev.dv_xname);
        !           592:                break;
        !           593:
        !           594:        case ADW_IERR_HVD_DEVICE:
        !           595:                panic("%s: HVD attached to LVD connector",
        !           596:                      sc->sc_dev.dv_xname);
        !           597:                break;
        !           598:
        !           599:        case ADW_IERR_SINGLE_END_DEVICE:
        !           600:                panic("%s: single-ended device is attached to"
        !           601:                      " one of the connectors",
        !           602:                      sc->sc_dev.dv_xname);
        !           603:                break;
        !           604:
        !           605:        case ADW_IERR_NO_CARRIER:
        !           606:                panic("%s: unable to create Carriers",
        !           607:                      sc->sc_dev.dv_xname);
        !           608:                break;
        !           609:
        !           610:        case ADW_WARN_BUSRESET_ERROR:
        !           611:                printf("%s: WARNING: Bus Reset Error\n",
        !           612:                      sc->sc_dev.dv_xname);
        !           613:                break;
        !           614:        }
        !           615:
        !           616:        /*
        !           617:         * Fill in the adapter.
        !           618:         */
        !           619:        sc->sc_adapter.scsi_cmd = adw_scsi_cmd;
        !           620:        sc->sc_adapter.scsi_minphys = adw_minphys;
        !           621:
        !           622:        /*
        !           623:          * fill in the prototype scsi_link.
        !           624:          */
        !           625:        sc->sc_link.adapter_softc = sc;
        !           626:        sc->sc_link.adapter_target = sc->chip_scsi_id;
        !           627:        sc->sc_link.adapter = &sc->sc_adapter;
        !           628:        sc->sc_link.device = &adw_dev;
        !           629:        sc->sc_link.openings = 4;
        !           630:        sc->sc_link.adapter_buswidth = ADW_MAX_TID+1;
        !           631:
        !           632:        bzero(&saa, sizeof(saa));
        !           633:        saa.saa_sc_link = &sc->sc_link;
        !           634:
        !           635:        config_found(&sc->sc_dev, &saa, scsiprint);
        !           636: }
        !           637:
        !           638:
        !           639: void
        !           640: adw_minphys(bp)
        !           641:        struct buf     *bp;
        !           642: {
        !           643:
        !           644:        if (bp->b_bcount > ((ADW_MAX_SG_LIST - 1) * PAGE_SIZE))
        !           645:                bp->b_bcount = ((ADW_MAX_SG_LIST - 1) * PAGE_SIZE);
        !           646:        minphys(bp);
        !           647: }
        !           648:
        !           649:
        !           650: /*
        !           651:  * start a scsi operation given the command and the data address.
        !           652:  * Also needs the unit, target and lu.
        !           653:  */
        !           654: int
        !           655: adw_scsi_cmd(xs)
        !           656:        struct scsi_xfer *xs;
        !           657: {
        !           658:        struct scsi_link *sc_link = xs->sc_link;
        !           659:        ADW_SOFTC      *sc = sc_link->adapter_softc;
        !           660:        ADW_CCB        *ccb;
        !           661:        int             s, fromqueue = 1, dontqueue = 0, nowait = 0, retry = 0;
        !           662:        int             flags;
        !           663:
        !           664:        s = splbio();           /* protect the queue */
        !           665:
        !           666:        /*
        !           667:          * If we're running the queue from adw_done(), we've been
        !           668:          * called with the first queue entry as our argument.
        !           669:          */
        !           670:        if (xs == LIST_FIRST(&sc->sc_queue)) {
        !           671:                if(sc->sc_freeze_dev[xs->sc_link->target]) {
        !           672:                        splx(s);
        !           673:                        return (TRY_AGAIN_LATER);
        !           674:                }
        !           675:                xs = adw_dequeue(sc);
        !           676:                fromqueue = 1;
        !           677:                nowait = 1;
        !           678:        } else {
        !           679:                if(sc->sc_freeze_dev[xs->sc_link->target]) {
        !           680:                        splx(s);
        !           681:                        return (TRY_AGAIN_LATER);
        !           682:                }
        !           683:
        !           684:                /* Polled requests can't be queued for later. */
        !           685:                dontqueue = xs->flags & SCSI_POLL;
        !           686:
        !           687:                /*
        !           688:                  * If there are jobs in the queue, run them first.
        !           689:                  */
        !           690:                if (!LIST_EMPTY(&sc->sc_queue)) {
        !           691:                        /*
        !           692:                          * If we can't queue, we have to abort, since
        !           693:                          * we have to preserve order.
        !           694:                          */
        !           695:                        if (dontqueue) {
        !           696:                                splx(s);
        !           697:                                return (TRY_AGAIN_LATER);
        !           698:                        }
        !           699:                        /*
        !           700:                          * Swap with the first queue entry.
        !           701:                          */
        !           702:                        adw_enqueue(sc, xs, 0);
        !           703:                        xs = adw_dequeue(sc);
        !           704:                        fromqueue = 1;
        !           705:                }
        !           706:        }
        !           707:
        !           708:
        !           709:        /*
        !           710:          * get a ccb to use. If the transfer
        !           711:          * is from a buf (possibly from interrupt time)
        !           712:          * then we can't allow it to sleep
        !           713:          */
        !           714:
        !           715:        flags = xs->flags;
        !           716:        if (nowait)
        !           717:                flags |= SCSI_NOSLEEP;
        !           718:        if ((ccb = adw_get_ccb(sc, flags)) == NULL) {
        !           719:                /*
        !           720:                  * If we can't queue, we lose.
        !           721:                  */
        !           722:                if (dontqueue) {
        !           723:                        splx(s);
        !           724:                        return (TRY_AGAIN_LATER);
        !           725:                }
        !           726:                /*
        !           727:                  * Stuff ourselves into the queue, in front
        !           728:                  * if we came off in the first place.
        !           729:                  */
        !           730:                adw_enqueue(sc, xs, fromqueue);
        !           731:                splx(s);
        !           732:                return (SUCCESSFULLY_QUEUED);
        !           733:        }
        !           734:        splx(s);                /* done playing with the queue */
        !           735:
        !           736:        ccb->xs = xs;
        !           737:        ccb->timeout = xs->timeout;
        !           738:
        !           739:        if (adw_build_req(xs, ccb, flags)) {
        !           740: retryagain:
        !           741:                s = splbio();
        !           742:                retry = adw_queue_ccb(sc, ccb, retry);
        !           743:                splx(s);
        !           744:
        !           745:                switch(retry) {
        !           746:                case ADW_BUSY:
        !           747:                        goto retryagain;
        !           748:
        !           749:                case ADW_ERROR:
        !           750:                        xs->error = XS_DRIVER_STUFFUP;
        !           751:                        return (COMPLETE);
        !           752:                }
        !           753:
        !           754:                /*
        !           755:                 * Usually return SUCCESSFULLY QUEUED
        !           756:                 */
        !           757:                if ((xs->flags & SCSI_POLL) == 0)
        !           758:                        return (SUCCESSFULLY_QUEUED);
        !           759:
        !           760:                /*
        !           761:                 * If we can't use interrupts, poll on completion
        !           762:                 */
        !           763:                if (adw_poll(sc, xs, ccb->timeout)) {
        !           764:                        adw_timeout(ccb);
        !           765:                        if (adw_poll(sc, xs, ccb->timeout))
        !           766:                                adw_timeout(ccb);
        !           767:                }
        !           768:        }
        !           769:        return (COMPLETE);
        !           770: }
        !           771:
        !           772:
        !           773: /*
        !           774:  * Build a request structure for the Wide Boards.
        !           775:  */
        !           776: int
        !           777: adw_build_req(xs, ccb, flags)
        !           778:        struct scsi_xfer *xs;
        !           779:        ADW_CCB        *ccb;
        !           780:        int             flags;
        !           781: {
        !           782:        struct scsi_link *sc_link = xs->sc_link;
        !           783:        ADW_SOFTC      *sc = sc_link->adapter_softc;
        !           784:        bus_dma_tag_t   dmat = sc->sc_dmat;
        !           785:        ADW_SCSI_REQ_Q *scsiqp;
        !           786:        int             error;
        !           787:
        !           788:        scsiqp = &ccb->scsiq;
        !           789:        bzero(scsiqp, sizeof(ADW_SCSI_REQ_Q));
        !           790:
        !           791:        /*
        !           792:         * Set the ADW_SCSI_REQ_Q 'ccb_ptr' to point to the
        !           793:         * physical CCB structure.
        !           794:         */
        !           795:        scsiqp->ccb_ptr = ccb->hashkey;
        !           796:
        !           797:        /*
        !           798:         * Build the ADW_SCSI_REQ_Q request.
        !           799:         */
        !           800:
        !           801:        /*
        !           802:         * Set CDB length and copy it to the request structure.
        !           803:         * For wide  boards a CDB length maximum of 16 bytes
        !           804:         * is supported.
        !           805:         */
        !           806:        bcopy(xs->cmd, &scsiqp->cdb, ((scsiqp->cdb_len = xs->cmdlen) <= 12)?
        !           807:                        xs->cmdlen : 12 );
        !           808:        if(xs->cmdlen > 12)
        !           809:                bcopy(&(xs->cmd[12]),  &scsiqp->cdb16, xs->cmdlen - 12);
        !           810:
        !           811:        scsiqp->target_id = sc_link->target;
        !           812:        scsiqp->target_lun = sc_link->lun;
        !           813:
        !           814:        scsiqp->vsense_addr = &ccb->scsi_sense;
        !           815:        scsiqp->sense_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr +
        !           816:                        ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsi_sense);
        !           817:        scsiqp->sense_len = sizeof(struct scsi_sense_data);
        !           818:
        !           819:        /*
        !           820:         * Build ADW_SCSI_REQ_Q for a scatter-gather buffer command.
        !           821:         */
        !           822:        if (xs->datalen) {
        !           823:                /*
        !           824:                  * Map the DMA transfer.
        !           825:                  */
        !           826: #ifdef TFS
        !           827:                if (xs->flags & SCSI_DATA_UIO) {
        !           828:                        error = bus_dmamap_load_uio(dmat,
        !           829:                                ccb->dmamap_xfer, (struct uio *) xs->data,
        !           830:                                (flags & SCSI_NOSLEEP) ?
        !           831:                                BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
        !           832:                } else
        !           833: #endif         /* TFS */
        !           834:                {
        !           835:                        error = bus_dmamap_load(dmat,
        !           836:                              ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
        !           837:                                (flags & SCSI_NOSLEEP) ?
        !           838:                                BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
        !           839:                }
        !           840:
        !           841:                if (error) {
        !           842:                        if (error == EFBIG) {
        !           843:                                printf("%s: adw_scsi_cmd, more than %d dma"
        !           844:                                       " segments\n",
        !           845:                                       sc->sc_dev.dv_xname, ADW_MAX_SG_LIST);
        !           846:                        } else {
        !           847:                                printf("%s: adw_scsi_cmd, error %d loading"
        !           848:                                       " dma map\n",
        !           849:                                       sc->sc_dev.dv_xname, error);
        !           850:                        }
        !           851:
        !           852:                        xs->error = XS_DRIVER_STUFFUP;
        !           853:                        adw_free_ccb(sc, ccb);
        !           854:                        return (0);
        !           855:                }
        !           856:                bus_dmamap_sync(dmat, ccb->dmamap_xfer,
        !           857:                    0, ccb->dmamap_xfer->dm_mapsize,
        !           858:                    (xs->flags & SCSI_DATA_IN) ?
        !           859:                    BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
        !           860:
        !           861:                /*
        !           862:                 * Build scatter-gather list.
        !           863:                 */
        !           864:                scsiqp->data_cnt = xs->datalen;
        !           865:                scsiqp->vdata_addr = xs->data;
        !           866:                scsiqp->data_addr = ccb->dmamap_xfer->dm_segs[0].ds_addr;
        !           867:                bzero(ccb->sg_block, sizeof(ADW_SG_BLOCK) * ADW_NUM_SG_BLOCK);
        !           868:                adw_build_sglist(ccb, scsiqp, ccb->sg_block);
        !           869:        } else {
        !           870:                /*
        !           871:                  * No data xfer, use non S/G values.
        !           872:                  */
        !           873:                scsiqp->data_cnt = 0;
        !           874:                scsiqp->vdata_addr = 0;
        !           875:                scsiqp->data_addr = 0;
        !           876:        }
        !           877:
        !           878:        return (1);
        !           879: }
        !           880:
        !           881:
        !           882: /*
        !           883:  * Build scatter-gather list for Wide Boards.
        !           884:  */
        !           885: void
        !           886: adw_build_sglist(ccb, scsiqp, sg_block)
        !           887:        ADW_CCB        *ccb;
        !           888:        ADW_SCSI_REQ_Q *scsiqp;
        !           889:        ADW_SG_BLOCK   *sg_block;
        !           890: {
        !           891:        u_long          sg_block_next_addr;     /* block and its next */
        !           892:        u_int32_t       sg_block_physical_addr;
        !           893:        int             i;      /* how many SG entries */
        !           894:        bus_dma_segment_t *sg_list = &ccb->dmamap_xfer->dm_segs[0];
        !           895:        int             sg_elem_cnt = ccb->dmamap_xfer->dm_nsegs;
        !           896:
        !           897:
        !           898:        sg_block_next_addr = (u_long) sg_block; /* allow math operation */
        !           899:        sg_block_physical_addr = ccb->hashkey +
        !           900:            offsetof(struct adw_ccb, sg_block[0]);
        !           901:        scsiqp->sg_real_addr = sg_block_physical_addr;
        !           902:
        !           903:        /*
        !           904:         * If there are more than NO_OF_SG_PER_BLOCK dma segments (hw sg-list)
        !           905:         * then split the request into multiple sg-list blocks.
        !           906:         */
        !           907:
        !           908:        do {
        !           909:                for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
        !           910:                        sg_block->sg_list[i].sg_addr = sg_list->ds_addr;
        !           911:                        sg_block->sg_list[i].sg_count = sg_list->ds_len;
        !           912:
        !           913:                        if (--sg_elem_cnt == 0) {
        !           914:                                /* last entry, get out */
        !           915:                                sg_block->sg_cnt = i + 1;
        !           916:                                sg_block->sg_ptr = NULL; /* next link = NULL */
        !           917:                                return;
        !           918:                        }
        !           919:                        sg_list++;
        !           920:                }
        !           921:                sg_block_next_addr += sizeof(ADW_SG_BLOCK);
        !           922:                sg_block_physical_addr += sizeof(ADW_SG_BLOCK);
        !           923:
        !           924:                sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
        !           925:                sg_block->sg_ptr = sg_block_physical_addr;
        !           926:                sg_block = (ADW_SG_BLOCK *) sg_block_next_addr; /* virt. addr */
        !           927:        } while (1);
        !           928: }
        !           929:
        !           930:
        !           931: /******************************************************************************/
        !           932: /*                       Interrupts and TimeOut routines                      */
        !           933: /******************************************************************************/
        !           934:
        !           935:
        !           936: int
        !           937: adw_intr(arg)
        !           938:        void           *arg;
        !           939: {
        !           940:        ADW_SOFTC      *sc = arg;
        !           941:        struct scsi_xfer *xs;
        !           942:
        !           943:
        !           944:        if(AdwISR(sc) != ADW_FALSE) {
        !           945:                /*
        !           946:                 * If there are queue entries in the software queue, try to
        !           947:                 * run the first one.  We should be more or less guaranteed
        !           948:                 * to succeed, since we just freed a CCB.
        !           949:                 *
        !           950:                 * NOTE: adw_scsi_cmd() relies on our calling it with
        !           951:                 * the first entry in the queue.
        !           952:                 */
        !           953:                if ((xs = LIST_FIRST(&sc->sc_queue)) != NULL)
        !           954:                        (void) adw_scsi_cmd(xs);
        !           955:
        !           956:                return (1);
        !           957:        }
        !           958:
        !           959:        return (0);
        !           960: }
        !           961:
        !           962:
        !           963: /*
        !           964:  * Poll a particular unit, looking for a particular xs
        !           965:  */
        !           966: int
        !           967: adw_poll(sc, xs, count)
        !           968:        ADW_SOFTC      *sc;
        !           969:        struct scsi_xfer *xs;
        !           970:        int             count;
        !           971: {
        !           972:
        !           973:        /* timeouts are in msec, so we loop in 1000 usec cycles */
        !           974:        while (count > 0) {
        !           975:                adw_intr(sc);
        !           976:                if (xs->flags & ITSDONE) {
        !           977:                        if ((xs->cmd->opcode == INQUIRY)
        !           978:                            && (xs->sc_link->lun == 0)
        !           979:                            && (xs->error == XS_NOERROR))
        !           980:                                adw_print_info(sc, xs->sc_link->target);
        !           981:                        return (0);
        !           982:                }
        !           983:                delay(1000);    /* only happens in boot so ok */
        !           984:                count--;
        !           985:        }
        !           986:        return (1);
        !           987: }
        !           988:
        !           989:
        !           990: void
        !           991: adw_timeout(arg)
        !           992:        void           *arg;
        !           993: {
        !           994:        ADW_CCB        *ccb = arg;
        !           995:        struct scsi_xfer *xs = ccb->xs;
        !           996:        struct scsi_link *sc_link = xs->sc_link;
        !           997:        ADW_SOFTC      *sc = sc_link->adapter_softc;
        !           998:        int             s;
        !           999:
        !          1000:        sc_print_addr(sc_link);
        !          1001:        printf("timed out");
        !          1002:
        !          1003:        s = splbio();
        !          1004:
        !          1005:        if (ccb->flags & CCB_ABORTED) {
        !          1006:        /*
        !          1007:         * Abort Timed Out
        !          1008:         *
        !          1009:         * No more opportunities. Lets try resetting the bus and
        !          1010:         * reinitialize the host adapter.
        !          1011:         */
        !          1012:                timeout_del(&xs->stimeout);
        !          1013:                printf(" AGAIN. Resetting SCSI Bus\n");
        !          1014:                adw_reset_bus(sc);
        !          1015:                splx(s);
        !          1016:                return;
        !          1017:        } else if (ccb->flags & CCB_ABORTING) {
        !          1018:        /*
        !          1019:         * Abort the operation that has timed out.
        !          1020:         *
        !          1021:         * Second opportunity.
        !          1022:         */
        !          1023:                printf("\n");
        !          1024:                xs->error = XS_TIMEOUT;
        !          1025:                ccb->flags |= CCB_ABORTED;
        !          1026: #if 0
        !          1027:                /*
        !          1028:                 * - XXX - 3.3a microcode is BROKEN!!!
        !          1029:                 *
        !          1030:                 * We cannot abort a CCB, so we can only hope the command
        !          1031:                 * get completed before the next timeout, otherwise a
        !          1032:                 * Bus Reset will arrive inexorably.
        !          1033:                 */
        !          1034:                /*
        !          1035:                 * ADW_ABORT_CCB() makes the board to generate an interrupt
        !          1036:                 *
        !          1037:                 * - XXX - The above assertion MUST be verified (and this
        !          1038:                 *         code changed as well [callout_*()]), when the
        !          1039:                 *         ADW_ABORT_CCB will be working again
        !          1040:                 */
        !          1041:                ADW_ABORT_CCB(sc, ccb);
        !          1042: #endif
        !          1043:                /*
        !          1044:                 * waiting for multishot callout_reset() let's restart it
        !          1045:                 * by hand so the next time a timeout event will occur
        !          1046:                 * we will reset the bus.
        !          1047:                 */
        !          1048:                timeout_add(&xs->stimeout, (ccb->timeout * hz) / 1000);
        !          1049:        } else {
        !          1050:        /*
        !          1051:         * Abort the operation that has timed out.
        !          1052:         *
        !          1053:         * First opportunity.
        !          1054:         */
        !          1055:                printf("\n");
        !          1056:                xs->error = XS_TIMEOUT;
        !          1057:                ccb->flags |= CCB_ABORTING;
        !          1058: #if 0
        !          1059:                /*
        !          1060:                 * - XXX - 3.3a microcode is BROKEN!!!
        !          1061:                 *
        !          1062:                 * We cannot abort a CCB, so we can only hope the command
        !          1063:                 * get completed before the next 2 timeout, otherwise a
        !          1064:                 * Bus Reset will arrive inexorably.
        !          1065:                 */
        !          1066:                /*
        !          1067:                 * ADW_ABORT_CCB() makes the board to generate an interrupt
        !          1068:                 *
        !          1069:                 * - XXX - The above assertion MUST be verified (and this
        !          1070:                 *         code changed as well [callout_*()]), when the
        !          1071:                 *         ADW_ABORT_CCB will be working again
        !          1072:                 */
        !          1073:                ADW_ABORT_CCB(sc, ccb);
        !          1074: #endif
        !          1075:                /*
        !          1076:                 * waiting for multishot callout_reset() let's restart it
        !          1077:                 * by hand so to give a second opportunity to the command
        !          1078:                 * which timed-out.
        !          1079:                 */
        !          1080:                timeout_add(&xs->stimeout, (ccb->timeout * hz) / 1000);
        !          1081:        }
        !          1082:
        !          1083:        splx(s);
        !          1084: }
        !          1085:
        !          1086:
        !          1087: void
        !          1088: adw_reset_bus(sc)
        !          1089:        ADW_SOFTC               *sc;
        !          1090: {
        !          1091:        ADW_CCB *ccb;
        !          1092:        int      s;
        !          1093:
        !          1094:        s = splbio();
        !          1095:        AdwResetSCSIBus(sc); /* XXX - should check return value? */
        !          1096:        while((ccb = TAILQ_LAST(&sc->sc_pending_ccb,
        !          1097:                        adw_pending_ccb)) != NULL) {
        !          1098:                timeout_del(&ccb->xs->stimeout);
        !          1099:                TAILQ_REMOVE(&sc->sc_pending_ccb, ccb, chain);
        !          1100:                TAILQ_INSERT_HEAD(&sc->sc_waiting_ccb, ccb, chain);
        !          1101:        }
        !          1102:
        !          1103:        bzero(sc->sc_freeze_dev, sizeof(sc->sc_freeze_dev));
        !          1104:        adw_queue_ccb(sc, TAILQ_FIRST(&sc->sc_waiting_ccb), 1);
        !          1105:
        !          1106:        splx(s);
        !          1107: }
        !          1108:
        !          1109:
        !          1110: /******************************************************************************/
        !          1111: /*              Host Adapter and Peripherals Information Routines             */
        !          1112: /******************************************************************************/
        !          1113:
        !          1114:
        !          1115: void
        !          1116: adw_print_info(sc, tid)
        !          1117:        ADW_SOFTC       *sc;
        !          1118:        int              tid;
        !          1119: {
        !          1120:        bus_space_handle_t ioh = sc->sc_ioh;
        !          1121:        bus_space_tag_t iot = sc->sc_iot;
        !          1122:        u_int16_t hshk_cfg, able_mask, period = 0;
        !          1123:
        !          1124:        /* hshk/HSHK means 'handskake' */
        !          1125:
        !          1126:        ADW_READ_WORD_LRAM(iot, ioh,
        !          1127:            ADW_MC_DEVICE_HSHK_CFG_TABLE + (2 * tid), hshk_cfg);
        !          1128:
        !          1129:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, able_mask);
        !          1130:        if ((able_mask & ADW_TID_TO_TIDMASK(tid)) == 0)
        !          1131:                hshk_cfg &= ~HSHK_CFG_WIDE_XFR;
        !          1132:
        !          1133:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, able_mask);
        !          1134:        if ((able_mask & ADW_TID_TO_TIDMASK(tid)) == 0)
        !          1135:                hshk_cfg &= ~HSHK_CFG_OFFSET;
        !          1136:
        !          1137:        printf("%s: target %d using %d bit ", sc->sc_dev.dv_xname, tid,
        !          1138:            (hshk_cfg & HSHK_CFG_WIDE_XFR) ? 16 : 8);
        !          1139:
        !          1140:        if ((hshk_cfg & HSHK_CFG_OFFSET) == 0)
        !          1141:                printf("async ");
        !          1142:        else {
        !          1143:                period = (hshk_cfg & 0x1f00) >> 8;
        !          1144:                switch (period) {
        !          1145:                case 0x11:
        !          1146:                        printf("80.0 ");
        !          1147:                        break;
        !          1148:                case 0x10:
        !          1149:                        printf("40.0 ");
        !          1150:                        break;
        !          1151:                default:
        !          1152:                        period = (period * 25) + 50;
        !          1153:                        printf("%d.%d ", 1000/period, ADW_TENTHS(1000, period));
        !          1154:                        break;
        !          1155:                }
        !          1156:                printf("MHz %d REQ/ACK offset ", hshk_cfg & HSHK_CFG_OFFSET);
        !          1157:        }
        !          1158:
        !          1159:        printf("xfers\n");
        !          1160: }
        !          1161:
        !          1162:
        !          1163: /******************************************************************************/
        !          1164: /*                        WIDE boards Interrupt callbacks                     */
        !          1165: /******************************************************************************/
        !          1166:
        !          1167:
        !          1168: /*
        !          1169:  * adw_isr_callback() - Second Level Interrupt Handler called by AdwISR()
        !          1170:  *
        !          1171:  * Interrupt callback function for the Wide SCSI Adw Library.
        !          1172:  *
        !          1173:  * Notice:
        !          1174:  * Interrupts are disabled by the caller (AdwISR() function), and will be
        !          1175:  * enabled at the end of the caller.
        !          1176:  */
        !          1177: void
        !          1178: adw_isr_callback(sc, scsiq)
        !          1179:        ADW_SOFTC      *sc;
        !          1180:        ADW_SCSI_REQ_Q *scsiq;
        !          1181: {
        !          1182:        bus_dma_tag_t   dmat;
        !          1183:        ADW_CCB        *ccb;
        !          1184:        struct scsi_xfer *xs;
        !          1185:        struct scsi_sense_data *s1, *s2;
        !          1186:
        !          1187:
        !          1188:        ccb = adw_ccb_phys_kv(sc, scsiq->ccb_ptr);
        !          1189:        TAILQ_REMOVE(&sc->sc_pending_ccb, ccb, chain);
        !          1190:
        !          1191:        if ((ccb->flags & CCB_ALLOC) == 0) {
        !          1192:                printf("%s: unallocated ccb found on pending list!\n",
        !          1193:                    sc->sc_dev.dv_xname);
        !          1194:                Debugger();
        !          1195:                adw_free_ccb(sc, ccb);
        !          1196:                return;
        !          1197:        }
        !          1198:
        !          1199:        xs = ccb->xs;
        !          1200:        timeout_del(&xs->stimeout);
        !          1201:
        !          1202:        /*
        !          1203:          * If we were a data transfer, unload the map that described
        !          1204:          * the data buffer.
        !          1205:          */
        !          1206:        dmat = sc->sc_dmat;
        !          1207:        if (xs->datalen) {
        !          1208:                bus_dmamap_sync(dmat, ccb->dmamap_xfer,
        !          1209:                    0, ccb->dmamap_xfer->dm_mapsize,
        !          1210:                    ((xs->flags & SCSI_DATA_IN) ?
        !          1211:                        BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
        !          1212:                bus_dmamap_unload(dmat, ccb->dmamap_xfer);
        !          1213:        }
        !          1214:
        !          1215:        /*
        !          1216:         * 'done_status' contains the command's ending status.
        !          1217:         * 'host_status' contains the host adapter status.
        !          1218:         * 'scsi_status' contains the scsi peripheral status.
        !          1219:         */
        !          1220:
        !          1221:        sc->sc_freeze_dev[scsiq->target_id] = 0;
        !          1222:        xs->status = scsiq->scsi_status;
        !          1223:
        !          1224:        switch (scsiq->done_status) {
        !          1225:        case QD_NO_ERROR: /* (scsi_status == 0) && (host_status == 0) */
        !          1226: NO_ERROR:
        !          1227:                xs->resid = scsiq->data_cnt;
        !          1228:                xs->error = XS_NOERROR;
        !          1229:                break;
        !          1230:
        !          1231:        case QD_WITH_ERROR:
        !          1232:                switch (scsiq->host_status) {
        !          1233:                case QHSTA_NO_ERROR:
        !          1234:                        switch (scsiq->scsi_status) {
        !          1235:                        case SCSI_COND_MET:
        !          1236:                        case SCSI_INTERM:
        !          1237:                        case SCSI_INTERM_COND_MET:
        !          1238:                                /*
        !          1239:                                 * These non-zero status values are
        !          1240:                                 * not really error conditions.
        !          1241:                                 *
        !          1242:                                 * XXX - would it be too paranoid to
        !          1243:                                 *       add SCSI_OK here in
        !          1244:                                 *       case the docs are wrong re
        !          1245:                                 *       QD_NO_ERROR?
        !          1246:                                 */
        !          1247:                                goto NO_ERROR;
        !          1248:
        !          1249:                        case SCSI_CHECK:
        !          1250:                        case SCSI_TERMINATED:
        !          1251:                        case SCSI_ACA_ACTIVE:
        !          1252:                                s1 = &ccb->scsi_sense;
        !          1253:                                s2 = &xs->sense;
        !          1254:                                *s2 = *s1;
        !          1255:                                xs->error = XS_SENSE;
        !          1256:                                break;
        !          1257:
        !          1258:                        case SCSI_BUSY:
        !          1259:                        case SCSI_QUEUE_FULL:
        !          1260:                        case SCSI_RESV_CONFLICT:
        !          1261:                                sc->sc_freeze_dev[scsiq->target_id] = 1;
        !          1262:                                xs->error = XS_BUSY;
        !          1263:                                break;
        !          1264:
        !          1265:                        default: /* scsiq->scsi_status value */
        !          1266:                                printf("%s: bad scsi_status: 0x%02x.\n"
        !          1267:                                    ,sc->sc_dev.dv_xname
        !          1268:                                    ,scsiq->scsi_status);
        !          1269:                                xs->error = XS_DRIVER_STUFFUP;
        !          1270:                                break;
        !          1271:                        }
        !          1272:                        break;
        !          1273:
        !          1274:                case QHSTA_M_SEL_TIMEOUT:
        !          1275:                        xs->error = XS_SELTIMEOUT;
        !          1276:                        break;
        !          1277:
        !          1278:                case QHSTA_M_DIRECTION_ERR:
        !          1279:                case QHSTA_M_SXFR_OFF_UFLW:
        !          1280:                case QHSTA_M_SXFR_OFF_OFLW:
        !          1281:                case QHSTA_M_SXFR_XFR_OFLW:
        !          1282:                case QHSTA_M_QUEUE_ABORTED:
        !          1283:                case QHSTA_M_INVALID_DEVICE:
        !          1284:                case QHSTA_M_SGBACKUP_ERROR:
        !          1285:                case QHSTA_M_SXFR_DESELECTED:
        !          1286:                case QHSTA_M_SXFR_XFR_PH_ERR:
        !          1287:                case QHSTA_M_BUS_DEVICE_RESET:
        !          1288:                case QHSTA_M_NO_AUTO_REQ_SENSE:
        !          1289:                case QHSTA_M_BAD_CMPL_STATUS_IN:
        !          1290:                case QHSTA_M_SXFR_UNKNOWN_ERROR:
        !          1291:                case QHSTA_M_AUTO_REQ_SENSE_FAIL:
        !          1292:                case QHSTA_M_UNEXPECTED_BUS_FREE:
        !          1293:                        printf("%s: host adapter error 0x%02x."
        !          1294:                               " See adw(4).\n"
        !          1295:                            ,sc->sc_dev.dv_xname, scsiq->host_status);
        !          1296:                        xs->error = XS_DRIVER_STUFFUP;
        !          1297:                        break;
        !          1298:
        !          1299:                case QHSTA_M_RDMA_PERR:
        !          1300:                case QHSTA_M_SXFR_WD_TMO:
        !          1301:                case QHSTA_M_WTM_TIMEOUT:
        !          1302:                case QHSTA_M_FROZEN_TIDQ:
        !          1303:                case QHSTA_M_SXFR_SDMA_ERR:
        !          1304:                case QHSTA_M_SXFR_SXFR_PERR:
        !          1305:                case QHSTA_M_SCSI_BUS_RESET:
        !          1306:                case QHSTA_M_DIRECTION_ERR_HUNG:
        !          1307:                case QHSTA_M_SCSI_BUS_RESET_UNSOL:
        !          1308:                        /*
        !          1309:                         * XXX - are all these cases really asking
        !          1310:                         *       for a card reset? _BUS_RESET and
        !          1311:                         *       _BUS_RESET_UNSOL added just to make
        !          1312:                         *       sure the pending queue is cleared out
        !          1313:                         *       in case card has lost track of them.
        !          1314:                         */
        !          1315:                        printf("%s: host adapter error 0x%02x,"
        !          1316:                               " resetting bus. See adw(4).\n"
        !          1317:                            ,sc->sc_dev.dv_xname, scsiq->host_status);
        !          1318:                        adw_reset_bus(sc);
        !          1319:                        xs->error = XS_RESET;
        !          1320:                        break;
        !          1321:
        !          1322:                default: /* scsiq->host_status value */
        !          1323:                        /*
        !          1324:                         * XXX - is a panic really appropriate here? If
        !          1325:                         *       not, would it be better to make the
        !          1326:                         *       XS_DRIVER_STUFFUP case above the
        !          1327:                         *       default behaviour? Or XS_RESET?
        !          1328:                         */
        !          1329:                        panic("%s: bad host_status: 0x%02x"
        !          1330:                            ,sc->sc_dev.dv_xname, scsiq->host_status);
        !          1331:                        break;
        !          1332:                }
        !          1333:                break;
        !          1334:
        !          1335:        case QD_ABORTED_BY_HOST:
        !          1336:                xs->error = XS_DRIVER_STUFFUP;
        !          1337:                break;
        !          1338:
        !          1339:        default: /* scsiq->done_status value */
        !          1340:                /*
        !          1341:                 * XXX - would QD_NO_STATUS really mean the I/O is not
        !          1342:                 *       done? and would that mean it should somehow be
        !          1343:                 *       put back as a pending I/O?
        !          1344:                 */
        !          1345:                printf("%s: bad done_status: 0x%02x"
        !          1346:                       " (host_status: 0x%02x, scsi_status: 0x%02x)\n"
        !          1347:                    ,sc->sc_dev.dv_xname
        !          1348:                    ,scsiq->done_status
        !          1349:                    ,scsiq->host_status
        !          1350:                    ,scsiq->scsi_status);
        !          1351:                xs->error = XS_DRIVER_STUFFUP;
        !          1352:                break;
        !          1353:        }
        !          1354:
        !          1355:        adw_free_ccb(sc, ccb);
        !          1356:
        !          1357:        xs->flags |= ITSDONE;
        !          1358:        scsi_done(xs);
        !          1359: }
        !          1360:
        !          1361:
        !          1362: /*
        !          1363:  * adw_async_callback() - Adw Library asynchronous event callback function.
        !          1364:  */
        !          1365: void
        !          1366: adw_async_callback(sc, code)
        !          1367:        ADW_SOFTC       *sc;
        !          1368:        u_int8_t        code;
        !          1369: {
        !          1370:        switch (code) {
        !          1371:        case ADW_ASYNC_SCSI_BUS_RESET_DET:
        !          1372:                /* The firmware detected a SCSI Bus reset. */
        !          1373:                printf("%s: SCSI Bus reset detected\n", sc->sc_dev.dv_xname);
        !          1374:                break;
        !          1375:
        !          1376:        case ADW_ASYNC_RDMA_FAILURE:
        !          1377:                /*
        !          1378:                 * Handle RDMA failure by resetting the SCSI Bus and
        !          1379:                 * possibly the chip if it is unresponsive.
        !          1380:                 */
        !          1381:                printf("%s: RDMA failure. Resetting the SCSI Bus and"
        !          1382:                                " the adapter\n", sc->sc_dev.dv_xname);
        !          1383:                adw_reset_bus(sc);
        !          1384:                break;
        !          1385:
        !          1386:        case ADW_HOST_SCSI_BUS_RESET:
        !          1387:                /* Host generated SCSI bus reset occurred. */
        !          1388:                printf("%s: Host generated SCSI bus reset occurred\n",
        !          1389:                                sc->sc_dev.dv_xname);
        !          1390:                break;
        !          1391:
        !          1392:
        !          1393:        case ADW_ASYNC_CARRIER_READY_FAILURE:
        !          1394:                /*
        !          1395:                 * Carrier Ready failure.
        !          1396:                 *
        !          1397:                 * A warning only - RISC too busy to realize it's been
        !          1398:                 * tickled. Occurs in normal operation under heavy
        !          1399:                 * load, so a message is printed only when ADW_DEBUG'ing
        !          1400:                 */
        !          1401: #ifdef ADW_DEBUG
        !          1402:                printf("%s: Carrier Ready failure!\n", sc->sc_dev.dv_xname);
        !          1403: #endif
        !          1404:                break;
        !          1405:
        !          1406:        default:
        !          1407:                printf("%s: Unknown Async callback code (ignored): 0x%02x\n",
        !          1408:                    sc->sc_dev.dv_xname, code);
        !          1409:                break;
        !          1410:        }
        !          1411: }

CVSweb