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

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

1.1       nbrk        1: /*     $OpenBSD: ncr5380sbc.c,v 1.19 2006/12/10 16:15:37 miod Exp $    */
                      2: /*     $NetBSD: ncr5380sbc.c,v 1.13 1996/10/13 01:37:25 christos Exp $ */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 David Jones, Gordon W. Ross
                      6:  * Copyright (c) 1994 Jarle Greipsland
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. The name of the authors may not be used to endorse or promote products
                     18:  *    derived from this software without specific prior written permission.
                     19:  * 4. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *      This product includes software developed by
                     22:  *      David Jones and Gordon Ross
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
                     25:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     26:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     27:  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
                     28:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     29:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     30:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     31:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     32:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     33:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     34:  */
                     35:
                     36: /*
                     37:  * This is a machine-independent driver for the NCR5380
                     38:  * SCSI Bus Controller (SBC), also known as the Am5380.
                     39:  *
                     40:  * This code should work with any memory-mapped 5380,
                     41:  * and can be shared by multiple adapters that address
                     42:  * the 5380 with different register offset spacings.
                     43:  * (This can happen on the atari, for example.)
                     44:  * For porting/design info. see: ncr5380.doc
                     45:  *
                     46:  * Credits, history:
                     47:  *
                     48:  * David Jones is the author of most of the code that now
                     49:  * appears in this file, and was the architect of the
                     50:  * current overall structure (MI/MD code separation, etc.)
                     51:  *
                     52:  * Gordon Ross integrated the message phase code, added lots of
                     53:  * comments about what happens when and why (re. SCSI spec.),
                     54:  * debugged some reentrance problems, and added several new
                     55:  * "hooks" needed for the Sun3 "si" adapters.
                     56:  *
                     57:  * The message in/out code was taken nearly verbatim from
                     58:  * the aic6360 driver by Jarle Greipsland.
                     59:  *
                     60:  * Several other NCR5380 drivers were used for reference
                     61:  * while developing this driver, including work by:
                     62:  *   The Alice Group (mac68k port) namely:
                     63:  *       Allen K. Briggs, Chris P. Caputo, Michael L. Finch,
                     64:  *       Bradley A. Grantham, and Lawrence A. Kesteloot
                     65:  *   Michael L. Hitch (amiga drivers: sci.c)
                     66:  *   Leo Weppelman (atari driver: ncr5380.c)
                     67:  * There are others too.  Thanks, everyone.
                     68:  */
                     69:
                     70: #include <sys/types.h>
                     71: #include <sys/param.h>
                     72: #include <sys/systm.h>
                     73: #include <sys/kernel.h>
                     74: #include <sys/errno.h>
                     75: #include <sys/device.h>
                     76: #include <sys/buf.h>
                     77: #include <sys/proc.h>
                     78: #include <sys/user.h>
                     79:
                     80: #include <scsi/scsi_all.h>
                     81: #include <scsi/scsi_debug.h>
                     82: #include <scsi/scsi_message.h>
                     83: #include <scsi/scsiconf.h>
                     84:
                     85: #ifdef DDB
                     86: #include <ddb/db_output.h>
                     87: #endif
                     88:
                     89: #include <dev/ic/ncr5380reg.h>
                     90: #include <dev/ic/ncr5380var.h>
                     91:
                     92: static void    ncr5380_sched(struct ncr5380_softc *);
                     93: static void    ncr5380_done(struct ncr5380_softc *);
                     94:
                     95: static int     ncr5380_select(struct ncr5380_softc *, struct sci_req *);
                     96: static void    ncr5380_reselect(struct ncr5380_softc *);
                     97:
                     98: static int     ncr5380_msg_in(struct ncr5380_softc *);
                     99: static int     ncr5380_msg_out(struct ncr5380_softc *);
                    100: static int     ncr5380_data_xfer(struct ncr5380_softc *, int);
                    101: static int     ncr5380_command(struct ncr5380_softc *);
                    102: static int     ncr5380_status(struct ncr5380_softc *);
                    103: static void    ncr5380_machine(struct ncr5380_softc *);
                    104:
                    105: void   ncr5380_abort(struct ncr5380_softc *);
                    106: void   ncr5380_cmd_timeout(void *);
                    107: /*
                    108:  * Action flags returned by the info_transfer functions:
                    109:  * (These determine what happens next.)
                    110:  */
                    111: #define ACT_CONTINUE   0x00    /* No flags: expect another phase */
                    112: #define ACT_DISCONNECT 0x01    /* Target is disconnecting */
                    113: #define ACT_CMD_DONE   0x02    /* Need to call scsi_done() */
                    114: #define ACT_RESET_BUS  0x04    /* Need bus reset (cmd timeout) */
                    115: #define ACT_WAIT_DMA   0x10    /* Wait for DMA to complete */
                    116:
                    117: /*****************************************************************
                    118:  * Debugging stuff
                    119:  *****************************************************************/
                    120:
                    121: #ifndef DDB
                    122: /* This is used only in recoverable places. */
                    123: #define Debugger() printf("Debug: ncr5380.c:%d\n", __LINE__)
                    124: #endif
                    125:
                    126: #ifdef NCR5380_DEBUG
                    127:
                    128: #define        NCR_DBG_BREAK   1
                    129: #define        NCR_DBG_CMDS    2
                    130: int ncr5380_debug = NCR_DBG_BREAK|NCR_DBG_CMDS;
                    131: struct ncr5380_softc *ncr5380_debug_sc;
                    132:
                    133: #define        NCR_BREAK() \
                    134:        do { if (ncr5380_debug & NCR_DBG_BREAK) Debugger(); } while (0)
                    135:
                    136: static void ncr5380_show_scsi_cmd(struct scsi_xfer *);
                    137: static void ncr5380_show_sense(struct scsi_xfer *);
                    138:
                    139: #ifdef DDB
                    140: void ncr5380_trace(char *, long);
                    141: void ncr5380_clear_trace(void);
                    142: void ncr5380_show_trace(void);
                    143: void ncr5380_show_req(struct sci_req *);
                    144: void ncr5380_show_req(struct sci_req *);
                    145: void ncr5380_show_state(void);
                    146: #endif /* DDB */
                    147: #else  /* NCR5380_DEBUG */
                    148:
                    149: #define        NCR_BREAK()             /* nada */
                    150: #define ncr5380_show_scsi_cmd(xs) /* nada */
                    151: #define ncr5380_show_sense(xs) /* nada */
                    152:
                    153: #endif /* NCR5380_DEBUG */
                    154:
                    155: static char *
                    156: phase_names[8] = {
                    157:        "DATA_OUT",
                    158:        "DATA_IN",
                    159:        "COMMAND",
                    160:        "STATUS",
                    161:        "UNSPEC1",
                    162:        "UNSPEC2",
                    163:        "MSG_OUT",
                    164:        "MSG_IN",
                    165: };
                    166:
                    167: /*****************************************************************
                    168:  * Actual chip control
                    169:  *****************************************************************/
                    170:
                    171: /*
                    172:  * XXX: These timeouts might need to be tuned...
                    173:  */
                    174:
                    175: /* This one is used when waiting for a phase change. (X100uS.) */
                    176: int ncr5380_wait_phase_timo = 1000 * 10 * 300; /* 5 min. */
                    177:
                    178: /* These are used in the following inline functions. */
                    179: int ncr5380_wait_req_timo = 1000 * 50; /* X2 = 100 mS. */
                    180: int ncr5380_wait_nrq_timo = 1000 * 25; /* X2 =  50 mS. */
                    181:
                    182: static __inline int ncr5380_wait_req(struct ncr5380_softc *);
                    183: static __inline int ncr5380_wait_not_req(struct ncr5380_softc *);
                    184: static __inline void ncr_sched_msgout(struct ncr5380_softc *, int);
                    185:
                    186: /* Return zero on success. */
                    187: static __inline int ncr5380_wait_req(sc)
                    188:        struct ncr5380_softc *sc;
                    189: {
                    190:        register int timo = ncr5380_wait_req_timo;
                    191:        for (;;) {
                    192:                if (*sc->sci_bus_csr & SCI_BUS_REQ) {
                    193:                        timo = 0;       /* return 0 */
                    194:                        break;
                    195:                }
                    196:                if (--timo < 0)
                    197:                        break;  /* return -1 */
                    198:                delay(2);
                    199:        }
                    200:        return (timo);
                    201: }
                    202:
                    203: /* Return zero on success. */
                    204: static __inline int ncr5380_wait_not_req(sc)
                    205:        struct ncr5380_softc *sc;
                    206: {
                    207:        register int timo = ncr5380_wait_nrq_timo;
                    208:        for (;;) {
                    209:                if ((*sc->sci_bus_csr & SCI_BUS_REQ) == 0) {
                    210:                        timo = 0;       /* return 0 */
                    211:                        break;
                    212:                }
                    213:                if (--timo < 0)
                    214:                        break;  /* return -1 */
                    215:                delay(2);
                    216:        }
                    217:        return (timo);
                    218: }
                    219:
                    220: /* Ask the target for a MSG_OUT phase. */
                    221: static __inline void
                    222: ncr_sched_msgout(sc, msg_code)
                    223:        struct ncr5380_softc *sc;
                    224:        int msg_code;
                    225: {
                    226:        /* First time, raise ATN line. */
                    227:        if (sc->sc_msgpriq == 0) {
                    228:                register u_char icmd;
                    229:                icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
                    230:                *sc->sci_icmd = icmd | SCI_ICMD_ATN;
                    231:                delay(2);
                    232:        }
                    233:        sc->sc_msgpriq |= msg_code;
                    234: }
                    235:
                    236:
                    237: int
                    238: ncr5380_pio_out(sc, phase, count, data)
                    239:        struct ncr5380_softc *sc;
                    240:        int phase, count;
                    241:        unsigned char           *data;
                    242: {
                    243:        register u_char         icmd;
                    244:        register int            resid;
                    245:        register int            error;
                    246:
                    247:        icmd = *(sc->sci_icmd) & SCI_ICMD_RMASK;
                    248:
                    249:        icmd |= SCI_ICMD_DATA;
                    250:        *sc->sci_icmd = icmd;
                    251:
                    252:        resid = count;
                    253:        while (resid > 0) {
                    254:                if (!SCI_BUSY(sc)) {
                    255:                        NCR_TRACE("pio_out: lost BSY, resid=%d\n", resid);
                    256:                        break;
                    257:                }
                    258:                if (ncr5380_wait_req(sc)) {
                    259:                        NCR_TRACE("pio_out: no REQ, resid=%d\n", resid);
                    260:                        break;
                    261:                }
                    262:                if (SCI_BUS_PHASE(*sc->sci_bus_csr) != phase)
                    263:                        break;
                    264:
                    265:                /* Put the data on the bus. */
                    266:                if (data)
                    267:                        *sc->sci_odata = *data++;
                    268:                else
                    269:                        *sc->sci_odata = 0;
                    270:
                    271:                /* Tell the target it's there. */
                    272:                icmd |= SCI_ICMD_ACK;
                    273:                *sc->sci_icmd = icmd;
                    274:
                    275:                /* Wait for target to get it. */
                    276:                error = ncr5380_wait_not_req(sc);
                    277:
                    278:                /* OK, it's got it (or we gave up waiting). */
                    279:                icmd &= ~SCI_ICMD_ACK;
                    280:                *sc->sci_icmd = icmd;
                    281:
                    282:                if (error) {
                    283:                        NCR_TRACE("pio_out: stuck REQ, resid=%d\n", resid);
                    284:                        break;
                    285:                }
                    286:
                    287:                --resid;
                    288:        }
                    289:
                    290:        /* Stop driving the data bus. */
                    291:        icmd &= ~SCI_ICMD_DATA;
                    292:        *sc->sci_icmd = icmd;
                    293:
                    294:        return (count - resid);
                    295: }
                    296:
                    297:
                    298: int
                    299: ncr5380_pio_in(sc, phase, count, data)
                    300:        struct ncr5380_softc *sc;
                    301:        int phase, count;
                    302:        unsigned char                   *data;
                    303: {
                    304:        register u_char         icmd;
                    305:        register int            resid;
                    306:        register int            error;
                    307:
                    308:        icmd = *(sc->sci_icmd) & SCI_ICMD_RMASK;
                    309:
                    310:        resid = count;
                    311:        while (resid > 0) {
                    312:                if (!SCI_BUSY(sc)) {
                    313:                        NCR_TRACE("pio_in: lost BSY, resid=%d\n", resid);
                    314:                        break;
                    315:                }
                    316:                if (ncr5380_wait_req(sc)) {
                    317:                        NCR_TRACE("pio_in: no REQ, resid=%d\n", resid);
                    318:                        break;
                    319:                }
                    320:                /* A phase change is not valid until AFTER REQ rises! */
                    321:                if (SCI_BUS_PHASE(*sc->sci_bus_csr) != phase)
                    322:                        break;
                    323:
                    324:                /* Read the data bus. */
                    325:                if (data)
                    326:                        *data++ = *sc->sci_data;
                    327:                else
                    328:                        (void) *sc->sci_data;
                    329:
                    330:                /* Tell target we got it. */
                    331:                icmd |= SCI_ICMD_ACK;
                    332:                *sc->sci_icmd = icmd;
                    333:
                    334:                /* Wait for target to drop REQ... */
                    335:                error = ncr5380_wait_not_req(sc);
                    336:
                    337:                /* OK, we can drop ACK. */
                    338:                icmd &= ~SCI_ICMD_ACK;
                    339:                *sc->sci_icmd = icmd;
                    340:
                    341:                if (error) {
                    342:                        NCR_TRACE("pio_in: stuck REQ, resid=%d\n", resid);
                    343:                        break;
                    344:                }
                    345:
                    346:                --resid;
                    347:        }
                    348:
                    349:        return (count - resid);
                    350: }
                    351:
                    352:
                    353: void
                    354: ncr5380_init(sc)
                    355:        struct ncr5380_softc *sc;
                    356: {
                    357:        int i, j;
                    358:        struct sci_req *sr;
                    359:
                    360: #ifdef NCR5380_DEBUG
                    361:        ncr5380_debug_sc = sc;
                    362: #endif
                    363:
                    364:        for (i = 0; i < SCI_OPENINGS; i++) {
                    365:                sr = &sc->sc_ring[i];
                    366:                sr->sr_xs = NULL;
                    367:                timeout_set(&sr->sr_timeout, ncr5380_cmd_timeout, sr);
                    368:        }
                    369:        for (i = 0; i < 8; i++)
                    370:                for (j = 0; j < 8; j++)
                    371:                        sc->sc_matrix[i][j] = NULL;
                    372:
                    373:        sc->sc_link.openings = 2;       /* XXX - Not SCI_OPENINGS */
                    374:        sc->sc_prevphase = PHASE_INVALID;
                    375:        sc->sc_state = NCR_IDLE;
                    376:
                    377:        *sc->sci_tcmd = PHASE_INVALID;
                    378:        *sc->sci_icmd = 0;
                    379:        *sc->sci_mode = 0;
                    380:        *sc->sci_sel_enb = 0;
                    381:        SCI_CLR_INTR(sc);
                    382:
                    383:        /* XXX: Enable reselect interrupts... */
                    384:        *sc->sci_sel_enb = 0x80;
                    385:
                    386:        /* Another hack (Er.. hook!) for the sun3 si: */
                    387:        if (sc->sc_intr_on) {
                    388:                NCR_TRACE("init: intr ON\n", 0);
                    389:                sc->sc_intr_on(sc);
                    390:        }
                    391: }
                    392:
                    393:
                    394: void
                    395: ncr5380_reset_scsibus(sc)
                    396:        struct ncr5380_softc *sc;
                    397: {
                    398:
                    399:        NCR_TRACE("reset_scsibus, cur=0x%x\n",
                    400:                          (long) sc->sc_current);
                    401:
                    402:        *sc->sci_icmd = SCI_ICMD_RST;
                    403:        delay(500);
                    404:        *sc->sci_icmd = 0;
                    405:
                    406:        *sc->sci_mode = 0;
                    407:        *sc->sci_tcmd = PHASE_INVALID;
                    408:
                    409:        SCI_CLR_INTR(sc);
                    410:        /* XXX - Need long delay here! */
                    411:        delay(100000);
                    412:
                    413:        /* XXX - Need to cancel disconnected requests. */
                    414: }
                    415:
                    416:
                    417: /*
                    418:  * Interrupt handler for the SCSI Bus Controller (SBC)
                    419:  * This may also called for a DMA timeout (at splbio).
                    420:  */
                    421: int
                    422: ncr5380_intr(sc)
                    423:        struct ncr5380_softc *sc;
                    424: {
                    425:        int claimed = 0;
                    426:
                    427:        /*
                    428:         * Do not touch SBC regs here unless sc_current == NULL
                    429:         * or it will complain about "register conflict" errors.
                    430:         * Instead, just let ncr5380_machine() deal with it.
                    431:         */
                    432:        NCR_TRACE("intr: top, state=%d\n", sc->sc_state);
                    433:
                    434:        if (sc->sc_state == NCR_IDLE) {
                    435:                /*
                    436:                 * Might be reselect.  ncr5380_reselect() will check,
                    437:                 * and set up the connection if so.  This will verify
                    438:                 * that sc_current == NULL at the beginning...
                    439:                 */
                    440:
                    441:                /* Another hack (Er.. hook!) for the sun3 si: */
                    442:                if (sc->sc_intr_off) {
                    443:                        NCR_TRACE("intr: for reselect, intr off\n", 0);
                    444:                    sc->sc_intr_off(sc);
                    445:                }
                    446:
                    447:                ncr5380_reselect(sc);
                    448:        }
                    449:
                    450:        /*
                    451:         * The remaining documented interrupt causes are phase mismatch and
                    452:         * disconnect.  In addition, the sunsi controller may produce a state
                    453:         * where SCI_CSR_DONE is false, yet DMA is complete.
                    454:         *
                    455:         * The procedure in all these cases is to let ncr5380_machine()
                    456:         * figure out what to do next.
                    457:         */
                    458:        if (sc->sc_state & NCR_WORKING) {
                    459:                NCR_TRACE("intr: call machine, cur=0x%x\n",
                    460:                                  (long) sc->sc_current);
                    461:                /* This will usually free-up the nexus. */
                    462:                ncr5380_machine(sc);
                    463:                NCR_TRACE("intr: machine done, cur=0x%x\n",
                    464:                                  (long) sc->sc_current);
                    465:                claimed = 1;
                    466:        }
                    467:
                    468:        /* Maybe we can run some commands now... */
                    469:        if (sc->sc_state == NCR_IDLE) {
                    470:                NCR_TRACE("intr: call sched, cur=0x%x\n",
                    471:                                  (long) sc->sc_current);
                    472:                ncr5380_sched(sc);
                    473:                NCR_TRACE("intr: sched done, cur=0x%x\n",
                    474:                                  (long) sc->sc_current);
                    475:        }
                    476:
                    477:        return claimed;
                    478: }
                    479:
                    480:
                    481: /*
                    482:  * Abort the current command (i.e. due to timeout)
                    483:  */
                    484: void
                    485: ncr5380_abort(sc)
                    486:        struct ncr5380_softc *sc;
                    487: {
                    488:
                    489:        /*
                    490:         * Finish it now.  If DMA is in progress, we
                    491:         * can not call ncr_sched_msgout() because
                    492:         * that hits the SBC (avoid DMA conflict).
                    493:         */
                    494:
                    495:        /* Another hack (Er.. hook!) for the sun3 si: */
                    496:        if (sc->sc_intr_off) {
                    497:                NCR_TRACE("abort: intr off\n", 0);
                    498:                sc->sc_intr_off(sc);
                    499:        }
                    500:
                    501:        sc->sc_state |= NCR_ABORTING;
                    502:        if ((sc->sc_state & NCR_DOINGDMA) == 0) {
                    503:                ncr_sched_msgout(sc, SEND_ABORT);
                    504:        }
                    505:        NCR_TRACE("abort: call machine, cur=0x%x\n",
                    506:                          (long) sc->sc_current);
                    507:        ncr5380_machine(sc);
                    508:        NCR_TRACE("abort: machine done, cur=0x%x\n",
                    509:                          (long) sc->sc_current);
                    510:
                    511:        /* Another hack (Er.. hook!) for the sun3 si: */
                    512:        if (sc->sc_intr_on) {
                    513:                NCR_TRACE("abort: intr ON\n", 0);
                    514:            sc->sc_intr_on(sc);
                    515:        }
                    516: }
                    517:
                    518: /*
                    519:  * Timeout handler, scheduled for each SCSI command.
                    520:  */
                    521: void
                    522: ncr5380_cmd_timeout(arg)
                    523:        void *arg;
                    524: {
                    525:        struct sci_req *sr = arg;
                    526:        struct scsi_xfer *xs;
                    527:        struct scsi_link *sc_link;
                    528:        struct ncr5380_softc *sc;
                    529:        int s;
                    530:
                    531:        s = splbio();
                    532:
                    533:        /* Get all our variables... */
                    534:        xs = sr->sr_xs;
                    535:        if (xs == NULL) {
                    536:                printf("ncr5380_cmd_timeout: no scsi_xfer\n");
                    537:                goto out;
                    538:        }
                    539:        sc_link = xs->sc_link;
                    540:        sc = sc_link->adapter_softc;
                    541:
                    542:        printf("%s: cmd timeout, targ=%d, lun=%d\n",
                    543:            sc->sc_dev.dv_xname,
                    544:            sr->sr_target, sr->sr_lun);
                    545:
                    546:        /*
                    547:         * Mark the overdue job as failed, and arrange for
                    548:         * ncr5380_machine to terminate it.  If the victim
                    549:         * is the current job, call ncr5380_machine() now.
                    550:         * Otherwise arrange for ncr5380_sched() to do it.
                    551:         */
                    552:        sr->sr_flags |= SR_OVERDUE;
                    553:        if (sc->sc_current == sr) {
                    554:                NCR_TRACE("cmd_tmo: call abort, sr=0x%x\n", (long) sr);
                    555:                ncr5380_abort(sc);
                    556:        } else {
                    557:                /*
                    558:                 * The driver may be idle, or busy with another job.
                    559:                 * Arrange for ncr5380_sched() to do the deed.
                    560:                 */
                    561:                NCR_TRACE("cmd_tmo: clear matrix, t/l=0x%02x\n",
                    562:                                  (sr->sr_target << 4) | sr->sr_lun);
                    563:                sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
                    564:        }
                    565:
                    566:        /*
                    567:         * We may have aborted the current job, or may have
                    568:         * already been idle. In either case, we should now
                    569:         * be idle, so try to start another job.
                    570:         */
                    571:        if (sc->sc_state == NCR_IDLE) {
                    572:                NCR_TRACE("cmd_tmo: call sched, cur=0x%x\n",
                    573:                                  (long) sc->sc_current);
                    574:                ncr5380_sched(sc);
                    575:                NCR_TRACE("cmd_tmo: sched done, cur=0x%x\n",
                    576:                                  (long) sc->sc_current);
                    577:        }
                    578:
                    579: out:
                    580:        splx(s);
                    581: }
                    582:
                    583:
                    584: /*****************************************************************
                    585:  * Interface to higher level
                    586:  *****************************************************************/
                    587:
                    588:
                    589: /*
                    590:  * Enter a new SCSI command into the "issue" queue, and
                    591:  * if there is work to do, start it going.
                    592:  *
                    593:  * WARNING:  This can be called recursively!
                    594:  * (see comment in ncr5380_done)
                    595:  */
                    596: int
                    597: ncr5380_scsi_cmd(xs)
                    598:        struct scsi_xfer *xs;
                    599: {
                    600:        struct  ncr5380_softc *sc;
                    601:        struct sci_req  *sr;
                    602:        int s, rv, i, flags;
                    603:
                    604:        sc = xs->sc_link->adapter_softc;
                    605:        flags = xs->flags;
                    606:
                    607:        if (sc->sc_flags & NCR5380_FORCE_POLLING)
                    608:                flags |= SCSI_POLL;
                    609:
                    610:        if (flags & SCSI_DATA_UIO)
                    611:                panic("ncr5380: scsi data uio requested");
                    612:
                    613:        s = splbio();
                    614:
                    615:        if (flags & SCSI_POLL) {
                    616:                /* Terminate any current command. */
                    617:                sr = sc->sc_current;
                    618:                if (sr) {
                    619:                        printf("%s: polled request aborting %d/%d\n",
                    620:                            sc->sc_dev.dv_xname,
                    621:                            sr->sr_target, sr->sr_lun);
                    622:                        ncr5380_abort(sc);
                    623:                }
                    624:                if (sc->sc_state != NCR_IDLE) {
                    625:                        panic("ncr5380_scsi_cmd: polled request, abort failed");
                    626:                }
                    627:        }
                    628:
                    629:        /*
                    630:         * Find lowest empty slot in ring buffer.
                    631:         * XXX: What about "fairness" and cmd order?
                    632:         */
                    633:        for (i = 0; i < SCI_OPENINGS; i++)
                    634:                if (sc->sc_ring[i].sr_xs == NULL)
                    635:                        goto new;
                    636:
                    637:        rv = TRY_AGAIN_LATER;
                    638:        NCR_TRACE("scsi_cmd: no openings, rv=%d\n", rv);
                    639:        goto out;
                    640:
                    641: new:
                    642:        /* Create queue entry */
                    643:        sr = &sc->sc_ring[i];
                    644:        sr->sr_xs = xs;
                    645:        sr->sr_target = xs->sc_link->target;
                    646:        sr->sr_lun = xs->sc_link->lun;
                    647:        sr->sr_dma_hand = NULL;
                    648:        sr->sr_dataptr = xs->data;
                    649:        sr->sr_datalen = xs->datalen;
                    650:        sr->sr_flags = (flags & SCSI_POLL) ? SR_IMMED : 0;
                    651:        sr->sr_status = -1;     /* no value */
                    652:        sc->sc_ncmds++;
                    653:        rv = SUCCESSFULLY_QUEUED;
                    654:
                    655:        NCR_TRACE("scsi_cmd: new sr=0x%x\n", (long)sr);
                    656:
                    657:        if (flags & SCSI_POLL) {
                    658:                /* Force this new command to be next. */
                    659:                sc->sc_rr = i;
                    660:        }
                    661:
                    662:        /*
                    663:         * If we were idle, run some commands...
                    664:         */
                    665:        if (sc->sc_state == NCR_IDLE) {
                    666:                NCR_TRACE("scsi_cmd: call sched, cur=0x%x\n",
                    667:                                  (long) sc->sc_current);
                    668:                ncr5380_sched(sc);
                    669:                NCR_TRACE("scsi_cmd: sched done, cur=0x%x\n",
                    670:                                  (long) sc->sc_current);
                    671:        }
                    672:
                    673:        if (flags & SCSI_POLL) {
                    674: #ifdef DIAGNOSTIC
                    675:                /* Make sure ncr5380_sched() finished it. */
                    676:                if (sc->sc_state != NCR_IDLE)
                    677:                        panic("ncr5380_scsi_cmd: poll didn't finish");
                    678: #endif
                    679:                rv = COMPLETE;
                    680:        }
                    681:
                    682: out:
                    683:        splx(s);
                    684:        return (rv);
                    685: }
                    686:
                    687:
                    688: /*
                    689:  * POST PROCESSING OF SCSI_CMD (usually current)
                    690:  * Called by ncr5380_sched(), ncr5380_machine()
                    691:  */
                    692: static void
                    693: ncr5380_done(sc)
                    694:        struct ncr5380_softc *sc;
                    695: {
                    696:        struct  sci_req *sr;
                    697:        struct  scsi_xfer *xs;
                    698:
                    699: #ifdef DIAGNOSTIC
                    700:        if (sc->sc_state == NCR_IDLE)
                    701:                panic("ncr5380_done: state=idle");
                    702:        if (sc->sc_current == NULL)
                    703:                panic("ncr5380_done: current=0");
                    704: #endif
                    705:
                    706:        sr = sc->sc_current;
                    707:        xs = sr->sr_xs;
                    708:
                    709:        NCR_TRACE("done: top, cur=0x%x\n", (long) sc->sc_current);
                    710:
                    711:        /*
                    712:         * Clean up DMA resources for this command.
                    713:         */
                    714:        if (sr->sr_dma_hand) {
                    715:                NCR_TRACE("done: dma_free, dh=0x%x\n",
                    716:                                  (long) sr->sr_dma_hand);
                    717:                (*sc->sc_dma_free)(sc);
                    718:        }
                    719: #ifdef DIAGNOSTIC
                    720:        if (sr->sr_dma_hand)
                    721:                panic("ncr5380_done: dma free did not");
                    722: #endif
                    723:
                    724:        if (sc->sc_state & NCR_ABORTING) {
                    725:                NCR_TRACE("done: aborting, error=%d\n", xs->error);
                    726:                if (xs->error == XS_NOERROR)
                    727:                        xs->error = XS_TIMEOUT;
                    728:        }
                    729:
                    730:        NCR_TRACE("done: check error=%d\n", (long) xs->error);
                    731:
                    732:        /* If error is already set, ignore sr_status value. */
                    733:        if (xs->error != XS_NOERROR)
                    734:                goto finish;
                    735:
                    736:        NCR_TRACE("done: check status=%d\n", sr->sr_status);
                    737:
                    738:        switch (sr->sr_status) {
                    739:        case SCSI_OK:   /* 0 */
                    740:                if (sr->sr_flags & SR_SENSE) {
                    741: #ifdef NCR5380_DEBUG
                    742:                        if (ncr5380_debug & NCR_DBG_CMDS) {
                    743:                                ncr5380_show_sense(xs);
                    744:                        }
                    745: #endif
                    746:                        xs->error = XS_SENSE;
                    747:                }
                    748:                break;
                    749:
                    750:        case SCSI_CHECK:
                    751:                if (sr->sr_flags & SR_SENSE) {
                    752:                        /* Sense command also asked for sense? */
                    753:                        printf("ncr5380_done: sense asked for sense\n");
                    754:                        NCR_BREAK();
                    755:                        xs->error = XS_DRIVER_STUFFUP;
                    756:                        break;
                    757:                }
                    758:                sr->sr_flags |= SR_SENSE;
                    759:                NCR_TRACE("done: get sense, sr=0x%x\n", (long) sr);
                    760:                /*
                    761:                 * Leave queued, but clear sc_current so we start over
                    762:                 * with selection.  Guaranteed to get the same request.
                    763:                 */
                    764:                sc->sc_state = NCR_IDLE;
                    765:                sc->sc_current = NULL;
                    766:                sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
                    767:                return;         /* XXX */
                    768:
                    769:        case SCSI_BUSY:
                    770:                xs->error = XS_BUSY;
                    771:                break;
                    772:
                    773:        case -1:
                    774:                /* This is our "impossible" initial value. */
                    775:                /* fallthrough */
                    776:        default:
                    777:                printf("%s: target %d, bad status=%d\n",
                    778:                    sc->sc_dev.dv_xname, sr->sr_target, sr->sr_status);
                    779:                xs->error = XS_DRIVER_STUFFUP;
                    780:                break;
                    781:        }
                    782:
                    783: finish:
                    784:
                    785:        NCR_TRACE("done: finish, error=%d\n", xs->error);
                    786:
                    787:        /*
                    788:         * Dequeue the finished command, but don't clear sc_state until
                    789:         * after the call to scsi_done(), because that may call back to
                    790:         * ncr5380_scsi_cmd() - unwanted recursion!
                    791:         *
                    792:         * Keeping sc->sc_state != idle terminates the recursion.
                    793:         */
                    794: #ifdef DIAGNOSTIC
                    795:        if ((sc->sc_state & NCR_WORKING) == 0)
                    796:                panic("ncr5380_done: bad state");
                    797: #endif
                    798:
                    799:        /* Clear our pointers to the request. */
                    800:        sc->sc_current = NULL;
                    801:        sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
                    802:        timeout_del(&sr->sr_timeout);
                    803:
                    804:        /* Make the request free. */
                    805:        sr->sr_xs = NULL;
                    806:        sc->sc_ncmds--;
                    807:
                    808:        /* Tell common SCSI code it is done. */
                    809:        xs->flags |= ITSDONE;
                    810:        scsi_done(xs);
                    811:
                    812:        sc->sc_state = NCR_IDLE;
                    813:        /* Now ncr5380_sched() may be called again. */
                    814: }
                    815:
                    816:
                    817: /*
                    818:  * Schedule a SCSI operation.  This routine should return
                    819:  * only after it achieves one of the following conditions:
                    820:  *     Busy (sc->sc_state != NCR_IDLE)
                    821:  *     No more work can be started.
                    822:  */
                    823: static void
                    824: ncr5380_sched(sc)
                    825:        struct  ncr5380_softc *sc;
                    826: {
                    827:        struct sci_req  *sr;
                    828:        struct scsi_xfer *xs;
                    829:        int     target = 0, lun = 0;
                    830:        int     error, i;
                    831:
                    832:        /* Another hack (Er.. hook!) for the sun3 si: */
                    833:        if (sc->sc_intr_off) {
                    834:                NCR_TRACE("sched: top, intr off\n", 0);
                    835:            sc->sc_intr_off(sc);
                    836:        }
                    837:
                    838: next_job:
                    839:        /*
                    840:         * Grab the next job from queue.  Must be idle.
                    841:         */
                    842: #ifdef DIAGNOSTIC
                    843:        if (sc->sc_state != NCR_IDLE)
                    844:                panic("ncr5380_sched: not idle");
                    845:        if (sc->sc_current)
                    846:                panic("ncr5380_sched: current set");
                    847: #endif
                    848:
                    849:        /*
                    850:         * Always start the search where we last looked.
                    851:         * The REQUEST_SENSE logic depends on this to
                    852:         * choose the same job as was last picked, so it
                    853:         * can just clear sc_current and reschedule.
                    854:         * (Avoids loss of "contingent allegiance".)
                    855:         */
                    856:        i = sc->sc_rr;
                    857:        sr = NULL;
                    858:        do {
                    859:                if (sc->sc_ring[i].sr_xs) {
                    860:                        target = sc->sc_ring[i].sr_target;
                    861:                        lun = sc->sc_ring[i].sr_lun;
                    862:                        if (sc->sc_matrix[target][lun] == NULL) {
                    863:                                /*
                    864:                                 * Do not mark the  target/LUN busy yet,
                    865:                                 * because reselect may cause some other
                    866:                                 * job to become the current one, so we
                    867:                                 * might not actually start this job.
                    868:                                 * Instead, set sc_matrix later on.
                    869:                                 */
                    870:                                sc->sc_rr = i;
                    871:                                sr = &sc->sc_ring[i];
                    872:                                break;
                    873:                        }
                    874:                }
                    875:                i++;
                    876:                if (i == SCI_OPENINGS)
                    877:                        i = 0;
                    878:        } while (i != sc->sc_rr);
                    879:
                    880:        if (sr == NULL) {
                    881:                NCR_TRACE("sched: no work, cur=0x%x\n",
                    882:                                  (long) sc->sc_current);
                    883:
                    884:                /* Another hack (Er.. hook!) for the sun3 si: */
                    885:                if (sc->sc_intr_on) {
                    886:                        NCR_TRACE("sched: ret, intr ON\n", 0);
                    887:                        sc->sc_intr_on(sc);
                    888:                }
                    889:
                    890:                return;         /* No more work to do. */
                    891:        }
                    892:
                    893:        NCR_TRACE("sched: select for t/l=0x%02x\n",
                    894:                          (sr->sr_target << 4) | sr->sr_lun);
                    895:
                    896:        sc->sc_state = NCR_WORKING;
                    897:        error = ncr5380_select(sc, sr);
                    898:        if (sc->sc_current) {
                    899:                /* Lost the race!  reselected out from under us! */
                    900:                /* Work with the reselected job. */
                    901:                if (sr->sr_flags & SR_IMMED) {
                    902:                        printf("%s: reselected while polling (abort)\n",
                    903:                            sc->sc_dev.dv_xname);
                    904:                        /* Abort the reselected job. */
                    905:                        sc->sc_state |= NCR_ABORTING;
                    906:                        sc->sc_msgpriq |= SEND_ABORT;
                    907:                }
                    908:                sr = sc->sc_current;
                    909:                xs = sr->sr_xs;
                    910:                NCR_TRACE("sched: reselect, new sr=0x%x\n", (long)sr);
                    911:                goto have_nexus;
                    912:        }
                    913:
                    914:        /* Normal selection result.  Target/LUN is now busy. */
                    915:        sc->sc_matrix[target][lun] = sr;
                    916:        sc->sc_current = sr;    /* connected */
                    917:        xs = sr->sr_xs;
                    918:
                    919:        /*
                    920:         * Initialize pointers, etc. for this job
                    921:         */
                    922:        sc->sc_dataptr  = sr->sr_dataptr;
                    923:        sc->sc_datalen  = sr->sr_datalen;
                    924:        sc->sc_prevphase = PHASE_INVALID;
                    925:        sc->sc_msgpriq = SEND_IDENTIFY;
                    926:        sc->sc_msgoutq = 0;
                    927:        sc->sc_msgout  = 0;
                    928:
                    929:        NCR_TRACE("sched: select rv=%d\n", error);
                    930:
                    931:        switch (error) {
                    932:        case XS_NOERROR:
                    933:                break;
                    934:
                    935:        case XS_BUSY:
                    936:                /* XXX - Reset and try again. */
                    937:                printf("%s: select found SCSI bus busy, resetting...\n",
                    938:                    sc->sc_dev.dv_xname);
                    939:                ncr5380_reset_scsibus(sc);
                    940:                /* fallthrough */
                    941:        case XS_SELTIMEOUT:
                    942:        default:
                    943:                xs->error = error;      /* from select */
                    944:                NCR_TRACE("sched: call done, sr=0x%x\n", (long)sr);
                    945:                ncr5380_done(sc);
                    946:
                    947:                /* Paranoia: clear everything. */
                    948:                sc->sc_dataptr = NULL;
                    949:                sc->sc_datalen = 0;
                    950:                sc->sc_prevphase = PHASE_INVALID;
                    951:                sc->sc_msgpriq = 0;
                    952:                sc->sc_msgoutq = 0;
                    953:                sc->sc_msgout  = 0;
                    954:
                    955:                goto next_job;
                    956:        }
                    957:
                    958:        /*
                    959:         * Selection was successful.  Normally, this means
                    960:         * we are starting a new command.  However, this
                    961:         * might be the termination of an overdue job.
                    962:         */
                    963:        if (sr->sr_flags & SR_OVERDUE) {
                    964:                NCR_TRACE("sched: overdue, sr=0x%x\n", (long)sr);
                    965:                sc->sc_state |= NCR_ABORTING;
                    966:                sc->sc_msgpriq |= SEND_ABORT;
                    967:                goto have_nexus;
                    968:        }
                    969:
                    970:        /*
                    971:         * This may be the continuation of some job that
                    972:         * completed with a "check condition" code.
                    973:         */
                    974:        if (sr->sr_flags & SR_SENSE) {
                    975:                NCR_TRACE("sched: get sense, sr=0x%x\n", (long)sr);
                    976:                /* Do not allocate DMA, nor set timeout. */
                    977:                goto have_nexus;
                    978:        }
                    979:
                    980:        /*
                    981:         * OK, we are starting a new command.
                    982:         * Initialize and allocate resources for the new command.
                    983:         * Device reset is special (only uses MSG_OUT phase).
                    984:         * Normal commands start in MSG_OUT phase where we will
                    985:         * send and IDENDIFY message, and then expect CMD phase.
                    986:         */
                    987: #ifdef NCR5380_DEBUG
                    988:        if (ncr5380_debug & NCR_DBG_CMDS) {
                    989:                printf("ncr5380_sched: begin, target=%d, LUN=%d\n",
                    990:                    xs->sc_link->target, xs->sc_link->lun);
                    991:                ncr5380_show_scsi_cmd(xs);
                    992:        }
                    993: #endif
                    994:        if (xs->flags & SCSI_RESET) {
                    995:                NCR_TRACE("sched: cmd=reset, sr=0x%x\n", (long)sr);
                    996:                /* Not an error, so do not set NCR_ABORTING */
                    997:                sc->sc_msgpriq |= SEND_DEV_RESET;
                    998:                goto have_nexus;
                    999:        }
                   1000:
                   1001: #ifdef DIAGNOSTIC
                   1002:        if ((xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) == 0) {
                   1003:                if (sc->sc_dataptr) {
                   1004:                        printf("%s: ptr but no data in/out flags?\n",
                   1005:                            sc->sc_dev.dv_xname);
                   1006:                        NCR_BREAK();
                   1007:                        sc->sc_dataptr = NULL;
                   1008:                }
                   1009:        }
                   1010: #endif
                   1011:
                   1012:        /* Allocate DMA space (maybe) */
                   1013:        if (sc->sc_dataptr && sc->sc_dma_alloc &&
                   1014:                (sc->sc_datalen >= sc->sc_min_dma_len))
                   1015:        {
                   1016:                NCR_TRACE("sched: dma_alloc, len=%d\n", sc->sc_datalen);
                   1017:                (*sc->sc_dma_alloc)(sc);
                   1018:        }
                   1019:
                   1020:        /*
                   1021:         * Initialization hook called just after select,
                   1022:         * at the beginning of COMMAND phase.
                   1023:         * (but AFTER the DMA allocation is done)
                   1024:         *
                   1025:         * The evil Sun "si" adapter (OBIO variant) needs some
                   1026:         * setup done to the DMA engine BEFORE the target puts
                   1027:         * the SCSI bus into any DATA phase.
                   1028:         */
                   1029:        if (sr->sr_dma_hand && sc->sc_dma_setup) {
                   1030:                NCR_TRACE("sched: dma_setup, dh=0x%x\n",
                   1031:                                  (long) sr->sr_dma_hand);
                   1032:            sc->sc_dma_setup(sc);
                   1033:        }
                   1034:
                   1035:        /*
                   1036:         * Schedule a timeout for the job we are starting.
                   1037:         */
                   1038:        if ((sr->sr_flags & SR_IMMED) == 0) {
                   1039:                i = (xs->timeout * hz) / 1000;
                   1040:                NCR_TRACE("sched: set timeout=%d\n", i);
                   1041:                timeout_add(&sr->sr_timeout, i);
                   1042:        }
                   1043:
                   1044: have_nexus:
                   1045:        NCR_TRACE("sched: call machine, cur=0x%x\n",
                   1046:                          (long) sc->sc_current);
                   1047:        ncr5380_machine(sc);
                   1048:        NCR_TRACE("sched: machine done, cur=0x%x\n",
                   1049:                          (long) sc->sc_current);
                   1050:
                   1051:        /*
                   1052:         * What state did ncr5380_machine() leave us in?
                   1053:         * Hopefully it sometimes completes a job...
                   1054:         */
                   1055:        if (sc->sc_state == NCR_IDLE)
                   1056:                goto next_job;
                   1057:
                   1058:        return;         /* Have work in progress. */
                   1059: }
                   1060:
                   1061:
                   1062: /*
                   1063:  *  Reselect handler: checks for reselection, and if we are being
                   1064:  *     reselected, it sets up sc->sc_current.
                   1065:  *
                   1066:  *  We are reselected when:
                   1067:  *     SEL is TRUE
                   1068:  *     IO  is TRUE
                   1069:  *     BSY is FALSE
                   1070:  */
                   1071: void
                   1072: ncr5380_reselect(sc)
                   1073:        struct ncr5380_softc *sc;
                   1074: {
                   1075:        struct sci_req *sr;
                   1076:        int target, lun, phase, timo;
                   1077:        int target_mask;
                   1078:        u_char bus, data, icmd, msg;
                   1079:
                   1080: #ifdef DIAGNOSTIC
                   1081:        /*
                   1082:         * Note: sc_state will be "idle" when ncr5380_intr()
                   1083:         * calls, or "working" when ncr5380_select() calls.
                   1084:         * (So don't test that in this DIAGNOSTIC)
                   1085:         */
                   1086:        if (sc->sc_current)
                   1087:                panic("ncr5380_reselect: current set");
                   1088: #endif
                   1089:
                   1090:        /*
                   1091:         * First, check the select line.
                   1092:         * (That has to be set first.)
                   1093:         */
                   1094:        bus = *(sc->sci_bus_csr);
                   1095:        if ((bus & SCI_BUS_SEL) == 0) {
                   1096:                /* Not a selection or reselection. */
                   1097:                return;
                   1098:        }
                   1099:
                   1100:        /*
                   1101:         * The target will assert BSY first (for bus arbitration),
                   1102:         * then raise SEL, and finally drop BSY.  Only then is the
                   1103:         * data bus required to have valid selection ID bits set.
                   1104:         * Wait for: SEL==1, BSY==0 before reading the data bus.
                   1105:         * While this theoretically can happen, we are apparently
                   1106:         * never fast enough to get here before BSY drops.
                   1107:         */
                   1108:        timo = ncr5380_wait_nrq_timo;
                   1109:        for (;;) {
                   1110:                if ((bus & SCI_BUS_BSY) == 0)
                   1111:                        break;
                   1112:                /* Probably never get here... */
                   1113:                if (--timo <= 0) {
                   1114:                        printf("%s: reselect, BSY stuck, bus=0x%x\n",
                   1115:                            sc->sc_dev.dv_xname, bus);
                   1116:                        /* Not much we can do. Reset the bus. */
                   1117:                        ncr5380_reset_scsibus(sc);
                   1118:                        return;
                   1119:                }
                   1120:                delay(2);
                   1121:                bus = *(sc->sci_bus_csr);
                   1122:                /* If SEL went away, forget it. */
                   1123:                if ((bus & SCI_BUS_SEL) == 0)
                   1124:                        return;
                   1125:                /* Still have SEL, check BSY. */
                   1126:        }
                   1127:        NCR_TRACE("reselect, valid data after %d loops\n",
                   1128:                          ncr5380_wait_nrq_timo - timo);
                   1129:
                   1130:        /*
                   1131:         * Good.  We have SEL=1 and BSY=0.  Now wait for a
                   1132:         * "bus settle delay" before we sample the data bus
                   1133:         */
                   1134:        delay(2);
                   1135:        data = *(sc->sci_data) & 0xFF;
                   1136:        /* Parity check is implicit in data validation below. */
                   1137:
                   1138:        /*
                   1139:         * Is this a reselect (I/O == 1) or have we been
                   1140:         * selected as a target? (I/O == 0)
                   1141:         */
                   1142:        if ((bus & SCI_BUS_IO) == 0) {
                   1143:                printf("%s: selected as target, data=0x%x\n",
                   1144:                    sc->sc_dev.dv_xname, data);
                   1145:                /* Not much we can do. Reset the bus. */
                   1146:                /* XXX: send some sort of message? */
                   1147:                ncr5380_reset_scsibus(sc);
                   1148:                return;
                   1149:        }
                   1150:
                   1151:        /*
                   1152:         * OK, this is a reselection.
                   1153:         */
                   1154:        for (target = 0; target < 7; target++) {
                   1155:                target_mask = (1 << target);
                   1156:                if (data & target_mask)
                   1157:                        break;
                   1158:        }
                   1159:        if ((data & 0x7F) != target_mask) {
                   1160:                /* No selecting ID? or >2 IDs on bus? */
                   1161:                printf("%s: bad reselect, data=0x%x\n",
                   1162:                    sc->sc_dev.dv_xname, data);
                   1163:                return;
                   1164:        }
                   1165:
                   1166:        NCR_TRACE("reselect: target=0x%x\n", target);
                   1167:
                   1168:        /* Raise BSY to acknowledge target reselection. */
                   1169:        *(sc->sci_icmd) = SCI_ICMD_BSY;
                   1170:
                   1171:        /* Wait for target to drop SEL. */
                   1172:        timo = ncr5380_wait_nrq_timo;
                   1173:        for (;;) {
                   1174:                bus = *(sc->sci_bus_csr);
                   1175:                if ((bus & SCI_BUS_SEL) == 0)
                   1176:                        break;  /* success */
                   1177:                if (--timo <= 0) {
                   1178:                        printf("%s: reselect, SEL stuck, bus=0x%x\n",
                   1179:                            sc->sc_dev.dv_xname, bus);
                   1180:                        NCR_BREAK();
                   1181:                        /* assume connected (fail later if not) */
                   1182:                        break;
                   1183:                }
                   1184:                delay(2);
                   1185:        }
                   1186:
                   1187:        /* Now we drop BSY, and we are connected. */
                   1188:        *(sc->sci_icmd) = 0;
                   1189:        *sc->sci_sel_enb = 0;
                   1190:        SCI_CLR_INTR(sc);
                   1191:
                   1192:        /*
                   1193:         * At this point the target should send an IDENTIFY message,
                   1194:         * which will permit us to determine the reselecting LUN.
                   1195:         * If not, we assume LUN 0.
                   1196:         */
                   1197:        lun = 0;
                   1198:        /* Wait for REQ before reading bus phase. */
                   1199:        if (ncr5380_wait_req(sc)) {
                   1200:                printf("%s: reselect, no REQ\n",
                   1201:                    sc->sc_dev.dv_xname);
                   1202:                /* Try to send an ABORT message. */
                   1203:                goto abort;
                   1204:        }
                   1205:        phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
                   1206:        if (phase != PHASE_MSG_IN) {
                   1207:                printf("%s: reselect, phase=%d\n",
                   1208:                    sc->sc_dev.dv_xname, phase);
                   1209:                goto abort;
                   1210:        }
                   1211:
                   1212:        /* Ack. the change to PHASE_MSG_IN */
                   1213:        *(sc->sci_tcmd) = PHASE_MSG_IN;
                   1214:
                   1215:        /* Peek at the message byte without consuming it! */
                   1216:        msg = *(sc->sci_data);
                   1217:        if ((msg & 0x80) == 0) {
                   1218:                printf("%s: reselect, not identify, msg=%d\n",
                   1219:                    sc->sc_dev.dv_xname, msg);
                   1220:                goto abort;
                   1221:        }
                   1222:        lun = msg & 7;
                   1223:
                   1224:        /* We now know target/LUN.  Do we have the request? */
                   1225:        sr = sc->sc_matrix[target][lun];
                   1226:        if (sr) {
                   1227:                /* We now have a nexus. */
                   1228:                sc->sc_state |= NCR_WORKING;
                   1229:                sc->sc_current = sr;
                   1230:                NCR_TRACE("reselect: resume sr=0x%x\n", (long)sr);
                   1231:
                   1232:                /* Implicit restore pointers message */
                   1233:                sc->sc_dataptr = sr->sr_dataptr;
                   1234:                sc->sc_datalen = sr->sr_datalen;
                   1235:
                   1236:                sc->sc_prevphase = PHASE_INVALID;
                   1237:                sc->sc_msgpriq = 0;
                   1238:                sc->sc_msgoutq = 0;
                   1239:                sc->sc_msgout  = 0;
                   1240:
                   1241:                /* XXX: Restore the normal mode register. */
                   1242:                /* If this target's bit is set, do NOT check parity. */
                   1243:                if (sc->sc_parity_disable & target_mask)
                   1244:                        *sc->sci_mode = (SCI_MODE_MONBSY);
                   1245:                else
                   1246:                        *sc->sci_mode = (SCI_MODE_MONBSY | SCI_MODE_PAR_CHK);
                   1247:
                   1248:                /*
                   1249:                 * Another hack for the Sun3 "si", which needs
                   1250:                 * some setup done to its DMA engine before the
                   1251:                 * target puts the SCSI bus into any DATA phase.
                   1252:                 */
                   1253:                if (sr->sr_dma_hand && sc->sc_dma_setup) {
                   1254:                        NCR_TRACE("reselect: call DMA setup, dh=0x%x\n",
                   1255:                                          (long) sr->sr_dma_hand);
                   1256:                    sc->sc_dma_setup(sc);
                   1257:                }
                   1258:
                   1259:                /* Now consume the IDENTIFY message. */
                   1260:                ncr5380_pio_in(sc, PHASE_MSG_IN, 1, &msg);
                   1261:                return;
                   1262:        }
                   1263:
                   1264:        printf("%s: phantom reselect: target=%d, LUN=%d\n",
                   1265:            sc->sc_dev.dv_xname, target, lun);
                   1266: abort:
                   1267:        /*
                   1268:         * Try to send an ABORT message.  This makes us
                   1269:         * temporarily busy, but no current command...
                   1270:         */
                   1271:        sc->sc_state |= NCR_ABORTING;
                   1272:
                   1273:        /* Raise ATN, delay, raise ACK... */
                   1274:        icmd = SCI_ICMD_ATN;
                   1275:        *sc->sci_icmd = icmd;
                   1276:        delay(2);
                   1277:
                   1278:        /* Now consume the IDENTIFY message. */
                   1279:        ncr5380_pio_in(sc, PHASE_MSG_IN, 1, &msg);
                   1280:
                   1281:        /* Finally try to send the ABORT. */
                   1282:        sc->sc_prevphase = PHASE_INVALID;
                   1283:        sc->sc_msgpriq = SEND_ABORT;
                   1284:        ncr5380_msg_out(sc);
                   1285:
                   1286:        *(sc->sci_tcmd) = PHASE_INVALID;
                   1287:        *sc->sci_sel_enb = 0;
                   1288:        SCI_CLR_INTR(sc);
                   1289:        *sc->sci_sel_enb = 0x80;
                   1290:
                   1291:        sc->sc_state &= ~NCR_ABORTING;
                   1292: }
                   1293:
                   1294:
                   1295: /*
                   1296:  *  Select target: xs is the transfer that we are selecting for.
                   1297:  *  sc->sc_current should be NULL.
                   1298:  *
                   1299:  *  Returns:
                   1300:  *     sc->sc_current != NULL  ==> we were reselected (race!)
                   1301:  *     XS_NOERROR              ==> selection worked
                   1302:  *     XS_BUSY                 ==> lost arbitration
                   1303:  *     XS_SELTIMEOUT           ==> no response to selection
                   1304:  */
                   1305: static int
                   1306: ncr5380_select(sc, sr)
                   1307:        struct ncr5380_softc *sc;
                   1308:        struct sci_req *sr;
                   1309: {
                   1310:        int timo, s, target_mask;
                   1311:        u_char data, icmd;
                   1312:
                   1313:        /* Check for reselect */
                   1314:        ncr5380_reselect(sc);
                   1315:        if (sc->sc_current) {
                   1316:                NCR_TRACE("select: reselect, cur=0x%x\n",
                   1317:                                  (long) sc->sc_current);
                   1318:                return XS_BUSY; /* reselected */
                   1319:        }
                   1320:
                   1321:        /*
                   1322:         * Set phase bits to 0, otherwise the 5380 won't drive the bus during
                   1323:         * selection.
                   1324:         */
                   1325:        *sc->sci_tcmd = PHASE_DATA_OUT;
                   1326:        *sc->sci_icmd = icmd = 0;
                   1327:        *sc->sci_mode = 0;
                   1328:
                   1329:        /*
                   1330:         * Arbitrate for the bus.  The 5380 takes care of the
                   1331:         * time-critical bus interactions.  We set our ID bit
                   1332:         * in the output data register and set MODE_ARB.  The
                   1333:         * 5380 watches for the required "bus free" period.
                   1334:         * If and when the "bus free" period is detected, the
                   1335:         * 5380 drives BSY, drives the data bus, and sets the
                   1336:         * "arbitration in progress" (AIP) bit to let us know
                   1337:         * arbitration has started (and that it asserts BSY).
                   1338:         * We then wait for one arbitration delay (2.2uS) and
                   1339:         * check the ICMD_LST bit, which will be set if some
                   1340:         * other target drives SEL during arbitration.
                   1341:         *
                   1342:         * There is a time-critical section during the period
                   1343:         * after we enter arbitration up until we assert SEL.
                   1344:         * Avoid long interrupts during this period.
                   1345:         */
                   1346:        s = splvm();    /* XXX: Begin time-critical section */
                   1347:
                   1348:        *(sc->sci_odata) = 0x80;        /* OUR_ID */
                   1349:        *(sc->sci_mode) = SCI_MODE_ARB;
                   1350:
                   1351: #define        WAIT_AIP_USEC   20      /* pleanty of time */
                   1352:        /* Wait for the AIP bit to turn on. */
                   1353:        timo = WAIT_AIP_USEC;
                   1354:        for (;;) {
                   1355:                if (*(sc->sci_icmd) & SCI_ICMD_AIP)
                   1356:                        break;
                   1357:                if (timo <= 0) {
                   1358:                        /*
                   1359:                         * Did not see any "bus free" period.
                   1360:                         * The usual reason is a reselection,
                   1361:                         * so treat this as arbitration loss.
                   1362:                         */
                   1363:                        NCR_TRACE("select: bus busy, rc=%d\n", XS_BUSY);
                   1364:                        goto lost_arb;
                   1365:                }
                   1366:                timo -= 2;
                   1367:                delay(2);
                   1368:        }
                   1369:        NCR_TRACE("select: have AIP after %d uSec.\n",
                   1370:                          WAIT_AIP_USEC - timo);
                   1371:
                   1372:        /* Got AIP.  Wait one arbitration delay (2.2 uS.) */
                   1373:        delay(3);
                   1374:
                   1375:        /* Check for ICMD_LST */
                   1376:        if (*(sc->sci_icmd) & SCI_ICMD_LST) {
                   1377:                /* Some other target asserted SEL. */
                   1378:                NCR_TRACE("select: lost one, rc=%d\n", XS_BUSY);
                   1379:                goto lost_arb;
                   1380:        }
                   1381:
                   1382:        /*
                   1383:         * No other device has declared itself the winner.
                   1384:         * The spec. says to check for higher IDs, but we
                   1385:         * are always the highest (ID=7) so don't bother.
                   1386:         * We can now declare victory by asserting SEL.
                   1387:         *
                   1388:         * Note that the 5380 is asserting BSY because we
                   1389:         * have entered arbitration mode.  We will now hold
                   1390:         * BSY directly so we can turn off ARB mode.
                   1391:         */
                   1392:        icmd = (SCI_ICMD_BSY | SCI_ICMD_SEL);
                   1393:        *sc->sci_icmd = icmd;
                   1394:
                   1395:        /*
                   1396:         * "The SCSI device that wins arbitration shall wait
                   1397:         *  at least a bus clear delay plus a bus settle delay
                   1398:         *  after asserting the SEL signal before changing
                   1399:         *  any [other] signal."  (1.2uS. total)
                   1400:         */
                   1401:        delay(2);
                   1402:
                   1403:        /*
                   1404:         * Check one last time to see if we really did
                   1405:         * win arbitration.  This might only happen if
                   1406:         * there can be a higher selection ID than ours.
                   1407:         * Keep this code for reference anyway...
                   1408:         */
                   1409:        if (*(sc->sci_icmd) & SCI_ICMD_LST) {
                   1410:                /* Some other target asserted SEL. */
                   1411:                NCR_TRACE("select: lost two, rc=%d\n", XS_BUSY);
                   1412:
                   1413:        lost_arb:
                   1414:                *sc->sci_icmd = 0;
                   1415:                *sc->sci_mode = 0;
                   1416:
                   1417:                splx(s);        /* XXX: End of time-critical section. */
                   1418:
                   1419:                /*
                   1420:                 * When we lose arbitration, it usually means
                   1421:                 * there is a target trying to reselect us.
                   1422:                 */
                   1423:                ncr5380_reselect(sc);
                   1424:                return XS_BUSY;
                   1425:        }
                   1426:
                   1427:        /* Leave ARB mode Now that we drive BSY+SEL */
                   1428:        *sc->sci_mode = 0;
                   1429:        *sc->sci_sel_enb = 0;
                   1430:
                   1431:        splx(s);        /* XXX: End of time-critical section. */
                   1432:
                   1433:        /*
                   1434:         * Arbitration is complete.  Now do selection:
                   1435:         * Drive the data bus with the ID bits for both
                   1436:         * the host and target.  Also set ATN now, to
                   1437:         * ask the target for a message out phase.
                   1438:         */
                   1439:        target_mask = (1 << sr->sr_target);
                   1440:        data = 0x80 | target_mask;
                   1441:        *(sc->sci_odata) = data;
                   1442:        icmd |= (SCI_ICMD_DATA | SCI_ICMD_ATN);
                   1443:        *(sc->sci_icmd) = icmd;
                   1444:        delay(2);       /* two deskew delays. */
                   1445:
                   1446:        /* De-assert BSY (targets sample the data now). */
                   1447:        icmd &= ~SCI_ICMD_BSY;
                   1448:        *(sc->sci_icmd) = icmd;
                   1449:        delay(3);       /* Bus settle delay. */
                   1450:
                   1451:        /*
                   1452:         * Wait for the target to assert BSY.
                   1453:         * SCSI spec. says wait for 250 mS.
                   1454:         */
                   1455:        for (timo = 25000;;) {
                   1456:                if (*sc->sci_bus_csr & SCI_BUS_BSY)
                   1457:                        goto success;
                   1458:                if (--timo <= 0)
                   1459:                        break;
                   1460:                delay(10);
                   1461:        }
                   1462:
                   1463:        /*
                   1464:         * There is no reaction from the target.  Start the selection
                   1465:         * timeout procedure. We release the databus but keep SEL+ATN
                   1466:         * asserted. After that we wait a 'selection abort time' (200
                   1467:         * usecs) and 2 deskew delays (90 ns) and check BSY again.
                   1468:         * When BSY is asserted, we assume the selection succeeded,
                   1469:         * otherwise we release the bus.
                   1470:         */
                   1471:        icmd &= ~SCI_ICMD_DATA;
                   1472:        *(sc->sci_icmd) = icmd;
                   1473:        delay(201);
                   1474:        if ((*sc->sci_bus_csr & SCI_BUS_BSY) == 0) {
                   1475:                /* Really no device on bus */
                   1476:                *sc->sci_tcmd = PHASE_INVALID;
                   1477:                *sc->sci_icmd = 0;
                   1478:                *sc->sci_mode = 0;
                   1479:                *sc->sci_sel_enb = 0;
                   1480:                SCI_CLR_INTR(sc);
                   1481:                *sc->sci_sel_enb = 0x80;
                   1482:                NCR_TRACE("select: device down, rc=%d\n", XS_SELTIMEOUT);
                   1483:                return XS_SELTIMEOUT;
                   1484:        }
                   1485:
                   1486: success:
                   1487:        /*
                   1488:         * The target is now driving BSY, so we can stop
                   1489:         * driving SEL and the data bus (keep ATN true).
                   1490:         * Configure the ncr5380 to monitor BSY, parity.
                   1491:         */
                   1492:        icmd &= ~(SCI_ICMD_DATA | SCI_ICMD_SEL);
                   1493:        *sc->sci_icmd = icmd;
                   1494:
                   1495:        /* If this target's bit is set, do NOT check parity. */
                   1496:        if (sc->sc_parity_disable & target_mask)
                   1497:                *sc->sci_mode = (SCI_MODE_MONBSY);
                   1498:        else
                   1499:                *sc->sci_mode = (SCI_MODE_MONBSY | SCI_MODE_PAR_CHK);
                   1500:
                   1501:        return XS_NOERROR;
                   1502: }
                   1503:
                   1504:
                   1505: /*****************************************************************
                   1506:  * Functions to handle each info. transfer phase:
                   1507:  *****************************************************************/
                   1508:
                   1509: /*
                   1510:  * The message system:
                   1511:  *
                   1512:  * This is a revamped message system that now should easier accommodate
                   1513:  * new messages, if necessary.
                   1514:  *
                   1515:  * Currently we accept these messages:
                   1516:  * IDENTIFY (when reselecting)
                   1517:  * COMMAND COMPLETE # (expect bus free after messages marked #)
                   1518:  * NOOP
                   1519:  * MESSAGE REJECT
                   1520:  * SYNCHRONOUS DATA TRANSFER REQUEST
                   1521:  * SAVE DATA POINTER
                   1522:  * RESTORE POINTERS
                   1523:  * DISCONNECT #
                   1524:  *
                   1525:  * We may send these messages in prioritized order:
                   1526:  * BUS DEVICE RESET #          if SCSI_RESET & xs->flags (or in weird sits.)
                   1527:  * MESSAGE PARITY ERROR                par. err. during MSGI
                   1528:  * MESSAGE REJECT              If we get a message we don't know how to handle
                   1529:  * ABORT #                     send on errors
                   1530:  * INITIATOR DETECTED ERROR    also on errors (SCSI2) (during info xfer)
                   1531:  * IDENTIFY                    At the start of each transfer
                   1532:  * SYNCHRONOUS DATA TRANSFER REQUEST   if appropriate
                   1533:  * NOOP                                if nothing else fits the bill ...
                   1534:  */
                   1535:
                   1536: #define IS1BYTEMSG(m) (((m) != 0x01 && (m) < 0x20) || (m) >= 0x80)
                   1537: #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
                   1538: #define ISEXTMSG(m) ((m) == 0x01)
                   1539:
                   1540: /*
                   1541:  * Precondition:
                   1542:  * The SCSI bus is already in the MSGI phase and there is a message byte
                   1543:  * on the bus, along with an asserted REQ signal.
                   1544:  *
                   1545:  * Our return value determines whether our caller, ncr5380_machine()
                   1546:  * will expect to see another REQ (and possibly phase change).
                   1547:  */
                   1548: static int
                   1549: ncr5380_msg_in(sc)
                   1550:        register struct ncr5380_softc *sc;
                   1551: {
                   1552:        struct sci_req *sr = sc->sc_current;
                   1553:        struct scsi_xfer *xs = sr->sr_xs;
                   1554:        int n, phase;
                   1555:        int act_flags;
                   1556:        register u_char icmd;
                   1557:
                   1558:        /* acknowledge phase change */
                   1559:        *sc->sci_tcmd = PHASE_MSG_IN;
                   1560:
                   1561:        act_flags = ACT_CONTINUE;
                   1562:        icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
                   1563:
                   1564:        if (sc->sc_prevphase == PHASE_MSG_IN) {
                   1565:                /* This is a continuation of the previous message. */
                   1566:                n = sc->sc_imp - sc->sc_imess;
                   1567:                NCR_TRACE("msg_in: continuation, n=%d\n", n);
                   1568:                goto nextbyte;
                   1569:        }
                   1570:
                   1571:        /* This is a new MESSAGE IN phase.  Clean up our state. */
                   1572:        sc->sc_state &= ~NCR_DROP_MSGIN;
                   1573:
                   1574: nextmsg:
                   1575:        n = 0;
                   1576:        sc->sc_imp = &sc->sc_imess[n];
                   1577:
                   1578: nextbyte:
                   1579:        /*
                   1580:         * Read a whole message, but don't ack the last byte.  If we reject the
                   1581:         * message, we have to assert ATN during the message transfer phase
                   1582:         * itself.
                   1583:         */
                   1584:        for (;;) {
                   1585:                /*
                   1586:                 * Read a message byte.
                   1587:                 * First, check BSY, REQ, phase...
                   1588:                 */
                   1589:                if (!SCI_BUSY(sc)) {
                   1590:                        NCR_TRACE("msg_in: lost BSY, n=%d\n", n);
                   1591:                        /* XXX - Assume the command completed? */
                   1592:                        act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
                   1593:                        return (act_flags);
                   1594:                }
                   1595:                if (ncr5380_wait_req(sc)) {
                   1596:                        NCR_TRACE("msg_in: BSY but no REQ, n=%d\n", n);
                   1597:                        /* Just let ncr5380_machine() handle it... */
                   1598:                        return (act_flags);
                   1599:                }
                   1600:                phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
                   1601:                if (phase != PHASE_MSG_IN) {
                   1602:                        /*
                   1603:                         * Target left MESSAGE IN, probably because it
                   1604:                         * a) noticed our ATN signal, or
                   1605:                         * b) ran out of messages.
                   1606:                         */
                   1607:                        return (act_flags);
                   1608:                }
                   1609:                /* Still in MESSAGE IN phase, and REQ is asserted. */
                   1610:                if (*sc->sci_csr & SCI_CSR_PERR) {
                   1611:                        ncr_sched_msgout(sc, SEND_PARITY_ERROR);
                   1612:                        sc->sc_state |= NCR_DROP_MSGIN;
                   1613:                }
                   1614:
                   1615:                /* Gather incoming message bytes if needed. */
                   1616:                if ((sc->sc_state & NCR_DROP_MSGIN) == 0) {
                   1617:                        if (n >= NCR_MAX_MSG_LEN) {
                   1618:                                ncr_sched_msgout(sc, SEND_REJECT);
                   1619:                                sc->sc_state |= NCR_DROP_MSGIN;
                   1620:                        } else {
                   1621:                                *sc->sc_imp++ = *sc->sci_data;
                   1622:                                n++;
                   1623:                                /*
                   1624:                                 * This testing is suboptimal, but most
                   1625:                                 * messages will be of the one byte variety, so
                   1626:                                 * it should not affect performance
                   1627:                                 * significantly.
                   1628:                                 */
                   1629:                                if (n == 1 && IS1BYTEMSG(sc->sc_imess[0]))
                   1630:                                        goto have_msg;
                   1631:                                if (n == 2 && IS2BYTEMSG(sc->sc_imess[0]))
                   1632:                                        goto have_msg;
                   1633:                                if (n >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
                   1634:                                        n == sc->sc_imess[1] + 2)
                   1635:                                        goto have_msg;
                   1636:                        }
                   1637:                }
                   1638:
                   1639:                /*
                   1640:                 * If we reach this spot we're either:
                   1641:                 * a) in the middle of a multi-byte message, or
                   1642:                 * b) dropping bytes.
                   1643:                 */
                   1644:
                   1645:                /* Ack the last byte read. */
                   1646:                icmd |= SCI_ICMD_ACK;
                   1647:                *sc->sci_icmd = icmd;
                   1648:
                   1649:                if (ncr5380_wait_not_req(sc)) {
                   1650:                        NCR_TRACE("msg_in: drop, stuck REQ, n=%d\n", n);
                   1651:                        act_flags |= ACT_RESET_BUS;
                   1652:                }
                   1653:
                   1654:                icmd &= ~SCI_ICMD_ACK;
                   1655:                *sc->sci_icmd = icmd;
                   1656:
                   1657:                if (act_flags != ACT_CONTINUE)
                   1658:                        return (act_flags);
                   1659:
                   1660:                /* back to nextbyte */
                   1661:        }
                   1662:
                   1663: have_msg:
                   1664:        /* We now have a complete message.  Parse it. */
                   1665:
                   1666:        switch (sc->sc_imess[0]) {
                   1667:        case MSG_CMDCOMPLETE:
                   1668:                NCR_TRACE("msg_in: CMDCOMPLETE\n", 0);
                   1669:                /* Target is about to disconnect. */
                   1670:                act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
                   1671:                break;
                   1672:
                   1673:        case MSG_PARITY_ERROR:
                   1674:                NCR_TRACE("msg_in: PARITY_ERROR\n", 0);
                   1675:                /* Resend the last message. */
                   1676:                ncr_sched_msgout(sc, sc->sc_msgout);
                   1677:                /* Reset icmd after scheduling the REJECT cmd - jwg */
                   1678:                icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
                   1679:                break;
                   1680:
                   1681:        case MSG_MESSAGE_REJECT:
                   1682:                /* The target rejects the last message we sent. */
                   1683:                NCR_TRACE("msg_in: got reject for 0x%x\n", sc->sc_msgout);
                   1684:                switch (sc->sc_msgout) {
                   1685:                case SEND_IDENTIFY:
                   1686:                        /* Really old target controller? */
                   1687:                        /* XXX ... */
                   1688:                        break;
                   1689:                case SEND_INIT_DET_ERR:
                   1690:                        goto abort;
                   1691:                }
                   1692:                break;
                   1693:
                   1694:        case MSG_NOOP:
                   1695:                NCR_TRACE("msg_in: NOOP\n", 0);
                   1696:                break;
                   1697:
                   1698:        case MSG_DISCONNECT:
                   1699:                NCR_TRACE("msg_in: DISCONNECT\n", 0);
                   1700:                /* Target is about to disconnect. */
                   1701:                act_flags |= ACT_DISCONNECT;
                   1702:                if ((xs->sc_link->quirks & SDEV_AUTOSAVE) == 0)
                   1703:                        break;
                   1704:                /*FALLTHROUGH*/
                   1705:
                   1706:        case MSG_SAVEDATAPOINTER:
                   1707:                NCR_TRACE("msg_in: SAVE_PTRS\n", 0);
                   1708:                sr->sr_dataptr = sc->sc_dataptr;
                   1709:                sr->sr_datalen = sc->sc_datalen;
                   1710:                break;
                   1711:
                   1712:        case MSG_RESTOREPOINTERS:
                   1713:                NCR_TRACE("msg_in: RESTORE_PTRS\n", 0);
                   1714:                sc->sc_dataptr = sr->sr_dataptr;
                   1715:                sc->sc_datalen = sr->sr_datalen;
                   1716:                break;
                   1717:
                   1718:        case MSG_EXTENDED:
                   1719:                switch (sc->sc_imess[2]) {
                   1720:                case MSG_EXT_SDTR:
                   1721:                case MSG_EXT_WDTR:
                   1722:                        /* The ncr5380 can not do synchronous mode. */
                   1723:                        goto reject;
                   1724:                default:
                   1725:                        printf("%s: unrecognized MESSAGE EXTENDED; sending REJECT\n",
                   1726:                            sc->sc_dev.dv_xname);
                   1727:                        NCR_BREAK();
                   1728:                        goto reject;
                   1729:                }
                   1730:                break;
                   1731:
                   1732:        default:
                   1733:                NCR_TRACE("msg_in: eh? imsg=0x%x\n", sc->sc_imess[0]);
                   1734:                printf("%s: unrecognized MESSAGE; sending REJECT\n",
                   1735:                    sc->sc_dev.dv_xname);
                   1736:                NCR_BREAK();
                   1737:                /* fallthrough */
                   1738:        reject:
                   1739:                ncr_sched_msgout(sc, SEND_REJECT);
                   1740:                /* Reset icmd after scheduling the REJECT cmd - jwg */
                   1741:                icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
                   1742:                break;
                   1743:
                   1744:        abort:
                   1745:                sc->sc_state |= NCR_ABORTING;
                   1746:                ncr_sched_msgout(sc, SEND_ABORT);
                   1747:                break;
                   1748:        }
                   1749:
                   1750:        /* Ack the last byte read. */
                   1751:        icmd |= SCI_ICMD_ACK;
                   1752:        *sc->sci_icmd = icmd;
                   1753:
                   1754:        if (ncr5380_wait_not_req(sc)) {
                   1755:                NCR_TRACE("msg_in: last, stuck REQ, n=%d\n", n);
                   1756:                act_flags |= ACT_RESET_BUS;
                   1757:        }
                   1758:
                   1759:        icmd &= ~SCI_ICMD_ACK;
                   1760:        *sc->sci_icmd = icmd;
                   1761:
                   1762:        /* Go get the next message, if any. */
                   1763:        if (act_flags == ACT_CONTINUE)
                   1764:                goto nextmsg;
                   1765:
                   1766:        return (act_flags);
                   1767: }
                   1768:
                   1769:
                   1770: /*
                   1771:  * The message out (and in) stuff is a bit complicated:
                   1772:  * If the target requests another message (sequence) without
                   1773:  * having changed phase in between it really asks for a
                   1774:  * retransmit, probably due to parity error(s).
                   1775:  * The following messages can be sent:
                   1776:  * IDENTIFY       @ These 4 stem from SCSI command activity
                   1777:  * SDTR                   @
                   1778:  * WDTR                   @
                   1779:  * DEV_RESET      @
                   1780:  * REJECT if MSGI doesn't make sense
                   1781:  * PARITY_ERROR if parity error while in MSGI
                   1782:  * INIT_DET_ERR if parity error while not in MSGI
                   1783:  * ABORT if INIT_DET_ERR rejected
                   1784:  * NOOP if asked for a message and there's nothing to send
                   1785:  *
                   1786:  * Note that we call this one with (sc_current == NULL)
                   1787:  * when sending ABORT for unwanted reselections.
                   1788:  */
                   1789: static int
                   1790: ncr5380_msg_out(sc)
                   1791:        register struct ncr5380_softc *sc;
                   1792: {
                   1793:        struct sci_req *sr = sc->sc_current;
                   1794:        int act_flags, n, phase, progress;
                   1795:        register u_char icmd, msg;
                   1796:
                   1797:        /* acknowledge phase change */
                   1798:        *sc->sci_tcmd = PHASE_MSG_OUT;
                   1799:
                   1800:        progress = 0;   /* did we send any messages? */
                   1801:        act_flags = ACT_CONTINUE;
                   1802:
                   1803:        /*
                   1804:         * Set ATN.  If we're just sending a trivial 1-byte message,
                   1805:         * we'll clear ATN later on anyway.  Also drive the data bus.
                   1806:         */
                   1807:        icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
                   1808:        icmd |= (SCI_ICMD_ATN | SCI_ICMD_DATA);
                   1809:        *sc->sci_icmd = icmd;
                   1810:
                   1811:        if (sc->sc_prevphase == PHASE_MSG_OUT) {
                   1812:                if (sc->sc_omp == sc->sc_omess) {
                   1813:                        /*
                   1814:                         * This is a retransmission.
                   1815:                         *
                   1816:                         * We get here if the target stayed in MESSAGE OUT
                   1817:                         * phase.  Section 5.1.9.2 of the SCSI 2 spec indicates
                   1818:                         * that all of the previously transmitted messages must
                   1819:                         * be sent again, in the same order.  Therefore, we
                   1820:                         * requeue all the previously transmitted messages, and
                   1821:                         * start again from the top.  Our simple priority
                   1822:                         * scheme keeps the messages in the right order.
                   1823:                         */
                   1824:                        sc->sc_msgpriq |= sc->sc_msgoutq;
                   1825:                        NCR_TRACE("msg_out: retrans priq=0x%x\n", sc->sc_msgpriq);
                   1826:                } else {
                   1827:                        /* This is a continuation of the previous message. */
                   1828:                        n = sc->sc_omp - sc->sc_omess;
                   1829:                        NCR_TRACE("msg_out: continuation, n=%d\n", n);
                   1830:                        goto nextbyte;
                   1831:                }
                   1832:        }
                   1833:
                   1834:        /* No messages transmitted so far. */
                   1835:        sc->sc_msgoutq = 0;
                   1836:
                   1837: nextmsg:
                   1838:        /* Pick up highest priority message. */
                   1839:        sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
                   1840:        sc->sc_msgpriq &= ~sc->sc_msgout;
                   1841:        sc->sc_msgoutq |= sc->sc_msgout;
                   1842:
                   1843:        /* Build the outgoing message data. */
                   1844:        switch (sc->sc_msgout) {
                   1845:        case SEND_IDENTIFY:
                   1846:                NCR_TRACE("msg_out: SEND_IDENTIFY\n", 0);
                   1847:                if (sr == NULL) {
                   1848:                        printf("%s: SEND_IDENTIFY while not connected; sending NOOP\n",
                   1849:                            sc->sc_dev.dv_xname);
                   1850:                        NCR_BREAK();
                   1851:                        goto noop;
                   1852:                }
                   1853:                /*
                   1854:                 * The identify message we send determines whether
                   1855:                 * disconnect/reselect is allowed for this command.
                   1856:                 * 0xC0+LUN: allows it, 0x80+LUN disallows it.
                   1857:                 */
                   1858:                msg = 0xc0;     /* MSG_IDENTIFY(0,1) */
                   1859:                if (sc->sc_no_disconnect & (1 << sr->sr_target))
                   1860:                        msg = 0x80;
                   1861:                if (sr->sr_flags & (SR_IMMED | SR_SENSE))
                   1862:                        msg = 0x80;
                   1863:                sc->sc_omess[0] = msg | sr->sr_lun;
                   1864:                n = 1;
                   1865:                break;
                   1866:
                   1867:        case SEND_DEV_RESET:
                   1868:                NCR_TRACE("msg_out: SEND_DEV_RESET\n", 0);
                   1869:                /* Expect disconnect after this! */
                   1870:                /* XXX: Kill jobs for this target? */
                   1871:                act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
                   1872:                sc->sc_omess[0] = MSG_BUS_DEV_RESET;
                   1873:                n = 1;
                   1874:                break;
                   1875:
                   1876:        case SEND_REJECT:
                   1877:                NCR_TRACE("msg_out: SEND_REJECT\n", 0);
                   1878:                sc->sc_omess[0] = MSG_MESSAGE_REJECT;
                   1879:                n = 1;
                   1880:                break;
                   1881:
                   1882:        case SEND_PARITY_ERROR:
                   1883:                NCR_TRACE("msg_out: SEND_PARITY_ERROR\n", 0);
                   1884:                sc->sc_omess[0] = MSG_PARITY_ERROR;
                   1885:                n = 1;
                   1886:                break;
                   1887:
                   1888:        case SEND_INIT_DET_ERR:
                   1889:                NCR_TRACE("msg_out: SEND_INIT_DET_ERR\n", 0);
                   1890:                sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
                   1891:                n = 1;
                   1892:                break;
                   1893:
                   1894:        case SEND_ABORT:
                   1895:                NCR_TRACE("msg_out: SEND_ABORT\n", 0);
                   1896:                /* Expect disconnect after this! */
                   1897:                /* XXX: Set error flag? */
                   1898:                act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
                   1899:                sc->sc_omess[0] = MSG_ABORT;
                   1900:                n = 1;
                   1901:                break;
                   1902:
                   1903:        case 0:
                   1904:                printf("%s: unexpected MESSAGE OUT; sending NOOP\n",
                   1905:                    sc->sc_dev.dv_xname);
                   1906:                NCR_BREAK();
                   1907:        noop:
                   1908:                NCR_TRACE("msg_out: send NOOP\n", 0);
                   1909:                sc->sc_omess[0] = MSG_NOOP;
                   1910:                n = 1;
                   1911:                break;
                   1912:
                   1913:        default:
                   1914:                printf("%s: weird MESSAGE OUT; sending NOOP\n",
                   1915:                    sc->sc_dev.dv_xname);
                   1916:                NCR_BREAK();
                   1917:                goto noop;
                   1918:        }
                   1919:        sc->sc_omp = &sc->sc_omess[n];
                   1920:
                   1921: nextbyte:
                   1922:        /* Send message bytes. */
                   1923:        while (n > 0) {
                   1924:                /*
                   1925:                 * Send a message byte.
                   1926:                 * First check BSY, REQ, phase...
                   1927:                 */
                   1928:                if (!SCI_BUSY(sc)) {
                   1929:                        NCR_TRACE("msg_out: lost BSY, n=%d\n", n);
                   1930:                        goto out;
                   1931:                }
                   1932:                if (ncr5380_wait_req(sc)) {
                   1933:                        NCR_TRACE("msg_out: no REQ, n=%d\n", n);
                   1934:                        goto out;
                   1935:                }
                   1936:                phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
                   1937:                if (phase != PHASE_MSG_OUT) {
                   1938:                        /*
                   1939:                         * Target left MESSAGE OUT, possibly to reject
                   1940:                         * our message.
                   1941:                         */
                   1942:                        NCR_TRACE("msg_out: new phase=%d\n", phase);
                   1943:                        goto out;
                   1944:                }
                   1945:
                   1946:                /* Yes, we can send this message byte. */
                   1947:                --n;
                   1948:
                   1949:                /* Clear ATN before last byte if this is the last message. */
                   1950:                if (n == 0 && sc->sc_msgpriq == 0) {
                   1951:                        icmd &= ~SCI_ICMD_ATN;
                   1952:                        *sc->sci_icmd = icmd;
                   1953:                        /* 2 deskew delays */
                   1954:                        delay(2);       /* XXX */
                   1955:                }
                   1956:
                   1957:                /* Put data on the bus. */
                   1958:                *sc->sci_odata = *--sc->sc_omp;
                   1959:
                   1960:                /* Raise ACK to tell target data is on the bus. */
                   1961:                icmd |= SCI_ICMD_ACK;
                   1962:                *sc->sci_icmd = icmd;
                   1963:
                   1964:                /* Wait for REQ to be negated. */
                   1965:                if (ncr5380_wait_not_req(sc)) {
                   1966:                        NCR_TRACE("msg_out: stuck REQ, n=%d\n", n);
                   1967:                        act_flags |= ACT_RESET_BUS;
                   1968:                }
                   1969:
                   1970:                /* Finally, drop ACK. */
                   1971:                icmd &= ~SCI_ICMD_ACK;
                   1972:                *sc->sci_icmd = icmd;
                   1973:
                   1974:                /* Stuck bus or something... */
                   1975:                if (act_flags & ACT_RESET_BUS)
                   1976:                        goto out;
                   1977:
                   1978:        }
                   1979:        progress++;
                   1980:
                   1981:        /* We get here only if the entire message has been transmitted. */
                   1982:        if (sc->sc_msgpriq != 0) {
                   1983:                /* There are more outgoing messages. */
                   1984:                goto nextmsg;
                   1985:        }
                   1986:
                   1987:        /*
                   1988:         * The last message has been transmitted.  We need to remember the last
                   1989:         * message transmitted (in case the target switches to MESSAGE IN phase
                   1990:         * and sends a MESSAGE REJECT), and the list of messages transmitted
                   1991:         * this time around (in case the target stays in MESSAGE OUT phase to
                   1992:         * request a retransmit).
                   1993:         */
                   1994:
                   1995: out:
                   1996:        /* Stop driving the data bus. */
                   1997:        icmd &= ~SCI_ICMD_DATA;
                   1998:        *sc->sci_icmd = icmd;
                   1999:
                   2000:        if (!progress)
                   2001:                act_flags |= ACT_RESET_BUS;
                   2002:
                   2003:        return (act_flags);
                   2004: }
                   2005:
                   2006:
                   2007: /*
                   2008:  * Handle command phase.
                   2009:  */
                   2010: static int
                   2011: ncr5380_command(sc)
                   2012:        struct ncr5380_softc *sc;
                   2013: {
                   2014:        struct sci_req *sr = sc->sc_current;
                   2015:        struct scsi_xfer *xs = sr->sr_xs;
                   2016:        struct scsi_sense rqs;
                   2017:        int len;
                   2018:
                   2019:        /* acknowledge phase change */
                   2020:        *sc->sci_tcmd = PHASE_COMMAND;
                   2021:
                   2022:        if (sr->sr_flags & SR_SENSE) {
                   2023:                rqs.opcode = REQUEST_SENSE;
                   2024:                rqs.byte2 = xs->sc_link->lun << 5;
                   2025:                rqs.length = sizeof(xs->sense);
                   2026:
                   2027:                rqs.unused[0] = rqs.unused[1] = rqs.control = 0;
                   2028:                len = ncr5380_pio_out(sc, PHASE_COMMAND, sizeof(rqs),
                   2029:                        (u_char *)&rqs);
                   2030:        }
                   2031:        else {
                   2032:                /* Assume command can be sent in one go. */
                   2033:                /* XXX: Do this using DMA, and get a phase change intr? */
                   2034:                len = ncr5380_pio_out(sc, PHASE_COMMAND, xs->cmdlen,
                   2035:                        (u_char *)xs->cmd);
                   2036:        }
                   2037:
                   2038:        if (len != xs->cmdlen) {
                   2039: #ifdef NCR5380_DEBUG
                   2040:                printf("ncr5380_command: short transfer: wanted %d got %d.\n",
                   2041:                    xs->cmdlen, len);
                   2042:                ncr5380_show_scsi_cmd(xs);
                   2043:                NCR_BREAK();
                   2044: #endif
                   2045:                if (len < 6) {
                   2046:                        xs->error = XS_DRIVER_STUFFUP;
                   2047:                        sc->sc_state |= NCR_ABORTING;
                   2048:                        ncr_sched_msgout(sc, SEND_ABORT);
                   2049:                }
                   2050:
                   2051:        }
                   2052:
                   2053:        return ACT_CONTINUE;
                   2054: }
                   2055:
                   2056:
                   2057: /*
                   2058:  * Handle either data_in or data_out
                   2059:  */
                   2060: static int
                   2061: ncr5380_data_xfer(sc, phase)
                   2062:        struct ncr5380_softc *sc;
                   2063:        int phase;
                   2064: {
                   2065:        struct sci_req *sr = sc->sc_current;
                   2066:        struct scsi_xfer *xs = sr->sr_xs;
                   2067:        int expected_phase;
                   2068:        int len;
                   2069:
                   2070:        if (sr->sr_flags & SR_SENSE) {
                   2071:                NCR_TRACE("data_xfer: get sense, sr=0x%x\n", (long)sr);
                   2072:                if (phase != PHASE_DATA_IN) {
                   2073:                        printf("%s: sense phase error\n", sc->sc_dev.dv_xname);
                   2074:                        goto abort;
                   2075:                }
                   2076:                /* acknowledge phase change */
                   2077:                *sc->sci_tcmd = PHASE_DATA_IN;
                   2078:                len = ncr5380_pio_in(sc, phase, sizeof(xs->sense),
                   2079:                                (u_char *)&xs->sense);
                   2080:                return ACT_CONTINUE;
                   2081:        }
                   2082:
                   2083:        /*
                   2084:         * When aborting a command, disallow any data phase.
                   2085:         */
                   2086:        if (sc->sc_state & NCR_ABORTING) {
                   2087:                printf("%s: aborting, but phase=%s (reset)\n",
                   2088:                    sc->sc_dev.dv_xname, phase_names[phase & 7]);
                   2089:                return ACT_RESET_BUS;   /* XXX */
                   2090:        }
                   2091:
                   2092:        /* Validate expected phase (data_in or data_out) */
                   2093:        expected_phase = (xs->flags & SCSI_DATA_OUT) ?
                   2094:                PHASE_DATA_OUT : PHASE_DATA_IN;
                   2095:        if (phase != expected_phase) {
                   2096:                printf("%s: data phase error\n", sc->sc_dev.dv_xname);
                   2097:                goto abort;
                   2098:        }
                   2099:
                   2100:        /* Make sure we have some data to move. */
                   2101:        if (sc->sc_datalen <= 0) {
                   2102:                /* Device needs padding. */
                   2103:                if (phase == PHASE_DATA_IN)
                   2104:                        ncr5380_pio_in(sc, phase, 4096, NULL);
                   2105:                else
                   2106:                        ncr5380_pio_out(sc, phase, 4096, NULL);
                   2107:                /* Make sure that caused a phase change. */
                   2108:                if (SCI_BUS_PHASE(*sc->sci_bus_csr) == phase) {
                   2109:                        /* More than 4k is just too much! */
                   2110:                        printf("%s: too much data padding\n",
                   2111:                               sc->sc_dev.dv_xname);
                   2112:                        goto abort;
                   2113:                }
                   2114:                return ACT_CONTINUE;
                   2115:        }
                   2116:
                   2117:        /*
                   2118:         * Attempt DMA only if dma_alloc gave us a DMA handle AND
                   2119:         * there is enough left to transfer so DMA is worth while.
                   2120:         */
                   2121:        if (sr->sr_dma_hand &&
                   2122:                (sc->sc_datalen >= sc->sc_min_dma_len))
                   2123:        {
                   2124:                /*
                   2125:                 * OK, really start DMA.  Note, the MD start function
                   2126:                 * is responsible for setting the TCMD register, etc.
                   2127:                 * (Acknowledge the phase change there, not here.)
                   2128:                 */
                   2129:                NCR_TRACE("data_xfer: dma_start, dh=0x%x\n",
                   2130:                          (long) sr->sr_dma_hand);
                   2131:                (*sc->sc_dma_start)(sc);
                   2132:                return ACT_WAIT_DMA;
                   2133:        }
                   2134:
                   2135:        /*
                   2136:         * Doing PIO for data transfer.  (Possibly "Pseudo DMA")
                   2137:         * XXX:  Do PDMA functions need to set tcmd later?
                   2138:         */
                   2139:        NCR_TRACE("data_xfer: doing PIO, len=%d\n", sc->sc_datalen);
                   2140:        /* acknowledge phase change */
                   2141:        *sc->sci_tcmd = phase;  /* XXX: OK for PDMA? */
                   2142:        if (phase == PHASE_DATA_OUT) {
                   2143:                len = (*sc->sc_pio_out)(sc, phase, sc->sc_datalen, sc->sc_dataptr);
                   2144:        } else {
                   2145:                len = (*sc->sc_pio_in) (sc, phase, sc->sc_datalen, sc->sc_dataptr);
                   2146:        }
                   2147:        sc->sc_dataptr += len;
                   2148:        sc->sc_datalen -= len;
                   2149:
                   2150:        NCR_TRACE("data_xfer: did PIO, resid=%d\n", sc->sc_datalen);
                   2151:        return (ACT_CONTINUE);
                   2152:
                   2153: abort:
                   2154:        sc->sc_state |= NCR_ABORTING;
                   2155:        ncr_sched_msgout(sc, SEND_ABORT);
                   2156:        return (ACT_CONTINUE);
                   2157: }
                   2158:
                   2159:
                   2160: static int
                   2161: ncr5380_status(sc)
                   2162:        struct ncr5380_softc *sc;
                   2163: {
                   2164:        int len;
                   2165:        u_char status;
                   2166:        struct sci_req *sr = sc->sc_current;
                   2167:
                   2168:        /* acknowledge phase change */
                   2169:        *sc->sci_tcmd = PHASE_STATUS;
                   2170:
                   2171:        len = ncr5380_pio_in(sc, PHASE_STATUS, 1, &status);
                   2172:        if (len) {
                   2173:                sr->sr_status = status;
                   2174:        } else {
                   2175:                printf("ncr5380_status: none?\n");
                   2176:        }
                   2177:
                   2178:        return ACT_CONTINUE;
                   2179: }
                   2180:
                   2181:
                   2182: /*
                   2183:  * This is the big state machine that follows SCSI phase changes.
                   2184:  * This is somewhat like a co-routine.  It will do a SCSI command,
                   2185:  * and exit if the command is complete, or if it must wait, i.e.
                   2186:  * for DMA to complete or for reselect to resume the job.
                   2187:  *
                   2188:  * The bus must be selected, and we need to know which command is
                   2189:  * being undertaken.
                   2190:  */
                   2191: static void
                   2192: ncr5380_machine(sc)
                   2193:        struct ncr5380_softc *sc;
                   2194: {
                   2195:        struct sci_req *sr;
                   2196:        struct scsi_xfer *xs;
                   2197:        int act_flags, phase, timo;
                   2198:
                   2199: #ifdef DIAGNOSTIC
                   2200:        if (sc->sc_state == NCR_IDLE)
                   2201:                panic("ncr5380_machine: state=idle");
                   2202:        if (sc->sc_current == NULL)
                   2203:                panic("ncr5380_machine: no current cmd");
                   2204: #endif
                   2205:
                   2206:        sr = sc->sc_current;
                   2207:        xs = sr->sr_xs;
                   2208:        act_flags = ACT_CONTINUE;
                   2209:
                   2210:        /*
                   2211:         * This will be called by ncr5380_intr() when DMA is
                   2212:         * complete.  Must stop DMA before touching the 5380 or
                   2213:         * there will be "register conflict" errors.
                   2214:         */
                   2215:        if (sc->sc_state & NCR_DOINGDMA) {
                   2216:                /* Pick-up where where we left off... */
                   2217:                goto dma_done;
                   2218:        }
                   2219:
                   2220: next_phase:
                   2221:
                   2222:        if (!SCI_BUSY(sc)) {
                   2223:                /* Unexpected disconnect */
                   2224:                printf("ncr5380_machine: unexpected disconnect.\n");
                   2225:                xs->error = XS_DRIVER_STUFFUP;
                   2226:                act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
                   2227:                goto do_actions;
                   2228:        }
                   2229:
                   2230:        /*
                   2231:         * Wait for REQ before reading the phase.
                   2232:         * Need to wait longer than usual here, because
                   2233:         * some devices are just plain slow...
                   2234:         */
                   2235:        timo = ncr5380_wait_phase_timo;
                   2236:        for (;;) {
                   2237:                if (*sc->sci_bus_csr & SCI_BUS_REQ)
                   2238:                        break;
                   2239:                if (--timo <= 0) {
                   2240:                        if (sc->sc_state & NCR_ABORTING) {
                   2241:                                printf("%s: no REQ while aborting, reset\n",
                   2242:                                    sc->sc_dev.dv_xname);
                   2243:                                act_flags |= ACT_RESET_BUS;
                   2244:                                goto do_actions;
                   2245:                        }
                   2246:                        printf("%s: no REQ for next phase, abort\n",
                   2247:                            sc->sc_dev.dv_xname);
                   2248:                        sc->sc_state |= NCR_ABORTING;
                   2249:                        ncr_sched_msgout(sc, SEND_ABORT);
                   2250:                        goto next_phase;
                   2251:                }
                   2252:                delay(100);
                   2253:        }
                   2254:
                   2255:        phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
                   2256:        NCR_TRACE("machine: phase=%s\n",
                   2257:                          (long) phase_names[phase & 7]);
                   2258:
                   2259:        /*
                   2260:         * We assume that the device knows what it's doing,
                   2261:         * so any phase is good.
                   2262:         */
                   2263:
                   2264: #if 0
                   2265:        /*
                   2266:         * XXX: Do not ACK the phase yet! do it later...
                   2267:         * XXX: ... each phase routine does that itself.
                   2268:         * In particular, DMA needs it done LATER.
                   2269:         */
                   2270:        *sc->sci_tcmd = phase;  /* acknowledge phase change */
                   2271: #endif
                   2272:
                   2273:        switch (phase) {
                   2274:
                   2275:        case PHASE_DATA_OUT:
                   2276:        case PHASE_DATA_IN:
                   2277:                act_flags = ncr5380_data_xfer(sc, phase);
                   2278:                break;
                   2279:
                   2280:        case PHASE_COMMAND:
                   2281:                act_flags = ncr5380_command(sc);
                   2282:                break;
                   2283:
                   2284:        case PHASE_STATUS:
                   2285:                act_flags = ncr5380_status(sc);
                   2286:                break;
                   2287:
                   2288:        case PHASE_MSG_OUT:
                   2289:                act_flags = ncr5380_msg_out(sc);
                   2290:                break;
                   2291:
                   2292:        case PHASE_MSG_IN:
                   2293:                act_flags = ncr5380_msg_in(sc);
                   2294:                break;
                   2295:
                   2296:        default:
                   2297:                printf("ncr5380_machine: Unexpected phase 0x%x\n", phase);
                   2298:                sc->sc_state |= NCR_ABORTING;
                   2299:                ncr_sched_msgout(sc, SEND_ABORT);
                   2300:                goto next_phase;
                   2301:
                   2302:        } /* switch */
                   2303:        sc->sc_prevphase = phase;
                   2304:
                   2305: do_actions:
                   2306:        __asm("_ncr5380_actions:");
                   2307:
                   2308:        if (act_flags & ACT_WAIT_DMA) {
                   2309:                act_flags &= ~ACT_WAIT_DMA;
                   2310:                /* Wait for DMA to complete (polling, or interrupt). */
                   2311:                if ((sr->sr_flags & SR_IMMED) == 0) {
                   2312:                        NCR_TRACE("machine: wait for DMA intr.\n", 0);
                   2313:                        return;         /* will resume at dma_done */
                   2314:                }
                   2315:                /* Busy-wait for it to finish. */
                   2316:                NCR_TRACE("machine: dma_poll, dh=0x%x\n",
                   2317:                                  (long) sr->sr_dma_hand);
                   2318:                (*sc->sc_dma_poll)(sc);
                   2319:        dma_done:
                   2320:                /* Return here after interrupt. */
                   2321:                if (sr->sr_flags & SR_OVERDUE)
                   2322:                        sc->sc_state |= NCR_ABORTING;
                   2323:                NCR_TRACE("machine: dma_stop, dh=0x%x\n",
                   2324:                                  (long) sr->sr_dma_hand);
                   2325:                (*sc->sc_dma_stop)(sc);
                   2326:                SCI_CLR_INTR(sc);       /* XXX */
                   2327:                /*
                   2328:                 * While DMA is running we can not touch the SBC,
                   2329:                 * so various places just set NCR_ABORTING and
                   2330:                 * expect us the "kick it" when DMA is done.
                   2331:                 */
                   2332:                if (sc->sc_state & NCR_ABORTING) {
                   2333:                        ncr_sched_msgout(sc, SEND_ABORT);
                   2334:                }
                   2335:        }
                   2336:
                   2337:        /*
                   2338:         * Check for parity error.
                   2339:         * XXX - better place to check?
                   2340:         */
                   2341:        if (*(sc->sci_csr) & SCI_CSR_PERR) {
                   2342:                printf("%s: parity error!\n", sc->sc_dev.dv_xname);
                   2343:                /* XXX: sc->sc_state |= NCR_ABORTING; */
                   2344:                ncr_sched_msgout(sc, SEND_PARITY_ERROR);
                   2345:        }
                   2346:
                   2347:        if (act_flags == ACT_CONTINUE)
                   2348:                goto next_phase;
                   2349:        /* All other actions "break" from the loop. */
                   2350:
                   2351:        NCR_TRACE("machine: act_flags=0x%x\n", act_flags);
                   2352:
                   2353:        if (act_flags & ACT_RESET_BUS) {
                   2354:                act_flags |= ACT_CMD_DONE;
                   2355:                /*
                   2356:                 * Reset the SCSI bus, usually due to a timeout.
                   2357:                 * The error code XS_TIMEOUT allows retries.
                   2358:                 */
                   2359:                sc->sc_state |= NCR_ABORTING;
                   2360:                printf("%s: reset SCSI bus for TID=%d LUN=%d\n",
                   2361:                    sc->sc_dev.dv_xname, sr->sr_target, sr->sr_lun);
                   2362:                ncr5380_reset_scsibus(sc);
                   2363:        }
                   2364:
                   2365:        if (act_flags & ACT_CMD_DONE) {
                   2366:                act_flags |= ACT_DISCONNECT;
                   2367:                /* Need to call scsi_done() */
                   2368:                /* XXX: from the aic6360 driver, but why? */
                   2369:                if (sc->sc_datalen < 0) {
                   2370:                        printf("%s: %d extra bytes from %d:%d\n",
                   2371:                            sc->sc_dev.dv_xname, -sc->sc_datalen,
                   2372:                            sr->sr_target, sr->sr_lun);
                   2373:                        sc->sc_datalen = 0;
                   2374:                }
                   2375:                xs->resid = sc->sc_datalen;
                   2376:                /* Note: this will clear sc_current */
                   2377:                NCR_TRACE("machine: call done, cur=0x%x\n", (long)sr);
                   2378:                ncr5380_done(sc);
                   2379:        }
                   2380:
                   2381:        if (act_flags & ACT_DISCONNECT) {
                   2382:                /*
                   2383:                 * The device has dropped BSY (or will soon).
                   2384:                 * We have to wait here for BSY to drop, otherwise
                   2385:                 * the next command may decide we need a bus reset.
                   2386:                 */
                   2387:                timo = ncr5380_wait_req_timo;   /* XXX */
                   2388:                for (;;) {
                   2389:                        if (!SCI_BUSY(sc))
                   2390:                                goto busfree;
                   2391:                        if (--timo <= 0)
                   2392:                                break;
                   2393:                        delay(2);
                   2394:                }
                   2395:                /* Device is sitting on the bus! */
                   2396:                printf("%s: Target %d LUN %d stuck busy, resetting...\n",
                   2397:                    sc->sc_dev.dv_xname, sr->sr_target, sr->sr_lun);
                   2398:                ncr5380_reset_scsibus(sc);
                   2399:        busfree:
                   2400:                NCR_TRACE("machine: discon, waited %d\n",
                   2401:                        ncr5380_wait_req_timo - timo);
                   2402:
                   2403:                *sc->sci_icmd = 0;
                   2404:                *sc->sci_mode = 0;
                   2405:                *sc->sci_tcmd = PHASE_INVALID;
                   2406:                *sc->sci_sel_enb = 0;
                   2407:                SCI_CLR_INTR(sc);
                   2408:                *sc->sci_sel_enb = 0x80;
                   2409:
                   2410:                if ((act_flags & ACT_CMD_DONE) == 0) {
                   2411:                        __asm("_ncr5380_disconnected:");
                   2412:                        NCR_TRACE("machine: discon, cur=0x%x\n", (long)sr);
                   2413:                }
                   2414:
                   2415:                /*
                   2416:                 * We may be here due to a disconnect message,
                   2417:                 * in which case we did NOT call ncr5380_done,
                   2418:                 * and we need to clear sc_current.
                   2419:                 */
                   2420:                sc->sc_state = NCR_IDLE;
                   2421:                sc->sc_current = NULL;
                   2422:
                   2423:                /* Paranoia: clear everything. */
                   2424:                sc->sc_dataptr = NULL;
                   2425:                sc->sc_datalen = 0;
                   2426:                sc->sc_prevphase = PHASE_INVALID;
                   2427:                sc->sc_msgpriq = 0;
                   2428:                sc->sc_msgoutq = 0;
                   2429:                sc->sc_msgout  = 0;
                   2430:
                   2431:                /* Our caller will re-enable interrupts. */
                   2432:        }
                   2433: }
                   2434:
                   2435:
                   2436: #ifdef NCR5380_DEBUG
                   2437:
                   2438: static void
                   2439: ncr5380_show_scsi_cmd(xs)
                   2440:        struct scsi_xfer *xs;
                   2441: {
                   2442:        u_char  *b = (u_char *) xs->cmd;
                   2443:        int     i  = 0;
                   2444:
                   2445:        if ( ! ( xs->flags & SCSI_RESET ) ) {
                   2446:                printf("si(%d:%d:%d)-",
                   2447:                    xs->sc_link->scsibus, xs->sc_link->target,
                   2448:                    xs->sc_link->lun);
                   2449:                while (i < xs->cmdlen) {
                   2450:                        if (i) printf(",");
                   2451:                        printf("%x",b[i++]);
                   2452:                }
                   2453:                printf("-\n");
                   2454:        } else {
                   2455:                printf("si(%d:%d:%d)-RESET-\n",
                   2456:                    xs->sc_link->scsibus, xs->sc_link->target,
                   2457:                    xs->sc_link->lun);
                   2458:        }
                   2459: }
                   2460:
                   2461:
                   2462: static void
                   2463: ncr5380_show_sense(xs)
                   2464:        struct scsi_xfer *xs;
                   2465: {
                   2466:        u_char  *b = (u_char *)&xs->sense;
                   2467:        int     i;
                   2468:
                   2469:        printf("sense:");
                   2470:        for (i = 0; i < sizeof(xs->sense); i++)
                   2471:                printf(" %02x", b[i]);
                   2472:        printf("\n");
                   2473: }
                   2474:
                   2475: int ncr5380_traceidx = 0;
                   2476:
                   2477: #define        TRACE_MAX       1024
                   2478: struct trace_ent {
                   2479:        char *msg;
                   2480:        long  val;
                   2481: } ncr5380_tracebuf[TRACE_MAX];
                   2482:
                   2483: void
                   2484: ncr5380_trace(msg, val)
                   2485:        char *msg;
                   2486:        long  val;
                   2487: {
                   2488:        register struct trace_ent *tr;
                   2489:        register int s;
                   2490:
                   2491:        s = splbio();
                   2492:
                   2493:        tr = &ncr5380_tracebuf[ncr5380_traceidx];
                   2494:
                   2495:        ncr5380_traceidx++;
                   2496:        if (ncr5380_traceidx >= TRACE_MAX)
                   2497:                ncr5380_traceidx = 0;
                   2498:
                   2499:        tr->msg = msg;
                   2500:        tr->val = val;
                   2501:
                   2502:        splx(s);
                   2503: }
                   2504:
                   2505: #ifdef DDB
                   2506: void
                   2507: ncr5380_clear_trace()
                   2508: {
                   2509:        ncr5380_traceidx = 0;
                   2510:        bzero((char *) ncr5380_tracebuf, sizeof(ncr5380_tracebuf));
                   2511: }
                   2512:
                   2513: void
                   2514: ncr5380_show_trace()
                   2515: {
                   2516:        struct trace_ent *tr;
                   2517:        int idx;
                   2518:
                   2519:        idx = ncr5380_traceidx;
                   2520:        do {
                   2521:                tr = &ncr5380_tracebuf[idx];
                   2522:                idx++;
                   2523:                if (idx >= TRACE_MAX)
                   2524:                        idx = 0;
                   2525:                if (tr->msg)
                   2526:                        db_printf(tr->msg, tr->val);
                   2527:        } while (idx != ncr5380_traceidx);
                   2528: }
                   2529:
                   2530: void
                   2531: ncr5380_show_req(sr)
                   2532:        struct sci_req *sr;
                   2533: {
                   2534:        struct scsi_xfer *xs = sr->sr_xs;
                   2535:
                   2536:        db_printf("TID=%d ",    sr->sr_target);
                   2537:        db_printf("LUN=%d ",    sr->sr_lun);
                   2538:        db_printf("dh=%p ",     sr->sr_dma_hand);
                   2539:        db_printf("dptr=%p ",   sr->sr_dataptr);
                   2540:        db_printf("dlen=0x%x ", sr->sr_datalen);
                   2541:        db_printf("flags=%d ",  sr->sr_flags);
                   2542:        db_printf("stat=%d ",   sr->sr_status);
                   2543:
                   2544:        if (xs == NULL) {
                   2545:                db_printf("(xs=NULL)\n");
                   2546:                return;
                   2547:        }
                   2548:        db_printf("\n");
                   2549: #ifdef SCSIDEBUG
                   2550:        show_scsi_xs(xs);
                   2551: #else
                   2552:        db_printf("xs=%p\n", xs);
                   2553: #endif
                   2554: }
                   2555:
                   2556: void
                   2557: ncr5380_show_state()
                   2558: {
                   2559:        struct ncr5380_softc *sc;
                   2560:        struct sci_req *sr;
                   2561:        int i, j, k;
                   2562:
                   2563:        sc = ncr5380_debug_sc;
                   2564:
                   2565:        if (sc == NULL) {
                   2566:                db_printf("ncr5380_debug_sc == NULL\n");
                   2567:                return;
                   2568:        }
                   2569:
                   2570:        db_printf("sc_ncmds=%d\n",      sc->sc_ncmds);
                   2571:        k = -1; /* which is current? */
                   2572:        for (i = 0; i < SCI_OPENINGS; i++) {
                   2573:                sr = &sc->sc_ring[i];
                   2574:                if (sr->sr_xs) {
                   2575:                        if (sr == sc->sc_current)
                   2576:                                k = i;
                   2577:                        db_printf("req %d: (sr=%p)", i, (long)sr);
                   2578:                        ncr5380_show_req(sr);
                   2579:                }
                   2580:        }
                   2581:        db_printf("sc_rr=%d, current=%d\n", sc->sc_rr, k);
                   2582:
                   2583:        db_printf("Active request matrix:\n");
                   2584:        for(i = 0; i < 8; i++) {                /* targets */
                   2585:                for (j = 0; j < 8; j++) {       /* LUN */
                   2586:                        sr = sc->sc_matrix[i][j];
                   2587:                        if (sr) {
                   2588:                                db_printf("TID=%d LUN=%d sr=0x%x\n", i, j, (long)sr);
                   2589:                        }
                   2590:                }
                   2591:        }
                   2592:
                   2593:        db_printf("sc_state=0x%x\n",    sc->sc_state);
                   2594:        db_printf("sc_current=%p\n",    sc->sc_current);
                   2595:        db_printf("sc_dataptr=%p\n",    sc->sc_dataptr);
                   2596:        db_printf("sc_datalen=0x%x\n",  sc->sc_datalen);
                   2597:
                   2598:        db_printf("sc_prevphase=%d\n",  sc->sc_prevphase);
                   2599:        db_printf("sc_msgpriq=0x%x\n",  sc->sc_msgpriq);
                   2600: }
                   2601:
                   2602: #endif /* DDB */
                   2603: #endif /* NCR5380_DEBUG */

CVSweb