[BACK]Return to sbic.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / mvme68k / dev

Annotation of src/sys/arch/mvme68k/dev/sbic.c, Revision 1.28

1.28    ! lukem       1: /*     $NetBSD: sbic.c,v 1.27 2005/12/11 12:18:17 christos Exp $       */
1.24      agc         2:
                      3: /*
                      4:  * Copyright (c) 1990 The Regents of the University of California.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to Berkeley by
                      8:  * Van Jacobson of Lawrence Berkeley Laboratory.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. Neither the name of the University nor the names of its contributors
                     19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  *
                     34:  *  @(#)scsi.c  7.5 (Berkeley) 5/4/91
                     35:  */
1.1       chuck      36:
                     37: /*
                     38:  * Changes Copyright (c) 1996 Steve Woodford
                     39:  * Original Copyright (c) 1994 Christian E. Hopps
                     40:  *
                     41:  * This code is derived from software contributed to Berkeley by
                     42:  * Van Jacobson of Lawrence Berkeley Laboratory.
                     43:  *
                     44:  * Redistribution and use in source and binary forms, with or without
                     45:  * modification, are permitted provided that the following conditions
                     46:  * are met:
                     47:  * 1. Redistributions of source code must retain the above copyright
                     48:  *    notice, this list of conditions and the following disclaimer.
                     49:  * 2. Redistributions in binary form must reproduce the above copyright
                     50:  *    notice, this list of conditions and the following disclaimer in the
                     51:  *    documentation and/or other materials provided with the distribution.
                     52:  * 3. All advertising materials mentioning features or use of this software
                     53:  *    must display the following acknowledgement:
                     54:  *  This product includes software developed by the University of
                     55:  *  California, Berkeley and its contributors.
                     56:  * 4. Neither the name of the University nor the names of its contributors
                     57:  *    may be used to endorse or promote products derived from this software
                     58:  *    without specific prior written permission.
                     59:  *
                     60:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     61:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     62:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     63:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     64:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     65:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     66:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     67:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     68:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     69:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     70:  * SUCH DAMAGE.
                     71:  *
                     72:  *  @(#)scsi.c  7.5 (Berkeley) 5/4/91
                     73:  */
                     74:
                     75: /*
                     76:  * Steve Woodford (SCW), Apr, 1996
                     77:  * MVME147S WD33C93 Scsi Bus Interface Controller driver,
                     78:  *
                     79:  * Basically a de-loused and tidied up version of the Amiga AMD 33C93 driver.
                     80:  *
                     81:  * The original driver used features which required at least a WD33C93A
                     82:  * chip. The '147 has the original WD33C93 chip (no 'A' suffix).
                     83:  *
                     84:  * This version of the driver is pretty well generic, so should work with
                     85:  * any flavour of WD33C93 chip.
                     86:  */
1.23      lukem      87:
                     88: #include <sys/cdefs.h>
1.28    ! lukem      89: __KERNEL_RCSID(0, "$NetBSD: sbic.c,v 1.27 2005/12/11 12:18:17 christos Exp $");
1.23      lukem      90:
1.7       jonathan   91: #include "opt_ddb.h"
1.1       chuck      92:
                     93: #include <sys/param.h>
                     94: #include <sys/systm.h>
                     95: #include <sys/device.h>
                     96: #include <sys/kernel.h> /* For hz */
                     97: #include <sys/disklabel.h>
                     98: #include <sys/buf.h>
1.12      scw        99:
1.6       bouyer    100: #include <dev/scsipi/scsi_all.h>
                    101: #include <dev/scsipi/scsipi_all.h>
                    102: #include <dev/scsipi/scsiconf.h>
1.12      scw       103:
1.15      mrg       104: #include <uvm/uvm_extern.h>
1.12      scw       105:
1.1       chuck     106: #include <mvme68k/mvme68k/isr.h>
                    107: #include <mvme68k/dev/dmavar.h>
                    108: #include <mvme68k/dev/sbicreg.h>
                    109: #include <mvme68k/dev/sbicvar.h>
                    110:
                    111:
                    112: /*
                    113:  * Since I can't find this in any other header files
                    114:  */
                    115: #define SCSI_PHASE(reg) (reg&0x07)
                    116:
                    117: /*
                    118:  * SCSI delays
                    119:  * In u-seconds, primarily for state changes on the SPC.
                    120:  */
                    121: #define SBIC_CMD_WAIT   50000   /* wait per step of 'immediate' cmds */
                    122: #define SBIC_DATA_WAIT  50000   /* wait per data in/out step */
                    123: #define SBIC_INIT_WAIT  50000   /* wait per step (both) during init */
                    124:
                    125: /*
                    126:  * Convenience macro for waiting for a particular sbic event
                    127:  */
                    128: #define SBIC_WAIT(regs, until, timeo) sbicwait(regs, until, timeo, __LINE__)
                    129:
                    130: int     sbicicmd            __P((struct sbic_softc *, void *, int, void *, int));
1.6       bouyer    131: int     sbicgo              __P((struct sbic_softc *, struct scsipi_xfer *));
                    132: int     sbicdmaok           __P((struct sbic_softc *, struct scsipi_xfer *));
1.1       chuck     133: int     sbicwait            __P((sbic_regmap_p, u_char, int , int));
                    134: int     sbiccheckdmap       __P((void *, u_long, u_long));
                    135: u_char  sbicselectbus       __P((struct sbic_softc *));
                    136: int     sbicxfout           __P((sbic_regmap_p, int, void *));
                    137: int     sbicxfin            __P((sbic_regmap_p, int, void *));
                    138: int     sbicfromscsiperiod  __P((struct sbic_softc *, int));
                    139: int     sbictoscsiperiod    __P((struct sbic_softc *, int));
                    140: int     sbicpoll            __P((struct sbic_softc *));
                    141: int     sbicnextstate       __P((struct sbic_softc *, u_char, u_char));
                    142: int     sbicmsgin           __P((struct sbic_softc *));
1.26      scw       143: int     sbicabort           __P((struct sbic_softc *, const char *));
1.1       chuck     144: void    sbicxfdone          __P((struct sbic_softc *));
                    145: void    sbicerror           __P((struct sbic_softc *,u_char));
                    146: void    sbicreset           __P((struct sbic_softc *));
                    147: void    sbic_scsidone       __P((struct sbic_acb *, int));
                    148: void    sbic_sched          __P((struct sbic_softc *));
                    149: void    sbic_save_ptrs      __P((struct sbic_softc *));
                    150: void    sbic_load_ptrs      __P((struct sbic_softc *));
                    151:
                    152: /*
                    153:  * Synch xfer parameters, and timing conversions
                    154:  */
                    155: int     sbic_min_period = SBIC_SYN_MIN_PERIOD;  /* in cycles = f(ICLK,FSn) */
                    156: int     sbic_max_offset = SBIC_SYN_MAX_OFFSET;  /* pure number */
                    157: int     sbic_cmd_wait   = SBIC_CMD_WAIT;
                    158: int     sbic_data_wait  = SBIC_DATA_WAIT;
                    159: int     sbic_init_wait  = SBIC_INIT_WAIT;
                    160:
                    161: /*
                    162:  * was broken before.. now if you want this you get it for all drives
                    163:  * on sbic controllers.
                    164:  */
                    165: u_char  sbic_inhibit_sync[8];
                    166: int     sbic_enable_reselect     = 1;   /* Allow Disconnect / Reselect */
                    167: int     sbic_no_dma              = 0;   /* Use PIO transfers instead of DMA */
                    168: int     sbic_parallel_operations = 1;   /* Allow command queues */
                    169:
                    170: /*
                    171:  * Some useful stuff for debugging purposes
                    172:  */
                    173: #ifdef DEBUG
                    174: int     sbicdma_ops     = 0;    /* total DMA operations */
                    175: int     sbicdma_hits    = 0;    /* number of DMA chains that were contiguous */
                    176: int     sbicdma_misses  = 0;    /* number of DMA chains that were not contiguous */
                    177: int     sbicdma_saves   = 0;
                    178:
