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

Annotation of sys/arch/mvme68k/dev/ssh.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ssh.c,v 1.16 2007/05/29 13:56:13 pyr Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 1994 Michael L. Hitch
                      5:  * Copyright (c) 1990 The Regents of the University of California.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to Berkeley by
                      9:  * Van Jacobson of Lawrence Berkeley Laboratory.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. Neither the name of the University nor the names of its contributors
                     20:  *    may be used to endorse or promote products derived from this software
                     21:  *    without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  *
                     35:  *     @(#)ssh.c       7.5 (Berkeley) 5/4/91
                     36:  */
                     37:
                     38: /*
                     39:  * 53C710 scsi adaptor driver
                     40:  */
                     41:
                     42: #include <sys/param.h>
                     43: #include <sys/systm.h>
                     44: #include <sys/device.h>
                     45: #include <sys/disklabel.h>
                     46: #include <sys/dkstat.h>
                     47: #include <sys/buf.h>
                     48: #include <sys/malloc.h>
                     49: #include <sys/queue.h>
                     50:
                     51: #include <scsi/scsi_all.h>
                     52: #include <scsi/scsiconf.h>
                     53:
                     54: #include <machine/autoconf.h>
                     55: #include <machine/cpu.h>
                     56:
                     57: #include <mvme68k/dev/sshreg.h>
                     58: #include <mvme68k/dev/sshvar.h>
                     59:
                     60: /*
                     61:  * SCSI delays
                     62:  * In u-seconds, primarily for state changes on the SPC.
                     63:  */
                     64: #define        SCSI_CMD_WAIT   500000  /* wait per step of 'immediate' cmds */
                     65: #define        SCSI_DATA_WAIT  500000  /* wait per data in/out step */
                     66: #define        SCSI_INIT_WAIT  500000  /* wait per step (both) during init */
                     67:
                     68: void ssh_select(struct ssh_softc *);
                     69: void sshabort(struct ssh_softc *, ssh_regmap_p, char *);
                     70: void ssherror(struct ssh_softc *, ssh_regmap_p, u_char);
                     71: void sshstart(struct ssh_softc *);
                     72: void sshreset(struct ssh_softc *);
                     73: void sshsetdelay(int);
                     74: void ssh_scsidone(struct ssh_acb *, int);
                     75: void ssh_sched(struct ssh_softc *);
                     76: int  ssh_poll(struct ssh_softc *, struct ssh_acb *);
                     77: void sshintr(struct ssh_softc *);
                     78: void sshinitialize(struct ssh_softc *);
                     79: void ssh_start(struct ssh_softc *, int, int, u_char *, int, u_char *, int);
                     80: int  ssh_checkintr(struct ssh_softc *, u_char, u_char, u_char, int *);
                     81: void scsi_period_to_ssh(struct ssh_softc *, int);
                     82:
                     83: /* 53C710 script */
                     84: const
                     85: #include <mvme68k/dev/ssh_script.out>
                     86:
                     87: /* default to not inhibit sync negotiation on any drive */
                     88: u_char ssh_inhibit_sync[8] = { 0, 0, 0, 0, 0, 0, 0};   /* initialize, so patchable */
                     89: u_char ssh_allow_disc[8] = { 3, 3, 3, 3, 3, 3, 3, 3};
                     90: int ssh_no_dma = 0;
                     91:
                     92: int ssh_reset_delay = 250;     /* delay after reset, in milleseconds */
                     93:
                     94: int ssh_cmd_wait = SCSI_CMD_WAIT;
                     95: int ssh_data_wait = SCSI_DATA_WAIT;
                     96: int ssh_init_wait = SCSI_INIT_WAIT;
                     97:
                     98: #ifdef DEBUG
                     99: /*
                    100:  *     0x01 - full debug
                    101:  *     0x02 - DMA chaining
                    102:  *     0x04 - sshintr
                    103:  *     0x08 - phase mismatch
                    104:  *     0x10 - <not used>
                    105:  *     0x20 - panic on unhandled exceptions
                    106:  *     0x100 - disconnect/reselect
                    107:  */
                    108: int   ssh_debug = 0;
                    109: int   sshsync_debug = 0;
                    110: int   sshdma_hits = 0;
                    111: int   sshdma_misses = 0;
                    112: int   sshchain_ints = 0;
                    113: int   sshstarts = 0;
                    114: int   sshints = 0;
                    115: int   sshphmm = 0;
                    116: #define SSH_TRACE_SIZE 128
                    117: #define SSH_TRACE(a,b,c,d) \
                    118:        ssh_trbuf[ssh_trix] = (a); \
                    119:        ssh_trbuf[ssh_trix+1] = (b); \
                    120:        ssh_trbuf[ssh_trix+2] = (c); \
                    121:        ssh_trbuf[ssh_trix+3] = (d); \
                    122:        ssh_trix = (ssh_trix + 4) & (SSH_TRACE_SIZE - 1);
                    123: u_char   ssh_trbuf[SSH_TRACE_SIZE];
                    124: int   ssh_trix;
                    125: #else
                    126: #define SSH_TRACE(a,b,c,d)
                    127: #endif
                    128:
                    129:
                    130: /*
                    131:  * default minphys routine for ssh based controllers
                    132:  */
                    133: void
                    134: ssh_minphys(bp)
                    135: struct buf *bp;
                    136: {
                    137:
                    138:        /*
                    139:         * No max transfer at this level.
                    140:         */
                    141:        minphys(bp);
                    142: }
                    143:
                    144: /*
                    145:  * used by specific ssh controller
                    146:  *
                    147:  */
                    148: int
                    149: ssh_scsicmd(xs)
                    150: struct scsi_xfer *xs;
                    151: {
                    152:        struct ssh_acb *acb;
                    153:        struct ssh_softc *sc;
                    154:        struct scsi_link *slp;
                    155:        int flags, s;
                    156:
                    157:        slp = xs->sc_link;
                    158:        sc = slp->adapter_softc;
                    159:        flags = xs->flags;
                    160:
                    161:        /* XXXX ?? */
                    162:        if (flags & SCSI_DATA_UIO)
                    163:                panic("ssh: scsi data uio requested");
                    164:
                    165:        /* XXXX ?? */
                    166:        if (sc->sc_nexus && flags & SCSI_POLL)
                    167:                panic("ssh_scsicmd: busy");
                    168:
                    169:        s = splbio();
                    170:        acb = TAILQ_FIRST(&sc->free_list);
                    171:        if (acb) {
                    172:                TAILQ_REMOVE(&sc->free_list, acb, chain);
                    173:        }
                    174:        splx(s);
                    175:
                    176:        if (acb == NULL) {
                    177:                return (TRY_AGAIN_LATER);
                    178:        }
                    179:
                    180:        acb->flags = ACB_ACTIVE;
                    181:        acb->xs = xs;
                    182:        bcopy(xs->cmd, &acb->cmd, xs->cmdlen);
                    183:        acb->clen = xs->cmdlen;
                    184:        acb->daddr = xs->data;
                    185:        acb->dleft = xs->datalen;
                    186:
                    187:        s = splbio();
                    188:        TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain);
                    189:
                    190:        if (sc->sc_nexus == NULL)
                    191:                ssh_sched(sc);
                    192:
                    193:        splx(s);
                    194:
                    195:        if (flags & SCSI_POLL || ssh_no_dma)
                    196:                return (ssh_poll(sc, acb));
                    197:        return (SUCCESSFULLY_QUEUED);
                    198: }
                    199:
                    200: int
                    201: ssh_poll(sc, acb)
                    202: struct ssh_softc *sc;
                    203: struct ssh_acb *acb;
                    204: {
                    205:        ssh_regmap_p rp = sc->sc_sshp;
                    206:        struct scsi_xfer *xs = acb->xs;
                    207:        int i;
                    208:        int status;
                    209:        u_char istat;
                    210:        u_char dstat;
                    211:        u_char sstat0;
                    212:        int s;
                    213:        int to;
                    214:
                    215:        s = splbio();
                    216:        to = xs->timeout / 1000;
                    217:        if (!TAILQ_EMPTY(&sc->nexus_list))
                    218:                printf("%s: ssh_poll called with disconnected device\n",
                    219:                                 sc->sc_dev.dv_xname);
                    220:        for (;;) {
                    221:                /* use cmd_wait values? */
                    222:                i = 50000;
                    223:                while (((istat = rp->ssh_istat) &
                    224:                                  (SSH_ISTAT_SIP | SSH_ISTAT_DIP)) == 0) {
                    225:                        if (--i <= 0) {
                    226: #ifdef DEBUG
                    227:                                printf ("waiting: tgt %d cmd %02x sbcl %02x dsp %x (+%x) dcmd %x ds %x timeout %d\n",
                    228:                                                  xs->sc_link->target, acb->cmd.opcode,
                    229:                                                  rp->ssh_sbcl, rp->ssh_dsp,
                    230:                                                  rp->ssh_dsp - sc->sc_scriptspa,
                    231:                                                  *((long *)&rp->ssh_dcmd), &acb->ds, acb->xs->timeout);
                    232: #endif
                    233:                                i = 50000;
                    234:                                --to;
                    235:                                if (to <= 0) {
                    236:                                        sshreset(sc);
                    237:                                        return (COMPLETE);
                    238:                                }
                    239:                        }
                    240:                        delay(10);
                    241:                }
                    242:                sstat0 = rp->ssh_sstat0;
                    243:                dstat = rp->ssh_dstat;
                    244:                if (ssh_checkintr(sc, istat, dstat, sstat0, &status)) {
                    245:                        if (acb != sc->sc_nexus)
                    246:                                printf("%s: ssh_poll disconnected device completed\n",
                    247:                                                 sc->sc_dev.dv_xname);
                    248:                        else if ((sc->sc_flags & SSH_INTDEFER) == 0) {
                    249:                                sc->sc_flags &= ~SSH_INTSOFF;
                    250:                                rp->ssh_sien = sc->sc_sien;
                    251:                                rp->ssh_dien = sc->sc_dien;
                    252:                        }
                    253:                        ssh_scsidone(sc->sc_nexus, status);
                    254:                }
                    255:                if (xs->flags & ITSDONE)
                    256:                        break;
                    257:        }
                    258:        splx(s);
                    259:        return (COMPLETE);
                    260: }
                    261:
                    262: /*
                    263:  * start next command that's ready
                    264:  */
                    265: void
                    266: ssh_sched(sc)
                    267: struct ssh_softc *sc;
                    268: {
                    269:        struct scsi_link *slp;
                    270:        struct ssh_acb *acb;
                    271:        int i;
                    272:
                    273: #ifdef DEBUG
                    274:        if (sc->sc_nexus) {
                    275:                printf("%s: ssh_sched- nexus %x/%d ready %x/%d\n",
                    276:                                 sc->sc_dev.dv_xname, sc->sc_nexus,
                    277:                                 sc->sc_nexus->xs->sc_link->target,
                    278:                                 TAILQ_FIRST(&sc->ready_list),
                    279:                                 TAILQ_FIRST(&sc->ready_list)->xs->sc_link->target);
                    280:                return;
                    281:        }
                    282: #endif
                    283:        TAILQ_FOREACH(acb, &sc->ready_list, chain) {
                    284:                slp = acb->xs->sc_link;
                    285:                i = slp->target;
                    286:                if (!(sc->sc_tinfo[i].lubusy & (1 << slp->lun))) {
                    287:                        struct ssh_tinfo *ti = &sc->sc_tinfo[i];
                    288:
                    289:                        TAILQ_REMOVE(&sc->ready_list, acb, chain);
                    290:                        sc->sc_nexus = acb;
                    291:                        slp = acb->xs->sc_link;
                    292:                        ti = &sc->sc_tinfo[slp->target];
                    293:                        ti->lubusy |= (1 << slp->lun);
                    294:                        break;
                    295:                }
                    296:        }
                    297:
                    298:        if (acb == NULL) {
                    299: #ifdef DEBUGXXX
                    300:                printf("%s: ssh_sched didn't find ready command\n",
                    301:                                 sc->sc_dev.dv_xname);
                    302: #endif
                    303:                return;
                    304:        }
                    305:
                    306:        if (acb->xs->flags & SCSI_RESET)
                    307:                sshreset(sc);
                    308:
                    309: #if 0
                    310:        acb->cmd.bytes[0] |= slp->lun << 5;     /* XXXX */
                    311: #endif
                    312:        ++sc->sc_active;
                    313:        ssh_select(sc);
                    314: }
                    315:
                    316: void
                    317: ssh_scsidone(acb, stat)
                    318:        struct ssh_acb *acb;
                    319:        int stat;
                    320: {
                    321:        struct scsi_xfer *xs;
                    322:        struct scsi_link *slp;
                    323:        struct ssh_softc *sc;
                    324:        int dosched = 0;
                    325:
                    326:        if (acb == NULL || (xs = acb->xs) == NULL) {
                    327: #ifdef DIAGNOSTIC
                    328:                printf("ssh_scsidone: NULL acb or scsi_xfer\n");
                    329: #if defined(DEBUG) && defined(DDB)
                    330:                Debugger();
                    331: #endif
                    332: #endif
                    333:                return;
                    334:        }
                    335:        slp = xs->sc_link;
                    336:        sc = slp->adapter_softc;
                    337:
                    338:        /*
                    339:         * is this right?
                    340:         */
                    341:        xs->status = stat;
                    342:
                    343:        if (xs->error == XS_NOERROR && !(acb->flags & ACB_CHKSENSE)) {
                    344:                if (stat == SCSI_CHECK) {
                    345:                        struct scsi_sense *ss = (void *)&acb->cmd;
                    346:                        bzero(ss, sizeof(*ss));
                    347:                        ss->opcode = REQUEST_SENSE;
                    348:                        ss->byte2 = slp->lun << 5;
                    349:                        ss->length = sizeof(struct scsi_sense_data);
                    350:                        acb->clen = sizeof(*ss);
                    351:                        acb->daddr = (char *)&xs->sense;
                    352:                        acb->dleft = sizeof(struct scsi_sense_data);
                    353:                        acb->flags = ACB_ACTIVE | ACB_CHKSENSE;
                    354:                        TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
                    355:                        --sc->sc_active;
                    356:                        sc->sc_tinfo[slp->target].lubusy &=
                    357:                        ~(1 << slp->lun);
                    358:                        sc->sc_tinfo[slp->target].senses++;
                    359:                        if (sc->sc_nexus == acb) {
                    360:                                sc->sc_nexus = NULL;
                    361:                                ssh_sched(sc);
                    362:                        }
                    363:                        SSH_TRACE('d','s',0,0)
                    364:                        return;
                    365:                }
                    366:        }
                    367:        if (xs->error == XS_NOERROR && (acb->flags & ACB_CHKSENSE)) {
                    368:                xs->error = XS_SENSE;
                    369:        } else {
                    370:                xs->resid = 0;          /* XXXX */
                    371:        }
                    372:
                    373: #if whataboutthisone
                    374:                case SCSI_BUSY:
                    375:                        xs->error = XS_BUSY;
                    376:                        break;
                    377: #endif
                    378:
                    379:        xs->flags |= ITSDONE;
                    380:
                    381:        /*
                    382:         * Remove the ACB from whatever queue it's on.  We have to do a bit of
                    383:         * a hack to figure out which queue it's on.  Note that it is *not*
                    384:         * necessary to cdr down the ready queue, but we must cdr down the
                    385:         * nexus queue and see if it's there, so we can mark the unit as no
                    386:         * longer busy.  This code is sickening, but it works.
                    387:         */
                    388:        if (acb == sc->sc_nexus) {
                    389:                sc->sc_nexus = NULL;
                    390:                sc->sc_tinfo[slp->target].lubusy &= ~(1<<slp->lun);
                    391:                if (!TAILQ_EMPTY(&sc->ready_list))
                    392:                        dosched = 1;    /* start next command */
                    393:                --sc->sc_active;
                    394:                SSH_TRACE('d','a',stat,0)
                    395:        } else if (TAILQ_LAST(&sc->ready_list, acb_list) ==
                    396:            TAILQ_NEXT(acb, chain)) {
                    397:                TAILQ_REMOVE(&sc->ready_list, acb, chain);
                    398:                SSH_TRACE('d','r',stat,0)
                    399:        } else {
                    400:                register struct ssh_acb *acb2;
                    401:                TAILQ_FOREACH(acb2, &sc->nexus_list, chain)
                    402:                        if (acb2 == acb) {
                    403:                                TAILQ_REMOVE(&sc->nexus_list, acb, chain);
                    404:                                sc->sc_tinfo[slp->target].lubusy
                    405:                                &= ~(1<<slp->lun);
                    406:                                --sc->sc_active;
                    407:                                break;
                    408:                        }
                    409:                if (acb2)
                    410:                        ;
                    411:                else if (TAILQ_NEXT(acb, chain) != NULL) {
                    412:                        TAILQ_REMOVE(&sc->ready_list, acb, chain);
                    413:                        --sc->sc_active;
                    414:                } else {
                    415:                        printf("%s: can't find matching acb\n",
                    416:                                         sc->sc_dev.dv_xname);
                    417: #ifdef DDB
                    418: /*                     Debugger(); */
                    419: #endif
                    420:                }
                    421:                SSH_TRACE('d','n',stat,0);
                    422:        }
                    423:        /* Put it on the free list. */
                    424:        acb->flags = ACB_FREE;
                    425:        TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
                    426:
                    427:        sc->sc_tinfo[slp->target].cmds++;
                    428:
                    429:        scsi_done(xs);
                    430:
                    431:        if (dosched && sc->sc_nexus == NULL)
                    432:                ssh_sched(sc);
                    433: }
                    434:
                    435: void
                    436: sshabort(sc, rp, where)
                    437: register struct ssh_softc *sc;
                    438: ssh_regmap_p rp;
                    439: char *where;
                    440: {
                    441: #ifdef fix_this
                    442:        int i;
                    443: #endif
                    444:
                    445:        printf ("%s: abort %s: dstat %02x, sstat0 %02x sbcl %02x\n",
                    446:                          sc->sc_dev.dv_xname,
                    447:                          where, rp->ssh_dstat, rp->ssh_sstat0, rp->ssh_sbcl);
                    448:
                    449:        if (sc->sc_active > 0) {
                    450: #ifdef TODO
                    451:                SET_SBIC_cmd (rp, SBIC_CMD_ABORT);
                    452:                WAIT_CIP (rp);
                    453:
                    454:                GET_SBIC_asr (rp, asr);
                    455:                if (asr & (SBIC_ASR_BSY|SBIC_ASR_LCI)) {
                    456:                        /* ok, get more drastic.. */
                    457:
                    458:                        SET_SBIC_cmd (rp, SBIC_CMD_RESET);
                    459:                        delay(25);
                    460:                        SBIC_WAIT(rp, SBIC_ASR_INT, 0);
                    461:                        GET_SBIC_csr (rp, csr);                 /* clears interrupt also */
                    462:
                    463:                        return;
                    464:                }
                    465:
                    466:                do {
                    467:                        SBIC_WAIT (rp, SBIC_ASR_INT, 0);
                    468:                        GET_SBIC_csr (rp, csr);
                    469:                }
                    470:                while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1)
                    471:                                 && (csr != SBIC_CSR_CMD_INVALID));
                    472: #endif
                    473:
                    474:                /* lets just hope it worked.. */
                    475: #ifdef fix_this
                    476:                for (i = 0; i < 2; ++i) {
                    477:                        if (sc->sc_iob[i].sc_xs && &sc->sc_iob[i] !=
                    478:                                 sc->sc_cur) {
                    479:                                printf ("sshabort: cleanup!\n");
                    480:                                sc->sc_iob[i].sc_xs = NULL;
                    481:                        }
                    482:                }
                    483: #endif /* fix_this */
                    484: /*             sc->sc_active = 0; */
                    485:        }
                    486: }
                    487:
                    488: void
                    489: sshinitialize(sc)
                    490:        struct ssh_softc *sc;
                    491: {
                    492:        /*
                    493:         * Need to check that scripts is on a long word boundary
                    494:         * Also should verify that dev doesn't span non-contiguous
                    495:         * physical pages.
                    496:         */
                    497:        sc->sc_scriptspa = kvtop((vaddr_t)scripts);
                    498:
                    499:        /*
                    500:         * malloc sc_acb to ensure that DS is on a long word boundary.
                    501:         */
                    502:
                    503:        MALLOC(sc->sc_acb, struct ssh_acb *,
                    504:                         sizeof(struct ssh_acb) * SSH_NACB, M_DEVBUF, M_NOWAIT);
                    505:        if (sc->sc_acb == NULL)
                    506:                panic("sshinitialize: ACB malloc failed!");
                    507:
                    508:        sc->sc_tcp[1] = 1000 / sc->sc_clock_freq;
                    509:        sc->sc_tcp[2] = 1500 / sc->sc_clock_freq;
                    510:        sc->sc_tcp[3] = 2000 / sc->sc_clock_freq;
                    511:        sc->sc_minsync = sc->sc_tcp[1];         /* in 4ns units */
                    512:        if (sc->sc_minsync < 25)
                    513:                sc->sc_minsync = 25;
                    514: #if not_used
                    515:        if (sc->sc_clock_freq <= 25)
                    516:                sc->sc_tcp[0] = sc->sc_tcp[1];
                    517:        else if (sc->sc_clock_freq <= 37)
                    518:                sc->sc_tcp[0] = sc->sc_tcp[2];
                    519:        else if (sc->sc_clock_freq <= 50)
                    520:                sc->sc_tcp[0] = sc->sc_tcp[3];
                    521:        else
                    522:                sc->sc_tcp[0] = 3000 / sc->sc_clock_freq;
                    523: #endif
                    524:
                    525:        sshreset (sc);
                    526: }
                    527:
                    528: void
                    529: sshreset(sc)
                    530: struct ssh_softc *sc;
                    531: {
                    532:        ssh_regmap_p rp;
                    533:        u_int i, s;
                    534:        u_char  dummy;
                    535:        struct ssh_acb *acb;
                    536:
                    537:        rp = sc->sc_sshp;
                    538:
                    539:        if (sc->sc_flags & SSH_ALIVE)
                    540:                sshabort(sc, rp, "reset");
                    541:
                    542:        s = splbio();
                    543:
                    544:        /*
                    545:         * Reset the chip
                    546:         * XXX - is this really needed?
                    547:         */
                    548:        rp->ssh_istat |= SSH_ISTAT_ABRT;        /* abort current script */
                    549:        rp->ssh_istat |= SSH_ISTAT_RST;         /* reset chip */
                    550:        rp->ssh_istat &= ~SSH_ISTAT_RST;
                    551:        /*
                    552:         * Reset SCSI bus (do we really want this?)
                    553:         */
                    554:        rp->ssh_sien = 0;
                    555:        rp->ssh_scntl1 |= SSH_SCNTL1_RST;
                    556:        delay(1);
                    557:        rp->ssh_scntl1 &= ~SSH_SCNTL1_RST;
                    558:
                    559:        /*
                    560:         * Set up various chip parameters
                    561:         */
                    562:        rp->ssh_scntl0 = SSH_ARB_FULL | SSH_SCNTL0_EPC | SSH_SCNTL0_EPG;
                    563:        rp->ssh_scntl1 = SSH_SCNTL1_ESR;
                    564:        rp->ssh_dcntl = sc->sc_dcntl;
                    565:        rp->ssh_dmode = 0x80;   /* burst length = 4 */
                    566:        rp->ssh_sien = 0x00;    /* don't enable interrupts yet */
                    567:        rp->ssh_dien = 0x00;    /* don't enable interrupts yet */
                    568:        rp->ssh_scid = 1 << sc->sc_link.adapter_target;
                    569:        rp->ssh_dwt = 0x00;
                    570:        rp->ssh_ctest0 |= SSH_CTEST0_BTD | SSH_CTEST0_EAN;
                    571:        rp->ssh_ctest7 = sc->sc_ctest7;
                    572:
                    573:        /* will need to re-negotiate sync xfers */
                    574:        bzero(&sc->sc_sync, sizeof (sc->sc_sync));
                    575:
                    576:        i = rp->ssh_istat;
                    577:        if (i & SSH_ISTAT_SIP)
                    578:                dummy = rp->ssh_sstat0;
                    579:        if (i & SSH_ISTAT_DIP)
                    580:                dummy = rp->ssh_dstat;
                    581:
                    582:        splx(s);
                    583:
                    584:        delay(ssh_reset_delay * 1000);
                    585:        printf(": version %d target %d\n", rp->ssh_ctest8 >> 4,
                    586:                         sc->sc_link.adapter_target);
                    587:
                    588:        if ((sc->sc_flags & SSH_ALIVE) == 0) {
                    589:                TAILQ_INIT(&sc->ready_list);
                    590:                TAILQ_INIT(&sc->nexus_list);
                    591:                TAILQ_INIT(&sc->free_list);
                    592:                sc->sc_nexus = NULL;
                    593:                acb = sc->sc_acb;
                    594:                bzero(acb, sizeof(struct ssh_acb) * SSH_NACB);
                    595:                for (i = 0; i < SSH_NACB; i++) {
                    596:                        TAILQ_INSERT_TAIL(&sc->free_list, acb, chain);
                    597:                        acb++;
                    598:                }
                    599:                bzero(sc->sc_tinfo, sizeof(sc->sc_tinfo));
                    600:        } else {
                    601:                if (sc->sc_nexus != NULL) {
                    602:                        sc->sc_nexus->xs->error = XS_DRIVER_STUFFUP;
                    603:                        ssh_scsidone(sc->sc_nexus, sc->sc_nexus->stat[0]);
                    604:                }
                    605:                while ((acb = TAILQ_FIRST(&sc->nexus_list))) {
                    606:                        acb->xs->error = XS_DRIVER_STUFFUP;
                    607:                        ssh_scsidone(acb, acb->stat[0]);
                    608:                }
                    609:        }
                    610:
                    611:        sc->sc_flags |= SSH_ALIVE;
                    612:        sc->sc_flags &= ~(SSH_INTDEFER|SSH_INTSOFF);
                    613:        /* enable SCSI and DMA interrupts */
                    614:        sc->sc_sien = SSH_SIEN_M_A | SSH_SIEN_STO | /*SSH_SIEN_SEL |*/ SSH_SIEN_SGE |
                    615:                                          SSH_SIEN_UDC | SSH_SIEN_RST | SSH_SIEN_PAR;
                    616:        sc->sc_dien = SSH_DIEN_BF | SSH_DIEN_ABRT | SSH_DIEN_SIR |
                    617:                                          /*SSH_DIEN_WTD |*/ SSH_DIEN_IID;
                    618:        rp->ssh_sien = sc->sc_sien;
                    619:        rp->ssh_dien = sc->sc_dien;
                    620: }
                    621:
                    622: /*
                    623:  * Setup Data Storage for 53C710 and start SCRIPTS processing
                    624:  */
                    625:
                    626: void
                    627: ssh_start (sc, target, lun, cbuf, clen, buf, len)
                    628:        struct ssh_softc *sc;
                    629:        int target;
                    630:        int lun;
                    631:        u_char *cbuf;
                    632:        int clen;
                    633:        u_char *buf;
                    634:        int len;
                    635: {
                    636:        ssh_regmap_p rp = sc->sc_sshp;
                    637: #ifdef DEBUG
                    638:        int i;
                    639: #endif
                    640:        int nchain;
                    641:        int count, tcount;
                    642:        char *addr, *dmaend;
                    643:        struct ssh_acb *acb = sc->sc_nexus;
                    644:
                    645: #ifdef DEBUG
                    646:        if (ssh_debug & 0x100 && rp->ssh_sbcl & SSH_BSY) {
                    647:                printf ("ACK! ssh was busy: rp %x script %x dsa %x active %d\n",
                    648:                                  rp, &scripts, &acb->ds, sc->sc_active);
                    649:                printf ("istat %02x sfbr %02x lcrc %02x sien %02x dien %02x\n",
                    650:                                  rp->ssh_istat, rp->ssh_sfbr, rp->ssh_lcrc,
                    651:                                  rp->ssh_sien, rp->ssh_dien);
                    652: #ifdef DDB
                    653:                /*Debugger();*/
                    654: #endif
                    655:        }
                    656: #endif
                    657:        acb->msgout[0] = MSG_IDENTIFY | lun;
                    658:        if (ssh_allow_disc[target] & 2 ||
                    659:                 (ssh_allow_disc[target] && len == 0))
                    660:                acb->msgout[0] = MSG_IDENTIFY_DR | lun;
                    661:        acb->status = 0;
                    662:        acb->stat[0] = -1;
                    663:        acb->msg[0] = -1;
                    664:        acb->ds.scsi_addr = (0x10000 << target) | (sc->sc_sync[target].sxfer << 8);
                    665:        acb->ds.idlen = 1;
                    666:        acb->ds.idbuf = (char *) kvtop((vaddr_t)&acb->msgout[0]);
                    667:        acb->ds.cmdlen = clen;
                    668:        acb->ds.cmdbuf = (char *) kvtop((vaddr_t)cbuf);
                    669:        acb->ds.stslen = 1;
                    670:        acb->ds.stsbuf = (char *) kvtop((vaddr_t)&acb->stat[0]);
                    671:        acb->ds.msglen = 1;
                    672:        acb->ds.msgbuf = (char *) kvtop((vaddr_t)&acb->msg[0]);
                    673:        acb->msg[1] = -1;
                    674:        acb->ds.msginlen = 1;
                    675:        acb->ds.extmsglen = 1;
                    676:        acb->ds.synmsglen = 3;
                    677:        acb->ds.msginbuf = (char *) kvtop((vaddr_t)&acb->msg[1]);
                    678:        acb->ds.extmsgbuf = (char *) kvtop((vaddr_t)&acb->msg[2]);
                    679:        acb->ds.synmsgbuf = (char *) kvtop((vaddr_t)&acb->msg[3]);
                    680:        bzero(&acb->ds.chain, sizeof (acb->ds.chain));
                    681:
                    682:        if (sc->sc_sync[target].state == SYNC_START) {
                    683:                if (ssh_inhibit_sync[target]) {
                    684:                        sc->sc_sync[target].state = SYNC_DONE;
                    685:                        sc->sc_sync[target].sbcl = 0;
                    686:                        sc->sc_sync[target].sxfer = 0;
                    687: #ifdef DEBUG
                    688:                        if (sshsync_debug)
                    689:                                printf ("Forcing target %d asynchronous\n", target);
                    690: #endif
                    691:                } else {
                    692:                        acb->msg[2] = -1;
                    693:                        acb->msgout[1] = MSG_EXT_MESSAGE;
                    694:                        acb->msgout[2] = 3;
                    695:                        acb->msgout[3] = MSG_SYNC_REQ;
                    696: #ifdef MAXTOR_SYNC_KLUDGE
                    697:                        acb->msgout[4] = 50 / 4;        /* ask for ridiculous period */
                    698: #else
                    699:                        acb->msgout[4] = sc->sc_minsync;
                    700: #endif
                    701:                        acb->msgout[5] = SSH_MAX_OFFSET;
                    702:                        acb->ds.idlen = 6;
                    703:                        sc->sc_sync[target].state = SYNC_SENT;
                    704: #ifdef DEBUG
                    705:                        if (sshsync_debug)
                    706:                                printf ("Sending sync request to target %d\n", target);
                    707: #endif
                    708:                }
                    709:        }
                    710:
                    711: /*
                    712:  * Build physical DMA addresses for scatter/gather I/O
                    713:  */
                    714:        acb->iob_buf = buf;
                    715:        acb->iob_len = len;
                    716:        acb->iob_curbuf = acb->iob_curlen = 0;
                    717:        nchain = 0;
                    718:        count = len;
                    719:        addr = buf;
                    720:        dmaend = NULL;
                    721:        while (count > 0) {
                    722:                acb->ds.chain[nchain].databuf = (char *) kvtop ((vaddr_t)addr);
                    723:                if (count < (tcount = NBPG - ((int) addr & PGOFSET)))
                    724:                        tcount = count;
                    725:                acb->ds.chain[nchain].datalen = tcount;
                    726:                addr += tcount;
                    727:                count -= tcount;
                    728:                if (acb->ds.chain[nchain].databuf == dmaend) {
                    729:                        dmaend += acb->ds.chain[nchain].datalen;
                    730:                        acb->ds.chain[nchain].datalen = 0;
                    731:                        acb->ds.chain[--nchain].datalen += tcount;
                    732: #ifdef DEBUG
                    733:                        ++sshdma_hits;
                    734: #endif
                    735:                } else {
                    736:                        dmaend = acb->ds.chain[nchain].databuf +
                    737:                                                acb->ds.chain[nchain].datalen;
                    738:                        acb->ds.chain[nchain].datalen = tcount;
                    739: #ifdef DEBUG
                    740:                        if (nchain)     /* Don't count miss on first one */
                    741:                                ++sshdma_misses;
                    742: #endif
                    743:                }
                    744:                ++nchain;
                    745:        }
                    746: #ifdef DEBUG
                    747:        if (nchain != 1 && len != 0 && ssh_debug & 3) {
                    748:                printf ("DMA chaining set: %d\n", nchain);
                    749:                for (i = 0; i < nchain; ++i) {
                    750:                        printf ("  [%d] %8x %4x\n", i, acb->ds.chain[i].databuf,
                    751:                                          acb->ds.chain[i].datalen);
                    752:                }
                    753:        }
                    754: #endif
                    755:
                    756:        /* push data cache for all data the 53c710 needs to access */
                    757:        dma_cachectl((caddr_t)acb, sizeof (struct ssh_acb));
                    758:        dma_cachectl(cbuf, clen);
                    759:        if (buf != NULL && len != 0)
                    760:                dma_cachectl(buf, len);
                    761:
                    762: #ifdef DEBUG
                    763:        if (ssh_debug & 0x100 && rp->ssh_sbcl & SSH_BSY) {
                    764:                printf ("ACK! ssh was busy at start: rp %x script %x dsa %x active %d\n",
                    765:                                  rp, &scripts, &acb->ds, sc->sc_active);
                    766: #ifdef DDB
                    767:                /*Debugger();*/
                    768: #endif
                    769:        }
                    770: #endif
                    771:
                    772:        if (TAILQ_EMPTY(&sc->nexus_list)) {
                    773:                if (rp->ssh_istat & SSH_ISTAT_CON)
                    774:                        printf("%s: ssh_select while connected?\n",
                    775:                                         sc->sc_dev.dv_xname);
                    776:                rp->ssh_temp = 0;
                    777:                rp->ssh_sbcl = sc->sc_sync[target].sbcl;
                    778:                rp->ssh_dsa = kvtop((vaddr_t)&acb->ds);
                    779:                rp->ssh_dsp = sc->sc_scriptspa;
                    780:                SSH_TRACE('s',1,0,0)
                    781:        } else {
                    782:                if ((rp->ssh_istat & SSH_ISTAT_CON) == 0) {
                    783:                        rp->ssh_istat = SSH_ISTAT_SIGP;
                    784:                        SSH_TRACE('s',2,0,0);
                    785:                } else {
                    786:                        SSH_TRACE('s',3,rp->ssh_istat,0);
                    787:                }
                    788:        }
                    789: #ifdef DEBUG
                    790:        ++sshstarts;
                    791: #endif
                    792: }
                    793:
                    794: /*
                    795:  * Process a DMA or SCSI interrupt from the 53C710 SSH
                    796:  */
                    797:
                    798: int
                    799: ssh_checkintr(sc, istat, dstat, sstat0, status)
                    800:        struct   ssh_softc *sc;
                    801:        u_char   istat;
                    802:        u_char   dstat;
                    803:        u_char   sstat0;
                    804:        int   *status;
                    805: {
                    806:        ssh_regmap_p rp = sc->sc_sshp;
                    807:        struct ssh_acb *acb = sc->sc_nexus;
                    808:        int   target;
                    809:        int   dfifo, dbc, sstat1;
                    810:
                    811:        dfifo = rp->ssh_dfifo;
                    812:        dbc = rp->ssh_dbc0;
                    813:        sstat1 = rp->ssh_sstat1;
                    814:        rp->ssh_ctest8 |= SSH_CTEST8_CLF;
                    815:        while ((rp->ssh_ctest1 & SSH_CTEST1_FMT) != SSH_CTEST1_FMT)
                    816:                ;
                    817:        rp->ssh_ctest8 &= ~SSH_CTEST8_CLF;
                    818: #ifdef DEBUG
                    819:        ++sshints;
                    820: #if 0
                    821:        if (ssh_debug & 0x100) {
                    822:                dma_cachectl(&acb->stat[0], 1);
                    823:                printf ("sshchkintr: istat %x dstat %x sstat0 %x dsps %x sbcl %x sts %x msg %x\n",
                    824:                                  istat, dstat, sstat0, rp->ssh_dsps, rp->ssh_sbcl, acb->stat[0], acb->msg[0]);
                    825:                printf ("sync msg in: %02x %02x %02x %02x %02x %02x\n",
                    826:                                  acb->msg[0], acb->msg[1], acb->msg[2],
                    827:                                  acb->msg[3], acb->msg[4], acb->msg[5]);
                    828:        }
                    829: #endif
                    830:        if (rp->ssh_dsp && (rp->ssh_dsp < sc->sc_scriptspa ||
                    831:                                                                rp->ssh_dsp >= sc->sc_scriptspa + sizeof(scripts))) {
                    832:                printf ("%s: dsp not within script dsp %x scripts %x:%x",
                    833:                                  sc->sc_dev.dv_xname, rp->ssh_dsp, sc->sc_scriptspa,
                    834:                                  sc->sc_scriptspa + sizeof(scripts));
                    835:                printf(" istat %x dstat %x sstat0 %x\n",
                    836:                                 istat, dstat, sstat0);
                    837:                Debugger();
                    838:        }
                    839: #endif
                    840:        SSH_TRACE('i',dstat,istat,(istat&SSH_ISTAT_DIP)?rp->ssh_dsps&0xff:sstat0);
                    841:        if (dstat & SSH_DSTAT_SIR && rp->ssh_dsps == 0xff00) {
                    842:                /* Normal completion status, or check condition */
                    843: #ifdef DEBUG
                    844:                if (rp->ssh_dsa != kvtop(&acb->ds)) {
                    845:                        printf ("ssh: invalid dsa: %x %x\n", rp->ssh_dsa,
                    846:                                          kvtop(&acb->ds));
                    847:                        panic("*** ssh DSA invalid ***");
                    848:                }
                    849: #endif
                    850:                target = acb->xs->sc_link->target;
                    851:                if (sc->sc_sync[target].state == SYNC_SENT) {
                    852: #ifdef DEBUG
                    853:                        if (sshsync_debug)
                    854:                                printf ("sync msg in: %02x %02x %02x %02x %02x %02x\n",
                    855:                                                  acb->msg[0], acb->msg[1], acb->msg[2],
                    856:                                                  acb->msg[3], acb->msg[4], acb->msg[5]);
                    857: #endif
                    858:                        if (acb->msg[1] == 0xff)
                    859:                                printf ("%s: target %d ignored sync request\n",
                    860:                                                  sc->sc_dev.dv_xname, target);
                    861:                        else if (acb->msg[1] == MSG_REJECT)
                    862:                                printf ("%s: target %d rejected sync request\n",
                    863:                                                  sc->sc_dev.dv_xname, target);
                    864:                        sc->sc_sync[target].state = SYNC_DONE;
                    865:                        sc->sc_sync[target].sxfer = 0;
                    866:                        sc->sc_sync[target].sbcl = 0;
                    867:                        if (acb->msg[2] == 3 &&
                    868:                                 acb->msg[3] == MSG_SYNC_REQ &&
                    869:                                 acb->msg[5] != 0) {
                    870: #ifdef MAXTOR_KLUDGE
                    871:                                /*
                    872:                                 * Kludge for my Maxtor XT8580S
                    873:                                 * It accepts whatever we request, even
                    874:                                 * though it won't work.  So we ask for
                    875:                                 * a short period than we can handle.  If
                    876:                                 * the device says it can do it, use 208ns.
                    877:                                 * If the device says it can do less than
                    878:                                 * 100ns, then we limit it to 100ns.
                    879:                                 */
                    880:                                if (acb->msg[4] && acb->msg[4] < 100 / 4) {
                    881: #ifdef DEBUG
                    882:                                        printf ("%d: target %d wanted %dns period\n",
                    883:                                                          sc->sc_dev.dv_xname, target,
                    884:                                                          acb->msg[4] * 4);
                    885: #endif
                    886:                                        if (acb->msg[4] == 50 / 4)
                    887:                                                acb->msg[4] = 208 / 4;
                    888:                                        else
                    889:                                                acb->msg[4]     = 100 / 4;
                    890:                                }
                    891: #endif /* MAXTOR_KLUDGE */
                    892:                                printf ("%s: target %d now synchronous, period=%dns, offset=%d\n",
                    893:                                                  sc->sc_dev.dv_xname, target,
                    894:                                                  acb->msg[4] * 4, acb->msg[5]);
                    895:                                scsi_period_to_ssh (sc, target);
                    896:                        }
                    897:                }
                    898:                dma_cachectl(&acb->stat[0], 1);
                    899:                *status = acb->stat[0];
                    900: #ifdef DEBUG
                    901:                if (rp->ssh_sbcl & SSH_BSY) {
                    902:                        /*printf ("ACK! ssh was busy at end: rp %x script %x dsa %x\n",
                    903:                                 rp, &scripts, &acb->ds);*/
                    904: #ifdef DDB
                    905:                        /*Debugger();*/
                    906: #endif
                    907:                }
                    908:                if (acb->msg[0] != 0x00)
                    909:                        printf("%s: message was not COMMAND COMPLETE: %x\n",
                    910:                                         sc->sc_dev.dv_xname, acb->msg[0]);
                    911: #endif
                    912:                if (!TAILQ_EMPTY(&sc->nexus_list))
                    913:                        rp->ssh_dcntl |= SSH_DCNTL_STD;
                    914:                return 1;
                    915:        }
                    916:        if (sstat0 & SSH_SSTAT0_M_A) {          /* Phase mismatch */
                    917: #ifdef DEBUG
                    918:                ++sshphmm;
                    919:                if (acb == NULL)
                    920:                        printf("%s: Phase mismatch with no active command?\n",
                    921:                                         sc->sc_dev.dv_xname);
                    922: #endif
                    923:                if (acb->iob_len) {
                    924:                        int adjust;
                    925:                        adjust = ((dfifo - (dbc & 0x7f)) & 0x7f);
                    926:                        if (sstat1 & SSH_SSTAT1_ORF)
                    927:                                ++adjust;
                    928:                        if (sstat1 & SSH_SSTAT1_OLF)
                    929:                                ++adjust;
                    930:                        acb->iob_curlen = *((long *)&rp->ssh_dcmd) & 0xffffff;
                    931:                        acb->iob_curlen += adjust;
                    932:                        acb->iob_curbuf = *((long *)&rp->ssh_dnad) - adjust;
                    933: #ifdef DEBUG
                    934:                        if (ssh_debug & 0x100) {
                    935:                                int i;
                    936:                                printf ("Phase mismatch: curbuf %x curlen %x dfifo %x dbc %x sstat1 %x adjust %x sbcl %x starts %d acb %x\n",
                    937:                                                  acb->iob_curbuf, acb->iob_curlen, dfifo,
                    938:                                                  dbc, sstat1, adjust, rp->ssh_sbcl, sshstarts, acb);
                    939:                                if (acb->ds.chain[1].datalen) {
                    940:                                        for (i = 0; acb->ds.chain[i].datalen; ++i)
                    941:                                                printf("chain[%d] addr %x len %x\n",
                    942:                                                                 i, acb->ds.chain[i].databuf,
                    943:                                                                 acb->ds.chain[i].datalen);
                    944:                                }
                    945:                        }
                    946: #endif
                    947:                        dma_cachectl((caddr_t)acb, sizeof(*acb));
                    948:                }
                    949: #ifdef DEBUG
                    950:                SSH_TRACE('m',rp->ssh_sbcl,(rp->ssh_dsp>>8),rp->ssh_dsp);
                    951:                if (ssh_debug & 9)
                    952:                        printf ("Phase mismatch: %x dsp +%x dcmd %x\n",
                    953:                                          rp->ssh_sbcl,
                    954:                                          rp->ssh_dsp - sc->sc_scriptspa,
                    955:                                          *((long *)&rp->ssh_dcmd));
                    956: #endif
                    957:                if ((rp->ssh_sbcl & SSH_REQ) == 0) {
                    958:                        printf ("Phase mismatch: REQ not asserted! %02x dsp %lx\n",
                    959:                                          rp->ssh_sbcl, rp->ssh_dsp);
                    960: #ifdef DEBUG
                    961:                        Debugger();
                    962: #endif
                    963:                }
                    964:                switch (rp->ssh_sbcl & 7) {
                    965:                        case 0:         /* data out */
                    966:                        case 1:         /* data in */
                    967:                        case 2:         /* status */
                    968:                        case 3:         /* command */
                    969:                        case 6:         /* message in */
                    970:                        case 7:         /* message out */
                    971:                                rp->ssh_dsp = sc->sc_scriptspa + Ent_switch;
                    972:                                break;
                    973:                        default:
                    974:                                goto bad_phase;
                    975:                }
                    976:                return 0;
                    977:        }
                    978:        if (sstat0 & SSH_SSTAT0_STO) {          /* Select timed out */
                    979: #ifdef DEBUG
                    980:                if (acb == NULL)
                    981:                        printf("%s: Select timeout with no active command?\n",
                    982:                                         sc->sc_dev.dv_xname);
                    983:                if (rp->ssh_sbcl & SSH_BSY) {
                    984:                        printf ("ACK! ssh was busy at timeout: rp %x script %x dsa %x\n",
                    985:                                          rp, &scripts, &acb->ds);
                    986:                        printf(" sbcl %x sdid %x istat %x dstat %x sstat0 %x\n",
                    987:                                         rp->ssh_sbcl, rp->ssh_sdid, istat, dstat, sstat0);
                    988:                        if (!(rp->ssh_sbcl & SSH_BSY)) {
                    989:                                printf ("Yikes, it's not busy now!\n");
                    990: #if 0
                    991:                                *status = -1;
                    992:                                if (!TAILQ_EMPTY(&sc->nexus_list))
                    993:                                        rp->ssh_dsp = sc->sc_scriptspa + Ent_wait_reselect;
                    994:                                return 1;
                    995: #endif
                    996:                        }
                    997: /*                     rp->ssh_dcntl |= SSH_DCNTL_STD;*/
                    998:                        return (0);
                    999: #ifdef DDB
                   1000:                        Debugger();
                   1001: #endif
                   1002:                }
                   1003: #endif
                   1004:                *status = -1;
                   1005:                acb->xs->error = XS_SELTIMEOUT;
                   1006:                if (!TAILQ_EMPTY(&sc->nexus_list))
                   1007:                        rp->ssh_dsp = sc->sc_scriptspa + Ent_wait_reselect;
                   1008:                return 1;
                   1009:        }
                   1010:        if (acb)
                   1011:                target = acb->xs->sc_link->target;
                   1012:        else
                   1013:                target = 7;
                   1014:        if (sstat0 & SSH_SSTAT0_UDC) {
                   1015: #ifdef DEBUG
                   1016:                if (acb == NULL)
                   1017:                        printf("%s: Unexpected disconnect with no active command?\n",
                   1018:                                         sc->sc_dev.dv_xname);
                   1019:                printf ("%s: target %d disconnected unexpectedly\n",
                   1020:                                  sc->sc_dev.dv_xname, target);
                   1021: #endif
                   1022: #if 0
                   1023:                sshabort (sc, rp, "sshchkintr");
                   1024: #endif
                   1025:                *status = STS_BUSY;
                   1026:                if (!TAILQ_EMPTY(&sc->nexus_list))
                   1027:                        rp->ssh_dsp = sc->sc_scriptspa + Ent_wait_reselect;
                   1028:                return 1;
                   1029:        }
                   1030:        if (dstat & SSH_DSTAT_SIR && (rp->ssh_dsps == 0xff01 ||
                   1031:                                                                                         rp->ssh_dsps == 0xff02)) {
                   1032: #ifdef DEBUG
                   1033:                if (ssh_debug & 0x100)
                   1034:                        printf ("%s: ID %02x disconnected TEMP %x (+%x) curbuf %x curlen %x buf %x len %x dfifo %x dbc %x sstat1 %x starts %d acb %x\n",
                   1035:                                          sc->sc_dev.dv_xname, 1 << target, rp->ssh_temp,
                   1036:                                          rp->ssh_temp ? rp->ssh_temp - sc->sc_scriptspa : 0,
                   1037:                                          acb->iob_curbuf, acb->iob_curlen,
                   1038:                                          acb->ds.chain[0].databuf, acb->ds.chain[0].datalen, dfifo, dbc, sstat1, sshstarts, acb);
                   1039: #endif
                   1040:                if (acb == NULL) {
                   1041:                        printf("%s: Disconnect with no active command?\n",
                   1042:                                         sc->sc_dev.dv_xname);
                   1043:                        return (0);
                   1044:                }
                   1045:                /*
                   1046:                 * XXXX need to update iob_curbuf/iob_curlen to reflect
                   1047:                 * current data transferred.  If device disconnected in
                   1048:                 * the middle of a DMA block, they should already be set
                   1049:                 * by the phase change interrupt.  If the disconnect
                   1050:                 * occurs on a DMA block boundary, we have to figure out
                   1051:                 * which DMA block it was.
                   1052:                 */
                   1053:                if (acb->iob_len && rp->ssh_temp) {
                   1054:                        int n = rp->ssh_temp - sc->sc_scriptspa;
                   1055:
                   1056:                        if (acb->iob_curlen && acb->iob_curlen != acb->ds.chain[0].datalen)
                   1057:                                printf("%s: iob_curbuf/len already set? n %x iob %lx/%lx chain[0] %p/%lx\n",
                   1058:                                                 sc->sc_dev.dv_xname, n, acb->iob_curbuf, acb->iob_curlen,
                   1059:                                                 acb->ds.chain[0].databuf, acb->ds.chain[0].datalen);
                   1060:                        if (n < Ent_datain)
                   1061:                                n = (n - Ent_dataout) / 16;
                   1062:                        else
                   1063:                                n = (n - Ent_datain) / 16;
                   1064:                        if (n <= 0 || n >= DMAMAXIO)
                   1065:                                printf("TEMP invalid %d\n", n);
                   1066:                        else {
                   1067:                                acb->iob_curbuf = (u_long)acb->ds.chain[n].databuf;
                   1068:                                acb->iob_curlen = acb->ds.chain[n].datalen;
                   1069:                        }
                   1070: #ifdef DEBUG
                   1071:                        if (ssh_debug & 0x100) {
                   1072:                                printf("%s: TEMP offset %d", sc->sc_dev.dv_xname, n);
                   1073:                                printf(" curbuf %x curlen %x\n", acb->iob_curbuf,
                   1074:                                                 acb->iob_curlen);
                   1075:                        }
                   1076: #endif
                   1077:                }
                   1078:                /*
                   1079:                 * If data transfer was interrupted by disconnect, iob_curbuf
                   1080:                 * and iob_curlen should reflect the point of interruption.
                   1081:                 * Adjust the DMA chain so that the data transfer begins
                   1082:                 * at the appropriate place upon reselection.
                   1083:                 * XXX This should only be done on save data pointer message?
                   1084:                 */
                   1085:                if (acb->iob_curlen) {
                   1086:                        int i, j;
                   1087:
                   1088: #ifdef DEBUG
                   1089:                        if (ssh_debug & 0x100)
                   1090:                                printf ("%s: adjusting DMA chain\n",
                   1091:                                                  sc->sc_dev.dv_xname);
                   1092:                        if (rp->ssh_dsps == 0xff02)
                   1093:                                printf ("%s: ID %02x disconnected without Save Data Pointers\n",
                   1094:                                                  sc->sc_dev.dv_xname, 1 << target);
                   1095: #endif
                   1096:                        for (i = 0; i < DMAMAXIO; ++i) {
                   1097:                                if (acb->ds.chain[i].datalen == 0)
                   1098:                                        break;
                   1099:                                if (acb->iob_curbuf >= (long)acb->ds.chain[i].databuf &&
                   1100:                                         acb->iob_curbuf < (long)(acb->ds.chain[i].databuf +
                   1101:                                                                                                          acb->ds.chain[i].datalen))
                   1102:                                        break;
                   1103:                        }
                   1104:                        if (i >= DMAMAXIO || acb->ds.chain[i].datalen == 0)
                   1105:                                printf("couldn't find saved data pointer\n");
                   1106: #ifdef DEBUG
                   1107:                        if (ssh_debug & 0x100)
                   1108:                                printf("  chain[0]: %x/%x -> %x/%x\n",
                   1109:                                                 acb->ds.chain[0].databuf,
                   1110:                                                 acb->ds.chain[0].datalen,
                   1111:                                                 acb->iob_curbuf,
                   1112:                                                 acb->iob_curlen);
                   1113: #endif
                   1114:                        acb->ds.chain[0].databuf = (char *)acb->iob_curbuf;
                   1115:                        acb->ds.chain[0].datalen = acb->iob_curlen;
                   1116:                        for (j = 1, ++i; i < DMAMAXIO && acb->ds.chain[i].datalen; ++i, ++j) {
                   1117: #ifdef DEBUG
                   1118:                                if (ssh_debug & 0x100)
                   1119:                                        printf("  chain[%d]: %x/%x -> %x/%x\n", j,
                   1120:                                                         acb->ds.chain[j].databuf,
                   1121:                                                         acb->ds.chain[j].datalen,
                   1122:                                                         acb->ds.chain[i].databuf,
                   1123:                                                         acb->ds.chain[i].datalen);
                   1124: #endif
                   1125:                                acb->ds.chain[j].databuf = acb->ds.chain[i].databuf;
                   1126:                                acb->ds.chain[j].datalen = acb->ds.chain[i].datalen;
                   1127:                        }
                   1128:                        if (j < DMAMAXIO)
                   1129:                                acb->ds.chain[j++].datalen = 0;
                   1130:                        dma_cachectl((caddr_t)&acb->ds.chain,
                   1131:                            j * sizeof(acb->ds.chain[0]));
                   1132:                }
                   1133:                ++sc->sc_tinfo[target].dconns;
                   1134:                /*
                   1135:                 * add nexus to waiting list
                   1136:                 * clear nexus
                   1137:                 * try to start another command for another target/lun
                   1138:                 */
                   1139:                acb->status = sc->sc_flags & SSH_INTSOFF;
                   1140:                TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain);
                   1141:                sc->sc_nexus = NULL;            /* no current device */
                   1142:                /* start script to wait for reselect */
                   1143:                if (sc->sc_nexus == NULL)
                   1144:                        rp->ssh_dsp = sc->sc_scriptspa + Ent_wait_reselect;
                   1145: /* XXXX start another command ? */
                   1146:                if (!TAILQ_EMPTY(&sc->ready_list))
                   1147:                        ssh_sched(sc);
                   1148:                return (0);
                   1149:        }
                   1150:        if (dstat & SSH_DSTAT_SIR && rp->ssh_dsps == 0xff03) {
                   1151:                int reselid = rp->ssh_scratch & 0x7f;
                   1152:                int reselun = rp->ssh_sfbr & 0x07;
                   1153:
                   1154:                sc->sc_sstat1 = rp->ssh_sbcl;   /* XXXX save current SBCL */
                   1155: #ifdef DEBUG
                   1156:                if (ssh_debug & 0x100)
                   1157:                        printf ("%s: target ID %02x reselected dsps %x\n",
                   1158:                                          sc->sc_dev.dv_xname, reselid,
                   1159:                                          rp->ssh_dsps);
                   1160:                if ((rp->ssh_sfbr & 0x80) == 0)
                   1161:                        printf("%s: Reselect message in was not identify: %x\n",
                   1162:                                         sc->sc_dev.dv_xname, rp->ssh_sfbr);
                   1163: #endif
                   1164:                if (sc->sc_nexus) {
                   1165: #ifdef DEBUG
                   1166:                        if (ssh_debug & 0x100)
                   1167:                                printf ("%s: reselect ID %02x w/active\n",
                   1168:                                                  sc->sc_dev.dv_xname, reselid);
                   1169: #endif
                   1170:                        TAILQ_INSERT_HEAD(&sc->ready_list, sc->sc_nexus, chain);
                   1171:                        sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target].lubusy
                   1172:                        &= ~(1 << sc->sc_nexus->xs->sc_link->lun);
                   1173:                        --sc->sc_active;
                   1174:                }
                   1175:                /*
                   1176:                 * locate acb of reselecting device
                   1177:                 * set sc->sc_nexus to acb
                   1178:                 */
                   1179:                TAILQ_FOREACH(acb, &sc->nexus_list, chain) {
                   1180:                        if (reselid != (acb->ds.scsi_addr >> 16) ||
                   1181:                                 reselun != (acb->msgout[0] & 0x07))
                   1182:                                continue;
                   1183:                        TAILQ_REMOVE(&sc->nexus_list, acb, chain);
                   1184:                        sc->sc_nexus = acb;
                   1185:                        sc->sc_flags |= acb->status;
                   1186:                        acb->status = 0;
                   1187:                        dma_cachectl(&acb->stat[0], 1); /* XXX necessary? */
                   1188:                        rp->ssh_dsa = kvtop((vaddr_t)&acb->ds);
                   1189:                        rp->ssh_sxfer = sc->sc_sync[acb->xs->sc_link->target].sxfer;
                   1190:                        rp->ssh_sbcl = sc->sc_sync[acb->xs->sc_link->target].sbcl;
                   1191:                        break;
                   1192:                }
                   1193:                if (acb == NULL) {
                   1194:                        printf("%s: target ID %02x reselect nexus_list %p\n",
                   1195:                                         sc->sc_dev.dv_xname, reselid,
                   1196:                                         TAILQ_FIRST(&sc->nexus_list));
                   1197:                        panic("unable to find reselecting device");
                   1198:                }
                   1199:                dma_cachectl((caddr_t)acb, sizeof(*acb));
                   1200:                rp->ssh_temp = 0;
                   1201:                rp->ssh_dcntl |= SSH_DCNTL_STD;
                   1202:                return (0);
                   1203:        }
                   1204:        if (dstat & SSH_DSTAT_SIR && rp->ssh_dsps == 0xff04) {
                   1205: #ifdef DEBUG
                   1206:                u_short ctest2 = rp->ssh_ctest2;
                   1207:
                   1208:                /* reselect was interrupted (by Sig_P or select) */
                   1209:                if (ssh_debug & 0x100 ||
                   1210:                         (ctest2 & SSH_CTEST2_SIGP) == 0)
                   1211:                        printf ("%s: reselect interrupted (Sig_P?) scntl1 %x ctest2 %x
                   1212:                                          sfbr %x istat %x/%x\n", sc->sc_dev.dv_xname, rp->ssh_scntl1,
                   1213:                                          ctest2, rp->ssh_sfbr, istat, rp->ssh_istat);
                   1214: #endif
                   1215:                /* XXX assumes it was not select */
                   1216:                if (sc->sc_nexus == NULL) {
                   1217:                        printf("%s: reselect interrupted, sc_nexus == NULL\n",
                   1218:                                         sc->sc_dev.dv_xname);
                   1219: #if 0
                   1220:                        ssh_dump(sc);
                   1221: #ifdef DDB
                   1222:                        Debugger();
                   1223: #endif
                   1224: #endif
                   1225:                        rp->ssh_dcntl |= SSH_DCNTL_STD;
                   1226:                        return (0);
                   1227:                }
                   1228:                target = sc->sc_nexus->xs->sc_link->target;
                   1229:                rp->ssh_temp = 0;
                   1230:                rp->ssh_dsa = kvtop((vaddr_t)&sc->sc_nexus->ds);
                   1231:                rp->ssh_sxfer = sc->sc_sync[target].sxfer;
                   1232:                rp->ssh_sbcl = sc->sc_sync[target].sbcl;
                   1233:                rp->ssh_dsp = sc->sc_scriptspa;
                   1234:                return (0);
                   1235:        }
                   1236:        if (dstat & SSH_DSTAT_SIR && rp->ssh_dsps == 0xff06) {
                   1237:                if (acb == NULL)
                   1238:                        printf("%s: Bad message-in with no active command?\n",
                   1239:                                         sc->sc_dev.dv_xname);
                   1240:                /* Unrecognized message in byte */
                   1241:                dma_cachectl(&acb->msg[1],1);
                   1242:                printf ("%s: Unrecognized message in data sfbr %x msg %x sbcl %x\n",
                   1243:                                  sc->sc_dev.dv_xname, rp->ssh_sfbr, acb->msg[1], rp->ssh_sbcl);
                   1244:                /* what should be done here? */
                   1245:                rp->ssh_dsp = sc->sc_scriptspa + Ent_switch;
                   1246:                return (0);
                   1247:        }
                   1248:        if (dstat & SSH_DSTAT_SIR && rp->ssh_dsps == 0xff0a) {
                   1249:                /* Status phase wasn't followed by message in phase? */
                   1250:                printf ("%s: Status phase not followed by message in phase? sbcl %x sbdl %x\n",
                   1251:                                  sc->sc_dev.dv_xname, rp->ssh_sbcl, rp->ssh_sbdl);
                   1252:                if (rp->ssh_sbcl == 0xa7) {
                   1253:                        /* It is now, just continue the script? */
                   1254:                        rp->ssh_dcntl |= SSH_DCNTL_STD;
                   1255:                        return (0);
                   1256:                }
                   1257:        }
                   1258:        if (sstat0 == 0 && dstat & SSH_DSTAT_SIR) {
                   1259:                dma_cachectl(&acb->stat[0], 1);
                   1260:                dma_cachectl(&acb->msg[0], 1);
                   1261:                printf ("SSH interrupt: %lx sts %x msg %x %x sbcl %x\n",
                   1262:                                  rp->ssh_dsps, acb->stat[0], acb->msg[0], acb->msg[1],
                   1263:                                  rp->ssh_sbcl);
                   1264:                sshreset (sc);
                   1265:                *status = -1;
                   1266:                return 0;       /* sshreset has cleaned up */
                   1267:        }
                   1268:        if (sstat0 & SSH_SSTAT0_SGE)
                   1269:                printf ("SSH: SCSI Gross Error\n");
                   1270:        if (sstat0 & SSH_SSTAT0_PAR)
                   1271:                printf ("SSH: Parity Error\n");
                   1272:        if (dstat & SSH_DSTAT_IID)
                   1273:                printf ("SSH: Invalid instruction detected\n");
                   1274:        bad_phase:
                   1275:        /*
                   1276:         * temporary panic for unhandled conditions
                   1277:         * displays various things about the 53C710 status and registers
                   1278:         * then panics.
                   1279:         * XXXX need to clean this up to print out the info, reset, and continue
                   1280:         */
                   1281:        printf ("sshchkintr: target %x ds %p\n", target, &acb->ds);
                   1282:        printf ("scripts %lx ds %lx rp %lx dsp %lx dcmd %lx\n", sc->sc_scriptspa,
                   1283:          kvtop((vaddr_t)&acb->ds), kvtop((vaddr_t)rp), rp->ssh_dsp,
                   1284:          *((long *)&rp->ssh_dcmd));
                   1285:        printf ("sshchkintr: istat %x dstat %x sstat0 %x dsps %lx "
                   1286:                          "dsa %lx sbcl %x sts %x msg %x %x sfbr %x\n",
                   1287:                          istat, dstat, sstat0, rp->ssh_dsps, rp->ssh_dsa,
                   1288:                          rp->ssh_sbcl, acb->stat[0], acb->msg[0], acb->msg[1],
                   1289:                          rp->ssh_sfbr);
                   1290: #ifdef DEBUG
                   1291:        if (ssh_debug & 0x20)
                   1292:                panic("sshchkintr: **** temp ****");
                   1293: #ifdef DDB
                   1294:        /* Debugger(); */
                   1295: #endif
                   1296: #endif
                   1297:        sshreset (sc);          /* hard reset */
                   1298:        *status = -1;
                   1299:        return 0;               /* sshreset cleaned up */
                   1300: }
                   1301:
                   1302: void
                   1303: ssh_select(sc)
                   1304: struct ssh_softc *sc;
                   1305: {
                   1306:        ssh_regmap_p rp;
                   1307:        struct ssh_acb *acb = sc->sc_nexus;
                   1308:
                   1309: #ifdef DEBUG
                   1310:        if (ssh_debug & 1)
                   1311:                printf ("%s: select ", sc->sc_dev.dv_xname);
                   1312: #endif
                   1313:
                   1314:        rp = sc->sc_sshp;
                   1315:        if (acb->xs->flags & SCSI_POLL || ssh_no_dma) {
                   1316:                sc->sc_flags |= SSH_INTSOFF;
                   1317:                sc->sc_flags &= ~SSH_INTDEFER;
                   1318:                if ((rp->ssh_istat & 0x08) == 0) {
                   1319:                        rp->ssh_sien = 0;
                   1320:                        rp->ssh_dien = 0;
                   1321:                }
                   1322: #if 0
                   1323:        } else if ((sc->sc_flags & SSH_INTDEFER) == 0) {
                   1324:                sc->sc_flags &= ~SSH_INTSOFF;
                   1325:                if ((rp->ssh_istat & 0x08) == 0) {
                   1326:                        rp->ssh_sien = sc->sc_sien;
                   1327:                        rp->ssh_dien = sc->sc_dien;
                   1328:                }
                   1329: #endif
                   1330:        }
                   1331: #ifdef DEBUG
                   1332:        if (ssh_debug & 1)
                   1333:                printf ("ssh_select: target %x cmd %02x ds %x\n",
                   1334:                                  acb->xs->sc_link->target, acb->cmd.opcode,
                   1335:                                  &sc->sc_nexus->ds);
                   1336: #endif
                   1337:
                   1338:        ssh_start(sc, acb->xs->sc_link->target, acb->xs->sc_link->lun,
                   1339:          (u_char *)&acb->cmd, acb->clen, acb->daddr, acb->dleft);
                   1340:
                   1341:        return;
                   1342: }
                   1343:
                   1344: /*
                   1345:  * 53C710 interrupt handler
                   1346:  */
                   1347: void
                   1348: sshintr(sc)
                   1349:        register struct ssh_softc *sc;
                   1350: {
                   1351:        ssh_regmap_p rp;
                   1352:        register u_char istat, dstat, sstat0;
                   1353:        int status;
                   1354:        int s = splbio();
                   1355:
                   1356:        istat = sc->sc_istat;
                   1357:        if ((istat & (SSH_ISTAT_SIP | SSH_ISTAT_DIP)) == 0) {
                   1358:                splx(s);
                   1359:                return;
                   1360:        }
                   1361:
                   1362:        /* Got a valid interrupt on this device */
                   1363:        rp = sc->sc_sshp;
                   1364:        dstat = sc->sc_dstat;
                   1365:        sstat0 = sc->sc_sstat0;
                   1366:        if (dstat & SSH_DSTAT_SIR)
                   1367:                sc->sc_intcode = rp->ssh_dsps;
                   1368:        sc->sc_istat = 0;
                   1369:
                   1370: #ifdef DEBUG
                   1371:        if (ssh_debug & 1)
                   1372:                printf ("%s: intr istat %x dstat %x sstat0 %x\n",
                   1373:                                  sc->sc_dev.dv_xname, istat, dstat, sstat0);
                   1374:        if (!sc->sc_active) {
                   1375:                printf ("%s: spurious interrupt? istat %x dstat %x sstat0 %x status %x\n",
                   1376:                                  sc->sc_dev.dv_xname, istat, dstat, sstat0, sc->sc_nexus->stat[0]);
                   1377:        }
                   1378: #else
                   1379:        if (!sc->sc_active) {
                   1380:                printf ("%s: spurious interrupt? istat %x dstat %x sstat0 %x status %x\n",
                   1381:                                  sc->sc_dev.dv_xname, istat, dstat, sstat0, sc->sc_nexus->stat[0]);
                   1382:                return;
                   1383:        }
                   1384: #endif
                   1385:
                   1386: #ifdef DEBUG
                   1387:        if (ssh_debug & 5) {
                   1388:                dma_cachectl(&sc->sc_nexus->stat[0], 1);
                   1389:                printf ("%s: intr istat %x dstat %x sstat0 %x dsps %x sbcl %x sts %x msg %x\n",
                   1390:                                  sc->sc_dev.dv_xname, istat, dstat, sstat0,
                   1391:                                  rp->ssh_dsps,  rp->ssh_sbcl,
                   1392:                                  sc->sc_nexus->stat[0], sc->sc_nexus->msg[0]);
                   1393:        }
                   1394: #endif
                   1395:        if (sc->sc_flags & SSH_INTDEFER) {
                   1396:                sc->sc_flags &= ~(SSH_INTDEFER | SSH_INTSOFF);
                   1397:                rp->ssh_sien = sc->sc_sien;
                   1398:                rp->ssh_dien = sc->sc_dien;
                   1399:        }
                   1400:        if (ssh_checkintr (sc, istat, dstat, sstat0, &status)) {
                   1401: #if 1
                   1402:                if (status == 0xff)
                   1403:                        printf ("sshintr: status == 0xff\n");
                   1404: #endif
                   1405:                if ((sc->sc_flags & (SSH_INTSOFF | SSH_INTDEFER)) != SSH_INTSOFF) {
                   1406: #if 0
                   1407:                        if (rp->ssh_sbcl & SSH_BSY) {
                   1408:                                printf ("%s: SCSI bus busy at completion",
                   1409:                                                  sc->sc_dev.dv_xname);
                   1410:                                printf(" targ %d sbcl %02x sfbr %x lcrc %02x dsp +%x\n",
                   1411:                                                 sc->sc_nexus->xs->sc_link->target,
                   1412:                                                 rp->ssh_sbcl, rp->ssh_sfbr, rp->ssh_lcrc,
                   1413:                                                 rp->ssh_dsp - sc->sc_scriptspa);
                   1414:                        }
                   1415: #endif
                   1416:                        ssh_scsidone(sc->sc_nexus, sc->sc_nexus->stat[0]);
                   1417:                }
                   1418:        }
                   1419:        splx(s);
                   1420: }
                   1421:
                   1422: /*
                   1423:  * This is based on the Progressive Peripherals 33MHz Zeus driver and will
                   1424:  * not be correct for other 53c710 boards.
                   1425:  *
                   1426:  */
                   1427: void
                   1428: scsi_period_to_ssh (sc, target)
                   1429:        struct ssh_softc *sc;
                   1430:        int target;
                   1431: {
                   1432:        int period, offset, sxfer, sbcl;
                   1433:
                   1434:        period = sc->sc_nexus->msg[4];
                   1435:        offset = sc->sc_nexus->msg[5];
                   1436:        for (sbcl = 1; sbcl < 4; ++sbcl) {
                   1437:                sxfer = (period * 4 - 1) / sc->sc_tcp[sbcl] - 3;
                   1438:                if (sxfer >= 0 && sxfer <= 7)
                   1439:                        break;
                   1440:        }
                   1441:        if (sbcl > 3) {
                   1442:                printf("ssh_sync: unable to compute sync params for period %dns\n",
                   1443:                                 period * 4);
                   1444:                /*
                   1445:                 * XXX need to pick a value we can do and renegotiate
                   1446:                 */
                   1447:                sxfer = sbcl = 0;
                   1448:        } else
                   1449:                sxfer   = (sxfer << 4) | ((offset <= SSH_MAX_OFFSET) ?
                   1450:                                                                                offset : SSH_MAX_OFFSET);
                   1451:        sc->sc_sync[target].sxfer = sxfer;
                   1452:        sc->sc_sync[target].sbcl = sbcl;
                   1453: #ifdef DEBUG
                   1454:        printf ("ssh sync: ssh_sxfr %02x, ssh_sbcl %02x\n", sxfer, sbcl);
                   1455: #endif
                   1456: }
                   1457:
                   1458: #ifdef DEBUG
                   1459:
                   1460: #if SSH_TRACE_SIZE
                   1461: void
                   1462: ssh_dump_trace()
                   1463: {
                   1464:        int i;
                   1465:
                   1466:        printf("ssh trace: next index %d\n", ssh_trix);
                   1467:        i = ssh_trix;
                   1468:        do {
                   1469:                printf("%3d: '%c' %02x %02x %02x\n", i, ssh_trbuf[i],
                   1470:                                 ssh_trbuf[i + 1], ssh_trbuf[i + 2], ssh_trbuf[i + 3]);
                   1471:                i = (i + 4) & (SSH_TRACE_SIZE - 1);
                   1472:        } while (i != ssh_trix);
                   1473: }
                   1474: #endif
                   1475:
                   1476: void
                   1477: ssh_dump_acb(acb)
                   1478: struct ssh_acb *acb;
                   1479: {
                   1480:        u_char *b = (u_char *) &acb->cmd;
                   1481:        int i;
                   1482:
                   1483: #if SSH_TRACE_SIZE
                   1484:        ssh_dump_trace();
                   1485: #endif
                   1486:        printf("acb@%x ", acb);
                   1487:        if (acb->xs == NULL) {
                   1488:                printf("<unused>\n");
                   1489:                return;
                   1490:        }
                   1491:        printf("(%d:%d) flags %2x clen %2d cmd ", acb->xs->sc_link->target,
                   1492:                         acb->xs->sc_link->lun, acb->flags, acb->clen);
                   1493:        for (i = acb->clen; i; --i)
                   1494:                printf(" %02x", *b++);
                   1495:        printf("\n");
                   1496:        printf("  xs: %08x data %8x:%04x ", acb->xs, acb->xs->data,
                   1497:                         acb->xs->datalen);
                   1498:        printf("va %8x:%04x ", acb->iob_buf, acb->iob_len);
                   1499:        printf("cur %8x:%04x\n", acb->iob_curbuf, acb->iob_curlen);
                   1500: }
                   1501:
                   1502: void
                   1503: ssh_dump(sc)
                   1504: struct ssh_softc *sc;
                   1505: {
                   1506:        struct ssh_acb *acb;
                   1507:        ssh_regmap_p rp = sc->sc_sshp;
                   1508:        int s;
                   1509:        int i;
                   1510:
                   1511:        s = splbio();
                   1512:        printf("%s@%x regs %x istat %x\n",
                   1513:                         sc->sc_dev.dv_xname, sc, rp, rp->ssh_istat);
                   1514:        if (acb = TAILQ_FIRST(&sc->free_list)) {
                   1515:                printf("Free list:\n");
                   1516:                while (acb) {
                   1517:                        ssh_dump_acb(acb);
                   1518:                        acb = TAILQ_NEXT(acb, chain);
                   1519:                }
                   1520:        }
                   1521:        if (acb = TAILQ_FIRST(&sc->ready_list)) {
                   1522:                printf("Ready list:\n");
                   1523:                while (acb) {
                   1524:                        ssh_dump_acb(acb);
                   1525:                        acb = TAILQ_NEXT(acb, chain);
                   1526:                }
                   1527:        }
                   1528:        if (acb = TAILQ_FIRST(&sc->nexus_list)) {
                   1529:                printf("Nexus list:\n");
                   1530:                while (acb) {
                   1531:                        ssh_dump_acb(acb);
                   1532:                        acb = TAILQ_NEXT(acb, chain);
                   1533:                }
                   1534:        }
                   1535:        if (sc->sc_nexus) {
                   1536:                printf("Nexus:\n");
                   1537:                ssh_dump_acb(sc->sc_nexus);
                   1538:        }
                   1539:        for (i = 0; i < 8; ++i) {
                   1540:                if (sc->sc_tinfo[i].cmds > 2) {
                   1541:                        printf("tgt %d: cmds %d disc %d senses %d lubusy %x\n",
                   1542:                                         i, sc->sc_tinfo[i].cmds,
                   1543:                                         sc->sc_tinfo[i].dconns,
                   1544:                                         sc->sc_tinfo[i].senses,
                   1545:                                         sc->sc_tinfo[i].lubusy);
                   1546:                }
                   1547:        }
                   1548:        splx(s);
                   1549: }
                   1550: #endif

CVSweb