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

Annotation of sys/arch/luna88k/dev/mb89352.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: mb89352.c,v 1.7 2006/11/28 23:59:45 dlg Exp $ */
                      2: /*     $NetBSD: mb89352.c,v 1.5 2000/03/23 07:01:31 thorpej Exp $      */
                      3: /*     NecBSD: mb89352.c,v 1.4 1998/03/14 07:31:20 kmatsuda Exp        */
                      4:
                      5: #ifdef DDB
                      6: #define        integrate
                      7: #else
                      8: #define        integrate       __inline static
                      9: #endif
                     10:
                     11: /*-
                     12:  * Copyright (c) 1996,97,98,99 The NetBSD Foundation, Inc.
                     13:  * All rights reserved.
                     14:  *
                     15:  * This code is derived from software contributed to The NetBSD Foundation
                     16:  * by Charles M. Hannum, Masaru Oki and Kouichi Matsuda.
                     17:  *
                     18:  * Redistribution and use in source and binary forms, with or without
                     19:  * modification, are permitted provided that the following conditions
                     20:  * are met:
                     21:  * 1. Redistributions of source code must retain the above copyright
                     22:  *    notice, this list of conditions and the following disclaimer.
                     23:  * 2. Redistributions in binary form must reproduce the above copyright
                     24:  *    notice, this list of conditions and the following disclaimer in the
                     25:  *    documentation and/or other materials provided with the distribution.
                     26:  * 3. All advertising materials mentioning features or use of this software
                     27:  *    must display the following acknowledgement:
                     28:  *     This product includes software developed by Charles M. Hannum.
                     29:  * 4. The name of the author may not be used to endorse or promote products
                     30:  *    derived from this software without specific prior written permission.
                     31:  *
                     32:  * Copyright (c) 1994 Jarle Greipsland
                     33:  * All rights reserved.
                     34:  *
                     35:  * Redistribution and use in source and binary forms, with or without
                     36:  * modification, are permitted provided that the following conditions
                     37:  * are met:
                     38:  * 1. Redistributions of source code must retain the above copyright
                     39:  *    notice, this list of conditions and the following disclaimer.
                     40:  * 2. Redistributions in binary form must reproduce the above copyright
                     41:  *    notice, this list of conditions and the following disclaimer in the
                     42:  *    documentation and/or other materials provided with the distribution.
                     43:  * 3. The name of the author may not be used to endorse or promote products
                     44:  *    derived from this software without specific prior written permission.
                     45:  *
                     46:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     47:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     48:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     49:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     50:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     51:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     52:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     53:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     54:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     55:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     56:  * POSSIBILITY OF SUCH DAMAGE.
                     57:  */
                     58: /*
                     59:  * [NetBSD for NEC PC-98 series]
                     60:  *  Copyright (c) 1996, 1997, 1998
                     61:  *     NetBSD/pc98 porting staff. All rights reserved.
                     62:  *  Copyright (c) 1996, 1997, 1998
                     63:  *     Kouichi Matsuda. All rights reserved.
                     64:  */
                     65:
                     66: /*
                     67:  * Acknowledgements: Many of the algorithms used in this driver are
                     68:  * inspired by the work of Julian Elischer (julian@tfs.com) and
                     69:  * Charles Hannum (mycroft@duality.gnu.ai.mit.edu).  Thanks a million!
                     70:  */
                     71:
                     72: /* TODO list:
                     73:  * 1) Get the DMA stuff working.
                     74:  * 2) Get the iov/uio stuff working. Is this a good thing ???
                     75:  * 3) Get the synch stuff working.
                     76:  * 4) Rewrite it to use malloc for the acb structs instead of static alloc.?
                     77:  */
                     78:
                     79: /*
                     80:  * A few customizable items:
                     81:  */
                     82:
                     83: /* Synchronous data transfers? */
                     84: #define SPC_USE_SYNCHRONOUS    0
                     85: #define SPC_SYNC_REQ_ACK_OFS   8
                     86:
                     87: /* Wide data transfers? */
                     88: #define        SPC_USE_WIDE            0
                     89: #define        SPC_MAX_WIDTH           0
                     90:
                     91: /* Max attempts made to transmit a message */
                     92: #define SPC_MSG_MAX_ATTEMPT    3 /* Not used now XXX */
                     93:
                     94: /*
                     95:  * Some spin loop parameters (essentially how long to wait some places)
                     96:  * The problem(?) is that sometimes we expect either to be able to transmit a
                     97:  * byte or to get a new one from the SCSI bus pretty soon.  In order to avoid
                     98:  * returning from the interrupt just to get yanked back for the next byte we
                     99:  * may spin in the interrupt routine waiting for this byte to come.  How long?
                    100:  * This is really (SCSI) device and processor dependent.  Tuneable, I guess.
                    101:  */
                    102: #define SPC_MSGIN_SPIN 1       /* Will spinwait upto ?ms for a new msg byte */
                    103: #define SPC_MSGOUT_SPIN        1
                    104:
                    105: /*
                    106:  * Include debug functions?  At the end of this file there are a bunch of
                    107:  * functions that will print out various information regarding queued SCSI
                    108:  * commands, driver state and chip contents.  You can call them from the
                    109:  * kernel debugger.  If you set SPC_DEBUG to 0 they are not included (the
                    110:  * kernel uses less memory) but you lose the debugging facilities.
                    111:  */
                    112: /* #define SPC_DEBUG */
                    113:
                    114: #define        SPC_ABORT_TIMEOUT       2000    /* time to wait for abort */
                    115:
                    116: /* End of customizable parameters */
                    117:
                    118: /*
                    119:  * MB89352 SCSI Protocol Controller (SPC) routines.
                    120:  */
                    121:
                    122: #include <sys/param.h>
                    123: #include <sys/systm.h>
                    124: #include <sys/kernel.h>
                    125: #include <sys/errno.h>
                    126: #include <sys/ioctl.h>
                    127: #include <sys/device.h>
                    128: #include <sys/buf.h>
                    129: #include <sys/proc.h>
                    130: #include <sys/user.h>
                    131: #include <sys/queue.h>
                    132:
                    133: #include <machine/intr.h>
                    134: #include <machine/bus.h>
                    135:
                    136: #include <scsi/scsi_all.h>
                    137: #include <scsi/scsi_message.h>
                    138: #include <scsi/scsiconf.h>
                    139:
                    140: #include <luna88k/dev/mb89352reg.h>
                    141: #include <luna88k/dev/mb89352var.h>
                    142:
                    143: #ifndef DDB
                    144: #define        Debugger() panic("should call debugger here (mb89352.c)")
                    145: #endif /* ! DDB */
                    146:
                    147: #ifdef SPC_DEBUG
                    148: int spc_debug = 0x00; /* SPC_SHOWSTART|SPC_SHOWMISC|SPC_SHOWTRACE; */
                    149: #endif
                    150:
                    151: void   spc_done        (struct spc_softc *, struct spc_acb *);
                    152: void   spc_dequeue     (struct spc_softc *, struct spc_acb *);
                    153: int    spc_scsi_cmd    (struct scsi_xfer *);
                    154: int    spc_poll        (struct spc_softc *, struct scsi_xfer *, int);
                    155: integrate void spc_sched_msgout(struct spc_softc *, u_char);
                    156: integrate void spc_setsync(struct spc_softc *, struct spc_tinfo *);
                    157: void   spc_select      (struct spc_softc *, struct spc_acb *);
                    158: void   spc_timeout     (void *);
                    159: void   spc_scsi_reset  (struct spc_softc *);
                    160: void   spc_reset       (struct spc_softc *);
                    161: void   spc_free_acb    (struct spc_softc *, struct spc_acb *, int);
                    162: struct spc_acb* spc_get_acb(struct spc_softc *, int);
                    163: int    spc_reselect    (struct spc_softc *, int);
                    164: void   spc_sense       (struct spc_softc *, struct spc_acb *);
                    165: void   spc_msgin       (struct spc_softc *);
                    166: void   spc_abort       (struct spc_softc *, struct spc_acb *);
                    167: void   spc_msgout      (struct spc_softc *);
                    168: int    spc_dataout_pio (struct spc_softc *, u_char *, int);
                    169: int    spc_datain_pio  (struct spc_softc *, u_char *, int);
                    170: #ifdef SPC_DEBUG
                    171: void   spc_print_acb   (struct spc_acb *);
                    172: void   spc_dump_driver (struct spc_softc *);
                    173: void   spc_dump89352   (struct spc_softc *);
                    174: void   spc_show_scsi_cmd(struct spc_acb *);
                    175: void   spc_print_active_acb(void);
                    176: #endif
                    177:
                    178: extern struct cfdriver spc_cd;
                    179:
                    180: struct scsi_device spc_dev = {
                    181:        NULL,                   /* Use default error handler */
                    182:        NULL,                   /* have a queue, served by this */
                    183:        NULL,                   /* have no async handler */
                    184:        NULL,                   /* Use default 'done' routine */
                    185: };
                    186:
                    187: /*
                    188:  * INITIALIZATION ROUTINES (probe, attach ++)
                    189:  */
                    190:
                    191: void
                    192: /* spc_attach(sc) */
                    193: spc_attach(sc, adapter)
                    194:        struct spc_softc *sc;
                    195:        struct scsi_adapter *adapter;
                    196: {
                    197:        struct scsibus_attach_args saa;
                    198:        SPC_TRACE(("spc_attach  "));
                    199:        sc->sc_state = SPC_INIT;
                    200:
                    201:        sc->sc_freq = 20;       /* XXXX Assume 20 MHz. */
                    202:
                    203: #if SPC_USE_SYNCHRONOUS
                    204:        /*
                    205:         * These are the bounds of the sync period, based on the frequency of
                    206:         * the chip's clock input and the size and offset of the sync period
                    207:         * register.
                    208:         *
                    209:         * For a 20MHz clock, this gives us 25, or 100nS, or 10MB/s, as a
                    210:         * maximum transfer rate, and 112.5, or 450nS, or 2.22MB/s, as a
                    211:         * minimum transfer rate.
                    212:         */
                    213:        sc->sc_minsync = (2 * 250) / sc->sc_freq;
                    214:        sc->sc_maxsync = (9 * 250) / sc->sc_freq;
                    215: #endif
                    216:
                    217:        spc_init(sc);   /* Init chip and driver */
                    218:
                    219:        /*
                    220:         * Fill in the adapter.
                    221:         */
                    222:        sc->sc_link.adapter_softc = sc;
                    223:        sc->sc_link.adapter_target = sc->sc_initiator;
                    224:        sc->sc_link.adapter = adapter;
                    225:        sc->sc_link.device = &spc_dev;
                    226:        sc->sc_link.openings = 2;
                    227:
                    228:        bzero(&saa, sizeof(saa));
                    229:        saa.saa_sc_link = &sc->sc_link;
                    230:
                    231:        /*
                    232:         * ask the adapter what subunits are present
                    233:         */
                    234:        config_found(&sc->sc_dev, &saa, scsiprint);
                    235: }
                    236:
                    237: /*
                    238:  * Initialize MB89352 chip itself
                    239:  * The following conditions should hold:
                    240:  * spc_isa_probe should have succeeded, i.e. the iobase address in spc_softc
                    241:  * must be valid.
                    242:  */
                    243: void
                    244: spc_reset(sc)
                    245:        struct spc_softc *sc;
                    246: {
                    247:        bus_space_tag_t iot = sc->sc_iot;
                    248:        bus_space_handle_t ioh = sc->sc_ioh;
                    249:
                    250:        SPC_TRACE(("spc_reset  "));
                    251:        /*
                    252:         * Disable interrupts then reset the FUJITSU chip.
                    253:         */
                    254:        bus_space_write_1(iot, ioh, SCTL, SCTL_DISABLE | SCTL_CTRLRST);
                    255:        bus_space_write_1(iot, ioh, SCMD, 0);
                    256:        bus_space_write_1(iot, ioh, TMOD, 0);
                    257:        bus_space_write_1(iot, ioh, PCTL, 0);
                    258:        bus_space_write_1(iot, ioh, TEMP, 0);
                    259:        bus_space_write_1(iot, ioh, TCH, 0);
                    260:        bus_space_write_1(iot, ioh, TCM, 0);
                    261:        bus_space_write_1(iot, ioh, TCL, 0);
                    262:        bus_space_write_1(iot, ioh, INTS, 0);
                    263:        bus_space_write_1(iot, ioh, SCTL,
                    264:            SCTL_DISABLE | SCTL_ABRT_ENAB | SCTL_PARITY_ENAB | SCTL_RESEL_ENAB);
                    265:        bus_space_write_1(iot, ioh, BDID, sc->sc_initiator);
                    266:        delay(400);
                    267:        bus_space_write_1(iot, ioh, SCTL,
                    268:            bus_space_read_1(iot, ioh, SCTL) & ~SCTL_DISABLE);
                    269: }
                    270:
                    271:
                    272: /*
                    273:  * Pull the SCSI RST line for 500us.
                    274:  */
                    275: void
                    276: spc_scsi_reset(sc)
                    277:        struct spc_softc *sc;
                    278: {
                    279:        bus_space_tag_t iot = sc->sc_iot;
                    280:        bus_space_handle_t ioh = sc->sc_ioh;
                    281:
                    282:        SPC_TRACE(("spc_scsi_reset  "));
                    283:        bus_space_write_1(iot, ioh, SCMD, bus_space_read_1(iot, ioh, SCMD) | SCMD_RST);
                    284:        delay(500);
                    285:        bus_space_write_1(iot, ioh, SCMD, bus_space_read_1(iot, ioh, SCMD) & ~SCMD_RST);
                    286:        delay(50);
                    287: }
                    288:
                    289: /*
                    290:  * Initialize spc SCSI driver.
                    291:  */
                    292: void
                    293: spc_init(sc)
                    294:        struct spc_softc *sc;
                    295: {
                    296:        struct spc_acb *acb;
                    297:        int r;
                    298:
                    299:        SPC_TRACE(("spc_init  "));
                    300:        spc_reset(sc);
                    301:        spc_scsi_reset(sc);
                    302:        spc_reset(sc);
                    303:
                    304:        if (sc->sc_state == SPC_INIT) {
                    305:                /* First time through; initialize. */
                    306:                TAILQ_INIT(&sc->ready_list);
                    307:                TAILQ_INIT(&sc->nexus_list);
                    308:                TAILQ_INIT(&sc->free_list);
                    309:                sc->sc_nexus = NULL;
                    310:                acb = sc->sc_acb;
                    311:                bzero(acb, sizeof(sc->sc_acb));
                    312:                for (r = 0; r < sizeof(sc->sc_acb) / sizeof(*acb); r++) {
                    313:                        TAILQ_INSERT_TAIL(&sc->free_list, acb, chain);
                    314:                        acb++;
                    315:                }
                    316:                bzero(&sc->sc_tinfo, sizeof(sc->sc_tinfo));
                    317:        } else {
                    318:                /* Cancel any active commands. */
                    319:                sc->sc_state = SPC_CLEANING;
                    320:                if ((acb = sc->sc_nexus) != NULL) {
                    321:                        acb->xs->error = XS_DRIVER_STUFFUP;
                    322:                        timeout_del(&acb->xs->stimeout);
                    323:                        spc_done(sc, acb);
                    324:                }
                    325:                while ((acb = TAILQ_FIRST(&sc->nexus_list)) != NULL) {
                    326:                        acb->xs->error = XS_DRIVER_STUFFUP;
                    327:                        timeout_del(&acb->xs->stimeout);
                    328:                        spc_done(sc, acb);
                    329:                }
                    330:        }
                    331:
                    332:        sc->sc_prevphase = PH_INVALID;
                    333:        for (r = 0; r < 8; r++) {
                    334:                struct spc_tinfo *ti = &sc->sc_tinfo[r];
                    335:
                    336:                ti->flags = 0;
                    337: #if SPC_USE_SYNCHRONOUS
                    338:                ti->flags |= DO_SYNC;
                    339:                ti->period = sc->sc_minsync;
                    340:                ti->offset = SPC_SYNC_REQ_ACK_OFS;
                    341: #else
                    342:                ti->period = ti->offset = 0;
                    343: #endif
                    344: #if SPC_USE_WIDE
                    345:                ti->flags |= DO_WIDE;
                    346:                ti->width = SPC_MAX_WIDTH;
                    347: #else
                    348:                ti->width = 0;
                    349: #endif
                    350:        }
                    351:
                    352:        sc->sc_state = SPC_IDLE;
                    353:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, SCTL,
                    354:            bus_space_read_1(sc->sc_iot, sc->sc_ioh, SCTL) | SCTL_INTR_ENAB);
                    355: }
                    356:
                    357: void
                    358: spc_free_acb(sc, acb, flags)
                    359:        struct spc_softc *sc;
                    360:        struct spc_acb *acb;
                    361:        int flags;
                    362: {
                    363:        int s;
                    364:
                    365:        SPC_TRACE(("spc_free_acb  "));
                    366:        s = splbio();
                    367:
                    368:        acb->flags = 0;
                    369:        TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
                    370:
                    371:        /*
                    372:         * If there were none, wake anybody waiting for one to come free,
                    373:         * starting with queued entries.
                    374:         */
                    375:        if (TAILQ_NEXT(acb, chain) == NULL)
                    376:                wakeup(&sc->free_list);
                    377:
                    378:        splx(s);
                    379: }
                    380:
                    381: struct spc_acb *
                    382: spc_get_acb(sc, flags)
                    383:        struct spc_softc *sc;
                    384:        int flags;
                    385: {
                    386:        struct spc_acb *acb;
                    387:        int s;
                    388:
                    389:        SPC_TRACE(("spc_get_acb  "));
                    390:        s = splbio();
                    391:
                    392:        while ((acb = TAILQ_FIRST(&sc->free_list)) == NULL &&
                    393:               (flags & SCSI_NOSLEEP) == 0)
                    394:                tsleep(&sc->free_list, PRIBIO, "spcacb", 0);
                    395:        if (acb) {
                    396:                TAILQ_REMOVE(&sc->free_list, acb, chain);
                    397:                acb->flags |= ACB_ALLOC;
                    398:        }
                    399:
                    400:        splx(s);
                    401:        return acb;
                    402: }
                    403:
                    404: /*
                    405:  * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
                    406:  */
                    407:
                    408: /*
                    409:  * Expected sequence:
                    410:  * 1) Command inserted into ready list
                    411:  * 2) Command selected for execution
                    412:  * 3) Command won arbitration and has selected target device
                    413:  * 4) Send message out (identify message, eventually also sync.negotiations)
                    414:  * 5) Send command
                    415:  * 5a) Receive disconnect message, disconnect.
                    416:  * 5b) Reselected by target
                    417:  * 5c) Receive identify message from target.
                    418:  * 6) Send or receive data
                    419:  * 7) Receive status
                    420:  * 8) Receive message (command complete etc.)
                    421:  * 9) If status == SCSI_CHECK construct a synthetic request sense SCSI cmd.
                    422:  *    Repeat 2-8 (no disconnects please...)
                    423:  */
                    424:
                    425: /*
                    426:  * Start a SCSI-command
                    427:  * This function is called by the higher level SCSI-driver to queue/run
                    428:  * SCSI-commands.
                    429:  */
                    430: int
                    431: spc_scsi_cmd(xs)
                    432:        struct scsi_xfer *xs;
                    433: {
                    434:        struct scsi_link *sc_link = xs->sc_link;
                    435:        struct spc_softc *sc = sc_link->adapter_softc;
                    436:        struct spc_acb *acb;
                    437:        int s, flags;
                    438:
                    439:        SPC_TRACE(("spc_scsi_cmd  "));
                    440:        SPC_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
                    441:            sc_link->target));
                    442:
                    443:        flags = xs->flags;
                    444:        if ((acb = spc_get_acb(sc, flags)) == NULL) {
                    445:                return TRY_AGAIN_LATER;
                    446:        }
                    447:
                    448:        /* Initialize acb */
                    449:        acb->xs = xs;
                    450:        acb->timeout = xs->timeout;
                    451:
                    452:        if (xs->flags & SCSI_RESET) {
                    453:                acb->flags |= ACB_RESET;
                    454:                acb->scsi_cmd_length = 0;
                    455:                acb->data_length = 0;
                    456:        } else {
                    457:                bcopy(xs->cmd, &acb->scsi_cmd, xs->cmdlen);
                    458:                acb->scsi_cmd_length = xs->cmdlen;
                    459:                acb->data_addr = xs->data;
                    460:                acb->data_length = xs->datalen;
                    461:        }
                    462:        acb->target_stat = 0;
                    463:
                    464:        s = splbio();
                    465:
                    466:        TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain);
                    467:        /*
                    468:         * Start scheduling unless a queue process is in progress.
                    469:         */
                    470:        if (sc->sc_state == SPC_IDLE)
                    471:                spc_sched(sc);
                    472:        /*
                    473:         * After successful sending, check if we should return just now.
                    474:         * If so, return SUCCESSFULLY_QUEUED.
                    475:         */
                    476:
                    477:        splx(s);
                    478:
                    479:        if ((flags & SCSI_POLL) == 0)
                    480:                return SUCCESSFULLY_QUEUED;
                    481:
                    482:        /* Not allowed to use interrupts, use polling instead */
                    483:        s = splbio();
                    484:        if (spc_poll(sc, xs, acb->timeout)) {
                    485:                spc_timeout(acb);
                    486:                if (spc_poll(sc, xs, acb->timeout))
                    487:                        spc_timeout(acb);
                    488:        }
                    489:        splx(s);
                    490:        return COMPLETE;
                    491: }
                    492:
                    493: /*
                    494:  * Used when interrupt driven I/O isn't allowed, e.g. during boot.
                    495:  */
                    496: int
                    497: spc_poll(sc, xs, count)
                    498:        struct spc_softc *sc;
                    499:        struct scsi_xfer *xs;
                    500:        int count;
                    501: {
                    502:        bus_space_tag_t iot = sc->sc_iot;
                    503:        bus_space_handle_t ioh = sc->sc_ioh;
                    504:
                    505:        SPC_TRACE(("spc_poll  "));
                    506:        while (count) {
                    507:                /*
                    508:                 * If we had interrupts enabled, would we
                    509:                 * have got an interrupt?
                    510:                 */
                    511:                if (bus_space_read_1(iot, ioh, INTS) != 0)
                    512:                        spc_intr(sc);
                    513:                if ((xs->flags & ITSDONE) != 0)
                    514:                        return 0;
                    515:                delay(1000);
                    516:                count--;
                    517:        }
                    518:        return 1;
                    519: }
                    520:
                    521: /*
                    522:  * LOW LEVEL SCSI UTILITIES
                    523:  */
                    524:
                    525: integrate void
                    526: spc_sched_msgout(sc, m)
                    527:        struct spc_softc *sc;
                    528:        u_char m;
                    529: {
                    530:        bus_space_tag_t iot = sc->sc_iot;
                    531:        bus_space_handle_t ioh = sc->sc_ioh;
                    532:
                    533:        SPC_TRACE(("spc_sched_msgout  "));
                    534:        if (sc->sc_msgpriq == 0)
                    535:                bus_space_write_1(iot, ioh, SCMD, SCMD_SET_ATN);
                    536:        sc->sc_msgpriq |= m;
                    537: }
                    538:
                    539: /*
                    540:  * Set synchronous transfer offset and period.
                    541:  */
                    542: integrate void
                    543: spc_setsync(sc, ti)
                    544:        struct spc_softc *sc;
                    545:        struct spc_tinfo *ti;
                    546: {
                    547: #if SPC_USE_SYNCHRONOUS
                    548:        bus_space_tag_t iot = sc->sc_iot;
                    549:        bus_space_handle_t ioh = sc->sc_ioh;
                    550:
                    551:        SPC_TRACE(("spc_setsync  "));
                    552:        if (ti->offset != 0)
                    553:                bus_space_write_1(iot, ioh, TMOD,
                    554:                    ((ti->period * sc->sc_freq) / 250 - 2) << 4 | ti->offset);
                    555:        else
                    556:                bus_space_write_1(iot, ioh, TMOD, 0);
                    557: #endif
                    558: }
                    559:
                    560: /*
                    561:  * Start a selection.  This is used by spc_sched() to select an idle target,
                    562:  * and by spc_done() to immediately reselect a target to get sense information.
                    563:  */
                    564: void
                    565: spc_select(sc, acb)
                    566:        struct spc_softc *sc;
                    567:        struct spc_acb *acb;
                    568: {
                    569:        struct scsi_link *sc_link = acb->xs->sc_link;
                    570:        int target = sc_link->target;
                    571:        struct spc_tinfo *ti = &sc->sc_tinfo[target];
                    572:        bus_space_tag_t iot = sc->sc_iot;
                    573:        bus_space_handle_t ioh = sc->sc_ioh;
                    574:
                    575:        SPC_TRACE(("spc_select  "));
                    576:        spc_setsync(sc, ti);
                    577:
                    578: #if 0
                    579:        bus_space_write_1(iot, ioh, SCMD, SCMD_SET_ATN);
                    580: #endif
                    581:
                    582:        bus_space_write_1(iot, ioh, PCTL, 0);
                    583:        bus_space_write_1(iot, ioh, TEMP,
                    584:            (1 << sc->sc_initiator) | (1 << target));
                    585:        /*
                    586:         * Setup BSY timeout (selection timeout).
                    587:         * 250ms according to the SCSI specification.
                    588:         * T = (X * 256 + 15) * Tclf * 2  (Tclf = 200ns on x68k)
                    589:         * To setup 256ms timeout,
                    590:         * 128000ns/200ns = X * 256 + 15
                    591:         * 640 - 15 = X * 256
                    592:         * X = 625 / 256
                    593:         * X = 2 + 113 / 256
                    594:         *  ==> tch = 2, tcm = 113 (correct?)
                    595:         */
                    596:        /* Time to the information transfer phase start. */
                    597:        /* XXX These values should be calculated from sc_freq */
                    598:        bus_space_write_1(iot, ioh, TCH, 2);
                    599:        bus_space_write_1(iot, ioh, TCM, 113);
                    600:        bus_space_write_1(iot, ioh, TCL, 3);
                    601:        bus_space_write_1(iot, ioh, SCMD, SCMD_SELECT);
                    602:
                    603:        sc->sc_state = SPC_SELECTING;
                    604: }
                    605:
                    606: int
                    607: spc_reselect(sc, message)
                    608:        struct spc_softc *sc;
                    609:        int message;
                    610: {
                    611:        u_char selid, target, lun;
                    612:        struct spc_acb *acb;
                    613:        struct scsi_link *sc_link;
                    614:        struct spc_tinfo *ti;
                    615:
                    616:        SPC_TRACE(("spc_reselect  "));
                    617:        /*
                    618:         * The SCSI chip made a snapshot of the data bus while the reselection
                    619:         * was being negotiated.  This enables us to determine which target did
                    620:         * the reselect.
                    621:         */
                    622:        selid = sc->sc_selid & ~(1 << sc->sc_initiator);
                    623:        if (selid & (selid - 1)) {
                    624:                printf("%s: reselect with invalid selid %02x; "
                    625:                    "sending DEVICE RESET\n", sc->sc_dev.dv_xname, selid);
                    626:                SPC_BREAK();
                    627:                goto reset;
                    628:        }
                    629:
                    630:        /*
                    631:         * Search wait queue for disconnected cmd
                    632:         * The list should be short, so I haven't bothered with
                    633:         * any more sophisticated structures than a simple
                    634:         * singly linked list.
                    635:         */
                    636:        target = ffs(selid) - 1;
                    637:        lun = message & 0x07;
                    638:        TAILQ_FOREACH(acb, &sc->nexus_list, chain) {
                    639:                sc_link = acb->xs->sc_link;
                    640:                if (sc_link->target == target &&
                    641:                    sc_link->lun == lun)
                    642:                        break;
                    643:        }
                    644:        if (acb == NULL) {
                    645:                printf("%s: reselect from target %d lun %d with no nexus; "
                    646:                    "sending ABORT\n", sc->sc_dev.dv_xname, target, lun);
                    647:                SPC_BREAK();
                    648:                goto abort;
                    649:        }
                    650:
                    651:        /* Make this nexus active again. */
                    652:        TAILQ_REMOVE(&sc->nexus_list, acb, chain);
                    653:        sc->sc_state = SPC_CONNECTED;
                    654:        sc->sc_nexus = acb;
                    655:        ti = &sc->sc_tinfo[target];
                    656:        ti->lubusy |= (1 << lun);
                    657:        spc_setsync(sc, ti);
                    658:
                    659:        if (acb->flags & ACB_RESET)
                    660:                spc_sched_msgout(sc, SEND_DEV_RESET);
                    661:        else if (acb->flags & ACB_ABORT)
                    662:                spc_sched_msgout(sc, SEND_ABORT);
                    663:
                    664:        /* Do an implicit RESTORE POINTERS. */
                    665:        sc->sc_dp = acb->data_addr;
                    666:        sc->sc_dleft = acb->data_length;
                    667:        sc->sc_cp = (u_char *)&acb->scsi_cmd;
                    668:        sc->sc_cleft = acb->scsi_cmd_length;
                    669:
                    670:        return (0);
                    671:
                    672: reset:
                    673:        spc_sched_msgout(sc, SEND_DEV_RESET);
                    674:        return (1);
                    675:
                    676: abort:
                    677:        spc_sched_msgout(sc, SEND_ABORT);
                    678:        return (1);
                    679: }
                    680:
                    681: /*
                    682:  * Schedule a SCSI operation.  This has now been pulled out of the interrupt
                    683:  * handler so that we may call it from spc_scsi_cmd and spc_done.  This may
                    684:  * save us an unnecessary interrupt just to get things going.  Should only be
                    685:  * called when state == SPC_IDLE and at bio pl.
                    686:  */
                    687: void
                    688: spc_sched(sc)
                    689:        struct spc_softc *sc;
                    690: {
                    691:        struct spc_acb *acb;
                    692:        struct scsi_link *sc_link;
                    693:        struct spc_tinfo *ti;
                    694:
                    695:        /* missing the hw, just return and wait for our hw */
                    696:        if (sc->sc_flags & SPC_INACTIVE)
                    697:                return;
                    698:        SPC_TRACE(("spc_sched  "));
                    699:        /*
                    700:         * Find first acb in ready queue that is for a target/lunit pair that
                    701:         * is not busy.
                    702:         */
                    703:        TAILQ_FOREACH(acb, &sc->ready_list, chain) {
                    704:                sc_link = acb->xs->sc_link;
                    705:                ti = &sc->sc_tinfo[sc_link->target];
                    706:                if ((ti->lubusy & (1 << sc_link->lun)) == 0) {
                    707:                        SPC_MISC(("selecting %d:%d  ",
                    708:                            sc_link->target, sc_link->lun));
                    709:                        TAILQ_REMOVE(&sc->ready_list, acb, chain);
                    710:                        sc->sc_nexus = acb;
                    711:                        spc_select(sc, acb);
                    712:                        return;
                    713:                } else
                    714:                        SPC_MISC(("%d:%d busy\n",
                    715:                            sc_link->target, sc_link->lun));
                    716:        }
                    717:        SPC_MISC(("idle  "));
                    718:        /* Nothing to start; just enable reselections and wait. */
                    719: }
                    720:
                    721: void
                    722: spc_sense(sc, acb)
                    723:        struct spc_softc *sc;
                    724:        struct spc_acb *acb;
                    725: {
                    726:        struct scsi_xfer *xs = acb->xs;
                    727:        struct scsi_link *sc_link = xs->sc_link;
                    728:        struct spc_tinfo *ti = &sc->sc_tinfo[sc_link->target];
                    729:        struct scsi_sense *ss = (void *)&acb->scsi_cmd;
                    730:
                    731:        SPC_MISC(("requesting sense  "));
                    732:        /* Next, setup a request sense command block */
                    733:        bzero(ss, sizeof(*ss));
                    734:        ss->opcode = REQUEST_SENSE;
                    735:        ss->byte2 = sc_link->lun << 5;
                    736:        ss->length = sizeof(struct scsi_sense_data);
                    737:        acb->scsi_cmd_length = sizeof(*ss);
                    738:        acb->data_addr = (char *)&xs->sense;
                    739:        acb->data_length = sizeof(struct scsi_sense_data);
                    740:        acb->flags |= ACB_SENSE;
                    741:        ti->senses++;
                    742:        if (acb->flags & ACB_NEXUS)
                    743:                ti->lubusy &= ~(1 << sc_link->lun);
                    744:        if (acb == sc->sc_nexus) {
                    745:                spc_select(sc, acb);
                    746:        } else {
                    747:                spc_dequeue(sc, acb);
                    748:                TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
                    749:                if (sc->sc_state == SPC_IDLE)
                    750:                        spc_sched(sc);
                    751:        }
                    752: }
                    753:
                    754: /*
                    755:  * POST PROCESSING OF SCSI_CMD (usually current)
                    756:  */
                    757: void
                    758: spc_done(sc, acb)
                    759:        struct spc_softc *sc;
                    760:        struct spc_acb *acb;
                    761: {
                    762:        struct scsi_xfer *xs = acb->xs;
                    763:        struct scsi_link *sc_link = xs->sc_link;
                    764:        struct spc_tinfo *ti = &sc->sc_tinfo[sc_link->target];
                    765:
                    766:        SPC_TRACE(("spc_done  "));
                    767:
                    768:        /*
                    769:         * Now, if we've come here with no error code, i.e. we've kept the
                    770:         * initial XS_NOERROR, and the status code signals that we should
                    771:         * check sense, we'll need to set up a request sense cmd block and
                    772:         * push the command back into the ready queue *before* any other
                    773:         * commands for this target/lunit, else we lose the sense info.
                    774:         * We don't support chk sense conditions for the request sense cmd.
                    775:         */
                    776:        if (xs->error == XS_NOERROR) {
                    777:                if (acb->flags & ACB_ABORT) {
                    778:                        xs->error = XS_DRIVER_STUFFUP;
                    779:                } else if (acb->flags & ACB_SENSE) {
                    780:                        xs->error = XS_SENSE;
                    781:                } else {
                    782:                        switch (acb->target_stat) {
                    783:                        case SCSI_CHECK:
                    784:                                /* First, save the return values */
                    785:                                xs->resid = acb->data_length;
                    786:                                xs->status = acb->target_stat;
                    787:                                spc_sense(sc, acb);
                    788:                                return;
                    789:                        case SCSI_BUSY:
                    790:                                xs->error = XS_BUSY;
                    791:                                break;
                    792:                        case SCSI_OK:
                    793:                                xs->resid = acb->data_length;
                    794:                                break;
                    795:                        default:
                    796:                                xs->error = XS_DRIVER_STUFFUP;
                    797: #ifdef SPC_DEBUG
                    798:                                printf("%s: spc_done: bad stat 0x%x\n",
                    799:                                    sc->sc_dev.dv_xname, acb->target_stat);
                    800: #endif
                    801:                                break;
                    802:                        }
                    803:                }
                    804:        }
                    805:
                    806:        xs->flags |= ITSDONE;
                    807:
                    808: #ifdef SPC_DEBUG
                    809:        if ((spc_debug & SPC_SHOWMISC) != 0) {
                    810:                if (xs->resid != 0)
                    811:                        printf("resid=%d ", xs->resid);
                    812:                if (xs->error == XS_SENSE)
                    813:                        printf("sense=0x%02x\n", xs->sense.error_code);
                    814:                else
                    815:                        printf("error=%d\n", xs->error);
                    816:        }
                    817: #endif
                    818:
                    819:        /*
                    820:         * Remove the ACB from whatever queue it happens to be on.
                    821:         */
                    822:        if (acb->flags & ACB_NEXUS)
                    823:                ti->lubusy &= ~(1 << sc_link->lun);
                    824:        if (acb == sc->sc_nexus) {
                    825:                sc->sc_nexus = NULL;
                    826:                sc->sc_state = SPC_IDLE;
                    827:                spc_sched(sc);
                    828:        } else
                    829:                spc_dequeue(sc, acb);
                    830:
                    831:        spc_free_acb(sc, acb, xs->flags);
                    832:        ti->cmds++;
                    833:        scsi_done(xs);
                    834: }
                    835:
                    836: void
                    837: spc_dequeue(sc, acb)
                    838:        struct spc_softc *sc;
                    839:        struct spc_acb *acb;
                    840: {
                    841:
                    842:        SPC_TRACE(("spc_dequeue  "));
                    843:        if (acb->flags & ACB_NEXUS)
                    844:                TAILQ_REMOVE(&sc->nexus_list, acb, chain);
                    845:        else
                    846:                TAILQ_REMOVE(&sc->ready_list, acb, chain);
                    847: }
                    848:
                    849: /*
                    850:  * INTERRUPT/PROTOCOL ENGINE
                    851:  */
                    852:
                    853: #define IS1BYTEMSG(m) (((m) != 0x01 && (m) < 0x20) || (m) >= 0x80)
                    854: #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
                    855: #define ISEXTMSG(m) ((m) == 0x01)
                    856:
                    857: /*
                    858:  * Precondition:
                    859:  * The SCSI bus is already in the MSGI phase and there is a message byte
                    860:  * on the bus, along with an asserted REQ signal.
                    861:  */
                    862: void
                    863: spc_msgin(sc)
                    864:        struct spc_softc *sc;
                    865: {
                    866:        bus_space_tag_t iot = sc->sc_iot;
                    867:        bus_space_handle_t ioh = sc->sc_ioh;
                    868:        int n;
                    869:
                    870:        SPC_TRACE(("spc_msgin  "));
                    871:
                    872:        if (sc->sc_prevphase == PH_MSGIN) {
                    873:                /* This is a continuation of the previous message. */
                    874:                n = sc->sc_imp - sc->sc_imess;
                    875:                goto nextbyte;
                    876:        }
                    877:
                    878:        /* This is a new MESSAGE IN phase.  Clean up our state. */
                    879:        sc->sc_flags &= ~SPC_DROP_MSGIN;
                    880:
                    881: nextmsg:
                    882:        n = 0;
                    883:        sc->sc_imp = &sc->sc_imess[n];
                    884:
                    885: nextbyte:
                    886:        /*
                    887:         * Read a whole message, but don't ack the last byte.  If we reject the
                    888:         * message, we have to assert ATN during the message transfer phase
                    889:         * itself.
                    890:         */
                    891:        for (;;) {
                    892: #if 0
                    893:                for (;;) {
                    894:                        if ((bus_space_read_1(iot, ioh, PSNS) & PSNS_REQ) != 0)
                    895:                                break;
                    896:                        /* Wait for REQINIT.  XXX Need timeout. */
                    897:                }
                    898: #endif
                    899:                if (bus_space_read_1(iot, ioh, INTS) != 0) {
                    900:                        /*
                    901:                         * Target left MESSAGE IN, probably because it
                    902:                         * a) noticed our ATN signal, or
                    903:                         * b) ran out of messages.
                    904:                         */
                    905:                        goto out;
                    906:                }
                    907:
                    908:                /* If parity error, just dump everything on the floor. */
                    909:                if ((bus_space_read_1(iot, ioh, SERR) &
                    910:                     (SERR_SCSI_PAR|SERR_SPC_PAR)) != 0) {
                    911:                        sc->sc_flags |= SPC_DROP_MSGIN;
                    912:                        spc_sched_msgout(sc, SEND_PARITY_ERROR);
                    913:                }
                    914:
                    915:                /* send TRANSFER command. */
                    916:                bus_space_write_1(iot, ioh, TCH, 0);
                    917:                bus_space_write_1(iot, ioh, TCM, 0);
                    918:                bus_space_write_1(iot, ioh, TCL, 1);
                    919:                bus_space_write_1(iot, ioh, PCTL,
                    920:                                  sc->sc_phase | PCTL_BFINT_ENAB);
                    921: #ifdef x68k
                    922:                bus_space_write_1(iot, ioh, SCMD, SCMD_XFR); /* | SCMD_PROG_XFR */
                    923: #else
                    924:                bus_space_write_1(iot, ioh, SCMD, SCMD_XFR | SCMD_PROG_XFR);    /* XXX */
                    925: #endif
                    926:                for (;;) {
                    927:                        /*if ((bus_space_read_1(iot, ioh, SSTS) & SSTS_BUSY) != 0
                    928:                                && (bus_space_read_1(iot, ioh, SSTS) & SSTS_DREG_EMPTY) != 0)*/
                    929:                        if ((bus_space_read_1(iot, ioh, SSTS) & SSTS_DREG_EMPTY) == 0)
                    930:                                break;
                    931:                        if (bus_space_read_1(iot, ioh, INTS) != 0)
                    932:                                goto out;
                    933:                }
                    934:
                    935:                /* Gather incoming message bytes if needed. */
                    936:                if ((sc->sc_flags & SPC_DROP_MSGIN) == 0) {
                    937:                        if (n >= SPC_MAX_MSG_LEN) {
                    938:                                (void) bus_space_read_1(iot, ioh, DREG);
                    939:                                sc->sc_flags |= SPC_DROP_MSGIN;
                    940:                                spc_sched_msgout(sc, SEND_REJECT);
                    941:                        } else {
                    942:                                *sc->sc_imp++ = bus_space_read_1(iot, ioh, DREG);
                    943:                                n++;
                    944:                                /*
                    945:                                 * This testing is suboptimal, but most
                    946:                                 * messages will be of the one byte variety, so
                    947:                                 * it should not affect performance
                    948:                                 * significantly.
                    949:                                 */
                    950:                                if (n == 1 && IS1BYTEMSG(sc->sc_imess[0]))
                    951:                                        break;
                    952:                                if (n == 2 && IS2BYTEMSG(sc->sc_imess[0]))
                    953:                                        break;
                    954:                                if (n >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
                    955:                                    n == sc->sc_imess[1] + 2)
                    956:                                        break;
                    957:                        }
                    958:                } else
                    959:                        (void) bus_space_read_1(iot, ioh, DREG);
                    960:
                    961:                /*
                    962:                 * If we reach this spot we're either:
                    963:                 * a) in the middle of a multi-byte message, or
                    964:                 * b) dropping bytes.
                    965:                 */
                    966: #if 0
                    967:                /* Ack the last byte read. */
                    968:                /*(void) bus_space_read_1(iot, ioh, DREG);*/
                    969:                while ((bus_space_read_1(iot, ioh, PSNS) & ACKI) != 0)
                    970:                        ;
                    971: #endif
                    972:        }
                    973:
                    974:        SPC_MISC(("n=%d imess=0x%02x  ", n, sc->sc_imess[0]));
                    975:
                    976:        /* We now have a complete message.  Parse it. */
                    977:        switch (sc->sc_state) {
                    978:                struct spc_acb *acb;
                    979:                struct scsi_link *sc_link;
                    980:                struct spc_tinfo *ti;
                    981:
                    982:        case SPC_CONNECTED:
                    983:                SPC_ASSERT(sc->sc_nexus != NULL);
                    984:                acb = sc->sc_nexus;
                    985:                ti = &sc->sc_tinfo[acb->xs->sc_link->target];
                    986:
                    987:                switch (sc->sc_imess[0]) {
                    988:                case MSG_CMDCOMPLETE:
                    989:                        if (sc->sc_dleft < 0) {
                    990:                                sc_link = acb->xs->sc_link;
                    991:                                printf("%s: %d extra bytes from %d:%d\n",
                    992:                                    sc->sc_dev.dv_xname, -sc->sc_dleft,
                    993:                                    sc_link->target, sc_link->lun);
                    994:                                acb->data_length = 0;
                    995:                        }
                    996:                        acb->xs->resid = acb->data_length = sc->sc_dleft;
                    997:                        sc->sc_state = SPC_CMDCOMPLETE;
                    998:                        break;
                    999:
                   1000:                case MSG_PARITY_ERROR:
                   1001:                        /* Resend the last message. */
                   1002:                        spc_sched_msgout(sc, sc->sc_lastmsg);
                   1003:                        break;
                   1004:
                   1005:                case MSG_MESSAGE_REJECT:
                   1006:                        SPC_MISC(("message rejected %02x  ", sc->sc_lastmsg));
                   1007:                        switch (sc->sc_lastmsg) {
                   1008: #if SPC_USE_SYNCHRONOUS + SPC_USE_WIDE
                   1009:                        case SEND_IDENTIFY:
                   1010:                                ti->flags &= ~(DO_SYNC | DO_WIDE);
                   1011:                                ti->period = ti->offset = 0;
                   1012:                                spc_setsync(sc, ti);
                   1013:                                ti->width = 0;
                   1014:                                break;
                   1015: #endif
                   1016: #if SPC_USE_SYNCHRONOUS
                   1017:                        case SEND_SDTR:
                   1018:                                ti->flags &= ~DO_SYNC;
                   1019:                                ti->period = ti->offset = 0;
                   1020:                                spc_setsync(sc, ti);
                   1021:                                break;
                   1022: #endif
                   1023: #if SPC_USE_WIDE
                   1024:                        case SEND_WDTR:
                   1025:                                ti->flags &= ~DO_WIDE;
                   1026:                                ti->width = 0;
                   1027:                                break;
                   1028: #endif
                   1029:                        case SEND_INIT_DET_ERR:
                   1030:                                spc_sched_msgout(sc, SEND_ABORT);
                   1031:                                break;
                   1032:                        }
                   1033:                        break;
                   1034:
                   1035:                case MSG_NOOP:
                   1036:                        break;
                   1037:
                   1038:                case MSG_DISCONNECT:
                   1039:                        ti->dconns++;
                   1040:                        sc->sc_state = SPC_DISCONNECT;
                   1041:                        break;
                   1042:
                   1043:                case MSG_SAVEDATAPOINTER:
                   1044:                        acb->data_addr = sc->sc_dp;
                   1045:                        acb->data_length = sc->sc_dleft;
                   1046:                        break;
                   1047:
                   1048:                case MSG_RESTOREPOINTERS:
                   1049:                        sc->sc_dp = acb->data_addr;
                   1050:                        sc->sc_dleft = acb->data_length;
                   1051:                        sc->sc_cp = (u_char *)&acb->scsi_cmd;
                   1052:                        sc->sc_cleft = acb->scsi_cmd_length;
                   1053:                        break;
                   1054:
                   1055:                case MSG_EXTENDED:
                   1056:                        switch (sc->sc_imess[2]) {
                   1057: #if SPC_USE_SYNCHRONOUS
                   1058:                        case MSG_EXT_SDTR:
                   1059:                                if (sc->sc_imess[1] != 3)
                   1060:                                        goto reject;
                   1061:                                ti->period = sc->sc_imess[3];
                   1062:                                ti->offset = sc->sc_imess[4];
                   1063:                                ti->flags &= ~DO_SYNC;
                   1064:                                if (ti->offset == 0) {
                   1065:                                } else if (ti->period < sc->sc_minsync ||
                   1066:                                           ti->period > sc->sc_maxsync ||
                   1067:                                           ti->offset > 8) {
                   1068:                                        ti->period = ti->offset = 0;
                   1069:                                        spc_sched_msgout(sc, SEND_SDTR);
                   1070:                                } else {
                   1071:                                        sc_print_addr(acb->xs->sc_link);
                   1072:                                        printf("sync, offset %d, "
                   1073:                                            "period %dnsec\n",
                   1074:                                            ti->offset, ti->period * 4);
                   1075:                                }
                   1076:                                spc_setsync(sc, ti);
                   1077:                                break;
                   1078: #endif
                   1079:
                   1080: #if SPC_USE_WIDE
                   1081:                        case MSG_EXT_WDTR:
                   1082:                                if (sc->sc_imess[1] != 2)
                   1083:                                        goto reject;
                   1084:                                ti->width = sc->sc_imess[3];
                   1085:                                ti->flags &= ~DO_WIDE;
                   1086:                                if (ti->width == 0) {
                   1087:                                } else if (ti->width > SPC_MAX_WIDTH) {
                   1088:                                        ti->width = 0;
                   1089:                                        spc_sched_msgout(sc, SEND_WDTR);
                   1090:                                } else {
                   1091:                                        sc_print_addr(acb->xs->sc_link);
                   1092:                                        printf("wide, width %d\n",
                   1093:                                            1 << (3 + ti->width));
                   1094:                                }
                   1095:                                break;
                   1096: #endif
                   1097:
                   1098:                        default:
                   1099:                                printf("%s: unrecognized MESSAGE EXTENDED; "
                   1100:                                    "sending REJECT\n", sc->sc_dev.dv_xname);
                   1101:                                SPC_BREAK();
                   1102:                                goto reject;
                   1103:                        }
                   1104:                        break;
                   1105:
                   1106:                default:
                   1107:                        printf("%s: unrecognized MESSAGE; sending REJECT\n",
                   1108:                            sc->sc_dev.dv_xname);
                   1109:                        SPC_BREAK();
                   1110:                reject:
                   1111:                        spc_sched_msgout(sc, SEND_REJECT);
                   1112:                        break;
                   1113:                }
                   1114:                break;
                   1115:
                   1116:        case SPC_RESELECTED:
                   1117:                if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
                   1118:                        printf("%s: reselect without IDENTIFY; "
                   1119:                            "sending DEVICE RESET\n", sc->sc_dev.dv_xname);
                   1120:                        SPC_BREAK();
                   1121:                        goto reset;
                   1122:                }
                   1123:
                   1124:                (void) spc_reselect(sc, sc->sc_imess[0]);
                   1125:                break;
                   1126:
                   1127:        default:
                   1128:                printf("%s: unexpected MESSAGE IN; sending DEVICE RESET\n",
                   1129:                    sc->sc_dev.dv_xname);
                   1130:                SPC_BREAK();
                   1131:        reset:
                   1132:                spc_sched_msgout(sc, SEND_DEV_RESET);
                   1133:                break;
                   1134:
                   1135: #ifdef notdef
                   1136:        abort:
                   1137:                spc_sched_msgout(sc, SEND_ABORT);
                   1138:                break;
                   1139: #endif
                   1140:        }
                   1141:
                   1142:        /* Ack the last message byte. */
                   1143: #if 0 /* XXX? */
                   1144:        (void) bus_space_read_1(iot, ioh, DREG);
                   1145:        while ((bus_space_read_1(iot, ioh, PSNS) & ACKI) != 0)
                   1146:                ;
                   1147: #endif
                   1148:
                   1149:        /* Go get the next message, if any. */
                   1150:        goto nextmsg;
                   1151:
                   1152: out:
                   1153:        bus_space_write_1(iot, ioh, SCMD, SCMD_RST_ACK);
                   1154:        SPC_MISC(("n=%d imess=0x%02x  ", n, sc->sc_imess[0]));
                   1155: }
                   1156:
                   1157: /*
                   1158:  * Send the highest priority, scheduled message.
                   1159:  */
                   1160: void
                   1161: spc_msgout(sc)
                   1162:        struct spc_softc *sc;
                   1163: {
                   1164:        bus_space_tag_t iot = sc->sc_iot;
                   1165:        bus_space_handle_t ioh = sc->sc_ioh;
                   1166: #if SPC_USE_SYNCHRONOUS
                   1167:        struct spc_tinfo *ti;
                   1168: #endif
                   1169:        int n;
                   1170:
                   1171:        SPC_TRACE(("spc_msgout  "));
                   1172:
                   1173:        if (sc->sc_prevphase == PH_MSGOUT) {
                   1174:                if (sc->sc_omp == sc->sc_omess) {
                   1175:                        /*
                   1176:                         * This is a retransmission.
                   1177:                         *
                   1178:                         * We get here if the target stayed in MESSAGE OUT
                   1179:                         * phase.  Section 5.1.9.2 of the SCSI 2 spec indicates
                   1180:                         * that all of the previously transmitted messages must
                   1181:                         * be sent again, in the same order.  Therefore, we
                   1182:                         * requeue all the previously transmitted messages, and
                   1183:                         * start again from the top.  Our simple priority
                   1184:                         * scheme keeps the messages in the right order.
                   1185:                         */
                   1186:                        SPC_MISC(("retransmitting  "));
                   1187:                        sc->sc_msgpriq |= sc->sc_msgoutq;
                   1188:                        /*
                   1189:                         * Set ATN.  If we're just sending a trivial 1-byte
                   1190:                         * message, we'll clear ATN later on anyway.
                   1191:                         */
                   1192:                        bus_space_write_1(iot, ioh, SCMD,
                   1193:                            SCMD_SET_ATN); /* XXX? */
                   1194:                } else {
                   1195:                        /* This is a continuation of the previous message. */
                   1196:                        n = sc->sc_omp - sc->sc_omess;
                   1197:                        goto nextbyte;
                   1198:                }
                   1199:        }
                   1200:
                   1201:        /* No messages transmitted so far. */
                   1202:        sc->sc_msgoutq = 0;
                   1203:        sc->sc_lastmsg = 0;
                   1204:
                   1205: nextmsg:
                   1206:        /* Pick up highest priority message. */
                   1207:        sc->sc_currmsg = sc->sc_msgpriq & -sc->sc_msgpriq;
                   1208:        sc->sc_msgpriq &= ~sc->sc_currmsg;
                   1209:        sc->sc_msgoutq |= sc->sc_currmsg;
                   1210:
                   1211:        /* Build the outgoing message data. */
                   1212:        switch (sc->sc_currmsg) {
                   1213:        case SEND_IDENTIFY:
                   1214:                SPC_ASSERT(sc->sc_nexus != NULL);
                   1215:                sc->sc_omess[0] =
                   1216:                    MSG_IDENTIFY(sc->sc_nexus->xs->sc_link->lun, 1);
                   1217:                n = 1;
                   1218:                break;
                   1219:
                   1220: #if SPC_USE_SYNCHRONOUS
                   1221:        case SEND_SDTR:
                   1222:                SPC_ASSERT(sc->sc_nexus != NULL);
                   1223:                ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target];
                   1224:                sc->sc_omess[4] = MSG_EXTENDED;
                   1225:                sc->sc_omess[3] = MSG_EXT_SDTR_LEN;
                   1226:                sc->sc_omess[2] = MSG_EXT_SDTR;
                   1227:                sc->sc_omess[1] = ti->period >> 2;
                   1228:                sc->sc_omess[0] = ti->offset;
                   1229:                n = 5;
                   1230:                break;
                   1231: #endif
                   1232:
                   1233: #if SPC_USE_WIDE
                   1234:        case SEND_WDTR:
                   1235:                SPC_ASSERT(sc->sc_nexus != NULL);
                   1236:                ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target];
                   1237:                sc->sc_omess[3] = MSG_EXTENDED;
                   1238:                sc->sc_omess[2] = MSG_EXT_WDTR_LEN;
                   1239:                sc->sc_omess[1] = MSG_EXT_WDTR;
                   1240:                sc->sc_omess[0] = ti->width;
                   1241:                n = 4;
                   1242:                break;
                   1243: #endif
                   1244:
                   1245:        case SEND_DEV_RESET:
                   1246:                sc->sc_flags |= SPC_ABORTING;
                   1247:                sc->sc_omess[0] = MSG_BUS_DEV_RESET;
                   1248:                n = 1;
                   1249:                break;
                   1250:
                   1251:        case SEND_REJECT:
                   1252:                sc->sc_omess[0] = MSG_MESSAGE_REJECT;
                   1253:                n = 1;
                   1254:                break;
                   1255:
                   1256:        case SEND_PARITY_ERROR:
                   1257:                sc->sc_omess[0] = MSG_PARITY_ERROR;
                   1258:                n = 1;
                   1259:                break;
                   1260:
                   1261:        case SEND_INIT_DET_ERR:
                   1262:                sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
                   1263:                n = 1;
                   1264:                break;
                   1265:
                   1266:        case SEND_ABORT:
                   1267:                sc->sc_flags |= SPC_ABORTING;
                   1268:                sc->sc_omess[0] = MSG_ABORT;
                   1269:                n = 1;
                   1270:                break;
                   1271:
                   1272:        default:
                   1273:                printf("%s: unexpected MESSAGE OUT; sending NOOP\n",
                   1274:                    sc->sc_dev.dv_xname);
                   1275:                SPC_BREAK();
                   1276:                sc->sc_omess[0] = MSG_NOOP;
                   1277:                n = 1;
                   1278:                break;
                   1279:        }
                   1280:        sc->sc_omp = &sc->sc_omess[n];
                   1281:
                   1282: nextbyte:
                   1283:        /* Send message bytes. */
                   1284:        /* send TRANSFER command. */
                   1285:        bus_space_write_1(iot, ioh, TCH, n >> 16);
                   1286:        bus_space_write_1(iot, ioh, TCM, n >> 8);
                   1287:        bus_space_write_1(iot, ioh, TCL, n);
                   1288:        bus_space_write_1(iot, ioh, PCTL, sc->sc_phase | PCTL_BFINT_ENAB);
                   1289: #ifdef x68k
                   1290:        bus_space_write_1(iot, ioh, SCMD, SCMD_XFR);    /* XXX */
                   1291: #else
                   1292:        bus_space_write_1(iot, ioh, SCMD,
                   1293:            SCMD_XFR | SCMD_PROG_XFR | SCMD_ICPT_XFR);
                   1294: #endif
                   1295:        for (;;) {
                   1296:                if ((bus_space_read_1(iot, ioh, SSTS) & SSTS_BUSY) != 0)
                   1297:                        break;
                   1298:                if (bus_space_read_1(iot, ioh, INTS) != 0)
                   1299:                        goto out;
                   1300:        }
                   1301:        for (;;) {
                   1302: #if 0
                   1303:                for (;;) {
                   1304:                        if ((bus_space_read_1(iot, ioh, PSNS) & PSNS_REQ) != 0)
                   1305:                                break;
                   1306:                        /* Wait for REQINIT.  XXX Need timeout. */
                   1307:                }
                   1308: #endif
                   1309:                if (bus_space_read_1(iot, ioh, INTS) != 0) {
                   1310:                        /*
                   1311:                         * Target left MESSAGE OUT, possibly to reject
                   1312:                         * our message.
                   1313:                         *
                   1314:                         * If this is the last message being sent, then we
                   1315:                         * deassert ATN, since either the target is going to
                   1316:                         * ignore this message, or it's going to ask for a
                   1317:                         * retransmission via MESSAGE PARITY ERROR (in which
                   1318:                         * case we reassert ATN anyway).
                   1319:                         */
                   1320: #if 0
                   1321:                        if (sc->sc_msgpriq == 0)
                   1322:                                bus_space_write_1(iot, ioh, SCMD, SCMD_RST_ATN);
                   1323: #endif
                   1324:                        goto out;
                   1325:                }
                   1326:
                   1327: #if 0
                   1328:                /* Clear ATN before last byte if this is the last message. */
                   1329:                if (n == 1 && sc->sc_msgpriq == 0)
                   1330:                        bus_space_write_1(iot, ioh, SCMD, SCMD_RST_ATN);
                   1331: #endif
                   1332:
                   1333:                while ((bus_space_read_1(iot, ioh, SSTS) & SSTS_DREG_FULL) != 0)
                   1334:                        ;
                   1335:                /* Send message byte. */
                   1336:                bus_space_write_1(iot, ioh, DREG, *--sc->sc_omp);
                   1337:                --n;
                   1338:                /* Keep track of the last message we've sent any bytes of. */
                   1339:                sc->sc_lastmsg = sc->sc_currmsg;
                   1340: #if 0
                   1341:                /* Wait for ACK to be negated.  XXX Need timeout. */
                   1342:                while ((bus_space_read_1(iot, ioh, PSNS) & ACKI) != 0)
                   1343:                        ;
                   1344: #endif
                   1345:
                   1346:                if (n == 0)
                   1347:                        break;
                   1348:        }
                   1349:
                   1350:        /* We get here only if the entire message has been transmitted. */
                   1351:        if (sc->sc_msgpriq != 0) {
                   1352:                /* There are more outgoing messages. */
                   1353:                goto nextmsg;
                   1354:        }
                   1355:
                   1356:        /*
                   1357:         * The last message has been transmitted.  We need to remember the last
                   1358:         * message transmitted (in case the target switches to MESSAGE IN phase
                   1359:         * and sends a MESSAGE REJECT), and the list of messages transmitted
                   1360:         * this time around (in case the target stays in MESSAGE OUT phase to
                   1361:         * request a retransmit).
                   1362:         */
                   1363:
                   1364: out:
                   1365:        /* Disable REQ/ACK protocol. */
                   1366:        return;
                   1367: }
                   1368:
                   1369: /*
                   1370:  * spc_dataout_pio: perform a data transfer using the FIFO datapath in the spc
                   1371:  * Precondition: The SCSI bus should be in the DOUT phase, with REQ asserted
                   1372:  * and ACK deasserted (i.e. waiting for a data byte).
                   1373:  *
                   1374:  * This new revision has been optimized (I tried) to make the common case fast,
                   1375:  * and the rarer cases (as a result) somewhat more complex.
                   1376:  */
                   1377: int
                   1378: spc_dataout_pio(sc, p, n)
                   1379:        struct spc_softc *sc;
                   1380:        u_char *p;
                   1381:        int n;
                   1382: {
                   1383:        bus_space_tag_t iot = sc->sc_iot;
                   1384:        bus_space_handle_t ioh = sc->sc_ioh;
                   1385:        u_char intstat = 0;
                   1386:        int out = 0;
                   1387: #define DOUTAMOUNT 8           /* Full FIFO */
                   1388:
                   1389:        SPC_TRACE(("spc_dataout_pio  "));
                   1390:        /* send TRANSFER command. */
                   1391:        bus_space_write_1(iot, ioh, TCH, n >> 16);
                   1392:        bus_space_write_1(iot, ioh, TCM, n >> 8);
                   1393:        bus_space_write_1(iot, ioh, TCL, n);
                   1394:        bus_space_write_1(iot, ioh, PCTL, sc->sc_phase | PCTL_BFINT_ENAB);
                   1395: #ifdef x68k
                   1396:        bus_space_write_1(iot, ioh, SCMD, SCMD_XFR);    /* XXX */
                   1397: #else
                   1398:        bus_space_write_1(iot, ioh, SCMD,
                   1399:            SCMD_XFR | SCMD_PROG_XFR | SCMD_ICPT_XFR);  /* XXX */
                   1400: #endif
                   1401:        for (;;) {
                   1402:                if ((bus_space_read_1(iot, ioh, SSTS) & SSTS_BUSY) != 0)
                   1403:                        break;
                   1404:                if (bus_space_read_1(iot, ioh, INTS) != 0)
                   1405:                        break;
                   1406:        }
                   1407:
                   1408:        /*
                   1409:         * I have tried to make the main loop as tight as possible.  This
                   1410:         * means that some of the code following the loop is a bit more
                   1411:         * complex than otherwise.
                   1412:         */
                   1413:        while (n > 0) {
                   1414:                int xfer;
                   1415:
                   1416:                for (;;) {
                   1417:                        intstat = bus_space_read_1(iot, ioh, INTS);
                   1418:                        /* Wait till buffer is empty. */
                   1419:                        if ((bus_space_read_1(iot, ioh, SSTS) &
                   1420:                            SSTS_DREG_EMPTY) != 0)
                   1421:                                break;
                   1422:                        /* Break on interrupt. */
                   1423:                        if (intstat != 0)
                   1424:                                goto phasechange;
                   1425:                }
                   1426:
                   1427:                xfer = min(DOUTAMOUNT, n);
                   1428:
                   1429:                SPC_MISC(("%d> ", xfer));
                   1430:
                   1431:                n -= xfer;
                   1432:                out += xfer;
                   1433:                bus_space_write_multi_1(iot, ioh, DREG, p, xfer);
                   1434:                p += xfer;
                   1435:        }
                   1436:
                   1437:        if (out == 0) {
                   1438:                for (;;) {
                   1439:                        if (bus_space_read_1(iot, ioh, INTS) != 0)
                   1440:                                break;
                   1441:                }
                   1442:                SPC_MISC(("extra data  "));
                   1443:        } else {
                   1444:                /* See the bytes off chip */
                   1445:                for (;;) {
                   1446:                        /* Wait till buffer is empty. */
                   1447:                        if ((bus_space_read_1(iot, ioh, SSTS) &
                   1448:                            SSTS_DREG_EMPTY) != 0)
                   1449:                                break;
                   1450:                        intstat = bus_space_read_1(iot, ioh, INTS);
                   1451:                        /* Break on interrupt. */
                   1452:                        if (intstat != 0)
                   1453:                                goto phasechange;
                   1454:                }
                   1455:        }
                   1456:
                   1457: phasechange:
                   1458:        /* Stop the FIFO data path. */
                   1459:
                   1460:        if (intstat != 0) {
                   1461:                /* Some sort of phase change. */
                   1462:                int amount;
                   1463:
                   1464:                amount = ((bus_space_read_1(iot, ioh, TCH) << 16) |
                   1465:                    (bus_space_read_1(iot, ioh, TCM) << 8) |
                   1466:                    bus_space_read_1(iot, ioh, TCL));
                   1467:                if (amount > 0) {
                   1468:                        out -= amount;
                   1469:                        SPC_MISC(("+%d ", amount));
                   1470:                }
                   1471:        }
                   1472:
                   1473:        return out;
                   1474: }
                   1475:
                   1476: /*
                   1477:  * spc_datain_pio: perform data transfers using the FIFO datapath in the spc
                   1478:  * Precondition: The SCSI bus should be in the DIN phase, with REQ asserted
                   1479:  * and ACK deasserted (i.e. at least one byte is ready).
                   1480:  *
                   1481:  * For now, uses a pretty dumb algorithm, hangs around until all data has been
                   1482:  * transferred.  This, is OK for fast targets, but not so smart for slow
                   1483:  * targets which don't disconnect or for huge transfers.
                   1484:  */
                   1485: int
                   1486: spc_datain_pio(sc, p, n)
                   1487:        struct spc_softc *sc;
                   1488:        u_char *p;
                   1489:        int n;
                   1490: {
                   1491:        bus_space_tag_t iot = sc->sc_iot;
                   1492:        bus_space_handle_t ioh = sc->sc_ioh;
                   1493:        u_int8_t intstat, sstat;
                   1494:        int in = 0;
                   1495: #define DINAMOUNT 8            /* Full FIFO */
                   1496:
                   1497:        SPC_TRACE(("spc_datain_pio  "));
                   1498:        /* send TRANSFER command. */
                   1499:        bus_space_write_1(iot, ioh, TCH, n >> 16);
                   1500:        bus_space_write_1(iot, ioh, TCM, n >> 8);
                   1501:        bus_space_write_1(iot, ioh, TCL, n);
                   1502:        bus_space_write_1(iot, ioh, PCTL, sc->sc_phase | PCTL_BFINT_ENAB);
                   1503: #ifdef x68k
                   1504:        bus_space_write_1(iot, ioh, SCMD, SCMD_XFR);    /* XXX */
                   1505: #else
                   1506:        bus_space_write_1(iot, ioh, SCMD,
                   1507:            SCMD_XFR | SCMD_PROG_XFR);  /* XXX */
                   1508: #endif
                   1509:        for (;;) {
                   1510:                if ((bus_space_read_1(iot, ioh, SSTS) & SSTS_BUSY) != 0)
                   1511:                        break;
                   1512:                if (bus_space_read_1(iot, ioh, INTS) != 0)
                   1513:                        goto phasechange;
                   1514:        }
                   1515:
                   1516:        /*
                   1517:         * We leave this loop if one or more of the following is true:
                   1518:         * a) phase != PH_DATAIN && FIFOs are empty
                   1519:         * b) reset has occurred or busfree is detected.
                   1520:         */
                   1521:        while (n > 0) {
                   1522:                int xfer;
                   1523:
                   1524:                /* Wait for fifo half full or phase mismatch */
                   1525:                for (;;) {
                   1526:                        intstat = bus_space_read_1(iot, ioh, INTS);
                   1527:                        sstat = bus_space_read_1(iot, ioh, SSTS);
                   1528:                        if (intstat != 0 ||
                   1529:                            (sstat & SSTS_DREG_FULL) != 0 ||
                   1530:                            (sstat & SSTS_DREG_EMPTY) == 0)
                   1531:                                break;
                   1532:                }
                   1533:
                   1534: #if 1
                   1535:                if (intstat != 0)
                   1536:                        goto phasechange;
                   1537: #else
                   1538:                if (intstat != 0 &&
                   1539:                    (sstat & SSTS_DREG_EMPTY) != 0)
                   1540:                        goto phasechange;
                   1541: #endif
                   1542:                if ((sstat & SSTS_DREG_FULL) != 0)
                   1543:                        xfer = min(DINAMOUNT, n);
                   1544:                else
                   1545:                        xfer = 1;
                   1546:
                   1547:                SPC_MISC((">%d ", xfer));
                   1548:
                   1549:                n -= xfer;
                   1550:                in += xfer;
                   1551:                bus_space_read_multi_1(iot, ioh, DREG, p, xfer);
                   1552:                p += xfer;
                   1553:
                   1554:                if (intstat != 0)
                   1555:                        goto phasechange;
                   1556:        }
                   1557:
                   1558:        /*
                   1559:         * Some SCSI-devices are rude enough to transfer more data than what
                   1560:         * was requested, e.g. 2048 bytes from a CD-ROM instead of the
                   1561:         * requested 512.  Test for progress, i.e. real transfers.  If no real
                   1562:         * transfers have been performed (n is probably already zero) and the
                   1563:         * FIFO is not empty, waste some bytes....
                   1564:         */
                   1565:        if (in == 0) {
                   1566:                for (;;) {
                   1567:                        /* XXX needs timeout */
                   1568:                        if (bus_space_read_1(iot, ioh, INTS) != 0)
                   1569:                                break;
                   1570:                }
                   1571:                SPC_MISC(("extra data  "));
                   1572:        }
                   1573:
                   1574: phasechange:
                   1575:        /* Stop the FIFO data path. */
                   1576:
                   1577:        return in;
                   1578: }
                   1579:
                   1580: /*
                   1581:  * Catch an interrupt from the adaptor
                   1582:  */
                   1583: /*
                   1584:  * This is the workhorse routine of the driver.
                   1585:  * Deficiencies (for now):
                   1586:  * 1) always uses programmed I/O
                   1587:  */
                   1588: int
                   1589: spc_intr(arg)
                   1590:        void *arg;
                   1591: {
                   1592:        struct spc_softc *sc = arg;
                   1593:        bus_space_tag_t iot = sc->sc_iot;
                   1594:        bus_space_handle_t ioh = sc->sc_ioh;
                   1595:        u_char ints;
                   1596:        struct spc_acb *acb;
                   1597:        struct scsi_link *sc_link;
                   1598:        struct spc_tinfo *ti;
                   1599:        int n;
                   1600:
                   1601:        /*
                   1602:         * Disable interrupt.
                   1603:         */
                   1604:        bus_space_write_1(iot, ioh, SCTL,
                   1605:            bus_space_read_1(iot, ioh, SCTL) & ~SCTL_INTR_ENAB);
                   1606:
                   1607:        SPC_TRACE(("spc_intr  "));
                   1608:
                   1609: loop:
                   1610:        /*
                   1611:         * Loop until transfer completion.
                   1612:         */
                   1613:        /*
                   1614:         * First check for abnormal conditions, such as reset.
                   1615:         */
                   1616: #ifdef x68k                    /* XXX? */
                   1617:        while ((ints = bus_space_read_1(iot, ioh, INTS)) == 0)
                   1618:                delay(1);
                   1619:        SPC_MISC(("ints = 0x%x  ", ints));
                   1620: #else
                   1621:        ints = bus_space_read_1(iot, ioh, INTS);
                   1622:        SPC_MISC(("ints = 0x%x  ", ints));
                   1623: #endif
                   1624:
                   1625:        if ((ints & INTS_RST) != 0) {
                   1626:                printf("%s: SCSI bus reset\n", sc->sc_dev.dv_xname);
                   1627:                goto reset;
                   1628:        }
                   1629:
                   1630:        /*
                   1631:         * Check for less serious errors.
                   1632:         */
                   1633:        if ((bus_space_read_1(iot, ioh, SERR) & (SERR_SCSI_PAR|SERR_SPC_PAR))
                   1634:            != 0) {
                   1635:                printf("%s: SCSI bus parity error\n", sc->sc_dev.dv_xname);
                   1636:                if (sc->sc_prevphase == PH_MSGIN) {
                   1637:                        sc->sc_flags |= SPC_DROP_MSGIN;
                   1638:                        spc_sched_msgout(sc, SEND_PARITY_ERROR);
                   1639:                } else
                   1640:                        spc_sched_msgout(sc, SEND_INIT_DET_ERR);
                   1641:        }
                   1642:
                   1643:        /*
                   1644:         * If we're not already busy doing something test for the following
                   1645:         * conditions:
                   1646:         * 1) We have been reselected by something
                   1647:         * 2) We have selected something successfully
                   1648:         * 3) Our selection process has timed out
                   1649:         * 4) This is really a bus free interrupt just to get a new command
                   1650:         *    going?
                   1651:         * 5) Spurious interrupt?
                   1652:         */
                   1653:        switch (sc->sc_state) {
                   1654:        case SPC_IDLE:
                   1655:        case SPC_SELECTING:
                   1656:                SPC_MISC(("ints:0x%02x ", ints));
                   1657:
                   1658:                if ((ints & INTS_SEL) != 0) {
                   1659:                        /*
                   1660:                         * We don't currently support target mode.
                   1661:                         */
                   1662:                        printf("%s: target mode selected; going to BUS FREE\n",
                   1663:                            sc->sc_dev.dv_xname);
                   1664:
                   1665:                        goto sched;
                   1666:                } else if ((ints & INTS_RESEL) != 0) {
                   1667:                        SPC_MISC(("reselected  "));
                   1668:
                   1669:                        /*
                   1670:                         * If we're trying to select a target ourselves,
                   1671:                         * push our command back into the ready list.
                   1672:                         */
                   1673:                        if (sc->sc_state == SPC_SELECTING) {
                   1674:                                SPC_MISC(("backoff selector  "));
                   1675:                                SPC_ASSERT(sc->sc_nexus != NULL);
                   1676:                                acb = sc->sc_nexus;
                   1677:                                sc->sc_nexus = NULL;
                   1678:                                TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
                   1679:                        }
                   1680:
                   1681:                        /* Save reselection ID. */
                   1682:                        sc->sc_selid = bus_space_read_1(iot, ioh, TEMP);
                   1683:
                   1684:                        sc->sc_state = SPC_RESELECTED;
                   1685:                } else if ((ints & INTS_CMD_DONE) != 0) {
                   1686:                        SPC_MISC(("selected  "));
                   1687:
                   1688:                        /*
                   1689:                         * We have selected a target. Things to do:
                   1690:                         * a) Determine what message(s) to send.
                   1691:                         * b) Verify that we're still selecting the target.
                   1692:                         * c) Mark device as busy.
                   1693:                         */
                   1694:                        if (sc->sc_state != SPC_SELECTING) {
                   1695:                                printf("%s: selection out while idle; "
                   1696:                                    "resetting\n", sc->sc_dev.dv_xname);
                   1697:                                SPC_BREAK();
                   1698:                                goto reset;
                   1699:                        }
                   1700:                        SPC_ASSERT(sc->sc_nexus != NULL);
                   1701:                        acb = sc->sc_nexus;
                   1702:                        sc_link = acb->xs->sc_link;
                   1703:                        ti = &sc->sc_tinfo[sc_link->target];
                   1704:
                   1705:                        sc->sc_msgpriq = SEND_IDENTIFY;
                   1706:                        if (acb->flags & ACB_RESET)
                   1707:                                sc->sc_msgpriq |= SEND_DEV_RESET;
                   1708:                        else if (acb->flags & ACB_ABORT)
                   1709:                                sc->sc_msgpriq |= SEND_ABORT;
                   1710:                        else {
                   1711: #if SPC_USE_SYNCHRONOUS
                   1712:                                if ((ti->flags & DO_SYNC) != 0)
                   1713:                                        sc->sc_msgpriq |= SEND_SDTR;
                   1714: #endif
                   1715: #if SPC_USE_WIDE
                   1716:                                if ((ti->flags & DO_WIDE) != 0)
                   1717:                                        sc->sc_msgpriq |= SEND_WDTR;
                   1718: #endif
                   1719:                        }
                   1720:
                   1721:                        acb->flags |= ACB_NEXUS;
                   1722:                        ti->lubusy |= (1 << sc_link->lun);
                   1723:
                   1724:                        /* Do an implicit RESTORE POINTERS. */
                   1725:                        sc->sc_dp = acb->data_addr;
                   1726:                        sc->sc_dleft = acb->data_length;
                   1727:                        sc->sc_cp = (u_char *)&acb->scsi_cmd;
                   1728:                        sc->sc_cleft = acb->scsi_cmd_length;
                   1729:
                   1730:                        /* On our first connection, schedule a timeout. */
                   1731:                        if ((acb->xs->flags & SCSI_POLL) == 0) {
                   1732:                                timeout_set(&acb->xs->stimeout, spc_timeout,
                   1733:                                    acb);
                   1734:                                timeout_add(&acb->xs->stimeout,
                   1735:                                    (acb->timeout * hz) / 1000);
                   1736:                        }
                   1737:                        sc->sc_state = SPC_CONNECTED;
                   1738:                } else if ((ints & INTS_TIMEOUT) != 0) {
                   1739:                        SPC_MISC(("selection timeout  "));
                   1740:
                   1741:                        if (sc->sc_state != SPC_SELECTING) {
                   1742:                                printf("%s: selection timeout while idle; "
                   1743:                                    "resetting\n", sc->sc_dev.dv_xname);
                   1744:                                SPC_BREAK();
                   1745:                                goto reset;
                   1746:                        }
                   1747:                        SPC_ASSERT(sc->sc_nexus != NULL);
                   1748:                        acb = sc->sc_nexus;
                   1749:
                   1750:                        delay(250);
                   1751:
                   1752:                        acb->xs->error = XS_SELTIMEOUT;
                   1753:                        goto finish;
                   1754:                } else {
                   1755:                        if (sc->sc_state != SPC_IDLE) {
                   1756:                                printf("%s: BUS FREE while not idle; "
                   1757:                                    "state=%d\n",
                   1758:                                    sc->sc_dev.dv_xname, sc->sc_state);
                   1759:                                SPC_BREAK();
                   1760:                                goto out;
                   1761:                        }
                   1762:
                   1763:                        goto sched;
                   1764:                }
                   1765:
                   1766:                /*
                   1767:                 * Turn off selection stuff, and prepare to catch bus free
                   1768:                 * interrupts, parity errors, and phase changes.
                   1769:                 */
                   1770:
                   1771:                sc->sc_flags = 0;
                   1772:                sc->sc_prevphase = PH_INVALID;
                   1773:                goto dophase;
                   1774:        }
                   1775:
                   1776:        if ((ints & INTS_DISCON) != 0) {
                   1777:                /* disable disconnect interrupt */
                   1778:                bus_space_write_1(iot, ioh, PCTL,
                   1779:                    bus_space_read_1(iot, ioh, PCTL) & ~PCTL_BFINT_ENAB);
                   1780:                /* XXX reset interrput */
                   1781:                bus_space_write_1(iot, ioh, INTS, ints);
                   1782:
                   1783:                switch (sc->sc_state) {
                   1784:                case SPC_RESELECTED:
                   1785:                        goto sched;
                   1786:
                   1787:                case SPC_CONNECTED:
                   1788:                        SPC_ASSERT(sc->sc_nexus != NULL);
                   1789:                        acb = sc->sc_nexus;
                   1790:
                   1791: #if SPC_USE_SYNCHRONOUS + SPC_USE_WIDE
                   1792:                        if (sc->sc_prevphase == PH_MSGOUT) {
                   1793:                                /*
                   1794:                                 * If the target went to BUS FREE phase during
                   1795:                                 * or immediately after sending a SDTR or WDTR
                   1796:                                 * message, disable negotiation.
                   1797:                                 */
                   1798:                                sc_link = acb->xs->sc_link;
                   1799:                                ti = &sc->sc_tinfo[sc_link->target];
                   1800:                                switch (sc->sc_lastmsg) {
                   1801: #if SPC_USE_SYNCHRONOUS
                   1802:                                case SEND_SDTR:
                   1803:                                        ti->flags &= ~DO_SYNC;
                   1804:                                        ti->period = ti->offset = 0;
                   1805:                                        break;
                   1806: #endif
                   1807: #if SPC_USE_WIDE
                   1808:                                case SEND_WDTR:
                   1809:                                        ti->flags &= ~DO_WIDE;
                   1810:                                        ti->width = 0;
                   1811:                                        break;
                   1812: #endif
                   1813:                                }
                   1814:                        }
                   1815: #endif
                   1816:
                   1817:                        if ((sc->sc_flags & SPC_ABORTING) == 0) {
                   1818:                                /*
                   1819:                                 * Section 5.1.1 of the SCSI 2 spec suggests
                   1820:                                 * issuing a REQUEST SENSE following an
                   1821:                                 * unexpected disconnect.  Some devices go into
                   1822:                                 * a contingent allegiance condition when
                   1823:                                 * disconnecting, and this is necessary to
                   1824:                                 * clean up their state.
                   1825:                                 */
                   1826:                                printf("%s: unexpected disconnect; "
                   1827:                                    "sending REQUEST SENSE\n",
                   1828:                                    sc->sc_dev.dv_xname);
                   1829:                                SPC_BREAK();
                   1830:                                spc_sense(sc, acb);
                   1831:                                goto out;
                   1832:                        }
                   1833:
                   1834:                        acb->xs->error = XS_DRIVER_STUFFUP;
                   1835:                        goto finish;
                   1836:
                   1837:                case SPC_DISCONNECT:
                   1838:                        SPC_ASSERT(sc->sc_nexus != NULL);
                   1839:                        acb = sc->sc_nexus;
                   1840:                        TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain);
                   1841:                        sc->sc_nexus = NULL;
                   1842:                        goto sched;
                   1843:
                   1844:                case SPC_CMDCOMPLETE:
                   1845:                        SPC_ASSERT(sc->sc_nexus != NULL);
                   1846:                        acb = sc->sc_nexus;
                   1847:                        goto finish;
                   1848:                }
                   1849:        }
                   1850:        else if ((ints & INTS_CMD_DONE) != 0 &&
                   1851:            sc->sc_prevphase == PH_MSGIN && sc->sc_state != SPC_CONNECTED)
                   1852:                goto out;
                   1853:
                   1854: dophase:
                   1855: #if 0
                   1856:        if ((bus_space_read_1(iot, ioh, PSNS) & PSNS_REQ) == 0) {
                   1857:                /* Wait for REQINIT. */
                   1858:                goto out;
                   1859:        }
                   1860: #else
                   1861:        bus_space_write_1(iot, ioh, INTS, ints);
                   1862:        ints = 0;
                   1863:        while ((bus_space_read_1(iot, ioh, PSNS) & PSNS_REQ) == 0)
                   1864:                delay(1);       /* need timeout XXX */
                   1865: #endif
                   1866:
                   1867:        /*
                   1868:         * State transition.
                   1869:         */
                   1870:        sc->sc_phase = bus_space_read_1(iot, ioh, PSNS) & PH_MASK;
                   1871: #if 0
                   1872:        bus_space_write_1(iot, ioh, PCTL, sc->sc_phase);
                   1873: #endif
                   1874:
                   1875:        SPC_MISC(("phase=%d\n", sc->sc_phase));
                   1876:        switch (sc->sc_phase) {
                   1877:        case PH_MSGOUT:
                   1878:                if (sc->sc_state != SPC_CONNECTED &&
                   1879:                    sc->sc_state != SPC_RESELECTED)
                   1880:                        break;
                   1881:                spc_msgout(sc);
                   1882:                sc->sc_prevphase = PH_MSGOUT;
                   1883:                goto loop;
                   1884:
                   1885:        case PH_MSGIN:
                   1886:                if (sc->sc_state != SPC_CONNECTED &&
                   1887:                    sc->sc_state != SPC_RESELECTED)
                   1888:                        break;
                   1889:                spc_msgin(sc);
                   1890:                sc->sc_prevphase = PH_MSGIN;
                   1891:                goto loop;
                   1892:
                   1893:        case PH_CMD:
                   1894:                if (sc->sc_state != SPC_CONNECTED)
                   1895:                        break;
                   1896: #ifdef SPC_DEBUG
                   1897:                if ((spc_debug & SPC_SHOWMISC) != 0) {
                   1898:                        SPC_ASSERT(sc->sc_nexus != NULL);
                   1899:                        acb = sc->sc_nexus;
                   1900:                        printf("cmd=0x%02x+%d  ",
                   1901:                            acb->scsi_cmd.opcode, acb->scsi_cmd_length - 1);
                   1902:                }
                   1903: #endif
                   1904:                n = spc_dataout_pio(sc, sc->sc_cp, sc->sc_cleft);
                   1905:                sc->sc_cp += n;
                   1906:                sc->sc_cleft -= n;
                   1907:                sc->sc_prevphase = PH_CMD;
                   1908:                goto loop;
                   1909:
                   1910:        case PH_DATAOUT:
                   1911:                if (sc->sc_state != SPC_CONNECTED)
                   1912:                        break;
                   1913:                SPC_MISC(("dataout dleft=%d  ", sc->sc_dleft));
                   1914:                n = spc_dataout_pio(sc, sc->sc_dp, sc->sc_dleft);
                   1915:                sc->sc_dp += n;
                   1916:                sc->sc_dleft -= n;
                   1917:                sc->sc_prevphase = PH_DATAOUT;
                   1918:                goto loop;
                   1919:
                   1920:        case PH_DATAIN:
                   1921:                if (sc->sc_state != SPC_CONNECTED)
                   1922:                        break;
                   1923:                SPC_MISC(("datain  "));
                   1924:                n = spc_datain_pio(sc, sc->sc_dp, sc->sc_dleft);
                   1925:                sc->sc_dp += n;
                   1926:                sc->sc_dleft -= n;
                   1927:                sc->sc_prevphase = PH_DATAIN;
                   1928:                goto loop;
                   1929:
                   1930:        case PH_STAT:
                   1931:                if (sc->sc_state != SPC_CONNECTED)
                   1932:                        break;
                   1933:                SPC_ASSERT(sc->sc_nexus != NULL);
                   1934:                acb = sc->sc_nexus;
                   1935:                /*acb->target_stat = bus_space_read_1(iot, ioh, DREG);*/
                   1936:                spc_datain_pio(sc, &acb->target_stat, 1);
                   1937:                SPC_MISC(("target_stat=0x%02x  ", acb->target_stat));
                   1938:                sc->sc_prevphase = PH_STAT;
                   1939:                goto loop;
                   1940:        }
                   1941:
                   1942:        printf("%s: unexpected bus phase; resetting\n", sc->sc_dev.dv_xname);
                   1943:        SPC_BREAK();
                   1944: reset:
                   1945:        spc_init(sc);
                   1946:        return 1;
                   1947:
                   1948: finish:
                   1949:        timeout_del(&acb->xs->stimeout);
                   1950:        bus_space_write_1(iot, ioh, INTS, ints);
                   1951:        ints = 0;
                   1952:        spc_done(sc, acb);
                   1953:        goto out;
                   1954:
                   1955: sched:
                   1956:        sc->sc_state = SPC_IDLE;
                   1957:        spc_sched(sc);
                   1958:        goto out;
                   1959:
                   1960: out:
                   1961:        if (ints)
                   1962:                bus_space_write_1(iot, ioh, INTS, ints);
                   1963:        bus_space_write_1(iot, ioh, SCTL,
                   1964:            bus_space_read_1(iot, ioh, SCTL) | SCTL_INTR_ENAB);
                   1965:        return 1;
                   1966: }
                   1967:
                   1968: void
                   1969: spc_abort(sc, acb)
                   1970:        struct spc_softc *sc;
                   1971:        struct spc_acb *acb;
                   1972: {
                   1973:
                   1974:        /* 2 secs for the abort */
                   1975:        acb->timeout = SPC_ABORT_TIMEOUT;
                   1976:        acb->flags |= ACB_ABORT;
                   1977:
                   1978:        if (acb == sc->sc_nexus) {
                   1979:                /*
                   1980:                 * If we're still selecting, the message will be scheduled
                   1981:                 * after selection is complete.
                   1982:                 */
                   1983:                if (sc->sc_state == SPC_CONNECTED)
                   1984:                        spc_sched_msgout(sc, SEND_ABORT);
                   1985:        } else {
                   1986:                spc_dequeue(sc, acb);
                   1987:                TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
                   1988:                if (sc->sc_state == SPC_IDLE)
                   1989:                        spc_sched(sc);
                   1990:        }
                   1991: }
                   1992:
                   1993: void
                   1994: spc_timeout(arg)
                   1995:        void *arg;
                   1996: {
                   1997:        struct spc_acb *acb = arg;
                   1998:        struct scsi_xfer *xs = acb->xs;
                   1999:        struct scsi_link *sc_link = xs->sc_link;
                   2000:        struct spc_softc *sc = sc_link->adapter_softc;
                   2001:        int s;
                   2002:
                   2003:        sc_print_addr(sc_link);
                   2004:        printf("timed out");
                   2005:
                   2006:        s = splbio();
                   2007:
                   2008:        if (acb->flags & ACB_ABORT) {
                   2009:                /* abort timed out */
                   2010:                printf(" AGAIN\n");
                   2011:                /* XXX Must reset! */
                   2012:        } else {
                   2013:                /* abort the operation that has timed out */
                   2014:                printf("\n");
                   2015:                acb->xs->error = XS_TIMEOUT;
                   2016:                spc_abort(sc, acb);
                   2017:        }
                   2018:
                   2019:        splx(s);
                   2020: }
                   2021:
                   2022: #ifdef SPC_DEBUG
                   2023: /*
                   2024:  * The following functions are mostly used for debugging purposes, either
                   2025:  * directly called from the driver or from the kernel debugger.
                   2026:  */
                   2027:
                   2028: void
                   2029: spc_show_scsi_cmd(acb)
                   2030:        struct spc_acb *acb;
                   2031: {
                   2032:        u_char  *b = (u_char *)&acb->scsi_cmd;
                   2033:        struct scsi_link *sc_link = acb->xs->sc_link;
                   2034:        int i;
                   2035:
                   2036:        sc_print_addr(sc_link);
                   2037:        if ((acb->xs->flags & SCSI_RESET) == 0) {
                   2038:                for (i = 0; i < acb->scsi_cmd_length; i++) {
                   2039:                        if (i)
                   2040:                                printf(",");
                   2041:                        printf("%x", b[i]);
                   2042:                }
                   2043:                printf("\n");
                   2044:        } else
                   2045:                printf("RESET\n");
                   2046: }
                   2047:
                   2048: void
                   2049: spc_print_acb(acb)
                   2050:        struct spc_acb *acb;
                   2051: {
                   2052:
                   2053:        printf("acb@%p xs=%p flags=%x", acb, acb->xs, acb->flags);
                   2054:        printf(" dp=%p dleft=%d target_stat=%x\n",
                   2055:               acb->data_addr, acb->data_length, acb->target_stat);
                   2056:        spc_show_scsi_cmd(acb);
                   2057: }
                   2058:
                   2059: void
                   2060: spc_print_active_acb()
                   2061: {
                   2062:        struct spc_acb *acb;
                   2063:        struct spc_softc *sc = spc_cd.cd_devs[0]; /* XXX */
                   2064:
                   2065:        printf("ready list:\n");
                   2066:        TAILQ_FOREACH(acb, &sc->ready_list, chain)
                   2067:                spc_print_acb(acb);
                   2068:        printf("nexus:\n");
                   2069:        if (sc->sc_nexus != NULL)
                   2070:                spc_print_acb(sc->sc_nexus);
                   2071:        printf("nexus list:\n");
                   2072:        TAILQ_FOREACH(acb, &sc->nexus_list, chain)
                   2073:                spc_print_acb(acb);
                   2074: }
                   2075:
                   2076: void
                   2077: spc_dump89352(sc)
                   2078:        struct spc_softc *sc;
                   2079: {
                   2080:        bus_space_tag_t iot = sc->sc_iot;
                   2081:        bus_space_handle_t ioh = sc->sc_ioh;
                   2082:
                   2083:        printf("mb89352: BDID=%x SCTL=%x SCMD=%x TMOD=%x\n",
                   2084:            bus_space_read_1(iot, ioh, BDID),
                   2085:            bus_space_read_1(iot, ioh, SCTL),
                   2086:            bus_space_read_1(iot, ioh, SCMD),
                   2087:            bus_space_read_1(iot, ioh, TMOD));
                   2088:        printf("         INTS=%x PSNS=%x SSTS=%x SERR=%x PCTL=%x\n",
                   2089:            bus_space_read_1(iot, ioh, INTS),
                   2090:            bus_space_read_1(iot, ioh, PSNS),
                   2091:            bus_space_read_1(iot, ioh, SSTS),
                   2092:            bus_space_read_1(iot, ioh, SERR),
                   2093:            bus_space_read_1(iot, ioh, PCTL));
                   2094:        printf("         MBC=%x DREG=%x TEMP=%x TCH=%x TCM=%x\n",
                   2095:            bus_space_read_1(iot, ioh, MBC),
                   2096: #if 0
                   2097:            bus_space_read_1(iot, ioh, DREG),
                   2098: #else
                   2099:            0,
                   2100: #endif
                   2101:            bus_space_read_1(iot, ioh, TEMP),
                   2102:            bus_space_read_1(iot, ioh, TCH),
                   2103:            bus_space_read_1(iot, ioh, TCM));
                   2104:        printf("         TCL=%x EXBF=%x\n",
                   2105:            bus_space_read_1(iot, ioh, TCL),
                   2106:            bus_space_read_1(iot, ioh, EXBF));
                   2107: }
                   2108:
                   2109: void
                   2110: spc_dump_driver(sc)
                   2111:        struct spc_softc *sc;
                   2112: {
                   2113:        struct spc_tinfo *ti;
                   2114:        int i;
                   2115:
                   2116:        printf("nexus=%p prevphase=%x\n", sc->sc_nexus, sc->sc_prevphase);
                   2117:        printf("state=%x msgin=%x msgpriq=%x msgoutq=%x lastmsg=%x "
                   2118:            "currmsg=%x\n", sc->sc_state, sc->sc_imess[0],
                   2119:            sc->sc_msgpriq, sc->sc_msgoutq, sc->sc_lastmsg, sc->sc_currmsg);
                   2120:        for (i = 0; i < 7; i++) {
                   2121:                ti = &sc->sc_tinfo[i];
                   2122:                printf("tinfo%d: %d cmds %d disconnects %d timeouts",
                   2123:                    i, ti->cmds, ti->dconns, ti->touts);
                   2124:                printf(" %d senses flags=%x\n", ti->senses, ti->flags);
                   2125:        }
                   2126: }
                   2127: #endif

CVSweb