1.5       christos  179: #define QPRINTF(a) if (sbic_debug > 1) printf a
1.1       chuck     180:
                    181: int     sbic_debug      = 0;    /* Debug all chip related things */
                    182: int     sync_debug      = 0;    /* Debug all Synchronous Scsi related things */
                    183: int     reselect_debug  = 0;    /* Debug all reselection related things */
                    184: int     data_pointer_debug = 0; /* Debug Data Pointer related things */
                    185:
                    186: void    sbictimeout __P((struct sbic_softc *dev));
                    187:
                    188: #else
                    189: #define QPRINTF(a)  /* */
                    190: #endif
                    191:
                    192:
                    193: /*
                    194:  * default minphys routine for sbic based controllers
                    195:  */
                    196: void
                    197: sbic_minphys(bp)
                    198:     struct buf *bp;
                    199: {
                    200:     /*
                    201:      * No max transfer at this level.
                    202:      */
                    203:     minphys(bp);
                    204: }
                    205:
                    206:
                    207: /*
                    208:  * Save DMA pointers.  Take into account partial transfer. Shut down DMA.
                    209:  */
                    210: void
                    211: sbic_save_ptrs(dev)
                    212:     struct sbic_softc   *dev;
                    213: {
                    214:     sbic_regmap_p       regs;
                    215:     struct sbic_acb*    acb;
                    216:     int                 count,
                    217:                         asr,
                    218:                         s;
                    219:
                    220:     /*
                    221:      * Only need to save pointers if DMA was active...
                    222:      */
                    223:     if ( dev->sc_cur == NULL || (dev->sc_flags & SBICF_INDMA) == 0 )
                    224:         return;
                    225:
                    226:     regs = dev->sc_sbicp;
                    227:
                    228:     s = splbio();
                    229:
                    230:     /*
                    231:      * Wait until WD chip is idle
                    232:      */
                    233:     do {
                    234:         GET_SBIC_asr(regs, asr);
                    235:         if( asr & SBIC_ASR_DBR ) {
1.5       christos  236:             printf("sbic_save_ptrs: asr %02x canceled!\n", asr);
1.1       chuck     237:             splx(s);
                    238:             return;
                    239:         }
                    240:     } while( asr & (SBIC_ASR_BSY|SBIC_ASR_CIP) );
                    241:
                    242:
                    243:     /*
                    244:      * Save important state.
                    245:      * must be done before dmastop
                    246:      */
                    247:     acb            = dev->sc_nexus;
                    248:     acb->sc_dmacmd = dev->sc_dmacmd;
                    249:
                    250:     /*
                    251:      * Fetch the residual count
                    252:      */
                    253:     SBIC_TC_GET(regs, count);
                    254:
                    255:     /*
                    256:      * Shut down DMA
                    257:      */
                    258:     dev->sc_dmastop(dev);
                    259:
                    260:     /*
                    261:      * No longer in DMA
                    262:      */
                    263:     dev->sc_flags &= ~SBICF_INDMA;
                    264:
                    265:     /*
                    266:      * Ensure the WD chip is back in polled I/O mode, with nothing to
                    267:      * transfer.
                    268:      */
                    269:     SBIC_TC_PUT(regs, 0);
                    270:     SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
                    271:
                    272:     /*
                    273:      * Update current count...
                    274:      */
                    275:     acb->sc_tcnt = count;
                    276:
                    277:     /*
                    278:      * Work out how many bytes were actually transferred
                    279:      */
                    280:     count        = dev->sc_tcnt - count;
                    281:     dev->sc_tcnt = acb->sc_tcnt;
                    282:
                    283:     /*
                    284:      * Fixup partial xfers
                    285:      */
                    286:     acb->sc_kv.dc_addr  += count;
                    287:     acb->sc_kv.dc_count -= count;
                    288:     acb->sc_pa.dc_addr  += count;
                    289:     acb->sc_pa.dc_count -= count >> 1;
                    290:
                    291: #ifdef DEBUG
                    292:     if ( data_pointer_debug )
1.12      scw       293:         printf("save at (%p,%x):%x\n",
1.1       chuck     294:                dev->sc_cur->dc_addr, dev->sc_cur->dc_count,count);
                    295:     sbicdma_saves++;
                    296: #endif
                    297:
                    298:     splx(s);
                    299: }
                    300:
                    301:
                    302: /*
                    303:  * DOES NOT RESTART DMA!!!
                    304:  */
                    305: void
                    306: sbic_load_ptrs(dev)
                    307:     struct sbic_softc   *dev;
                    308: {
                    309:     struct sbic_acb *acb = dev->sc_nexus;
                    310:     int             s;
                    311:
                    312:     if ( acb->sc_kv.dc_count == 0 ) {
                    313:         /*
                    314:          * No data to xfer
                    315:          */
                    316:         return;
                    317:     }
                    318:
                    319:     s = splbio();
                    320:
                    321:     /*
                    322:      * Reset the Scatter-Gather chain
                    323:      */
                    324:     dev->sc_last = dev->sc_cur = &acb->sc_pa;
                    325:
                    326:     /*
                    327:      * Restore the Transfer Count and DMA specific data
                    328:      */
                    329:     dev->sc_tcnt   = acb->sc_tcnt;
                    330:     dev->sc_dmacmd = acb->sc_dmacmd;
                    331:
                    332: #ifdef DEBUG
                    333:     sbicdma_ops++;
                    334: #endif
                    335:
                    336:     /*
                    337:      * Need to fixup new segment?
                    338:      */
                    339:     if ( dev->sc_tcnt == 0 ) {
                    340:         /*
                    341:          * sc_tcnt == 0 implies end of segment
                    342:          */
                    343:         char    *vaddr, *paddr;
                    344:         int     count;
                    345:
                    346:         /*
                    347:          * do kvm to pa mappings
                    348:          */
                    349:         vaddr = acb->sc_kv.dc_addr;
1.12      scw       350:         paddr = acb->sc_pa.dc_addr = (char *) kvtop((caddr_t)vaddr);
1.1       chuck     351:
1.20      thorpej   352:         for (count = (PAGE_SIZE - ((int)vaddr & PGOFSET));
1.1       chuck     353:              count < acb->sc_kv.dc_count &&
1.12      scw       354:              (char*)kvtop((caddr_t)(vaddr + count + 4)) == paddr + count + 4;
1.20      thorpej   355:              count += PAGE_SIZE)
1.1       chuck     356:             ;   /* Do nothing */
                    357:
                    358:         /*
                    359:          * If it's all contiguous...
                    360:          */
                    361:         if ( count > acb->sc_kv.dc_count ) {
                    362:             count = acb->sc_kv.dc_count;
                    363: #ifdef  DEBUG
                    364:             sbicdma_hits++;
                    365: #endif
                    366:         }
                    367: #ifdef  DEBUG
                    368:         else
                    369:             sbicdma_misses++;
                    370: #endif
                    371:
                    372:         acb->sc_tcnt        = count;
                    373:         acb->sc_pa.dc_count = count >> 1;
                    374:
                    375: #ifdef DEBUG
                    376:         if ( data_pointer_debug )
1.12      scw       377:             printf("DMA recalc:kv(%p,%x)pa(%p,%lx)\n", acb->sc_kv.dc_addr,
1.1       chuck     378:                                                       acb->sc_kv.dc_count,
                    379:                                                       acb->sc_pa.dc_addr,
                    380:                                                       acb->sc_tcnt);
                    381: #endif
                    382:
                    383:     }
                    384:
                    385:     splx(s);
                    386: }
                    387:
                    388: /*
                    389:  * used by specific sbic controller
                    390:  *
                    391:  * it appears that the higher level code does nothing with LUN's
                    392:  * so I will too.  I could plug it in, however so could they
1.6       bouyer    393:  * in scsi_scsipi_cmd().
1.1       chuck     394:  */
1.16      bouyer    395: void
                    396: sbic_scsi_request(chan, req, arg)
                    397:        struct scsipi_channel *chan;
                    398:        scsipi_adapter_req_t req;
                    399:        void *arg;
                    400: {
1.6       bouyer    401:     struct scsipi_xfer *xs;
1.16      bouyer    402:     struct scsipi_periph *periph;
                    403:     struct sbic_softc   *dev = (void *)chan->chan_adapter->adapt_dev;
1.1       chuck     404:     struct sbic_acb     *acb;
1.16      bouyer    405:     int                 flags, s;
1.1       chuck     406:
1.16      bouyer    407:     switch (req) {
                    408:     case ADAPTER_REQ_RUN_XFER:
                    409:        xs = arg;
                    410:        periph = xs->xs_periph;
                    411:         flags = xs->xs_control;
1.1       chuck     412:
1.16      bouyer    413:         if ( flags & XS_CTL_DATA_UIO )
                    414:             panic("sbic: scsi data uio requested");
1.1       chuck     415:
1.16      bouyer    416:         if ( dev->sc_nexus && (flags & XS_CTL_POLL) )
                    417:             panic("sbic_scsicmd: busy");
1.1       chuck     418:
1.16      bouyer    419:         s = splbio();
1.1       chuck     420:
1.16      bouyer    421:         if ( (acb = dev->free_list.tqh_first) != NULL )
                    422:             TAILQ_REMOVE(&dev->free_list, acb, chain);
1.1       chuck     423:
1.16      bouyer    424:         splx(s);
1.1       chuck     425:
1.16      bouyer    426:         if ( acb == NULL ) {
1.1       chuck     427: #ifdef DEBUG
1.16      bouyer    428:             printf("sbic_scsicmd: unable to queue request for target %d\n",
                    429:                 periph->periph_target);
1.1       chuck     430: #ifdef DDB
1.16      bouyer    431:             Debugger();
1.1       chuck     432: #endif
                    433: #endif
1.16      bouyer    434:             xs->error = XS_RESOURCE_SHORTAGE;
                    435:            scsipi_done(xs);
                    436:             return;
                    437:         }
                    438:
                    439:         if ( flags & XS_CTL_DATA_IN )
                    440:             acb->flags = ACB_ACTIVE | ACB_DATAIN;
                    441:         else
                    442:             acb->flags = ACB_ACTIVE;
1.1       chuck     443:
1.16      bouyer    444:         acb->xs             = xs;
                    445:         acb->clen           = xs->cmdlen;
                    446:         acb->sc_kv.dc_addr  = xs->data;
                    447:         acb->sc_kv.dc_count = xs->datalen;
                    448:         acb->pa_addr        = xs->data ? (char *)kvtop((caddr_t)xs->data) : 0;
1.17      scw       449:         memcpy(&acb->cmd, xs->cmd, xs->cmdlen);
1.1       chuck     450:
1.16      bouyer    451:         if ( flags & XS_CTL_POLL ) {
                    452:             /*
                    453:              * This has major side effects -- it locks up the machine
                    454:              */
                    455:             int stat;
1.1       chuck     456:
1.16      bouyer    457:             s = splbio();
1.1       chuck     458:
1.16      bouyer    459:             dev->sc_flags |= SBICF_ICMD;
1.1       chuck     460:
1.16      bouyer    461:             do {
                    462:                 /*
                    463:                  * If we already had a nexus, while away the time until idle...
                    464:                  * This is likely only to happen if a reselection occurs between
                    465:                  * here and our earlier check for ICMD && sc_nexus (which would
                    466:                  * have resulted in a panic() had it been true).
                    467:                  */
                    468:                 while ( dev->sc_nexus )
                    469:                     sbicpoll(dev);
1.1       chuck     470:
1.16      bouyer    471:                 /*
                    472:                  * Fix up the new nexus
                    473:                  */
                    474:                 dev->sc_nexus   = acb;
                    475:                 dev->sc_xs      = xs;
                    476:                 dev->target     = periph->periph_target;
                    477:                 dev->lun        = periph->periph_lun;
1.1       chuck     478:
1.16      bouyer    479:                 stat = sbicicmd(dev, &acb->cmd, acb->clen,
                    480:                                 acb->sc_kv.dc_addr, acb->sc_kv.dc_count);
1.1       chuck     481:
1.16      bouyer    482:             } while ( dev->sc_nexus != acb );
1.1       chuck     483:
1.16      bouyer    484:             sbic_scsidone(acb, stat);
1.1       chuck     485:
1.16      bouyer    486:             splx(s);
1.1       chuck     487:
1.16      bouyer    488:             return;
                    489:         }
1.1       chuck     490:
1.16      bouyer    491:         s = splbio();
                    492:         TAILQ_INSERT_TAIL(&dev->ready_list, acb, chain);
1.1       chuck     493:
1.16      bouyer    494:         /*
                    495:          * If nothing is active, try to start it now.
                    496:          */
                    497:         if ( dev->sc_nexus == NULL )
                    498:             sbic_sched(dev);
1.1       chuck     499:
1.16      bouyer    500:         splx(s);
1.1       chuck     501:
1.16      bouyer    502:         return;
1.1       chuck     503:
1.16      bouyer    504:     case ADAPTER_REQ_GROW_RESOURCES:
                    505:        /* XXX Not supported. */
                    506:        return;
                    507:
                    508:     case ADAPTER_REQ_SET_XFER_MODE:
                    509:        /* XXX Not supported. */
                    510:        return;
                    511:     }
1.1       chuck     512:
                    513: }
                    514:
                    515: /*
                    516:  * attempt to start the next available command
                    517:  */
                    518: void
                    519: sbic_sched(dev)
                    520:     struct sbic_softc *dev;
                    521: {
1.6       bouyer    522:     struct scsipi_xfer    *xs;
1.16      bouyer    523:     struct scsipi_periph  *periph = NULL;    /* Gag the compiler */
1.1       chuck     524:     struct sbic_acb     *acb;
                    525:     int                 flags,
                    526:                         stat;
                    527:
                    528:     /*
                    529:      * XXXSCW
                    530:      * I'll keep this test here, even though I can't see any obvious way
                    531:      * in which sbic_sched() could be called with sc_nexus non NULL
                    532:      */
                    533:     if ( dev->sc_nexus )
                    534:         return;         /* a command is current active */
                    535:
                    536:     /*
                    537:      * Loop through the ready list looking for work to do...
                    538:      */
                    539:     for (acb = dev->ready_list.tqh_first; acb; acb = acb->chain.tqe_next) {
                    540:         int     i, j;
                    541:
1.16      bouyer    542:         periph = acb->xs->xs_periph;
                    543:         i   = periph->periph_target;
                    544:         j   = 1 << periph->periph_lun;
1.1       chuck     545:
                    546:         /*
                    547:          * We've found a potential command, but is the target/lun busy?
                    548:          */
                    549:         if ( (dev->sc_tinfo[i].lubusy & j) == 0 ) {
                    550:             /*
                    551:              * Nope, it's not busy, so we can use it.
                    552:              */
                    553:             dev->sc_tinfo[i].lubusy |= j;
                    554:             TAILQ_REMOVE(&dev->ready_list, acb, chain);
                    555:             dev->sc_nexus = acb;
                    556:             acb->sc_pa.dc_addr = acb->pa_addr;  /* XXXX check */
                    557:             break;
                    558:         }
                    559:     }
                    560:
                    561:     if ( acb == NULL ) {
                    562:         QPRINTF(("sbicsched: no work\n"));
                    563:         return;         /* did not find an available command */
                    564:     }
                    565:
                    566: #ifdef DEBUG
                    567:     if ( data_pointer_debug > 1 )
1.16      bouyer    568:         printf("sbic_sched(%d,%d)\n", periph->periph_target,
                    569:                        periph->periph_lun);
1.1       chuck     570: #endif
                    571:
                    572:     dev->sc_xs = xs = acb->xs;
1.10      thorpej   573:     flags      = xs->xs_control;
1.1       chuck     574:
1.10      thorpej   575:     if ( flags & XS_CTL_RESET )
1.1       chuck     576:         sbicreset(dev);
                    577:
                    578:     dev->sc_stat[0] = -1;
1.16      bouyer    579:     dev->target     = periph->periph_target;
                    580:     dev->lun        = periph->periph_lun;
1.1       chuck     581:
1.10      thorpej   582:     if ( flags & XS_CTL_POLL || (!sbic_parallel_operations &&
1.1       chuck     583:                               (sbicdmaok(dev, xs) == 0)) )
                    584:         stat = sbicicmd(dev, &acb->cmd, acb->clen,
                    585:                         acb->sc_kv.dc_addr, acb->sc_kv.dc_count);
                    586:     else
1.11      scw       587:     if ( sbicgo(dev, xs) == 0 && xs->error != XS_SELTIMEOUT )
1.1       chuck     588:         return;
                    589:     else
                    590:         stat = dev->sc_stat[0];
                    591:
                    592:     sbic_scsidone(acb, stat);
                    593: }
                    594:
                    595: void
                    596: sbic_scsidone(acb, stat)
                    597:     struct sbic_acb *acb;
                    598:     int             stat;
                    599: {
1.6       bouyer    600:     struct scsipi_xfer    *xs  = acb->xs;
1.16      bouyer    601:     struct scsipi_periph  *periph = xs->xs_periph;
                    602:     struct sbic_softc   *dev = (void *)periph->periph_channel->chan_adapter->adapt_dev;
1.1       chuck     603:     int                 dosched = 0;
                    604:
                    605: #ifdef DIAGNOSTIC
                    606:     if ( acb == NULL || xs == NULL ) {
1.6       bouyer    607:         printf("sbic_scsidone -- (%d,%d) no scsipi_xfer\n", dev->target, dev->lun);
1.1       chuck     608: #ifdef DDB
                    609:         Debugger();
                    610: #endif
                    611:         return;
                    612:     }
                    613: #endif
                    614:
                    615:
                    616: #ifdef DEBUG
                    617:     if ( data_pointer_debug > 1 )
1.16      bouyer    618:         printf("scsidone: (%d,%d)->(%d,%d)%02x\n", periph->periph_target,
                    619:                        periph->periph_lun,
1.1       chuck     620:                                                    dev->target, dev->lun, stat);
                    621:
1.16      bouyer    622:     if ( xs->xs_periph->periph_target == dev->sc_channel.chan_id)
1.1       chuck     623:         panic("target == hostid");
                    624: #endif
                    625:
1.16      bouyer    626:     xs->status = stat;
                    627:     xs->resid = 0;      /* XXXX */
                    628:     if ( xs->error == XS_NOERROR) {
                    629:         if ( stat == SCSI_CHECK || stat == SCSI_BUSY)
                    630:             xs->error = XS_BUSY;
1.1       chuck     631:     }
                    632:
                    633:
                    634:     /*
                    635:      * Remove the ACB from whatever queue it's on.  We have to do a bit of
                    636:      * a hack to figure out which queue it's on.  Note that it is *not*
                    637:      * necessary to cdr down the ready queue, but we must cdr down the
                    638:      * nexus queue and see if it's there, so we can mark the unit as no
                    639:      * longer busy.  This code is sickening, but it works.
                    640:      */
                    641:     if ( acb == dev->sc_nexus ) {
                    642:
                    643:         dev->sc_nexus = NULL;
                    644:         dev->sc_xs    = NULL;
                    645:
1.16      bouyer    646:         dev->sc_tinfo[periph->periph_target].lubusy &=
                    647:                        ~(1 << periph->periph_lun);
1.1       chuck     648:
                    649:         if ( dev->ready_list.tqh_first )
                    650:             dosched = 1;    /* start next command */
                    651:
                    652:     } else
                    653:     if ( dev->ready_list.tqh_last == &acb->chain.tqe_next ) {
                    654:
                    655:         TAILQ_REMOVE(&dev->ready_list, acb, chain);
                    656:
                    657:     } else {
                    658:
1.8       scw       659:         struct sbic_acb *a;
1.1       chuck     660:
                    661:         for (a = dev->nexus_list.tqh_first; a; a = a->chain.tqe_next) {
                    662:             if ( a == acb ) {
                    663:                 TAILQ_REMOVE(&dev->nexus_list, acb, chain);
1.16      bouyer    664:                 dev->sc_tinfo[periph->periph_target].lubusy &=
                    665:                                        ~(1 << periph->periph_lun);
1.1       chuck     666:                 break;
                    667:             }
                    668:         }
                    669:
                    670:         if ( a )
                    671:             ;
                    672:         else if ( acb->chain.tqe_next ) {
                    673:             TAILQ_REMOVE(&dev->ready_list, acb, chain);
                    674:         } else {
1.5       christos  675:             printf("%s: can't find matching acb\n", dev->sc_dev.dv_xname);
1.1       chuck     676: #ifdef DDB
                    677:             Debugger();
                    678: #endif
                    679:         }
                    680:     }
                    681:
                    682:     /*
                    683:      * Put it on the free list.
                    684:      */
                    685:     acb->flags = ACB_FREE;
                    686:     TAILQ_INSERT_HEAD(&dev->free_list, acb, chain);
                    687:
1.16      bouyer    688:     dev->sc_tinfo[periph->periph_target].cmds++;
1.1       chuck     689:
1.6       bouyer    690:     scsipi_done(xs);
1.1       chuck     691:
                    692:     if ( dosched )
                    693:         sbic_sched(dev);
                    694: }
                    695:
                    696: int
                    697: sbicdmaok(dev, xs)
                    698:     struct sbic_softc   *dev;
