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

Annotation of sys/dev/ic/bha.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: bha.c,v 1.10 2007/04/10 17:47:55 miod Exp $   */
                      2: /*     $NetBSD: bha.c,v 1.27 1998/11/19 21:53:00 thorpej Exp $ */
                      3:
                      4: #undef BHADEBUG
                      5: #ifdef DDB
                      6: #define        integrate
                      7: #else
                      8: #define        integrate       static inline
                      9: #endif
                     10:
                     11: /*-
                     12:  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
                     13:  * All rights reserved.
                     14:  *
                     15:  * This code is derived from software contributed to The NetBSD Foundation
                     16:  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
                     17:  * Simulation Facility, NASA Ames Research Center.
                     18:  *
                     19:  * Redistribution and use in source and binary forms, with or without
                     20:  * modification, are permitted provided that the following conditions
                     21:  * are met:
                     22:  * 1. Redistributions of source code must retain the above copyright
                     23:  *    notice, this list of conditions and the following disclaimer.
                     24:  * 2. Redistributions in binary form must reproduce the above copyright
                     25:  *    notice, this list of conditions and the following disclaimer in the
                     26:  *    documentation and/or other materials provided with the distribution.
                     27:  * 3. All advertising materials mentioning features or use of this software
                     28:  *    must display the following acknowledgement:
                     29:  *     This product includes software developed by the NetBSD
                     30:  *     Foundation, Inc. and its contributors.
                     31:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     32:  *    contributors may be used to endorse or promote products derived
                     33:  *    from this software without specific prior written permission.
                     34:  *
                     35:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     36:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     37:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     38:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     39:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     40:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     41:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     42:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     43:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     44:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     45:  * POSSIBILITY OF SUCH DAMAGE.
                     46:  */
                     47:
                     48: /*
                     49:  * Originally written by Julian Elischer (julian@tfs.com)
                     50:  * for TRW Financial Systems for use under the MACH(2.5) operating system.
                     51:  *
                     52:  * TRW Financial Systems, in accordance with their agreement with Carnegie
                     53:  * Mellon University, makes this software available to CMU to distribute
                     54:  * or use in any manner that they see fit as long as this message is kept with
                     55:  * the software. For this reason TFS also grants any other persons or
                     56:  * organisations permission to use or modify this software.
                     57:  *
                     58:  * TFS supplies this software to be publicly redistributed
                     59:  * on the understanding that TFS is not responsible for the correct
                     60:  * functioning of this software in any circumstances.
                     61:  */
                     62:
                     63: #include <sys/types.h>
                     64: #include <sys/param.h>
                     65: #include <sys/systm.h>
                     66: #include <sys/kernel.h>
                     67: #include <sys/errno.h>
                     68: #include <sys/ioctl.h>
                     69: #include <sys/device.h>
                     70: #include <sys/malloc.h>
                     71: #include <sys/buf.h>
                     72: #include <sys/proc.h>
                     73: #include <sys/user.h>
                     74:
                     75: #include <machine/bus.h>
                     76: #include <machine/intr.h>
                     77:
                     78: #include <scsi/scsi_all.h>
                     79: #include <scsi/scsiconf.h>
                     80:
                     81: #include <dev/ic/bhareg.h>
                     82: #include <dev/ic/bhavar.h>
                     83:
                     84: #ifndef DDB
                     85: #define Debugger() panic("should call debugger here (bha.c)")
                     86: #endif /* ! DDB */
                     87:
                     88: #define        BHA_MAXXFER     ((BHA_NSEG - 1) << PGSHIFT)
                     89: #define        ISWIDE(sc)      ((sc)->sc_iswide)
                     90:
                     91: #ifdef BHADEBUG
                     92: int     bha_debug = 1;
                     93: #endif /* BHADEBUG */
                     94:
                     95: integrate void bha_finish_ccbs(struct bha_softc *);
                     96: integrate void bha_reset_ccb(struct bha_softc *, struct bha_ccb *);
                     97: void bha_free_ccb(struct bha_softc *, struct bha_ccb *);
                     98: integrate int bha_init_ccb(struct bha_softc *, struct bha_ccb *);
                     99: struct bha_ccb *bha_get_ccb(struct bha_softc *, int);
                    100: struct bha_ccb *bha_ccb_phys_kv(struct bha_softc *, u_long);
                    101: void bha_queue_ccb(struct bha_softc *, struct bha_ccb *);
                    102: void bha_collect_mbo(struct bha_softc *);
                    103: void bha_start_ccbs(struct bha_softc *);
                    104: void bha_done(struct bha_softc *, struct bha_ccb *);
                    105: int bha_init(struct bha_softc *);
                    106: void bhaminphys(struct buf *);
                    107: int bha_scsi_cmd(struct scsi_xfer *);
                    108: int bha_poll(struct bha_softc *, struct scsi_xfer *, int);
                    109: void bha_timeout(void *arg);
                    110: int bha_create_ccbs(struct bha_softc *, struct bha_ccb *, int);
                    111: void bha_enqueue(struct bha_softc *, struct scsi_xfer *, int);
                    112: struct scsi_xfer *bha_dequeue(struct bha_softc *);
                    113:
                    114: struct cfdriver bha_cd = {
                    115:        NULL, "bha", DV_DULL
                    116: };
                    117:
                    118: /* the below structure is so we have a default dev struct for out link struct */
                    119: struct scsi_device bha_dev = {
                    120:        NULL,                   /* Use default error handler */
                    121:        NULL,                   /* have a queue, served by this */
                    122:        NULL,                   /* have no async handler */
                    123:        NULL,                   /* Use default 'done' routine */
                    124: };
                    125:
                    126: #define BHA_RESET_TIMEOUT      2000    /* time to wait for reset (mSec) */
                    127: #define        BHA_ABORT_TIMEOUT       2000    /* time to wait for abort (mSec) */
                    128:
                    129: /*
                    130:  * Insert a scsi_xfer into the software queue.  We overload xs->free_list
                    131:  * to avoid having to allocate additional resources (since we're used
                    132:  * only during resource shortages anyhow.
                    133:  */
                    134: void
                    135: bha_enqueue(sc, xs, infront)
                    136:        struct bha_softc *sc;
                    137:        struct scsi_xfer *xs;
                    138:        int infront;
                    139: {
                    140:
                    141:        if (infront || LIST_EMPTY(&sc->sc_queue)) {
                    142:                if (LIST_EMPTY(&sc->sc_queue))
                    143:                        sc->sc_queuelast = xs;
                    144:                LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
                    145:                return;
                    146:        }
                    147:
                    148:        LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
                    149:        sc->sc_queuelast = xs;
                    150: }
                    151:
                    152: /*
                    153:  * Pull a scsi_xfer off the front of the software queue.
                    154:  */
                    155: struct scsi_xfer *
                    156: bha_dequeue(sc)
                    157:        struct bha_softc *sc;
                    158: {
                    159:        struct scsi_xfer *xs;
                    160:
                    161:        xs = LIST_FIRST(&sc->sc_queue);
                    162:        LIST_REMOVE(xs, free_list);
                    163:
                    164:        if (LIST_EMPTY(&sc->sc_queue))
                    165:                sc->sc_queuelast = NULL;
                    166:
                    167:        return (xs);
                    168: }
                    169:
                    170: /*
                    171:  * bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
                    172:  *
                    173:  * Activate Adapter command
                    174:  *    icnt:   number of args (outbound bytes including opcode)
                    175:  *    ibuf:   argument buffer
                    176:  *    ocnt:   number of expected returned bytes
                    177:  *    obuf:   result buffer
                    178:  *    wait:   number of seconds to wait for response
                    179:  *
                    180:  * Performs an adapter command through the ports.  Not to be confused with a
                    181:  * scsi command, which is read in via the dma; one of the adapter commands
                    182:  * tells it to read in a scsi command.
                    183:  */
                    184: int
                    185: bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
                    186:        bus_space_tag_t iot;
                    187:        bus_space_handle_t ioh;
                    188:        struct bha_softc *sc;
                    189:        int icnt, ocnt;
                    190:        u_char *ibuf, *obuf;
                    191: {
                    192:        const char *name;
                    193:        register int i;
                    194:        int wait;
                    195:        u_char sts;
                    196:        u_char opcode = ibuf[0];
                    197:
                    198:        if (sc != NULL)
                    199:                name = sc->sc_dev.dv_xname;
                    200:        else
                    201:                name = "(bha probe)";
                    202:
                    203:        /*
                    204:         * Calculate a reasonable timeout for the command.
                    205:         */
                    206:        switch (opcode) {
                    207:        case BHA_INQUIRE_DEVICES:
                    208:        case BHA_INQUIRE_DEVICES_2:
                    209:                wait = 90 * 20000;
                    210:                break;
                    211:        default:
                    212:                wait = 1 * 20000;
                    213:                break;
                    214:        }
                    215:
                    216:        /*
                    217:         * Wait for the adapter to go idle, unless it's one of
                    218:         * the commands which don't need this
                    219:         */
                    220:        if (opcode != BHA_MBO_INTR_EN) {
                    221:                for (i = 20000; i; i--) {       /* 1 sec? */
                    222:                        sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
                    223:                        if (sts & BHA_STAT_IDLE)
                    224:                                break;
                    225:                        delay(50);
                    226:                }
                    227:                if (!i) {
                    228:                        printf("%s: bha_cmd, host not idle(0x%x)\n",
                    229:                            name, sts);
                    230:                        return (1);
                    231:                }
                    232:        }
                    233:        /*
                    234:         * Now that it is idle, if we expect output, preflush the
                    235:         * queue feeding to us.
                    236:         */
                    237:        if (ocnt) {
                    238:                while ((bus_space_read_1(iot, ioh, BHA_STAT_PORT)) &
                    239:                    BHA_STAT_DF)
                    240:                        bus_space_read_1(iot, ioh, BHA_DATA_PORT);
                    241:        }
                    242:        /*
                    243:         * Output the command and the number of arguments given
                    244:         * for each byte, first check the port is empty.
                    245:         */
                    246:        while (icnt--) {
                    247:                for (i = wait; i; i--) {
                    248:                        sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
                    249:                        if (!(sts & BHA_STAT_CDF))
                    250:                                break;
                    251:                        delay(50);
                    252:                }
                    253:                if (!i) {
                    254:                        if (opcode != BHA_INQUIRE_REVISION)
                    255:                                printf("%s: bha_cmd, cmd/data port full\n",
                    256:                                    name);
                    257:                        goto bad;
                    258:                }
                    259:                bus_space_write_1(iot, ioh, BHA_CMD_PORT, *ibuf++);
                    260:        }
                    261:        /*
                    262:         * If we expect input, loop that many times, each time,
                    263:         * looking for the data register to have valid data
                    264:         */
                    265:        while (ocnt--) {
                    266:                for (i = wait; i; i--) {
                    267:                        sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
                    268:                        if (sts & BHA_STAT_DF)
                    269:                                break;
                    270:                        delay(50);
                    271:                }
                    272:                if (!i) {
                    273:                        if (opcode != BHA_INQUIRE_REVISION)
                    274:                                printf("%s: bha_cmd, cmd/data port empty %d\n",
                    275:                                    name, ocnt);
                    276:                        goto bad;
                    277:                }
                    278:                *obuf++ = bus_space_read_1(iot, ioh, BHA_DATA_PORT);
                    279:        }
                    280:        /*
                    281:         * Wait for the board to report a finished instruction.
                    282:         * We may get an extra interrupt for the HACC signal, but this is
                    283:         * unimportant.
                    284:         */
                    285:        if (opcode != BHA_MBO_INTR_EN && opcode != BHA_MODIFY_IOPORT) {
                    286:                for (i = 20000; i; i--) {       /* 1 sec? */
                    287:                        sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT);
                    288:                        /* XXX Need to save this in the interrupt handler? */
                    289:                        if (sts & BHA_INTR_HACC)
                    290:                                break;
                    291:                        delay(50);
                    292:                }
                    293:                if (!i) {
                    294:                        printf("%s: bha_cmd, host not finished(0x%x)\n",
                    295:                            name, sts);
                    296:                        return (1);
                    297:                }
                    298:        }
                    299:        bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
                    300:        return (0);
                    301:
                    302: bad:
                    303:        bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_SRST);
                    304:        return (1);
                    305: }
                    306:
                    307: /*
                    308:  * Attach all the sub-devices we can find
                    309:  */
                    310: void
                    311: bha_attach(sc, bpd)
                    312:        struct bha_softc *sc;
                    313:        struct bha_probe_data *bpd;
                    314: {
                    315:        struct scsibus_attach_args saa;
                    316:        int s;
                    317:
                    318:        /*
                    319:         * Fill in the adapter.
                    320:         */
                    321:        sc->sc_adapter.scsi_cmd = bha_scsi_cmd;
                    322:        sc->sc_adapter.scsi_minphys = bhaminphys;
                    323:
                    324:        /*
                    325:         * fill in the prototype scsi_link.
                    326:         */
                    327:        sc->sc_link.adapter_softc = sc;
                    328:        sc->sc_link.adapter_target = bpd->sc_scsi_dev;
                    329:        sc->sc_link.adapter = &sc->sc_adapter;
                    330:        sc->sc_link.device = &bha_dev;
                    331:        sc->sc_link.openings = 4;
                    332:
                    333:        TAILQ_INIT(&sc->sc_free_ccb);
                    334:        TAILQ_INIT(&sc->sc_waiting_ccb);
                    335:        LIST_INIT(&sc->sc_queue);
                    336:
                    337:        s = splbio();
                    338:        bha_inquire_setup_information(sc);
                    339:
                    340:        printf("%s: model BT-%s, firmware %s\n", sc->sc_dev.dv_xname,
                    341:            sc->sc_model, sc->sc_firmware);
                    342:
                    343:        if (bha_init(sc) != 0) {
                    344:                /* Error during initialization! */
                    345:                splx(s);
                    346:                return;
                    347:        }
                    348:
                    349:        splx(s);
                    350:
                    351:        bzero(&saa, sizeof(saa));
                    352:        saa.saa_sc_link = &sc->sc_link;
                    353:
                    354:        /*
                    355:         * ask the adapter what subunits are present
                    356:         */
                    357:        config_found(&sc->sc_dev, &saa, scsiprint);
                    358: }
                    359:
                    360: integrate void
                    361: bha_finish_ccbs(sc)
                    362:        struct bha_softc *sc;
                    363: {
                    364:        struct bha_mbx_in *wmbi;
                    365:        struct bha_ccb *ccb;
                    366:        int i;
                    367:
                    368:        wmbi = wmbx->tmbi;
                    369:
                    370:        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
                    371:            0, sc->sc_dmamap_control->dm_mapsize,
                    372:            BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                    373:
                    374:        if (wmbi->comp_stat == BHA_MBI_FREE) {
                    375:                for (i = 0; i < BHA_MBX_SIZE; i++) {
                    376:                        if (wmbi->comp_stat != BHA_MBI_FREE) {
                    377:                                printf("%s: mbi not in round-robin order\n",
                    378:                                    sc->sc_dev.dv_xname);
                    379:                                goto AGAIN;
                    380:                        }
                    381:                        bha_nextmbx(wmbi, wmbx, mbi);
                    382:                        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
                    383:                            0, sc->sc_dmamap_control->dm_mapsize,
                    384:                            BUS_DMASYNC_POSTREAD);
                    385:                }
                    386: #ifdef BHADIAGnot
                    387:                printf("%s: mbi interrupt with no full mailboxes\n",
                    388:                    sc->sc_dev.dv_xname);
                    389: #endif
                    390:                return;
                    391:        }
                    392:
                    393: AGAIN:
                    394:        do {
                    395:                ccb = bha_ccb_phys_kv(sc, phystol(wmbi->ccb_addr));
                    396:                if (!ccb) {
                    397:                        printf("%s: bad mbi ccb pointer; skipping\n",
                    398:                            sc->sc_dev.dv_xname);
                    399:                        goto next;
                    400:                }
                    401:
                    402:                bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
                    403:                    0, sc->sc_dmamap_control->dm_mapsize,
                    404:                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                    405:
                    406: #ifdef BHADEBUG
                    407:                if (bha_debug) {
                    408:                        u_int8_t *cp = ccb->scsi_cmd.bytes;
                    409:                        printf("op=%x %x %x %x %x %x\n",
                    410:                                ccb->scsi_cmd.opcode,
                    411:                                cp[0], cp[1], cp[2], cp[3], cp[4]);
                    412:                        printf("stat %x for mbi addr = 0x%08x, ",
                    413:                                wmbi->comp_stat, wmbi);
                    414:                        printf("ccb addr = 0x%x\n", ccb);
                    415:                }
                    416: #endif /* BHADEBUG */
                    417:
                    418:                switch (wmbi->comp_stat) {
                    419:                case BHA_MBI_OK:
                    420:                case BHA_MBI_ERROR:
                    421:                        if ((ccb->flags & CCB_ABORT) != 0) {
                    422:                                /*
                    423:                                 * If we already started an abort, wait for it
                    424:                                 * to complete before clearing the CCB.  We
                    425:                                 * could instead just clear CCB_SENDING, but
                    426:                                 * what if the mailbox was already received?
                    427:                                 * The worst that happens here is that we clear
                    428:                                 * the CCB a bit later than we need to.  BFD.
                    429:                                 */
                    430:                                goto next;
                    431:                        }
                    432:                        break;
                    433:
                    434:                case BHA_MBI_ABORT:
                    435:                case BHA_MBI_UNKNOWN:
                    436:                        /*
                    437:                         * Even if the CCB wasn't found, we clear it anyway.
                    438:                         * See preceding comment.
                    439:                         */
                    440:                        break;
                    441:
                    442:                default:
                    443:                        printf("%s: bad mbi status %02x; skipping\n",
                    444:                            sc->sc_dev.dv_xname, wmbi->comp_stat);
                    445:                        goto next;
                    446:                }
                    447:
                    448:                timeout_del(&ccb->xs->stimeout);
                    449:                bha_done(sc, ccb);
                    450:
                    451:        next:
                    452:                wmbi->comp_stat = BHA_MBI_FREE;
                    453:                bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
                    454:                    0, sc->sc_dmamap_control->dm_mapsize,
                    455:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                    456:                bha_nextmbx(wmbi, wmbx, mbi);
                    457:                bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
                    458:                    0, sc->sc_dmamap_control->dm_mapsize,
                    459:                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                    460:        } while (wmbi->comp_stat != BHA_MBI_FREE);
                    461:
                    462:        wmbx->tmbi = wmbi;
                    463: }
                    464:
                    465: /*
                    466:  * Catch an interrupt from the adaptor
                    467:  */
                    468: int
                    469: bha_intr(arg)
                    470:        void *arg;
                    471: {
                    472:        struct bha_softc *sc = arg;
                    473:        bus_space_tag_t iot = sc->sc_iot;
                    474:        bus_space_handle_t ioh = sc->sc_ioh;
                    475:        u_char sts;
                    476:
                    477: #ifdef BHADEBUG
                    478:        printf("%s: bha_intr ", sc->sc_dev.dv_xname);
                    479: #endif /* BHADEBUG */
                    480:
                    481:        /*
                    482:         * First acknowledge the interrupt, Then if it's not telling about
                    483:         * a completed operation just return.
                    484:         */
                    485:        sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT);
                    486:        if ((sts & BHA_INTR_ANYINTR) == 0)
                    487:                return (0);
                    488:        bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
                    489:
                    490: #ifdef BHADIAG
                    491:        /* Make sure we clear CCB_SENDING before finishing a CCB. */
                    492:        bha_collect_mbo(sc);
                    493: #endif
                    494:
                    495:        /* Mail box out empty? */
                    496:        if (sts & BHA_INTR_MBOA) {
                    497:                struct bha_toggle toggle;
                    498:
                    499:                toggle.cmd.opcode = BHA_MBO_INTR_EN;
                    500:                toggle.cmd.enable = 0;
                    501:                bha_cmd(iot, ioh, sc,
                    502:                    sizeof(toggle.cmd), (u_char *)&toggle.cmd,
                    503:                    0, (u_char *)0);
                    504:                bha_start_ccbs(sc);
                    505:        }
                    506:
                    507:        /* Mail box in full? */
                    508:        if (sts & BHA_INTR_MBIF)
                    509:                bha_finish_ccbs(sc);
                    510:
                    511:        return (1);
                    512: }
                    513:
                    514: integrate void
                    515: bha_reset_ccb(sc, ccb)
                    516:        struct bha_softc *sc;
                    517:        struct bha_ccb *ccb;
                    518: {
                    519:
                    520:        ccb->flags = 0;
                    521: }
                    522:
                    523: /*
                    524:  * A ccb is put onto the free list.
                    525:  */
                    526: void
                    527: bha_free_ccb(sc, ccb)
                    528:        struct bha_softc *sc;
                    529:        struct bha_ccb *ccb;
                    530: {
                    531:        int s;
                    532:
                    533:        s = splbio();
                    534:
                    535:        bha_reset_ccb(sc, ccb);
                    536:        TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
                    537:
                    538:        /*
                    539:         * If there were none, wake anybody waiting for one to come free,
                    540:         * starting with queued entries.
                    541:         */
                    542:        if (TAILQ_NEXT(ccb, chain) == NULL)
                    543:                wakeup(&sc->sc_free_ccb);
                    544:
                    545:        splx(s);
                    546: }
                    547:
                    548: integrate int
                    549: bha_init_ccb(sc, ccb)
                    550:        struct bha_softc *sc;
                    551:        struct bha_ccb *ccb;
                    552: {
                    553:        bus_dma_tag_t dmat = sc->sc_dmat;
                    554:        int hashnum, error;
                    555:
                    556:        /*
                    557:         * Create the DMA map for this CCB.
                    558:         */
                    559:        error = bus_dmamap_create(dmat, BHA_MAXXFER, BHA_NSEG, BHA_MAXXFER,
                    560:            0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW | sc->sc_dmaflags,
                    561:            &ccb->dmamap_xfer);
                    562:        if (error) {
                    563:                printf("%s: unable to create ccb DMA map, error = %d\n",
                    564:                    sc->sc_dev.dv_xname, error);
                    565:                return (error);
                    566:        }
                    567:
                    568:        /*
                    569:         * put in the phystokv hash table
                    570:         * Never gets taken out.
                    571:         */
                    572:        ccb->hashkey = sc->sc_dmamap_control->dm_segs[0].ds_addr +
                    573:            BHA_CCB_OFF(ccb);
                    574:        hashnum = CCB_HASH(ccb->hashkey);
                    575:        ccb->nexthash = sc->sc_ccbhash[hashnum];
                    576:        sc->sc_ccbhash[hashnum] = ccb;
                    577:        bha_reset_ccb(sc, ccb);
                    578:        return (0);
                    579: }
                    580:
                    581: /*
                    582:  * Create a set of ccbs and add them to the free list.  Called once
                    583:  * by bha_init().  We return the number of CCBs successfully created.
                    584:  */
                    585: int
                    586: bha_create_ccbs(sc, ccbstore, count)
                    587:        struct bha_softc *sc;
                    588:        struct bha_ccb *ccbstore;
                    589:        int count;
                    590: {
                    591:        struct bha_ccb *ccb;
                    592:        int i, error;
                    593:
                    594:        bzero(ccbstore, sizeof(struct bha_ccb) * count);
                    595:        for (i = 0; i < count; i++) {
                    596:                ccb = &ccbstore[i];
                    597:                if ((error = bha_init_ccb(sc, ccb)) != 0) {
                    598:                        printf("%s: unable to initialize ccb, error = %d\n",
                    599:                            sc->sc_dev.dv_xname, error);
                    600:                        goto out;
                    601:                }
                    602:                TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
                    603:        }
                    604:  out:
                    605:        return (i);
                    606: }
                    607:
                    608: /*
                    609:  * Get a free ccb
                    610:  *
                    611:  * If there are none, see if we can allocate a new one.  If so, put it in
                    612:  * the hash table too otherwise either return an error or sleep.
                    613:  */
                    614: struct bha_ccb *
                    615: bha_get_ccb(sc, flags)
                    616:        struct bha_softc *sc;
                    617:        int flags;
                    618: {
                    619:        struct bha_ccb *ccb;
                    620:        int s;
                    621:
                    622:        s = splbio();
                    623:
                    624:        /*
                    625:         * If we can and have to, sleep waiting for one to come free
                    626:         * but only if we can't allocate a new one.
                    627:         */
                    628:        for (;;) {
                    629:                ccb = TAILQ_FIRST(&sc->sc_free_ccb);
                    630:                if (ccb) {
                    631:                        TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
                    632:                        break;
                    633:                }
                    634:                if ((flags & SCSI_NOSLEEP) != 0)
                    635:                        goto out;
                    636:                tsleep(&sc->sc_free_ccb, PRIBIO, "bhaccb", 0);
                    637:        }
                    638:
                    639:        ccb->flags |= CCB_ALLOC;
                    640:
                    641: out:
                    642:        splx(s);
                    643:        return (ccb);
                    644: }
                    645:
                    646: /*
                    647:  * Given a physical address, find the ccb that it corresponds to.
                    648:  */
                    649: struct bha_ccb *
                    650: bha_ccb_phys_kv(sc, ccb_phys)
                    651:        struct bha_softc *sc;
                    652:        u_long ccb_phys;
                    653: {
                    654:        int hashnum = CCB_HASH(ccb_phys);
                    655:        struct bha_ccb *ccb = sc->sc_ccbhash[hashnum];
                    656:
                    657:        while (ccb) {
                    658:                if (ccb->hashkey == ccb_phys)
                    659:                        break;
                    660:                ccb = ccb->nexthash;
                    661:        }
                    662:        return (ccb);
                    663: }
                    664:
                    665: /*
                    666:  * Queue a CCB to be sent to the controller, and send it if possible.
                    667:  */
                    668: void
                    669: bha_queue_ccb(sc, ccb)
                    670:        struct bha_softc *sc;
                    671:        struct bha_ccb *ccb;
                    672: {
                    673:
                    674:        timeout_set(&ccb->xs->stimeout, bha_timeout, ccb);
                    675:        TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
                    676:        bha_start_ccbs(sc);
                    677: }
                    678:
                    679: /*
                    680:  * Garbage collect mailboxes that are no longer in use.
                    681:  */
                    682: void
                    683: bha_collect_mbo(sc)
                    684:        struct bha_softc *sc;
                    685: {
                    686:        struct bha_mbx_out *wmbo;       /* Mail Box Out pointer */
                    687: #ifdef BHADIAG
                    688:        struct bha_ccb *ccb;
                    689: #endif
                    690:
                    691:        wmbo = wmbx->cmbo;
                    692:
                    693:        while (sc->sc_mbofull > 0) {
                    694:                bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
                    695:                    0, sc->sc_dmamap_control->dm_mapsize,
                    696:                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                    697:                if (wmbo->cmd != BHA_MBO_FREE)
                    698:                        break;
                    699:
                    700: #ifdef BHADIAG
                    701:                ccb = bha_ccb_phys_kv(sc, phystol(wmbo->ccb_addr));
                    702:                ccb->flags &= ~CCB_SENDING;
                    703: #endif
                    704:
                    705:                --sc->sc_mbofull;
                    706:                bha_nextmbx(wmbo, wmbx, mbo);
                    707:        }
                    708:
                    709:        wmbx->cmbo = wmbo;
                    710: }
                    711:
                    712: /*
                    713:  * Send as many CCBs as we have empty mailboxes for.
                    714:  */
                    715: void
                    716: bha_start_ccbs(sc)
                    717:        struct bha_softc *sc;
                    718: {
                    719:        bus_space_tag_t iot = sc->sc_iot;
                    720:        bus_space_handle_t ioh = sc->sc_ioh;
                    721:        struct bha_mbx_out *wmbo;       /* Mail Box Out pointer */
                    722:        struct bha_ccb *ccb;
                    723:        struct scsi_xfer *xs;
                    724:
                    725:        wmbo = wmbx->tmbo;
                    726:
                    727:        while ((ccb = TAILQ_FIRST(&sc->sc_waiting_ccb)) != NULL) {
                    728:
                    729:                xs = ccb->xs;
                    730:                if (sc->sc_mbofull >= BHA_MBX_SIZE) {
                    731:                        bha_collect_mbo(sc);
                    732:                        if (sc->sc_mbofull >= BHA_MBX_SIZE) {
                    733:                                struct bha_toggle toggle;
                    734:
                    735:                                toggle.cmd.opcode = BHA_MBO_INTR_EN;
                    736:                                toggle.cmd.enable = 1;
                    737:                                bha_cmd(iot, ioh, sc,
                    738:                                    sizeof(toggle.cmd), (u_char *)&toggle.cmd,
                    739:                                    0, (u_char *)0);
                    740:                                break;
                    741:                        }
                    742:                }
                    743:
                    744:                TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
                    745: #ifdef BHADIAG
                    746:                ccb->flags |= CCB_SENDING;
                    747: #endif
                    748:
                    749:                /* Link ccb to mbo. */
                    750:                ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
                    751:                    BHA_CCB_OFF(ccb), wmbo->ccb_addr);
                    752:                if (ccb->flags & CCB_ABORT)
                    753:                        wmbo->cmd = BHA_MBO_ABORT;
                    754:                else
                    755:                        wmbo->cmd = BHA_MBO_START;
                    756:
                    757:                bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
                    758:                    0, sc->sc_dmamap_control->dm_mapsize,
                    759:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                    760:
                    761:                /* Tell the card to poll immediately. */
                    762:                bus_space_write_1(iot, ioh, BHA_CMD_PORT, BHA_START_SCSI);
                    763:
                    764:                if ((xs->flags & SCSI_POLL) == 0)
                    765:                        timeout_add(&xs->stimeout, (ccb->timeout * hz) / 1000);
                    766:
                    767:                ++sc->sc_mbofull;
                    768:                bha_nextmbx(wmbo, wmbx, mbo);
                    769:        }
                    770:
                    771:        wmbx->tmbo = wmbo;
                    772: }
                    773:
                    774: /*
                    775:  * We have a ccb which has been processed by the
                    776:  * adaptor, now we look to see how the operation
                    777:  * went. Wake up the owner if waiting
                    778:  */
                    779: void
                    780: bha_done(sc, ccb)
                    781:        struct bha_softc *sc;
                    782:        struct bha_ccb *ccb;
                    783: {
                    784:        bus_dma_tag_t dmat = sc->sc_dmat;
                    785:        struct scsi_sense_data *s1, *s2;
                    786:        struct scsi_xfer *xs = ccb->xs;
                    787:
                    788:        SC_DEBUG(xs->sc_link, SDEV_DB2, ("bha_done\n"));
                    789:
                    790:        /*
                    791:         * If we were a data transfer, unload the map that described
                    792:         * the data buffer.
                    793:         */
                    794:        if (xs->datalen) {
                    795:                bus_dmamap_sync(dmat, ccb->dmamap_xfer,
                    796:                    0, ccb->dmamap_xfer->dm_mapsize,
                    797:                    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
                    798:                    BUS_DMASYNC_POSTWRITE);
                    799:                bus_dmamap_unload(dmat, ccb->dmamap_xfer);
                    800:        }
                    801:
                    802:        /*
                    803:         * Otherwise, put the results of the operation
                    804:         * into the xfer and call whoever started it
                    805:         */
                    806: #ifdef BHADIAG
                    807:        if (ccb->flags & CCB_SENDING) {
                    808:                printf("%s: exiting ccb still in transit!\n",
                    809:                    sc->sc_dev.dv_xname);
                    810:                Debugger();
                    811:                return;
                    812:        }
                    813: #endif
                    814:        if ((ccb->flags & CCB_ALLOC) == 0) {
                    815:                printf("%s: exiting ccb not allocated!\n",
                    816:                    sc->sc_dev.dv_xname);
                    817:                Debugger();
                    818:                return;
                    819:        }
                    820:        if (xs->error == XS_NOERROR) {
                    821:                if (ccb->host_stat != BHA_OK) {
                    822:                        switch (ccb->host_stat) {
                    823:                        case BHA_SEL_TIMEOUT:   /* No response */
                    824:                                xs->error = XS_SELTIMEOUT;
                    825:                                break;
                    826:                        default:        /* Other scsi protocol messes */
                    827:                                printf("%s: host_stat %x\n",
                    828:                                    sc->sc_dev.dv_xname, ccb->host_stat);
                    829:                                xs->error = XS_DRIVER_STUFFUP;
                    830:                                break;
                    831:                        }
                    832:                } else if (ccb->target_stat != SCSI_OK) {
                    833:                        switch (ccb->target_stat) {
                    834:                        case SCSI_CHECK:
                    835:                                s1 = &ccb->scsi_sense;
                    836:                                s2 = &xs->sense;
                    837:                                *s2 = *s1;
                    838:                                xs->error = XS_SENSE;
                    839:                                break;
                    840:                        case SCSI_BUSY:
                    841:                                xs->error = XS_BUSY;
                    842:                                break;
                    843:                        default:
                    844:                                printf("%s: target_stat %x\n",
                    845:                                    sc->sc_dev.dv_xname, ccb->target_stat);
                    846:                                xs->error = XS_DRIVER_STUFFUP;
                    847:                                break;
                    848:                        }
                    849:                } else
                    850:                        xs->resid = 0;
                    851:        }
                    852:        bha_free_ccb(sc, ccb);
                    853:        xs->flags |= ITSDONE;
                    854:        scsi_done(xs);
                    855:
                    856:        /*
                    857:         * If there are queue entries in the software queue, try to
                    858:         * run the first one.  We should be more or less guaranteed
                    859:         * to succeed, since we just freed a CCB.
                    860:         *
                    861:         * NOTE: bha_scsi_cmd() relies on our calling it with
                    862:         * the first entry in the queue.
                    863:         */
                    864:        if ((xs = LIST_FIRST(&sc->sc_queue)) != NULL)
                    865:                (void) bha_scsi_cmd(xs);
                    866: }
                    867:
                    868: /*
                    869:  * Find the board and find its irq/drq
                    870:  */
                    871: int
                    872: bha_find(iot, ioh, sc)
                    873:        bus_space_tag_t iot;
                    874:        bus_space_handle_t ioh;
                    875:        struct bha_probe_data *sc;
                    876: {
                    877:        int i, iswide;
                    878:        u_char sts;
                    879:        struct bha_extended_inquire inquire;
                    880:        struct bha_config config;
                    881:        int irq, drq;
                    882:
                    883:        /* Check something is at the ports we need to access */
                    884:        sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
                    885:        if (sts == 0xFF) {
                    886: #ifdef BHADEBUG
                    887:                if (bha_debug)
                    888:                        printf("bha_find: Not present\n");
                    889: #endif /* BHADEBUG */
                    890:                return (0);
                    891:        }
                    892:
                    893:        /*
                    894:         * Reset board, If it doesn't respond, assume
                    895:         * that it's not there.. good for the probe
                    896:         */
                    897:
                    898:        bus_space_write_1(iot, ioh, BHA_CTRL_PORT,
                    899:            BHA_CTRL_HRST | BHA_CTRL_SRST);
                    900:
                    901:        for (i = BHA_RESET_TIMEOUT; i--;) {
                    902:                delay(100);
                    903:                sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
                    904:                if (sts == (BHA_STAT_IDLE | BHA_STAT_INIT))
                    905:                        break;
                    906:        }
                    907:        if (i < 0) {
                    908: #ifdef BHADEBUG
                    909:                if (bha_debug)
                    910:                        printf("bha_find: No answer from board a=%x sts=%b\n",
                    911:                            ioh, sts, BHA_STAT_BITS);
                    912: #endif /* BHADEBUG */
                    913:                return (0);
                    914:        }
                    915:
                    916:        /*
                    917:         * The BusLogic cards implement an Adaptec 1542 (aha)-compatible
                    918:         * interface. The native bha interface is not compatible with
                    919:         * an aha. 1542. We need to ensure that we never match an
                    920:         * Adaptec 1542. We must also avoid sending Adaptec-compatible
                    921:         * commands to a real bha, lest it go into 1542 emulation mode.
                    922:         * (On an indirect bus like ISA, we should always probe for BusLogic
                    923:         * interfaces  before Adaptec interfaces).
                    924:         */
                    925:
                    926:        /*
                    927:         * Make sure we don't match an AHA-1542A or AHA-1542B, by checking
                    928:         * for an extended-geometry register.  The 1542[AB] don't have one.
                    929:         */
                    930:        sts = bus_space_read_1(iot, ioh, BHA_EXTGEOM_PORT);
                    931:        if (sts == 0xFF)
                    932:                return (0);
                    933:
                    934:        /*
                    935:         * Check that we actually know how to use this board.
                    936:         */
                    937:        delay(1000);
                    938:        inquire.cmd.opcode = BHA_INQUIRE_EXTENDED;
                    939:        inquire.cmd.len = sizeof(inquire.reply);
                    940:        i = bha_cmd(iot, ioh, NULL,
                    941:            sizeof(inquire.cmd), (u_char *)&inquire.cmd,
                    942:            sizeof(inquire.reply), (u_char *)&inquire.reply);
                    943:
                    944:        /*
                    945:         * Some 1542Cs (CP, perhaps not CF, may depend on firmware rev)
                    946:         * have the extended-geometry register and also respond to
                    947:         * BHA_INQUIRE_EXTENDED.  Make sure we never  match such cards,
                    948:         * by checking the size of the reply is what a BusLogic card returns.
                    949:         */
                    950:        if (i) {
                    951: #ifdef BHADEBUG
                    952:                printf("bha_find: board returned %d instead of %d to %s\n",
                    953:                       i, sizeof(inquire.reply), "INQUIRE_EXTENDED");
                    954: #endif
                    955:                return (0);
                    956:        }
                    957:
                    958:        /* OK, we know we've found a buslogic adaptor. */
                    959:
                    960:        switch (inquire.reply.bus_type) {
                    961:        case BHA_BUS_TYPE_24BIT:
                    962:        case BHA_BUS_TYPE_32BIT:
                    963:                break;
                    964:        case BHA_BUS_TYPE_MCA:
                    965:                /* We don't grok MicroChannel (yet). */
                    966:                return (0);
                    967:        default:
                    968:                printf("bha_find: illegal bus type %c\n",
                    969:                    inquire.reply.bus_type);
                    970:                return (0);
                    971:        }
                    972:
                    973:        /* Note if we have a wide bus. */
                    974:        iswide = inquire.reply.scsi_flags & BHA_SCSI_WIDE;
                    975:
                    976:        /*
                    977:         * Assume we have a board at this stage setup dma channel from
                    978:         * jumpers and save int level
                    979:         */
                    980:        delay(1000);
                    981:        config.cmd.opcode = BHA_INQUIRE_CONFIG;
                    982:        bha_cmd(iot, ioh, NULL,
                    983:            sizeof(config.cmd), (u_char *)&config.cmd,
                    984:            sizeof(config.reply), (u_char *)&config.reply);
                    985:        switch (config.reply.chan) {
                    986:        case EISADMA:
                    987:                drq = -1;
                    988:                break;
                    989:        case CHAN0:
                    990:                drq = 0;
                    991:                break;
                    992:        case CHAN5:
                    993:                drq = 5;
                    994:                break;
                    995:        case CHAN6:
                    996:                drq = 6;
                    997:                break;
                    998:        case CHAN7:
                    999:                drq = 7;
                   1000:                break;
                   1001:        default:
                   1002:                printf("bha_find: illegal drq setting %x\n",
                   1003:                    config.reply.chan);
                   1004:                return (0);
                   1005:        }
                   1006:
                   1007:        switch (config.reply.intr) {
                   1008:        case INT9:
                   1009:                irq = 9;
                   1010:                break;
                   1011:        case INT10:
                   1012:                irq = 10;
                   1013:                break;
                   1014:        case INT11:
                   1015:                irq = 11;
                   1016:                break;
                   1017:        case INT12:
                   1018:                irq = 12;
                   1019:                break;
                   1020:        case INT14:
                   1021:                irq = 14;
                   1022:                break;
                   1023:        case INT15:
                   1024:                irq = 15;
                   1025:                break;
                   1026:        default:
                   1027:                printf("bha_find: illegal irq setting %x\n",
                   1028:                    config.reply.intr);
                   1029:                return (0);
                   1030:        }
                   1031:
                   1032:        /* if we want to fill in softc, do so now */
                   1033:        if (sc != NULL) {
                   1034:                sc->sc_irq = irq;
                   1035:                sc->sc_drq = drq;
                   1036:                sc->sc_scsi_dev = config.reply.scsi_dev;
                   1037:                sc->sc_iswide = iswide;
                   1038:        }
                   1039:
                   1040:        return (1);
                   1041: }
                   1042:
                   1043:
                   1044: /*
                   1045:  * Disable the ISA-compatibility ioports on PCI bha devices,
                   1046:  * to ensure they're not autoconfigured a second time as an ISA bha.
                   1047:  */
                   1048: int
                   1049: bha_disable_isacompat(sc)
                   1050:        struct bha_softc *sc;
                   1051: {
                   1052:        struct bha_isadisable isa_disable;
                   1053:
                   1054:        isa_disable.cmd.opcode = BHA_MODIFY_IOPORT;
                   1055:        isa_disable.cmd.modifier = BHA_IOMODIFY_DISABLE1;
                   1056:        bha_cmd(sc->sc_iot, sc->sc_ioh, sc,
                   1057:            sizeof(isa_disable.cmd), (u_char *)&isa_disable.cmd,
                   1058:            0, (u_char *)0);
                   1059:        return (0);
                   1060: }
                   1061:
                   1062:
                   1063: /*
                   1064:  * Start the board, ready for normal operation
                   1065:  */
                   1066: int
                   1067: bha_init(sc)
                   1068:        struct bha_softc *sc;
                   1069: {
                   1070:        bus_space_tag_t iot = sc->sc_iot;
                   1071:        bus_space_handle_t ioh = sc->sc_ioh;
                   1072:        bus_dma_segment_t seg;
                   1073:        struct bha_devices devices;
                   1074:        struct bha_setup setup;
                   1075:        struct bha_mailbox mailbox;
                   1076:        struct bha_period period;
                   1077:        int error, i, j, initial_ccbs, rlen, rseg;
                   1078:
                   1079:        /* Enable round-robin scheme - appeared at firmware rev. 3.31. */
                   1080:        if (strcmp(sc->sc_firmware, "3.31") >= 0) {
                   1081:                struct bha_toggle toggle;
                   1082:
                   1083:                toggle.cmd.opcode = BHA_ROUND_ROBIN;
                   1084:                toggle.cmd.enable = 1;
                   1085:                bha_cmd(iot, ioh, sc,
                   1086:                    sizeof(toggle.cmd), (u_char *)&toggle.cmd,
                   1087:                    0, (u_char *)0);
                   1088:        }
                   1089:
                   1090:        /*
                   1091:         * Inquire installed devices (to force synchronous negotiation).
                   1092:         */
                   1093:
                   1094:        /*
                   1095:         * Poll targets 0 - 7.
                   1096:         */
                   1097:        devices.cmd.opcode = BHA_INQUIRE_DEVICES;
                   1098:        bha_cmd(iot, ioh, sc,
                   1099:            sizeof(devices.cmd), (u_char *)&devices.cmd,
                   1100:            sizeof(devices.reply), (u_char *)&devices.reply);
                   1101:
                   1102:        /* Count installed units. */
                   1103:        initial_ccbs = 0;
                   1104:        for (i = 0; i < 8; i++) {
                   1105:                for (j = 0; j < 8; j++) {
                   1106:                        if (((devices.reply.lun_map[i] >> j) & 1) == 1)
                   1107:                                initial_ccbs++;
                   1108:                }
                   1109:        }
                   1110:
                   1111:        /*
                   1112:         * Poll targets 8 - 15 if we have a wide bus.
                   1113:          */
                   1114:        if (ISWIDE(sc)) {
                   1115:                devices.cmd.opcode = BHA_INQUIRE_DEVICES_2;
                   1116:                bha_cmd(iot, ioh, sc,
                   1117:                    sizeof(devices.cmd), (u_char *)&devices.cmd,
                   1118:                    sizeof(devices.reply), (u_char *)&devices.reply);
                   1119:
                   1120:                for (i = 0; i < 8; i++) {
                   1121:                        for (j = 0; j < 8; j++) {
                   1122:                                if (((devices.reply.lun_map[i] >> j) & 1) == 1)
                   1123:                                        initial_ccbs++;
                   1124:                        }
                   1125:                }
                   1126:        }
                   1127:
                   1128:        initial_ccbs *= sc->sc_link.openings;
                   1129:        if (initial_ccbs > BHA_CCB_MAX)
                   1130:                initial_ccbs = BHA_CCB_MAX;
                   1131:        if (initial_ccbs == 0)  /* yes, this can happen */
                   1132:                initial_ccbs = sc->sc_link.openings;
                   1133:
                   1134:        /* Obtain setup information from. */
                   1135:        rlen = sizeof(setup.reply) +
                   1136:            (ISWIDE(sc) ? sizeof(setup.reply_w) : 0);
                   1137:        setup.cmd.opcode = BHA_INQUIRE_SETUP;
                   1138:        setup.cmd.len = rlen;
                   1139:        bha_cmd(iot, ioh, sc,
                   1140:            sizeof(setup.cmd), (u_char *)&setup.cmd,
                   1141:            rlen, (u_char *)&setup.reply);
                   1142:
                   1143:        printf("%s: %s, %s\n", sc->sc_dev.dv_xname,
                   1144:            setup.reply.sync_neg ? "sync" : "async",
                   1145:            setup.reply.parity ? "parity" : "no parity");
                   1146:
                   1147:        for (i = 0; i < 8; i++)
                   1148:                period.reply.period[i] = setup.reply.sync[i].period * 5 + 20;
                   1149:        if (ISWIDE(sc)) {
                   1150:                for (i = 0; i < 8; i++)
                   1151:                        period.reply_w.period[i] =
                   1152:                            setup.reply_w.sync_high[i].period * 5 + 20;
                   1153:        }
                   1154:
                   1155:        if (sc->sc_firmware[0] >= '3') {
                   1156:                rlen = sizeof(period.reply) +
                   1157:                    (ISWIDE(sc) ? sizeof(period.reply_w) : 0);
                   1158:                period.cmd.opcode = BHA_INQUIRE_PERIOD;
                   1159:                period.cmd.len = sizeof(period.reply);
                   1160:                bha_cmd(iot, ioh, sc,
                   1161:                    sizeof(period.cmd), (u_char *)&period.cmd,
                   1162:                    rlen, (u_char *)&period.reply);
                   1163:        }
                   1164:
                   1165:        for (i = 0; i < 8; i++) {
                   1166:                if (!setup.reply.sync[i].valid ||
                   1167:                    (!setup.reply.sync[i].offset &&
                   1168:                     !setup.reply.sync[i].period))
                   1169:                        continue;
                   1170:                printf("%s targ %d: sync, offset %d, period %dnsec\n",
                   1171:                    sc->sc_dev.dv_xname, i,
                   1172:                    setup.reply.sync[i].offset, period.reply.period[i] * 10);
                   1173:        }
                   1174:        if (ISWIDE(sc)) {
                   1175:                for (i = 0; i < 8; i++) {
                   1176:                        if (!setup.reply_w.sync_high[i].valid ||
                   1177:                            (!setup.reply_w.sync_high[i].offset &&
                   1178:                             !setup.reply_w.sync_high[i].period))
                   1179:                                continue;
                   1180:                        printf("%s targ %d: sync, offset %d, period %dnsec\n",
                   1181:                            sc->sc_dev.dv_xname, i + 8,
                   1182:                            setup.reply_w.sync_high[i].offset,
                   1183:                            period.reply_w.period[i] * 10);
                   1184:                }
                   1185:        }
                   1186:
                   1187:        /*
                   1188:         * Allocate the mailbox and control blocks.
                   1189:         */
                   1190:        if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct bha_control),
                   1191:            NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
                   1192:                printf("%s: unable to allocate control structures, "
                   1193:                    "error = %d\n", sc->sc_dev.dv_xname, error);
                   1194:                return (error);
                   1195:        }
                   1196:        if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
                   1197:            sizeof(struct bha_control), (caddr_t *)&sc->sc_control,
                   1198:            BUS_DMA_NOWAIT)) != 0) {
                   1199:                printf("%s: unable to map control structures, error = %d\n",
                   1200:                    sc->sc_dev.dv_xname, error);
                   1201:                return (error);
                   1202:        }
                   1203:
                   1204:        /*
                   1205:         * Create and load the DMA map used for the mailbox and
                   1206:         * control blocks.
                   1207:         */
                   1208:        if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct bha_control),
                   1209:            1, sizeof(struct bha_control), 0, BUS_DMA_NOWAIT | sc->sc_dmaflags,
                   1210:            &sc->sc_dmamap_control)) != 0) {
                   1211:                printf("%s: unable to create control DMA map, error = %d\n",
                   1212:                    sc->sc_dev.dv_xname, error);
                   1213:                return (error);
                   1214:        }
                   1215:        if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
                   1216:            sc->sc_control, sizeof(struct bha_control), NULL,
                   1217:            BUS_DMA_NOWAIT)) != 0) {
                   1218:                printf("%s: unable to load control DMA map, error = %d\n",
                   1219:                    sc->sc_dev.dv_xname, error);
                   1220:                return (error);
                   1221:        }
                   1222:
                   1223:        /*
                   1224:         * Initialize the control blocks.
                   1225:         */
                   1226:        i = bha_create_ccbs(sc, sc->sc_control->bc_ccbs, initial_ccbs);
                   1227:        if (i == 0) {
                   1228:                printf("%s: unable to create control blocks\n",
                   1229:                    sc->sc_dev.dv_xname);
                   1230:                return (ENOMEM);
                   1231:        } else if (i != initial_ccbs) {
                   1232:                printf("%s: WARNING: only %d of %d control blocks created\n",
                   1233:                    sc->sc_dev.dv_xname, i, initial_ccbs);
                   1234:        }
                   1235:
                   1236:        /*
                   1237:         * Set up initial mail box for round-robin operation.
                   1238:         */
                   1239:        for (i = 0; i < BHA_MBX_SIZE; i++) {
                   1240:                wmbx->mbo[i].cmd = BHA_MBO_FREE;
                   1241:                bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
                   1242:                    0, sc->sc_dmamap_control->dm_mapsize,
                   1243:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   1244:                wmbx->mbi[i].comp_stat = BHA_MBI_FREE;
                   1245:                bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
                   1246:                    0, sc->sc_dmamap_control->dm_mapsize,
                   1247:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   1248:        }
                   1249:        wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
                   1250:        wmbx->tmbi = &wmbx->mbi[0];
                   1251:        sc->sc_mbofull = 0;
                   1252:
                   1253:        /* Initialize mail box. */
                   1254:        mailbox.cmd.opcode = BHA_MBX_INIT_EXTENDED;
                   1255:        mailbox.cmd.nmbx = BHA_MBX_SIZE;
                   1256:        ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
                   1257:            offsetof(struct bha_control, bc_mbx), mailbox.cmd.addr);
                   1258:        bha_cmd(iot, ioh, sc,
                   1259:            sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
                   1260:            0, (u_char *)0);
                   1261:        return (0);
                   1262: }
                   1263:
                   1264: void
                   1265: bha_inquire_setup_information(sc)
                   1266:        struct bha_softc *sc;
                   1267: {
                   1268:        bus_space_tag_t iot = sc->sc_iot;
                   1269:        bus_space_handle_t ioh = sc->sc_ioh;
                   1270:        struct bha_model model;
                   1271:        struct bha_revision revision;
                   1272:        struct bha_digit digit;
                   1273:        char *p;
                   1274:
                   1275:        /*
                   1276:         * Get the firmware revision.
                   1277:         */
                   1278:        p = sc->sc_firmware;
                   1279:        revision.cmd.opcode = BHA_INQUIRE_REVISION;
                   1280:        bha_cmd(iot, ioh, sc,
                   1281:            sizeof(revision.cmd), (u_char *)&revision.cmd,
                   1282:            sizeof(revision.reply), (u_char *)&revision.reply);
                   1283:        *p++ = revision.reply.firm_revision;
                   1284:        *p++ = '.';
                   1285:        *p++ = revision.reply.firm_version;
                   1286:        digit.cmd.opcode = BHA_INQUIRE_REVISION_3;
                   1287:        bha_cmd(iot, ioh, sc,
                   1288:            sizeof(digit.cmd), (u_char *)&digit.cmd,
                   1289:            sizeof(digit.reply), (u_char *)&digit.reply);
                   1290:        *p++ = digit.reply.digit;
                   1291:        if (revision.reply.firm_revision >= '3' ||
                   1292:            (revision.reply.firm_revision == '3' &&
                   1293:             revision.reply.firm_version >= '3')) {
                   1294:                digit.cmd.opcode = BHA_INQUIRE_REVISION_4;
                   1295:                bha_cmd(iot, ioh, sc,
                   1296:                    sizeof(digit.cmd), (u_char *)&digit.cmd,
                   1297:                    sizeof(digit.reply), (u_char *)&digit.reply);
                   1298:                *p++ = digit.reply.digit;
                   1299:        }
                   1300:        while (p > sc->sc_firmware && (p[-1] == ' ' || p[-1] == '\0'))
                   1301:                p--;
                   1302:        *p = '\0';
                   1303:
                   1304:        /*
                   1305:         * Get the model number.
                   1306:         */
                   1307:        if (revision.reply.firm_revision >= '3') {
                   1308:                p = sc->sc_model;
                   1309:                model.cmd.opcode = BHA_INQUIRE_MODEL;
                   1310:                model.cmd.len = sizeof(model.reply);
                   1311:                bha_cmd(iot, ioh, sc,
                   1312:                    sizeof(model.cmd), (u_char *)&model.cmd,
                   1313:                    sizeof(model.reply), (u_char *)&model.reply);
                   1314:                *p++ = model.reply.id[0];
                   1315:                *p++ = model.reply.id[1];
                   1316:                *p++ = model.reply.id[2];
                   1317:                *p++ = model.reply.id[3];
                   1318:                while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
                   1319:                        p--;
                   1320:                *p++ = model.reply.version[0];
                   1321:                *p++ = model.reply.version[1];
                   1322:                while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
                   1323:                        p--;
                   1324:                *p = '\0';
                   1325:        } else
                   1326:                strlcpy(sc->sc_model, "542B", sizeof sc->sc_model);
                   1327: }
                   1328:
                   1329: void
                   1330: bhaminphys(bp)
                   1331:        struct buf *bp;
                   1332: {
                   1333:
                   1334:        if (bp->b_bcount > BHA_MAXXFER)
                   1335:                bp->b_bcount = BHA_MAXXFER;
                   1336:        minphys(bp);
                   1337: }
                   1338:
                   1339: /*
                   1340:  * start a scsi operation given the command and the data address.  Also needs
                   1341:  * the unit, target and lu.
                   1342:  */
                   1343: int
                   1344: bha_scsi_cmd(xs)
                   1345:        struct scsi_xfer *xs;
                   1346: {
                   1347:        struct scsi_link *sc_link = xs->sc_link;
                   1348:        struct bha_softc *sc = sc_link->adapter_softc;
                   1349:        bus_dma_tag_t dmat = sc->sc_dmat;
                   1350:        struct bha_ccb *ccb;
                   1351:        int error, seg, flags, s;
                   1352:        int fromqueue = 0, dontqueue = 0;
                   1353:
                   1354:        SC_DEBUG(sc_link, SDEV_DB2, ("bha_scsi_cmd\n"));
                   1355:
                   1356:        s = splbio();           /* protect the queue */
                   1357:
                   1358:        /*
                   1359:         * If we're running the queue from bha_done(), we've been
                   1360:         * called with the first queue entry as our argument.
                   1361:         */
                   1362:        if (xs == LIST_FIRST(&sc->sc_queue)) {
                   1363:                xs = bha_dequeue(sc);
                   1364:                fromqueue = 1;
                   1365:                goto get_ccb;
                   1366:        }
                   1367:
                   1368:        /* Polled requests can't be queued for later. */
                   1369:        dontqueue = xs->flags & SCSI_POLL;
                   1370:
                   1371:        /*
                   1372:         * If there are jobs in the queue, run them first.
                   1373:         */
                   1374:        if (!LIST_EMPTY(&sc->sc_queue)) {
                   1375:                /*
                   1376:                 * If we can't queue, we have to abort, since
                   1377:                 * we have to preserve order.
                   1378:                 */
                   1379:                if (dontqueue) {
                   1380:                        splx(s);
                   1381:                        return (TRY_AGAIN_LATER);
                   1382:                }
                   1383:
                   1384:                /*
                   1385:                 * Swap with the first queue entry.
                   1386:                 */
                   1387:                bha_enqueue(sc, xs, 0);
                   1388:                xs = bha_dequeue(sc);
                   1389:                fromqueue = 1;
                   1390:        }
                   1391:
                   1392:  get_ccb:
                   1393:        /*
                   1394:         * get a ccb to use. If the transfer
                   1395:         * is from a buf (possibly from interrupt time)
                   1396:         * then we can't allow it to sleep
                   1397:         */
                   1398:        flags = xs->flags;
                   1399:        if ((ccb = bha_get_ccb(sc, flags)) == NULL) {
                   1400:                /*
                   1401:                 * If we can't queue, we lose.
                   1402:                 */
                   1403:                if (dontqueue) {
                   1404:                        splx(s);
                   1405:                        return (TRY_AGAIN_LATER);
                   1406:                }
                   1407:
                   1408:                /*
                   1409:                 * Stuff ourselves into the queue, in front
                   1410:                 * if we came off in the first place.
                   1411:                 */
                   1412:                bha_enqueue(sc, xs, fromqueue);
                   1413:                splx(s);
                   1414:                return (SUCCESSFULLY_QUEUED);
                   1415:        }
                   1416:
                   1417:        splx(s);                /* done playing with the queue */
                   1418:
                   1419:        ccb->xs = xs;
                   1420:        ccb->timeout = xs->timeout;
                   1421:
                   1422:        /*
                   1423:         * Put all the arguments for the xfer in the ccb
                   1424:         */
                   1425:        if (flags & SCSI_RESET) {
                   1426:                ccb->opcode = BHA_RESET_CCB;
                   1427:                ccb->scsi_cmd_length = 0;
                   1428:        } else {
                   1429:                /* can't use S/G if zero length */
                   1430:                ccb->opcode = (xs->datalen ? BHA_INIT_SCAT_GATH_CCB
                   1431:                                           : BHA_INITIATOR_CCB);
                   1432:                bcopy(xs->cmd, &ccb->scsi_cmd,
                   1433:                    ccb->scsi_cmd_length = xs->cmdlen);
                   1434:        }
                   1435:
                   1436:        if (xs->datalen) {
                   1437:                /*
                   1438:                 * Map the DMA transfer.
                   1439:                 */
                   1440: #ifdef TFS
                   1441:                if (flags & SCSI_DATA_UIO) {
                   1442:                        error = bus_dmamap_load_uio(dmat,
                   1443:                            ccb->dmamap_xfer, (struct uio *)xs->data,
                   1444:                            (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
                   1445:                            BUS_DMA_WAITOK);
                   1446:                } else
                   1447: #endif /* TFS */
                   1448:                {
                   1449:                        error = bus_dmamap_load(dmat,
                   1450:                            ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
                   1451:                            (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
                   1452:                            BUS_DMA_WAITOK);
                   1453:                }
                   1454:
                   1455:                if (error) {
                   1456:                        if (error == EFBIG) {
                   1457:                                printf("%s: bha_scsi_cmd, more than %d"
                   1458:                                    " dma segments\n",
                   1459:                                    sc->sc_dev.dv_xname, BHA_NSEG);
                   1460:                        } else {
                   1461:                                printf("%s: bha_scsi_cmd, error %d loading"
                   1462:                                    " dma map\n",
                   1463:                                    sc->sc_dev.dv_xname, error);
                   1464:                        }
                   1465:                        goto bad;
                   1466:                }
                   1467:
                   1468:                bus_dmamap_sync(dmat, ccb->dmamap_xfer,
                   1469:                    0, ccb->dmamap_xfer->dm_mapsize,
                   1470:                    (flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
                   1471:                    BUS_DMASYNC_PREWRITE);
                   1472:
                   1473:                /*
                   1474:                 * Load the hardware scatter/gather map with the
                   1475:                 * contents of the DMA map.
                   1476:                 */
                   1477:                for (seg = 0; seg < ccb->dmamap_xfer->dm_nsegs; seg++) {
                   1478:                        ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_addr,
                   1479:                            ccb->scat_gath[seg].seg_addr);
                   1480:                        ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_len,
                   1481:                            ccb->scat_gath[seg].seg_len);
                   1482:                }
                   1483:
                   1484:                ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
                   1485:                    BHA_CCB_OFF(ccb) + offsetof(struct bha_ccb, scat_gath),
                   1486:                    ccb->data_addr);
                   1487:                ltophys(ccb->dmamap_xfer->dm_nsegs *
                   1488:                    sizeof(struct bha_scat_gath), ccb->data_length);
                   1489:        } else {
                   1490:                /*
                   1491:                 * No data xfer, use non S/G values.
                   1492:                 */
                   1493:                ltophys(0, ccb->data_addr);
                   1494:                ltophys(0, ccb->data_length);
                   1495:        }
                   1496:
                   1497:        ccb->data_out = 0;
                   1498:        ccb->data_in = 0;
                   1499:        ccb->target = sc_link->target;
                   1500:        ccb->lun = sc_link->lun;
                   1501:        ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
                   1502:            BHA_CCB_OFF(ccb) + offsetof(struct bha_ccb, scsi_sense),
                   1503:            ccb->sense_ptr);
                   1504:        ccb->req_sense_length = sizeof(ccb->scsi_sense);
                   1505:        ccb->host_stat = 0x00;
                   1506:        ccb->target_stat = 0x00;
                   1507:        ccb->link_id = 0;
                   1508:        ltophys(0, ccb->link_addr);
                   1509:
                   1510:        bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
                   1511:            0, sc->sc_dmamap_control->dm_mapsize,
                   1512:            BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   1513:
                   1514:        s = splbio();
                   1515:        bha_queue_ccb(sc, ccb);
                   1516:        splx(s);
                   1517:
                   1518:        /*
                   1519:         * Usually return SUCCESSFULLY QUEUED
                   1520:         */
                   1521:        SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
                   1522:        if ((flags & SCSI_POLL) == 0)
                   1523:                return (SUCCESSFULLY_QUEUED);
                   1524:
                   1525:        /*
                   1526:         * If we can't use interrupts, poll on completion
                   1527:         */
                   1528:        if (bha_poll(sc, xs, ccb->timeout)) {
                   1529:                bha_timeout(ccb);
                   1530:                if (bha_poll(sc, xs, ccb->timeout))
                   1531:                        bha_timeout(ccb);
                   1532:        }
                   1533:        return (COMPLETE);
                   1534:
                   1535: bad:
                   1536:        xs->error = XS_DRIVER_STUFFUP;
                   1537:        bha_free_ccb(sc, ccb);
                   1538:        return (COMPLETE);
                   1539: }
                   1540:
                   1541: /*
                   1542:  * Poll a particular unit, looking for a particular xs
                   1543:  */
                   1544: int
                   1545: bha_poll(sc, xs, count)
                   1546:        struct bha_softc *sc;
                   1547:        struct scsi_xfer *xs;
                   1548:        int count;
                   1549: {
                   1550:        bus_space_tag_t iot = sc->sc_iot;
                   1551:        bus_space_handle_t ioh = sc->sc_ioh;
                   1552:
                   1553:        /* timeouts are in msec, so we loop in 1000 usec cycles */
                   1554:        while (count) {
                   1555:                /*
                   1556:                 * If we had interrupts enabled, would we
                   1557:                 * have got an interrupt?
                   1558:                 */
                   1559:                if (bus_space_read_1(iot, ioh, BHA_INTR_PORT) &
                   1560:                    BHA_INTR_ANYINTR)
                   1561:                        bha_intr(sc);
                   1562:                if (xs->flags & ITSDONE)
                   1563:                        return (0);
                   1564:                delay(1000);    /* only happens in boot so ok */
                   1565:                count--;
                   1566:        }
                   1567:        return (1);
                   1568: }
                   1569:
                   1570: void
                   1571: bha_timeout(arg)
                   1572:        void *arg;
                   1573: {
                   1574:        struct bha_ccb *ccb = arg;
                   1575:        struct scsi_xfer *xs = ccb->xs;
                   1576:        struct scsi_link *sc_link = xs->sc_link;
                   1577:        struct bha_softc *sc = sc_link->adapter_softc;
                   1578:        int s;
                   1579:
                   1580:        sc_print_addr(sc_link);
                   1581:        printf("timed out");
                   1582:
                   1583:        s = splbio();
                   1584:
                   1585: #ifdef BHADIAG
                   1586:        /*
                   1587:         * If the ccb's mbx is not free, then the board has gone Far East?
                   1588:         */
                   1589:        bha_collect_mbo(sc);
                   1590:        if (ccb->flags & CCB_SENDING) {
                   1591:                printf("%s: not taking commands!\n", sc->sc_dev.dv_xname);
                   1592:                Debugger();
                   1593:        }
                   1594: #endif
                   1595:
                   1596:        /*
                   1597:         * If it has been through before, then
                   1598:         * a previous abort has failed, don't
                   1599:         * try abort again
                   1600:         */
                   1601:        if (ccb->flags & CCB_ABORT) {
                   1602:                /* abort timed out */
                   1603:                printf(" AGAIN\n");
                   1604:                /* XXX Must reset! */
                   1605:        } else {
                   1606:                /* abort the operation that has timed out */
                   1607:                printf("\n");
                   1608:                ccb->xs->error = XS_TIMEOUT;
                   1609:                ccb->timeout = BHA_ABORT_TIMEOUT;
                   1610:                ccb->flags |= CCB_ABORT;
                   1611:                bha_queue_ccb(sc, ccb);
                   1612:        }
                   1613:
                   1614:        splx(s);
                   1615: }

CVSweb