1.6       bouyer    699:     struct scsipi_xfer    *xs;
1.1       chuck     700: {
1.11      scw       701:     if ( sbic_no_dma || xs->datalen == 0 ||
                    702:         xs->datalen & 0x03 || (int)xs->data & 0x03)
1.1       chuck     703:         return(0);
                    704:
                    705:     /*
1.21      wiz       706:      * controller supports DMA to any addresses?
1.1       chuck     707:      */
                    708:     if ( (dev->sc_flags & SBICF_BADDMA) == 0 )
                    709:         return(1);
                    710:
                    711:     /*
1.21      wiz       712:      * this address is ok for DMA?
1.1       chuck     713:      */
                    714:     if ( sbiccheckdmap(xs->data, xs->datalen, dev->sc_dmamask) == 0 )
                    715:         return(1);
                    716:
                    717:     return(0);
                    718: }
                    719:
                    720: int
                    721: sbicwait(regs, until, timeo, line)
                    722:     sbic_regmap_p   regs;
                    723:     u_char          until;
                    724:     int             timeo;
                    725:     int             line;
                    726: {
                    727:     u_char  val;
                    728:
                    729:     if ( timeo == 0 )
                    730:         timeo = 1000000;    /* some large value.. */
                    731:
                    732:     GET_SBIC_asr(regs, val);
                    733:
                    734:     while ( (val & until) == 0 ) {
                    735:
                    736:         if ( timeo-- == 0 ) {
                    737:             int csr;
                    738:             GET_SBIC_csr(regs, csr);
1.5       christos  739:             printf("sbicwait TIMEO @%d with asr=x%x csr=x%x\n", line, val, csr);
1.1       chuck     740: #if defined(DDB) && defined(DEBUG)
                    741:             Debugger();
                    742: #endif
                    743:             return(val); /* Maybe I should abort */
                    744:             break;
                    745:         }
                    746:
                    747:         DELAY(1);
                    748:         GET_SBIC_asr(regs, val);
                    749:     }
                    750:
                    751:     return(val);
                    752: }
                    753:
                    754: int
                    755: sbicabort(dev, where)
                    756:     struct sbic_softc   *dev;
1.26      scw       757:     const char          *where;
1.1       chuck     758: {
                    759:     sbic_regmap_p   regs = dev->sc_sbicp;
                    760:     u_char          csr,
                    761:                     asr;
                    762:
                    763:     GET_SBIC_asr(regs, asr);
                    764:     GET_SBIC_csr(regs, csr);
                    765:
1.5       christos  766:     printf ("%s: abort %s: csr = 0x%02x, asr = 0x%02x\n",
1.1       chuck     767:             dev->sc_dev.dv_xname, where, csr, asr);
                    768:
                    769:     /*
                    770:      * Clean up chip itself
                    771:      */
                    772:     if ( dev->sc_flags & SBICF_SELECTED ) {
                    773:
                    774:         while ( asr & SBIC_ASR_DBR ) {
                    775:             /*
                    776:              * sbic is jammed w/data. need to clear it
                    777:              * But we don't know what direction it needs to go
                    778:              */
                    779:             GET_SBIC_data(regs, asr);
1.5       christos  780:             printf("%s: abort %s: clearing data buffer 0x%02x\n",
1.1       chuck     781:                    dev->sc_dev.dv_xname, where, asr);
                    782:             GET_SBIC_asr(regs, asr);
                    783:             if ( asr & SBIC_ASR_DBR ) /* Not the read direction, then */
                    784:                 SET_SBIC_data(regs, asr);
                    785:             GET_SBIC_asr(regs, asr);
                    786:         }
                    787:
                    788:         WAIT_CIP(regs);
                    789:
1.5       christos  790:         printf("%s: sbicabort - sending ABORT command\n", dev->sc_dev.dv_xname);
1.1       chuck     791:         SET_SBIC_cmd(regs, SBIC_CMD_ABORT);
                    792:         WAIT_CIP(regs);
                    793:
                    794:         GET_SBIC_asr(regs, asr);
                    795:
                    796:         if ( asr & (SBIC_ASR_BSY|SBIC_ASR_LCI) ) {
                    797:             /*
                    798:              * ok, get more drastic..
                    799:              */
1.5       christos  800:             printf("%s: sbicabort - asr %x, trying to reset\n",
1.1       chuck     801:                     dev->sc_dev.dv_xname, asr);
                    802:             sbicreset(dev);
                    803:             dev->sc_flags &= ~SBICF_SELECTED;
1.2       chuck     804:             return SBIC_STATE_ERROR;
1.1       chuck     805:         }
                    806:
1.5       christos  807:         printf("%s: sbicabort - sending DISC command\n", dev->sc_dev.dv_xname);
1.1       chuck     808:         SET_SBIC_cmd(regs, SBIC_CMD_DISC);
                    809:
                    810:         do {
                    811:             SBIC_WAIT (regs, SBIC_ASR_INT, 0);
                    812:             GET_SBIC_asr(regs, asr);
                    813:             GET_SBIC_csr (regs, csr);
                    814:             QPRINTF(("csr: 0x%02x, asr: 0x%02x\n", csr, asr));
                    815:         } while ( (csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1) &&
                    816:                   (csr != SBIC_CSR_CMD_INVALID) );
                    817:
                    818:         /*
                    819:          * lets just hope it worked..
                    820:          */
                    821:         dev->sc_flags &= ~SBICF_SELECTED;
                    822:     }
                    823:
1.2       chuck     824:     return SBIC_STATE_ERROR;
1.1       chuck     825: }
                    826:
                    827:
                    828: /*
                    829:  * Initialize driver-private structures
                    830:  */
                    831: void
                    832: sbicinit(dev)
                    833:     struct sbic_softc *dev;
                    834: {
                    835:     u_int   i;
                    836:
                    837:     if ( (dev->sc_flags & SBICF_ALIVE) == 0 ) {
                    838:
                    839:         struct sbic_acb *acb;
                    840:
                    841:         TAILQ_INIT(&dev->ready_list);
                    842:         TAILQ_INIT(&dev->nexus_list);
                    843:         TAILQ_INIT(&dev->free_list);
1.13      thorpej   844:        callout_init(&dev->sc_timo_ch);
1.1       chuck     845:
                    846:         dev->sc_nexus = NULL;
                    847:         dev->sc_xs    = NULL;
                    848:
                    849:         acb = dev->sc_acb;
1.17      scw       850:         memset(acb, 0, sizeof(dev->sc_acb));
1.1       chuck     851:
                    852:         for (i = 0; i < sizeof(dev->sc_acb) / sizeof(*acb); i++) {
                    853:             TAILQ_INSERT_TAIL(&dev->free_list, acb, chain);
                    854:             acb++;
                    855:         }
                    856:
1.17      scw       857:         memset(dev->sc_tinfo, 0, sizeof(dev->sc_tinfo));
1.1       chuck     858:
                    859: #ifdef DEBUG
                    860:         /*
                    861:          * make sure timeout is really not needed
                    862:          */
1.13      thorpej   863:        callout_reset(&dev->sc_timo_ch, 30 * hz, (void *)sbictimeout, dev);
1.1       chuck     864: #endif
                    865:
                    866:     } else
                    867:         panic("sbic: reinitializing driver!");
                    868:
                    869:     dev->sc_flags |=  SBICF_ALIVE;
                    870:     dev->sc_flags &= ~SBICF_SELECTED;
                    871:
                    872:     /*
                    873:      * initialize inhibit array
1.9       scw       874:         * Never enable Sync, since it just doesn't work on mvme147 :(
1.1       chuck     875:      */
1.9       scw       876:     for (i = 0; i < 8; ++i)
                    877:         sbic_inhibit_sync[i] = 1;
1.1       chuck     878:
                    879:     sbicreset(dev);
                    880: }
                    881:
                    882: void
                    883: sbicreset(dev)
                    884:     struct sbic_softc *dev;
                    885: {
                    886:     sbic_regmap_p   regs = dev->sc_sbicp;
                    887:     u_int           my_id,
                    888:                     s;
                    889:     u_char          csr;
                    890:
                    891:     s = splbio();
                    892:
1.16      bouyer    893:     my_id = dev->sc_channel.chan_id & SBIC_ID_MASK;
1.1       chuck     894:
                    895:     if (dev->sc_clkfreq < 110)
                    896:         my_id |= SBIC_ID_FS_8_10;
                    897:     else if (dev->sc_clkfreq < 160)
                    898:         my_id |= SBIC_ID_FS_12_15;
                    899:     else if (dev->sc_clkfreq < 210)
                    900:         my_id |= SBIC_ID_FS_16_20;
                    901:
                    902:     SET_SBIC_myid(regs, my_id);
                    903:
                    904:     /*
                    905:      * Reset the chip
                    906:      */
                    907:     SET_SBIC_cmd(regs, SBIC_CMD_RESET);
                    908:     DELAY(25);
                    909:
                    910:     SBIC_WAIT(regs, SBIC_ASR_INT, 0);
                    911:     GET_SBIC_csr(regs, csr);       /* clears interrupt also */
                    912:
                    913:     /*
                    914:      * Set up various chip parameters
                    915:      */
                    916:     SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
                    917:
                    918:     /*
                    919:      * don't allow Selection (SBIC_RID_ES)
                    920:      * until we can handle target mode!!
                    921:      */
                    922:     SET_SBIC_rselid(regs, SBIC_RID_ER);
                    923:
                    924:     /*
                    925:      * Asynchronous for now
                    926:      */
                    927:     SET_SBIC_syn(regs, 0);
                    928:
                    929:     /*
                    930:      * Anything else was zeroed by reset
                    931:      */
                    932:     splx(s);
                    933:
                    934:     dev->sc_flags &= ~SBICF_SELECTED;
                    935: }
                    936:
                    937: void
                    938: sbicerror(dev, csr)
                    939:     struct sbic_softc   *dev;
                    940:     u_char              csr;
                    941: {
1.6       bouyer    942:     struct scsipi_xfer    *xs  = dev->sc_xs;
1.1       chuck     943:
                    944: #ifdef DIAGNOSTIC
                    945:     if ( xs == NULL )
                    946:         panic("sbicerror: dev->sc_xs == NULL");
                    947: #endif
                    948:
1.10      thorpej   949:     if ( xs->xs_control & XS_CTL_SILENT )
1.1       chuck     950:         return;
                    951:
1.5       christos  952:     printf("%s: csr == 0x%02x\n", dev->sc_dev.dv_xname, csr);
1.1       chuck     953: }
                    954:
                    955: /*
                    956:  * select the bus, return when selected or error.
                    957:  *
                    958:  * Returns the current CSR following selection and optionally MSG out phase.
                    959:  * i.e. the returned CSR *should* indicate CMD phase...
                    960:  * If the return value is 0, some error happened.
                    961:  */
                    962: u_char
                    963: sbicselectbus(dev)
                    964:     struct sbic_softc   *dev;
                    965: {
                    966:     sbic_regmap_p   regs   = dev->sc_sbicp;
                    967:     u_char          target = dev->target,
                    968:                     lun    = dev->lun,
                    969:                     asr,
                    970:                     csr,
                    971:                     id;
                    972:
                    973:     /*
                    974:      * if we're already selected, return (XXXX panic maybe?)
                    975:      */
                    976:     if ( dev->sc_flags & SBICF_SELECTED )
                    977:         return(0);
                    978:
                    979:     QPRINTF(("sbicselectbus %d: ", target));
                    980:
                    981:     /*
                    982:      * issue select
                    983:      */
                    984:     SET_SBIC_selid(regs, target);
                    985:     SET_SBIC_timeo(regs, SBIC_TIMEOUT(250, dev->sc_clkfreq));
                    986:
                    987:     GET_SBIC_asr(regs, asr);
                    988:
                    989:     if ( asr & (SBIC_ASR_INT|SBIC_ASR_BSY) ) {
                    990:         /*
                    991:          * This means we got ourselves reselected upon
                    992:          */
                    993:         QPRINTF(("WD busy (reselect?)\n"));
                    994:         return 0;
                    995:     }
                    996:
                    997:     SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN);
                    998:
                    999:     /*
1.18      wiz      1000:      * wait for select (merged from separate function may need
1.1       chuck    1001:      * cleanup)
                   1002:      */
                   1003:     WAIT_CIP(regs);
                   1004:
                   1005:     do {
                   1006:
                   1007:         asr = SBIC_WAIT(regs, SBIC_ASR_INT | SBIC_ASR_LCI, 0);
                   1008:
                   1009:         if ( asr & SBIC_ASR_LCI ) {
                   1010:             QPRINTF(("late LCI: asr %02x\n", asr));
                   1011:             return 0;
                   1012:         }
                   1013:
                   1014:         /*
                   1015:          * Clear interrupt
                   1016:          */
                   1017:         GET_SBIC_csr (regs, csr);
                   1018:
                   1019:         QPRINTF(("%02x ", csr));
                   1020:
                   1021:         /*
                   1022:          * Reselected from under our feet?
                   1023:          */
                   1024:         if ( csr == SBIC_CSR_RSLT_NI || csr == SBIC_CSR_RSLT_IFY ) {
                   1025:             QPRINTF(("got reselected, asr %02x\n", asr));
                   1026:             /*
                   1027:              * We need to handle this now so we don't lock up later
                   1028:              */
                   1029:             sbicnextstate(dev, csr, asr);
                   1030:
                   1031:             return 0;
                   1032:         }
                   1033:
                   1034:         /*
                   1035:          * Whoops!
                   1036:          */
                   1037:         if ( csr == SBIC_CSR_SLT || csr == SBIC_CSR_SLT_ATN ) {
                   1038:             panic("sbicselectbus: target issued select!");
                   1039:             return 0;
                   1040:         }
                   1041:
                   1042:     } while (csr != (SBIC_CSR_MIS_2 | MESG_OUT_PHASE) &&
                   1043:              csr != (SBIC_CSR_MIS_2 | CMD_PHASE) &&
                   1044:              csr != SBIC_CSR_SEL_TIMEO);
                   1045:
                   1046:     /*
                   1047:      * Anyone at home?
                   1048:      */
                   1049:     if ( csr == SBIC_CSR_SEL_TIMEO ) {
                   1050:         dev->sc_xs->error = XS_SELTIMEOUT;
                   1051:         QPRINTF(("Selection Timeout\n"));
                   1052:         return 0;
                   1053:     }
                   1054:
                   1055:     QPRINTF(("Selection Complete\n"));
                   1056:
                   1057:     /*
                   1058:      * Assume we're now selected
                   1059:      */
                   1060:     GET_SBIC_selid(regs, id);
                   1061:     dev->target    = id;
                   1062:     dev->lun       = lun;
                   1063:     dev->sc_flags |= SBICF_SELECTED;
                   1064:
                   1065:     /*
                   1066:      * Enable (or not) reselection
                   1067:      * XXXSCW This is probably not necessary since we don't use use the
1.2       chuck    1068:      * Select-and-Xfer-with-ATN command to initiate a selection...
1.1       chuck    1069:      */
                   1070:     if ( !sbic_enable_reselect && dev->nexus_list.tqh_first == NULL)
                   1071:         SET_SBIC_rselid (regs, 0);
                   1072:     else
                   1073:         SET_SBIC_rselid (regs, SBIC_RID_ER);
                   1074:
                   1075:     /*
                   1076:      * We only really need to do anything when the target goes to MSG out
                   1077:      * If the device ignored ATN, it's probably old and brain-dead,
                   1078:      * but we'll try to support it anyhow.
                   1079:      * If it doesn't support message out, it definately doesn't
                   1080:      * support synchronous transfers, so no point in even asking...
                   1081:      */
                   1082:     if ( csr == (SBIC_CSR_MIS_2 | MESG_OUT_PHASE) ) {
                   1083:         /*
                   1084:          * Send identify message (SCSI-2 requires an identify msg)
                   1085:          */
                   1086:         if ( sbic_inhibit_sync[id] && dev->sc_sync[id].state == SYNC_START ) {
                   1087:             /*
                   1088:              * Handle drives that don't want to be asked
                   1089:              * whether to go sync at all.
                   1090:              */
                   1091:             dev->sc_sync[id].offset = 0;
                   1092:             dev->sc_sync[id].period = sbic_min_period;
                   1093:             dev->sc_sync[id].state  = SYNC_DONE;
                   1094:         }
                   1095:
                   1096:         /*
                   1097:          * Do we need to negotiate Synchronous Xfers for this target?
                   1098:          */
                   1099:         if ( dev->sc_sync[id].state != SYNC_START ) {
                   1100:             /*
                   1101:              * Nope, we've already negotiated.
                   1102:              * Now see if we should allow the target to disconnect/reselect...
                   1103:              */
1.10      thorpej  1104:             if ( dev->sc_xs->xs_control & XS_CTL_POLL || dev->sc_flags & SBICF_ICMD ||
1.1       chuck    1105:                                                   !sbic_enable_reselect )
                   1106:                 SEND_BYTE (regs, MSG_IDENTIFY | lun);
                   1107:             else
                   1108:                 SEND_BYTE (regs, MSG_IDENTIFY_DR | lun);
                   1109:
                   1110:         } else {
                   1111:             /*
                   1112:              * try to initiate a sync transfer.
                   1113:              * So compose the sync message we're going
                   1114:              * to send to the target
                   1115:              */
                   1116: #ifdef DEBUG
                   1117:             if ( sync_debug )
1.5       christos 1118:                 printf("\nSending sync request to target %d ... ", id);
1.1       chuck    1119: #endif
                   1120:             /*
                   1121:              * setup scsi message sync message request
                   1122:              */
                   1123:             dev->sc_msg[0] = MSG_IDENTIFY | lun;
                   1124:             dev->sc_msg[1] = MSG_EXT_MESSAGE;
                   1125:             dev->sc_msg[2] = 3;
                   1126:             dev->sc_msg[3] = MSG_SYNC_REQ;
                   1127:             dev->sc_msg[4] = sbictoscsiperiod(dev, sbic_min_period);
                   1128:             dev->sc_msg[5] = sbic_max_offset;
                   1129:
                   1130:             sbicxfout(regs, 6, dev->sc_msg);
                   1131:
                   1132:             dev->sc_sync[id].state = SYNC_SENT;
                   1133: #ifdef DEBUG
                   1134:             if ( sync_debug )
1.5       christos 1135:                 printf ("sent\n");
1.1       chuck    1136: #endif
                   1137:         }
                   1138:
                   1139:         /*
                   1140:          * There's one interrupt still to come: the change to CMD phase...
                   1141:          */
                   1142:         SBIC_WAIT(regs, SBIC_ASR_INT , 0);
                   1143:         GET_SBIC_csr(regs, csr);
                   1144:     }
                   1145:
1.2       chuck    1146:     /*
                   1147:      * set sync or async
                   1148:      */
                   1149:     if ( dev->sc_sync[target].state == SYNC_DONE ) {
                   1150: #ifdef  DEBUG
                   1151:         if ( sync_debug )
1.5       christos 1152:             printf("select(%d): sync reg = 0x%02x\n", target,
1.2       chuck    1153:                             SBIC_SYN(dev->sc_sync[target].offset,
                   1154:                                      dev->sc_sync[target].period));
                   1155: #endif
                   1156:         SET_SBIC_syn(regs, SBIC_SYN(dev->sc_sync[target].offset,
                   1157:                                     dev->sc_sync[target].period));
                   1158:     } else {
                   1159: #ifdef  DEBUG
                   1160:         if ( sync_debug )
1.5       christos 1161:             printf("select(%d): sync reg = 0x%02x\n", target,
1.2       chuck    1162:                             SBIC_SYN(0,sbic_min_period));
                   1163: #endif
                   1164:         SET_SBIC_syn(regs, SBIC_SYN(0, sbic_min_period));
                   1165:     }
                   1166:
1.1       chuck    1167:     return csr;
                   1168: }
                   1169:
                   1170: /*
1.2       chuck    1171:  * Information Transfer *to* a Scsi Target.
                   1172:  *
                   1173:  * Note: Don't expect there to be an interrupt immediately after all
                   1174:  * the data is transferred out. The WD spec sheet says that the Transfer-
                   1175:  * Info command for non-MSG_IN phases only completes when the target
                   1176:  * next asserts 'REQ'. That is, when the SCSI bus changes to a new state.
                   1177:  *
                   1178:  * This can have a nasty effect on commands which take a relatively long
                   1179:  * time to complete, for example a START/STOP unit command may remain in
                   1180:  * CMD phase until the disk has spun up. Only then will the target change
                   1181:  * to STATUS phase. This is really only a problem for immediate commands
                   1182:  * since we don't allow disconnection for them (yet).
1.1       chuck    1183:  */
                   1184: int
                   1185: sbicxfout(regs, len, bp)
                   1186:     sbic_regmap_p   regs;
                   1187:     int             len;
                   1188:     void            *bp;
                   1189: {
                   1190:     int     wait = sbic_data_wait;
                   1191:     u_char  asr,
                   1192:             *buf = bp;
                   1193:
                   1194:     QPRINTF(("sbicxfout {%d} %02x %02x %02x %02x %02x "
                   1195:         "%02x %02x %02x %02x %02x\n", len, buf[0], buf[1], buf[2],
                   1196:         buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9]));
                   1197:
                   1198:     /*
                   1199:      * sigh.. WD-PROTO strikes again.. sending the command in one go
                   1200:      * causes the chip to lock up if talking to certain (misbehaving?)
                   1201:      * targets. Anyway, this procedure should work for all targets, but
                   1202:      * it's slightly slower due to the overhead
                   1203:      */
                   1204:     WAIT_CIP (regs);
                   1205:
                   1206:     SBIC_TC_PUT (regs, 0);
                   1207:     SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
                   1208:     SBIC_TC_PUT (regs, (unsigned)len);
                   1209:     SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO);
                   1210:
                   1211:     /*
                   1212:      * Loop for each byte transferred
                   1213:      */
                   1214:     do {
                   1215:
                   1216:         GET_SBIC_asr (regs, asr);
                   1217:
                   1218:         if ( asr & SBIC_ASR_DBR ) {
                   1219:             if ( len ) {
                   1220:                 SET_SBIC_data (regs, *buf);
                   1221:                 buf++;
                   1222:                 len--;
                   1223:             } else {
                   1224:                 SET_SBIC_data (regs, 0);
                   1225:             }
                   1226:             wait = sbic_data_wait;
                   1227:         }
                   1228:
1.2       chuck    1229:     } while ( len && (asr & SBIC_ASR_INT) == 0 && wait-- > 0 );
1.1       chuck    1230:
                   1231: #ifdef  DEBUG
                   1232:     QPRINTF(("sbicxfout done: %d bytes remaining (wait:%d)\n", len, wait));
                   1233: #endif
                   1234:
                   1235:     /*
1.2       chuck    1236:      * Normally, an interrupt will be pending when this routing returns.
1.1       chuck    1237:      */
                   1238:     return(len);
                   1239: }
                   1240:
                   1241: /*
                   1242:  * Information Transfer *from* a Scsi Target
                   1243:  * returns # bytes left to read
                   1244:  */
                   1245: int
                   1246: sbicxfin(regs, len, bp)
                   1247:     sbic_regmap_p   regs;
                   1248:     int             len;
                   1249:     void            *bp;
                   1250: {
                   1251:     int     wait = sbic_data_wait;
                   1252:     u_char  *buf = bp;
                   1253:     u_char  asr;
                   1254: #ifdef  DEBUG
                   1255:     u_char  *obp = bp;
                   1256: #endif
                   1257:
                   1258:     WAIT_CIP (regs);
                   1259:
                   1260:     SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
                   1261:     SBIC_TC_PUT (regs, (unsigned)len);
                   1262:     SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO);
                   1263:
                   1264:     /*
                   1265:      * Loop for each byte transferred
                   1266:      */
                   1267:     do {
                   1268:
                   1269:         GET_SBIC_asr (regs, asr);
                   1270:
                   1271:         if ( asr & SBIC_ASR_DBR ) {
                   1272:             if ( len ) {
                   1273:                 GET_SBIC_data (regs, *buf);
                   1274:                 buf++;
                   1275:                 len--;
                   1276:             } else {
                   1277:                 u_char foo;
                   1278:                 GET_SBIC_data (regs, foo);
                   1279:             }
                   1280:             wait = sbic_data_wait;
                   1281:         }
                   1282:
                   1283:     } while ( (asr & SBIC_ASR_INT) == 0 && wait-- > 0 );
                   1284:
                   1285:     QPRINTF(("sbicxfin {%d} %02x %02x %02x %02x %02x %02x "
                   1286:         "%02x %02x %02x %02x\n", len, obp[0], obp[1], obp[2],
                   1287:         obp[3], obp[4], obp[5], obp[6], obp[7], obp[8], obp[9]));
                   1288:
                   1289:     SBIC_TC_PUT (regs, 0);
                   1290:
                   1291:     /*
                   1292:      * this leaves with one csr to be read
                   1293:      */
                   1294:     return len;
                   1295: }
                   1296:
                   1297: /*
                   1298:  * SCSI 'immediate' command:  issue a command to some SCSI device
                   1299:  * and get back an 'immediate' response (i.e., do programmed xfer
                   1300:  * to get the response data).  'cbuf' is a buffer containing a scsi
                   1301:  * command of length clen bytes.  'buf' is a buffer of length 'len'
                   1302:  * bytes for data.  The transfer direction is determined by the device
                   1303:  * (i.e., by the scsi bus data xfer phase).  If 'len' is zero, the
                   1304:  * command must supply no data.
1.2       chuck    1305:  *
                   1306:  * Note that although this routine looks like it can handle disconnect/
                   1307:  * reselect, the fact is that it can't. There is still some work to be
                   1308:  * done to clean this lot up.
1.1       chuck    1309:  */
                   1310: int
                   1311: sbicicmd(dev, cbuf, clen, buf, len)
                   1312:     struct sbic_softc   *dev;
                   1313:     void                *cbuf,
                   1314:                         *buf;
                   1315:     int                 clen,
                   1316:                         len;
                   1317: {
                   1318:     sbic_regmap_p   regs = dev->sc_sbicp;
                   1319:     struct sbic_acb *acb = dev->sc_nexus;
                   1320:     u_char          csr,
                   1321:                     asr;
1.2       chuck    1322:     int             still_busy = SBIC_STATE_RUNNING;
1.1       chuck    1323:
                   1324:     /*
                   1325:      * Make sure pointers are OK
                   1326:      */
                   1327:     dev->sc_last = dev->sc_cur = &acb->sc_pa;
                   1328:     dev->sc_tcnt = acb->sc_tcnt = 0;
                   1329:
                   1330:     acb->sc_dmacmd      = 0;
                   1331:     acb->sc_pa.dc_count = 0; /* No DMA */
                   1332:     acb->sc_kv.dc_addr  = buf;
                   1333:     acb->sc_kv.dc_count = len;
                   1334:
                   1335: #ifdef  DEBUG
                   1336:     if ( data_pointer_debug > 1 )
1.5       christos 1337:         printf("sbicicmd(%d,%d):%d\n", dev->target, dev->lun, acb->sc_kv.dc_count);
1.1       chuck    1338: #endif
                   1339:
                   1340:     /*
                   1341:      * set the sbic into non-DMA mode
                   1342:      */
                   1343:     SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
                   1344:
                   1345:     dev->sc_stat[0] = 0xff;
                   1346:     dev->sc_msg[0]  = 0xff;
                   1347:
                   1348:     /*
                   1349:      * We're stealing the SCSI bus
                   1350:      */
                   1351:     dev->sc_flags |= SBICF_ICMD;
                   1352:
                   1353:     do {
                   1354:         GET_SBIC_asr (regs, asr);
                   1355:
                   1356:         /*
                   1357:          * select the SCSI bus (it's an error if bus isn't free)
                   1358:          */
1.2       chuck    1359:         if ( (dev->sc_flags & SBICF_SELECTED) == 0 &&
                   1360:              still_busy != SBIC_STATE_DISCONNECT ) {
1.1       chuck    1361:             if ( (csr = sbicselectbus(dev)) == 0 ) {
                   1362:                 dev->sc_flags &= ~SBICF_ICMD;
                   1363:                 return(-1);
                   1364:             }
                   1365:         } else
1.2       chuck    1366:         if ( (asr & (SBIC_ASR_BSY | SBIC_ASR_INT)) == SBIC_ASR_INT )
1.1       chuck    1367:             GET_SBIC_csr(regs, csr);
1.2       chuck    1368:         else
                   1369:             csr = 0;
                   1370:
                   1371:         if ( csr ) {
                   1372:
                   1373:             QPRINTF((">ASR:0x%02x CSR:0x%02x< ", asr, csr));
1.1       chuck    1374:
1.2       chuck    1375:             switch ( csr ) {
1.1       chuck    1376:
1.2       chuck    1377:               case SBIC_CSR_S_XFERRED:
                   1378:               case SBIC_CSR_DISC:
                   1379:               case SBIC_CSR_DISC_1:
                   1380:                 {
                   1381:                     u_char  phase;
1.1       chuck    1382:
1.2       chuck    1383:                     dev->sc_flags &= ~SBICF_SELECTED;
                   1384:                     GET_SBIC_cmd_phase (regs, phase);
                   1385:
                   1386:                     if ( phase == 0x60 ) {
                   1387:                         GET_SBIC_tlun (regs, dev->sc_stat[0]);
                   1388:                         still_busy = SBIC_STATE_DONE; /* done */
                   1389:                     } else {
1.1       chuck    1390: #ifdef DEBUG
1.2       chuck    1391:                         if ( reselect_debug > 1 )
1.5       christos 1392:                             printf("sbicicmd: handling disconnect\n");
1.1       chuck    1393: #endif
1.2       chuck    1394:                         still_busy = SBIC_STATE_DISCONNECT;
                   1395:                     }
1.1       chuck    1396:                 }
1.2       chuck    1397:                 break;
1.1       chuck    1398:
1.2       chuck    1399:               case SBIC_CSR_XFERRED | CMD_PHASE:
                   1400:               case SBIC_CSR_MIS     | CMD_PHASE:
                   1401:               case SBIC_CSR_MIS_1   | CMD_PHASE:
                   1402:               case SBIC_CSR_MIS_2   | CMD_PHASE:
                   1403:                 {
                   1404:                     if ( sbicxfout(regs, clen, cbuf) )
                   1405:                         still_busy = sbicabort(dev, "icmd sending cmd");
                   1406:                 }
                   1407:                 break;
1.1       chuck    1408:
1.2       chuck    1409:               case SBIC_CSR_XFERRED | STATUS_PHASE:
                   1410:               case SBIC_CSR_MIS     | STATUS_PHASE:
                   1411:               case SBIC_CSR_MIS_1   | STATUS_PHASE:
                   1412:               case SBIC_CSR_MIS_2   | STATUS_PHASE:
                   1413:                 {
                   1414:                     /*
                   1415:                      * The sbic does the status/cmd-complete reading ok,
                   1416:                      * so do this with its hi-level commands.
                   1417:                      */
1.1       chuck    1418: #ifdef DEBUG
1.2       chuck    1419:                     if ( sbic_debug )
1.5       christos 1420:                         printf("SBICICMD status phase (bsy=%d)\n", still_busy);
1.1       chuck    1421: #endif
1.2       chuck    1422:                     SET_SBIC_cmd_phase(regs, 0x46);
                   1423:                     SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN_XFER);
                   1424:                 }
                   1425:                 break;
1.1       chuck    1426:
1.2       chuck    1427:               default:
                   1428:                 {
                   1429:                     still_busy = sbicnextstate(dev, csr, asr);
                   1430:                 }
                   1431:                 break;
1.1       chuck    1432:             }
                   1433:
1.2       chuck    1434:             /*
                   1435:              * make sure the last command was taken,
                   1436:              * ie. we're not hunting after an ignored command..
                   1437:              */
                   1438:             GET_SBIC_asr(regs, asr);
1.1       chuck    1439:
1.2       chuck    1440:             /*
                   1441:              * tapes may take a loooong time..
                   1442:              */
                   1443:             while (asr & SBIC_ASR_BSY ) {
1.1       chuck    1444:
1.2       chuck    1445:                 if ( asr & SBIC_ASR_DBR ) {
                   1446:                     int     i;
1.1       chuck    1447:
1.5       christos 1448:                     printf("sbicicmd: Waiting while sbic is jammed, CSR:%02x,ASR:%02x\n", csr,asr);
1.1       chuck    1449: #ifdef DDB
1.2       chuck    1450:                     Debugger();
1.1       chuck    1451: #endif
1.2       chuck    1452:                     /*
                   1453:                      * SBIC is jammed
                   1454:                      * DUNNO which direction
                   1455:                      * Try old direction
                   1456:                      */
                   1457:                     GET_SBIC_data(regs, i);
                   1458:                     GET_SBIC_asr(regs, asr);
                   1459:
                   1460:                     if ( asr & SBIC_ASR_DBR ) /* Wants us to write */
                   1461:                         SET_SBIC_data(regs, i);
                   1462:                 }
                   1463:
1.1       chuck    1464:                 GET_SBIC_asr(regs, asr);
                   1465:             }
                   1466:         }
                   1467:
                   1468:         /*
                   1469:          * wait for last command to complete
                   1470:          */
                   1471:         if ( asr & SBIC_ASR_LCI ) {
1.5       christos 1472:             printf("sbicicmd: last command ignored\n");
1.1       chuck    1473:         }
                   1474:         else
1.2       chuck    1475:         if ( still_busy >= SBIC_STATE_RUNNING ) /* Bsy */
1.1       chuck    1476:             SBIC_WAIT (regs, SBIC_ASR_INT, sbic_cmd_wait);
                   1477:
                   1478:         /*
                   1479:          * do it again
                   1480:          */
1.2       chuck    1481:     } while ( still_busy >= SBIC_STATE_RUNNING && dev->sc_stat[0] == 0xff );
1.1       chuck    1482:
                   1483:     /*
                   1484:      * Sometimes we need to do an extra read of the CSR
                   1485:      */
                   1486:     GET_SBIC_csr(regs, csr);
                   1487:
                   1488: #ifdef DEBUG
                   1489:     if ( data_pointer_debug > 1 )
1.5       christos 1490:         printf("sbicicmd done(%d,%d):%d =%d=\n", dev->target, dev->lun,
1.1       chuck    1491:                                                  acb->sc_kv.dc_count,
                   1492:                                                  dev->sc_stat[0]);
                   1493: #endif
                   1494:
                   1495:     dev->sc_flags &= ~SBICF_ICMD;
                   1496:
                   1497:     return(dev->sc_stat[0]);
                   1498: }
                   1499:
                   1500: /*
                   1501:  * Finish SCSI xfer command:  After the completion interrupt from
                   1502:  * a read/write operation, sequence through the final phases in
                   1503:  * programmed i/o.  This routine is a lot like sbicicmd except we
                   1504:  * skip (and don't allow) the select, cmd out and data in/out phases.
                   1505:  */
                   1506: void
                   1507: sbicxfdone(dev)
                   1508:     struct sbic_softc   *dev;
                   1509: {
                   1510:     sbic_regmap_p   regs = dev->sc_sbicp;
                   1511:     u_char          phase,
                   1512:                     csr;
                   1513:     int             s;
                   1514:
                   1515:     QPRINTF(("{"));
                   1516:     s = splbio();
                   1517:
                   1518:     /*
                   1519:      * have the sbic complete on its own
                   1520:      */
                   1521:     SBIC_TC_PUT(regs, 0);
                   1522:     SET_SBIC_cmd_phase(regs, 0x46);
                   1523:     SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN_XFER);
                   1524:
                   1525:     do {
                   1526:
                   1527:         SBIC_WAIT (regs, SBIC_ASR_INT, 0);
                   1528:         GET_SBIC_csr (regs, csr);
                   1529:         QPRINTF(("%02x:", csr));
                   1530:
                   1531:     } while ( (csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1) &&
                   1532:               (csr != SBIC_CSR_S_XFERRED));
                   1533:
                   1534:     dev->sc_flags &= ~SBICF_SELECTED;
                   1535:
                   1536:     GET_SBIC_cmd_phase (regs, phase);
                   1537:     QPRINTF(("}%02x", phase));
                   1538:
                   1539:     if ( phase == 0x60 )
                   1540:         GET_SBIC_tlun(regs, dev->sc_stat[0]);
                   1541:     else
                   1542:         sbicerror(dev, csr);
                   1543:
                   1544:     QPRINTF(("=STS:%02x=\n", dev->sc_stat[0]));
                   1545:
                   1546:     splx(s);
                   1547: }
                   1548:
                   1549: /*
                   1550:  * No DMA chains
                   1551:  */
                   1552: int
                   1553: sbicgo(dev, xs)
                   1554:     struct sbic_softc   *dev;
1.6       bouyer   1555:     struct scsipi_xfer    *xs;
1.1       chuck    1556: {
                   1557:     struct sbic_acb *acb = dev->sc_nexus;
                   1558:     sbic_regmap_p   regs = dev->sc_sbicp;
                   1559:     int             i,
                   1560:                     dmaflags,
                   1561:                     count,
                   1562:                     usedma;
                   1563:     u_char          csr,
                   1564:                     asr,
                   1565:                     *addr;
                   1566:
1.16      bouyer   1567:     dev->target = xs->xs_periph->periph_target;
                   1568:     dev->lun    = xs->xs_periph->periph_lun;
1.1       chuck    1569:
                   1570:     usedma = sbicdmaok(dev, xs);
                   1571:
                   1572: #ifdef DEBUG
                   1573:     if ( data_pointer_debug > 1 )
1.5       christos 1574:         printf("sbicgo(%d,%d): usedma=%d\n", dev->target, dev->lun, usedma);
1.1       chuck    1575: #endif
                   1576:
                   1577:     /*
                   1578:      * select the SCSI bus (it's an error if bus isn't free)
                   1579:      */
                   1580:     if ( (csr = sbicselectbus(dev)) == 0 )
                   1581:         return(0); /* Not done: needs to be rescheduled */
                   1582:
                   1583:     dev->sc_stat[0] = 0xff;
                   1584:
                   1585:     /*
                   1586:      * Calculate DMA chains now
                   1587:      */
                   1588:     if ( acb->flags & ACB_DATAIN )
                   1589:         dmaflags = DMAGO_READ;
                   1590:     else
                   1591:         dmaflags = 0;
                   1592:
                   1593:     addr  = acb->sc_kv.dc_addr;
                   1594:     count = acb->sc_kv.dc_count;
                   1595:
1.12      scw      1596:     if ( count && ((char *)kvtop((caddr_t)addr) != acb->sc_pa.dc_addr) ) {
1.19      chs      1597:         printf("sbic: DMA buffer mapping changed %p->%x\n",
1.12      scw      1598:                 acb->sc_pa.dc_addr, kvtop((caddr_t)addr));
1.1       chuck    1599: #ifdef DDB
                   1600:         Debugger();
                   1601: #endif
                   1602:     }
                   1603:
                   1604: #ifdef DEBUG
                   1605:     ++sbicdma_ops;          /* count total DMA operations */
                   1606: #endif
                   1607:
                   1608:     /*
                   1609:      * Allocate the DMA chain
                   1610:      * Mark end of segment...
                   1611:      */
                   1612:     acb->sc_tcnt        = dev->sc_tcnt = 0;
                   1613:     acb->sc_pa.dc_count = 0;
                   1614:
                   1615:     sbic_load_ptrs(dev);
                   1616:
                   1617:     /*
                   1618:      * Enable interrupts but don't do any DMA
                   1619:      * enintr() also enables interrupts for the sbic
                   1620:      */
                   1621:     dev->sc_enintr(dev);
                   1622:
                   1623:     if ( usedma ) {
                   1624:         dev->sc_tcnt = dev->sc_dmago(dev, acb->sc_pa.dc_addr,
                   1625:                                           acb->sc_pa.dc_count, dmaflags);
                   1626: #ifdef DEBUG
                   1627:         dev->sc_dmatimo = dev->sc_tcnt ? 1 : 0;
                   1628: #endif
                   1629:     } else
                   1630:         dev->sc_dmacmd = 0; /* Don't use DMA */
                   1631:
                   1632:     acb->sc_dmacmd = dev->sc_dmacmd;
                   1633:
                   1634: #ifdef DEBUG
                   1635:     if ( data_pointer_debug > 1 ) {
1.12      scw      1636:         printf("sbicgo dmago:%d(%p:%lx) dmacmd=0x%02x\n", dev->target,
1.1       chuck    1637:                                            dev->sc_cur->dc_addr,
                   1638:                                            dev->sc_tcnt,
                   1639:                                            dev->sc_dmacmd);
                   1640:     }
                   1641: #endif
                   1642:
                   1643:     /*
                   1644:      * Lets cycle a while then let the interrupt handler take over.
                   1645:      */
                   1646:     GET_SBIC_asr(regs, asr);
                   1647:
                   1648:     do {
                   1649:
                   1650:         QPRINTF(("go "));
                   1651:
                   1652:         /*
                   1653:          * Handle the new phase
                   1654:          */
                   1655:         i = sbicnextstate(dev, csr, asr);
                   1656: #if 0
                   1657:         WAIT_CIP(regs);
                   1658: #endif
                   1659:         if ( i == SBIC_STATE_RUNNING ) {
                   1660:             GET_SBIC_asr(regs, asr);
                   1661:
                   1662:             if ( asr & SBIC_ASR_LCI )
1.5       christos 1663:                 printf("sbicgo: LCI asr:%02x csr:%02x\n", asr, csr);
1.1       chuck    1664:
                   1665:             if ( asr & SBIC_ASR_INT )
                   1666:                 GET_SBIC_csr(regs, csr);
                   1667:         }
                   1668:
                   1669:     } while ( i == SBIC_STATE_RUNNING && asr & (SBIC_ASR_INT|SBIC_ASR_LCI) );
                   1670:
                   1671:     if ( i == SBIC_STATE_DONE ) {
                   1672:         if ( dev->sc_stat[0] == 0xff )
                   1673: #if 0
1.5       christos 1674:             printf("sbicgo: done & stat = 0xff\n");
1.1       chuck    1675: #else
                   1676:             ;
                   1677: #endif
                   1678:         else
                   1679:             return 1;   /* Did we really finish that fast? */
                   1680:     }
                   1681:
                   1682:     return 0;
                   1683: }
                   1684:
                   1685:
                   1686: int
                   1687: sbicintr(dev)
                   1688:     struct sbic_softc   *dev;
                   1689: {
                   1690:     sbic_regmap_p       regs = dev->sc_sbicp;
                   1691:     u_char              asr,
                   1692:                         csr;
                   1693:     int                 i;
                   1694:
                   1695:     /*
                   1696:      * pending interrupt?
                   1697:      */
                   1698:     GET_SBIC_asr (regs, asr);
                   1699:     if ( (asr & SBIC_ASR_INT) == 0 )
                   1700:         return(0);
                   1701:
1.2       chuck    1702:     GET_SBIC_csr(regs, csr);
                   1703:
1.1       chuck    1704:     do {
                   1705:
                   1706:         QPRINTF(("intr[0x%x]", csr));
                   1707:
                   1708:         i = sbicnextstate(dev, csr, asr);
                   1709: #if 0
                   1710:         WAIT_CIP(regs);
                   1711: #endif
1.2       chuck    1712:         if ( i == SBIC_STATE_RUNNING ) {
                   1713:             GET_SBIC_asr(regs, asr);
                   1714:
                   1715:             if ( asr & SBIC_ASR_LCI )
1.5       christos 1716:                 printf("sbicgo: LCI asr:%02x csr:%02x\n", asr, csr);
1.2       chuck    1717:
                   1718:             if ( asr & SBIC_ASR_INT )
                   1719:                 GET_SBIC_csr(regs, csr);
                   1720:         }
1.1       chuck    1721:
                   1722:     } while ( i == SBIC_STATE_RUNNING && asr & (SBIC_ASR_INT|SBIC_ASR_LCI) );
                   1723:
                   1724:     QPRINTF(("intr done. state=%d, asr=0x%02x\n", i, asr));
                   1725:
                   1726:     return(1);
                   1727: }
                   1728:
                   1729: /*
                   1730:  * Run commands and wait for disconnect.
                   1731:  * This is only ever called when a command is in progress, when we
                   1732:  * want to busy wait for it to finish.
                   1733:  */
                   1734: int
                   1735: sbicpoll(dev)
                   1736:     struct sbic_softc   *dev;
                   1737: {
                   1738:     sbic_regmap_p       regs = dev->sc_sbicp;
                   1739:     u_char              asr,
1.25      scw      1740:                         csr = SBIC_CSR_RESET;  /* XXX: Quell un-init warning */
1.1       chuck    1741:     int                 i;
                   1742:
                   1743:     /*
                   1744:      * Wait for the next interrupt
                   1745:      */
                   1746:     SBIC_WAIT(regs, SBIC_ASR_INT, sbic_cmd_wait);
                   1747:
                   1748:     do {
                   1749:         GET_SBIC_asr (regs, asr);
                   1750:
                   1751:         if ( asr & SBIC_ASR_INT )
                   1752:             GET_SBIC_csr(regs, csr);
                   1753:
                   1754:         QPRINTF(("poll[0x%x]", csr));
                   1755:
                   1756:         /*
                   1757:          * Handle it
                   1758:          */
                   1759:         i = sbicnextstate(dev, csr, asr);
                   1760:
                   1761:         WAIT_CIP(regs);
                   1762:         GET_SBIC_asr(regs, asr);
                   1763:
                   1764:         /*
                   1765:          * tapes may take a loooong time..
                   1766:          */
                   1767:         while ( asr & SBIC_ASR_BSY ) {
1.2       chuck    1768:             u_char z = 0;
1.1       chuck    1769:
                   1770:             if ( asr & SBIC_ASR_DBR ) {
1.5       christos 1771:                 printf("sbipoll: Waiting while sbic is jammed, CSR:%02x,ASR:%02x\n", csr,asr);
1.1       chuck    1772: #ifdef DDB
                   1773:                 Debugger();
                   1774: #endif
                   1775:                 /*
                   1776:                  * SBIC is jammed
                   1777:                  * DUNNO which direction
                   1778:                  * Try old direction
                   1779:                  */
1.2       chuck    1780:                 GET_SBIC_data(regs, z);
1.1       chuck    1781:                 GET_SBIC_asr(regs, asr);
                   1782:
                   1783:                 if ( asr & SBIC_ASR_DBR ) /* Wants us to write */
1.2       chuck    1784:                     SET_SBIC_data(regs, z);
1.1       chuck    1785:             }
                   1786:
                   1787:             GET_SBIC_asr(regs, asr);
                   1788:         }
                   1789:
                   1790:         if ( asr & SBIC_ASR_LCI )
1.5       christos 1791:             printf("sbicpoll: LCI asr:%02x csr:%02x\n", asr,csr);
1.1       chuck    1792:         else
1.2       chuck    1793:         if ( i == SBIC_STATE_RUNNING ) /* BSY */
1.1       chuck    1794:             SBIC_WAIT(regs, SBIC_ASR_INT, sbic_cmd_wait);
                   1795:
                   1796:     } while ( i == SBIC_STATE_RUNNING );
                   1797:
                   1798:     return(1);
                   1799: }
                   1800:
                   1801: /*
                   1802:  * Handle a single msgin
                   1803:  */
                   1804: int
                   1805: sbicmsgin(dev)
                   1806:     struct sbic_softc   *dev;
                   1807: {
                   1808:     sbic_regmap_p       regs = dev->sc_sbicp;
                   1809:     int                 recvlen = 1;
                   1810:     u_char              asr,
                   1811:                         csr,
                   1812:                         *tmpaddr,
                   1813:                         *msgaddr;
                   1814:
                   1815:     tmpaddr = msgaddr = dev->sc_msg;
                   1816:
                   1817:     tmpaddr[0] = 0xff;
                   1818:     tmpaddr[1] = 0xff;
                   1819:
                   1820:     GET_SBIC_asr(regs, asr);
                   1821:
                   1822: #ifdef DEBUG
                   1823:     if ( reselect_debug > 1 )
1.5       christos 1824:         printf("sbicmsgin asr=%02x\n", asr);
1.1       chuck    1825: #endif
                   1826:
                   1827:     GET_SBIC_selid (regs, csr);
                   1828:     SET_SBIC_selid (regs, csr | SBIC_SID_FROM_SCSI);
                   1829:
                   1830:     SBIC_TC_PUT(regs, 0);
                   1831:     SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
                   1832:
                   1833:     do {
                   1834:         while( recvlen-- ) {
                   1835:
                   1836:             /*
                   1837:              * Fetch the next byte of the message
                   1838:              */
                   1839:             RECV_BYTE(regs, *tmpaddr);
                   1840:
                   1841:             /*
                   1842:              * get the command completion interrupt, or we
                   1843:              * can't send a new command (LCI)
                   1844:              */
                   1845:             SBIC_WAIT(regs, SBIC_ASR_INT, 0);
                   1846:             GET_SBIC_csr(regs, csr);
                   1847:
                   1848: #ifdef DEBUG
                   1849:             if ( reselect_debug > 1 )
1.5       christos 1850:                 printf("sbicmsgin: got %02x csr %02x\n", *tmpaddr, csr);
1.1       chuck    1851: #endif
                   1852:
                   1853:             tmpaddr++;
                   1854:
                   1855:             if ( recvlen ) {
                   1856:                 /*
                   1857:                  * Clear ACK, and wait for the interrupt for the next byte
                   1858:                  */
                   1859:                 SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
                   1860:                 SBIC_WAIT(regs, SBIC_ASR_INT, 0);
                   1861:                 GET_SBIC_csr(regs, csr);
                   1862:             }
                   1863:         }
                   1864:
                   1865:         if ( msgaddr[0] == 0xff ) {
1.5       christos 1866:             printf("sbicmsgin: sbic swallowed our message\n");
1.1       chuck    1867:             break;
                   1868:         }
                   1869:
                   1870: #ifdef DEBUG
                   1871:         if ( sync_debug ) {
                   1872:             GET_SBIC_asr(regs, asr);
1.5       christos 1873:             printf("msgin done csr 0x%x asr 0x%x msg 0x%x\n", csr, asr, msgaddr[0]);
1.1       chuck    1874:         }
                   1875: #endif
                   1876:         /*
                   1877:          * test whether this is a reply to our sync
                   1878:          * request
                   1879:          */
                   1880:         if ( MSG_ISIDENTIFY(msgaddr[0]) ) {
                   1881:
                   1882:             /*
                   1883:              * Got IFFY msg -- ack it
                   1884:              */
                   1885:             QPRINTF(("IFFY"));
                   1886:
                   1887:         } else
                   1888:         if ( msgaddr[0] == MSG_REJECT &&
                   1889:              dev->sc_sync[dev->target].state == SYNC_SENT) {
                   1890:
                   1891:             /*
                   1892:              * Target probably rejected our Sync negotiation.
                   1893:              */
                   1894:             QPRINTF(("REJECT of SYN"));
                   1895:
                   1896: #ifdef DEBUG
                   1897:             if ( sync_debug )
1.5       christos 1898:                 printf("target %d rejected sync, going async\n", dev->target);
1.1       chuck    1899: #endif
                   1900:
                   1901:             dev->sc_sync[dev->target].period = sbic_min_period;
                   1902:             dev->sc_sync[dev->target].offset = 0;
                   1903:             dev->sc_sync[dev->target].state  = SYNC_DONE;
                   1904:             SET_SBIC_syn(regs, SBIC_SYN(dev->sc_sync[dev->target].offset,
                   1905:                                         dev->sc_sync[dev->target].period));
                   1906:
                   1907:         } else
                   1908:         if ( msgaddr[0] == MSG_REJECT ) {
                   1909:
                   1910:             /*
                   1911:              * we'll never REJECt a REJECT message..
                   1912:              */
                   1913:             QPRINTF(("REJECT"));
                   1914:
                   1915:         } else
                   1916:         if ( msgaddr[0] == MSG_SAVE_DATA_PTR ) {
                   1917:
                   1918:             /*
                   1919:              * don't reject this either.
                   1920:              */
                   1921:             QPRINTF(("MSG_SAVE_DATA_PTR"));
                   1922:
                   1923:         } else
                   1924:         if ( msgaddr[0] == MSG_RESTORE_PTR ) {
                   1925:
                   1926:             /*
                   1927:              * don't reject this either.
                   1928:              */
                   1929:             QPRINTF(("MSG_RESTORE_PTR"));
                   1930:
                   1931:         } else
                   1932:         if ( msgaddr[0] == MSG_DISCONNECT ) {
                   1933:
                   1934:             /*
                   1935:              * Target is disconnecting...
                   1936:              */
                   1937:             QPRINTF(("DISCONNECT"));
                   1938:
                   1939: #ifdef DEBUG
                   1940:             if ( reselect_debug > 1 && msgaddr[0] == MSG_DISCONNECT )
1.5       christos 1941:                 printf("sbicmsgin: got disconnect msg %s\n",
1.1       chuck    1942:                        (dev->sc_flags & SBICF_ICMD) ? "rejecting" : "");
                   1943: #endif
                   1944:
                   1945:             if ( dev->sc_flags & SBICF_ICMD ) {
                   1946:                 /*
                   1947:                  * We're in immediate mode. Prevent disconnects.
                   1948:                  * prepare to reject the message, NACK
                   1949:                  */
                   1950:                 SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN);
                   1951:                 WAIT_CIP(regs);
                   1952:             }
                   1953:
                   1954:         } else
                   1955:         if ( msgaddr[0] == MSG_CMD_COMPLETE ) {
                   1956:
                   1957:             /*
                   1958:              * !! KLUDGE ALERT !! quite a few drives don't seem to
                   1959:              * really like the current way of sending the
                   1960:              * sync-handshake together with the ident-message, and
                   1961:              * they react by sending command-complete and
                   1962:              * disconnecting right after returning the valid sync
                   1963:              * handshake. So, all I can do is reselect the drive,
                   1964:              * and hope it won't disconnect again. I don't think
                   1965:              * this is valid behavior, but I can't help fixing a
                   1966:              * problem that apparently exists.
                   1967:              *
                   1968:              * Note: we should not get here on `normal' command
                   1969:              * completion, as that condition is handled by the
                   1970:              * high-level sel&xfer resume command used to walk
                   1971:              * thru status/cc-phase.
                   1972:              */
                   1973:             QPRINTF(("CMD_COMPLETE"));
                   1974:
                   1975: #ifdef DEBUG
                   1976:             if ( sync_debug )
1.5       christos 1977:                 printf ("GOT MSG %d! target %d acting weird.."
1.1       chuck    1978:                         " waiting for disconnect...\n", msgaddr[0], dev->target);
                   1979: #endif
                   1980:
                   1981:             /*
                   1982:              * Check to see if sbic is handling this
                   1983:              */
                   1984:             GET_SBIC_asr(regs, asr);
                   1985:
                   1986:             /*
                   1987:              * XXXSCW: I'm not convinced of this, we haven't negated ACK yet...
                   1988:              */
                   1989:             if ( asr & SBIC_ASR_BSY )
                   1990:                 return SBIC_STATE_RUNNING;
                   1991:
                   1992:             /*
                   1993:              * Let's try this: Assume it works and set status to 00
                   1994:              */
                   1995:             dev->sc_stat[0] = 0;
                   1996:
                   1997:         } else
                   1998:         if ( msgaddr[0] == MSG_EXT_MESSAGE && tmpaddr == &(msgaddr[1]) ) {
                   1999:
                   2000:             /*
                   2001:              * Target is sending us an extended message. We'll assume it's
                   2002:              * the response to our Sync. negotiation.
                   2003:              */
                   2004:             QPRINTF(("ExtMSG\n"));
                   2005:
                   2006:             /*
                   2007:              * Read in whole extended message. First, negate ACK to accept
                   2008:              * the MSG_EXT_MESSAGE byte...
                   2009:              */
                   2010:             SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
                   2011:
                   2012:             /*
                   2013:              * Wait for the interrupt for the next byte (length)
                   2014:              */
                   2015:             SBIC_WAIT(regs, SBIC_ASR_INT, 0);
                   2016:             GET_SBIC_csr(regs, csr);
                   2017:
                   2018: #ifdef  DEBUG
                   2019:             QPRINTF(("CLR ACK csr %02x\n", csr));
                   2020: #endif
                   2021:
                   2022:             /*
                   2023:              * Read the length byte
                   2024:              */
                   2025:             RECV_BYTE(regs, *tmpaddr);
                   2026:
                   2027:             /*
                   2028:              * Wait for command completion IRQ
                   2029:              */
                   2030:             SBIC_WAIT(regs, SBIC_ASR_INT, 0);
                   2031:             GET_SBIC_csr(regs, csr);
                   2032:
                   2033:             /*
                   2034:              * Reload the loop counter
                   2035:              */
                   2036:             recvlen = *tmpaddr++;
                   2037:
                   2038:             QPRINTF(("Recving ext msg, csr %02x len %02x\n", csr, recvlen));
                   2039:
                   2040:         } else
                   2041:         if ( msgaddr[0] == MSG_EXT_MESSAGE && msgaddr[1] == 3 &&
                   2042:              msgaddr[2] == MSG_SYNC_REQ ) {
                   2043:
                   2044:             /*
                   2045:              * We've received the complete Extended Message Sync. Request...
                   2046:              */
                   2047:             QPRINTF(("SYN"));
                   2048:
                   2049:             /*
                   2050:              * Compute the required Transfer Period for the WD chip...
                   2051:              */
                   2052:             dev->sc_sync[dev->target].period = sbicfromscsiperiod(dev, msgaddr[3]);
                   2053:             dev->sc_sync[dev->target].offset = msgaddr[4];
                   2054:             dev->sc_sync[dev->target].state  = SYNC_DONE;
                   2055:
                   2056:             /*
                   2057:              * Put the WD chip in synchronous mode
                   2058:              */
                   2059:             SET_SBIC_syn(regs, SBIC_SYN(dev->sc_sync[dev->target].offset,
                   2060:                                         dev->sc_sync[dev->target].period));
1.2       chuck    2061: #ifdef  DEBUG
                   2062:             if ( sync_debug )
1.5       christos 2063:                 printf("msgin(%d): sync reg = 0x%02x\n", dev->target,
1.2       chuck    2064:                                 SBIC_SYN(dev->sc_sync[dev->target].offset,
                   2065:                                          dev->sc_sync[dev->target].period));
                   2066: #endif
1.1       chuck    2067:
1.5       christos 2068:             printf("%s: target %d now synchronous, period=%dns, offset=%d.\n",
1.1       chuck    2069:                    dev->sc_dev.dv_xname, dev->target,
                   2070:                    msgaddr[3] * 4, msgaddr[4]);
                   2071:
                   2072:         } else {
                   2073:
                   2074:             /*
                   2075:              * We don't support whatever this message is...
                   2076:              */
                   2077: #ifdef DEBUG
                   2078:             if ( sbic_debug || sync_debug )
1.5       christos 2079:                 printf ("sbicmsgin: Rejecting message 0x%02x\n", msgaddr[0]);
1.1       chuck    2080: #endif
                   2081:
                   2082:             /*
                   2083:              * prepare to reject the message, NACK
                   2084:              */
                   2085:             SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN);
                   2086:             WAIT_CIP(regs);
                   2087:         }
                   2088:
                   2089:         /*
                   2090:          * Negate ACK to complete the transfer
                   2091:          */
                   2092:         SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
                   2093:
                   2094:         /*
                   2095:          * Wait for the interrupt for the next byte, or phase change.
                   2096:          * Only read the CSR if we have more data to transfer.
                   2097:          * XXXSCW: We should really verify that we're still in MSG IN phase
                   2098:          * before blindly going back around this loop, but that would mean
                   2099:          * we read the CSR... <sigh>
                   2100:          */
                   2101:         SBIC_WAIT(regs, SBIC_ASR_INT, 0);
                   2102:         if ( recvlen > 0 )
                   2103:             GET_SBIC_csr(regs, csr);
                   2104:
                   2105:     } while ( recvlen > 0 );
                   2106:
                   2107:     /*
                   2108:      * Should still have one CSR to read
                   2109:      */
                   2110:     return SBIC_STATE_RUNNING;
                   2111: }
                   2112:
                   2113:
                   2114: /*
                   2115:  * sbicnextstate()
                   2116:  * return:
1.2       chuck    2117:  *      SBIC_STATE_DONE        == done
                   2118:  *      SBIC_STATE_RUNNING     == working
                   2119:  *      SBIC_STATE_DISCONNECT  == disconnected
                   2120:  *      SBIC_STATE_ERROR       == error
1.1       chuck    2121:  */
                   2122: int
                   2123: sbicnextstate(dev, csr, asr)
                   2124:     struct sbic_softc   *dev;
                   2125:     u_char              csr,
                   2126:                         asr;
                   2127: {
                   2128:     sbic_regmap_p       regs = dev->sc_sbicp;
                   2129:     struct sbic_acb     *acb = dev->sc_nexus;
                   2130:
                   2131:     QPRINTF(("next[%02x,%02x]: ",asr,csr));
                   2132:
                   2133:     switch (csr) {
                   2134:
                   2135:       case SBIC_CSR_XFERRED | CMD_PHASE:
                   2136:       case SBIC_CSR_MIS     | CMD_PHASE:
                   2137:       case SBIC_CSR_MIS_1   | CMD_PHASE:
                   2138:       case SBIC_CSR_MIS_2   | CMD_PHASE:
                   2139:         {
                   2140:             if ( sbicxfout(regs, acb->clen, &acb->cmd) )
                   2141:                 goto abort;
                   2142:         }
                   2143:         break;
                   2144:
                   2145:       case SBIC_CSR_XFERRED | STATUS_PHASE:
                   2146:       case SBIC_CSR_MIS     | STATUS_PHASE:
                   2147:       case SBIC_CSR_MIS_1   | STATUS_PHASE:
                   2148:       case SBIC_CSR_MIS_2   | STATUS_PHASE:
                   2149:         {
                   2150:             SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
                   2151:
                   2152:             /*
                   2153:              * this should be the normal i/o completion case.
                   2154:              * get the status & cmd complete msg then let the
                   2155:              * device driver look at what happened.
                   2156:              */
                   2157:             sbicxfdone(dev);
                   2158:
                   2159: #ifdef DEBUG
                   2160:             dev->sc_dmatimo = 0;
                   2161:             if ( data_pointer_debug > 1 )
1.12      scw      2162:                 printf("next dmastop: %d(%p:%lx)\n", dev->target,
1.1       chuck    2163:                                                     dev->sc_cur->dc_addr,
                   2164:                                                     dev->sc_tcnt);
                   2165: #endif
                   2166:             /*
                   2167:              * Stop the DMA chip
                   2168:              */
                   2169:             dev->sc_dmastop(dev);
                   2170:
                   2171:             dev->sc_flags &= ~(SBICF_INDMA | SBICF_DCFLUSH);
                   2172:
                   2173:             /*
                   2174:              * Indicate to the upper layers that the command is done
                   2175:              */
                   2176:             sbic_scsidone(acb, dev->sc_stat[0]);
                   2177:
                   2178:             return SBIC_STATE_DONE;
                   2179:         }
                   2180:
                   2181:       case SBIC_CSR_XFERRED | DATA_OUT_PHASE:
                   2182:       case SBIC_CSR_XFERRED | DATA_IN_PHASE:
                   2183:       case SBIC_CSR_MIS     | DATA_OUT_PHASE:
                   2184:       case SBIC_CSR_MIS     | DATA_IN_PHASE:
                   2185:       case SBIC_CSR_MIS_1   | DATA_OUT_PHASE:
                   2186:       case SBIC_CSR_MIS_1   | DATA_IN_PHASE:
                   2187:       case SBIC_CSR_MIS_2   | DATA_OUT_PHASE:
                   2188:       case SBIC_CSR_MIS_2   | DATA_IN_PHASE:
                   2189:         {
                   2190:             /*
                   2191:              * Verify that we expected to transfer data...
                   2192:              */
                   2193:             if ( acb->sc_kv.dc_count <= 0 ) {
1.5       christos 2194:                 printf("next: DATA phase with xfer count == %d, asr:0x%02x csr:0x%02x\n",
1.1       chuck    2195:                         acb->sc_kv.dc_count, asr, csr);
                   2196:                 goto abort;
                   2197:             }
                   2198:
                   2199:             /*
                   2200:              * Should we transfer using PIO or DMA ?
                   2201:              */
1.10      thorpej  2202:             if ( dev->sc_xs->xs_control & XS_CTL_POLL || dev->sc_flags & SBICF_ICMD ||
1.1       chuck    2203:                  acb->sc_dmacmd == 0 ) {
                   2204:
                   2205:                 /*
                   2206:                  * Do PIO transfer
                   2207:                  */
                   2208:                 int     i;
                   2209:
                   2210: #ifdef DEBUG
                   2211:                 if ( data_pointer_debug > 1 )
1.12      scw      2212:                     printf("next PIO: %d(%p:%x)\n", dev->target,
1.1       chuck    2213:                                                     acb->sc_kv.dc_addr,
                   2214:                                                     acb->sc_kv.dc_count);
                   2215: #endif
                   2216:
                   2217:                 if ( SBIC_PHASE(csr) == DATA_IN_PHASE )
                   2218:                     /*
                   2219:                      * data in
                   2220:                      */
                   2221:                     i = sbicxfin(regs, acb->sc_kv.dc_count,
                   2222:                                        acb->sc_kv.dc_addr);
                   2223:                 else
                   2224:                     /*
                   2225:                      * data out
                   2226:                      */
                   2227:                     i = sbicxfout(regs, acb->sc_kv.dc_count,
                   2228:                                         acb->sc_kv.dc_addr);
                   2229:
                   2230:                 acb->sc_kv.dc_addr += (acb->sc_kv.dc_count - i);
                   2231:                 acb->sc_kv.dc_count = i;
                   2232:
                   2233:                 /*
                   2234:                  * Update current count...
                   2235:                  */
                   2236:                 acb->sc_tcnt = dev->sc_tcnt = i;
                   2237:
                   2238:                 dev->sc_flags &= ~SBICF_INDMA;
                   2239:
                   2240:             } else {
                   2241:
                   2242:                 /*
                   2243:                  * Do DMA transfer
1.21      wiz      2244:                  * set next DMA addr and dec count
1.1       chuck    2245:                  */
                   2246:                 sbic_save_ptrs(dev);
                   2247:                 sbic_load_ptrs(dev);
                   2248:
                   2249:                 SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI |
                   2250:                                        SBIC_MACHINE_DMA_MODE);
                   2251:
                   2252: #ifdef DEBUG
                   2253:                 dev->sc_dmatimo = 1;
                   2254:                 if ( data_pointer_debug > 1 )
1.12      scw      2255:                     printf("next DMA: %d(%p:%lx)\n", dev->target,
1.1       chuck    2256:                                                     dev->sc_cur->dc_addr,
                   2257:                                                     dev->sc_tcnt);
                   2258: #endif
                   2259:                 /*
                   2260:                  * Start the DMA chip going
                   2261:                  */
                   2262:                 dev->sc_tcnt = dev->sc_dmanext(dev);
                   2263:
                   2264:                 /*
                   2265:                  * Tell the WD chip how much to transfer this time around
                   2266:                  */
                   2267:                 SBIC_TC_PUT(regs, (unsigned)dev->sc_tcnt);
                   2268:
                   2269:                 /*
                   2270:                  * Start the transfer
                   2271:                  */
                   2272:                 SET_SBIC_cmd(regs, SBIC_CMD_XFER_INFO);
                   2273:
                   2274:                 /*
                   2275:                  * Indicate that we're in DMA mode
                   2276:                  */
                   2277:                 dev->sc_flags |= SBICF_INDMA;
                   2278:             }
                   2279:         }
                   2280:         break;
                   2281:
                   2282:       case SBIC_CSR_XFERRED | MESG_IN_PHASE:
                   2283:       case SBIC_CSR_MIS     | MESG_IN_PHASE:
                   2284:       case SBIC_CSR_MIS_1   | MESG_IN_PHASE:
                   2285:       case SBIC_CSR_MIS_2   | MESG_IN_PHASE:
                   2286:         {
                   2287:             sbic_save_ptrs(dev);
                   2288:
                   2289:             /*
                   2290:              * Handle a single message in...
                   2291:              */
                   2292:             return sbicmsgin(dev);
                   2293:         }
                   2294:
                   2295:       case SBIC_CSR_MSGIN_W_ACK:
                   2296:         {
                   2297:             /*
                   2298:              * We should never see this since it's handled in 'sbicmsgin()'
                   2299:              * but just for the sake of paranoia...
                   2300:              */
                   2301:             SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); /* Dunno what I'm ACKing */
1.5       christos 2302:             printf("Acking unknown msgin CSR:%02x",csr);
1.1       chuck    2303:         }
                   2304:         break;
                   2305:
                   2306:       case SBIC_CSR_XFERRED | MESG_OUT_PHASE:
                   2307:       case SBIC_CSR_MIS     | MESG_OUT_PHASE:
                   2308:       case SBIC_CSR_MIS_1   | MESG_OUT_PHASE:
                   2309:       case SBIC_CSR_MIS_2   | MESG_OUT_PHASE:
                   2310:         {
                   2311:             /*
                   2312:              * We only ever handle a message out phase here for sending a
                   2313:              * REJECT message.
                   2314:              */
                   2315:             sbic_save_ptrs(dev);
                   2316:
                   2317: #ifdef DEBUG
                   2318:             if (sync_debug)
1.5       christos 2319:                 printf ("sending REJECT msg to last msg.\n");
1.1       chuck    2320: #endif
                   2321:
                   2322:             SEND_BYTE(regs, MSG_REJECT);
                   2323:             WAIT_CIP(regs);
                   2324:         }
                   2325:         break;
                   2326:
                   2327:       case SBIC_CSR_DISC:
                   2328:       case SBIC_CSR_DISC_1:
                   2329:         {
                   2330:             /*
                   2331:              * Try to schedule another target
                   2332:              */
                   2333:             sbic_save_ptrs(dev);
                   2334:
                   2335:             dev->sc_flags &= ~SBICF_SELECTED;
                   2336:
                   2337: #ifdef DEBUG
                   2338:             if ( reselect_debug > 1 )
1.5       christos 2339:                 printf("sbicnext target %d disconnected\n", dev->target);
1.1       chuck    2340: #endif
                   2341:
                   2342:             TAILQ_INSERT_HEAD(&dev->nexus_list, acb, chain);
                   2343:
                   2344:             ++dev->sc_tinfo[dev->target].dconns;
                   2345:
                   2346:             dev->sc_nexus = NULL;
                   2347:             dev->sc_xs    = NULL;
                   2348:
1.10      thorpej  2349:             if ( acb->xs->xs_control & XS_CTL_POLL || dev->sc_flags & SBICF_ICMD ||
1.1       chuck    2350:                                                !sbic_parallel_operations )
                   2351:                 return SBIC_STATE_DISCONNECT;
                   2352:
                   2353:             QPRINTF(("sbicnext: calling sbic_sched\n"));
                   2354:
                   2355:             sbic_sched(dev);
                   2356:
                   2357:             QPRINTF(("sbicnext: sbic_sched returned\n"));
                   2358:
                   2359:             return SBIC_STATE_DISCONNECT;
                   2360:         }
                   2361:
                   2362:       case SBIC_CSR_RSLT_NI:
                   2363:       case SBIC_CSR_RSLT_IFY:
                   2364:         {
                   2365:             /*
                   2366:              * A reselection.
                   2367:              * Note that since we don't enable Advanced Features (assuming
                   2368:              * the WD chip is at least the 'A' revision), we're only ever
                   2369:              * likely to see the 'SBIC_CSR_RSLT_NI' status. But for the
                   2370:              * hell of it, we'll handle it anyway, for all the extra code
                   2371:              * it needs...
                   2372:              */
                   2373:             u_char  newtarget,
                   2374:                     newlun;
                   2375:
                   2376:             GET_SBIC_rselid(regs, newtarget);
                   2377:
                   2378:             /*
                   2379:              * check SBIC_RID_SIV?
                   2380:              */
                   2381:             newtarget &= SBIC_RID_MASK;
                   2382:
                   2383:             if ( csr == SBIC_CSR_RSLT_IFY ) {
                   2384:
                   2385:                 /*
                   2386:                  * Read Identify msg to avoid lockup
                   2387:                  */
                   2388:                 GET_SBIC_data(regs, newlun);
                   2389:                 WAIT_CIP(regs);
                   2390:                 newlun &= SBIC_TLUN_MASK;
                   2391:
                   2392:             } else {
                   2393:
                   2394:                 /*
                   2395:                  * Need to read Identify message the hard way, assuming
                   2396:                  * the target even sends us one...
                   2397:                  */
                   2398:                 for (newlun = 255; newlun; --newlun) {
                   2399:                     GET_SBIC_asr(regs, asr);
                   2400:                     if (asr & SBIC_ASR_INT)
                   2401:                         break;
1.2       chuck    2402:                     delay(10);
1.1       chuck    2403:                 }
                   2404:
                   2405:                 /*
                   2406:                  * If we didn't get an interrupt, somethink's up
                   2407:                  */
                   2408:                 if ( (asr & SBIC_ASR_INT) == 0 ) {
1.5       christos 2409:                     printf("%s: Reselect without identify? asr %x\n",
1.2       chuck    2410:                             dev->sc_dev.dv_xname, asr);
1.1       chuck    2411:                     newlun = 0; /* XXXX */
                   2412:                 } else {
                   2413:                     /*
                   2414:                      * We got an interrupt, verify that it's a change to
                   2415:                      * message in phase, and if so read the message.
                   2416:                      */
                   2417:                     GET_SBIC_csr(regs,csr);
                   2418:
1.12      scw      2419:                     if ( csr == (SBIC_CSR_MIS   | MESG_IN_PHASE) ||
                   2420:                          csr == (SBIC_CSR_MIS_1 | MESG_IN_PHASE) ||
                   2421:                          csr == (SBIC_CSR_MIS_2 | MESG_IN_PHASE) ) {
1.1       chuck    2422:                         /*
                   2423:                          * Yup, gone to message in. Fetch the target LUN
                   2424:                          */
                   2425:                         sbicmsgin(dev);
                   2426:                         newlun = dev->sc_msg[0] & 0x07;
                   2427:
                   2428:                     } else {
                   2429:                         /*
                   2430:                          * Whoops! Target didn't go to message in phase!!
                   2431:                          */
1.5       christos 2432:                         printf("RSLT_NI - not MESG_IN_PHASE %x\n", csr);
1.1       chuck    2433:                         newlun = 0; /* XXXSCW */
                   2434:                     }
                   2435:                 }
                   2436:             }
                   2437:
                   2438:             /*
                   2439:              * Ok, we have the identity of the reselecting target.
                   2440:              */
                   2441: #ifdef DEBUG
                   2442:             if ( reselect_debug > 1 ||
                   2443:                 (reselect_debug && csr == SBIC_CSR_RSLT_NI) ) {
1.5       christos 2444:                 printf("sbicnext: reselect %s from targ %d lun %d\n",
1.1       chuck    2445:                         csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY", newtarget, newlun);
                   2446:             }
                   2447: #endif
                   2448:
                   2449:             if ( dev->sc_nexus ) {
                   2450:                 /*
                   2451:                  * Whoops! We've been reselected with an command in progress!
                   2452:                  * The best we can do is to put the current command back on the
                   2453:                  * ready list and hope for the best.
                   2454:                  */
                   2455: #ifdef DEBUG
                   2456:                 if ( reselect_debug > 1 ) {
1.5       christos 2457:                     printf("%s: reselect %s with active command\n",
1.1       chuck    2458:                         dev->sc_dev.dv_xname,
                   2459:                         csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY");
                   2460:                 }
                   2461: #endif
                   2462:
                   2463:                 TAILQ_INSERT_HEAD(&dev->ready_list, dev->sc_nexus, chain);
                   2464:
                   2465:                 dev->sc_tinfo[dev->target].lubusy &= ~(1 << dev->lun);
                   2466:
                   2467:                 dev->sc_nexus = NULL;
                   2468:                 dev->sc_xs    = NULL;
                   2469:             }
                   2470:
                   2471:             /*
                   2472:              * Reload sync values for this target
                   2473:              */
                   2474:             if ( dev->sc_sync[newtarget].state == SYNC_DONE )
                   2475:                 SET_SBIC_syn(regs, SBIC_SYN (dev->sc_sync[newtarget].offset,
                   2476:                                              dev->sc_sync[newtarget].period));
                   2477:             else
                   2478:                 SET_SBIC_syn(regs, SBIC_SYN (0, sbic_min_period));
                   2479:
                   2480:             /*
                   2481:              * Loop through the nexus list until we find the saved entry
                   2482:              * for the reselecting target...
                   2483:              */
                   2484:             for (acb = dev->nexus_list.tqh_first; acb;
                   2485:                                                   acb = acb->chain.tqe_next) {
                   2486:
1.16      bouyer   2487:                 if ( acb->xs->xs_periph->periph_target == newtarget &&
                   2488:                      acb->xs->xs_periph->periph_lun    == newlun) {
1.1       chuck    2489:                     /*
                   2490:                      * We've found the saved entry. Dequeue it, and
                   2491:                      * make it current again.
                   2492:                      */
                   2493:                     TAILQ_REMOVE(&dev->nexus_list, acb, chain);
                   2494:
                   2495:                     dev->sc_nexus  = acb;
                   2496:                     dev->sc_xs     = acb->xs;
                   2497:                     dev->sc_flags |= SBICF_SELECTED;
                   2498:                     dev->target    = newtarget;
                   2499:                     dev->lun       = newlun;
                   2500:                     break;
                   2501:                 }
                   2502:             }
                   2503:
                   2504:             if ( acb == NULL ) {
1.12      scw      2505:                 printf("%s: reselect %s targ %d not in nexus_list %p\n",
1.1       chuck    2506:                         dev->sc_dev.dv_xname,
                   2507:                         csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY", newtarget,
                   2508:                         &dev->nexus_list.tqh_first);
                   2509:                 panic("bad reselect in sbic");
                   2510:             }
                   2511:
                   2512:             if ( csr == SBIC_CSR_RSLT_IFY )
                   2513:                 SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
                   2514:         }
                   2515:         break;
                   2516:
                   2517:       default:
                   2518:         abort:
                   2519:         {
                   2520:             /*
                   2521:              * Something unexpected happened -- deal with it.
                   2522:              */
1.5       christos 2523:             printf("next: aborting asr 0x%02x csr 0x%02x\n", asr, csr);
1.1       chuck    2524:
                   2525: #ifdef DDB
                   2526:             Debugger();
                   2527: #endif
                   2528:
                   2529: #ifdef DEBUG
                   2530:             dev->sc_dmatimo = 0;
                   2531:             if ( data_pointer_debug > 1 )
1.12      scw      2532:                 printf("next dmastop: %d(%p:%lx)\n", dev->target,
1.1       chuck    2533:                                                     dev->sc_cur->dc_addr,
                   2534:                                                     dev->sc_tcnt);
                   2535: #endif
                   2536:
                   2537:             dev->sc_dmastop(dev);
                   2538:             SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
                   2539:             if ( dev->sc_xs ) sbicerror(dev, csr);
                   2540:             sbicabort(dev, "next");
                   2541:
                   2542:             if ( dev->sc_flags & SBICF_INDMA ) {
                   2543:                 dev->sc_flags &= ~(SBICF_INDMA | SBICF_DCFLUSH);
                   2544:
                   2545: #ifdef DEBUG
                   2546:                 dev->sc_dmatimo = 0;
                   2547:                 if ( data_pointer_debug > 1 )
1.12      scw      2548:                     printf("next dmastop: %d(%p:%lx)\n", dev->target,
1.1       chuck    2549:                                                         dev->sc_cur->dc_addr,
                   2550:                                                         dev->sc_tcnt);
                   2551: #endif
                   2552:                 sbic_scsidone(acb, -1);
                   2553:             }
                   2554:
                   2555:             return SBIC_STATE_ERROR;
                   2556:         }
                   2557:     }
                   2558:
                   2559:     return(SBIC_STATE_RUNNING);
                   2560: }
                   2561:
                   2562:
                   2563: /*
                   2564:  * Check if DMA can not be used with specified buffer
                   2565:  */
                   2566: int
                   2567: sbiccheckdmap(bp, len, mask)
                   2568:     void    *bp;
                   2569:     u_long  len,
                   2570:             mask;
                   2571: {
                   2572:     u_char  *buffer;
                   2573:     u_long  phy_buf;
                   2574:     u_long  phy_len;
                   2575:
                   2576:     buffer = bp;
                   2577:
                   2578:     if ( len == 0 )
                   2579:         return(1);
                   2580:
                   2581:     while ( len ) {
                   2582:
1.12      scw      2583:         phy_buf = kvtop((caddr_t)buffer);
1.20      thorpej  2584:         phy_len = PAGE_SIZE - ((int) buffer & PGOFSET);
1.1       chuck    2585:
                   2586:         if ( len < phy_len )
                   2587:             phy_len = len;
                   2588:
                   2589:         if ( phy_buf & mask )
                   2590:             return(1);
                   2591:
                   2592:         buffer += phy_len;
                   2593:         len    -= phy_len;
                   2594:     }
                   2595:
                   2596:     return(0);
                   2597: }
                   2598:
                   2599: int
                   2600: sbictoscsiperiod(dev, a)
                   2601:     struct sbic_softc   *dev;
                   2602:     int                 a;
                   2603: {
                   2604:     unsigned int fs;
                   2605:
                   2606:     /*
                   2607:      * cycle = DIV / (2 * CLK)
                   2608:      * DIV = FS + 2
1.28    ! lukem    2609:      * best we can do is 200ns at 20 MHz, 2 cycles
1.1       chuck    2610:      */
                   2611:
                   2612:     GET_SBIC_myid(dev->sc_sbicp, fs);
                   2613:
                   2614:     fs = (fs >> 6) + 2;         /* DIV */
                   2615:
                   2616:     fs = (fs * 10000) / (dev->sc_clkfreq << 1); /* Cycle, in ns */
                   2617:
                   2618:     if ( a < 2 )
                   2619:         a = 8;                  /* map to Cycles */
                   2620:
                   2621:     return ( (fs * a) >> 2 );   /* in 4 ns units */
                   2622: }
                   2623:
                   2624: int
                   2625: sbicfromscsiperiod(dev, p)
                   2626:     struct sbic_softc   *dev;
                   2627:     int                 p;
                   2628: {
                   2629:     unsigned    fs,
                   2630:                 ret;
                   2631:
                   2632:     /*
                   2633:      * Just the inverse of the above
                   2634:      */
                   2635:     GET_SBIC_myid(dev->sc_sbicp, fs);
                   2636:
                   2637:     fs = (fs >> 6) + 2;     /* DIV */
                   2638:
                   2639:     fs = (fs * 10000) / (dev->sc_clkfreq << 1); /* Cycle, in ns */
                   2640:
                   2641:     ret = p << 2;           /* in ns units */
                   2642:     ret = ret / fs;         /* in Cycles */
                   2643:
                   2644:     if ( ret < sbic_min_period )
                   2645:         return(sbic_min_period);
                   2646:
                   2647:     /*
                   2648:      * verify rounding
                   2649:      */
                   2650:     if ( sbictoscsiperiod(dev, ret) < p )
                   2651:         ret++;
                   2652:
                   2653:     return( (ret >= 8) ? 0 : ret );
                   2654: }
                   2655:
                   2656: #ifdef DEBUG
                   2657: void
                   2658: sbictimeout(dev)
                   2659:     struct sbic_softc   *dev;
                   2660: {
                   2661:     int     s,
                   2662:             asr;
                   2663:
                   2664:     s = splbio();
                   2665:
                   2666:     if ( dev->sc_dmatimo ) {
                   2667:
                   2668:         if ( dev->sc_dmatimo > 1 ) {
                   2669:
1.21      wiz      2670:             printf("%s: DMA timeout #%d\n", dev->sc_dev.dv_xname,
1.1       chuck    2671:                                             dev->sc_dmatimo - 1);
                   2672:
                   2673:             GET_SBIC_asr(dev->sc_sbicp, asr);
                   2674:
                   2675:             if ( asr & SBIC_ASR_INT ) {
                   2676:                 /*
                   2677:                  * We need to service a missed IRQ
                   2678:                  */
                   2679:                 sbicintr(dev);
1.2       chuck    2680:             } else {
                   2681:                 (void) sbicabort(dev, "timeout");
                   2682:                 splx(s);
                   2683:                 return;
1.1       chuck    2684:             }
                   2685:         }
                   2686:
                   2687:         dev->sc_dmatimo++;
                   2688:     }
                   2689:
                   2690:     splx(s);
                   2691:
1.13      thorpej  2692:     callout_reset(&dev->sc_timo_ch, 30 * hz, (void *)sbictimeout, dev);
1.1       chuck    2693: }
                   2694: #endif

CVSweb <webmaster@jp.NetBSD.org>