[BACK]Return to aic79xx.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / ic

Annotation of src/sys/dev/ic/aic79xx.c, Revision 1.66

1.66    ! andvar      1: /*     $NetBSD: aic79xx.c,v 1.65 2022/04/07 19:33:37 andvar Exp $      */
1.1       fvdl        2:
                      3: /*
                      4:  * Core routines and tables shareable across OS platforms.
                      5:  *
                      6:  * Copyright (c) 1994-2002 Justin T. Gibbs.
                      7:  * Copyright (c) 2000-2003 Adaptec Inc.
                      8:  * All rights reserved.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions, and the following disclaimer,
                     15:  *    without modification.
                     16:  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
                     17:  *    substantially similar to the "NO WARRANTY" disclaimer below
                     18:  *    ("Disclaimer") and any redistribution must be conditioned upon
                     19:  *    including a substantially similar Disclaimer requirement for further
                     20:  *    binary redistribution.
                     21:  * 3. Neither the names of the above-listed copyright holders nor the names
                     22:  *    of any contributors may be used to endorse or promote products derived
                     23:  *    from this software without specific prior written permission.
                     24:  *
                     25:  * Alternatively, this software may be distributed under the terms of the
                     26:  * GNU General Public License ("GPL") version 2 as published by the Free
                     27:  * Software Foundation.
                     28:  *
                     29:  * NO WARRANTY
                     30:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
                     31:  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
                     32:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
                     33:  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
                     34:  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     35:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     36:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     37:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     38:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
                     39:  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     40:  * POSSIBILITY OF SUCH DAMAGES.
                     41:  *
1.21      thorpej    42:  * Id: //depot/aic7xxx/aic7xxx/aic79xx.c#202 $
1.1       fvdl       43:  *
1.21      thorpej    44:  * $FreeBSD: src/sys/dev/aic7xxx/aic79xx.c,v 1.24 2003/06/28 04:46:54 gibbs Exp $
1.1       fvdl       45:  */
                     46: /*
                     47:  * Ported from FreeBSD by Pascal Renauld, Network Storage Solutions, Inc.
                     48:  * - April 2003
                     49:  */
1.6       lukem      50:
                     51: #include <sys/cdefs.h>
1.66    ! andvar     52: __KERNEL_RCSID(0, "$NetBSD: aic79xx.c,v 1.65 2022/04/07 19:33:37 andvar Exp $");
1.1       fvdl       53:
                     54: #include <dev/ic/aic79xx_osm.h>
                     55: #include <dev/ic/aic79xx_inline.h>
                     56: #include <dev/ic/aic7xxx_cam.h>
                     57:
                     58: #include <dev/microcode/aic7xxx/aicasm.h>
                     59: #include <dev/microcode/aic7xxx/aicasm_insformat.h>
                     60:
                     61:
                     62: /******************************** Globals *************************************/
                     63: struct ahd_softc_tailq ahd_tailq = TAILQ_HEAD_INITIALIZER(ahd_tailq);
                     64:
                     65: /***************************** Lookup Tables **********************************/
1.55      jdolecek   66: const char * const ahd_chip_names[] =
1.1       fvdl       67: {
                     68:        "NONE",
                     69:        "aic7901",
                     70:        "aic7902",
                     71:        "aic7901A"
                     72: };
                     73:
                     74: /*
                     75:  * Hardware error codes.
                     76:  */
                     77: struct ahd_hard_error_entry {
1.43      tsutsui    78:        uint8_t errno;
1.31      christos   79:        const char *errmesg;
1.1       fvdl       80: };
                     81:
                     82: static struct ahd_hard_error_entry ahd_hard_errors[] = {
                     83:        { DSCTMOUT,     "Discard Timer has timed out" },
                     84:        { ILLOPCODE,    "Illegal Opcode in sequencer program" },
                     85:        { SQPARERR,     "Sequencer Parity Error" },
                     86:        { DPARERR,      "Data-path Parity Error" },
                     87:        { MPARERR,      "Scratch or SCB Memory Parity Error" },
                     88:        { CIOPARERR,    "CIOBUS Parity Error" },
                     89: };
                     90: static const u_int num_errors = NUM_ELEMENTS(ahd_hard_errors);
                     91:
                     92: static struct ahd_phase_table_entry ahd_phase_table[] =
                     93: {
                     94:        { P_DATAOUT,    MSG_NOOP,               "in Data-out phase"     },
                     95:        { P_DATAIN,     MSG_INITIATOR_DET_ERR,  "in Data-in phase"      },
                     96:        { P_DATAOUT_DT, MSG_NOOP,               "in DT Data-out phase"  },
                     97:        { P_DATAIN_DT,  MSG_INITIATOR_DET_ERR,  "in DT Data-in phase"   },
                     98:        { P_COMMAND,    MSG_NOOP,               "in Command phase"      },
                     99:        { P_MESGOUT,    MSG_NOOP,               "in Message-out phase"  },
                    100:        { P_STATUS,     MSG_INITIATOR_DET_ERR,  "in Status phase"       },
                    101:        { P_MESGIN,     MSG_PARITY_ERROR,       "in Message-in phase"   },
                    102:        { P_BUSFREE,    MSG_NOOP,               "while idle"            },
                    103:        { 0,            MSG_NOOP,               "in unknown phase"      }
                    104: };
                    105:
                    106: /*
                    107:  * In most cases we only wish to itterate over real phases, so
                    108:  * exclude the last element from the count.
                    109:  */
                    110: static const u_int num_phases = NUM_ELEMENTS(ahd_phase_table) - 1;
                    111:
                    112: /* Our Sequencer Program */
                    113: #include <dev/microcode/aic7xxx/aic79xx_seq.h>
                    114:
                    115: /**************************** Function Declarations ***************************/
                    116: static void            ahd_handle_transmission_error(struct ahd_softc *ahd);
                    117: static void            ahd_handle_lqiphase_error(struct ahd_softc *ahd,
                    118:                                                  u_int lqistat1);
                    119: static int             ahd_handle_pkt_busfree(struct ahd_softc *ahd,
                    120:                                               u_int busfreetime);
                    121: static int             ahd_handle_nonpkt_busfree(struct ahd_softc *ahd);
                    122: static void            ahd_handle_proto_violation(struct ahd_softc *ahd);
                    123: static void            ahd_force_renegotiation(struct ahd_softc *ahd,
                    124:                                                struct ahd_devinfo *devinfo);
                    125:
                    126: static struct ahd_tmode_tstate*
                    127:                        ahd_alloc_tstate(struct ahd_softc *ahd,
                    128:                                         u_int scsi_id, char channel);
                    129: #ifdef AHD_TARGET_MODE
                    130: static void            ahd_free_tstate(struct ahd_softc *ahd,
                    131:                                        u_int scsi_id, char channel, int force);
                    132: #endif
                    133: static void            ahd_devlimited_syncrate(struct ahd_softc *ahd,
                    134:                                                struct ahd_initiator_tinfo *,
                    135:                                                u_int *period,
                    136:                                                u_int *ppr_options,
                    137:                                                role_t role);
                    138: static void            ahd_update_neg_table(struct ahd_softc *ahd,
                    139:                                             struct ahd_devinfo *devinfo,
                    140:                                             struct ahd_transinfo *tinfo);
                    141: static void            ahd_update_pending_scbs(struct ahd_softc *ahd);
                    142: static void            ahd_fetch_devinfo(struct ahd_softc *ahd,
                    143:                                          struct ahd_devinfo *devinfo);
                    144: static void            ahd_scb_devinfo(struct ahd_softc *ahd,
                    145:                                        struct ahd_devinfo *devinfo,
                    146:                                        struct scb *scb);
                    147: static void            ahd_setup_initiator_msgout(struct ahd_softc *ahd,
                    148:                                                   struct ahd_devinfo *devinfo,
                    149:                                                   struct scb *scb);
                    150: static void            ahd_build_transfer_msg(struct ahd_softc *ahd,
                    151:                                               struct ahd_devinfo *devinfo);
                    152: static void            ahd_construct_sdtr(struct ahd_softc *ahd,
                    153:                                           struct ahd_devinfo *devinfo,
                    154:                                           u_int period, u_int offset);
                    155: static void            ahd_construct_wdtr(struct ahd_softc *ahd,
                    156:                                           struct ahd_devinfo *devinfo,
                    157:                                           u_int bus_width);
                    158: static void            ahd_construct_ppr(struct ahd_softc *ahd,
                    159:                                          struct ahd_devinfo *devinfo,
                    160:                                          u_int period, u_int offset,
                    161:                                          u_int bus_width, u_int ppr_options);
                    162: static void            ahd_clear_msg_state(struct ahd_softc *ahd);
                    163: static void            ahd_handle_message_phase(struct ahd_softc *ahd);
                    164: typedef enum {
                    165:        AHDMSG_1B,
                    166:        AHDMSG_2B,
                    167:        AHDMSG_EXT
                    168: } ahd_msgtype;
                    169: static int             ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type,
                    170:                                     u_int msgval, int full);
                    171: static int             ahd_parse_msg(struct ahd_softc *ahd,
                    172:                                      struct ahd_devinfo *devinfo);
                    173: static int             ahd_handle_msg_reject(struct ahd_softc *ahd,
                    174:                                              struct ahd_devinfo *devinfo);
                    175: static void            ahd_handle_ign_wide_residue(struct ahd_softc *ahd,
                    176:                                                struct ahd_devinfo *devinfo);
                    177: static void            ahd_reinitialize_dataptrs(struct ahd_softc *ahd);
                    178: static void            ahd_handle_devreset(struct ahd_softc *ahd,
                    179:                                            struct ahd_devinfo *devinfo,
                    180:                                            u_int lun, cam_status status,
1.31      christos  181:                                            const char *message,
                    182:                                            int verbose_level);
1.1       fvdl      183: #if AHD_TARGET_MODE
                    184: static void            ahd_setup_target_msgin(struct ahd_softc *ahd,
                    185:                                               struct ahd_devinfo *devinfo,
                    186:                                               struct scb *scb);
                    187: #endif
                    188:
                    189: static u_int           ahd_sglist_size(struct ahd_softc *ahd);
                    190: static u_int           ahd_sglist_allocsize(struct ahd_softc *ahd);
                    191: static void            ahd_initialize_hscbs(struct ahd_softc *ahd);
                    192: static int             ahd_init_scbdata(struct ahd_softc *ahd);
                    193: static void            ahd_fini_scbdata(struct ahd_softc *ahd);
                    194: static void            ahd_setup_iocell_workaround(struct ahd_softc *ahd);
                    195: static void            ahd_iocell_first_selection(struct ahd_softc *ahd);
                    196: static void            ahd_add_col_list(struct ahd_softc *ahd,
                    197:                                         struct scb *scb, u_int col_idx);
                    198: static void            ahd_rem_col_list(struct ahd_softc *ahd,
                    199:                                         struct scb *scb);
                    200: static void            ahd_chip_init(struct ahd_softc *ahd);
                    201: static void            ahd_qinfifo_requeue(struct ahd_softc *ahd,
                    202:                                            struct scb *prev_scb,
                    203:                                            struct scb *scb);
                    204: static int             ahd_qinfifo_count(struct ahd_softc *ahd);
                    205: static int             ahd_search_scb_list(struct ahd_softc *ahd, int target,
                    206:                                            char channel, int lun, u_int tag,
                    207:                                            role_t role, uint32_t status,
                    208:                                            ahd_search_action action,
                    209:                                            u_int *list_head, u_int tid);
                    210: static void            ahd_stitch_tid_list(struct ahd_softc *ahd,
                    211:                                            u_int tid_prev, u_int tid_cur,
                    212:                                            u_int tid_next);
                    213: static void            ahd_add_scb_to_free_list(struct ahd_softc *ahd,
                    214:                                                 u_int scbid);
                    215: static u_int           ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid,
                    216:                                     u_int prev, u_int next, u_int tid);
                    217: static void            ahd_reset_current_bus(struct ahd_softc *ahd);
                    218: static ahd_callback_t  ahd_reset_poll;
                    219: static ahd_callback_t  ahd_stat_timer;
                    220: #ifdef AHD_DUMP_SEQ
                    221: static void            ahd_dumpseq(struct ahd_softc *ahd);
                    222: #endif
                    223: static void            ahd_loadseq(struct ahd_softc *ahd);
                    224: static int             ahd_check_patch(struct ahd_softc *ahd,
1.56      jdolecek  225:                                        const struct patch **start_patch,
1.1       fvdl      226:                                        u_int start_instr, u_int *skip_addr);
                    227: static u_int           ahd_resolve_seqaddr(struct ahd_softc *ahd,
                    228:                                            u_int address);
                    229: static void            ahd_download_instr(struct ahd_softc *ahd,
                    230:                                           u_int instrptr, uint8_t *dconsts);
                    231: static int             ahd_probe_stack_size(struct ahd_softc *ahd);
1.21      thorpej   232: static int             ahd_scb_active_in_fifo(struct ahd_softc *ahd,
                    233:                                               struct scb *scb);
                    234: static void            ahd_run_data_fifo(struct ahd_softc *ahd,
                    235:                                          struct scb *scb);
                    236:
1.1       fvdl      237: #ifdef AHD_TARGET_MODE
                    238: static void            ahd_queue_lstate_event(struct ahd_softc *ahd,
                    239:                                               struct ahd_tmode_lstate *lstate,
                    240:                                               u_int initiator_id,
                    241:                                               u_int event_type,
                    242:                                               u_int event_arg);
                    243: static void            ahd_update_scsiid(struct ahd_softc *ahd,
                    244:                                          u_int targid_mask);
                    245: static int             ahd_handle_target_cmd(struct ahd_softc *ahd,
                    246:                                              struct target_cmd *cmd);
                    247: #endif
                    248:
                    249: /************************** Added for porting to NetBSD ***********************/
                    250: static int ahd_createdmamem(bus_dma_tag_t tag,
                    251:                            int size,
                    252:                            int flags,
                    253:                            bus_dmamap_t *mapp,
1.37      christos  254:                            void **vaddr,
1.1       fvdl      255:                            bus_addr_t *baddr,
                    256:                            bus_dma_segment_t *seg,
                    257:                            int *nseg,
                    258:                            const char *myname, const char *what);
                    259:
                    260: static void ahd_freedmamem(bus_dma_tag_t tag,
                    261:                           int size,
                    262:                           bus_dmamap_t map,
1.37      christos  263:                           void *vaddr,
1.1       fvdl      264:                           bus_dma_segment_t *seg,
                    265:                           int nseg);
                    266:
                    267: /******************************** Private Inlines *****************************/
1.33      perry     268: static inline void     ahd_assert_atn(struct ahd_softc *ahd);
                    269: static inline int      ahd_currently_packetized(struct ahd_softc *ahd);
                    270: static inline int      ahd_set_active_fifo(struct ahd_softc *ahd);
1.1       fvdl      271:
1.33      perry     272: static inline void
1.1       fvdl      273: ahd_assert_atn(struct ahd_softc *ahd)
                    274: {
                    275:        ahd_outb(ahd, SCSISIGO, ATNO);
                    276: }
                    277:
                    278: /*
                    279:  * Determine if the current connection has a packetized
                    280:  * agreement.  This does not necessarily mean that we
                    281:  * are currently in a packetized transfer.  We could
                    282:  * just as easily be sending or receiving a message.
                    283:  */
1.33      perry     284: static inline int
1.1       fvdl      285: ahd_currently_packetized(struct ahd_softc *ahd)
                    286: {
                    287:        ahd_mode_state   saved_modes;
                    288:        int              packetized;
                    289:
                    290:        saved_modes = ahd_save_modes(ahd);
                    291:        if ((ahd->bugs & AHD_PKTIZED_STATUS_BUG) != 0) {
                    292:                /*
                    293:                 * The packetized bit refers to the last
                    294:                 * connection, not the current one.  Check
                    295:                 * for non-zero LQISTATE instead.
                    296:                 */
                    297:                ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                    298:                packetized = ahd_inb(ahd, LQISTATE) != 0;
                    299:        } else {
                    300:                ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                    301:                packetized = ahd_inb(ahd, LQISTAT2) & PACKETIZED;
                    302:        }
                    303:        ahd_restore_modes(ahd, saved_modes);
                    304:        return (packetized);
                    305: }
                    306:
1.33      perry     307: static inline int
1.1       fvdl      308: ahd_set_active_fifo(struct ahd_softc *ahd)
                    309: {
                    310:        u_int active_fifo;
                    311:
                    312:        AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                    313:        active_fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO;
                    314:        switch (active_fifo) {
                    315:        case 0:
                    316:        case 1:
                    317:                ahd_set_modes(ahd, active_fifo, active_fifo);
                    318:                return (1);
                    319:        default:
                    320:                return (0);
                    321:        }
                    322: }
                    323:
                    324: /************************* Sequencer Execution Control ************************/
                    325: /*
                    326:  * Restart the sequencer program from address zero
                    327:  */
                    328: void
                    329: ahd_restart(struct ahd_softc *ahd)
                    330: {
1.30      perry     331:
1.1       fvdl      332:        ahd_pause(ahd);
                    333:
                    334:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                    335:
                    336:        /* No more pending messages */
                    337:        ahd_clear_msg_state(ahd);
                    338:        ahd_outb(ahd, SCSISIGO, 0);             /* De-assert BSY */
                    339:        ahd_outb(ahd, MSG_OUT, MSG_NOOP);       /* No message to send */
                    340:        ahd_outb(ahd, SXFRCTL1, ahd_inb(ahd, SXFRCTL1) & ~BITBUCKET);
                    341:        ahd_outb(ahd, SEQINTCTL, 0);
                    342:        ahd_outb(ahd, LASTPHASE, P_BUSFREE);
                    343:        ahd_outb(ahd, SEQ_FLAGS, 0);
                    344:        ahd_outb(ahd, SAVED_SCSIID, 0xFF);
                    345:        ahd_outb(ahd, SAVED_LUN, 0xFF);
                    346:
                    347:        /*
                    348:         * Ensure that the sequencer's idea of TQINPOS
                    349:         * matches our own.  The sequencer increments TQINPOS
                    350:         * only after it sees a DMA complete and a reset could
                    351:         * occur before the increment leaving the kernel to believe
                    352:         * the command arrived but the sequencer to not.
                    353:         */
                    354:        ahd_outb(ahd, TQINPOS, ahd->tqinfifonext);
                    355:
                    356:        /* Always allow reselection */
                    357:        ahd_outb(ahd, SCSISEQ1,
                    358:                 ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
                    359:        ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
                    360:        ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
                    361:        ahd_unpause(ahd);
                    362: }
                    363:
                    364: void
                    365: ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo)
                    366: {
                    367:        ahd_mode_state   saved_modes;
                    368:
                    369: #ifdef AHD_DEBUG
                    370:        if ((ahd_debug & AHD_SHOW_FIFOS) != 0)
                    371:                printf("%s: Clearing FIFO %d\n", ahd_name(ahd), fifo);
                    372: #endif
                    373:        saved_modes = ahd_save_modes(ahd);
                    374:        ahd_set_modes(ahd, fifo, fifo);
                    375:        ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT);
                    376:        if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)
                    377:                ahd_outb(ahd, CCSGCTL, CCSGRESET);
                    378:        ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
                    379:        ahd_outb(ahd, SG_STATE, 0);
                    380:        ahd_restore_modes(ahd, saved_modes);
                    381: }
                    382:
                    383: /************************* Input/Output Queues ********************************/
                    384: /*
                    385:  * Flush and completed commands that are sitting in the command
1.4       wiz       386:  * complete queues down on the chip but have yet to be DMA'ed back up.
1.1       fvdl      387:  */
                    388: void
                    389: ahd_flush_qoutfifo(struct ahd_softc *ahd)
                    390: {
                    391:        struct          scb *scb;
                    392:        ahd_mode_state  saved_modes;
                    393:        u_int           saved_scbptr;
                    394:        u_int           ccscbctl;
                    395:        u_int           scbid;
                    396:        u_int           next_scbid;
                    397:
                    398:        saved_modes = ahd_save_modes(ahd);
1.21      thorpej   399:
                    400:        /*
                    401:         * Complete any SCBs that just finished being
                    402:         * DMA'ed into the qoutfifo.
                    403:         */
                    404:        ahd_run_qoutfifo(ahd);
                    405:
                    406:        /*
1.64      andvar    407:         * Flush the good status FIFO for completed packetized commands.
1.21      thorpej   408:         */
                    409:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                    410:        saved_scbptr = ahd_get_scbptr(ahd);
                    411:        while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) {
                    412:                u_int fifo_mode;
                    413:                u_int i;
                    414:
                    415:                scbid = (ahd_inb(ahd, GSFIFO+1) << 8)
                    416:                      | ahd_inb(ahd, GSFIFO);
                    417:                scb = ahd_lookup_scb(ahd, scbid);
                    418:                if (scb == NULL) {
                    419:                        printf("%s: Warning - GSFIFO SCB %d invalid\n",
                    420:                               ahd_name(ahd), scbid);
                    421:                        continue;
                    422:                }
                    423:                /*
                    424:                 * Determine if this transaction is still active in
                    425:                 * any FIFO.  If it is, we must flush that FIFO to
                    426:                 * the host before completing the  command.
                    427:                 */
                    428:                fifo_mode = 0;
                    429:                for (i = 0; i < 2; i++) {
                    430:                        /* Toggle to the other mode. */
                    431:                        fifo_mode ^= 1;
                    432:                        ahd_set_modes(ahd, fifo_mode, fifo_mode);
                    433:                        if (ahd_scb_active_in_fifo(ahd, scb) == 0)
                    434:                                continue;
                    435:
                    436:                        ahd_run_data_fifo(ahd, scb);
                    437:
                    438:                        /*
                    439:                         * Clearing this transaction in this FIFO may
                    440:                         * cause a CFG4DATA for this same transaction
                    441:                         * to assert in the other FIFO.  Make sure we
                    442:                         * loop one more time and check the other FIFO.
                    443:                         */
                    444:                        i = 0;
                    445:                }
                    446:                ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                    447:                ahd_set_scbptr(ahd, scbid);
                    448:                if ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_LIST_NULL) == 0
                    449:                 && ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_FULL_RESID) != 0
                    450:                  || (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR)
                    451:                      & SG_LIST_NULL) != 0)) {
                    452:                        u_int comp_head;
                    453:
                    454:                        /*
                    455:                         * The transfer completed with a residual.
                    456:                         * Place this SCB on the complete DMA list
                    457:                         * so that we Update our in-core copy of the
                    458:                         * SCB before completing the command.
                    459:                         */
                    460:                        ahd_outb(ahd, SCB_SCSI_STATUS, 0);
                    461:                        ahd_outb(ahd, SCB_SGPTR,
                    462:                                 ahd_inb_scbram(ahd, SCB_SGPTR)
                    463:                                 | SG_STATUS_VALID);
                    464:                        ahd_outw(ahd, SCB_TAG, SCB_GET_TAG(scb));
                    465:                        comp_head = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
                    466:                        ahd_outw(ahd, SCB_NEXT_COMPLETE, comp_head);
                    467:                        if (SCBID_IS_NULL(comp_head))
                    468:                                ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD,
                    469:                                         SCB_GET_TAG(scb));
                    470:                } else
                    471:                        ahd_complete_scb(ahd, scb);
                    472:        }
                    473:        ahd_set_scbptr(ahd, saved_scbptr);
                    474:
                    475:        /*
                    476:         * Setup for command channel portion of flush.
                    477:         */
1.1       fvdl      478:        ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
                    479:
                    480:        /*
                    481:         * Wait for any inprogress DMA to complete and clear DMA state
                    482:         * if this if for an SCB in the qinfifo.
                    483:         */
1.18      thorpej   484:        while (((ccscbctl = ahd_inb(ahd, CCSCBCTL)) & (CCARREN|CCSCBEN)) != 0) {
1.1       fvdl      485:
                    486:                if ((ccscbctl & (CCSCBDIR|CCARREN)) == (CCSCBDIR|CCARREN)) {
                    487:                        if ((ccscbctl & ARRDONE) != 0)
                    488:                                break;
                    489:                } else if ((ccscbctl & CCSCBDONE) != 0)
                    490:                        break;
                    491:                ahd_delay(200);
                    492:        }
                    493:        if ((ccscbctl & CCSCBDIR) != 0)
                    494:                ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN));
                    495:
1.21      thorpej   496:        saved_scbptr = ahd_get_scbptr(ahd);
1.1       fvdl      497:        /*
                    498:         * Manually update/complete any completed SCBs that are waiting to be
                    499:         * DMA'ed back up to the host.
                    500:         */
                    501:        scbid = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
                    502:        while (!SCBID_IS_NULL(scbid)) {
                    503:                uint8_t *hscb_ptr;
                    504:                u_int    i;
1.30      perry     505:
1.1       fvdl      506:                ahd_set_scbptr(ahd, scbid);
                    507:                next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
                    508:                scb = ahd_lookup_scb(ahd, scbid);
                    509:                if (scb == NULL) {
                    510:                        printf("%s: Warning - DMA-up and complete "
                    511:                               "SCB %d invalid\n", ahd_name(ahd), scbid);
                    512:                        continue;
                    513:                }
                    514:                hscb_ptr = (uint8_t *)scb->hscb;
                    515:                for (i = 0; i < sizeof(struct hardware_scb); i++)
                    516:                        *hscb_ptr++ = ahd_inb_scbram(ahd, SCB_BASE + i);
                    517:
                    518:                ahd_complete_scb(ahd, scb);
                    519:                scbid = next_scbid;
                    520:        }
                    521:        ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL);
                    522:
                    523:        scbid = ahd_inw(ahd, COMPLETE_SCB_HEAD);
                    524:        while (!SCBID_IS_NULL(scbid)) {
                    525:
                    526:                ahd_set_scbptr(ahd, scbid);
                    527:                next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
                    528:                scb = ahd_lookup_scb(ahd, scbid);
                    529:                if (scb == NULL) {
                    530:                        printf("%s: Warning - Complete SCB %d invalid\n",
                    531:                               ahd_name(ahd), scbid);
                    532:                        continue;
                    533:                }
                    534:
                    535:                ahd_complete_scb(ahd, scb);
                    536:                scbid = next_scbid;
                    537:        }
                    538:        ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
1.21      thorpej   539:
                    540:        /*
                    541:         * Restore state.
                    542:         */
1.1       fvdl      543:        ahd_set_scbptr(ahd, saved_scbptr);
1.21      thorpej   544:        ahd_restore_modes(ahd, saved_modes);
                    545:        ahd->flags |= AHD_UPDATE_PEND_CMDS;
                    546: }
                    547:
                    548: /*
                    549:  * Determine if an SCB for a packetized transaction
                    550:  * is active in a FIFO.
                    551:  */
                    552: static int
                    553: ahd_scb_active_in_fifo(struct ahd_softc *ahd, struct scb *scb)
                    554: {
1.1       fvdl      555:
                    556:        /*
1.21      thorpej   557:         * The FIFO is only active for our transaction if
                    558:         * the SCBPTR matches the SCB's ID and the firmware
                    559:         * has installed a handler for the FIFO or we have
                    560:         * a pending SAVEPTRS or CFG4DATA interrupt.
1.1       fvdl      561:         */
1.21      thorpej   562:        if (ahd_get_scbptr(ahd) != SCB_GET_TAG(scb)
                    563:         || ((ahd_inb(ahd, LONGJMP_ADDR+1) & INVALID_ADDR) != 0
                    564:          && (ahd_inb(ahd, SEQINTSRC) & (CFG4DATA|SAVEPTRS)) == 0))
                    565:                return (0);
                    566:
                    567:        return (1);
                    568: }
                    569:
                    570: /*
                    571:  * Run a data fifo to completion for a transaction we know
                    572:  * has completed across the SCSI bus (good status has been
                    573:  * received).  We are already set to the correct FIFO mode
                    574:  * on entry to this routine.
                    575:  *
                    576:  * This function attempts to operate exactly as the firmware
                    577:  * would when running this FIFO.  Care must be taken to update
                    578:  * this routine any time the firmware's FIFO algorithm is
                    579:  * changed.
                    580:  */
                    581: static void
                    582: ahd_run_data_fifo(struct ahd_softc *ahd, struct scb *scb)
                    583: {
                    584:        u_int seqintsrc;
                    585:
                    586:        while (1) {
                    587:                seqintsrc = ahd_inb(ahd, SEQINTSRC);
                    588:                if ((seqintsrc & CFG4DATA) != 0) {
                    589:                        uint32_t datacnt;
                    590:                        uint32_t sgptr;
                    591:
                    592:                        /*
                    593:                         * Clear full residual flag.
                    594:                         */
                    595:                        sgptr = ahd_inl_scbram(ahd, SCB_SGPTR) & ~SG_FULL_RESID;
                    596:                        ahd_outb(ahd, SCB_SGPTR, sgptr);
                    597:
                    598:                        /*
                    599:                         * Load datacnt and address.
                    600:                         */
                    601:                        datacnt = ahd_inl_scbram(ahd, SCB_DATACNT);
                    602:                        if ((datacnt & AHD_DMA_LAST_SEG) != 0) {
                    603:                                sgptr |= LAST_SEG;
                    604:                                ahd_outb(ahd, SG_STATE, 0);
                    605:                        } else
                    606:                                ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
                    607:                        ahd_outq(ahd, HADDR, ahd_inq_scbram(ahd, SCB_DATAPTR));
                    608:                        ahd_outl(ahd, HCNT, datacnt & AHD_SG_LEN_MASK);
                    609:                        ahd_outb(ahd, SG_CACHE_PRE, sgptr);
                    610:                        ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);
                    611:
                    612:                        /*
                    613:                         * Initialize Residual Fields.
                    614:                         */
                    615:                        ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, datacnt >> 24);
                    616:                        ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr & SG_PTR_MASK);
                    617:
                    618:                        /*
                    619:                         * Mark the SCB as having a FIFO in use.
                    620:                         */
                    621:                        ahd_outb(ahd, SCB_FIFO_USE_COUNT,
                    622:                                 ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) + 1);
1.30      perry     623:
1.21      thorpej   624:                        /*
                    625:                         * Install a "fake" handler for this FIFO.
                    626:                         */
                    627:                        ahd_outw(ahd, LONGJMP_ADDR, 0);
                    628:
                    629:                        /*
                    630:                         * Notify the hardware that we have satisfied
                    631:                         * this sequencer interrupt.
                    632:                         */
                    633:                        ahd_outb(ahd, CLRSEQINTSRC, CLRCFG4DATA);
                    634:                } else if ((seqintsrc & SAVEPTRS) != 0) {
                    635:                        uint32_t sgptr;
                    636:                        uint32_t resid;
                    637:
                    638:                        if ((ahd_inb(ahd, LONGJMP_ADDR+1)&INVALID_ADDR) != 0) {
                    639:                                /*
                    640:                                 * Snapshot Save Pointers.  Clear
                    641:                                 * the snapshot and continue.
                    642:                                 */
                    643:                                ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
                    644:                                continue;
                    645:                        }
                    646:
                    647:                        /*
                    648:                         * Disable S/G fetch so the DMA engine
                    649:                         * is available to future users.
                    650:                         */
                    651:                        if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)
                    652:                                ahd_outb(ahd, CCSGCTL, 0);
                    653:                        ahd_outb(ahd, SG_STATE, 0);
                    654:
                    655:                        /*
1.66    ! andvar    656:                         * Flush the data FIFO.  Strictly only
1.21      thorpej   657:                         * necessary for Rev A parts.
                    658:                         */
                    659:                        ahd_outb(ahd, DFCNTRL,
                    660:                                 ahd_inb(ahd, DFCNTRL) | FIFOFLUSH);
                    661:
                    662:                        /*
                    663:                         * Calculate residual.
                    664:                         */
                    665:                        sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
                    666:                        resid = ahd_inl(ahd, SHCNT);
                    667:                        resid |=
                    668:                            ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24;
                    669:                        ahd_outl(ahd, SCB_RESIDUAL_DATACNT, resid);
                    670:                        if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG) == 0) {
                    671:                                /*
                    672:                                 * Must back up to the correct S/G element.
                    673:                                 * Typically this just means resetting our
                    674:                                 * low byte to the offset in the SG_CACHE,
                    675:                                 * but if we wrapped, we have to correct
                    676:                                 * the other bytes of the sgptr too.
                    677:                                 */
                    678:                                if ((ahd_inb(ahd, SG_CACHE_SHADOW) & 0x80) != 0
                    679:                                 && (sgptr & 0x80) == 0)
                    680:                                        sgptr -= 0x100;
                    681:                                sgptr &= ~0xFF;
                    682:                                sgptr |= ahd_inb(ahd, SG_CACHE_SHADOW)
                    683:                                       & SG_ADDR_MASK;
                    684:                                ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
                    685:                                ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, 0);
                    686:                        } else if ((resid & AHD_SG_LEN_MASK) == 0) {
                    687:                                ahd_outb(ahd, SCB_RESIDUAL_SGPTR,
                    688:                                         sgptr | SG_LIST_NULL);
                    689:                        }
                    690:                        /*
                    691:                         * Save Pointers.
                    692:                         */
                    693:                        ahd_outq(ahd, SCB_DATAPTR, ahd_inq(ahd, SHADDR));
                    694:                        ahd_outl(ahd, SCB_DATACNT, resid);
                    695:                        ahd_outl(ahd, SCB_SGPTR, sgptr);
                    696:                        ahd_outb(ahd, CLRSEQINTSRC, CLRSAVEPTRS);
                    697:                        ahd_outb(ahd, SEQIMODE,
                    698:                                 ahd_inb(ahd, SEQIMODE) | ENSAVEPTRS);
                    699:                        /*
                    700:                         * If the data is to the SCSI bus, we are
                    701:                         * done, otherwise wait for FIFOEMP.
                    702:                         */
                    703:                        if ((ahd_inb(ahd, DFCNTRL) & DIRECTION) != 0)
                    704:                                break;
                    705:                } else if ((ahd_inb(ahd, SG_STATE) & LOADING_NEEDED) != 0) {
                    706:                        uint32_t sgptr;
                    707:                        uint64_t data_addr;
                    708:                        uint32_t data_len;
                    709:                        u_int    dfcntrl;
                    710:
                    711:                        /*
                    712:                         * Disable S/G fetch so the DMA engine
                    713:                         * is available to future users.
                    714:                         */
                    715:                        if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) {
                    716:                                ahd_outb(ahd, CCSGCTL, 0);
                    717:                                ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
                    718:                        }
                    719:
                    720:                        /*
                    721:                         * Wait for the DMA engine to notice that the
                    722:                         * host transfer is enabled and that there is
                    723:                         * space in the S/G FIFO for new segments before
                    724:                         * loading more segments.
                    725:                         */
                    726:                        if ((ahd_inb(ahd, DFSTATUS) & PRELOAD_AVAIL) == 0)
                    727:                                continue;
                    728:                        if ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) == 0)
                    729:                                continue;
                    730:
                    731:                        /*
                    732:                         * Determine the offset of the next S/G
                    733:                         * element to load.
                    734:                         */
                    735:                        sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
                    736:                        sgptr &= SG_PTR_MASK;
                    737:                        if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
                    738:                                struct ahd_dma64_seg *sg;
                    739:
                    740:                                sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
                    741:                                data_addr = sg->addr;
                    742:                                data_len = sg->len;
                    743:                                sgptr += sizeof(*sg);
                    744:                        } else {
                    745:                                struct  ahd_dma_seg *sg;
                    746:
                    747:                                sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
                    748:                                data_addr = sg->len & AHD_SG_HIGH_ADDR_MASK;
                    749:                                data_addr <<= 8;
                    750:                                data_addr |= sg->addr;
                    751:                                data_len = sg->len;
                    752:                                sgptr += sizeof(*sg);
                    753:                        }
                    754:
                    755:                        /*
                    756:                         * Update residual information.
                    757:                         */
                    758:                        ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, data_len >> 24);
                    759:                        ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
                    760:
                    761:                        /*
                    762:                         * Load the S/G.
                    763:                         */
                    764:                        if (data_len & AHD_DMA_LAST_SEG) {
                    765:                                sgptr |= LAST_SEG;
                    766:                                ahd_outb(ahd, SG_STATE, 0);
                    767:                        }
                    768:                        ahd_outq(ahd, HADDR, data_addr);
                    769:                        ahd_outl(ahd, HCNT, data_len & AHD_SG_LEN_MASK);
                    770:                        ahd_outb(ahd, SG_CACHE_PRE, sgptr & 0xFF);
                    771:
                    772:                        /*
                    773:                         * Advertise the segment to the hardware.
                    774:                         */
                    775:                        dfcntrl = ahd_inb(ahd, DFCNTRL)|PRELOADEN|HDMAEN;
                    776:                        if ((ahd->features & AHD_NEW_DFCNTRL_OPTS)!=0) {
                    777:                                /*
                    778:                                 * Use SCSIENWRDIS so that SCSIEN
                    779:                                 * is never modified by this
                    780:                                 * operation.
                    781:                                 */
                    782:                                dfcntrl |= SCSIENWRDIS;
                    783:                        }
                    784:                        ahd_outb(ahd, DFCNTRL, dfcntrl);
                    785:                } else if ((ahd_inb(ahd, SG_CACHE_SHADOW)
                    786:                         & LAST_SEG_DONE) != 0) {
                    787:
                    788:                        /*
                    789:                         * Transfer completed to the end of SG list
                    790:                         * and has flushed to the host.
                    791:                         */
                    792:                        ahd_outb(ahd, SCB_SGPTR,
                    793:                                 ahd_inb_scbram(ahd, SCB_SGPTR) | SG_LIST_NULL);
                    794:                        break;
                    795:                } else if ((ahd_inb(ahd, DFSTATUS) & FIFOEMP) != 0) {
                    796:                        break;
1.1       fvdl      797:                }
1.21      thorpej   798:                ahd_delay(200);
1.1       fvdl      799:        }
                    800:        /*
1.21      thorpej   801:         * Clear any handler for this FIFO, decrement
                    802:         * the FIFO use count for the SCB, and release
                    803:         * the FIFO.
1.1       fvdl      804:         */
1.21      thorpej   805:        ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
                    806:        ahd_outb(ahd, SCB_FIFO_USE_COUNT,
                    807:                 ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) - 1);
                    808:        ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
1.1       fvdl      809: }
                    810:
                    811: void
                    812: ahd_run_qoutfifo(struct ahd_softc *ahd)
                    813: {
                    814:        struct scb *scb;
                    815:        u_int  scb_index;
                    816:
                    817:        if ((ahd->flags & AHD_RUNNING_QOUTFIFO) != 0)
                    818:                panic("ahd_run_qoutfifo recursion");
                    819:        ahd->flags |= AHD_RUNNING_QOUTFIFO;
                    820:        ahd_sync_qoutfifo(ahd, BUS_DMASYNC_POSTREAD);
                    821:        while ((ahd->qoutfifo[ahd->qoutfifonext]
                    822:             & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) {
                    823:
                    824:                scb_index = ahd_le16toh(ahd->qoutfifo[ahd->qoutfifonext]
                    825:                                      & ~QOUTFIFO_ENTRY_VALID_LE);
                    826:                scb = ahd_lookup_scb(ahd, scb_index);
                    827:                if (scb == NULL) {
                    828:                        printf("%s: WARNING no command for scb %d "
                    829:                               "(cmdcmplt)\nQOUTPOS = %d\n",
                    830:                               ahd_name(ahd), scb_index,
                    831:                               ahd->qoutfifonext);
                    832:                        ahd_dump_card_state(ahd);
                    833:                } else
                    834:                        ahd_complete_scb(ahd, scb);
                    835:
                    836:                ahd->qoutfifonext = (ahd->qoutfifonext+1) & (AHD_QOUT_SIZE-1);
                    837:                if (ahd->qoutfifonext == 0)
                    838:                        ahd->qoutfifonext_valid_tag ^= QOUTFIFO_ENTRY_VALID_LE;
                    839:        }
                    840:        ahd->flags &= ~AHD_RUNNING_QOUTFIFO;
                    841: }
                    842:
                    843: /************************* Interrupt Handling *********************************/
                    844: void
                    845: ahd_handle_hwerrint(struct ahd_softc *ahd)
                    846: {
                    847:        /*
                    848:         * Some catastrophic hardware error has occurred.
                    849:         * Print it for the user and disable the controller.
                    850:         */
                    851:        int i;
                    852:        int error;
                    853:
                    854:        error = ahd_inb(ahd, ERROR);
                    855:        for (i = 0; i < num_errors; i++) {
                    856:                if ((error & ahd_hard_errors[i].errno) != 0)
                    857:                        printf("%s: hwerrint, %s\n",
                    858:                               ahd_name(ahd), ahd_hard_errors[i].errmesg);
                    859:        }
                    860:
                    861:        ahd_dump_card_state(ahd);
                    862:        panic("BRKADRINT");
                    863:
                    864:        /* Tell everyone that this HBA is no longer available */
                    865:        ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
                    866:                       CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
                    867:                       CAM_NO_HBA);
                    868:
                    869:        /* Tell the system that this controller has gone away. */
                    870:        ahd_free(ahd);
                    871: }
                    872:
                    873: void
1.36      christos  874: ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
1.1       fvdl      875: {
                    876:        u_int seqintcode;
                    877:
                    878:        /*
                    879:         * Save the sequencer interrupt code and clear the SEQINT
                    880:         * bit. We will unpause the sequencer, if appropriate,
                    881:         * after servicing the request.
                    882:         */
                    883:        seqintcode = ahd_inb(ahd, SEQINTCODE);
                    884:        ahd_outb(ahd, CLRINT, CLRSEQINT);
                    885:        if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) {
                    886:                /*
                    887:                 * Unpause the sequencer and let it clear
                    888:                 * SEQINT by writing NO_SEQINT to it.  This
                    889:                 * will cause the sequencer to be paused again,
                    890:                 * which is the expected state of this routine.
                    891:                 */
                    892:                ahd_unpause(ahd);
                    893:                while (!ahd_is_paused(ahd))
                    894:                        ;
                    895:                ahd_outb(ahd, CLRINT, CLRSEQINT);
                    896:        }
                    897:        ahd_update_modes(ahd);
                    898: #ifdef AHD_DEBUG
                    899:        if ((ahd_debug & AHD_SHOW_MISC) != 0)
                    900:                printf("%s: Handle Seqint Called for code %d\n",
                    901:                       ahd_name(ahd), seqintcode);
                    902: #endif
                    903:        switch (seqintcode) {
1.9       thorpej   904:        case BAD_SCB_STATUS:
                    905:        {
                    906:                struct  scb *scb;
                    907:                u_int   scbid;
                    908:                int     cmds_pending;
                    909:
                    910:                scbid = ahd_get_scbptr(ahd);
                    911:                scb = ahd_lookup_scb(ahd, scbid);
                    912:                if (scb != NULL) {
                    913:                        ahd_complete_scb(ahd, scb);
                    914:                } else {
                    915:                        printf("%s: WARNING no command for scb %d "
                    916:                               "(bad status)\n", ahd_name(ahd), scbid);
                    917:                        ahd_dump_card_state(ahd);
                    918:                }
                    919:                cmds_pending = ahd_inw(ahd, CMDS_PENDING);
                    920:                if (cmds_pending > 0)
                    921:                        ahd_outw(ahd, CMDS_PENDING, cmds_pending - 1);
                    922:                break;
                    923:        }
1.1       fvdl      924:        case ENTERING_NONPACK:
                    925:        {
                    926:                struct  scb *scb;
                    927:                u_int   scbid;
                    928:
                    929:                AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
                    930:                                 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
                    931:                scbid = ahd_get_scbptr(ahd);
                    932:                scb = ahd_lookup_scb(ahd, scbid);
                    933:                if (scb == NULL) {
                    934:                        /*
                    935:                         * Somehow need to know if this
                    936:                         * is from a selection or reselection.
1.19      thorpej   937:                         * From that, we can determine target
1.1       fvdl      938:                         * ID so we at least have an I_T nexus.
                    939:                         */
                    940:                } else {
                    941:                        ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
                    942:                        ahd_outb(ahd, SAVED_LUN, scb->hscb->lun);
                    943:                        ahd_outb(ahd, SEQ_FLAGS, 0x0);
                    944:                }
                    945:                if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0
                    946:                 && (ahd_inb(ahd, SCSISIGO) & ATNO) != 0) {
                    947:                        /*
                    948:                         * Phase change after read stream with
                    949:                         * CRC error with P0 asserted on last
                    950:                         * packet.
                    951:                         */
                    952: #ifdef AHD_DEBUG
                    953:                        if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
                    954:                                printf("%s: Assuming LQIPHASE_NLQ with "
                    955:                                       "P0 assertion\n", ahd_name(ahd));
                    956: #endif
                    957:                }
                    958: #ifdef AHD_DEBUG
                    959:                if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
                    960:                        printf("%s: Entering NONPACK\n", ahd_name(ahd));
                    961: #endif
                    962:                break;
                    963:        }
                    964:        case INVALID_SEQINT:
                    965:                printf("%s: Invalid Sequencer interrupt occurred.\n",
                    966:                       ahd_name(ahd));
                    967:                ahd_dump_card_state(ahd);
                    968:                ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
                    969:                break;
                    970:        case STATUS_OVERRUN:
                    971:        {
1.9       thorpej   972:                struct  scb *scb;
                    973:                u_int   scbid;
                    974:
                    975:                scbid = ahd_get_scbptr(ahd);
                    976:                scb = ahd_lookup_scb(ahd, scbid);
                    977:                if (scb != NULL)
                    978:                        ahd_print_path(ahd, scb);
                    979:                else
                    980:                        printf("%s: ", ahd_name(ahd));
                    981:                printf("SCB %d Packetized Status Overrun", scbid);
1.1       fvdl      982:                ahd_dump_card_state(ahd);
                    983:                ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
                    984:                break;
                    985:        }
                    986:        case CFG4ISTAT_INTR:
                    987:        {
                    988:                struct  scb *scb;
                    989:                u_int   scbid;
                    990:
                    991:                scbid = ahd_get_scbptr(ahd);
                    992:                scb = ahd_lookup_scb(ahd, scbid);
                    993:                if (scb == NULL) {
                    994:                        ahd_dump_card_state(ahd);
                    995:                        printf("CFG4ISTAT: Free SCB %d referenced", scbid);
                    996:                        panic("For safety");
                    997:                }
                    998:                ahd_outq(ahd, HADDR, scb->sense_busaddr);
                    999:                ahd_outw(ahd, HCNT, AHD_SENSE_BUFSIZE);
                   1000:                ahd_outb(ahd, HCNT + 2, 0);
                   1001:                ahd_outb(ahd, SG_CACHE_PRE, SG_LAST_SEG);
                   1002:                ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);
                   1003:                break;
                   1004:        }
                   1005:        case ILLEGAL_PHASE:
                   1006:        {
                   1007:                u_int bus_phase;
                   1008:
                   1009:                bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
                   1010:                printf("%s: ILLEGAL_PHASE 0x%x\n",
                   1011:                       ahd_name(ahd), bus_phase);
                   1012:
                   1013:                switch (bus_phase) {
                   1014:                case P_DATAOUT:
                   1015:                case P_DATAIN:
                   1016:                case P_DATAOUT_DT:
                   1017:                case P_DATAIN_DT:
                   1018:                case P_MESGOUT:
                   1019:                case P_STATUS:
                   1020:                case P_MESGIN:
                   1021:                        ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
                   1022:                        printf("%s: Issued Bus Reset.\n", ahd_name(ahd));
                   1023:                        break;
                   1024:                case P_COMMAND:
                   1025:                {
                   1026:                        struct  ahd_devinfo devinfo;
                   1027:                        struct  scb *scb;
1.46      christos 1028: #ifdef notdef
1.1       fvdl     1029:                        struct  ahd_initiator_tinfo *targ_info;
                   1030:                        struct  ahd_tmode_tstate *tstate;
1.46      christos 1031: #endif
1.1       fvdl     1032:                        u_int   scbid;
                   1033:
                   1034:                        /*
                   1035:                         * If a target takes us into the command phase
                   1036:                         * assume that it has been externally reset and
                   1037:                         * has thus lost our previous packetized negotiation
                   1038:                         * agreement.  Since we have not sent an identify
                   1039:                         * message and may not have fully qualified the
                   1040:                         * connection, we change our command to TUR, assert
                   1041:                         * ATN and ABORT the task when we go to message in
                   1042:                         * phase.  The OSM will see the REQUEUE_REQUEST
                   1043:                         * status and retry the command.
                   1044:                         */
                   1045:                        scbid = ahd_get_scbptr(ahd);
                   1046:                        scb = ahd_lookup_scb(ahd, scbid);
                   1047:                        if (scb == NULL) {
                   1048:                                printf("Invalid phase with no valid SCB.  "
                   1049:                                       "Resetting bus.\n");
                   1050:                                ahd_reset_channel(ahd, 'A',
                   1051:                                                  /*Initiate Reset*/TRUE);
                   1052:                                break;
                   1053:                        }
                   1054:                        ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
                   1055:                                            SCB_GET_TARGET(ahd, scb),
                   1056:                                            SCB_GET_LUN(scb),
                   1057:                                            SCB_GET_CHANNEL(ahd, scb),
                   1058:                                            ROLE_INITIATOR);
1.46      christos 1059: #ifdef notdef
1.1       fvdl     1060:                        targ_info = ahd_fetch_transinfo(ahd,
                   1061:                                                        devinfo.channel,
                   1062:                                                        devinfo.our_scsiid,
                   1063:                                                        devinfo.target,
                   1064:                                                        &tstate);
1.46      christos 1065: #endif
1.1       fvdl     1066:                        ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
                   1067:                                      AHD_TRANS_ACTIVE, /*paused*/TRUE);
                   1068:                        ahd_set_syncrate(ahd, &devinfo, /*period*/0,
                   1069:                                         /*offset*/0, /*ppr_options*/0,
                   1070:                                         AHD_TRANS_ACTIVE, /*paused*/TRUE);
                   1071:                        ahd_outb(ahd, SCB_CDB_STORE, 0);
                   1072:                        ahd_outb(ahd, SCB_CDB_STORE+1, 0);
                   1073:                        ahd_outb(ahd, SCB_CDB_STORE+2, 0);
                   1074:                        ahd_outb(ahd, SCB_CDB_STORE+3, 0);
                   1075:                        ahd_outb(ahd, SCB_CDB_STORE+4, 0);
                   1076:                        ahd_outb(ahd, SCB_CDB_STORE+5, 0);
                   1077:                        ahd_outb(ahd, SCB_CDB_LEN, 6);
                   1078:                        scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE);
                   1079:                        scb->hscb->control |= MK_MESSAGE;
                   1080:                        ahd_outb(ahd, SCB_CONTROL, scb->hscb->control);
                   1081:                        ahd_outb(ahd, MSG_OUT, HOST_MSG);
                   1082:                        ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
                   1083:                        /*
                   1084:                         * The lun is 0, regardless of the SCB's lun
                   1085:                         * as we have not sent an identify message.
                   1086:                         */
                   1087:                        ahd_outb(ahd, SAVED_LUN, 0);
                   1088:                        ahd_outb(ahd, SEQ_FLAGS, 0);
                   1089:                        ahd_assert_atn(ahd);
                   1090:                        scb->flags &= ~(SCB_PACKETIZED);
                   1091:                        scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT;
                   1092:                        ahd_freeze_devq(ahd, scb);
                   1093:                        ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
                   1094:                        ahd_freeze_scb(scb);
                   1095:
                   1096:                        /*
                   1097:                         * Allow the sequencer to continue with
                   1098:                         * non-pack processing.
                   1099:                         */
                   1100:                        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   1101:                        ahd_outb(ahd, CLRLQOINT1, CLRLQOPHACHGINPKT);
                   1102:                        if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
                   1103:                                ahd_outb(ahd, CLRLQOINT1, 0);
                   1104:                        }
                   1105: #ifdef AHD_DEBUG
                   1106:                        if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
                   1107:                                ahd_print_path(ahd, scb);
                   1108:                                printf("Unexpected command phase from "
                   1109:                                       "packetized target\n");
                   1110:                        }
                   1111: #endif
                   1112:                        break;
                   1113:                }
                   1114:                }
                   1115:                break;
                   1116:        }
                   1117:        case CFG4OVERRUN:
                   1118:        {
                   1119:                struct  scb *scb;
                   1120:                u_int   scb_index;
1.30      perry    1121:
1.1       fvdl     1122: #ifdef AHD_DEBUG
                   1123:                if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
                   1124:                        printf("%s: CFG4OVERRUN mode = %x\n", ahd_name(ahd),
                   1125:                               ahd_inb(ahd, MODE_PTR));
                   1126:                }
                   1127: #endif
                   1128:                scb_index = ahd_get_scbptr(ahd);
                   1129:                scb = ahd_lookup_scb(ahd, scb_index);
                   1130:                if (scb == NULL) {
                   1131:                        /*
                   1132:                         * Attempt to transfer to an SCB that is
                   1133:                         * not outstanding.
                   1134:                         */
                   1135:                        ahd_assert_atn(ahd);
                   1136:                        ahd_outb(ahd, MSG_OUT, HOST_MSG);
                   1137:                        ahd->msgout_buf[0] = MSG_ABORT_TASK;
                   1138:                        ahd->msgout_len = 1;
                   1139:                        ahd->msgout_index = 0;
                   1140:                        ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
                   1141:                        /*
                   1142:                         * Clear status received flag to prevent any
                   1143:                         * attempt to complete this bogus SCB.
                   1144:                         */
                   1145:                        ahd_outb(ahd, SCB_CONTROL,
1.21      thorpej  1146:                                 ahd_inb_scbram(ahd, SCB_CONTROL)
                   1147:                                 & ~STATUS_RCVD);
1.1       fvdl     1148:                }
                   1149:                break;
                   1150:        }
                   1151:        case DUMP_CARD_STATE:
                   1152:        {
                   1153:                ahd_dump_card_state(ahd);
                   1154:                break;
                   1155:        }
                   1156:        case PDATA_REINIT:
                   1157:        {
                   1158: #ifdef AHD_DEBUG
                   1159:                if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
                   1160:                        printf("%s: PDATA_REINIT - DFCNTRL = 0x%x "
                   1161:                               "SG_CACHE_SHADOW = 0x%x\n",
                   1162:                               ahd_name(ahd), ahd_inb(ahd, DFCNTRL),
                   1163:                               ahd_inb(ahd, SG_CACHE_SHADOW));
                   1164:                }
                   1165: #endif
                   1166:                ahd_reinitialize_dataptrs(ahd);
                   1167:                break;
                   1168:        }
                   1169:        case HOST_MSG_LOOP:
                   1170:        {
                   1171:                struct ahd_devinfo devinfo;
                   1172:
                   1173:                /*
                   1174:                 * The sequencer has encountered a message phase
                   1175:                 * that requires host assistance for completion.
                   1176:                 * While handling the message phase(s), we will be
                   1177:                 * notified by the sequencer after each byte is
1.26      wiz      1178:                 * transferred so we can track bus phase changes.
1.1       fvdl     1179:                 *
                   1180:                 * If this is the first time we've seen a HOST_MSG_LOOP
                   1181:                 * interrupt, initialize the state of the host message
                   1182:                 * loop.
                   1183:                 */
                   1184:                ahd_fetch_devinfo(ahd, &devinfo);
                   1185:                if (ahd->msg_type == MSG_TYPE_NONE) {
                   1186:                        struct scb *scb;
                   1187:                        u_int scb_index;
                   1188:                        u_int bus_phase;
                   1189:
                   1190:                        bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
                   1191:                        if (bus_phase != P_MESGIN
                   1192:                         && bus_phase != P_MESGOUT) {
                   1193:                                printf("ahd_intr: HOST_MSG_LOOP bad "
                   1194:                                       "phase 0x%x\n", bus_phase);
                   1195:                                /*
                   1196:                                 * Probably transitioned to bus free before
                   1197:                                 * we got here.  Just punt the message.
                   1198:                                 */
                   1199:                                ahd_dump_card_state(ahd);
                   1200:                                ahd_clear_intstat(ahd);
                   1201:                                ahd_restart(ahd);
                   1202:                                return;
                   1203:                        }
                   1204:
                   1205:                        scb_index = ahd_get_scbptr(ahd);
                   1206:                        scb = ahd_lookup_scb(ahd, scb_index);
                   1207:                        if (devinfo.role == ROLE_INITIATOR) {
                   1208:                                if (bus_phase == P_MESGOUT)
                   1209:                                        ahd_setup_initiator_msgout(ahd,
                   1210:                                                                   &devinfo,
                   1211:                                                                   scb);
                   1212:                                else {
                   1213:                                        ahd->msg_type =
                   1214:                                            MSG_TYPE_INITIATOR_MSGIN;
                   1215:                                        ahd->msgin_index = 0;
                   1216:                                }
                   1217:                        }
                   1218: #if AHD_TARGET_MODE
                   1219:                        else {
                   1220:                                if (bus_phase == P_MESGOUT) {
                   1221:                                        ahd->msg_type =
                   1222:                                            MSG_TYPE_TARGET_MSGOUT;
                   1223:                                        ahd->msgin_index = 0;
                   1224:                                }
1.30      perry    1225:                                else
1.1       fvdl     1226:                                        ahd_setup_target_msgin(ahd,
                   1227:                                                               &devinfo,
                   1228:                                                               scb);
                   1229:                        }
                   1230: #endif
                   1231:                }
                   1232:
                   1233:                ahd_handle_message_phase(ahd);
                   1234:                break;
                   1235:        }
                   1236:        case NO_MATCH:
                   1237:        {
                   1238:                /* Ensure we don't leave the selection hardware on */
                   1239:                AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                   1240:                ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
                   1241:
                   1242:                printf("%s:%c:%d: no active SCB for reconnecting "
                   1243:                       "target - issuing BUS DEVICE RESET\n",
                   1244:                       ahd_name(ahd), 'A', ahd_inb(ahd, SELID) >> 4);
                   1245:                printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
                   1246:                       "REG0 == 0x%x ACCUM = 0x%x\n",
                   1247:                       ahd_inb(ahd, SAVED_SCSIID), ahd_inb(ahd, SAVED_LUN),
                   1248:                       ahd_inw(ahd, REG0), ahd_inb(ahd, ACCUM));
                   1249:                printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
                   1250:                       "SINDEX == 0x%x\n",
                   1251:                       ahd_inb(ahd, SEQ_FLAGS), ahd_get_scbptr(ahd),
                   1252:                       ahd_find_busy_tcl(ahd,
                   1253:                                         BUILD_TCL(ahd_inb(ahd, SAVED_SCSIID),
                   1254:                                                   ahd_inb(ahd, SAVED_LUN))),
                   1255:                       ahd_inw(ahd, SINDEX));
                   1256:                printf("SELID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
                   1257:                       "SCB_CONTROL == 0x%x\n",
                   1258:                       ahd_inb(ahd, SELID), ahd_inb_scbram(ahd, SCB_SCSIID),
                   1259:                       ahd_inb_scbram(ahd, SCB_LUN),
                   1260:                       ahd_inb_scbram(ahd, SCB_CONTROL));
                   1261:                printf("SCSIBUS[0] == 0x%x, SCSISIGI == 0x%x\n",
                   1262:                       ahd_inb(ahd, SCSIBUS), ahd_inb(ahd, SCSISIGI));
                   1263:                printf("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0));
                   1264:                printf("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0));
                   1265:                ahd_dump_card_state(ahd);
                   1266:                ahd->msgout_buf[0] = MSG_BUS_DEV_RESET;
                   1267:                ahd->msgout_len = 1;
                   1268:                ahd->msgout_index = 0;
                   1269:                ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
                   1270:                ahd_outb(ahd, MSG_OUT, HOST_MSG);
                   1271:                ahd_assert_atn(ahd);
                   1272:                break;
                   1273:        }
                   1274:        case PROTO_VIOLATION:
                   1275:        {
                   1276:                ahd_handle_proto_violation(ahd);
                   1277:                break;
                   1278:        }
                   1279:        case IGN_WIDE_RES:
                   1280:        {
                   1281:                struct ahd_devinfo devinfo;
                   1282:
                   1283:                ahd_fetch_devinfo(ahd, &devinfo);
                   1284:                ahd_handle_ign_wide_residue(ahd, &devinfo);
                   1285:                break;
                   1286:        }
                   1287:        case BAD_PHASE:
                   1288:        {
                   1289:                u_int lastphase;
                   1290:
                   1291:                lastphase = ahd_inb(ahd, LASTPHASE);
                   1292:                printf("%s:%c:%d: unknown scsi bus phase %x, "
                   1293:                       "lastphase = 0x%x.  Attempting to continue\n",
                   1294:                       ahd_name(ahd), 'A',
                   1295:                       SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
                   1296:                       lastphase, ahd_inb(ahd, SCSISIGI));
                   1297:                break;
                   1298:        }
                   1299:        case MISSED_BUSFREE:
                   1300:        {
                   1301:                u_int lastphase;
                   1302:
                   1303:                lastphase = ahd_inb(ahd, LASTPHASE);
                   1304:                printf("%s:%c:%d: Missed busfree. "
                   1305:                       "Lastphase = 0x%x, Curphase = 0x%x\n",
                   1306:                       ahd_name(ahd), 'A',
                   1307:                       SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
                   1308:                       lastphase, ahd_inb(ahd, SCSISIGI));
                   1309:                ahd_restart(ahd);
                   1310:                return;
                   1311:        }
                   1312:        case DATA_OVERRUN:
                   1313:        {
                   1314:                /*
                   1315:                 * When the sequencer detects an overrun, it
                   1316:                 * places the controller in "BITBUCKET" mode
                   1317:                 * and allows the target to complete its transfer.
                   1318:                 * Unfortunately, none of the counters get updated
                   1319:                 * when the controller is in this mode, so we have
                   1320:                 * no way of knowing how large the overrun was.
                   1321:                 */
                   1322:                struct  scb *scb;
                   1323:                u_int   scbindex;
                   1324: #ifdef AHD_DEBUG
                   1325:                u_int   lastphase;
                   1326: #endif
                   1327:
                   1328:                scbindex = ahd_get_scbptr(ahd);
                   1329:                scb = ahd_lookup_scb(ahd, scbindex);
                   1330: #ifdef AHD_DEBUG
                   1331:                lastphase = ahd_inb(ahd, LASTPHASE);
                   1332:                if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
                   1333:                        ahd_print_path(ahd, scb);
                   1334:                        printf("data overrun detected %s.  Tag == 0x%x.\n",
                   1335:                               ahd_lookup_phase_entry(lastphase)->phasemsg,
                   1336:                               SCB_GET_TAG(scb));
                   1337:                        ahd_print_path(ahd, scb);
                   1338:                        printf("%s seen Data Phase.  Length = %ld.  "
                   1339:                               "NumSGs = %d.\n",
                   1340:                               ahd_inb(ahd, SEQ_FLAGS) & DPHASE
                   1341:                               ? "Have" : "Haven't",
                   1342:                               ahd_get_transfer_length(scb), scb->sg_count);
                   1343:                        ahd_dump_sglist(scb);
                   1344:                }
                   1345: #endif
                   1346:
                   1347:                /*
                   1348:                 * Set this and it will take effect when the
                   1349:                 * target does a command complete.
                   1350:                 */
                   1351:                ahd_freeze_devq(ahd, scb);
                   1352:                ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
                   1353:                ahd_freeze_scb(scb);
                   1354:                break;
                   1355:        }
                   1356:        case MKMSG_FAILED:
                   1357:        {
                   1358:                struct ahd_devinfo devinfo;
                   1359:                struct scb *scb;
                   1360:                u_int scbid;
                   1361:
                   1362:                ahd_fetch_devinfo(ahd, &devinfo);
                   1363:                printf("%s:%c:%d:%d: Attempt to issue message failed\n",
                   1364:                       ahd_name(ahd), devinfo.channel, devinfo.target,
                   1365:                       devinfo.lun);
                   1366:                scbid = ahd_get_scbptr(ahd);
                   1367:                scb = ahd_lookup_scb(ahd, scbid);
                   1368:                if (scb != NULL
                   1369:                 && (scb->flags & SCB_RECOVERY_SCB) != 0)
                   1370:                        /*
                   1371:                         * Ensure that we didn't put a second instance of this
                   1372:                         * SCB into the QINFIFO.
                   1373:                         */
                   1374:                        ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
                   1375:                                           SCB_GET_CHANNEL(ahd, scb),
                   1376:                                           SCB_GET_LUN(scb), SCB_GET_TAG(scb),
                   1377:                                           ROLE_INITIATOR, /*status*/0,
                   1378:                                           SEARCH_REMOVE);
                   1379:                ahd_outb(ahd, SCB_CONTROL,
1.21      thorpej  1380:                         ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE);
1.1       fvdl     1381:                break;
                   1382:        }
                   1383:        case TASKMGMT_FUNC_COMPLETE:
                   1384:        {
                   1385:                u_int   scbid;
                   1386:                struct  scb *scb;
                   1387:
                   1388:                scbid = ahd_get_scbptr(ahd);
                   1389:                scb = ahd_lookup_scb(ahd, scbid);
                   1390:                if (scb != NULL) {
                   1391:                        u_int      lun;
                   1392:                        u_int      tag;
                   1393:                        cam_status error;
                   1394:
                   1395:                        ahd_print_path(ahd, scb);
                   1396:                        printf("Task Management Func 0x%x Complete\n",
                   1397:                               scb->hscb->task_management);
                   1398:                        lun = CAM_LUN_WILDCARD;
                   1399:                        tag = SCB_LIST_NULL;
                   1400:
                   1401:                        switch (scb->hscb->task_management) {
                   1402:                        case SIU_TASKMGMT_ABORT_TASK:
1.9       thorpej  1403:                                tag = SCB_GET_TAG(scb);
1.51      mrg      1404:                                /* FALLTHROUGH */
1.1       fvdl     1405:                        case SIU_TASKMGMT_ABORT_TASK_SET:
                   1406:                        case SIU_TASKMGMT_CLEAR_TASK_SET:
                   1407:                                lun = scb->hscb->lun;
                   1408:                                error = CAM_REQ_ABORTED;
                   1409:                                ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
                   1410:                                               'A', lun, tag, ROLE_INITIATOR,
                   1411:                                               error);
                   1412:                                break;
                   1413:                        case SIU_TASKMGMT_LUN_RESET:
                   1414:                                lun = scb->hscb->lun;
1.51      mrg      1415:                                /* FALLTHROUGH */
1.1       fvdl     1416:                        case SIU_TASKMGMT_TARGET_RESET:
                   1417:                        {
                   1418:                                struct ahd_devinfo devinfo;
                   1419:
                   1420:                                ahd_scb_devinfo(ahd, &devinfo, scb);
                   1421:                                error = CAM_BDR_SENT;
                   1422:                                ahd_handle_devreset(ahd, &devinfo, lun,
                   1423:                                                    CAM_BDR_SENT,
                   1424:                                                    lun != CAM_LUN_WILDCARD
                   1425:                                                    ? "Lun Reset"
                   1426:                                                    : "Target Reset",
                   1427:                                                    /*verbose_level*/0);
                   1428:                                break;
                   1429:                        }
                   1430:                        default:
                   1431:                                panic("Unexpected TaskMgmt Func\n");
                   1432:                                break;
                   1433:                        }
                   1434:                }
                   1435:                break;
                   1436:        }
                   1437:        case TASKMGMT_CMD_CMPLT_OKAY:
                   1438:        {
                   1439:                u_int   scbid;
                   1440:                struct  scb *scb;
                   1441:
                   1442:                /*
                   1443:                 * An ABORT TASK TMF failed to be delivered before
                   1444:                 * the targeted command completed normally.
                   1445:                 */
                   1446:                scbid = ahd_get_scbptr(ahd);
                   1447:                scb = ahd_lookup_scb(ahd, scbid);
                   1448:                if (scb != NULL) {
                   1449:                        /*
                   1450:                         * Remove the second instance of this SCB from
                   1451:                         * the QINFIFO if it is still there.
1.43      tsutsui  1452:                         */
1.1       fvdl     1453:                        ahd_print_path(ahd, scb);
                   1454:                        printf("SCB completes before TMF\n");
                   1455:                        /*
                   1456:                         * Handle losing the race.  Wait until any
                   1457:                         * current selection completes.  We will then
                   1458:                         * set the TMF back to zero in this SCB so that
                   1459:                         * the sequencer doesn't bother to issue another
                   1460:                         * sequencer interrupt for its completion.
                   1461:                         */
                   1462:                        while ((ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
                   1463:                            && (ahd_inb(ahd, SSTAT0) & SELDO) == 0
                   1464:                            && (ahd_inb(ahd, SSTAT1) & SELTO) == 0)
                   1465:                                ;
                   1466:                        ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0);
                   1467:                        ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
1.30      perry    1468:                                           SCB_GET_CHANNEL(ahd, scb),
1.9       thorpej  1469:                                           SCB_GET_LUN(scb), SCB_GET_TAG(scb),
1.30      perry    1470:                                           ROLE_INITIATOR, /*status*/0,
1.1       fvdl     1471:                                           SEARCH_REMOVE);
                   1472:                }
                   1473:                break;
                   1474:        }
                   1475:        case TRACEPOINT0:
                   1476:        case TRACEPOINT1:
                   1477:        case TRACEPOINT2:
                   1478:        case TRACEPOINT3:
                   1479:                printf("%s: Tracepoint %d\n", ahd_name(ahd),
                   1480:                       seqintcode - TRACEPOINT0);
                   1481:                break;
                   1482:        case NO_SEQINT:
                   1483:                break;
                   1484:        case SAW_HWERR:
                   1485:                ahd_handle_hwerrint(ahd);
                   1486:                break;
                   1487:        default:
                   1488:                printf("%s: Unexpected SEQINTCODE %d\n", ahd_name(ahd),
                   1489:                       seqintcode);
                   1490:                break;
                   1491:        }
                   1492:        /*
                   1493:         *  The sequencer is paused immediately on
                   1494:         *  a SEQINT, so we should restart it when
                   1495:         *  we're done.
                   1496:         */
                   1497:        ahd_unpause(ahd);
                   1498: }
                   1499:
                   1500: void
1.36      christos 1501: ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
1.1       fvdl     1502: {
                   1503:        struct scb      *scb;
                   1504:        u_int            status0;
                   1505:        u_int            status3;
                   1506:        u_int            status;
                   1507:        u_int            lqistat1;
                   1508:        u_int            lqostat0;
                   1509:        u_int            scbid;
                   1510:        u_int            busfreetime;
                   1511:
                   1512:        ahd_update_modes(ahd);
                   1513:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   1514:
                   1515:        status3 = ahd_inb(ahd, SSTAT3) & (NTRAMPERR|OSRAMPERR);
                   1516:        status0 = ahd_inb(ahd, SSTAT0) & (IOERR|OVERRUN|SELDI|SELDO);
                   1517:        status = ahd_inb(ahd, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
                   1518:        lqistat1 = ahd_inb(ahd, LQISTAT1);
                   1519:        lqostat0 = ahd_inb(ahd, LQOSTAT0);
                   1520:        busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME;
                   1521:        if ((status0 & (SELDI|SELDO)) != 0) {
                   1522:                u_int simode0;
                   1523:
                   1524:                ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                   1525:                simode0 = ahd_inb(ahd, SIMODE0);
                   1526:                status0 &= simode0 & (IOERR|OVERRUN|SELDI|SELDO);
                   1527:                ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   1528:        }
                   1529:        scbid = ahd_get_scbptr(ahd);
                   1530:        scb = ahd_lookup_scb(ahd, scbid);
                   1531:        if (scb != NULL
                   1532:         && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
                   1533:                scb = NULL;
                   1534:
                   1535:        /* Make sure the sequencer is in a safe location. */
                   1536:        ahd_clear_critical_section(ahd);
                   1537:
                   1538:        if ((status0 & IOERR) != 0) {
                   1539:                u_int now_lvd;
                   1540:
                   1541:                now_lvd = ahd_inb(ahd, SBLKCTL) & ENAB40;
                   1542:                printf("%s: Transceiver State Has Changed to %s mode\n",
                   1543:                       ahd_name(ahd), now_lvd ? "LVD" : "SE");
                   1544:                ahd_outb(ahd, CLRSINT0, CLRIOERR);
                   1545:                /*
                   1546:                 * A change in I/O mode is equivalent to a bus reset.
                   1547:                 */
1.9       thorpej  1548:                ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1.1       fvdl     1549:                ahd_pause(ahd);
                   1550:                ahd_setup_iocell_workaround(ahd);
                   1551:                ahd_unpause(ahd);
                   1552:        } else if ((status0 & OVERRUN) != 0) {
                   1553:                printf("%s: SCSI offset overrun detected.  Resetting bus.\n",
                   1554:                       ahd_name(ahd));
                   1555:                ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
                   1556:        } else if ((status & SCSIRSTI) != 0) {
                   1557:                printf("%s: Someone reset channel A\n", ahd_name(ahd));
                   1558:                ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE);
                   1559:        } else if ((status & SCSIPERR) != 0) {
                   1560:                ahd_handle_transmission_error(ahd);
                   1561:        } else if (lqostat0 != 0) {
                   1562:                printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0);
                   1563:                ahd_outb(ahd, CLRLQOINT0, lqostat0);
                   1564:                if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
                   1565:                        ahd_outb(ahd, CLRLQOINT1, 0);
                   1566:                }
                   1567:        } else if ((status & SELTO) != 0) {
1.31      christos 1568:                u_int  scbid1;
1.1       fvdl     1569:
                   1570:                /* Stop the selection */
                   1571:                ahd_outb(ahd, SCSISEQ0, 0);
                   1572:
                   1573:                /* No more pending messages */
                   1574:                ahd_clear_msg_state(ahd);
                   1575:
                   1576:                /* Clear interrupt state */
                   1577:                ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
                   1578:
                   1579:                /*
                   1580:                 * Although the driver does not care about the
                   1581:                 * 'Selection in Progress' status bit, the busy
1.53      msaitoh  1582:                 * LED does.  SELINGO is only cleared by a successful
1.1       fvdl     1583:                 * selection, so we must manually clear it to insure
                   1584:                 * the LED turns off just incase no future successful
                   1585:                 * selections occur (e.g. no devices on the bus).
                   1586:                 */
                   1587:                ahd_outb(ahd, CLRSINT0, CLRSELINGO);
                   1588:
1.31      christos 1589:                scbid1 = ahd_inw(ahd, WAITING_TID_HEAD);
                   1590:                scb = ahd_lookup_scb(ahd, scbid1);
1.1       fvdl     1591:                if (scb == NULL) {
                   1592:                        printf("%s: ahd_intr - referenced scb not "
                   1593:                               "valid during SELTO scb(0x%x)\n",
1.31      christos 1594:                               ahd_name(ahd), scbid1);
1.1       fvdl     1595:                        ahd_dump_card_state(ahd);
                   1596:                } else {
                   1597:                        struct ahd_devinfo devinfo;
                   1598: #ifdef AHD_DEBUG
                   1599:                        if ((ahd_debug & AHD_SHOW_SELTO) != 0) {
                   1600:                                ahd_print_path(ahd, scb);
                   1601:                                printf("Saw Selection Timeout for SCB 0x%x\n",
1.31      christos 1602:                                       scbid1);
1.1       fvdl     1603:                        }
                   1604: #endif
                   1605:                        /*
                   1606:                         * Force a renegotiation with this target just in
                   1607:                         * case the cable was pulled and will later be
                   1608:                         * re-attached.  The target may forget its negotiation
                   1609:                         * settings with us should it attempt to reselect
                   1610:                         * during the interruption.  The target will not issue
                   1611:                         * a unit attention in this case, so we must always
                   1612:                         * renegotiate.
                   1613:                         */
                   1614:                        ahd_scb_devinfo(ahd, &devinfo, scb);
                   1615:                        ahd_force_renegotiation(ahd, &devinfo);
                   1616:                        ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT);
                   1617:                        ahd_freeze_devq(ahd, scb);
                   1618:                }
                   1619:                ahd_outb(ahd, CLRINT, CLRSCSIINT);
                   1620:                ahd_iocell_first_selection(ahd);
                   1621:                ahd_unpause(ahd);
                   1622:        } else if ((status0 & (SELDI|SELDO)) != 0) {
                   1623:                ahd_iocell_first_selection(ahd);
                   1624:                ahd_unpause(ahd);
                   1625:        } else if (status3 != 0) {
                   1626:                printf("%s: SCSI Cell parity error SSTAT3 == 0x%x\n",
                   1627:                       ahd_name(ahd), status3);
                   1628:                ahd_outb(ahd, CLRSINT3, status3);
                   1629:        } else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) {
                   1630:                ahd_handle_lqiphase_error(ahd, lqistat1);
                   1631:        } else if ((lqistat1 & LQICRCI_NLQ) != 0) {
                   1632:                /*
                   1633:                 * This status can be delayed during some
                   1634:                 * streaming operations.  The SCSIPHASE
                   1635:                 * handler has already dealt with this case
                   1636:                 * so just clear the error.
                   1637:                 */
                   1638:                ahd_outb(ahd, CLRLQIINT1, CLRLQICRCI_NLQ);
                   1639:        } else if ((status & BUSFREE) != 0) {
                   1640:                u_int lqostat1;
                   1641:                int   restart;
                   1642:                int   clear_fifo;
                   1643:                int   packetized;
                   1644:                u_int mode;
                   1645:
                   1646:                /*
                   1647:                 * Clear our selection hardware as soon as possible.
                   1648:                 * We may have an entry in the waiting Q for this target,
                   1649:                 * that is affected by this busfree and we don't want to
                   1650:                 * go about selecting the target while we handle the event.
                   1651:                 */
                   1652:                ahd_outb(ahd, SCSISEQ0, 0);
                   1653:
                   1654:                /*
                   1655:                 * Determine what we were up to at the time of
                   1656:                 * the busfree.
                   1657:                 */
                   1658:                mode = AHD_MODE_SCSI;
                   1659:                busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME;
                   1660:                lqostat1 = ahd_inb(ahd, LQOSTAT1);
                   1661:                switch (busfreetime) {
                   1662:                case BUSFREE_DFF0:
                   1663:                case BUSFREE_DFF1:
                   1664:                {
1.31      christos 1665:                        u_int   scbid1;
                   1666:                        struct  scb *scb1;
1.1       fvdl     1667:
                   1668:                        mode = busfreetime == BUSFREE_DFF0
                   1669:                             ? AHD_MODE_DFF0 : AHD_MODE_DFF1;
                   1670:                        ahd_set_modes(ahd, mode, mode);
1.31      christos 1671:                        scbid1 = ahd_get_scbptr(ahd);
                   1672:                        scb1 = ahd_lookup_scb(ahd, scbid1);
                   1673:                        if (scb1 == NULL) {
1.9       thorpej  1674:                                printf("%s: Invalid SCB %d in DFF%d "
1.1       fvdl     1675:                                       "during unexpected busfree\n",
1.31      christos 1676:                                       ahd_name(ahd), scbid1, mode);
1.1       fvdl     1677:                                packetized = 0;
                   1678:                        } else
1.44      tsutsui  1679:                                packetized =
                   1680:                                    (scb1->flags & SCB_PACKETIZED) != 0;
1.1       fvdl     1681:                        clear_fifo = 1;
                   1682:                        break;
                   1683:                }
                   1684:                case BUSFREE_LQO:
                   1685:                        clear_fifo = 0;
                   1686:                        packetized = 1;
                   1687:                        break;
                   1688:                default:
                   1689:                        clear_fifo = 0;
                   1690:                        packetized =  (lqostat1 & LQOBUSFREE) != 0;
                   1691:                        if (!packetized
                   1692:                         && ahd_inb(ahd, LASTPHASE) == P_BUSFREE)
                   1693:                                packetized = 1;
                   1694:                        break;
                   1695:                }
                   1696:
                   1697: #ifdef AHD_DEBUG
                   1698:                if ((ahd_debug & AHD_SHOW_MISC) != 0)
                   1699:                        printf("Saw Busfree.  Busfreetime = 0x%x.\n",
                   1700:                               busfreetime);
                   1701: #endif
                   1702:                /*
                   1703:                 * Busfrees that occur in non-packetized phases are
                   1704:                 * handled by the nonpkt_busfree handler.
                   1705:                 */
                   1706:                if (packetized && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) {
                   1707:                        restart = ahd_handle_pkt_busfree(ahd, busfreetime);
                   1708:                } else {
                   1709:                        packetized = 0;
                   1710:                        restart = ahd_handle_nonpkt_busfree(ahd);
                   1711:                }
                   1712:                /*
                   1713:                 * Clear the busfree interrupt status.  The setting of
                   1714:                 * the interrupt is a pulse, so in a perfect world, we
                   1715:                 * would not need to muck with the ENBUSFREE logic.  This
                   1716:                 * would ensure that if the bus moves on to another
                   1717:                 * connection, busfree protection is still in force.  If
                   1718:                 * BUSFREEREV is broken, however, we must manually clear
                   1719:                 * the ENBUSFREE if the busfree occurred during a non-pack
                   1720:                 * connection so that we don't get false positives during
                   1721:                 * future, packetized, connections.
                   1722:                 */
                   1723:                ahd_outb(ahd, CLRSINT1, CLRBUSFREE);
                   1724:                if (packetized == 0
                   1725:                 && (ahd->bugs & AHD_BUSFREEREV_BUG) != 0)
                   1726:                        ahd_outb(ahd, SIMODE1,
                   1727:                                 ahd_inb(ahd, SIMODE1) & ~ENBUSFREE);
                   1728:
                   1729:                if (clear_fifo)
                   1730:                        ahd_clear_fifo(ahd, mode);
                   1731:
                   1732:                ahd_clear_msg_state(ahd);
                   1733:                ahd_outb(ahd, CLRINT, CLRSCSIINT);
                   1734:                if (restart) {
                   1735:                        ahd_restart(ahd);
                   1736:                } else {
                   1737:                        ahd_unpause(ahd);
                   1738:                }
                   1739:        } else {
                   1740:                printf("%s: Missing case in ahd_handle_scsiint. status = %x\n",
                   1741:                       ahd_name(ahd), status);
                   1742:                ahd_dump_card_state(ahd);
                   1743:                ahd_clear_intstat(ahd);
                   1744:                ahd_unpause(ahd);
                   1745:        }
                   1746: }
                   1747:
                   1748: static void
                   1749: ahd_handle_transmission_error(struct ahd_softc *ahd)
                   1750: {
                   1751:        struct  scb *scb;
                   1752:        u_int   scbid;
                   1753:        u_int   lqistat1;
                   1754:        u_int   msg_out;
                   1755:        u_int   curphase;
                   1756:        u_int   lastphase;
                   1757:        u_int   perrdiag;
                   1758:        u_int   cur_col;
                   1759:        int     silent;
                   1760:
                   1761:        scb = NULL;
                   1762:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   1763:        lqistat1 = ahd_inb(ahd, LQISTAT1) & ~(LQIPHASE_LQ|LQIPHASE_NLQ);
1.46      christos 1764:        (void)ahd_inb(ahd, LQISTAT2);
1.1       fvdl     1765:        if ((lqistat1 & (LQICRCI_NLQ|LQICRCI_LQ)) == 0
                   1766:         && (ahd->bugs & AHD_NLQICRC_DELAYED_BUG) != 0) {
                   1767:                u_int lqistate;
                   1768:
                   1769:                ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                   1770:                lqistate = ahd_inb(ahd, LQISTATE);
                   1771:                if ((lqistate >= 0x1E && lqistate <= 0x24)
                   1772:                 || (lqistate == 0x29)) {
                   1773: #ifdef AHD_DEBUG
                   1774:                        if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
                   1775:                                printf("%s: NLQCRC found via LQISTATE\n",
                   1776:                                       ahd_name(ahd));
                   1777:                        }
                   1778: #endif
                   1779:                        lqistat1 |= LQICRCI_NLQ;
                   1780:                }
                   1781:                ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   1782:        }
                   1783:
                   1784:        ahd_outb(ahd, CLRLQIINT1, lqistat1);
                   1785:        lastphase = ahd_inb(ahd, LASTPHASE);
                   1786:        curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
                   1787:        perrdiag = ahd_inb(ahd, PERRDIAG);
                   1788:        msg_out = MSG_INITIATOR_DET_ERR;
                   1789:        ahd_outb(ahd, CLRSINT1, CLRSCSIPERR);
1.30      perry    1790:
1.1       fvdl     1791:        /*
                   1792:         * Try to find the SCB associated with this error.
                   1793:         */
                   1794:        silent = FALSE;
                   1795:        if (lqistat1 == 0
                   1796:         || (lqistat1 & LQICRCI_NLQ) != 0) {
1.43      tsutsui  1797:                if ((lqistat1 & (LQICRCI_NLQ|LQIOVERI_NLQ)) != 0)
1.1       fvdl     1798:                        ahd_set_active_fifo(ahd);
                   1799:                scbid = ahd_get_scbptr(ahd);
                   1800:                scb = ahd_lookup_scb(ahd, scbid);
                   1801:                if (scb != NULL && SCB_IS_SILENT(scb))
                   1802:                        silent = TRUE;
                   1803:        }
                   1804:
                   1805:        cur_col = 0;
                   1806:        if (silent == FALSE) {
                   1807:                printf("%s: Transmission error detected\n", ahd_name(ahd));
                   1808:                ahd_lqistat1_print(lqistat1, &cur_col, 50);
                   1809:                ahd_lastphase_print(lastphase, &cur_col, 50);
                   1810:                ahd_scsisigi_print(curphase, &cur_col, 50);
                   1811:                ahd_perrdiag_print(perrdiag, &cur_col, 50);
                   1812:                printf("\n");
                   1813:                ahd_dump_card_state(ahd);
                   1814:        }
                   1815:
                   1816:        if ((lqistat1 & (LQIOVERI_LQ|LQIOVERI_NLQ)) != 0) {
                   1817:                if (silent == FALSE) {
                   1818:                        printf("%s: Gross protocol error during incoming "
                   1819:                               "packet.  lqistat1 == 0x%x.  Resetting bus.\n",
                   1820:                               ahd_name(ahd), lqistat1);
                   1821:                }
                   1822:                ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
                   1823:                return;
                   1824:        } else if ((lqistat1 & LQICRCI_LQ) != 0) {
                   1825:                /*
                   1826:                 * A CRC error has been detected on an incoming LQ.
                   1827:                 * The bus is currently hung on the last ACK.
                   1828:                 * Hit LQIRETRY to release the last ack, and
                   1829:                 * wait for the sequencer to determine that ATNO
                   1830:                 * is asserted while in message out to take us
                   1831:                 * to our host message loop.  No NONPACKREQ or
                   1832:                 * LQIPHASE type errors will occur in this
                   1833:                 * scenario.  After this first LQIRETRY, the LQI
                   1834:                 * manager will be in ISELO where it will
                   1835:                 * happily sit until another packet phase begins.
                   1836:                 * Unexpected bus free detection is enabled
                   1837:                 * through any phases that occur after we release
                   1838:                 * this last ack until the LQI manager sees a
                   1839:                 * packet phase.  This implies we may have to
1.64      andvar   1840:                 * ignore a perfectly valid "unexpected busfree"
1.1       fvdl     1841:                 * after our "initiator detected error" message is
                   1842:                 * sent.  A busfree is the expected response after
1.50      snj      1843:                 * we tell the target that its L_Q was corrupted.
1.1       fvdl     1844:                 * (SPI4R09 10.7.3.3.3)
                   1845:                 */
                   1846:                ahd_outb(ahd, LQCTL2, LQIRETRY);
                   1847:                printf("LQIRetry for LQICRCI_LQ to release ACK\n");
                   1848:        } else if ((lqistat1 & LQICRCI_NLQ) != 0) {
                   1849:                /*
                   1850:                 * We detected a CRC error in a NON-LQ packet.
                   1851:                 * The hardware has varying behavior in this situation
                   1852:                 * depending on whether this packet was part of a
                   1853:                 * stream or not.
                   1854:                 *
                   1855:                 * PKT by PKT mode:
                   1856:                 * The hardware has already acked the complete packet.
                   1857:                 * If the target honors our outstanding ATN condition,
                   1858:                 * we should be (or soon will be) in MSGOUT phase.
                   1859:                 * This will trigger the LQIPHASE_LQ status bit as the
                   1860:                 * hardware was expecting another LQ.  Unexpected
                   1861:                 * busfree detection is enabled.  Once LQIPHASE_LQ is
                   1862:                 * true (first entry into host message loop is much
                   1863:                 * the same), we must clear LQIPHASE_LQ and hit
                   1864:                 * LQIRETRY so the hardware is ready to handle
                   1865:                 * a future LQ.  NONPACKREQ will not be asserted again
                   1866:                 * once we hit LQIRETRY until another packet is
                   1867:                 * processed.  The target may either go busfree
                   1868:                 * or start another packet in response to our message.
                   1869:                 *
                   1870:                 * Read Streaming P0 asserted:
                   1871:                 * If we raise ATN and the target completes the entire
                   1872:                 * stream (P0 asserted during the last packet), the
                   1873:                 * hardware will ack all data and return to the ISTART
                   1874:                 * state.  When the target reponds to our ATN condition,
                   1875:                 * LQIPHASE_LQ will be asserted.  We should respond to
                   1876:                 * this with an LQIRETRY to prepare for any future
                   1877:                 * packets.  NONPACKREQ will not be asserted again
                   1878:                 * once we hit LQIRETRY until another packet is
                   1879:                 * processed.  The target may either go busfree or
                   1880:                 * start another packet in response to our message.
                   1881:                 * Busfree detection is enabled.
                   1882:                 *
                   1883:                 * Read Streaming P0 not asserted:
                   1884:                 * If we raise ATN and the target transitions to
                   1885:                 * MSGOUT in or after a packet where P0 is not
                   1886:                 * asserted, the hardware will assert LQIPHASE_NLQ.
                   1887:                 * We should respond to the LQIPHASE_NLQ with an
                   1888:                 * LQIRETRY.  Should the target stay in a non-pkt
                   1889:                 * phase after we send our message, the hardware
                   1890:                 * will assert LQIPHASE_LQ.  Recovery is then just as
                   1891:                 * listed above for the read streaming with P0 asserted.
                   1892:                 * Busfree detection is enabled.
                   1893:                 */
                   1894:                if (silent == FALSE)
                   1895:                        printf("LQICRC_NLQ\n");
                   1896:                if (scb == NULL) {
                   1897:                        printf("%s: No SCB valid for LQICRC_NLQ.  "
                   1898:                               "Resetting bus\n", ahd_name(ahd));
                   1899:                        ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
                   1900:                        return;
                   1901:                }
                   1902:        } else if ((lqistat1 & LQIBADLQI) != 0) {
                   1903:                printf("Need to handle BADLQI!\n");
                   1904:                ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
                   1905:                return;
                   1906:        } else if ((perrdiag & (PARITYERR|PREVPHASE)) == PARITYERR) {
                   1907:                if ((curphase & ~P_DATAIN_DT) != 0) {
                   1908:                        /* Ack the byte.  So we can continue. */
                   1909:                        if (silent == FALSE)
                   1910:                                printf("Acking %s to clear perror\n",
                   1911:                                    ahd_lookup_phase_entry(curphase)->phasemsg);
                   1912:                        ahd_inb(ahd, SCSIDAT);
                   1913:                }
1.30      perry    1914:
1.1       fvdl     1915:                if (curphase == P_MESGIN)
                   1916:                        msg_out = MSG_PARITY_ERROR;
                   1917:        }
                   1918:
                   1919:        /*
1.30      perry    1920:         * We've set the hardware to assert ATN if we
1.1       fvdl     1921:         * get a parity error on "in" phases, so all we
                   1922:         * need to do is stuff the message buffer with
                   1923:         * the appropriate message.  "In" phases have set
                   1924:         * mesg_out to something other than MSG_NOP.
                   1925:         */
                   1926:        ahd->send_msg_perror = msg_out;
                   1927:        if (scb != NULL && msg_out == MSG_INITIATOR_DET_ERR)
                   1928:                scb->flags |= SCB_TRANSMISSION_ERROR;
                   1929:        ahd_outb(ahd, MSG_OUT, HOST_MSG);
                   1930:        ahd_outb(ahd, CLRINT, CLRSCSIINT);
                   1931:        ahd_unpause(ahd);
                   1932: }
                   1933:
                   1934: static void
                   1935: ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1)
                   1936: {
                   1937:        /*
                   1938:         * Clear the sources of the interrupts.
                   1939:         */
                   1940:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   1941:        ahd_outb(ahd, CLRLQIINT1, lqistat1);
                   1942:
                   1943:        /*
                   1944:         * If the "illegal" phase changes were in response
                   1945:         * to our ATN to flag a CRC error, AND we ended up
                   1946:         * on packet boundaries, clear the error, restart the
                   1947:         * LQI manager as appropriate, and go on our merry
                   1948:         * way toward sending the message.  Otherwise, reset
                   1949:         * the bus to clear the error.
                   1950:         */
                   1951:        ahd_set_active_fifo(ahd);
                   1952:        if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0
                   1953:         && (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) {
                   1954:                if ((lqistat1 & LQIPHASE_LQ) != 0) {
                   1955:                        printf("LQIRETRY for LQIPHASE_LQ\n");
                   1956:                        ahd_outb(ahd, LQCTL2, LQIRETRY);
                   1957:                } else if ((lqistat1 & LQIPHASE_NLQ) != 0) {
                   1958:                        printf("LQIRETRY for LQIPHASE_NLQ\n");
                   1959:                        ahd_outb(ahd, LQCTL2, LQIRETRY);
                   1960:                } else
                   1961:                        panic("ahd_handle_lqiphase_error: No phase errors\n");
                   1962:                ahd_dump_card_state(ahd);
                   1963:                ahd_outb(ahd, CLRINT, CLRSCSIINT);
                   1964:                ahd_unpause(ahd);
                   1965:        } else {
1.57      andvar   1966:                printf("Resetting Channel for LQI Phase error\n");
1.1       fvdl     1967:                ahd_dump_card_state(ahd);
                   1968:                ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
                   1969:        }
                   1970: }
                   1971:
                   1972: /*
                   1973:  * Packetized unexpected or expected busfree.
                   1974:  * Entered in mode based on busfreetime.
                   1975:  */
                   1976: static int
                   1977: ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
                   1978: {
                   1979:        u_int lqostat1;
                   1980:
                   1981:        AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
                   1982:                         ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
                   1983:        lqostat1 = ahd_inb(ahd, LQOSTAT1);
                   1984:        if ((lqostat1 & LQOBUSFREE) != 0) {
                   1985:                struct scb *scb;
                   1986:                u_int scbid;
                   1987:                u_int saved_scbptr;
                   1988:                u_int waiting_h;
                   1989:                u_int waiting_t;
                   1990:                u_int next;
                   1991:
                   1992:                if ((busfreetime & BUSFREE_LQO) == 0)
                   1993:                        printf("%s: Warning, BUSFREE time is 0x%x.  "
                   1994:                               "Expected BUSFREE_LQO.\n",
                   1995:                               ahd_name(ahd), busfreetime);
                   1996:                /*
                   1997:                 * The LQO manager detected an unexpected busfree
                   1998:                 * either:
                   1999:                 *
                   2000:                 * 1) During an outgoing LQ.
                   2001:                 * 2) After an outgoing LQ but before the first
                   2002:                 *    REQ of the command packet.
                   2003:                 * 3) During an outgoing command packet.
                   2004:                 *
                   2005:                 * In all cases, CURRSCB is pointing to the
                   2006:                 * SCB that encountered the failure.  Clean
                   2007:                 * up the queue, clear SELDO and LQOBUSFREE,
                   2008:                 * and allow the sequencer to restart the select
                   2009:                 * out at its lesure.
                   2010:                 */
                   2011:                ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   2012:                scbid = ahd_inw(ahd, CURRSCB);
                   2013:                scb = ahd_lookup_scb(ahd, scbid);
                   2014:                if (scb == NULL)
1.43      tsutsui  2015:                        panic("SCB not valid during LQOBUSFREE");
1.1       fvdl     2016:                /*
                   2017:                 * Clear the status.
                   2018:                 */
                   2019:                ahd_outb(ahd, CLRLQOINT1, CLRLQOBUSFREE);
                   2020:                if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0)
                   2021:                        ahd_outb(ahd, CLRLQOINT1, 0);
                   2022:                ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
                   2023:                ahd_flush_device_writes(ahd);
                   2024:                ahd_outb(ahd, CLRSINT0, CLRSELDO);
                   2025:
                   2026:                /*
                   2027:                 * Return the LQO manager to its idle loop.  It will
                   2028:                 * not do this automatically if the busfree occurs
                   2029:                 * after the first REQ of either the LQ or command
                   2030:                 * packet or between the LQ and command packet.
                   2031:                 */
                   2032:                ahd_outb(ahd, LQCTL2, ahd_inb(ahd, LQCTL2) | LQOTOIDLE);
                   2033:
                   2034:                /*
                   2035:                 * Update the waiting for selection queue so
                   2036:                 * we restart on the correct SCB.
                   2037:                 */
                   2038:                waiting_h = ahd_inw(ahd, WAITING_TID_HEAD);
                   2039:                saved_scbptr = ahd_get_scbptr(ahd);
                   2040:                if (waiting_h != scbid) {
                   2041:
                   2042:                        ahd_outw(ahd, WAITING_TID_HEAD, scbid);
                   2043:                        waiting_t = ahd_inw(ahd, WAITING_TID_TAIL);
                   2044:                        if (waiting_t == waiting_h) {
                   2045:                                ahd_outw(ahd, WAITING_TID_TAIL, scbid);
                   2046:                                next = SCB_LIST_NULL;
                   2047:                        } else {
                   2048:                                ahd_set_scbptr(ahd, waiting_h);
                   2049:                                next = ahd_inw_scbram(ahd, SCB_NEXT2);
                   2050:                        }
                   2051:                        ahd_set_scbptr(ahd, scbid);
                   2052:                        ahd_outw(ahd, SCB_NEXT2, next);
                   2053:                }
                   2054:                ahd_set_scbptr(ahd, saved_scbptr);
                   2055:                if (scb->crc_retry_count < AHD_MAX_LQ_CRC_ERRORS) {
                   2056:                        if (SCB_IS_SILENT(scb) == FALSE) {
                   2057:                                ahd_print_path(ahd, scb);
                   2058:                                printf("Probable outgoing LQ CRC error.  "
                   2059:                                       "Retrying command\n");
                   2060:                        }
                   2061:                        scb->crc_retry_count++;
                   2062:                } else {
                   2063:                        ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
                   2064:                        ahd_freeze_scb(scb);
                   2065:                        ahd_freeze_devq(ahd, scb);
                   2066:                }
                   2067:                /* Return unpausing the sequencer. */
                   2068:                return (0);
                   2069:        } else if ((ahd_inb(ahd, PERRDIAG) & PARITYERR) != 0) {
                   2070:                /*
                   2071:                 * Ignore what are really parity errors that
                   2072:                 * occur on the last REQ of a free running
                   2073:                 * clock prior to going busfree.  Some drives
                   2074:                 * do not properly active negate just before
                   2075:                 * going busfree resulting in a parity glitch.
                   2076:                 */
                   2077:                ahd_outb(ahd, CLRSINT1, CLRSCSIPERR|CLRBUSFREE);
                   2078: #ifdef AHD_DEBUG
                   2079:                if ((ahd_debug & AHD_SHOW_MASKED_ERRORS) != 0)
                   2080:                        printf("%s: Parity on last REQ detected "
                   2081:                               "during busfree phase.\n",
                   2082:                               ahd_name(ahd));
                   2083: #endif
                   2084:                /* Return unpausing the sequencer. */
                   2085:                return (0);
                   2086:        }
                   2087:        if (ahd->src_mode != AHD_MODE_SCSI) {
                   2088:                u_int   scbid;
                   2089:                struct  scb *scb;
                   2090:
                   2091:                scbid = ahd_get_scbptr(ahd);
                   2092:                scb = ahd_lookup_scb(ahd, scbid);
                   2093:                ahd_print_path(ahd, scb);
                   2094:                printf("Unexpected PKT busfree condition\n");
                   2095:                ahd_dump_card_state(ahd);
                   2096:                ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A',
                   2097:                               SCB_GET_LUN(scb), SCB_GET_TAG(scb),
                   2098:                               ROLE_INITIATOR, CAM_UNEXP_BUSFREE);
                   2099:
                   2100:                /* Return restarting the sequencer. */
                   2101:                return (1);
                   2102:        }
                   2103:        printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd));
                   2104:        ahd_dump_card_state(ahd);
                   2105:        /* Restart the sequencer. */
                   2106:        return (1);
                   2107: }
                   2108:
                   2109: /*
                   2110:  * Non-packetized unexpected or expected busfree.
                   2111:  */
                   2112: static int
                   2113: ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
                   2114: {
                   2115:        struct  ahd_devinfo devinfo;
                   2116:        struct  scb *scb;
                   2117:        u_int   lastphase;
                   2118:        u_int   saved_scsiid;
                   2119:        u_int   saved_lun;
                   2120:        u_int   target;
                   2121:        u_int   initiator_role_id;
                   2122:        u_int   scbid;
                   2123:        u_int   ppr_busfree;
                   2124:        int     printerror;
                   2125:
                   2126:        /*
                   2127:         * Look at what phase we were last in.  If its message out,
                   2128:         * chances are pretty good that the busfree was in response
                   2129:         * to one of our abort requests.
                   2130:         */
                   2131:        lastphase = ahd_inb(ahd, LASTPHASE);
                   2132:        saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
                   2133:        saved_lun = ahd_inb(ahd, SAVED_LUN);
                   2134:        target = SCSIID_TARGET(ahd, saved_scsiid);
                   2135:        initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
                   2136:        ahd_compile_devinfo(&devinfo, initiator_role_id,
                   2137:                            target, saved_lun, 'A', ROLE_INITIATOR);
                   2138:        printerror = 1;
                   2139:
                   2140:        scbid = ahd_get_scbptr(ahd);
                   2141:        scb = ahd_lookup_scb(ahd, scbid);
                   2142:        if (scb != NULL
                   2143:         && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
                   2144:                scb = NULL;
                   2145:
                   2146:        ppr_busfree = (ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0;
                   2147:        if (lastphase == P_MESGOUT) {
                   2148:                u_int tag;
                   2149:
                   2150:                tag = SCB_LIST_NULL;
                   2151:                if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT_TAG, TRUE)
                   2152:                 || ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT, TRUE)) {
                   2153:                        int found;
                   2154:                        int sent_msg;
                   2155:
                   2156:                        if (scb == NULL) {
                   2157:                                ahd_print_devinfo(ahd, &devinfo);
                   2158:                                printf("Abort for unidentified "
                   2159:                                       "connection completed.\n");
                   2160:                                /* restart the sequencer. */
                   2161:                                return (1);
                   2162:                        }
                   2163:                        sent_msg = ahd->msgout_buf[ahd->msgout_index - 1];
                   2164:                        ahd_print_path(ahd, scb);
                   2165:                        printf("SCB %d - Abort%s Completed.\n",
                   2166:                               SCB_GET_TAG(scb),
                   2167:                               sent_msg == MSG_ABORT_TAG ? "" : " Tag");
                   2168:
                   2169:                        if (sent_msg == MSG_ABORT_TAG)
                   2170:                                tag = SCB_GET_TAG(scb);
                   2171:
                   2172:                        if ((scb->flags & SCB_CMDPHASE_ABORT) != 0) {
                   2173:                                /*
                   2174:                                 * This abort is in response to an
                   2175:                                 * unexpected switch to command phase
                   2176:                                 * for a packetized connection.  Since
                   2177:                                 * the identify message was never sent,
                   2178:                                 * "saved lun" is 0.  We really want to
                   2179:                                 * abort only the SCB that encountered
                   2180:                                 * this error, which could have a different
                   2181:                                 * lun.  The SCB will be retried so the OS
                   2182:                                 * will see the UA after renegotiating to
                   2183:                                 * packetized.
                   2184:                                 */
                   2185:                                tag = SCB_GET_TAG(scb);
                   2186:                                saved_lun = scb->hscb->lun;
                   2187:                        }
                   2188:                        found = ahd_abort_scbs(ahd, target, 'A', saved_lun,
                   2189:                                               tag, ROLE_INITIATOR,
                   2190:                                               CAM_REQ_ABORTED);
                   2191:                        printf("found == 0x%x\n", found);
                   2192:                        printerror = 0;
                   2193:                } else if (ahd_sent_msg(ahd, AHDMSG_1B,
                   2194:                                        MSG_BUS_DEV_RESET, TRUE)) {
                   2195: #ifdef __FreeBSD__
                   2196:                        /*
                   2197:                         * Don't mark the user's request for this BDR
                   2198:                         * as completing with CAM_BDR_SENT.  CAM3
                   2199:                         * specifies CAM_REQ_CMP.
                   2200:                         */
                   2201:                        if (scb != NULL
                   2202:                         && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV
                   2203:                         && ahd_match_scb(ahd, scb, target, 'A',
                   2204:                                          CAM_LUN_WILDCARD, SCB_LIST_NULL,
                   2205:                                          ROLE_INITIATOR))
                   2206:                                ahd_set_transaction_status(scb, CAM_REQ_CMP);
                   2207: #endif
                   2208:                        ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD,
                   2209:                                            CAM_BDR_SENT, "Bus Device Reset",
                   2210:                                            /*verbose_level*/0);
                   2211:                        printerror = 0;
                   2212:                } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE)
                   2213:                        && ppr_busfree == 0) {
                   2214:                        struct ahd_initiator_tinfo *tinfo;
                   2215:                        struct ahd_tmode_tstate *tstate;
                   2216:
                   2217:                        /*
                   2218:                         * PPR Rejected.  Try non-ppr negotiation
                   2219:                         * and retry command.
                   2220:                         */
                   2221: #ifdef AHD_DEBUG
                   2222:                        if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
                   2223:                                printf("PPR negotiation rejected busfree.\n");
                   2224: #endif
                   2225:                        tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
                   2226:                                                    devinfo.our_scsiid,
                   2227:                                                    devinfo.target, &tstate);
                   2228:                        tinfo->curr.transport_version = 2;
                   2229:                        tinfo->goal.transport_version = 2;
                   2230:                        tinfo->goal.ppr_options = 0;
                   2231:                        ahd_qinfifo_requeue_tail(ahd, scb);
                   2232:                        printerror = 0;
1.16      thorpej  2233:                } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
1.1       fvdl     2234:                        && ppr_busfree == 0) {
                   2235:                        /*
1.16      thorpej  2236:                         * Negotiation Rejected.  Go-narrow and
1.1       fvdl     2237:                         * retry command.
                   2238:                         */
                   2239: #ifdef AHD_DEBUG
                   2240:                        if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
1.16      thorpej  2241:                                printf("WDTR Negotiation rejected busfree.\n");
1.1       fvdl     2242: #endif
                   2243:                        ahd_set_width(ahd, &devinfo,
                   2244:                                      MSG_EXT_WDTR_BUS_8_BIT,
                   2245:                                      AHD_TRANS_CUR|AHD_TRANS_GOAL,
                   2246:                                      /*paused*/TRUE);
1.16      thorpej  2247:                        ahd_qinfifo_requeue_tail(ahd, scb);
                   2248:                        printerror = 0;
                   2249:                } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
                   2250:                        && ppr_busfree == 0) {
                   2251:                        /*
                   2252:                         * Negotiation Rejected.  Go-async and
                   2253:                         * retry command.
                   2254:                         */
                   2255: #ifdef AHD_DEBUG
                   2256:                        if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
                   2257:                                printf("SDTR negotiation rejected busfree.\n");
                   2258: #endif
1.1       fvdl     2259:                        ahd_set_syncrate(ahd, &devinfo,
                   2260:                                        /*period*/0, /*offset*/0,
                   2261:                                        /*ppr_options*/0,
                   2262:                                        AHD_TRANS_CUR|AHD_TRANS_GOAL,
                   2263:                                        /*paused*/TRUE);
                   2264:                        ahd_qinfifo_requeue_tail(ahd, scb);
                   2265:                        printerror = 0;
                   2266:                } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
                   2267:                        && ahd_sent_msg(ahd, AHDMSG_1B,
                   2268:                                         MSG_INITIATOR_DET_ERR, TRUE)) {
                   2269:
                   2270: #ifdef AHD_DEBUG
                   2271:                        if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
                   2272:                                printf("Expected IDE Busfree\n");
                   2273: #endif
                   2274:                        printerror = 0;
                   2275:                } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE)
                   2276:                        && ahd_sent_msg(ahd, AHDMSG_1B,
                   2277:                                        MSG_MESSAGE_REJECT, TRUE)) {
                   2278:
                   2279: #ifdef AHD_DEBUG
                   2280:                        if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
                   2281:                                printf("Expected QAS Reject Busfree\n");
                   2282: #endif
                   2283:                        printerror = 0;
                   2284:                }
                   2285:        }
                   2286:
                   2287:        /*
                   2288:         * The busfree required flag is honored at the end of
                   2289:         * the message phases.  We check it last in case we
                   2290:         * had to send some other message that caused a busfree.
                   2291:         */
                   2292:        if (printerror != 0
                   2293:         && (lastphase == P_MESGIN || lastphase == P_MESGOUT)
                   2294:         && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) {
                   2295:
                   2296:                ahd_freeze_devq(ahd, scb);
                   2297:                ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
                   2298:                ahd_freeze_scb(scb);
                   2299:                if ((ahd->msg_flags & MSG_FLAG_IU_REQ_CHANGED) != 0) {
                   2300:                        ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
                   2301:                                       SCB_GET_CHANNEL(ahd, scb),
                   2302:                                       SCB_GET_LUN(scb), SCB_LIST_NULL,
                   2303:                                       ROLE_INITIATOR, CAM_REQ_ABORTED);
                   2304:                } else {
                   2305: #ifdef AHD_DEBUG
                   2306:                        if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
                   2307:                                printf("PPR Negotiation Busfree.\n");
                   2308: #endif
                   2309:                        ahd_done(ahd, scb);
                   2310:                }
                   2311:                printerror = 0;
                   2312:        }
                   2313:        if (printerror != 0) {
                   2314:                int aborted;
                   2315:
                   2316:                aborted = 0;
                   2317:                if (scb != NULL) {
                   2318:                        u_int tag;
                   2319:
                   2320:                        if ((scb->hscb->control & TAG_ENB) != 0)
                   2321:                                tag = SCB_GET_TAG(scb);
                   2322:                        else
                   2323:                                tag = SCB_LIST_NULL;
                   2324:                        ahd_print_path(ahd, scb);
                   2325:                        aborted = ahd_abort_scbs(ahd, target, 'A',
                   2326:                                       SCB_GET_LUN(scb), tag,
                   2327:                                       ROLE_INITIATOR,
                   2328:                                       CAM_UNEXP_BUSFREE);
                   2329:                } else {
                   2330:                        /*
                   2331:                         * We had not fully identified this connection,
                   2332:                         * so we cannot abort anything.
                   2333:                         */
                   2334:                        printf("%s: ", ahd_name(ahd));
                   2335:                }
                   2336:                if (lastphase != P_BUSFREE)
                   2337:                        ahd_force_renegotiation(ahd, &devinfo);
                   2338:                printf("Unexpected busfree %s, %d SCBs aborted, "
                   2339:                       "PRGMCNT == 0x%x\n",
                   2340:                       ahd_lookup_phase_entry(lastphase)->phasemsg,
                   2341:                       aborted,
                   2342:                       ahd_inb(ahd, PRGMCNT)
                   2343:                        | (ahd_inb(ahd, PRGMCNT+1) << 8));
                   2344:                ahd_dump_card_state(ahd);
                   2345:        }
                   2346:        /* Always restart the sequencer. */
                   2347:        return (1);
                   2348: }
                   2349:
                   2350: static void
                   2351: ahd_handle_proto_violation(struct ahd_softc *ahd)
                   2352: {
                   2353:        struct  ahd_devinfo devinfo;
                   2354:        struct  scb *scb;
                   2355:        u_int   scbid;
                   2356:        u_int   seq_flags;
                   2357:        u_int   curphase;
                   2358:        u_int   lastphase;
                   2359:        int     found;
                   2360:
                   2361:        ahd_fetch_devinfo(ahd, &devinfo);
                   2362:        scbid = ahd_get_scbptr(ahd);
                   2363:        scb = ahd_lookup_scb(ahd, scbid);
                   2364:        seq_flags = ahd_inb(ahd, SEQ_FLAGS);
                   2365:        curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
                   2366:        lastphase = ahd_inb(ahd, LASTPHASE);
                   2367:        if ((seq_flags & NOT_IDENTIFIED) != 0) {
                   2368:
                   2369:                /*
                   2370:                 * The reconnecting target either did not send an
                   2371:                 * identify message, or did, but we didn't find an SCB
                   2372:                 * to match.
                   2373:                 */
                   2374:                ahd_print_devinfo(ahd, &devinfo);
                   2375:                printf("Target did not send an IDENTIFY message. "
                   2376:                       "LASTPHASE = 0x%x.\n", lastphase);
                   2377:                scb = NULL;
                   2378:        } else if (scb == NULL) {
                   2379:                /*
                   2380:                 * We don't seem to have an SCB active for this
                   2381:                 * transaction.  Print an error and reset the bus.
                   2382:                 */
                   2383:                ahd_print_devinfo(ahd, &devinfo);
                   2384:                printf("No SCB found during protocol violation\n");
                   2385:                goto proto_violation_reset;
                   2386:        } else {
                   2387:                ahd_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
                   2388:                if ((seq_flags & NO_CDB_SENT) != 0) {
                   2389:                        ahd_print_path(ahd, scb);
                   2390:                        printf("No or incomplete CDB sent to device.\n");
                   2391:                } else if ((ahd_inb_scbram(ahd, SCB_CONTROL)
                   2392:                          & STATUS_RCVD) == 0) {
                   2393:                        /*
                   2394:                         * The target never bothered to provide status to
                   2395:                         * us prior to completing the command.  Since we don't
                   2396:                         * know the disposition of this command, we must attempt
                   2397:                         * to abort it.  Assert ATN and prepare to send an abort
                   2398:                         * message.
                   2399:                         */
                   2400:                        ahd_print_path(ahd, scb);
                   2401:                        printf("Completed command without status.\n");
                   2402:                } else {
                   2403:                        ahd_print_path(ahd, scb);
                   2404:                        printf("Unknown protocol violation.\n");
                   2405:                        ahd_dump_card_state(ahd);
                   2406:                }
                   2407:        }
                   2408:        if ((lastphase & ~P_DATAIN_DT) == 0
                   2409:         || lastphase == P_COMMAND) {
                   2410: proto_violation_reset:
                   2411:                /*
                   2412:                 * Target either went directly to data
                   2413:                 * phase or didn't respond to our ATN.
                   2414:                 * The only safe thing to do is to blow
                   2415:                 * it away with a bus reset.
                   2416:                 */
                   2417:                found = ahd_reset_channel(ahd, 'A', TRUE);
                   2418:                printf("%s: Issued Channel %c Bus Reset. "
                   2419:                       "%d SCBs aborted\n", ahd_name(ahd), 'A', found);
                   2420:        } else {
                   2421:                /*
                   2422:                 * Leave the selection hardware off in case
                   2423:                 * this abort attempt will affect yet to
                   2424:                 * be sent commands.
                   2425:                 */
                   2426:                ahd_outb(ahd, SCSISEQ0,
                   2427:                         ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
                   2428:                ahd_assert_atn(ahd);
                   2429:                ahd_outb(ahd, MSG_OUT, HOST_MSG);
                   2430:                if (scb == NULL) {
                   2431:                        ahd_print_devinfo(ahd, &devinfo);
                   2432:                        ahd->msgout_buf[0] = MSG_ABORT_TASK;
                   2433:                        ahd->msgout_len = 1;
                   2434:                        ahd->msgout_index = 0;
                   2435:                        ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
                   2436:                } else {
                   2437:                        ahd_print_path(ahd, scb);
                   2438:                        scb->flags |= SCB_ABORT;
                   2439:                }
                   2440:                printf("Protocol violation %s.  Attempting to abort.\n",
                   2441:                       ahd_lookup_phase_entry(curphase)->phasemsg);
                   2442:        }
                   2443: }
                   2444:
                   2445: /*
                   2446:  * Force renegotiation to occur the next time we initiate
                   2447:  * a command to the current device.
                   2448:  */
                   2449: static void
                   2450: ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
                   2451: {
                   2452:        struct  ahd_initiator_tinfo *targ_info;
                   2453:        struct  ahd_tmode_tstate *tstate;
                   2454:
                   2455: #ifdef AHD_DEBUG
                   2456:        if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
                   2457:                ahd_print_devinfo(ahd, devinfo);
                   2458:                printf("Forcing renegotiation\n");
                   2459:        }
                   2460: #endif
                   2461:        targ_info = ahd_fetch_transinfo(ahd,
                   2462:                                        devinfo->channel,
                   2463:                                        devinfo->our_scsiid,
                   2464:                                        devinfo->target,
                   2465:                                        &tstate);
                   2466:        ahd_update_neg_request(ahd, devinfo, tstate,
                   2467:                               targ_info, AHD_NEG_IF_NON_ASYNC);
                   2468: }
                   2469:
                   2470: #define AHD_MAX_STEPS 2000
                   2471: void
                   2472: ahd_clear_critical_section(struct ahd_softc *ahd)
                   2473: {
                   2474:        ahd_mode_state  saved_modes;
                   2475:        int             stepping;
                   2476:        int             steps;
                   2477:        int             first_instr;
                   2478:        u_int           simode0;
                   2479:        u_int           simode1;
                   2480:        u_int           simode3;
                   2481:        u_int           lqimode0;
                   2482:        u_int           lqimode1;
                   2483:        u_int           lqomode0;
                   2484:        u_int           lqomode1;
                   2485:
                   2486:        if (ahd->num_critical_sections == 0)
                   2487:                return;
                   2488:
                   2489:        stepping = FALSE;
                   2490:        steps = 0;
                   2491:        first_instr = 0;
                   2492:        simode0 = 0;
                   2493:        simode1 = 0;
                   2494:        simode3 = 0;
                   2495:        lqimode0 = 0;
                   2496:        lqimode1 = 0;
                   2497:        lqomode0 = 0;
                   2498:        lqomode1 = 0;
                   2499:        saved_modes = ahd_save_modes(ahd);
                   2500:        for (;;) {
                   2501:                struct  cs *cs;
                   2502:                u_int   seqaddr;
                   2503:                u_int   i;
                   2504:
                   2505:                ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   2506:                seqaddr = ahd_inb(ahd, CURADDR)
                   2507:                        | (ahd_inb(ahd, CURADDR+1) << 8);
                   2508:
                   2509:                cs = ahd->critical_sections;
                   2510:                for (i = 0; i < ahd->num_critical_sections; i++, cs++) {
1.30      perry    2511:
1.1       fvdl     2512:                        if (cs->begin < seqaddr && cs->end >= seqaddr)
                   2513:                                break;
                   2514:                }
                   2515:
                   2516:                if (i == ahd->num_critical_sections)
                   2517:                        break;
                   2518:
                   2519:                if (steps > AHD_MAX_STEPS) {
                   2520:                        printf("%s: Infinite loop in critical section\n"
                   2521:                               "%s: First Instruction 0x%x now 0x%x\n",
                   2522:                               ahd_name(ahd), ahd_name(ahd), first_instr,
                   2523:                               seqaddr);
                   2524:                        ahd_dump_card_state(ahd);
                   2525:                        panic("critical section loop");
                   2526:                }
                   2527:
                   2528:                steps++;
                   2529: #ifdef AHD_DEBUG
                   2530:                if ((ahd_debug & AHD_SHOW_MISC) != 0)
                   2531:                        printf("%s: Single stepping at 0x%x\n", ahd_name(ahd),
                   2532:                               seqaddr);
                   2533: #endif
                   2534:                if (stepping == FALSE) {
                   2535:
                   2536:                        first_instr = seqaddr;
1.43      tsutsui  2537:                        ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                   2538:                        simode0 = ahd_inb(ahd, SIMODE0);
1.1       fvdl     2539:                        simode3 = ahd_inb(ahd, SIMODE3);
                   2540:                        lqimode0 = ahd_inb(ahd, LQIMODE0);
                   2541:                        lqimode1 = ahd_inb(ahd, LQIMODE1);
                   2542:                        lqomode0 = ahd_inb(ahd, LQOMODE0);
                   2543:                        lqomode1 = ahd_inb(ahd, LQOMODE1);
                   2544:                        ahd_outb(ahd, SIMODE0, 0);
                   2545:                        ahd_outb(ahd, SIMODE3, 0);
                   2546:                        ahd_outb(ahd, LQIMODE0, 0);
                   2547:                        ahd_outb(ahd, LQIMODE1, 0);
                   2548:                        ahd_outb(ahd, LQOMODE0, 0);
                   2549:                        ahd_outb(ahd, LQOMODE1, 0);
                   2550:                        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1.19      thorpej  2551:                        simode1 = ahd_inb(ahd, SIMODE1);
                   2552:                        /*
                   2553:                         * We don't clear ENBUSFREE.  Unfortunately
                   2554:                         * we cannot re-enable busfree detection within
                   2555:                         * the current connection, so we must leave it
                   2556:                         * on while single stepping.
                   2557:                         */
                   2558:                        ahd_outb(ahd, SIMODE1, simode1 & ENBUSFREE);
1.1       fvdl     2559:                        ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP);
                   2560:                        stepping = TRUE;
                   2561:                }
                   2562:                ahd_outb(ahd, CLRSINT1, CLRBUSFREE);
                   2563:                ahd_outb(ahd, CLRINT, CLRSCSIINT);
                   2564:                ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
                   2565:                ahd_outb(ahd, HCNTRL, ahd->unpause);
1.19      thorpej  2566:                while (!ahd_is_paused(ahd))
1.1       fvdl     2567:                        ahd_delay(200);
                   2568:                ahd_update_modes(ahd);
                   2569:        }
                   2570:        if (stepping) {
                   2571:                ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                   2572:                ahd_outb(ahd, SIMODE0, simode0);
                   2573:                ahd_outb(ahd, SIMODE3, simode3);
                   2574:                ahd_outb(ahd, LQIMODE0, lqimode0);
                   2575:                ahd_outb(ahd, LQIMODE1, lqimode1);
                   2576:                ahd_outb(ahd, LQOMODE0, lqomode0);
                   2577:                ahd_outb(ahd, LQOMODE1, lqomode1);
                   2578:                ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   2579:                ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP);
1.43      tsutsui  2580:                ahd_outb(ahd, SIMODE1, simode1);
1.9       thorpej  2581:                /*
1.65      andvar   2582:                 * SCSIINT seems to glitch occasionally when
1.9       thorpej  2583:                 * the interrupt masks are restored.  Clear SCSIINT
                   2584:                 * one more time so that only persistent errors
                   2585:                 * are seen as a real interrupt.
                   2586:                 */
                   2587:                ahd_outb(ahd, CLRINT, CLRSCSIINT);
1.1       fvdl     2588:        }
                   2589:        ahd_restore_modes(ahd, saved_modes);
                   2590: }
                   2591:
                   2592: /*
                   2593:  * Clear any pending interrupt status.
                   2594:  */
                   2595: void
                   2596: ahd_clear_intstat(struct ahd_softc *ahd)
                   2597: {
                   2598:        AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
                   2599:                         ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
                   2600:        /* Clear any interrupt conditions this may have caused */
                   2601:        ahd_outb(ahd, CLRLQIINT0, CLRLQIATNQAS|CLRLQICRCT1|CLRLQICRCT2
                   2602:                                 |CLRLQIBADLQT|CLRLQIATNLQ|CLRLQIATNCMD);
                   2603:        ahd_outb(ahd, CLRLQIINT1, CLRLQIPHASE_LQ|CLRLQIPHASE_NLQ|CLRLIQABORT
                   2604:                                 |CLRLQICRCI_LQ|CLRLQICRCI_NLQ|CLRLQIBADLQI
                   2605:                                 |CLRLQIOVERI_LQ|CLRLQIOVERI_NLQ|CLRNONPACKREQ);
                   2606:        ahd_outb(ahd, CLRLQOINT0, CLRLQOTARGSCBPERR|CLRLQOSTOPT2|CLRLQOATNLQ
                   2607:                                 |CLRLQOATNPKT|CLRLQOTCRC);
                   2608:        ahd_outb(ahd, CLRLQOINT1, CLRLQOINITSCBPERR|CLRLQOSTOPI2|CLRLQOBADQAS
                   2609:                                 |CLRLQOBUSFREE|CLRLQOPHACHGINPKT);
                   2610:        if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
                   2611:                ahd_outb(ahd, CLRLQOINT0, 0);
                   2612:                ahd_outb(ahd, CLRLQOINT1, 0);
                   2613:        }
                   2614:        ahd_outb(ahd, CLRSINT3, CLRNTRAMPERR|CLROSRAMPERR);
                   2615:        ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
                   2616:                                |CLRBUSFREE|CLRSCSIPERR|CLRREQINIT);
                   2617:        ahd_outb(ahd, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO
                   2618:                                |CLRIOERR|CLROVERRUN);
                   2619:        ahd_outb(ahd, CLRINT, CLRSCSIINT);
                   2620: }
                   2621:
                   2622: /**************************** Debugging Routines ******************************/
                   2623: #ifdef AHD_DEBUG
                   2624: uint32_t ahd_debug = AHD_DEBUG_OPTS;
                   2625: #endif
                   2626: void
                   2627: ahd_print_scb(struct scb *scb)
                   2628: {
                   2629:        struct hardware_scb *hscb;
                   2630:        int i;
                   2631:
                   2632:        hscb = scb->hscb;
                   2633:        printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
                   2634:               (void *)scb,
                   2635:               hscb->control,
                   2636:               hscb->scsiid,
                   2637:               hscb->lun,
                   2638:               hscb->cdb_len);
                   2639:        printf("Shared Data: ");
                   2640:        for (i = 0; i < sizeof(hscb->shared_data.idata.cdb); i++)
                   2641:                printf("%#02x", hscb->shared_data.idata.cdb[i]);
                   2642:        printf("        dataptr:%#x%x datacnt:%#x sgptr:%#x tag:%#x\n",
                   2643:               (uint32_t)((ahd_le64toh(hscb->dataptr) >> 32) & 0xFFFFFFFF),
                   2644:               (uint32_t)(ahd_le64toh(hscb->dataptr) & 0xFFFFFFFF),
                   2645:               ahd_le32toh(hscb->datacnt),
                   2646:               ahd_le32toh(hscb->sgptr),
                   2647:               SCB_GET_TAG(scb));
                   2648:        ahd_dump_sglist(scb);
                   2649: }
                   2650:
                   2651: void
                   2652: ahd_dump_sglist(struct scb *scb)
                   2653: {
                   2654:        int i;
                   2655:
                   2656:        if (scb->sg_count > 0) {
                   2657:                if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) {
                   2658:                        struct ahd_dma64_seg *sg_list;
                   2659:
                   2660:                        sg_list = (struct ahd_dma64_seg*)scb->sg_list;
                   2661:                        for (i = 0; i < scb->sg_count; i++) {
                   2662:                                uint64_t addr;
                   2663:
                   2664:                                addr = ahd_le64toh(sg_list[i].addr);
                   2665:                                printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
                   2666:                                       i,
                   2667:                                       (uint32_t)((addr >> 32) & 0xFFFFFFFF),
                   2668:                                       (uint32_t)(addr & 0xFFFFFFFF),
                   2669:                                       sg_list[i].len & AHD_SG_LEN_MASK,
                   2670:                                       (sg_list[i].len & AHD_DMA_LAST_SEG)
                   2671:                                     ? " Last" : "");
                   2672:                        }
                   2673:                } else {
                   2674:                        struct ahd_dma_seg *sg_list;
                   2675:
                   2676:                        sg_list = (struct ahd_dma_seg*)scb->sg_list;
                   2677:                        for (i = 0; i < scb->sg_count; i++) {
                   2678:                                uint32_t len;
                   2679:
                   2680:                                len = ahd_le32toh(sg_list[i].len);
                   2681:                                printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
                   2682:                                       i,
1.20      thorpej  2683:                                       (len & AHD_SG_HIGH_ADDR_MASK) >> 24,
1.1       fvdl     2684:                                       ahd_le32toh(sg_list[i].addr),
                   2685:                                       len & AHD_SG_LEN_MASK,
                   2686:                                       len & AHD_DMA_LAST_SEG ? " Last" : "");
                   2687:                        }
                   2688:                }
                   2689:        }
                   2690: }
                   2691:
                   2692: /************************* Transfer Negotiation *******************************/
                   2693: /*
                   2694:  * Allocate per target mode instance (ID we respond to as a target)
                   2695:  * transfer negotiation data structures.
                   2696:  */
                   2697: static struct ahd_tmode_tstate *
1.36      christos 2698: ahd_alloc_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel)
1.1       fvdl     2699: {
                   2700:        struct ahd_tmode_tstate *master_tstate;
                   2701:        struct ahd_tmode_tstate *tstate;
                   2702:        int i;
                   2703:
                   2704:        master_tstate = ahd->enabled_targets[ahd->our_id];
                   2705:        if (ahd->enabled_targets[scsi_id] != NULL
                   2706:         && ahd->enabled_targets[scsi_id] != master_tstate)
                   2707:                panic("%s: ahd_alloc_tstate - Target already allocated",
                   2708:                      ahd_name(ahd));
1.52      chs      2709:        tstate = malloc(sizeof(*tstate), M_DEVBUF, M_WAITOK | M_ZERO);
1.1       fvdl     2710:
                   2711:        /*
                   2712:         * If we have allocated a master tstate, copy user settings from
                   2713:         * the master tstate (taken from SRAM or the EEPROM) for this
                   2714:         * channel, but reset our current and goal settings to async/narrow
                   2715:         * until an initiator talks to us.
                   2716:         */
                   2717:        if (master_tstate != NULL) {
                   2718:                memcpy(tstate, master_tstate, sizeof(*tstate));
                   2719:                memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
                   2720:                for (i = 0; i < 16; i++) {
                   2721:                        memset(&tstate->transinfo[i].curr, 0,
                   2722:                              sizeof(tstate->transinfo[i].curr));
                   2723:                        memset(&tstate->transinfo[i].goal, 0,
                   2724:                              sizeof(tstate->transinfo[i].goal));
                   2725:                }
                   2726:        } else
                   2727:                memset(tstate, 0, sizeof(*tstate));
                   2728:        ahd->enabled_targets[scsi_id] = tstate;
                   2729:        return (tstate);
                   2730: }
                   2731:
                   2732: #ifdef AHD_TARGET_MODE
                   2733: /*
                   2734:  * Free per target mode instance (ID we respond to as a target)
                   2735:  * transfer negotiation data structures.
                   2736:  */
                   2737: static void
                   2738: ahd_free_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel, int force)
                   2739: {
                   2740:        struct ahd_tmode_tstate *tstate;
                   2741:
                   2742:        /*
                   2743:         * Don't clean up our "master" tstate.
                   2744:         * It has our default user settings.
                   2745:         */
                   2746:        if (scsi_id == ahd->our_id
                   2747:         && force == FALSE)
                   2748:                return;
                   2749:
                   2750:        tstate = ahd->enabled_targets[scsi_id];
                   2751:        if (tstate != NULL)
                   2752:                free(tstate, M_DEVBUF);
                   2753:        ahd->enabled_targets[scsi_id] = NULL;
                   2754: }
                   2755: #endif
                   2756:
                   2757: /*
                   2758:  * Called when we have an active connection to a target on the bus,
                   2759:  * this function finds the nearest period to the input period limited
                   2760:  * by the capabilities of the bus connectivity of and sync settings for
                   2761:  * the target.
                   2762:  */
                   2763: void
                   2764: ahd_devlimited_syncrate(struct ahd_softc *ahd,
                   2765:                        struct ahd_initiator_tinfo *tinfo,
                   2766:                        u_int *period, u_int *ppr_options, role_t role)
                   2767: {
                   2768:        struct  ahd_transinfo *transinfo;
                   2769:        u_int   maxsync;
                   2770:
                   2771:        if ((ahd_inb(ahd, SBLKCTL) & ENAB40) != 0
                   2772:         && (ahd_inb(ahd, SSTAT2) & EXP_ACTIVE) == 0) {
                   2773:                maxsync = AHD_SYNCRATE_PACED;
                   2774:        } else {
                   2775:                maxsync = AHD_SYNCRATE_ULTRA;
                   2776:                /* Can't do DT related options on an SE bus */
                   2777:                *ppr_options &= MSG_EXT_PPR_QAS_REQ;
                   2778:        }
                   2779:        /*
                   2780:         * Never allow a value higher than our current goal
                   2781:         * period otherwise we may allow a target initiated
                   2782:         * negotiation to go above the limit as set by the
                   2783:         * user.  In the case of an initiator initiated
                   2784:         * sync negotiation, we limit based on the user
                   2785:         * setting.  This allows the system to still accept
                   2786:         * incoming negotiations even if target initiated
                   2787:         * negotiation is not performed.
                   2788:         */
                   2789:        if (role == ROLE_TARGET)
                   2790:                transinfo = &tinfo->user;
1.30      perry    2791:        else
1.1       fvdl     2792:                transinfo = &tinfo->goal;
                   2793:        *ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN);
                   2794:        if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
                   2795:                maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2);
                   2796:                *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
                   2797:        }
                   2798:        if (transinfo->period == 0) {
                   2799:                *period = 0;
                   2800:                *ppr_options = 0;
                   2801:        } else {
                   2802:                *period = MAX(*period, transinfo->period);
                   2803:                ahd_find_syncrate(ahd, period, ppr_options, maxsync);
                   2804:        }
                   2805: }
                   2806:
                   2807: /*
                   2808:  * Look up the valid period to SCSIRATE conversion in our table.
                   2809:  * Return the period and offset that should be sent to the target
                   2810:  * if this was the beginning of an SDTR.
                   2811:  */
                   2812: void
1.36      christos 2813: ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
1.1       fvdl     2814:                  u_int *ppr_options, u_int maxsync)
                   2815: {
                   2816:        if (*period < maxsync)
                   2817:                *period = maxsync;
                   2818:
                   2819:        if ((*ppr_options & MSG_EXT_PPR_DT_REQ) != 0
                   2820:         && *period > AHD_SYNCRATE_MIN_DT)
                   2821:                *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1.30      perry    2822:
1.1       fvdl     2823:        if (*period > AHD_SYNCRATE_MIN)
                   2824:                *period = 0;
                   2825:
                   2826:        /* Honor PPR option conformance rules. */
                   2827:        if (*period > AHD_SYNCRATE_PACED)
                   2828:                *ppr_options &= ~MSG_EXT_PPR_RTI;
                   2829:
                   2830:        if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0)
                   2831:                *ppr_options &= (MSG_EXT_PPR_DT_REQ|MSG_EXT_PPR_QAS_REQ);
                   2832:
                   2833:        if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0)
                   2834:                *ppr_options &= MSG_EXT_PPR_QAS_REQ;
                   2835:
                   2836:        /* Skip all PACED only entries if IU is not available */
                   2837:        if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0
                   2838:         && *period < AHD_SYNCRATE_DT)
                   2839:                *period = AHD_SYNCRATE_DT;
                   2840:
                   2841:        /* Skip all DT only entries if DT is not available */
                   2842:        if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
                   2843:         && *period < AHD_SYNCRATE_ULTRA2)
                   2844:                *period = AHD_SYNCRATE_ULTRA2;
                   2845: }
                   2846:
                   2847: /*
                   2848:  * Truncate the given synchronous offset to a value the
                   2849:  * current adapter type and syncrate are capable of.
                   2850:  */
                   2851: void
                   2852: ahd_validate_offset(struct ahd_softc *ahd,
                   2853:                    struct ahd_initiator_tinfo *tinfo,
1.36      christos 2854:                    u_int period, u_int *offset, int wide,
1.1       fvdl     2855:                    role_t role)
                   2856: {
                   2857:        u_int maxoffset;
                   2858:
                   2859:        /* Limit offset to what we can do */
                   2860:        if (period == 0)
                   2861:                maxoffset = 0;
                   2862:        else if (period <= AHD_SYNCRATE_PACED) {
                   2863:                if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0)
                   2864:                        maxoffset = MAX_OFFSET_PACED_BUG;
                   2865:                else
                   2866:                        maxoffset = MAX_OFFSET_PACED;
                   2867:        } else
                   2868:                maxoffset = MAX_OFFSET_NON_PACED;
                   2869:        *offset = MIN(*offset, maxoffset);
                   2870:        if (tinfo != NULL) {
                   2871:                if (role == ROLE_TARGET)
                   2872:                        *offset = MIN(*offset, tinfo->user.offset);
                   2873:                else
                   2874:                        *offset = MIN(*offset, tinfo->goal.offset);
                   2875:        }
                   2876: }
                   2877:
                   2878: /*
                   2879:  * Truncate the given transfer width parameter to a value the
                   2880:  * current adapter type is capable of.
                   2881:  */
                   2882: void
                   2883: ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo,
                   2884:                   u_int *bus_width, role_t role)
                   2885: {
                   2886:        switch (*bus_width) {
                   2887:        default:
                   2888:                if (ahd->features & AHD_WIDE) {
                   2889:                        /* Respond Wide */
                   2890:                        *bus_width = MSG_EXT_WDTR_BUS_16_BIT;
                   2891:                        break;
                   2892:                }
                   2893:                /* FALLTHROUGH */
                   2894:        case MSG_EXT_WDTR_BUS_8_BIT:
                   2895:                *bus_width = MSG_EXT_WDTR_BUS_8_BIT;
                   2896:                break;
                   2897:        }
                   2898:        if (tinfo != NULL) {
                   2899:                if (role == ROLE_TARGET)
                   2900:                        *bus_width = MIN(tinfo->user.width, *bus_width);
                   2901:                else
                   2902:                        *bus_width = MIN(tinfo->goal.width, *bus_width);
                   2903:        }
                   2904: }
                   2905:
                   2906: /*
                   2907:  * Update the bitmask of targets for which the controller should
1.26      wiz      2908:  * negotiate with at the next convenient opportunity.  This currently
1.1       fvdl     2909:  * means the next time we send the initial identify messages for
                   2910:  * a new transaction.
                   2911:  */
                   2912: int
                   2913: ahd_update_neg_request(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
                   2914:                       struct ahd_tmode_tstate *tstate,
                   2915:                       struct ahd_initiator_tinfo *tinfo, ahd_neg_type neg_type)
                   2916: {
                   2917:        u_int auto_negotiate_orig;
                   2918:
                   2919:        auto_negotiate_orig = tstate->auto_negotiate;
                   2920:        if (neg_type == AHD_NEG_ALWAYS) {
                   2921:                /*
                   2922:                 * Force our "current" settings to be
                   2923:                 * unknown so that unless a bus reset
                   2924:                 * occurs the need to renegotiate is
                   2925:                 * recorded persistently.
                   2926:                 */
                   2927:                if ((ahd->features & AHD_WIDE) != 0)
                   2928:                        tinfo->curr.width = AHD_WIDTH_UNKNOWN;
                   2929:                tinfo->curr.period = AHD_PERIOD_UNKNOWN;
                   2930:                tinfo->curr.offset = AHD_OFFSET_UNKNOWN;
                   2931:        }
                   2932:        if (tinfo->curr.period != tinfo->goal.period
                   2933:         || tinfo->curr.width != tinfo->goal.width
                   2934:         || tinfo->curr.offset != tinfo->goal.offset
                   2935:         || tinfo->curr.ppr_options != tinfo->goal.ppr_options
                   2936:         || (neg_type == AHD_NEG_IF_NON_ASYNC
                   2937:          && (tinfo->goal.offset != 0
                   2938:           || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
                   2939:           || tinfo->goal.ppr_options != 0)))
                   2940:                tstate->auto_negotiate |= devinfo->target_mask;
                   2941:        else
                   2942:                tstate->auto_negotiate &= ~devinfo->target_mask;
                   2943:
                   2944:        return (auto_negotiate_orig != tstate->auto_negotiate);
                   2945: }
                   2946:
                   2947: /*
                   2948:  * Update the user/goal/curr tables of synchronous negotiation
                   2949:  * parameters as well as, in the case of a current or active update,
                   2950:  * any data structures on the host controller.  In the case of an
                   2951:  * active update, the specified target is currently talking to us on
                   2952:  * the bus, so the transfer parameter update must take effect
                   2953:  * immediately.
                   2954:  */
                   2955: void
                   2956: ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
                   2957:                 u_int period, u_int offset, u_int ppr_options,
                   2958:                 u_int type, int paused)
                   2959: {
                   2960:        struct  ahd_initiator_tinfo *tinfo;
                   2961:        struct  ahd_tmode_tstate *tstate;
                   2962:        u_int   old_period;
                   2963:        u_int   old_offset;
                   2964:        u_int   old_ppr;
                   2965:        int     active;
                   2966:        int     update_needed;
                   2967:
                   2968:        active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE;
                   2969:        update_needed = 0;
                   2970:
                   2971:        if (period == 0 || offset == 0) {
                   2972:                period = 0;
                   2973:                offset = 0;
                   2974:        }
                   2975:
                   2976:        tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
                   2977:                                    devinfo->target, &tstate);
                   2978:
                   2979:        if ((type & AHD_TRANS_USER) != 0) {
                   2980:                tinfo->user.period = period;
                   2981:                tinfo->user.offset = offset;
                   2982:                tinfo->user.ppr_options = ppr_options;
                   2983:        }
                   2984:
                   2985:        if ((type & AHD_TRANS_GOAL) != 0) {
                   2986:                tinfo->goal.period = period;
                   2987:                tinfo->goal.offset = offset;
                   2988:                tinfo->goal.ppr_options = ppr_options;
                   2989:        }
                   2990:
                   2991:        old_period = tinfo->curr.period;
                   2992:        old_offset = tinfo->curr.offset;
1.43      tsutsui  2993:        old_ppr    = tinfo->curr.ppr_options;
1.1       fvdl     2994:
                   2995:        if ((type & AHD_TRANS_CUR) != 0
                   2996:         && (old_period != period
                   2997:          || old_offset != offset
                   2998:          || old_ppr != ppr_options)) {
                   2999:
                   3000:                update_needed++;
                   3001:
                   3002:                tinfo->curr.period = period;
                   3003:                tinfo->curr.offset = offset;
                   3004:                tinfo->curr.ppr_options = ppr_options;
                   3005:
                   3006:                ahd_send_async(ahd, devinfo->channel, devinfo->target,
                   3007:                               CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
                   3008:
                   3009:                if (bootverbose) {
                   3010:                        if (offset != 0) {
                   3011:                                int options;
                   3012:
                   3013:                                printf("%s: target %d synchronous with "
                   3014:                                       "period = 0x%x, offset = 0x%x",
                   3015:                                       ahd_name(ahd), devinfo->target,
                   3016:                                       period, offset);
                   3017:                                options = 0;
                   3018:                                if ((ppr_options & MSG_EXT_PPR_RD_STRM) != 0) {
                   3019:                                        printf("(RDSTRM");
                   3020:                                        options++;
                   3021:                                }
                   3022:                                if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
                   3023:                                        printf("%s", options ? "|DT" : "(DT");
                   3024:                                        options++;
                   3025:                                }
                   3026:                                if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
                   3027:                                        printf("%s", options ? "|IU" : "(IU");
                   3028:                                        options++;
                   3029:                                }
                   3030:                                if ((ppr_options & MSG_EXT_PPR_RTI) != 0) {
                   3031:                                        printf("%s", options ? "|RTI" : "(RTI");
                   3032:                                        options++;
                   3033:                                }
                   3034:                                if ((ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) {
                   3035:                                        printf("%s", options ? "|QAS" : "(QAS");
                   3036:                                        options++;
                   3037:                                }
                   3038:                                if (options != 0)
                   3039:                                        printf(")\n");
                   3040:                                else
                   3041:                                        printf("\n");
                   3042:                        } else {
                   3043:                                printf("%s: target %d using "
                   3044:                                       "asynchronous transfers%s\n",
                   3045:                                       ahd_name(ahd), devinfo->target,
                   3046:                                       (ppr_options & MSG_EXT_PPR_QAS_REQ) != 0
                   3047:                                     ?  "(QAS)" : "");
                   3048:                        }
                   3049:                }
                   3050:        }
                   3051:        /*
                   3052:         * Always refresh the neg-table to handle the case of the
                   3053:         * sequencer setting the ENATNO bit for a MK_MESSAGE request.
                   3054:         * We will always renegotiate in that case if this is a
                   3055:         * packetized request.  Also manage the busfree expected flag
                   3056:         * from this common routine so that we catch changes due to
                   3057:         * WDTR or SDTR messages.
                   3058:         */
                   3059:        if ((type & AHD_TRANS_CUR) != 0) {
                   3060:                if (!paused)
                   3061:                        ahd_pause(ahd);
                   3062:                ahd_update_neg_table(ahd, devinfo, &tinfo->curr);
                   3063:                if (!paused)
                   3064:                        ahd_unpause(ahd);
                   3065:                if (ahd->msg_type != MSG_TYPE_NONE) {
                   3066:                        if ((old_ppr & MSG_EXT_PPR_IU_REQ)
                   3067:                         != (ppr_options & MSG_EXT_PPR_IU_REQ)) {
                   3068: #ifdef AHD_DEBUG
                   3069:                                if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
                   3070:                                        ahd_print_devinfo(ahd, devinfo);
                   3071:                                        printf("Expecting IU Change busfree\n");
                   3072:                                }
                   3073: #endif
                   3074:                                ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE
                   3075:                                               |  MSG_FLAG_IU_REQ_CHANGED;
                   3076:                        }
                   3077:                        if ((old_ppr & MSG_EXT_PPR_IU_REQ) != 0) {
                   3078: #ifdef AHD_DEBUG
                   3079:                                if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
                   3080:                                        printf("PPR with IU_REQ outstanding\n");
                   3081: #endif
                   3082:                                ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE;
                   3083:                        }
                   3084:                }
                   3085:        }
                   3086:
                   3087:        update_needed += ahd_update_neg_request(ahd, devinfo, tstate,
                   3088:                                                tinfo, AHD_NEG_TO_GOAL);
                   3089:
                   3090:        if (update_needed && active)
                   3091:                ahd_update_pending_scbs(ahd);
                   3092: }
                   3093:
                   3094: /*
                   3095:  * Update the user/goal/curr tables of wide negotiation
                   3096:  * parameters as well as, in the case of a current or active update,
                   3097:  * any data structures on the host controller.  In the case of an
                   3098:  * active update, the specified target is currently talking to us on
                   3099:  * the bus, so the transfer parameter update must take effect
                   3100:  * immediately.
                   3101:  */
                   3102: void
                   3103: ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
                   3104:              u_int width, u_int type, int paused)
                   3105: {
                   3106:        struct  ahd_initiator_tinfo *tinfo;
                   3107:        struct  ahd_tmode_tstate *tstate;
                   3108:        u_int   oldwidth;
                   3109:        int     active;
                   3110:        int     update_needed;
                   3111:
                   3112:        active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE;
                   3113:        update_needed = 0;
                   3114:        tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
                   3115:                                    devinfo->target, &tstate);
                   3116:
                   3117:        if ((type & AHD_TRANS_USER) != 0)
                   3118:                tinfo->user.width = width;
                   3119:
                   3120:        if ((type & AHD_TRANS_GOAL) != 0)
                   3121:                tinfo->goal.width = width;
                   3122:
                   3123:        oldwidth = tinfo->curr.width;
                   3124:        if ((type & AHD_TRANS_CUR) != 0 && oldwidth != width) {
                   3125:
                   3126:                update_needed++;
                   3127:
                   3128:                tinfo->curr.width = width;
                   3129:                ahd_send_async(ahd, devinfo->channel, devinfo->target,
                   3130:                               CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
                   3131:
                   3132:                if (bootverbose) {
                   3133:                        printf("%s: target %d using %dbit transfers\n",
                   3134:                               ahd_name(ahd), devinfo->target,
                   3135:                               8 * (0x01 << width));
                   3136:                }
                   3137:        }
                   3138:
                   3139:        if ((type & AHD_TRANS_CUR) != 0) {
                   3140:                if (!paused)
                   3141:                        ahd_pause(ahd);
                   3142:                ahd_update_neg_table(ahd, devinfo, &tinfo->curr);
                   3143:                if (!paused)
                   3144:                        ahd_unpause(ahd);
                   3145:        }
                   3146:
                   3147:        update_needed += ahd_update_neg_request(ahd, devinfo, tstate,
                   3148:                                                tinfo, AHD_NEG_TO_GOAL);
                   3149:        if (update_needed && active)
                   3150:                ahd_update_pending_scbs(ahd);
                   3151:
                   3152: }
                   3153:
                   3154: /*
                   3155:  * Update the current state of tagged queuing for a given target.
                   3156:  */
                   3157: void
                   3158: ahd_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
                   3159:           ahd_queue_alg alg)
                   3160: {
                   3161:        ahd_platform_set_tags(ahd, devinfo, alg);
                   3162:        ahd_send_async(ahd, devinfo->channel, devinfo->target,
                   3163:                       devinfo->lun, AC_TRANSFER_NEG, &alg);
                   3164: }
                   3165:
                   3166: static void
                   3167: ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
                   3168:                     struct ahd_transinfo *tinfo)
                   3169: {
                   3170:        ahd_mode_state  saved_modes;
                   3171:        u_int           period;
                   3172:        u_int           ppr_opts;
                   3173:        u_int           con_opts;
                   3174:        u_int           offset;
                   3175:        u_int           saved_negoaddr;
                   3176:        uint8_t         iocell_opts[sizeof(ahd->iocell_opts)];
                   3177:
                   3178:        saved_modes = ahd_save_modes(ahd);
                   3179:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   3180:
                   3181:        saved_negoaddr = ahd_inb(ahd, NEGOADDR);
                   3182:        ahd_outb(ahd, NEGOADDR, devinfo->target);
                   3183:        period = tinfo->period;
                   3184:        offset = tinfo->offset;
1.30      perry    3185:        memcpy(iocell_opts, ahd->iocell_opts, sizeof(ahd->iocell_opts));
1.1       fvdl     3186:        ppr_opts = tinfo->ppr_options & (MSG_EXT_PPR_QAS_REQ|MSG_EXT_PPR_DT_REQ
                   3187:                                        |MSG_EXT_PPR_IU_REQ|MSG_EXT_PPR_RTI);
                   3188:        con_opts = 0;
                   3189:        if (period == 0)
                   3190:                period = AHD_SYNCRATE_ASYNC;
                   3191:        if (period == AHD_SYNCRATE_160) {
                   3192:
                   3193:                if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) {
                   3194:                        /*
                   3195:                         * When the SPI4 spec was finalized, PACE transfers
                   3196:                         * was not made a configurable option in the PPR
                   3197:                         * message.  Instead it is assumed to be enabled for
                   3198:                         * any syncrate faster than 80MHz.  Nevertheless,
                   3199:                         * Harpoon2A4 allows this to be configurable.
                   3200:                         *
                   3201:                         * Harpoon2A4 also assumes at most 2 data bytes per
                   3202:                         * negotiated REQ/ACK offset.  Paced transfers take
                   3203:                         * 4, so we must adjust our offset.
                   3204:                         */
                   3205:                        ppr_opts |= PPROPT_PACE;
                   3206:                        offset *= 2;
                   3207:
                   3208:                        /*
                   3209:                         * Harpoon2A assumed that there would be a
1.34      lukem    3210:                         * fallback rate between 160 MHz and 80 MHz,
1.1       fvdl     3211:                         * so 7 is used as the period factor rather
                   3212:                         * than 8 for 160MHz.
                   3213:                         */
                   3214:                        period = AHD_SYNCRATE_REVA_160;
                   3215:                }
                   3216:                if ((tinfo->ppr_options & MSG_EXT_PPR_PCOMP_EN) == 0)
                   3217:                        iocell_opts[AHD_PRECOMP_SLEW_INDEX] &=
                   3218:                            ~AHD_PRECOMP_MASK;
                   3219:        } else {
                   3220:                /*
                   3221:                 * Precomp should be disabled for non-paced transfers.
                   3222:                 */
                   3223:                iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK;
                   3224:
                   3225:                if ((ahd->features & AHD_NEW_IOCELL_OPTS) != 0
                   3226:                 && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0) {
                   3227:                        /*
                   3228:                         * Slow down our CRC interval to be
                   3229:                         * compatible with devices that can't
                   3230:                         * handle a CRC at full speed.
                   3231:                         */
                   3232:                        con_opts |= ENSLOWCRC;
                   3233:                }
                   3234:        }
                   3235:
                   3236:        ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PRECOMP_SLEW);
                   3237:        ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_PRECOMP_SLEW_INDEX]);
                   3238:        ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_AMPLITUDE);
                   3239:        ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_AMPLITUDE_INDEX]);
                   3240:
                   3241:        ahd_outb(ahd, NEGPERIOD, period);
                   3242:        ahd_outb(ahd, NEGPPROPTS, ppr_opts);
                   3243:        ahd_outb(ahd, NEGOFFSET, offset);
                   3244:
                   3245:        if (tinfo->width == MSG_EXT_WDTR_BUS_16_BIT)
                   3246:                con_opts |= WIDEXFER;
                   3247:
                   3248:        /*
                   3249:         * During packetized transfers, the target will
1.26      wiz      3250:         * give us the opportunity to send command packets
1.1       fvdl     3251:         * without us asserting attention.
                   3252:         */
                   3253:        if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) == 0)
                   3254:                con_opts |= ENAUTOATNO;
                   3255:        ahd_outb(ahd, NEGCONOPTS, con_opts);
                   3256:        ahd_outb(ahd, NEGOADDR, saved_negoaddr);
                   3257:        ahd_restore_modes(ahd, saved_modes);
                   3258: }
                   3259:
                   3260: /*
                   3261:  * When the transfer settings for a connection change, setup for
                   3262:  * negotiation in pending SCBs to effect the change as quickly as
                   3263:  * possible.  We also cancel any negotiations that are scheduled
                   3264:  * for inflight SCBs that have not been started yet.
                   3265:  */
                   3266: static void
                   3267: ahd_update_pending_scbs(struct ahd_softc *ahd)
                   3268: {
                   3269:        struct          scb *pending_scb;
                   3270:        int             pending_scb_count;
1.20      thorpej  3271:        u_int           scb_tag;
1.1       fvdl     3272:        int             paused;
                   3273:        u_int           saved_scbptr;
                   3274:        ahd_mode_state  saved_modes;
                   3275:
                   3276:        /*
                   3277:         * Traverse the pending SCB list and ensure that all of the
                   3278:         * SCBs there have the proper settings.  We can only safely
                   3279:         * clear the negotiation required flag (setting requires the
                   3280:         * execution queue to be modified) and this is only possible
                   3281:         * if we are not already attempting to select out for this
                   3282:         * SCB.  For this reason, all callers only call this routine
                   3283:         * if we are changing the negotiation settings for the currently
                   3284:         * active transaction on the bus.
                   3285:         */
                   3286:        pending_scb_count = 0;
                   3287:        LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
                   3288:                struct ahd_devinfo devinfo;
                   3289:                struct hardware_scb *pending_hscb;
                   3290:                struct ahd_tmode_tstate *tstate;
                   3291:
                   3292:                ahd_scb_devinfo(ahd, &devinfo, pending_scb);
1.46      christos 3293:                (void)ahd_fetch_transinfo(ahd, devinfo.channel,
                   3294:                                          devinfo.our_scsiid,
                   3295:                                          devinfo.target, &tstate);
1.1       fvdl     3296:                pending_hscb = pending_scb->hscb;
                   3297:                if ((tstate->auto_negotiate & devinfo.target_mask) == 0
                   3298:                 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
                   3299:                        pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
                   3300:                        pending_hscb->control &= ~MK_MESSAGE;
                   3301:                }
                   3302:                ahd_sync_scb(ahd, pending_scb,
                   3303:                             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   3304:                pending_scb_count++;
                   3305:        }
                   3306:
                   3307:        if (pending_scb_count == 0)
                   3308:                return;
                   3309:
                   3310:        if (ahd_is_paused(ahd)) {
                   3311:                paused = 1;
                   3312:        } else {
                   3313:                paused = 0;
                   3314:                ahd_pause(ahd);
                   3315:        }
                   3316:
                   3317:        /*
                   3318:         * Force the sequencer to reinitialize the selection for
                   3319:         * the command at the head of the execution queue if it
                   3320:         * has already been setup.  The negotiation changes may
                   3321:         * effect whether we select-out with ATN.
                   3322:         */
                   3323:        saved_modes = ahd_save_modes(ahd);
                   3324:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   3325:        ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
                   3326:        saved_scbptr = ahd_get_scbptr(ahd);
                   3327:        /* Ensure that the hscbs down on the card match the new information */
1.20      thorpej  3328:        for (scb_tag = 0; scb_tag < ahd->scb_data.maxhscbs; scb_tag++) {
1.1       fvdl     3329:                struct  hardware_scb *pending_hscb;
                   3330:                u_int   control;
                   3331:
                   3332:                pending_scb = ahd_lookup_scb(ahd, scb_tag);
                   3333:                if (pending_scb == NULL)
                   3334:                        continue;
1.20      thorpej  3335:                ahd_set_scbptr(ahd, scb_tag);
1.1       fvdl     3336:                pending_hscb = pending_scb->hscb;
                   3337:                control = ahd_inb_scbram(ahd, SCB_CONTROL);
                   3338:                control &= ~MK_MESSAGE;
                   3339:                control |= pending_hscb->control & MK_MESSAGE;
                   3340:                ahd_outb(ahd, SCB_CONTROL, control);
                   3341:        }
                   3342:        ahd_set_scbptr(ahd, saved_scbptr);
                   3343:        ahd_restore_modes(ahd, saved_modes);
                   3344:
                   3345:        if (paused == 0)
                   3346:                ahd_unpause(ahd);
                   3347: }
                   3348:
                   3349: /**************************** Pathing Information *****************************/
                   3350: static void
                   3351: ahd_fetch_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
                   3352: {
                   3353:        ahd_mode_state  saved_modes;
                   3354:        u_int           saved_scsiid;
                   3355:        role_t          role;
                   3356:        int             our_id;
                   3357:
                   3358:        saved_modes = ahd_save_modes(ahd);
                   3359:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   3360:
                   3361:        if (ahd_inb(ahd, SSTAT0) & TARGET)
                   3362:                role = ROLE_TARGET;
                   3363:        else
                   3364:                role = ROLE_INITIATOR;
                   3365:
                   3366:        if (role == ROLE_TARGET
                   3367:         && (ahd_inb(ahd, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) {
                   3368:                /* We were selected, so pull our id from TARGIDIN */
                   3369:                our_id = ahd_inb(ahd, TARGIDIN) & OID;
                   3370:        } else if (role == ROLE_TARGET)
                   3371:                our_id = ahd_inb(ahd, TOWNID);
                   3372:        else
                   3373:                our_id = ahd_inb(ahd, IOWNID);
                   3374:
                   3375:        saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
                   3376:        ahd_compile_devinfo(devinfo,
                   3377:                            our_id,
                   3378:                            SCSIID_TARGET(ahd, saved_scsiid),
                   3379:                            ahd_inb(ahd, SAVED_LUN),
                   3380:                            SCSIID_CHANNEL(ahd, saved_scsiid),
                   3381:                            role);
                   3382:        ahd_restore_modes(ahd, saved_modes);
                   3383: }
                   3384:
                   3385: void
                   3386: ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
                   3387: {
                   3388:        printf("%s:%c:%d:%d: (0x%x) ", ahd_name(ahd), 'A',
                   3389:               devinfo->target, devinfo->lun, ahd_get_scbptr(ahd));
                   3390: }
                   3391:
                   3392: struct ahd_phase_table_entry*
                   3393: ahd_lookup_phase_entry(int phase)
                   3394: {
                   3395:        struct ahd_phase_table_entry *entry;
                   3396:        struct ahd_phase_table_entry *last_entry;
                   3397:
                   3398:        /*
                   3399:         * num_phases doesn't include the default entry which
                   3400:         * will be returned if the phase doesn't match.
                   3401:         */
                   3402:        last_entry = &ahd_phase_table[num_phases];
                   3403:        for (entry = ahd_phase_table; entry < last_entry; entry++) {
                   3404:                if (phase == entry->phase)
                   3405:                        break;
                   3406:        }
                   3407:        return (entry);
                   3408: }
                   3409:
                   3410: void
                   3411: ahd_compile_devinfo(struct ahd_devinfo *devinfo, u_int our_id, u_int target,
                   3412:                    u_int lun, char channel, role_t role)
                   3413: {
                   3414:        devinfo->our_scsiid = our_id;
                   3415:        devinfo->target = target;
                   3416:        devinfo->lun = lun;
                   3417:        devinfo->target_offset = target;
                   3418:        devinfo->channel = channel;
                   3419:        devinfo->role = role;
                   3420:        if (channel == 'B')
                   3421:                devinfo->target_offset += 8;
                   3422:        devinfo->target_mask = (0x01 << devinfo->target_offset);
                   3423: }
                   3424:
                   3425: static void
1.36      christos 3426: ahd_scb_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
1.1       fvdl     3427:                struct scb *scb)
                   3428: {
                   3429:        role_t  role;
                   3430:        int     our_id;
                   3431:
                   3432:        our_id = SCSIID_OUR_ID(scb->hscb->scsiid);
                   3433:        role = ROLE_INITIATOR;
                   3434:        if ((scb->hscb->control & TARGET_SCB) != 0)
                   3435:                role = ROLE_TARGET;
                   3436:        ahd_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahd, scb),
                   3437:                            SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahd, scb), role);
                   3438: }
                   3439:
                   3440:
                   3441: /************************ Message Phase Processing ****************************/
                   3442: /*
                   3443:  * When an initiator transaction with the MK_MESSAGE flag either reconnects
                   3444:  * or enters the initial message out phase, we are interrupted.  Fill our
1.26      wiz      3445:  * outgoing message buffer with the appropriate message and begin handing
1.1       fvdl     3446:  * the message phase(s) manually.
                   3447:  */
                   3448: static void
                   3449: ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
                   3450:                           struct scb *scb)
                   3451: {
                   3452:        /*
                   3453:         * To facilitate adding multiple messages together,
                   3454:         * each routine should increment the index and len
                   3455:         * variables instead of setting them explicitly.
                   3456:         */
                   3457:        ahd->msgout_index = 0;
                   3458:        ahd->msgout_len = 0;
                   3459:
                   3460:        if (ahd_currently_packetized(ahd))
                   3461:                ahd->msg_flags |= MSG_FLAG_PACKETIZED;
                   3462:
                   3463:        if (ahd->send_msg_perror
                   3464:         && ahd_inb(ahd, MSG_OUT) == HOST_MSG) {
                   3465:                ahd->msgout_buf[ahd->msgout_index++] = ahd->send_msg_perror;
                   3466:                ahd->msgout_len++;
                   3467:                ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
                   3468: #ifdef AHD_DEBUG
                   3469:                if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
                   3470:                        printf("Setting up for Parity Error delivery\n");
                   3471: #endif
                   3472:                return;
                   3473:        } else if (scb == NULL) {
                   3474:                printf("%s: WARNING. No pending message for "
                   3475:                       "I_T msgin.  Issuing NO-OP\n", ahd_name(ahd));
                   3476:                ahd->msgout_buf[ahd->msgout_index++] = MSG_NOOP;
                   3477:                ahd->msgout_len++;
                   3478:                ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
                   3479:                return;
                   3480:        }
                   3481:
                   3482:        if ((scb->flags & SCB_DEVICE_RESET) == 0
                   3483:         && (scb->flags & SCB_PACKETIZED) == 0
                   3484:         && ahd_inb(ahd, MSG_OUT) == MSG_IDENTIFYFLAG) {
                   3485:                u_int identify_msg;
                   3486:
                   3487:                identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);
                   3488:                if ((scb->hscb->control & DISCENB) != 0)
                   3489:                        identify_msg |= MSG_IDENTIFY_DISCFLAG;
                   3490:                ahd->msgout_buf[ahd->msgout_index++] = identify_msg;
                   3491:                ahd->msgout_len++;
                   3492:
                   3493:                if ((scb->hscb->control & TAG_ENB) != 0) {
                   3494:                        ahd->msgout_buf[ahd->msgout_index++] =
                   3495:                            scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);
                   3496:                        ahd->msgout_buf[ahd->msgout_index++] = SCB_GET_TAG(scb);
                   3497:                        ahd->msgout_len += 2;
                   3498:                }
                   3499:        }
                   3500:
                   3501:        if (scb->flags & SCB_DEVICE_RESET) {
                   3502:                ahd->msgout_buf[ahd->msgout_index++] = MSG_BUS_DEV_RESET;
                   3503:                ahd->msgout_len++;
                   3504:                ahd_print_path(ahd, scb);
                   3505:                printf("Bus Device Reset Message Sent\n");
                   3506:                /*
                   3507:                 * Clear our selection hardware in advance of
                   3508:                 * the busfree.  We may have an entry in the waiting
                   3509:                 * Q for this target, and we don't want to go about
                   3510:                 * selecting while we handle the busfree and blow it
                   3511:                 * away.
                   3512:                 */
                   3513:                ahd_outb(ahd, SCSISEQ0, 0);
                   3514:        } else if ((scb->flags & SCB_ABORT) != 0) {
                   3515:
                   3516:                if ((scb->hscb->control & TAG_ENB) != 0) {
                   3517:                        ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT_TAG;
                   3518:                } else {
                   3519:                        ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT;
                   3520:                }
                   3521:                ahd->msgout_len++;
                   3522:                ahd_print_path(ahd, scb);
                   3523:                printf("Abort%s Message Sent\n",
                   3524:                       (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
                   3525:                /*
                   3526:                 * Clear our selection hardware in advance of
                   3527:                 * the busfree.  We may have an entry in the waiting
                   3528:                 * Q for this target, and we don't want to go about
                   3529:                 * selecting while we handle the busfree and blow it
                   3530:                 * away.
                   3531:                 */
                   3532:                ahd_outb(ahd, SCSISEQ0, 0);
                   3533:        } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
                   3534:                ahd_build_transfer_msg(ahd, devinfo);
                   3535:                /*
                   3536:                 * Clear our selection hardware in advance of potential
                   3537:                 * PPR IU status change busfree.  We may have an entry in
                   3538:                 * the waiting Q for this target, and we don't want to go
                   3539:                 * about selecting while we handle the busfree and blow
                   3540:                 * it away.
                   3541:                 */
                   3542:                ahd_outb(ahd, SCSISEQ0, 0);
                   3543:        } else {
                   3544:                printf("ahd_intr: AWAITING_MSG for an SCB that "
                   3545:                       "does not have a waiting message\n");
                   3546:                printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
                   3547:                       devinfo->target_mask);
                   3548:                panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x "
                   3549:                      "SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control,
1.21      thorpej  3550:                      ahd_inb_scbram(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT),
1.1       fvdl     3551:                      scb->flags);
                   3552:        }
                   3553:
                   3554:        /*
                   3555:         * Clear the MK_MESSAGE flag from the SCB so we aren't
                   3556:         * asked to send this message again.
                   3557:         */
                   3558:        ahd_outb(ahd, SCB_CONTROL,
                   3559:                 ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE);
                   3560:        scb->hscb->control &= ~MK_MESSAGE;
                   3561:        ahd->msgout_index = 0;
                   3562:        ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
                   3563: }
                   3564:
                   3565: /*
                   3566:  * Build an appropriate transfer negotiation message for the
                   3567:  * currently active target.
                   3568:  */
                   3569: static void
                   3570: ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
                   3571: {
                   3572:        /*
                   3573:         * We need to initiate transfer negotiations.
                   3574:         * If our current and goal settings are identical,
                   3575:         * we want to renegotiate due to a check condition.
                   3576:         */
                   3577:        struct  ahd_initiator_tinfo *tinfo;
                   3578:        struct  ahd_tmode_tstate *tstate;
                   3579:        int     dowide;
                   3580:        int     dosync;
                   3581:        int     doppr;
                   3582:        u_int   period;
                   3583:        u_int   ppr_options;
                   3584:        u_int   offset;
                   3585:
                   3586:        tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
                   3587:                                    devinfo->target, &tstate);
                   3588:        /*
                   3589:         * Filter our period based on the current connection.
                   3590:         * If we can't perform DT transfers on this segment (not in LVD
                   3591:         * mode for instance), then our decision to issue a PPR message
                   3592:         * may change.
                   3593:         */
                   3594:        period = tinfo->goal.period;
1.16      thorpej  3595:        offset = tinfo->goal.offset;
1.1       fvdl     3596:        ppr_options = tinfo->goal.ppr_options;
                   3597:        /* Target initiated PPR is not allowed in the SCSI spec */
                   3598:        if (devinfo->role == ROLE_TARGET)
                   3599:                ppr_options = 0;
                   3600:        ahd_devlimited_syncrate(ahd, tinfo, &period,
                   3601:                                &ppr_options, devinfo->role);
                   3602:        dowide = tinfo->curr.width != tinfo->goal.width;
1.16      thorpej  3603:        dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
1.1       fvdl     3604:        /*
                   3605:         * Only use PPR if we have options that need it, even if the device
                   3606:         * claims to support it.  There might be an expander in the way
                   3607:         * that doesn't.
                   3608:         */
                   3609:        doppr = ppr_options != 0;
                   3610:
                   3611:        if (!dowide && !dosync && !doppr) {
                   3612:                dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
1.16      thorpej  3613:                dosync = tinfo->goal.offset != 0;
1.1       fvdl     3614:        }
                   3615:
                   3616:        if (!dowide && !dosync && !doppr) {
                   3617:                /*
                   3618:                 * Force async with a WDTR message if we have a wide bus,
                   3619:                 * or just issue an SDTR with a 0 offset.
                   3620:                 */
                   3621:                if ((ahd->features & AHD_WIDE) != 0)
                   3622:                        dowide = 1;
                   3623:                else
                   3624:                        dosync = 1;
                   3625:
                   3626:                if (bootverbose) {
                   3627:                        ahd_print_devinfo(ahd, devinfo);
                   3628:                        printf("Ensuring async\n");
                   3629:                }
                   3630:        }
                   3631:        /* Target initiated PPR is not allowed in the SCSI spec */
                   3632:        if (devinfo->role == ROLE_TARGET)
                   3633:                doppr = 0;
                   3634:
                   3635:        /*
                   3636:         * Both the PPR message and SDTR message require the
                   3637:         * goal syncrate to be limited to what the target device
                   3638:         * is capable of handling (based on whether an LVD->SE
                   3639:         * expander is on the bus), so combine these two cases.
                   3640:         * Regardless, guarantee that if we are using WDTR and SDTR
                   3641:         * messages that WDTR comes first.
                   3642:         */
                   3643:        if (doppr || (dosync && !dowide)) {
                   3644:
                   3645:                offset = tinfo->goal.offset;
                   3646:                ahd_validate_offset(ahd, tinfo, period, &offset,
                   3647:                                    doppr ? tinfo->goal.width
                   3648:                                          : tinfo->curr.width,
                   3649:                                    devinfo->role);
                   3650:                if (doppr) {
                   3651:                        ahd_construct_ppr(ahd, devinfo, period, offset,
                   3652:                                          tinfo->goal.width, ppr_options);
                   3653:                } else {
                   3654:                        ahd_construct_sdtr(ahd, devinfo, period, offset);
                   3655:                }
                   3656:        } else {
                   3657:                ahd_construct_wdtr(ahd, devinfo, tinfo->goal.width);
                   3658:        }
                   3659: }
                   3660:
                   3661: /*
                   3662:  * Build a synchronous negotiation message in our message
                   3663:  * buffer based on the input parameters.
                   3664:  */
                   3665: static void
                   3666: ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
                   3667:                   u_int period, u_int offset)
                   3668: {
                   3669:        if (offset == 0)
                   3670:                period = AHD_ASYNC_XFER_PERIOD;
                   3671:        ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
                   3672:        ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR_LEN;
                   3673:        ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR;
                   3674:        ahd->msgout_buf[ahd->msgout_index++] = period;
                   3675:        ahd->msgout_buf[ahd->msgout_index++] = offset;
                   3676:        ahd->msgout_len += 5;
                   3677:        if (bootverbose) {
                   3678:                printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
                   3679:                       ahd_name(ahd), devinfo->channel, devinfo->target,
                   3680:                       devinfo->lun, period, offset);
                   3681:        }
                   3682: }
                   3683:
                   3684: /*
1.26      wiz      3685:  * Build a wide negotiation message in our message
1.1       fvdl     3686:  * buffer based on the input parameters.
                   3687:  */
                   3688: static void
                   3689: ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
                   3690:                   u_int bus_width)
                   3691: {
                   3692:        ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
                   3693:        ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR_LEN;
                   3694:        ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR;
                   3695:        ahd->msgout_buf[ahd->msgout_index++] = bus_width;
                   3696:        ahd->msgout_len += 4;
                   3697:        if (bootverbose) {
                   3698:                printf("(%s:%c:%d:%d): Sending WDTR %x\n",
                   3699:                       ahd_name(ahd), devinfo->channel, devinfo->target,
                   3700:                       devinfo->lun, bus_width);
                   3701:        }
                   3702: }
                   3703:
                   3704: /*
                   3705:  * Build a parallel protocol request message in our message
                   3706:  * buffer based on the input parameters.
                   3707:  */
                   3708: static void
                   3709: ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
                   3710:                  u_int period, u_int offset, u_int bus_width,
                   3711:                  u_int ppr_options)
                   3712: {
                   3713:        /*
                   3714:         * Always request precompensation from
                   3715:         * the other target if we are running
                   3716:         * at paced syncrates.
                   3717:         */
                   3718:        if (period <= AHD_SYNCRATE_PACED)
                   3719:                ppr_options |= MSG_EXT_PPR_PCOMP_EN;
                   3720:        if (offset == 0)
                   3721:                period = AHD_ASYNC_XFER_PERIOD;
                   3722:        ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
                   3723:        ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR_LEN;
                   3724:        ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR;
                   3725:        ahd->msgout_buf[ahd->msgout_index++] = period;
                   3726:        ahd->msgout_buf[ahd->msgout_index++] = 0;
                   3727:        ahd->msgout_buf[ahd->msgout_index++] = offset;
                   3728:        ahd->msgout_buf[ahd->msgout_index++] = bus_width;
                   3729:        ahd->msgout_buf[ahd->msgout_index++] = ppr_options;
                   3730:        ahd->msgout_len += 8;
                   3731:        if (bootverbose) {
                   3732:                printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period 0x%x, "
                   3733:                       "offset 0x%x, ppr_options 0x%x\n", ahd_name(ahd),
                   3734:                       devinfo->channel, devinfo->target, devinfo->lun,
                   3735:                       bus_width, period, offset, ppr_options);
                   3736:        }
                   3737: }
                   3738:
                   3739: /*
                   3740:  * Clear any active message state.
                   3741:  */
                   3742: static void
                   3743: ahd_clear_msg_state(struct ahd_softc *ahd)
                   3744: {
                   3745:        ahd_mode_state saved_modes;
                   3746:
                   3747:        saved_modes = ahd_save_modes(ahd);
                   3748:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   3749:        ahd->send_msg_perror = 0;
                   3750:        ahd->msg_flags = MSG_FLAG_NONE;
                   3751:        ahd->msgout_len = 0;
                   3752:        ahd->msgin_index = 0;
                   3753:        ahd->msg_type = MSG_TYPE_NONE;
                   3754:        if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0) {
                   3755:                /*
                   3756:                 * The target didn't care to respond to our
                   3757:                 * message request, so clear ATN.
                   3758:                 */
                   3759:                ahd_outb(ahd, CLRSINT1, CLRATNO);
                   3760:        }
                   3761:        ahd_outb(ahd, MSG_OUT, MSG_NOOP);
                   3762:        ahd_outb(ahd, SEQ_FLAGS2,
                   3763:                 ahd_inb(ahd, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
                   3764:        ahd_restore_modes(ahd, saved_modes);
                   3765: }
                   3766:
                   3767: /*
                   3768:  * Manual message loop handler.
                   3769:  */
                   3770: static void
                   3771: ahd_handle_message_phase(struct ahd_softc *ahd)
1.30      perry    3772: {
1.1       fvdl     3773:        struct  ahd_devinfo devinfo;
                   3774:        u_int   bus_phase;
                   3775:        int     end_session;
                   3776:
                   3777:        ahd_fetch_devinfo(ahd, &devinfo);
                   3778:        end_session = FALSE;
                   3779:        bus_phase = ahd_inb(ahd, LASTPHASE);
                   3780:
                   3781:        if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0) {
                   3782:                printf("LQIRETRY for LQIPHASE_OUTPKT\n");
                   3783:                ahd_outb(ahd, LQCTL2, LQIRETRY);
                   3784:        }
                   3785: reswitch:
                   3786:        switch (ahd->msg_type) {
                   3787:        case MSG_TYPE_INITIATOR_MSGOUT:
                   3788:        {
                   3789:                int lastbyte;
                   3790:                int phasemis;
                   3791:                int msgdone;
                   3792:
                   3793:                if (ahd->msgout_len == 0 && ahd->send_msg_perror == 0)
                   3794:                        panic("HOST_MSG_LOOP interrupt with no active message");
                   3795:
                   3796: #ifdef AHD_DEBUG
                   3797:                if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
                   3798:                        ahd_print_devinfo(ahd, &devinfo);
                   3799:                        printf("INITIATOR_MSG_OUT");
                   3800:                }
                   3801: #endif
                   3802:                phasemis = bus_phase != P_MESGOUT;
                   3803:                if (phasemis) {
                   3804: #ifdef AHD_DEBUG
                   3805:                        if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
                   3806:                                printf(" PHASEMIS %s\n",
                   3807:                                       ahd_lookup_phase_entry(bus_phase)
                   3808:                                                             ->phasemsg);
                   3809:                        }
                   3810: #endif
                   3811:                        if (bus_phase == P_MESGIN) {
                   3812:                                /*
                   3813:                                 * Change gears and see if
                   3814:                                 * this messages is of interest to
                   3815:                                 * us or should be passed back to
                   3816:                                 * the sequencer.
                   3817:                                 */
                   3818:                                ahd_outb(ahd, CLRSINT1, CLRATNO);
                   3819:                                ahd->send_msg_perror = 0;
                   3820:                                ahd->msg_type = MSG_TYPE_INITIATOR_MSGIN;
                   3821:                                ahd->msgin_index = 0;
                   3822:                                goto reswitch;
                   3823:                        }
                   3824:                        end_session = TRUE;
                   3825:                        break;
                   3826:                }
                   3827:
                   3828:                if (ahd->send_msg_perror) {
                   3829:                        ahd_outb(ahd, CLRSINT1, CLRATNO);
                   3830:                        ahd_outb(ahd, CLRSINT1, CLRREQINIT);
                   3831: #ifdef AHD_DEBUG
                   3832:                        if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
                   3833:                                printf(" byte 0x%x\n", ahd->send_msg_perror);
                   3834: #endif
                   3835:                        /*
                   3836:                         * If we are notifying the target of a CRC error
                   3837:                         * during packetized operations, the target is
                   3838:                         * within its rights to acknowledge our message
                   3839:                         * with a busfree.
                   3840:                         */
                   3841:                        if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0
                   3842:                         && ahd->send_msg_perror == MSG_INITIATOR_DET_ERR)
                   3843:                                ahd->msg_flags |= MSG_FLAG_EXPECT_IDE_BUSFREE;
                   3844:
                   3845:                        ahd_outb(ahd, RETURN_2, ahd->send_msg_perror);
                   3846:                        ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE);
                   3847:                        break;
                   3848:                }
                   3849:
                   3850:                msgdone = ahd->msgout_index == ahd->msgout_len;
                   3851:                if (msgdone) {
                   3852:                        /*
                   3853:                         * The target has requested a retry.
                   3854:                         * Re-assert ATN, reset our message index to
                   3855:                         * 0, and try again.
                   3856:                         */
                   3857:                        ahd->msgout_index = 0;
                   3858:                        ahd_assert_atn(ahd);
                   3859:                }
                   3860:
                   3861:                lastbyte = ahd->msgout_index == (ahd->msgout_len - 1);
                   3862:                if (lastbyte) {
                   3863:                        /* Last byte is signified by dropping ATN */
                   3864:                        ahd_outb(ahd, CLRSINT1, CLRATNO);
                   3865:                }
                   3866:
                   3867:                /*
                   3868:                 * Clear our interrupt status and present
                   3869:                 * the next byte on the bus.
                   3870:                 */
                   3871:                ahd_outb(ahd, CLRSINT1, CLRREQINIT);
                   3872: #ifdef AHD_DEBUG
                   3873:                if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
                   3874:                        printf(" byte 0x%x\n",
                   3875:                               ahd->msgout_buf[ahd->msgout_index]);
                   3876: #endif
                   3877:                ahd_outb(ahd, RETURN_2, ahd->msgout_buf[ahd->msgout_index++]);
                   3878:                ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE);
                   3879:                break;
                   3880:        }
                   3881:        case MSG_TYPE_INITIATOR_MSGIN:
                   3882:        {
                   3883:                int phasemis;
                   3884:                int message_done;
                   3885:
                   3886: #ifdef AHD_DEBUG
                   3887:                if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
                   3888:                        ahd_print_devinfo(ahd, &devinfo);
                   3889:                        printf("INITIATOR_MSG_IN");
                   3890:                }
                   3891: #endif
                   3892:                phasemis = bus_phase != P_MESGIN;
                   3893:                if (phasemis) {
                   3894: #ifdef AHD_DEBUG
                   3895:                        if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
                   3896:                                printf(" PHASEMIS %s\n",
                   3897:                                       ahd_lookup_phase_entry(bus_phase)
                   3898:                                                             ->phasemsg);
                   3899:                        }
                   3900: #endif
                   3901:                        ahd->msgin_index = 0;
                   3902:                        if (bus_phase == P_MESGOUT
                   3903:                         && (ahd->send_msg_perror != 0
                   3904:                          || (ahd->msgout_len != 0
                   3905:                           && ahd->msgout_index == 0))) {
                   3906:                                ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
                   3907:                                goto reswitch;
                   3908:                        }
                   3909:                        end_session = TRUE;
                   3910:                        break;
                   3911:                }
                   3912:
                   3913:                /* Pull the byte in without acking it */
                   3914:                ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIBUS);
                   3915: #ifdef AHD_DEBUG
                   3916:                if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
                   3917:                        printf(" byte 0x%x\n",
                   3918:                               ahd->msgin_buf[ahd->msgin_index]);
                   3919: #endif
                   3920:
                   3921:                message_done = ahd_parse_msg(ahd, &devinfo);
                   3922:
                   3923:                if (message_done) {
                   3924:                        /*
                   3925:                         * Clear our incoming message buffer in case there
                   3926:                         * is another message following this one.
                   3927:                         */
                   3928:                        ahd->msgin_index = 0;
                   3929:
                   3930:                        /*
                   3931:                         * If this message illicited a response,
                   3932:                         * assert ATN so the target takes us to the
                   3933:                         * message out phase.
                   3934:                         */
                   3935:                        if (ahd->msgout_len != 0) {
                   3936: #ifdef AHD_DEBUG
                   3937:                                if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
                   3938:                                        ahd_print_devinfo(ahd, &devinfo);
                   3939:                                        printf("Asserting ATN for response\n");
                   3940:                                }
                   3941: #endif
                   3942:                                ahd_assert_atn(ahd);
                   3943:                        }
1.30      perry    3944:                } else
1.1       fvdl     3945:                        ahd->msgin_index++;
                   3946:
                   3947:                if (message_done == MSGLOOP_TERMINATED) {
                   3948:                        end_session = TRUE;
                   3949:                } else {
                   3950:                        /* Ack the byte */
                   3951:                        ahd_outb(ahd, CLRSINT1, CLRREQINIT);
                   3952:                        ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_READ);
                   3953:                }
                   3954:                break;
                   3955:        }
                   3956:        case MSG_TYPE_TARGET_MSGIN:
                   3957:        {
                   3958:                int msgdone;
                   3959:                int msgout_request;
                   3960:
                   3961:                /*
                   3962:                 * By default, the message loop will continue.
                   3963:                 */
                   3964:                ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG);
                   3965:
                   3966:                if (ahd->msgout_len == 0)
                   3967:                        panic("Target MSGIN with no active message");
                   3968:
                   3969:                /*
                   3970:                 * If we interrupted a mesgout session, the initiator
                   3971:                 * will not know this until our first REQ.  So, we
                   3972:                 * only honor mesgout requests after we've sent our
                   3973:                 * first byte.
                   3974:                 */
                   3975:                if ((ahd_inb(ahd, SCSISIGI) & ATNI) != 0
                   3976:                 && ahd->msgout_index > 0)
                   3977:                        msgout_request = TRUE;
                   3978:                else
                   3979:                        msgout_request = FALSE;
                   3980:
                   3981:                if (msgout_request) {
                   3982:
                   3983:                        /*
                   3984:                         * Change gears and see if
                   3985:                         * this messages is of interest to
                   3986:                         * us or should be passed back to
                   3987:                         * the sequencer.
                   3988:                         */
                   3989:                        ahd->msg_type = MSG_TYPE_TARGET_MSGOUT;
                   3990:                        ahd_outb(ahd, SCSISIGO, P_MESGOUT | BSYO);
                   3991:                        ahd->msgin_index = 0;
                   3992:                        /* Dummy read to REQ for first byte */
                   3993:                        ahd_inb(ahd, SCSIDAT);
                   3994:                        ahd_outb(ahd, SXFRCTL0,
                   3995:                                 ahd_inb(ahd, SXFRCTL0) | SPIOEN);
                   3996:                        break;
                   3997:                }
                   3998:
                   3999:                msgdone = ahd->msgout_index == ahd->msgout_len;
                   4000:                if (msgdone) {
                   4001:                        ahd_outb(ahd, SXFRCTL0,
                   4002:                                 ahd_inb(ahd, SXFRCTL0) & ~SPIOEN);
                   4003:                        end_session = TRUE;
                   4004:                        break;
                   4005:                }
                   4006:
                   4007:                /*
                   4008:                 * Present the next byte on the bus.
                   4009:                 */
                   4010:                ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) | SPIOEN);
                   4011:                ahd_outb(ahd, SCSIDAT, ahd->msgout_buf[ahd->msgout_index++]);
                   4012:                break;
                   4013:        }
                   4014:        case MSG_TYPE_TARGET_MSGOUT:
                   4015:        {
                   4016:                int lastbyte;
                   4017:                int msgdone;
                   4018:
                   4019:                /*
                   4020:                 * By default, the message loop will continue.
                   4021:                 */
                   4022:                ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG);
                   4023:
                   4024:                /*
                   4025:                 * The initiator signals that this is
                   4026:                 * the last byte by dropping ATN.
                   4027:                 */
                   4028:                lastbyte = (ahd_inb(ahd, SCSISIGI) & ATNI) == 0;
                   4029:
                   4030:                /*
                   4031:                 * Read the latched byte, but turn off SPIOEN first
                   4032:                 * so that we don't inadvertently cause a REQ for the
                   4033:                 * next byte.
                   4034:                 */
                   4035:                ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) & ~SPIOEN);
                   4036:                ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIDAT);
                   4037:                msgdone = ahd_parse_msg(ahd, &devinfo);
                   4038:                if (msgdone == MSGLOOP_TERMINATED) {
                   4039:                        /*
                   4040:                         * The message is *really* done in that it caused
                   4041:                         * us to go to bus free.  The sequencer has already
                   4042:                         * been reset at this point, so pull the ejection
                   4043:                         * handle.
                   4044:                         */
                   4045:                        return;
                   4046:                }
1.30      perry    4047:
1.1       fvdl     4048:                ahd->msgin_index++;
                   4049:
                   4050:                /*
                   4051:                 * XXX Read spec about initiator dropping ATN too soon
                   4052:                 *     and use msgdone to detect it.
                   4053:                 */
                   4054:                if (msgdone == MSGLOOP_MSGCOMPLETE) {
                   4055:                        ahd->msgin_index = 0;
                   4056:
                   4057:                        /*
                   4058:                         * If this message illicited a response, transition
                   4059:                         * to the Message in phase and send it.
                   4060:                         */
                   4061:                        if (ahd->msgout_len != 0) {
                   4062:                                ahd_outb(ahd, SCSISIGO, P_MESGIN | BSYO);
                   4063:                                ahd_outb(ahd, SXFRCTL0,
                   4064:                                         ahd_inb(ahd, SXFRCTL0) | SPIOEN);
                   4065:                                ahd->msg_type = MSG_TYPE_TARGET_MSGIN;
                   4066:                                ahd->msgin_index = 0;
                   4067:                                break;
                   4068:                        }
                   4069:                }
                   4070:
                   4071:                if (lastbyte)
                   4072:                        end_session = TRUE;
                   4073:                else {
                   4074:                        /* Ask for the next byte. */
                   4075:                        ahd_outb(ahd, SXFRCTL0,
                   4076:                                 ahd_inb(ahd, SXFRCTL0) | SPIOEN);
                   4077:                }
                   4078:
                   4079:                break;
                   4080:        }
                   4081:        default:
                   4082:                panic("Unknown REQINIT message type");
                   4083:        }
                   4084:
                   4085:        if (end_session) {
                   4086:                if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) {
                   4087:                        printf("%s: Returning to Idle Loop\n",
                   4088:                               ahd_name(ahd));
1.19      thorpej  4089:                        ahd_clear_msg_state(ahd);
                   4090:
                   4091:                        /*
                   4092:                         * Perform the equivalent of a clear_target_state.
                   4093:                         */
1.1       fvdl     4094:                        ahd_outb(ahd, LASTPHASE, P_BUSFREE);
1.19      thorpej  4095:                        ahd_outb(ahd, SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT);
1.1       fvdl     4096:                        ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
                   4097:                } else {
                   4098:                        ahd_clear_msg_state(ahd);
                   4099:                        ahd_outb(ahd, RETURN_1, EXIT_MSG_LOOP);
                   4100:                }
                   4101:        }
                   4102: }
                   4103:
                   4104: /*
                   4105:  * See if we sent a particular extended message to the target.
                   4106:  * If "full" is true, return true only if the target saw the full
                   4107:  * message.  If "full" is false, return true if the target saw at
                   4108:  * least the first byte of the message.
                   4109:  */
                   4110: static int
                   4111: ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, u_int msgval, int full)
                   4112: {
                   4113:        int found;
                   4114:        u_int index;
                   4115:
                   4116:        found = FALSE;
                   4117:        index = 0;
                   4118:
                   4119:        while (index < ahd->msgout_len) {
                   4120:                if (ahd->msgout_buf[index] == MSG_EXTENDED) {
                   4121:                        u_int end_index;
                   4122:
                   4123:                        end_index = index + 1 + ahd->msgout_buf[index + 1];
                   4124:                        if (ahd->msgout_buf[index+2] == msgval
                   4125:                         && type == AHDMSG_EXT) {
                   4126:
                   4127:                                if (full) {
                   4128:                                        if (ahd->msgout_index > end_index)
                   4129:                                                found = TRUE;
                   4130:                                } else if (ahd->msgout_index > index)
                   4131:                                        found = TRUE;
                   4132:                        }
                   4133:                        index = end_index;
                   4134:                } else if (ahd->msgout_buf[index] >= MSG_SIMPLE_TASK
                   4135:                        && ahd->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
                   4136:
                   4137:                        /* Skip tag type and tag id or residue param*/
                   4138:                        index += 2;
                   4139:                } else {
                   4140:                        /* Single byte message */
                   4141:                        if (type == AHDMSG_1B
                   4142:                         && ahd->msgout_index > index
                   4143:                         && (ahd->msgout_buf[index] == msgval
                   4144:                          || ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0
                   4145:                           && msgval == MSG_IDENTIFYFLAG)))
                   4146:                                found = TRUE;
                   4147:                        index++;
                   4148:                }
                   4149:
                   4150:                if (found)
                   4151:                        break;
                   4152:        }
                   4153:        return (found);
                   4154: }
                   4155:
                   4156: /*
                   4157:  * Wait for a complete incoming message, parse it, and respond accordingly.
                   4158:  */
                   4159: static int
                   4160: ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
                   4161: {
                   4162:        struct  ahd_initiator_tinfo *tinfo;
                   4163:        struct  ahd_tmode_tstate *tstate;
                   4164:        int     reject;
                   4165:        int     done;
                   4166:        int     response;
                   4167:
                   4168:        done = MSGLOOP_IN_PROG;
                   4169:        response = FALSE;
                   4170:        reject = FALSE;
                   4171:        tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
                   4172:                                    devinfo->target, &tstate);
                   4173:
                   4174:        /*
                   4175:         * Parse as much of the message as is available,
                   4176:         * rejecting it if we don't support it.  When
                   4177:         * the entire message is available and has been
                   4178:         * handled, return MSGLOOP_MSGCOMPLETE, indicating
                   4179:         * that we have parsed an entire message.
                   4180:         *
                   4181:         * In the case of extended messages, we accept the length
                   4182:         * byte outright and perform more checking once we know the
                   4183:         * extended message type.
                   4184:         */
                   4185:        switch (ahd->msgin_buf[0]) {
                   4186:        case MSG_DISCONNECT:
                   4187:        case MSG_SAVEDATAPOINTER:
                   4188:        case MSG_CMDCOMPLETE:
                   4189:        case MSG_RESTOREPOINTERS:
                   4190:        case MSG_IGN_WIDE_RESIDUE:
                   4191:                /*
                   4192:                 * End our message loop as these are messages
                   4193:                 * the sequencer handles on its own.
                   4194:                 */
                   4195:                done = MSGLOOP_TERMINATED;
                   4196:                break;
                   4197:        case MSG_MESSAGE_REJECT:
                   4198:                response = ahd_handle_msg_reject(ahd, devinfo);
                   4199:                /* FALLTHROUGH */
                   4200:        case MSG_NOOP:
                   4201:                done = MSGLOOP_MSGCOMPLETE;
                   4202:                break;
                   4203:        case MSG_EXTENDED:
                   4204:        {
                   4205:                /* Wait for enough of the message to begin validation */
                   4206:                if (ahd->msgin_index < 2)
                   4207:                        break;
                   4208:                switch (ahd->msgin_buf[2]) {
                   4209:                case MSG_EXT_SDTR:
                   4210:                {
                   4211:                        u_int    period;
                   4212:                        u_int    ppr_options;
                   4213:                        u_int    offset;
                   4214:                        u_int    saved_offset;
1.30      perry    4215:
1.1       fvdl     4216:                        if (ahd->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
                   4217:                                reject = TRUE;
                   4218:                                break;
                   4219:                        }
                   4220:
                   4221:                        /*
                   4222:                         * Wait until we have both args before validating
                   4223:                         * and acting on this message.
                   4224:                         *
                   4225:                         * Add one to MSG_EXT_SDTR_LEN to account for
                   4226:                         * the extended message preamble.
                   4227:                         */
                   4228:                        if (ahd->msgin_index < (MSG_EXT_SDTR_LEN + 1))
                   4229:                                break;
                   4230:
                   4231:                        period = ahd->msgin_buf[3];
                   4232:                        ppr_options = 0;
                   4233:                        saved_offset = offset = ahd->msgin_buf[4];
                   4234:                        ahd_devlimited_syncrate(ahd, tinfo, &period,
                   4235:                                                &ppr_options, devinfo->role);
                   4236:                        ahd_validate_offset(ahd, tinfo, period, &offset,
                   4237:                                            tinfo->curr.width, devinfo->role);
                   4238:                        if (bootverbose) {
                   4239:                                printf("(%s:%c:%d:%d): Received "
                   4240:                                       "SDTR period %x, offset %x\n\t"
                   4241:                                       "Filtered to period %x, offset %x\n",
                   4242:                                       ahd_name(ahd), devinfo->channel,
                   4243:                                       devinfo->target, devinfo->lun,
                   4244:                                       ahd->msgin_buf[3], saved_offset,
                   4245:                                       period, offset);
                   4246:                        }
                   4247:                        ahd_set_syncrate(ahd, devinfo, period,
                   4248:                                         offset, ppr_options,
                   4249:                                         AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
                   4250:                                         /*paused*/TRUE);
                   4251:
                   4252:                        /*
                   4253:                         * See if we initiated Sync Negotiation
                   4254:                         * and didn't have to fall down to async
                   4255:                         * transfers.
                   4256:                         */
                   4257:                        if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, TRUE)) {
                   4258:                                /* We started it */
                   4259:                                if (saved_offset != offset) {
                   4260:                                        /* Went too low - force async */
                   4261:                                        reject = TRUE;
                   4262:                                }
                   4263:                        } else {
                   4264:                                /*
                   4265:                                 * Send our own SDTR in reply
                   4266:                                 */
1.43      tsutsui  4267:                                if (bootverbose
1.1       fvdl     4268:                                 && devinfo->role == ROLE_INITIATOR) {
                   4269:                                        printf("(%s:%c:%d:%d): Target "
                   4270:                                               "Initiated SDTR\n",
                   4271:                                               ahd_name(ahd), devinfo->channel,
                   4272:                                               devinfo->target, devinfo->lun);
                   4273:                                }
                   4274:                                ahd->msgout_index = 0;
                   4275:                                ahd->msgout_len = 0;
                   4276:                                ahd_construct_sdtr(ahd, devinfo,
                   4277:                                                   period, offset);
                   4278:                                ahd->msgout_index = 0;
                   4279:                                response = TRUE;
                   4280:                        }
                   4281:                        done = MSGLOOP_MSGCOMPLETE;
                   4282:                        break;
                   4283:                }
                   4284:                case MSG_EXT_WDTR:
                   4285:                {
                   4286:                        u_int bus_width;
                   4287:                        u_int saved_width;
                   4288:                        u_int sending_reply;
                   4289:
                   4290:                        sending_reply = FALSE;
                   4291:                        if (ahd->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
                   4292:                                reject = TRUE;
                   4293:                                break;
                   4294:                        }
                   4295:
                   4296:                        /*
                   4297:                         * Wait until we have our arg before validating
                   4298:                         * and acting on this message.
                   4299:                         *
                   4300:                         * Add one to MSG_EXT_WDTR_LEN to account for
                   4301:                         * the extended message preamble.
                   4302:                         */
                   4303:                        if (ahd->msgin_index < (MSG_EXT_WDTR_LEN + 1))
                   4304:                                break;
                   4305:
                   4306:                        bus_width = ahd->msgin_buf[3];
                   4307:                        saved_width = bus_width;
                   4308:                        ahd_validate_width(ahd, tinfo, &bus_width,
                   4309:                                           devinfo->role);
                   4310:                        if (bootverbose) {
                   4311:                                printf("(%s:%c:%d:%d): Received WDTR "
                   4312:                                       "%x filtered to %x\n",
                   4313:                                       ahd_name(ahd), devinfo->channel,
                   4314:                                       devinfo->target, devinfo->lun,
                   4315:                                       saved_width, bus_width);
                   4316:                        }
                   4317:
                   4318:                        if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, TRUE)) {
                   4319:                                /*
                   4320:                                 * Don't send a WDTR back to the
                   4321:                                 * target, since we asked first.
                   4322:                                 * If the width went higher than our
                   4323:                                 * request, reject it.
                   4324:                                 */
                   4325:                                if (saved_width > bus_width) {
                   4326:                                        reject = TRUE;
                   4327:                                        printf("(%s:%c:%d:%d): requested %dBit "
                   4328:                                               "transfers.  Rejecting...\n",
                   4329:                                               ahd_name(ahd), devinfo->channel,
                   4330:                                               devinfo->target, devinfo->lun,
                   4331:                                               8 * (0x01 << bus_width));
                   4332:                                        bus_width = 0;
                   4333:                                }
                   4334:                        } else {
                   4335:                                /*
                   4336:                                 * Send our own WDTR in reply
                   4337:                                 */
                   4338:                                if (bootverbose
                   4339:                                 && devinfo->role == ROLE_INITIATOR) {
1.43      tsutsui  4340:                                        printf("(%s:%c:%d:%d): Target "
1.1       fvdl     4341:                                               "Initiated WDTR\n",
                   4342:                                               ahd_name(ahd), devinfo->channel,
                   4343:                                               devinfo->target, devinfo->lun);
                   4344:                                }
                   4345:                                ahd->msgout_index = 0;
                   4346:                                ahd->msgout_len = 0;
                   4347:                                ahd_construct_wdtr(ahd, devinfo, bus_width);
                   4348:                                ahd->msgout_index = 0;
                   4349:                                response = TRUE;
                   4350:                                sending_reply = TRUE;
                   4351:                        }
1.16      thorpej  4352:                        /*
                   4353:                         * After a wide message, we are async, but
                   4354:                         * some devices don't seem to honor this portion
                   4355:                         * of the spec.  Force a renegotiation of the
                   4356:                         * sync component of our transfer agreement even
                   4357:                         * if our goal is async.  By updating our width
                   4358:                         * after forcing the negotiation, we avoid
                   4359:                         * renegotiating for width.
                   4360:                         */
                   4361:                        ahd_update_neg_request(ahd, devinfo, tstate,
                   4362:                                               tinfo, AHD_NEG_ALWAYS);
1.1       fvdl     4363:                        ahd_set_width(ahd, devinfo, bus_width,
                   4364:                                      AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
                   4365:                                      /*paused*/TRUE);
                   4366:                        if (sending_reply == FALSE && reject == FALSE) {
                   4367:
1.16      thorpej  4368:                                /*
                   4369:                                 * We will always have an SDTR to send.
                   4370:                                 */
                   4371:                                ahd->msgout_index = 0;
                   4372:                                ahd->msgout_len = 0;
                   4373:                                ahd_build_transfer_msg(ahd, devinfo);
                   4374:                                ahd->msgout_index = 0;
                   4375:                                response = TRUE;
1.1       fvdl     4376:                        }
                   4377:                        done = MSGLOOP_MSGCOMPLETE;
                   4378:                        break;
                   4379:                }
                   4380:                case MSG_EXT_PPR:
                   4381:                {
                   4382:                        u_int   period;
                   4383:                        u_int   offset;
                   4384:                        u_int   bus_width;
                   4385:                        u_int   ppr_options;
                   4386:                        u_int   saved_width;
                   4387:                        u_int   saved_offset;
                   4388:                        u_int   saved_ppr_options;
                   4389:
                   4390:                        if (ahd->msgin_buf[1] != MSG_EXT_PPR_LEN) {
                   4391:                                reject = TRUE;
                   4392:                                break;
                   4393:                        }
                   4394:
                   4395:                        /*
                   4396:                         * Wait until we have all args before validating
                   4397:                         * and acting on this message.
                   4398:                         *
                   4399:                         * Add one to MSG_EXT_PPR_LEN to account for
                   4400:                         * the extended message preamble.
                   4401:                         */
                   4402:                        if (ahd->msgin_index < (MSG_EXT_PPR_LEN + 1))
                   4403:                                break;
                   4404:
                   4405:                        period = ahd->msgin_buf[3];
                   4406:                        offset = ahd->msgin_buf[5];
                   4407:                        bus_width = ahd->msgin_buf[6];
                   4408:                        saved_width = bus_width;
                   4409:                        ppr_options = ahd->msgin_buf[7];
                   4410:                        /*
                   4411:                         * According to the spec, a DT only
                   4412:                         * period factor with no DT option
                   4413:                         * set implies async.
                   4414:                         */
                   4415:                        if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0
                   4416:                         && period <= 9)
                   4417:                                offset = 0;
                   4418:                        saved_ppr_options = ppr_options;
                   4419:                        saved_offset = offset;
                   4420:
                   4421:                        /*
                   4422:                         * Transfer options are only available if we
                   4423:                         * are negotiating wide.
                   4424:                         */
                   4425:                        if (bus_width == 0)
                   4426:                                ppr_options &= MSG_EXT_PPR_QAS_REQ;
                   4427:
                   4428:                        ahd_validate_width(ahd, tinfo, &bus_width,
                   4429:                                           devinfo->role);
                   4430:                        ahd_devlimited_syncrate(ahd, tinfo, &period,
                   4431:                                                &ppr_options, devinfo->role);
                   4432:                        ahd_validate_offset(ahd, tinfo, period, &offset,
                   4433:                                            bus_width, devinfo->role);
                   4434:
                   4435:                        if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, TRUE)) {
                   4436:                                /*
                   4437:                                 * If we are unable to do any of the
                   4438:                                 * requested options (we went too low),
                   4439:                                 * then we'll have to reject the message.
                   4440:                                 */
                   4441:                                if (saved_width > bus_width
                   4442:                                 || saved_offset != offset
                   4443:                                 || saved_ppr_options != ppr_options) {
                   4444:                                        reject = TRUE;
                   4445:                                        period = 0;
                   4446:                                        offset = 0;
                   4447:                                        bus_width = 0;
                   4448:                                        ppr_options = 0;
                   4449:                                }
                   4450:                        } else {
                   4451:                                if (devinfo->role != ROLE_TARGET)
                   4452:                                        printf("(%s:%c:%d:%d): Target "
                   4453:                                               "Initiated PPR\n",
                   4454:                                               ahd_name(ahd), devinfo->channel,
                   4455:                                               devinfo->target, devinfo->lun);
                   4456:                                else
                   4457:                                        printf("(%s:%c:%d:%d): Initiator "
                   4458:                                               "Initiated PPR\n",
                   4459:                                               ahd_name(ahd), devinfo->channel,
                   4460:                                               devinfo->target, devinfo->lun);
                   4461:                                ahd->msgout_index = 0;
                   4462:                                ahd->msgout_len = 0;
                   4463:                                ahd_construct_ppr(ahd, devinfo, period, offset,
                   4464:                                                  bus_width, ppr_options);
                   4465:                                ahd->msgout_index = 0;
                   4466:                                response = TRUE;
                   4467:                        }
                   4468:                        if (bootverbose) {
                   4469:                                printf("(%s:%c:%d:%d): Received PPR width %x, "
                   4470:                                       "period %x, offset %x,options %x\n"
                   4471:                                       "\tFiltered to width %x, period %x, "
                   4472:                                       "offset %x, options %x\n",
                   4473:                                       ahd_name(ahd), devinfo->channel,
                   4474:                                       devinfo->target, devinfo->lun,
                   4475:                                       saved_width, ahd->msgin_buf[3],
                   4476:                                       saved_offset, saved_ppr_options,
                   4477:                                       bus_width, period, offset, ppr_options);
                   4478:                        }
                   4479:                        ahd_set_width(ahd, devinfo, bus_width,
                   4480:                                      AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
                   4481:                                      /*paused*/TRUE);
                   4482:                        ahd_set_syncrate(ahd, devinfo, period,
                   4483:                                         offset, ppr_options,
                   4484:                                         AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
                   4485:                                         /*paused*/TRUE);
                   4486:
                   4487:                        done = MSGLOOP_MSGCOMPLETE;
                   4488:                        break;
                   4489:                }
                   4490:                default:
                   4491:                        /* Unknown extended message.  Reject it. */
                   4492:                        reject = TRUE;
                   4493:                        break;
                   4494:                }
                   4495:                break;
                   4496:        }
                   4497: #ifdef AHD_TARGET_MODE
                   4498:        case MSG_BUS_DEV_RESET:
                   4499:                ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD,
                   4500:                                    CAM_BDR_SENT,
                   4501:                                    "Bus Device Reset Received",
                   4502:                                    /*verbose_level*/0);
                   4503:                ahd_restart(ahd);
                   4504:                done = MSGLOOP_TERMINATED;
                   4505:                break;
                   4506:        case MSG_ABORT_TAG:
                   4507:        case MSG_ABORT:
                   4508:        case MSG_CLEAR_QUEUE:
                   4509:        {
                   4510:                int tag;
                   4511:
                   4512:                /* Target mode messages */
                   4513:                if (devinfo->role != ROLE_TARGET) {
                   4514:                        reject = TRUE;
                   4515:                        break;
                   4516:                }
                   4517:                tag = SCB_LIST_NULL;
                   4518:                if (ahd->msgin_buf[0] == MSG_ABORT_TAG)
                   4519:                        tag = ahd_inb(ahd, INITIATOR_TAG);
                   4520:                ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
                   4521:                               devinfo->lun, tag, ROLE_TARGET,
                   4522:                               CAM_REQ_ABORTED);
                   4523:
                   4524:                tstate = ahd->enabled_targets[devinfo->our_scsiid];
                   4525:                if (tstate != NULL) {
                   4526:                        struct ahd_tmode_lstate* lstate;
                   4527:
                   4528:                        lstate = tstate->enabled_luns[devinfo->lun];
                   4529:                        if (lstate != NULL) {
                   4530:                                ahd_queue_lstate_event(ahd, lstate,
                   4531:                                                       devinfo->our_scsiid,
                   4532:                                                       ahd->msgin_buf[0],
                   4533:                                                       /*arg*/tag);
                   4534:                                ahd_send_lstate_events(ahd, lstate);
                   4535:                        }
                   4536:                }
                   4537:                ahd_restart(ahd);
                   4538:                done = MSGLOOP_TERMINATED;
                   4539:                break;
                   4540:        }
                   4541: #endif
                   4542:        case MSG_QAS_REQUEST:
                   4543: #ifdef AHD_DEBUG
                   4544:                if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
                   4545:                        printf("%s: QAS request.  SCSISIGI == 0x%x\n",
                   4546:                               ahd_name(ahd), ahd_inb(ahd, SCSISIGI));
                   4547: #endif
                   4548:                ahd->msg_flags |= MSG_FLAG_EXPECT_QASREJ_BUSFREE;
                   4549:                /* FALLTHROUGH */
                   4550:        case MSG_TERM_IO_PROC:
                   4551:        default:
                   4552:                reject = TRUE;
                   4553:                break;
                   4554:        }
                   4555:
                   4556:        if (reject) {
                   4557:                /*
                   4558:                 * Setup to reject the message.
                   4559:                 */
                   4560:                ahd->msgout_index = 0;
                   4561:                ahd->msgout_len = 1;
                   4562:                ahd->msgout_buf[0] = MSG_MESSAGE_REJECT;
                   4563:                done = MSGLOOP_MSGCOMPLETE;
                   4564:                response = TRUE;
                   4565:        }
                   4566:
                   4567:        if (done != MSGLOOP_IN_PROG && !response)
                   4568:                /* Clear the outgoing message buffer */
                   4569:                ahd->msgout_len = 0;
                   4570:
                   4571:        return (done);
                   4572: }
                   4573:
                   4574: /*
                   4575:  * Process a message reject message.
                   4576:  */
                   4577: static int
                   4578: ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
                   4579: {
                   4580:        /*
                   4581:         * What we care about here is if we had an
                   4582:         * outstanding SDTR or WDTR message for this
                   4583:         * target.  If we did, this is a signal that
                   4584:         * the target is refusing negotiation.
                   4585:         */
                   4586:        struct scb *scb;
                   4587:        struct ahd_initiator_tinfo *tinfo;
                   4588:        struct ahd_tmode_tstate *tstate;
                   4589:        u_int scb_index;
                   4590:        u_int last_msg;
                   4591:        int   response = 0;
                   4592:
                   4593:        scb_index = ahd_get_scbptr(ahd);
                   4594:        scb = ahd_lookup_scb(ahd, scb_index);
                   4595:        tinfo = ahd_fetch_transinfo(ahd, devinfo->channel,
                   4596:                                    devinfo->our_scsiid,
                   4597:                                    devinfo->target, &tstate);
                   4598:        /* Might be necessary */
                   4599:        last_msg = ahd_inb(ahd, LAST_MSG);
                   4600:
                   4601:        if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) {
                   4602:                if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/TRUE)
                   4603:                 && tinfo->goal.period <= AHD_SYNCRATE_PACED) {
                   4604:                        /*
                   4605:                         * Target may not like our SPI-4 PPR Options.
                   4606:                         * Attempt to negotiate 80MHz which will turn
                   4607:                         * off these options.
                   4608:                         */
1.43      tsutsui  4609:                        if (bootverbose) {
1.1       fvdl     4610:                                printf("(%s:%c:%d:%d): PPR Rejected. "
                   4611:                                       "Trying simple U160 PPR\n",
                   4612:                                       ahd_name(ahd), devinfo->channel,
                   4613:                                       devinfo->target, devinfo->lun);
                   4614:                        }
                   4615:                        tinfo->goal.period = AHD_SYNCRATE_DT;
                   4616:                        tinfo->goal.ppr_options &= MSG_EXT_PPR_IU_REQ
                   4617:                                                |  MSG_EXT_PPR_QAS_REQ
                   4618:                                                |  MSG_EXT_PPR_DT_REQ;
                   4619:                } else {
                   4620:                        /*
                   4621:                         * Target does not support the PPR message.
                   4622:                         * Attempt to negotiate SPI-2 style.
                   4623:                         */
1.43      tsutsui  4624:                        if (bootverbose) {
1.1       fvdl     4625:                                printf("(%s:%c:%d:%d): PPR Rejected. "
                   4626:                                       "Trying WDTR/SDTR\n",
                   4627:                                       ahd_name(ahd), devinfo->channel,
                   4628:                                       devinfo->target, devinfo->lun);
                   4629:                        }
                   4630:                        tinfo->goal.ppr_options = 0;
                   4631:                        tinfo->curr.transport_version = 2;
                   4632:                        tinfo->goal.transport_version = 2;
                   4633:                }
                   4634:                ahd->msgout_index = 0;
                   4635:                ahd->msgout_len = 0;
                   4636:                ahd_build_transfer_msg(ahd, devinfo);
                   4637:                ahd->msgout_index = 0;
                   4638:                response = 1;
                   4639:        } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) {
                   4640:
                   4641:                /* note 8bit xfers */
                   4642:                printf("(%s:%c:%d:%d): refuses WIDE negotiation.  Using "
                   4643:                       "8bit transfers\n", ahd_name(ahd),
                   4644:                       devinfo->channel, devinfo->target, devinfo->lun);
                   4645:                ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
                   4646:                              AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
                   4647:                              /*paused*/TRUE);
                   4648:                /*
                   4649:                 * No need to clear the sync rate.  If the target
                   4650:                 * did not accept the command, our syncrate is
                   4651:                 * unaffected.  If the target started the negotiation,
                   4652:                 * but rejected our response, we already cleared the
                   4653:                 * sync rate before sending our WDTR.
                   4654:                 */
                   4655:                if (tinfo->goal.offset != tinfo->curr.offset) {
                   4656:
                   4657:                        /* Start the sync negotiation */
                   4658:                        ahd->msgout_index = 0;
                   4659:                        ahd->msgout_len = 0;
                   4660:                        ahd_build_transfer_msg(ahd, devinfo);
                   4661:                        ahd->msgout_index = 0;
                   4662:                        response = 1;
                   4663:                }
                   4664:        } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) {
                   4665:                /* note asynch xfers and clear flag */
                   4666:                ahd_set_syncrate(ahd, devinfo, /*period*/0,
                   4667:                                 /*offset*/0, /*ppr_options*/0,
                   4668:                                 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
                   4669:                                 /*paused*/TRUE);
                   4670:                printf("(%s:%c:%d:%d): refuses synchronous negotiation. "
                   4671:                       "Using asynchronous transfers\n",
                   4672:                       ahd_name(ahd), devinfo->channel,
                   4673:                       devinfo->target, devinfo->lun);
                   4674:        } else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
                   4675:                int tag_type;
                   4676:                int mask;
                   4677:
                   4678:                tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
                   4679:
                   4680:                if (tag_type == MSG_SIMPLE_TASK) {
                   4681:                        printf("(%s:%c:%d:%d): refuses tagged commands.  "
                   4682:                               "Performing non-tagged I/O\n", ahd_name(ahd),
                   4683:                               devinfo->channel, devinfo->target, devinfo->lun);
                   4684:                        ahd_set_tags(ahd, devinfo, AHD_QUEUE_NONE);
                   4685:                        mask = ~0x23;
                   4686:                } else {
                   4687:                        printf("(%s:%c:%d:%d): refuses %s tagged commands.  "
                   4688:                               "Performing simple queue tagged I/O only\n",
                   4689:                               ahd_name(ahd), devinfo->channel, devinfo->target,
                   4690:                               devinfo->lun, tag_type == MSG_ORDERED_Q_TAG
                   4691:                               ? "ordered" : "head of queue");
                   4692:                        ahd_set_tags(ahd, devinfo, AHD_QUEUE_BASIC);
                   4693:                        mask = ~0x03;
                   4694:                }
                   4695:
                   4696:                /*
                   4697:                 * Resend the identify for this CCB as the target
                   4698:                 * may believe that the selection is invalid otherwise.
                   4699:                 */
                   4700:                ahd_outb(ahd, SCB_CONTROL,
                   4701:                         ahd_inb_scbram(ahd, SCB_CONTROL) & mask);
1.43      tsutsui  4702:                scb->hscb->control &= mask;
1.1       fvdl     4703:                ahd_set_transaction_tag(scb, /*enabled*/FALSE,
                   4704:                                        /*type*/MSG_SIMPLE_TASK);
                   4705:                ahd_outb(ahd, MSG_OUT, MSG_IDENTIFYFLAG);
                   4706:                ahd_assert_atn(ahd);
                   4707:                ahd_busy_tcl(ahd, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
                   4708:                             SCB_GET_TAG(scb));
                   4709:
                   4710:                /*
                   4711:                 * Requeue all tagged commands for this target
1.26      wiz      4712:                 * currently in our possession so they can be
1.1       fvdl     4713:                 * converted to untagged commands.
                   4714:                 */
                   4715:                ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
                   4716:                                   SCB_GET_CHANNEL(ahd, scb),
                   4717:                                   SCB_GET_LUN(scb), /*tag*/SCB_LIST_NULL,
                   4718:                                   ROLE_INITIATOR, CAM_REQUEUE_REQ,
                   4719:                                   SEARCH_COMPLETE);
                   4720:        } else if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_IDENTIFYFLAG, TRUE)) {
                   4721:                /*
                   4722:                 * Most likely the device believes that we had
                   4723:                 * previously negotiated packetized.
                   4724:                 */
                   4725:                ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE
                   4726:                               |  MSG_FLAG_IU_REQ_CHANGED;
                   4727:
                   4728:                ahd_force_renegotiation(ahd, devinfo);
                   4729:                ahd->msgout_index = 0;
                   4730:                ahd->msgout_len = 0;
                   4731:                ahd_build_transfer_msg(ahd, devinfo);
                   4732:                ahd->msgout_index = 0;
                   4733:                response = 1;
                   4734:        } else {
                   4735:                /*
                   4736:                 * Otherwise, we ignore it.
                   4737:                 */
                   4738:                printf("%s:%c:%d: Message reject for %x -- ignored\n",
                   4739:                       ahd_name(ahd), devinfo->channel, devinfo->target,
                   4740:                       last_msg);
                   4741:        }
                   4742:        return (response);
                   4743: }
                   4744:
                   4745: /*
                   4746:  * Process an ignore wide residue message.
                   4747:  */
                   4748: static void
1.35      christos 4749: ahd_handle_ign_wide_residue(struct ahd_softc *ahd,
1.36      christos 4750:     struct ahd_devinfo *devinfo)
1.1       fvdl     4751: {
                   4752:        u_int scb_index;
                   4753:        struct scb *scb;
                   4754:
                   4755:        printf("%s: ahd_handle_ign_wide_residue\n", ahd_name(ahd));
                   4756:
                   4757:        scb_index = ahd_get_scbptr(ahd);
                   4758:        scb = ahd_lookup_scb(ahd, scb_index);
                   4759:        /*
                   4760:         * XXX Actually check data direction in the sequencer?
                   4761:         * Perhaps add datadir to some spare bits in the hscb?
                   4762:         */
                   4763:        if ((ahd_inb(ahd, SEQ_FLAGS) & DPHASE) == 0
                   4764:         || ahd_get_transfer_dir(scb) != CAM_DIR_IN) {
                   4765:                /*
                   4766:                 * Ignore the message if we haven't
                   4767:                 * seen an appropriate data phase yet.
                   4768:                 */
                   4769:        } else {
                   4770:                /*
                   4771:                 * If the residual occurred on the last
                   4772:                 * transfer and the transfer request was
                   4773:                 * expected to end on an odd count, do
                   4774:                 * nothing.  Otherwise, subtract a byte
                   4775:                 * and update the residual count accordingly.
                   4776:                 */
                   4777:                uint32_t sgptr;
                   4778:
                   4779:                sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
                   4780:                if ((sgptr & SG_LIST_NULL) != 0
1.21      thorpej  4781:                 && (ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
                   4782:                     & SCB_XFERLEN_ODD) != 0) {
1.1       fvdl     4783:                        /*
                   4784:                         * If the residual occurred on the last
                   4785:                         * transfer and the transfer request was
                   4786:                         * expected to end on an odd count, do
                   4787:                         * nothing.
                   4788:                         */
                   4789:                } else {
                   4790:                        uint32_t data_cnt;
                   4791:                        uint64_t data_addr;
                   4792:                        uint32_t sglen;
                   4793:
                   4794:                        /* Pull in the rest of the sgptr */
1.11      thorpej  4795:                        sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
                   4796:                        data_cnt = ahd_inl_scbram(ahd, SCB_RESIDUAL_DATACNT);
                   4797:                        if ((sgptr & SG_LIST_NULL) != 0) {
                   4798:                                /*
                   4799:                                 * The residual data count is not updated
                   4800:                                 * for the command run to completion case.
1.63      msaitoh  4801:                                 * Explicitly zero the count.
1.11      thorpej  4802:                                 */
                   4803:                                data_cnt &= ~AHD_SG_LEN_MASK;
                   4804:                        }
                   4805:                        data_addr = ahd_inq(ahd, SHADDR);
1.1       fvdl     4806:                        data_cnt += 1;
                   4807:                        data_addr -= 1;
1.11      thorpej  4808:                        sgptr &= SG_PTR_MASK;
1.1       fvdl     4809:                        if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
                   4810:                                struct ahd_dma64_seg *sg;
                   4811:
                   4812:                                sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
                   4813:
                   4814:                                /*
                   4815:                                 * The residual sg ptr points to the next S/G
                   4816:                                 * to load so we must go back one.
                   4817:                                 */
                   4818:                                sg--;
                   4819:                                sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
                   4820:                                if (sg != scb->sg_list
                   4821:                                 && sglen < (data_cnt & AHD_SG_LEN_MASK)) {
                   4822:
                   4823:                                        sg--;
                   4824:                                        sglen = ahd_le32toh(sg->len);
                   4825:                                        /*
                   4826:                                         * Preserve High Address and SG_LIST
                   4827:                                         * bits while setting the count to 1.
                   4828:                                         */
                   4829:                                        data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK));
                   4830:                                        data_addr = ahd_le64toh(sg->addr)
                   4831:                                                  + (sglen & AHD_SG_LEN_MASK)
                   4832:                                                  - 1;
                   4833:
                   4834:                                        /*
                   4835:                                         * Increment sg so it points to the
                   4836:                                         * "next" sg.
                   4837:                                         */
                   4838:                                        sg++;
                   4839:                                        sgptr = ahd_sg_virt_to_bus(ahd, scb,
                   4840:                                                                   sg);
                   4841:                                }
                   4842:                        } else {
                   4843:                                struct ahd_dma_seg *sg;
                   4844:
                   4845:                                sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
                   4846:
                   4847:                                /*
                   4848:                                 * The residual sg ptr points to the next S/G
                   4849:                                 * to load so we must go back one.
                   4850:                                 */
                   4851:                                sg--;
                   4852:                                sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
                   4853:                                if (sg != scb->sg_list
                   4854:                                 && sglen < (data_cnt & AHD_SG_LEN_MASK)) {
                   4855:
                   4856:                                        sg--;
                   4857:                                        sglen = ahd_le32toh(sg->len);
                   4858:                                        /*
                   4859:                                         * Preserve High Address and SG_LIST
                   4860:                                         * bits while setting the count to 1.
                   4861:                                         */
                   4862:                                        data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK));
                   4863:                                        data_addr = ahd_le32toh(sg->addr)
                   4864:                                                  + (sglen & AHD_SG_LEN_MASK)
                   4865:                                                  - 1;
                   4866:
                   4867:                                        /*
                   4868:                                         * Increment sg so it points to the
                   4869:                                         * "next" sg.
                   4870:                                         */
                   4871:                                        sg++;
                   4872:                                        sgptr = ahd_sg_virt_to_bus(ahd, scb,
1.43      tsutsui  4873:                                                                   sg);
1.1       fvdl     4874:                                }
                   4875:                        }
1.11      thorpej  4876:                        /*
                   4877:                         * Toggle the "oddness" of the transfer length
                   4878:                         * to handle this mid-transfer ignore wide
                   4879:                         * residue.  This ensures that the oddness is
                   4880:                         * correct for subsequent data transfers.
                   4881:                         */
                   4882:                        ahd_outb(ahd, SCB_TASK_ATTRIBUTE,
1.21      thorpej  4883:                            ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
                   4884:                            ^ SCB_XFERLEN_ODD);
1.1       fvdl     4885:
1.11      thorpej  4886:                        ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
                   4887:                        ahd_outl(ahd, SCB_RESIDUAL_DATACNT, data_cnt);
1.1       fvdl     4888:                        /*
                   4889:                         * The FIFO's pointers will be updated if/when the
                   4890:                         * sequencer re-enters a data phase.
                   4891:                         */
                   4892:                }
                   4893:        }
                   4894: }
                   4895:
                   4896:
                   4897: /*
                   4898:  * Reinitialize the data pointers for the active transfer
                   4899:  * based on its current residual.
                   4900:  */
                   4901: static void
                   4902: ahd_reinitialize_dataptrs(struct ahd_softc *ahd)
                   4903: {
                   4904:        struct           scb *scb;
                   4905:        ahd_mode_state   saved_modes;
                   4906:        u_int            scb_index;
                   4907:        u_int            wait;
                   4908:        uint32_t         sgptr;
                   4909:        uint32_t         resid;
                   4910:        uint64_t         dataptr;
                   4911:
                   4912:        AHD_ASSERT_MODES(ahd, AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK,
                   4913:                         AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK);
1.30      perry    4914:
1.1       fvdl     4915:        scb_index = ahd_get_scbptr(ahd);
                   4916:        scb = ahd_lookup_scb(ahd, scb_index);
                   4917:
                   4918:        /*
                   4919:         * Release and reacquire the FIFO so we
                   4920:         * have a clean slate.
                   4921:         */
                   4922:        ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
                   4923:        wait = 1000;
1.19      thorpej  4924:        while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE))
1.1       fvdl     4925:                ahd_delay(100);
                   4926:        if (wait == 0) {
                   4927:                ahd_print_path(ahd, scb);
                   4928:                printf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n");
                   4929:                ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT);
                   4930:        }
                   4931:        saved_modes = ahd_save_modes(ahd);
                   4932:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   4933:        ahd_outb(ahd, DFFSTAT,
                   4934:                 ahd_inb(ahd, DFFSTAT)
                   4935:                | (saved_modes == 0x11 ? CURRFIFO_1 : CURRFIFO_0));
                   4936:
                   4937:        /*
                   4938:         * Determine initial values for data_addr and data_cnt
                   4939:         * for resuming the data phase.
                   4940:         */
                   4941:        sgptr = (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24)
                   4942:              | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16)
                   4943:              | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8)
                   4944:              | ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
                   4945:        sgptr &= SG_PTR_MASK;
                   4946:
                   4947:        resid = (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 2) << 16)
                   4948:              | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 1) << 8)
                   4949:              | ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT);
                   4950:
                   4951:        if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
                   4952:                struct ahd_dma64_seg *sg;
                   4953:
                   4954:                sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
                   4955:
                   4956:                /* The residual sg_ptr always points to the next sg */
                   4957:                sg--;
                   4958:
                   4959:                dataptr = ahd_le64toh(sg->addr)
                   4960:                        + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK)
                   4961:                        - resid;
                   4962:                ahd_outb(ahd, HADDR + 7, dataptr >> 56);
                   4963:                ahd_outb(ahd, HADDR + 6, dataptr >> 48);
                   4964:                ahd_outb(ahd, HADDR + 5, dataptr >> 40);
                   4965:                ahd_outb(ahd, HADDR + 4, dataptr >> 32);
                   4966:        } else {
                   4967:                struct   ahd_dma_seg *sg;
                   4968:
                   4969:                sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
                   4970:
                   4971:                /* The residual sg_ptr always points to the next sg */
                   4972:                sg--;
                   4973:
                   4974:                dataptr = ahd_le32toh(sg->addr)
                   4975:                        + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK)
                   4976:                        - resid;
                   4977:                ahd_outb(ahd, HADDR + 4,
                   4978:                         (ahd_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24);
                   4979:        }
                   4980:        ahd_outb(ahd, HADDR + 3, dataptr >> 24);
                   4981:        ahd_outb(ahd, HADDR + 2, dataptr >> 16);
                   4982:        ahd_outb(ahd, HADDR + 1, dataptr >> 8);
                   4983:        ahd_outb(ahd, HADDR, dataptr);
                   4984:        ahd_outb(ahd, HCNT + 2, resid >> 16);
                   4985:        ahd_outb(ahd, HCNT + 1, resid >> 8);
                   4986:        ahd_outb(ahd, HCNT, resid);
                   4987: }
                   4988:
                   4989: /*
                   4990:  * Handle the effects of issuing a bus device reset message.
                   4991:  */
                   4992: static void
                   4993: ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
1.31      christos 4994:                    u_int lun, cam_status status, const char *message,
1.1       fvdl     4995:                    int verbose_level)
                   4996: {
                   4997: #ifdef AHD_TARGET_MODE
                   4998:        struct ahd_tmode_tstate* tstate;
                   4999: #endif
                   5000:        int found;
                   5001:
                   5002:        found = ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
                   5003:                               lun, SCB_LIST_NULL, devinfo->role,
                   5004:                               status);
                   5005:
                   5006: #ifdef AHD_TARGET_MODE
                   5007:        /*
                   5008:         * Send an immediate notify ccb to all target mord peripheral
                   5009:         * drivers affected by this action.
                   5010:         */
                   5011:        tstate = ahd->enabled_targets[devinfo->our_scsiid];
                   5012:        if (tstate != NULL) {
                   5013:                u_int cur_lun;
                   5014:                u_int max_lun;
                   5015:
                   5016:                if (lun != CAM_LUN_WILDCARD) {
                   5017:                        cur_lun = 0;
                   5018:                        max_lun = AHD_NUM_LUNS - 1;
                   5019:                } else {
                   5020:                        cur_lun = lun;
                   5021:                        max_lun = lun;
                   5022:                }
                   5023:                for (cur_lun <= max_lun; cur_lun++) {
                   5024:                        struct ahd_tmode_lstate* lstate;
                   5025:
                   5026:                        lstate = tstate->enabled_luns[cur_lun];
                   5027:                        if (lstate == NULL)
                   5028:                                continue;
                   5029:
                   5030:                        ahd_queue_lstate_event(ahd, lstate, devinfo->our_scsiid,
                   5031:                                               MSG_BUS_DEV_RESET, /*arg*/0);
                   5032:                        ahd_send_lstate_events(ahd, lstate);
                   5033:                }
                   5034:        }
                   5035: #endif
                   5036:
                   5037:        /*
                   5038:         * Go back to async/narrow transfers and renegotiate.
                   5039:         */
                   5040:        ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
                   5041:                      AHD_TRANS_CUR, /*paused*/TRUE);
                   5042:        ahd_set_syncrate(ahd, devinfo, /*period*/0, /*offset*/0,
                   5043:                         /*ppr_options*/0, AHD_TRANS_CUR, /*paused*/TRUE);
                   5044:
                   5045:        ahd_send_async(ahd, devinfo->channel, devinfo->target,
                   5046:                       lun, AC_SENT_BDR, NULL);
1.30      perry    5047:
1.1       fvdl     5048:        if (message != NULL
                   5049:         && (verbose_level <= bootverbose))
                   5050:                printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd),
                   5051:                       message, devinfo->channel, devinfo->target, found);
                   5052: }
                   5053:
                   5054: #ifdef AHD_TARGET_MODE
                   5055: static void
                   5056: ahd_setup_target_msgin(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
                   5057:                       struct scb *scb)
                   5058: {
                   5059:
1.30      perry    5060:        /*
1.1       fvdl     5061:         * To facilitate adding multiple messages together,
                   5062:         * each routine should increment the index and len
                   5063:         * variables instead of setting them explicitly.
1.30      perry    5064:         */
1.1       fvdl     5065:        ahd->msgout_index = 0;
                   5066:        ahd->msgout_len = 0;
                   5067:
                   5068:        if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)
                   5069:                ahd_build_transfer_msg(ahd, devinfo);
                   5070:        else
                   5071:                panic("ahd_intr: AWAITING target message with no message");
                   5072:
                   5073:        ahd->msgout_index = 0;
                   5074:        ahd->msg_type = MSG_TYPE_TARGET_MSGIN;
                   5075: }
                   5076: #endif
                   5077: /**************************** Initialization **********************************/
                   5078: static u_int
                   5079: ahd_sglist_size(struct ahd_softc *ahd)
                   5080: {
                   5081:        bus_size_t list_size;
                   5082:
                   5083:        list_size = sizeof(struct ahd_dma_seg) * AHD_NSEG;
                   5084:        if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
                   5085:                list_size = sizeof(struct ahd_dma64_seg) * AHD_NSEG;
                   5086:        return (list_size);
                   5087: }
                   5088:
                   5089: /*
                   5090:  * Calculate the optimum S/G List allocation size.  S/G elements used
                   5091:  * for a given transaction must be physically contiguous.  Assume the
                   5092:  * OS will allocate full pages to us, so it doesn't make sense to request
                   5093:  * less than a page.
                   5094:  */
                   5095: static u_int
                   5096: ahd_sglist_allocsize(struct ahd_softc *ahd)
                   5097: {
                   5098:        bus_size_t sg_list_increment;
                   5099:        bus_size_t sg_list_size;
                   5100:        bus_size_t max_list_size;
                   5101:        bus_size_t best_list_size;
                   5102:
                   5103:        /* Start out with the minimum required for AHD_NSEG. */
                   5104:        sg_list_increment = ahd_sglist_size(ahd);
                   5105:        sg_list_size = sg_list_increment;
                   5106:
                   5107:        /* Get us as close as possible to a page in size. */
                   5108:        while ((sg_list_size + sg_list_increment) <= PAGE_SIZE)
                   5109:                sg_list_size += sg_list_increment;
                   5110:
                   5111:        /*
                   5112:         * Try to reduce the amount of wastage by allocating
                   5113:         * multiple pages.
                   5114:         */
                   5115:        best_list_size = sg_list_size;
                   5116:        max_list_size = roundup(sg_list_increment, PAGE_SIZE);
                   5117:        if (max_list_size < 4 * PAGE_SIZE)
                   5118:                max_list_size = 4 * PAGE_SIZE;
                   5119:        if (max_list_size > (AHD_SCB_MAX_ALLOC * sg_list_increment))
                   5120:                max_list_size = (AHD_SCB_MAX_ALLOC * sg_list_increment);
                   5121:        while ((sg_list_size + sg_list_increment) <= max_list_size
                   5122:           &&  (sg_list_size % PAGE_SIZE) != 0) {
                   5123:                bus_size_t new_mod;
                   5124:                bus_size_t best_mod;
                   5125:
                   5126:                sg_list_size += sg_list_increment;
                   5127:                new_mod = sg_list_size % PAGE_SIZE;
                   5128:                best_mod = best_list_size % PAGE_SIZE;
                   5129:                if (new_mod > best_mod || new_mod == 0) {
                   5130:                        best_list_size = sg_list_size;
                   5131:                }
                   5132:        }
                   5133:        return (best_list_size);
                   5134: }
                   5135:
                   5136: int
                   5137: ahd_softc_init(struct ahd_softc *ahd)
                   5138: {
                   5139:
                   5140:        ahd->unpause = 0;
1.30      perry    5141:        ahd->pause = PAUSE;
1.1       fvdl     5142:        return (0);
                   5143: }
                   5144:
                   5145: void
                   5146: ahd_set_unit(struct ahd_softc *ahd, int unit)
                   5147: {
                   5148:        ahd->unit = unit;
                   5149: }
                   5150:
                   5151: void
1.38      dyoung   5152: ahd_set_name(struct ahd_softc *ahd, const char *name)
1.1       fvdl     5153: {
                   5154:        ahd->name = name;
                   5155: }
                   5156:
                   5157: void
                   5158: ahd_free(struct ahd_softc *ahd)
                   5159: {
                   5160:        int i;
                   5161:
                   5162:        switch (ahd->init_level) {
                   5163:        default:
                   5164:        case 2:
                   5165:                ahd_shutdown(ahd);
                   5166:                TAILQ_REMOVE(&ahd_tailq, ahd, links);
                   5167:                /* FALLTHROUGH */
                   5168:        case 1:
1.44      tsutsui  5169:                bus_dmamap_unload(ahd->parent_dmat,
                   5170:                    ahd->shared_data_map.dmamap);
                   5171:                bus_dmamap_destroy(ahd->parent_dmat,
                   5172:                    ahd->shared_data_map.dmamap);
                   5173:                bus_dmamem_unmap(ahd->parent_dmat, (void *)ahd->qoutfifo,
                   5174:                    ahd->shared_data_size);
                   5175:                bus_dmamem_free(ahd->parent_dmat,
                   5176:                    &ahd->shared_data_map.dmasegs, ahd->shared_data_map.nseg);
1.1       fvdl     5177:                break;
                   5178:        case 0:
1.43      tsutsui  5179:                break;
1.1       fvdl     5180:        }
                   5181:
                   5182:        ahd_platform_free(ahd);
1.9       thorpej  5183:        ahd_fini_scbdata(ahd);
1.1       fvdl     5184:        for (i = 0; i < AHD_NUM_TARGETS; i++) {
                   5185:                struct ahd_tmode_tstate *tstate;
                   5186:
                   5187:                tstate = ahd->enabled_targets[i];
                   5188:                if (tstate != NULL) {
                   5189: #if AHD_TARGET_MODE
                   5190:                        int j;
                   5191:
                   5192:                        for (j = 0; j < AHD_NUM_LUNS; j++) {
                   5193:                                struct ahd_tmode_lstate *lstate;
                   5194:
                   5195:                                lstate = tstate->enabled_luns[j];
                   5196:                                if (lstate != NULL) {
                   5197:                                        xpt_free_path(lstate->path);
                   5198:                                        free(lstate, M_DEVBUF);
                   5199:                                }
                   5200:                        }
                   5201: #endif
                   5202:                        free(tstate, M_DEVBUF);
                   5203:                }
                   5204:        }
                   5205: #if AHD_TARGET_MODE
                   5206:        if (ahd->black_hole != NULL) {
                   5207:                xpt_free_path(ahd->black_hole->path);
                   5208:                free(ahd->black_hole, M_DEVBUF);
                   5209:        }
                   5210: #endif
                   5211:        if (ahd->seep_config != NULL)
                   5212:                free(ahd->seep_config, M_DEVBUF);
                   5213:        if (ahd->saved_stack != NULL)
                   5214:                free(ahd->saved_stack, M_DEVBUF);
                   5215: #ifndef __FreeBSD__
                   5216:        free(ahd, M_DEVBUF);
                   5217: #endif
                   5218:        return;
                   5219: }
                   5220:
                   5221: void
                   5222: ahd_shutdown(void *arg)
                   5223: {
                   5224:        struct  ahd_softc *ahd;
                   5225:
1.44      tsutsui  5226:        ahd = arg;
1.1       fvdl     5227:
                   5228: #ifdef AHD_DEBUG
                   5229:        printf("%s: ahd_shutdown\n", ahd_name(ahd));
                   5230: #endif
                   5231:        /*
                   5232:         * Stop periodic timer callbacks.
                   5233:         */
                   5234:        ahd_timer_stop(&ahd->reset_timer);
                   5235:        ahd_timer_stop(&ahd->stat_timer);
                   5236:
                   5237:        /* This will reset most registers to 0, but not all */
1.15      thorpej  5238:        ahd_reset(ahd, /*reinit*/FALSE);
1.1       fvdl     5239: }
                   5240:
                   5241: /*
                   5242:  * Reset the controller and record some information about it
1.15      thorpej  5243:  * that is only available just after a reset.  If "reinit" is
1.26      wiz      5244:  * non-zero, this reset occurred after initial configuration
1.15      thorpej  5245:  * and the caller requests that the chip be fully reinitialized
1.62      msaitoh  5246:  * to a runnable state.  Chip interrupts are *not* enabled after
1.15      thorpej  5247:  * a reinitialization.  The caller must enable interrupts via
                   5248:  * ahd_intr_enable().
1.1       fvdl     5249:  */
                   5250: int
1.15      thorpej  5251: ahd_reset(struct ahd_softc *ahd, int reinit)
1.1       fvdl     5252: {
                   5253:        u_int    sxfrctl1;
                   5254:        int      wait;
                   5255:        uint32_t cmd;
1.43      tsutsui  5256:        struct ahd_pci_busdata  *bd = ahd->bus_data;
1.1       fvdl     5257:
                   5258:        /*
                   5259:         * Preserve the value of the SXFRCTL1 register for all channels.
                   5260:         * It contains settings that affect termination and we don't want
                   5261:         * to disturb the integrity of the bus.
                   5262:         */
                   5263:        ahd_pause(ahd);
                   5264:        ahd_update_modes(ahd);
                   5265:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   5266:        sxfrctl1 = ahd_inb(ahd, SXFRCTL1);
                   5267:
                   5268:        cmd = pci_conf_read(bd->pc, bd->tag, PCI_COMMAND_STATUS_REG);
                   5269:
                   5270:        if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) {
                   5271:                uint32_t mod_cmd;
                   5272:
                   5273:                /*
                   5274:                 * A4 Razor #632
                   5275:                 * During the assertion of CHIPRST, the chip
                   5276:                 * does not disable its parity logic prior to
                   5277:                 * the start of the reset.  This may cause a
                   5278:                 * parity error to be detected and thus a
                   5279:                 * spurious SERR or PERR assertion.  Disble
                   5280:                 * PERR and SERR responses during the CHIPRST.
                   5281:                 */
1.44      tsutsui  5282:                mod_cmd = cmd &
                   5283:                    ~(PCI_COMMAND_PARITY_ENABLE|PCI_COMMAND_SERR_ENABLE);
                   5284:                pci_conf_write(bd->pc, bd->tag,
                   5285:                    PCI_COMMAND_STATUS_REG, mod_cmd);
1.1       fvdl     5286:        }
                   5287:        ahd_outb(ahd, HCNTRL, CHIPRST | ahd->pause);
                   5288:
                   5289:        /*
                   5290:         * Ensure that the reset has finished.  We delay 1000us
                   5291:         * prior to reading the register to make sure the chip
                   5292:         * has sufficiently completed its reset to handle register
                   5293:         * accesses.
                   5294:         */
                   5295:        wait = 1000;
                   5296:        do {
                   5297:                ahd_delay(1000);
                   5298:        } while (--wait && !(ahd_inb(ahd, HCNTRL) & CHIPRSTACK));
                   5299:
                   5300:        if (wait == 0) {
                   5301:                printf("%s: WARNING - Failed chip reset!  "
                   5302:                       "Trying to initialize anyway.\n", ahd_name(ahd));
                   5303:        }
                   5304:        ahd_outb(ahd, HCNTRL, ahd->pause);
                   5305:
                   5306:        if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) {
                   5307:                /*
                   5308:                 * Clear any latched PCI error status and restore
                   5309:                 * previous SERR and PERR response enables.
                   5310:                 */
1.25      fvdl     5311:                pci_conf_write(bd->pc, bd->tag, PCI_COMMAND_STATUS_REG, cmd |
1.24      briggs   5312:                    (PCI_STATUS_PARITY_ERROR | PCI_STATUS_TARGET_TARGET_ABORT |
                   5313:                     PCI_STATUS_MASTER_TARGET_ABORT | PCI_STATUS_MASTER_ABORT |
                   5314:                     PCI_STATUS_SPECIAL_ERROR));
1.1       fvdl     5315:        }
                   5316:
                   5317:        /*
1.43      tsutsui  5318:         * Mode should be SCSI after a chip reset, but lets
                   5319:         * set it just to be safe. We touch the MODE_PTR
1.1       fvdl     5320:         * register directly so as to bypass the lazy update
                   5321:         * ode in ahd_set_modes().
1.43      tsutsui  5322:         */
1.1       fvdl     5323:        ahd_known_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   5324:        ahd_outb(ahd, MODE_PTR,
                   5325:                 ahd_build_mode_state(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI));
                   5326:
                   5327:        /*
                   5328:         * Restore SXFRCTL1.
                   5329:         *
                   5330:         * We must always initialize STPWEN to 1 before we
                   5331:         * restore the saved values.  STPWEN is initialized
                   5332:         * to a tri-state condition which can only be cleared
                   5333:         * by turning it on.
                   5334:         */
                   5335:        ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
                   5336:        ahd_outb(ahd, SXFRCTL1, sxfrctl1);
                   5337:
                   5338:        /* Determine chip configuration */
                   5339:        ahd->features &= ~AHD_WIDE;
                   5340:        if ((ahd_inb(ahd, SBLKCTL) & SELWIDE) != 0)
                   5341:                ahd->features |= AHD_WIDE;
                   5342:
                   5343:        /*
                   5344:         * If a recovery action has forced a chip reset,
                   5345:         * re-initialize the chip to our liking.
                   5346:         */
1.15      thorpej  5347:        if (reinit != 0)
1.1       fvdl     5348:                ahd_chip_init(ahd);
                   5349:
                   5350:        return (0);
                   5351: }
                   5352:
                   5353: /*
                   5354:  * Determine the number of SCBs available on the controller
                   5355:  */
                   5356: int
                   5357: ahd_probe_scbs(struct ahd_softc *ahd) {
                   5358:        int i;
                   5359:
                   5360:        AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
                   5361:                         ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
                   5362:        for (i = 0; i < AHD_SCB_MAX; i++) {
                   5363:                int j;
                   5364:                int ret;
                   5365:
                   5366:                ahd_set_scbptr(ahd, i);
                   5367:                ahd_outw(ahd, SCB_BASE, i);
                   5368:                for (j = 2; j < 64; j++)
                   5369:                        ahd_outb(ahd, SCB_BASE+j, 0);
                   5370:                /* Start out life as unallocated (needing an abort) */
                   5371:                ahd_outb(ahd, SCB_CONTROL, MK_MESSAGE);
                   5372:                ret = ahd_inw_scbram(ahd, SCB_BASE);
                   5373:                if (ret != i) {
1.44      tsutsui  5374:                        printf("%s: ahd_probe_scbs (!=%d): returned 0x%x\n",
                   5375:                            ahd_name(ahd), i, ret);
1.1       fvdl     5376:                        break;
                   5377:                }
                   5378:                ahd_set_scbptr(ahd, 0);
                   5379:                ret = ahd_inw_scbram(ahd, SCB_BASE);
                   5380:                if (ret != 0) {
1.44      tsutsui  5381:                        printf("ahd_probe_scbs (non zero): returned 0x%x\n",
                   5382:                            ret);
1.1       fvdl     5383:                        break;
                   5384:                }
                   5385:        }
                   5386:        return (i);
                   5387: }
                   5388:
                   5389: static void
                   5390: ahd_initialize_hscbs(struct ahd_softc *ahd)
                   5391: {
                   5392:        int i;
1.30      perry    5393:
1.1       fvdl     5394:        for (i = 0; i < ahd->scb_data.maxhscbs; i++) {
                   5395:                ahd_set_scbptr(ahd, i);
                   5396:
                   5397:                /* Clear the control byte. */
                   5398:                ahd_outb(ahd, SCB_CONTROL, 0);
                   5399:
                   5400:                /* Set the next pointer */
                   5401:                ahd_outw(ahd, SCB_NEXT, SCB_LIST_NULL);
                   5402:        }
                   5403: }
                   5404:
                   5405: static int
                   5406: ahd_init_scbdata(struct ahd_softc *ahd)
                   5407: {
                   5408:        struct  scb_data *scb_data;
                   5409:        int     i;
                   5410:
                   5411:        scb_data = &ahd->scb_data;
                   5412:        TAILQ_INIT(&scb_data->free_scbs);
                   5413:        for (i = 0; i < AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT; i++)
                   5414:                LIST_INIT(&scb_data->free_scb_lists[i]);
                   5415:        LIST_INIT(&scb_data->any_dev_free_scb_list);
                   5416:        SLIST_INIT(&scb_data->hscb_maps);
                   5417:        SLIST_INIT(&scb_data->sg_maps);
                   5418:        SLIST_INIT(&scb_data->sense_maps);
                   5419:
                   5420:        /* Determine the number of hardware SCBs and initialize them */
                   5421:        scb_data->maxhscbs = ahd_probe_scbs(ahd);
                   5422:        if (scb_data->maxhscbs == 0) {
                   5423:                printf("%s: No SCB space found\n", ahd_name(ahd));
                   5424:                return (ENXIO);
                   5425:        }
                   5426:        ahd_initialize_hscbs(ahd);
                   5427:
                   5428:        /*
                   5429:         * Create our DMA tags.  These tags define the kinds of device
                   5430:         * accessible memory allocations and memory mappings we will
                   5431:         * need to perform during normal operation.
                   5432:         *
                   5433:         * Unless we need to further restrict the allocation, we rely
                   5434:         * on the restrictions of the parent dmat, hence the common
                   5435:         * use of MAXADDR and MAXSIZE.
                   5436:         */
                   5437:
                   5438:        /* Perform initial CCB allocation */
                   5439:        ahd_alloc_scbs(ahd);
                   5440:
                   5441:        if (scb_data->numscbs == 0) {
                   5442:                printf("%s: ahd_init_scbdata - "
                   5443:                       "Unable to allocate initial scbs\n",
                   5444:                       ahd_name(ahd));
                   5445:                goto error_exit;
                   5446:        }
                   5447:
                   5448:        /*
1.58      andvar   5449:         * Note that we were successful
1.1       fvdl     5450:         */
1.30      perry    5451:        return (0);
1.1       fvdl     5452:
                   5453: error_exit:
                   5454:
                   5455:        return (ENOMEM);
                   5456: }
                   5457:
                   5458: static struct scb *
                   5459: ahd_find_scb_by_tag(struct ahd_softc *ahd, u_int tag)
                   5460: {
                   5461:        struct scb *scb;
                   5462:
                   5463:        /*
                   5464:         * Look on the pending list.
                   5465:         */
                   5466:        LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
                   5467:                if (SCB_GET_TAG(scb) == tag)
                   5468:                        return (scb);
                   5469:        }
                   5470:
                   5471:        /*
                   5472:         * Then on all of the collision free lists.
                   5473:         */
                   5474:        TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
                   5475:                struct scb *list_scb;
                   5476:
                   5477:                list_scb = scb;
                   5478:                do {
                   5479:                        if (SCB_GET_TAG(list_scb) == tag)
                   5480:                                return (list_scb);
                   5481:                        list_scb = LIST_NEXT(list_scb, collision_links);
                   5482:                } while (list_scb);
                   5483:        }
                   5484:
                   5485:        /*
                   5486:         * And finally on the generic free list.
                   5487:         */
                   5488:        LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) {
                   5489:                if (SCB_GET_TAG(scb) == tag)
                   5490:                        return (scb);
                   5491:        }
                   5492:
                   5493:        return (NULL);
                   5494: }
                   5495:
                   5496: static void
                   5497: ahd_fini_scbdata(struct ahd_softc *ahd)
                   5498: {
                   5499:        struct scb_data *scb_data;
                   5500:
                   5501:        scb_data = &ahd->scb_data;
                   5502:        if (scb_data == NULL)
                   5503:                return;
                   5504:
                   5505:        switch (scb_data->init_level) {
                   5506:        default:
                   5507:        case 3:
                   5508:        {
                   5509:                struct map_node *sns_map;
                   5510:
                   5511:                while ((sns_map = SLIST_FIRST(&scb_data->sense_maps)) != NULL) {
                   5512:                        SLIST_REMOVE_HEAD(&scb_data->sense_maps, links);
                   5513:                        ahd_freedmamem(ahd->parent_dmat, PAGE_SIZE,
1.37      christos 5514:                                       sns_map->dmamap, (void *)sns_map->vaddr,
1.1       fvdl     5515:                                       &sns_map->dmasegs, sns_map->nseg);
                   5516:                        free(sns_map, M_DEVBUF);
                   5517:                }
                   5518:        }
1.51      mrg      5519:        /* FALLTHROUGH */
1.1       fvdl     5520:        case 2:
                   5521:        {
                   5522:                struct map_node *sg_map;
                   5523:
                   5524:                while ((sg_map = SLIST_FIRST(&scb_data->sg_maps)) != NULL) {
                   5525:                        SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
1.44      tsutsui  5526:                        ahd_freedmamem(ahd->parent_dmat,
                   5527:                                       ahd_sglist_allocsize(ahd),
1.37      christos 5528:                                       sg_map->dmamap, (void *)sg_map->vaddr,
1.1       fvdl     5529:                                       &sg_map->dmasegs, sg_map->nseg);
                   5530:                        free(sg_map, M_DEVBUF);
                   5531:                }
                   5532:        }
1.51      mrg      5533:        /* FALLTHROUGH */
1.1       fvdl     5534:        case 1:
                   5535:        {
                   5536:                struct map_node *hscb_map;
                   5537:
                   5538:                while ((hscb_map = SLIST_FIRST(&scb_data->hscb_maps)) != NULL) {
                   5539:                        SLIST_REMOVE_HEAD(&scb_data->hscb_maps, links);
                   5540:                        ahd_freedmamem(ahd->parent_dmat, PAGE_SIZE,
1.44      tsutsui  5541:                                       hscb_map->dmamap,
                   5542:                                       (void *)hscb_map->vaddr,
1.1       fvdl     5543:                                       &hscb_map->dmasegs, hscb_map->nseg);
                   5544:                        free(hscb_map, M_DEVBUF);
                   5545:                }
                   5546:        }
1.51      mrg      5547:        /* FALLTHROUGH */
1.1       fvdl     5548:        case 0:
                   5549:                break;
                   5550:        }
                   5551: }
                   5552:
                   5553: /*
                   5554:  * DSP filter Bypass must be enabled until the first selection
                   5555:  * after a change in bus mode (Razor #491 and #493).
                   5556:  */
                   5557: static void
                   5558: ahd_setup_iocell_workaround(struct ahd_softc *ahd)
                   5559: {
                   5560:        ahd_mode_state saved_modes;
                   5561:
                   5562:        saved_modes = ahd_save_modes(ahd);
                   5563:        ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                   5564:        ahd_outb(ahd, DSPDATACTL, ahd_inb(ahd, DSPDATACTL)
                   5565:               | BYPASSENAB | RCVROFFSTDIS | XMITOFFSTDIS);
                   5566:        ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) | (ENSELDO|ENSELDI));
                   5567: #ifdef AHD_DEBUG
                   5568:        if ((ahd_debug & AHD_SHOW_MISC) != 0)
                   5569:                printf("%s: Setting up iocell workaround\n", ahd_name(ahd));
                   5570: #endif
                   5571:        ahd_restore_modes(ahd, saved_modes);
1.20      thorpej  5572:        ahd->flags &= ~AHD_HAD_FIRST_SEL;
1.1       fvdl     5573: }
                   5574:
                   5575: static void
                   5576: ahd_iocell_first_selection(struct ahd_softc *ahd)
                   5577: {
                   5578:        ahd_mode_state  saved_modes;
                   5579:        u_int           sblkctl;
                   5580:
1.20      thorpej  5581:        if ((ahd->flags & AHD_HAD_FIRST_SEL) != 0)
                   5582:                return;
1.1       fvdl     5583:        saved_modes = ahd_save_modes(ahd);
                   5584:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   5585:        sblkctl = ahd_inb(ahd, SBLKCTL);
                   5586:        ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                   5587: #ifdef AHD_DEBUG
                   5588:        if ((ahd_debug & AHD_SHOW_MISC) != 0)
                   5589:                printf("%s: iocell first selection\n", ahd_name(ahd));
                   5590: #endif
                   5591:        if ((sblkctl & ENAB40) != 0) {
                   5592:                ahd_outb(ahd, DSPDATACTL,
                   5593:                         ahd_inb(ahd, DSPDATACTL) & ~BYPASSENAB);
                   5594: #ifdef AHD_DEBUG
                   5595:                if ((ahd_debug & AHD_SHOW_MISC) != 0)
                   5596:                        printf("%s: BYPASS now disabled\n", ahd_name(ahd));
                   5597: #endif
                   5598:        }
                   5599:        ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI));
                   5600:        ahd_outb(ahd, CLRINT, CLRSCSIINT);
                   5601:        ahd_restore_modes(ahd, saved_modes);
1.20      thorpej  5602:        ahd->flags |= AHD_HAD_FIRST_SEL;
1.1       fvdl     5603: }
                   5604:
                   5605: /*************************** SCB Management ***********************************/
                   5606: static void
                   5607: ahd_add_col_list(struct ahd_softc *ahd, struct scb *scb, u_int col_idx)
                   5608: {
                   5609:        struct  scb_list *free_list;
                   5610:        struct  scb_tailq *free_tailq;
                   5611:        struct  scb *first_scb;
                   5612:
                   5613:        scb->flags |= SCB_ON_COL_LIST;
                   5614:        AHD_SET_SCB_COL_IDX(scb, col_idx);
                   5615:        free_list = &ahd->scb_data.free_scb_lists[col_idx];
                   5616:        free_tailq = &ahd->scb_data.free_scbs;
                   5617:        first_scb = LIST_FIRST(free_list);
                   5618:        if (first_scb != NULL) {
                   5619:                LIST_INSERT_AFTER(first_scb, scb, collision_links);
                   5620:        } else {
                   5621:                LIST_INSERT_HEAD(free_list, scb, collision_links);
                   5622:                TAILQ_INSERT_TAIL(free_tailq, scb, links.tqe);
                   5623:        }
                   5624: }
                   5625:
                   5626: static void
                   5627: ahd_rem_col_list(struct ahd_softc *ahd, struct scb *scb)
                   5628: {
                   5629:        struct  scb_list *free_list;
                   5630:        struct  scb_tailq *free_tailq;
                   5631:        struct  scb *first_scb;
                   5632:        u_int   col_idx;
                   5633:
                   5634:        scb->flags &= ~SCB_ON_COL_LIST;
                   5635:        col_idx = AHD_GET_SCB_COL_IDX(ahd, scb);
                   5636:        free_list = &ahd->scb_data.free_scb_lists[col_idx];
                   5637:        free_tailq = &ahd->scb_data.free_scbs;
                   5638:        first_scb = LIST_FIRST(free_list);
                   5639:        if (first_scb == scb) {
                   5640:                struct scb *next_scb;
                   5641:
                   5642:                /*
                   5643:                 * Maintain order in the collision free
                   5644:                 * lists for fairness if this device has
                   5645:                 * other colliding tags active.
                   5646:                 */
                   5647:                next_scb = LIST_NEXT(scb, collision_links);
                   5648:                if (next_scb != NULL) {
                   5649:                        TAILQ_INSERT_AFTER(free_tailq, scb,
                   5650:                                           next_scb, links.tqe);
                   5651:                }
                   5652:                TAILQ_REMOVE(free_tailq, scb, links.tqe);
                   5653:        }
                   5654:        LIST_REMOVE(scb, collision_links);
                   5655: }
                   5656:
                   5657: /*
                   5658:  * Get a free scb. If there are none, see if we can allocate a new SCB.
                   5659:  */
                   5660: struct scb *
                   5661: ahd_get_scb(struct ahd_softc *ahd, u_int col_idx)
                   5662: {
                   5663:        struct scb *scb;
                   5664:        TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
                   5665:                if (AHD_GET_SCB_COL_IDX(ahd, scb) != col_idx) {
                   5666:                        ahd_rem_col_list(ahd, scb);
                   5667:                        goto found;
                   5668:                }
                   5669:        }
1.32      bouyer   5670:        if ((scb = LIST_FIRST(&ahd->scb_data.any_dev_free_scb_list)) == NULL)
                   5671:                return (NULL);
1.1       fvdl     5672:        LIST_REMOVE(scb, links.le);
                   5673:        if (col_idx != AHD_NEVER_COL_IDX
                   5674:         && (scb->col_scb != NULL)
                   5675:         && (scb->col_scb->flags & SCB_ACTIVE) == 0) {
                   5676:                LIST_REMOVE(scb->col_scb, links.le);
                   5677:                ahd_add_col_list(ahd, scb->col_scb, col_idx);
                   5678:        }
                   5679: found:
                   5680:        scb->flags |= SCB_ACTIVE;
                   5681:        return (scb);
                   5682: }
                   5683:
                   5684: /*
                   5685:  * Return an SCB resource to the free list.
                   5686:  */
                   5687: void
                   5688: ahd_free_scb(struct ahd_softc *ahd, struct scb *scb)
1.30      perry    5689: {
1.1       fvdl     5690:
                   5691:        /* Clean up for the next user */
                   5692:        scb->flags = SCB_FLAG_NONE;
                   5693:        scb->hscb->control = 0;
1.9       thorpej  5694:        ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = NULL;
1.1       fvdl     5695:
                   5696:        if (scb->col_scb == NULL) {
                   5697:
                   5698:                /*
                   5699:                 * No collision possible.  Just free normally.
                   5700:                 */
                   5701:                LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
                   5702:                                 scb, links.le);
                   5703:        } else if ((scb->col_scb->flags & SCB_ON_COL_LIST) != 0) {
                   5704:
                   5705:                /*
                   5706:                 * The SCB we might have collided with is on
                   5707:                 * a free collision list.  Put both SCBs on
                   5708:                 * the generic list.
                   5709:                 */
                   5710:                ahd_rem_col_list(ahd, scb->col_scb);
                   5711:                LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
                   5712:                                 scb, links.le);
                   5713:                LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
                   5714:                                 scb->col_scb, links.le);
                   5715:        } else if ((scb->col_scb->flags
                   5716:                  & (SCB_PACKETIZED|SCB_ACTIVE)) == SCB_ACTIVE
                   5717:                && (scb->col_scb->hscb->control & TAG_ENB) != 0) {
                   5718:
                   5719:                /*
                   5720:                 * The SCB we might collide with on the next allocation
                   5721:                 * is still active in a non-packetized, tagged, context.
                   5722:                 * Put us on the SCB collision list.
                   5723:                 */
                   5724:                ahd_add_col_list(ahd, scb,
                   5725:                                 AHD_GET_SCB_COL_IDX(ahd, scb->col_scb));
                   5726:        } else {
                   5727:                /*
                   5728:                 * The SCB we might collide with on the next allocation
                   5729:                 * is either active in a packetized context, or free.
                   5730:                 * Since we can't collide, put this SCB on the generic
                   5731:                 * free list.
                   5732:                 */
                   5733:                LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
                   5734:                                 scb, links.le);
                   5735:        }
                   5736:
                   5737:        ahd_platform_scb_free(ahd, scb);
                   5738: }
                   5739:
1.32      bouyer   5740: int
1.1       fvdl     5741: ahd_alloc_scbs(struct ahd_softc *ahd)
                   5742: {
                   5743:        struct scb_data *scb_data;
                   5744:        struct scb      *next_scb;
                   5745:        struct hardware_scb *hscb;
                   5746:        struct map_node *hscb_map;
                   5747:        struct map_node *sg_map;
                   5748:        struct map_node *sense_map;
                   5749:        uint8_t         *segs;
                   5750:        uint8_t         *sense_data;
                   5751:        bus_addr_t       hscb_busaddr;
                   5752:        bus_addr_t       sg_busaddr;
                   5753:        bus_addr_t       sense_busaddr;
                   5754:        int              newcount;
                   5755:        int              i;
                   5756:
                   5757:        scb_data = &ahd->scb_data;
                   5758:        if (scb_data->numscbs >= AHD_SCB_MAX_ALLOC)
                   5759:                /* Can't allocate any more */
1.32      bouyer   5760:                return (0);
1.1       fvdl     5761:
1.7       thorpej  5762:        KASSERT(scb_data->scbs_left >= 0);
1.1       fvdl     5763:        if (scb_data->scbs_left != 0) {
                   5764:                int offset;
                   5765:
                   5766:                offset = (PAGE_SIZE / sizeof(*hscb)) - scb_data->scbs_left;
                   5767:                hscb_map = SLIST_FIRST(&scb_data->hscb_maps);
                   5768:                hscb = &((struct hardware_scb *)hscb_map->vaddr)[offset];
                   5769:                hscb_busaddr = hscb_map->physaddr + (offset * sizeof(*hscb));
                   5770:        } else {
1.32      bouyer   5771:                hscb_map = malloc(sizeof(*hscb_map), M_DEVBUF, M_WAITOK);
1.1       fvdl     5772:
                   5773:                if (hscb_map == NULL)
1.32      bouyer   5774:                        return (0);
1.1       fvdl     5775:
                   5776:                memset(hscb_map, 0, sizeof(*hscb_map));
                   5777:
                   5778:                /* Allocate the next batch of hardware SCBs */
1.44      tsutsui  5779:                if (ahd_createdmamem(ahd->parent_dmat, PAGE_SIZE,
                   5780:                                     ahd->sc_dmaflags,
                   5781:                                     &hscb_map->dmamap,
                   5782:                                     (void **)&hscb_map->vaddr,
1.1       fvdl     5783:                                     &hscb_map->physaddr, &hscb_map->dmasegs,
1.30      perry    5784:                                     &hscb_map->nseg, ahd_name(ahd),
1.1       fvdl     5785:                                     "hardware SCB structures") < 0) {
                   5786:                        free(hscb_map, M_DEVBUF);
1.32      bouyer   5787:                        return (0);
1.1       fvdl     5788:                }
                   5789:
                   5790:                SLIST_INSERT_HEAD(&scb_data->hscb_maps, hscb_map, links);
                   5791:
                   5792:                hscb = (struct hardware_scb *)hscb_map->vaddr;
                   5793:                hscb_busaddr = hscb_map->physaddr;
                   5794:                scb_data->scbs_left = PAGE_SIZE / sizeof(*hscb);
                   5795:        }
                   5796:
                   5797:        scb_data->init_level++;
                   5798:
                   5799:        if (scb_data->sgs_left != 0) {
                   5800:                int offset;
                   5801:
1.9       thorpej  5802:                offset = ((ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd))
                   5803:                       - scb_data->sgs_left) * ahd_sglist_size(ahd);
1.1       fvdl     5804:                sg_map = SLIST_FIRST(&scb_data->sg_maps);
                   5805:                segs = sg_map->vaddr + offset;
                   5806:                sg_busaddr = sg_map->physaddr + offset;
                   5807:        } else {
1.32      bouyer   5808:                sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_WAITOK);
1.1       fvdl     5809:
                   5810:                if (sg_map == NULL)
1.32      bouyer   5811:                        return (0);
1.1       fvdl     5812:
1.41      cegger   5813:                memset(sg_map, 0, sizeof(*sg_map));
1.1       fvdl     5814:
                   5815:                /* Allocate the next batch of S/G lists */
1.44      tsutsui  5816:                if (ahd_createdmamem(ahd->parent_dmat,
                   5817:                                     ahd_sglist_allocsize(ahd),
                   5818:                                     ahd->sc_dmaflags,
1.37      christos 5819:                                     &sg_map->dmamap, (void **)&sg_map->vaddr,
1.1       fvdl     5820:                                     &sg_map->physaddr, &sg_map->dmasegs,
1.30      perry    5821:                                     &sg_map->nseg, ahd_name(ahd),
1.1       fvdl     5822:                                     "SG data structures") < 0) {
                   5823:                        free(sg_map, M_DEVBUF);
1.32      bouyer   5824:                        return (0);
1.1       fvdl     5825:                }
                   5826:
                   5827:                SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
                   5828:
                   5829:                segs = sg_map->vaddr;
                   5830:                sg_busaddr = sg_map->physaddr;
                   5831:                scb_data->sgs_left =
                   5832:                    ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd);
                   5833: #ifdef AHD_DEBUG
                   5834:                if (ahd_debug & AHD_SHOW_MEMORY)
1.44      tsutsui  5835:                        printf("%s: ahd_alloc_scbs - Mapped SG data\n",
                   5836:                            ahd_name(ahd));
1.1       fvdl     5837: #endif
                   5838:        }
                   5839:
                   5840:        scb_data->init_level++;
                   5841:
                   5842:
                   5843:        if (scb_data->sense_left != 0) {
                   5844:                int offset;
                   5845:
                   5846:                offset = PAGE_SIZE - (AHD_SENSE_BUFSIZE * scb_data->sense_left);
                   5847:                sense_map = SLIST_FIRST(&scb_data->sense_maps);
                   5848:                sense_data = sense_map->vaddr + offset;
                   5849:                sense_busaddr = sense_map->physaddr + offset;
                   5850:        } else {
1.32      bouyer   5851:                sense_map = malloc(sizeof(*sense_map), M_DEVBUF, M_WAITOK);
1.1       fvdl     5852:
                   5853:                if (sense_map == NULL)
1.32      bouyer   5854:                        return (0);
1.1       fvdl     5855:
1.41      cegger   5856:                memset(sense_map, 0, sizeof(*sense_map));
1.1       fvdl     5857:
                   5858:                /* Allocate the next batch of sense buffers */
1.44      tsutsui  5859:                if (ahd_createdmamem(ahd->parent_dmat, PAGE_SIZE,
                   5860:                                     ahd->sc_dmaflags,
                   5861:                                     &sense_map->dmamap,
                   5862:                                     (void **)&sense_map->vaddr,
1.1       fvdl     5863:                                     &sense_map->physaddr, &sense_map->dmasegs,
1.30      perry    5864:                                     &sense_map->nseg, ahd_name(ahd),
1.1       fvdl     5865:                                     "Sense Data structures") < 0) {
                   5866:                        free(sense_map, M_DEVBUF);
1.32      bouyer   5867:                        return (0);
1.1       fvdl     5868:                }
                   5869:
                   5870:                SLIST_INSERT_HEAD(&scb_data->sense_maps, sense_map, links);
                   5871:
                   5872:                sense_data = sense_map->vaddr;
                   5873:                sense_busaddr = sense_map->physaddr;
                   5874:                scb_data->sense_left = PAGE_SIZE / AHD_SENSE_BUFSIZE;
                   5875: #ifdef AHD_DEBUG
                   5876:                if (ahd_debug & AHD_SHOW_MEMORY)
1.44      tsutsui  5877:                        printf("%s: ahd_alloc_scbs - Mapped sense data\n",
                   5878:                            ahd_name(ahd));
1.1       fvdl     5879: #endif
                   5880:        }
                   5881:
                   5882:        scb_data->init_level++;
                   5883:
                   5884:        newcount = MIN(scb_data->sense_left, scb_data->scbs_left);
                   5885:        newcount = MIN(newcount, scb_data->sgs_left);
                   5886:        newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs));
                   5887:        scb_data->sense_left -= newcount;
                   5888:        scb_data->scbs_left -= newcount;
                   5889:        scb_data->sgs_left -= newcount;
                   5890:
                   5891:        for (i = 0; i < newcount; i++) {
                   5892:                u_int col_tag;
                   5893:
                   5894:                struct scb_platform_data *pdata;
                   5895: #ifndef __linux__
                   5896:                int error;
                   5897: #endif
1.44      tsutsui  5898:                next_scb = malloc(sizeof(*next_scb), M_DEVBUF, M_WAITOK);
1.1       fvdl     5899:                if (next_scb == NULL)
                   5900:                        break;
                   5901:
1.44      tsutsui  5902:                pdata = malloc(sizeof(*pdata), M_DEVBUF, M_WAITOK);
1.1       fvdl     5903:                if (pdata == NULL) {
                   5904:                        free(next_scb, M_DEVBUF);
                   5905:                        break;
                   5906:                }
                   5907:                next_scb->platform_data = pdata;
                   5908:                next_scb->hscb_map = hscb_map;
                   5909:                next_scb->sg_map = sg_map;
                   5910:                next_scb->sense_map = sense_map;
                   5911:                next_scb->sg_list = segs;
                   5912:                next_scb->sense_data = sense_data;
                   5913:                next_scb->sense_busaddr = sense_busaddr;
1.10      thorpej  5914:                memset(hscb, 0, sizeof(*hscb));
1.1       fvdl     5915:                next_scb->hscb = hscb;
                   5916:                hscb->hscb_busaddr = ahd_htole32(hscb_busaddr);
1.7       thorpej  5917:                KASSERT((vaddr_t)hscb >= (vaddr_t)hscb_map->vaddr &&
                   5918:                        (vaddr_t)hscb < (vaddr_t)hscb_map->vaddr + PAGE_SIZE);
1.1       fvdl     5919:
                   5920:                /*
                   5921:                 * The sequencer always starts with the second entry.
                   5922:                 * The first entry is embedded in the scb.
                   5923:                 */
                   5924:                next_scb->sg_list_busaddr = sg_busaddr;
                   5925:                if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
                   5926:                        next_scb->sg_list_busaddr
                   5927:                            += sizeof(struct ahd_dma64_seg);
                   5928:                else
                   5929:                        next_scb->sg_list_busaddr += sizeof(struct ahd_dma_seg);
                   5930:                next_scb->ahd_softc = ahd;
                   5931:                next_scb->flags = SCB_FLAG_NONE;
                   5932:
                   5933:                error = bus_dmamap_create(ahd->parent_dmat,
1.44      tsutsui  5934:                                          AHD_MAXTRANSFER_SIZE, AHD_NSEG,
                   5935:                                          MAXBSIZE, 0,
                   5936:                                          BUS_DMA_WAITOK|BUS_DMA_ALLOCNOW|
                   5937:                                          ahd->sc_dmaflags,
1.1       fvdl     5938:                                          &next_scb->dmamap);
                   5939:                if (error != 0) {
                   5940:                        free(next_scb, M_DEVBUF);
                   5941:                        free(pdata, M_DEVBUF);
                   5942:                        break;
                   5943:                }
                   5944:                next_scb->hscb->tag = ahd_htole16(scb_data->numscbs);
                   5945:                col_tag = scb_data->numscbs ^ 0x100;
                   5946:                next_scb->col_scb = ahd_find_scb_by_tag(ahd, col_tag);
                   5947:                if (next_scb->col_scb != NULL)
                   5948:                        next_scb->col_scb->col_scb = next_scb;
                   5949:                ahd_free_scb(ahd, next_scb);
                   5950:                hscb++;
                   5951:                hscb_busaddr += sizeof(*hscb);
                   5952:                segs += ahd_sglist_size(ahd);
                   5953:                sg_busaddr += ahd_sglist_size(ahd);
                   5954:                sense_data += AHD_SENSE_BUFSIZE;
                   5955:                sense_busaddr += AHD_SENSE_BUFSIZE;
                   5956:                scb_data->numscbs++;
                   5957:        }
1.32      bouyer   5958:        return (i);
1.1       fvdl     5959: }
                   5960:
                   5961: void
1.31      christos 5962: ahd_controller_info(struct ahd_softc *ahd, char *tbuf, size_t l)
1.1       fvdl     5963: {
                   5964:        const char *speed;
                   5965:        const char *type;
1.47      christos 5966:        size_t len;
1.1       fvdl     5967:
1.47      christos 5968:        len = snprintf(tbuf, l, "%s: ",
1.28      itojun   5969:            ahd_chip_names[ahd->chip & AHD_CHIPID_MASK]);
1.47      christos 5970:        if (len > l)
                   5971:                return;
1.1       fvdl     5972:        speed = "Ultra320 ";
                   5973:        if ((ahd->features & AHD_WIDE) != 0) {
                   5974:                type = "Wide ";
                   5975:        } else {
                   5976:                type = "Single ";
                   5977:        }
1.47      christos 5978:        len += snprintf(tbuf + len, l  - len, "%s%sChannel %c, SCSI Id=%d, ",
1.1       fvdl     5979:                      speed, type, ahd->channel, ahd->our_id);
1.47      christos 5980:        if (len > l)
                   5981:                return;
                   5982:        snprintf(tbuf + len, l - len, "%s, %d SCBs", ahd->bus_description,
1.1       fvdl     5983:                ahd->scb_data.maxhscbs);
                   5984: }
                   5985:
1.55      jdolecek 5986: static const char * const channel_strings[] = {
1.1       fvdl     5987:        "Primary Low",
                   5988:        "Primary High",
1.30      perry    5989:        "Secondary Low",
1.1       fvdl     5990:        "Secondary High"
                   5991: };
                   5992:
1.55      jdolecek 5993: static const char * const termstat_strings[] = {
1.1       fvdl     5994:        "Terminated Correctly",
                   5995:        "Over Terminated",
                   5996:        "Under Terminated",
                   5997:        "Not Configured"
                   5998: };
                   5999:
                   6000: /*
                   6001:  * Start the board, ready for normal operation
                   6002:  */
                   6003: int
                   6004: ahd_init(struct ahd_softc *ahd)
                   6005: {
                   6006:        uint8_t         *next_vaddr;
                   6007:        bus_addr_t       next_baddr;
                   6008:        size_t           driver_data_size;
                   6009:        int              i;
                   6010:        int              error;
                   6011:        u_int            warn_user;
                   6012:        uint8_t          current_sensing;
                   6013:        uint8_t          fstat;
1.30      perry    6014:
1.1       fvdl     6015:        AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                   6016:
                   6017:        ahd->stack_size = ahd_probe_stack_size(ahd);
                   6018:        ahd->saved_stack = malloc(ahd->stack_size * sizeof(uint16_t),
1.52      chs      6019:                                  M_DEVBUF, M_WAITOK | M_ZERO);
1.1       fvdl     6020:
                   6021:        /*
                   6022:         * Verify that the compiler hasn't over-agressively
                   6023:         * padded important structures.
                   6024:         */
                   6025:        if (sizeof(struct hardware_scb) != 64)
                   6026:                panic("Hardware SCB size is incorrect");
                   6027:
                   6028: #ifdef AHD_DEBUG
                   6029:        if ((ahd_debug & AHD_DEBUG_SEQUENCER) != 0)
                   6030:                ahd->flags |= AHD_SEQUENCER_DEBUG;
                   6031: #endif
                   6032:
                   6033:        /*
                   6034:         * Default to allowing initiator operations.
                   6035:         */
                   6036:        ahd->flags |= AHD_INITIATORROLE;
                   6037:
                   6038:        /*
                   6039:         * Only allow target mode features if this unit has them enabled.
                   6040:         */
                   6041:        if ((AHD_TMODE_ENABLE & (0x1 << ahd->unit)) == 0)
                   6042:                ahd->features &= ~AHD_TARGETMODE;
                   6043:
                   6044:        /*
                   6045:         * DMA tag for our command fifos and other data in system memory
                   6046:         * the card's sequencer must be able to access.  For initiator
                   6047:         * roles, we need to allocate space for the qoutfifo.  When providing
                   6048:         * for the target mode role, we must additionally provide space for
                   6049:         * the incoming target command fifo.
                   6050:         */
                   6051:        driver_data_size = AHD_SCB_MAX * sizeof(uint16_t)
                   6052:                         + sizeof(struct hardware_scb);
                   6053:        if ((ahd->features & AHD_TARGETMODE) != 0)
                   6054:                driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd);
                   6055:        if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0)
                   6056:                driver_data_size += PKT_OVERRUN_BUFSIZE;
                   6057:        ahd->shared_data_size = driver_data_size;
                   6058:
1.7       thorpej  6059:        memset(&ahd->shared_data_map, 0, sizeof(ahd->shared_data_map));
1.1       fvdl     6060:        ahd->sc_dmaflags = BUS_DMA_NOWAIT;
                   6061:
                   6062:        if (ahd_createdmamem(ahd->parent_dmat, ahd->shared_data_size,
                   6063:                             ahd->sc_dmaflags,
1.44      tsutsui  6064:                             &ahd->shared_data_map.dmamap,
                   6065:                             (void **)&ahd->shared_data_map.vaddr,
                   6066:                             &ahd->shared_data_map.physaddr,
                   6067:                             &ahd->shared_data_map.dmasegs,
                   6068:                             &ahd->shared_data_map.nseg, ahd_name(ahd),
                   6069:                             "shared data") < 0)
1.1       fvdl     6070:                return (ENOMEM);
1.7       thorpej  6071:        ahd->qoutfifo = (void *) ahd->shared_data_map.vaddr;
1.1       fvdl     6072:
                   6073:        ahd->init_level++;
                   6074:
                   6075:        next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE];
1.44      tsutsui  6076:        next_baddr = ahd->shared_data_map.physaddr +
                   6077:            AHD_QOUT_SIZE * sizeof(uint16_t);
1.1       fvdl     6078:        if ((ahd->features & AHD_TARGETMODE) != 0) {
                   6079:                ahd->targetcmds = (struct target_cmd *)next_vaddr;
                   6080:                next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);
                   6081:                next_baddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);
                   6082:        }
                   6083:
                   6084:        if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) {
                   6085:                ahd->overrun_buf = next_vaddr;
                   6086:                next_vaddr += PKT_OVERRUN_BUFSIZE;
                   6087:                next_baddr += PKT_OVERRUN_BUFSIZE;
                   6088:        }
                   6089:
                   6090:        /*
                   6091:         * We need one SCB to serve as the "next SCB".  Since the
                   6092:         * tag identifier in this SCB will never be used, there is
                   6093:         * no point in using a valid HSCB tag from an SCB pulled from
                   6094:         * the standard free pool.  So, we allocate this "sentinel"
                   6095:         * specially from the DMA safe memory chunk used for the QOUTFIFO.
                   6096:         */
                   6097:        ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr;
1.7       thorpej  6098:        ahd->next_queued_hscb_map = &ahd->shared_data_map;
1.9       thorpej  6099:        ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr);
1.1       fvdl     6100:
                   6101:        memset(&ahd->scb_data, 0, sizeof(struct scb_data));
                   6102:
                   6103:        /* Allocate SCB data now that parent_dmat is initialized */
                   6104:        if (ahd_init_scbdata(ahd) != 0)
                   6105:                return (ENOMEM);
                   6106:
                   6107:        if ((ahd->flags & AHD_INITIATORROLE) == 0)
                   6108:                ahd->flags &= ~AHD_RESET_BUS_A;
                   6109:
                   6110:        /*
                   6111:         * Before committing these settings to the chip, give
                   6112:         * the OSM one last chance to modify our configuration.
                   6113:         */
                   6114:        ahd_platform_init(ahd);
                   6115:
                   6116:        /* Bring up the chip. */
                   6117:        ahd_chip_init(ahd);
                   6118:
                   6119:        AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                   6120:
                   6121:        if ((ahd->flags & AHD_CURRENT_SENSING) == 0)
                   6122:                goto init_done;
                   6123:
                   6124:        /*
                   6125:         * Verify termination based on current draw and
                   6126:         * warn user if the bus is over/under terminated.
                   6127:         */
                   6128:        error = ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL,
                   6129:                                   CURSENSE_ENB);
                   6130:        if (error != 0) {
                   6131:                printf("%s: current sensing timeout 1\n", ahd_name(ahd));
                   6132:                goto init_done;
                   6133:        }
                   6134:        for (i = 20, fstat = FLX_FSTAT_BUSY;
                   6135:             (fstat & FLX_FSTAT_BUSY) != 0 && i; i--) {
                   6136:                error = ahd_read_flexport(ahd, FLXADDR_FLEXSTAT, &fstat);
                   6137:                if (error != 0) {
                   6138:                        printf("%s: current sensing timeout 2\n",
                   6139:                               ahd_name(ahd));
                   6140:                        goto init_done;
                   6141:                }
                   6142:        }
                   6143:        if (i == 0) {
                   6144:                printf("%s: Timedout during current-sensing test\n",
                   6145:                       ahd_name(ahd));
                   6146:                goto init_done;
                   6147:        }
                   6148:
                   6149:        /* Latch Current Sensing status. */
                   6150:        error = ahd_read_flexport(ahd, FLXADDR_CURRENT_STAT, &current_sensing);
                   6151:        if (error != 0) {
                   6152:                printf("%s: current sensing timeout 3\n", ahd_name(ahd));
                   6153:                goto init_done;
                   6154:        }
                   6155:
                   6156:        /* Diable current sensing. */
                   6157:        ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
                   6158:
                   6159: #ifdef AHD_DEBUG
                   6160:        if ((ahd_debug & AHD_SHOW_TERMCTL) != 0) {
                   6161:                printf("%s: current_sensing == 0x%x\n",
                   6162:                       ahd_name(ahd), current_sensing);
                   6163:        }
                   6164: #endif
                   6165:        warn_user = 0;
                   6166:        for (i = 0; i < 4; i++, current_sensing >>= FLX_CSTAT_SHIFT) {
                   6167:                u_int term_stat;
                   6168:
                   6169:                term_stat = (current_sensing & FLX_CSTAT_MASK);
                   6170:                switch (term_stat) {
                   6171:                case FLX_CSTAT_OVER:
                   6172:                case FLX_CSTAT_UNDER:
                   6173:                        warn_user++;
1.51      mrg      6174:                        /* FALLTHROUGH */
1.1       fvdl     6175:                case FLX_CSTAT_INVALID:
                   6176:                case FLX_CSTAT_OKAY:
                   6177:                        if (warn_user == 0 && bootverbose == 0)
                   6178:                                break;
                   6179:                        printf("%s: %s Channel %s\n", ahd_name(ahd),
                   6180:                               channel_strings[i], termstat_strings[term_stat]);
                   6181:                        break;
                   6182:                }
                   6183:        }
                   6184:        if (warn_user) {
                   6185:                printf("%s: WARNING. Termination is not configured correctly.\n"
                   6186:                       "%s: WARNING. SCSI bus operations may FAIL.\n",
                   6187:                       ahd_name(ahd), ahd_name(ahd));
                   6188:        }
                   6189: init_done:
                   6190:        ahd_reset_current_bus(ahd);
                   6191:        ahd_restart(ahd);
                   6192:        ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
                   6193:                        ahd_stat_timer, ahd);
                   6194:
                   6195:        return (0);
                   6196: }
                   6197:
                   6198: /*
                   6199:  * (Re)initialize chip state after a chip reset.
                   6200:  */
                   6201: static void
                   6202: ahd_chip_init(struct ahd_softc *ahd)
                   6203: {
                   6204:        uint32_t busaddr;
                   6205:        u_int    sxfrctl1;
                   6206:        u_int    scsiseq_template;
                   6207:        u_int    wait;
                   6208:        u_int    i;
                   6209:        u_int    target;
                   6210:
                   6211:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   6212:        /*
                   6213:         * Take the LED out of diagnostic mode
                   6214:         */
                   6215:        ahd_outb(ahd, SBLKCTL, ahd_inb(ahd, SBLKCTL) & ~(DIAGLEDEN|DIAGLEDON));
                   6216:
                   6217:        /*
                   6218:         * Return HS_MAILBOX to its default value.
                   6219:         */
                   6220:        ahd->hs_mailbox = 0;
                   6221:        ahd_outb(ahd, HS_MAILBOX, 0);
                   6222:
                   6223:        /* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1. */
                   6224:        ahd_outb(ahd, IOWNID, ahd->our_id);
                   6225:        ahd_outb(ahd, TOWNID, ahd->our_id);
                   6226:        sxfrctl1 = (ahd->flags & AHD_TERM_ENB_A) != 0 ? STPWEN : 0;
                   6227:        sxfrctl1 |= (ahd->flags & AHD_SPCHK_ENB_A) != 0 ? ENSPCHK : 0;
                   6228:        if ((ahd->bugs & AHD_LONG_SETIMO_BUG)
                   6229:         && (ahd->seltime != STIMESEL_MIN)) {
                   6230:                /*
                   6231:                 * The selection timer duration is twice as long
                   6232:                 * as it should be.  Halve it by adding "1" to
                   6233:                 * the user specified setting.
                   6234:                 */
                   6235:                sxfrctl1 |= ahd->seltime + STIMESEL_BUG_ADJ;
                   6236:        } else {
                   6237:                sxfrctl1 |= ahd->seltime;
                   6238:        }
1.30      perry    6239:
1.1       fvdl     6240:        ahd_outb(ahd, SXFRCTL0, DFON);
                   6241:        ahd_outb(ahd, SXFRCTL1, sxfrctl1|ahd->seltime|ENSTIMER|ACTNEGEN);
                   6242:        ahd_outb(ahd, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
                   6243:
                   6244:        /*
                   6245:         * Now that termination is set, wait for up
                   6246:         * to 500ms for our transceivers to settle.  If
                   6247:         * the adapter does not have a cable attached,
1.9       thorpej  6248:         * the transceivers may never settle, so don't
1.1       fvdl     6249:         * complain if we fail here.
                   6250:         */
                   6251:        for (wait = 10000;
                   6252:             (ahd_inb(ahd, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
                   6253:             wait--)
                   6254:                ahd_delay(100);
                   6255:
                   6256:        /* Clear any false bus resets due to the transceivers settling */
                   6257:        ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
                   6258:        ahd_outb(ahd, CLRINT, CLRSCSIINT);
                   6259:
                   6260:        /* Initialize mode specific S/G state. */
                   6261:        for (i = 0; i < 2; i++) {
                   6262:                ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
                   6263:                ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
                   6264:                ahd_outb(ahd, SG_STATE, 0);
                   6265:                ahd_outb(ahd, CLRSEQINTSRC, 0xFF);
                   6266:                ahd_outb(ahd, SEQIMODE,
                   6267:                         ENSAVEPTRS|ENCFG4DATA|ENCFG4ISTAT
                   6268:                        |ENCFG4TSTAT|ENCFG4ICMD|ENCFG4TCMD);
                   6269:        }
                   6270:
                   6271:        ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                   6272:        ahd_outb(ahd, DSCOMMAND0, ahd_inb(ahd, DSCOMMAND0)|MPARCKEN|CACHETHEN);
                   6273:        ahd_outb(ahd, DFF_THRSH, RD_DFTHRSH_75|WR_DFTHRSH_75);
                   6274:        ahd_outb(ahd, SIMODE0, ENIOERR|ENOVERRUN);
                   6275:        ahd_outb(ahd, SIMODE3, ENNTRAMPERR|ENOSRAMPERR);
                   6276:        if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
                   6277:                ahd_outb(ahd, OPTIONMODE, AUTOACKEN|AUTO_MSGOUT_DE);
                   6278:        } else {
                   6279:                ahd_outb(ahd, OPTIONMODE, AUTOACKEN|BUSFREEREV|AUTO_MSGOUT_DE);
                   6280:        }
                   6281:        ahd_outb(ahd, SCSCHKN, CURRFIFODEF|WIDERESEN|SHVALIDSTDIS);
                   6282:        if ((ahd->chip & AHD_BUS_MASK) == AHD_PCIX)
                   6283:                /*
                   6284:                 * Do not issue a target abort when a split completion
                   6285:                 * error occurs.  Let our PCIX interrupt handler deal
                   6286:                 * with it instead. H2A4 Razor #625
                   6287:                 */
                   6288:                ahd_outb(ahd, PCIXCTL, ahd_inb(ahd, PCIXCTL) | SPLTSTADIS);
                   6289:
                   6290:        if ((ahd->bugs & AHD_LQOOVERRUN_BUG) != 0)
                   6291:                ahd_outb(ahd, LQOSCSCTL, LQONOCHKOVER);
                   6292:
                   6293:        /*
                   6294:         * Tweak IOCELL settings.
                   6295:         */
                   6296:        if ((ahd->flags & AHD_HP_BOARD) != 0) {
                   6297:                for (i = 0; i < NUMDSPS; i++) {
                   6298:                        ahd_outb(ahd, DSPSELECT, i);
                   6299:                        ahd_outb(ahd, WRTBIASCTL, WRTBIASCTL_HP_DEFAULT);
                   6300:                }
                   6301: #ifdef AHD_DEBUG
                   6302:                if ((ahd_debug & AHD_SHOW_MISC) != 0)
                   6303:                        printf("%s: WRTBIASCTL now 0x%x\n", ahd_name(ahd),
                   6304:                               WRTBIASCTL_HP_DEFAULT);
                   6305: #endif
                   6306:        }
                   6307:        ahd_setup_iocell_workaround(ahd);
                   6308:
                   6309:        /*
                   6310:         * Enable LQI Manager interrupts.
                   6311:         */
                   6312:        ahd_outb(ahd, LQIMODE1, ENLQIPHASE_LQ|ENLQIPHASE_NLQ|ENLIQABORT
                   6313:                              | ENLQICRCI_LQ|ENLQICRCI_NLQ|ENLQIBADLQI
                   6314:                              | ENLQIOVERI_LQ|ENLQIOVERI_NLQ);
                   6315:        ahd_outb(ahd, LQOMODE0, ENLQOATNLQ|ENLQOATNPKT|ENLQOTCRC);
                   6316:        /*
                   6317:         * An interrupt from LQOBUSFREE is made redundant by the
                   6318:         * BUSFREE interrupt.  We choose to have the sequencer catch
                   6319:         * LQOPHCHGINPKT errors manually for the command phase at the
                   6320:         * start of a packetized selection case.
                   6321:                ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE|ENLQOPHACHGINPKT);
                   6322:         */
                   6323:        ahd_outb(ahd, LQOMODE1, 0);
                   6324:
                   6325:        /*
                   6326:         * Setup sequencer interrupt handlers.
                   6327:         */
                   6328:        ahd_outw(ahd, INTVEC1_ADDR, ahd_resolve_seqaddr(ahd, LABEL_seq_isr));
                   6329:        ahd_outw(ahd, INTVEC2_ADDR, ahd_resolve_seqaddr(ahd, LABEL_timer_isr));
                   6330:
                   6331:        /*
                   6332:         * Setup SCB Offset registers.
                   6333:         */
                   6334:        if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
                   6335:                ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb,
                   6336:                         pkt_long_lun));
                   6337:        } else {
                   6338:                ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb, lun));
                   6339:        }
                   6340:        ahd_outb(ahd, CMDLENPTR, offsetof(struct hardware_scb, cdb_len));
                   6341:        ahd_outb(ahd, ATTRPTR, offsetof(struct hardware_scb, task_attribute));
                   6342:        ahd_outb(ahd, FLAGPTR, offsetof(struct hardware_scb, task_management));
                   6343:        ahd_outb(ahd, CMDPTR, offsetof(struct hardware_scb,
                   6344:                                       shared_data.idata.cdb));
                   6345:        ahd_outb(ahd, QNEXTPTR,
                   6346:                 offsetof(struct hardware_scb, next_hscb_busaddr));
                   6347:        ahd_outb(ahd, ABRTBITPTR, MK_MESSAGE_BIT_OFFSET);
                   6348:        ahd_outb(ahd, ABRTBYTEPTR, offsetof(struct hardware_scb, control));
                   6349:        if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
                   6350:                ahd_outb(ahd, LUNLEN,
                   6351:                         sizeof(ahd->next_queued_hscb->pkt_long_lun) - 1);
                   6352:        } else {
1.13      thorpej  6353:                ahd_outb(ahd, LUNLEN, LUNLEN_SINGLE_LEVEL_LUN);
1.1       fvdl     6354:        }
                   6355:        ahd_outb(ahd, CDBLIMIT, SCB_CDB_LEN_PTR - 1);
                   6356:        ahd_outb(ahd, MAXCMD, 0xFF);
                   6357:        ahd_outb(ahd, SCBAUTOPTR,
                   6358:                 AUSCBPTR_EN | offsetof(struct hardware_scb, tag));
                   6359:
                   6360:        /* We haven't been enabled for target mode yet. */
                   6361:        ahd_outb(ahd, MULTARGID, 0);
                   6362:        ahd_outb(ahd, MULTARGID + 1, 0);
                   6363:
                   6364:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   6365:        /* Initialize the negotiation table. */
                   6366:        if ((ahd->features & AHD_NEW_IOCELL_OPTS) == 0) {
                   6367:                /*
                   6368:                 * Clear the spare bytes in the neg table to avoid
                   6369:                 * spurious parity errors.
                   6370:                 */
                   6371:                for (target = 0; target < AHD_NUM_TARGETS; target++) {
                   6372:                        ahd_outb(ahd, NEGOADDR, target);
                   6373:                        ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PER_DEV0);
                   6374:                        for (i = 0; i < AHD_NUM_PER_DEV_ANNEXCOLS; i++)
                   6375:                                ahd_outb(ahd, ANNEXDAT, 0);
                   6376:                }
                   6377:        }
                   6378:
                   6379:        for (target = 0; target < AHD_NUM_TARGETS; target++) {
                   6380:                struct   ahd_devinfo devinfo;
                   6381:                struct   ahd_initiator_tinfo *tinfo;
                   6382:                struct   ahd_tmode_tstate *tstate;
                   6383:
                   6384:                tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
                   6385:                                            target, &tstate);
                   6386:                ahd_compile_devinfo(&devinfo, ahd->our_id,
                   6387:                                    target, CAM_LUN_WILDCARD,
                   6388:                                    'A', ROLE_INITIATOR);
                   6389:                ahd_update_neg_table(ahd, &devinfo, &tinfo->curr);
                   6390:        }
                   6391:
                   6392:        ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR);
                   6393:        ahd_outb(ahd, CLRINT, CLRSCSIINT);
                   6394:
1.19      thorpej  6395: #if NEEDS_MORE_TESTING
1.1       fvdl     6396:        /*
                   6397:         * Always enable abort on incoming L_Qs if this feature is
                   6398:         * supported.  We use this to catch invalid SCB references.
                   6399:         */
                   6400:        if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0)
                   6401:                ahd_outb(ahd, LQCTL1, ABORTPENDING);
                   6402:        else
1.19      thorpej  6403: #endif
1.1       fvdl     6404:                ahd_outb(ahd, LQCTL1, 0);
                   6405:
                   6406:        /* All of our queues are empty */
                   6407:        ahd->qoutfifonext = 0;
                   6408:        ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID_LE;
                   6409:        ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID >> 8);
                   6410:        for (i = 0; i < AHD_QOUT_SIZE; i++)
                   6411:                ahd->qoutfifo[i] = 0;
                   6412:        ahd_sync_qoutfifo(ahd, BUS_DMASYNC_PREREAD);
                   6413:
                   6414:        ahd->qinfifonext = 0;
                   6415:        for (i = 0; i < AHD_QIN_SIZE; i++)
                   6416:                ahd->qinfifo[i] = SCB_LIST_NULL;
                   6417:
                   6418:        if ((ahd->features & AHD_TARGETMODE) != 0) {
                   6419:                /* All target command blocks start out invalid. */
                   6420:                for (i = 0; i < AHD_TMODE_CMDS; i++)
                   6421:                        ahd->targetcmds[i].cmd_valid = 0;
                   6422:                ahd_sync_tqinfifo(ahd, BUS_DMASYNC_PREREAD);
                   6423:                ahd->tqinfifonext = 1;
                   6424:                ahd_outb(ahd, KERNEL_TQINPOS, ahd->tqinfifonext - 1);
                   6425:                ahd_outb(ahd, TQINPOS, ahd->tqinfifonext);
                   6426:        }
                   6427:
                   6428:        /* Initialize Scratch Ram. */
                   6429:        ahd_outb(ahd, SEQ_FLAGS, 0);
                   6430:        ahd_outb(ahd, SEQ_FLAGS2, 0);
                   6431:
                   6432:        /* We don't have any waiting selections */
                   6433:        ahd_outw(ahd, WAITING_TID_HEAD, SCB_LIST_NULL);
                   6434:        ahd_outw(ahd, WAITING_TID_TAIL, SCB_LIST_NULL);
                   6435:        for (i = 0; i < AHD_NUM_TARGETS; i++) {
                   6436:                ahd_outw(ahd, WAITING_SCB_TAILS + (2 * i), SCB_LIST_NULL);
                   6437:        }
                   6438:
                   6439:        /*
                   6440:         * Nobody is waiting to be DMAed into the QOUTFIFO.
                   6441:         */
                   6442:        ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
                   6443:        ahd_outw(ahd, COMPLETE_SCB_DMAINPROG_HEAD, SCB_LIST_NULL);
                   6444:        ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL);
                   6445:
                   6446:        /*
                   6447:         * The Freeze Count is 0.
                   6448:         */
                   6449:        ahd_outw(ahd, QFREEZE_COUNT, 0);
                   6450:
                   6451:        /*
                   6452:         * Tell the sequencer where it can find our arrays in memory.
                   6453:         */
1.7       thorpej  6454:        busaddr = ahd->shared_data_map.physaddr;
1.1       fvdl     6455:        ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF);
                   6456:        ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF);
                   6457:        ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF);
                   6458:        ahd_outb(ahd, SHARED_DATA_ADDR + 3, (busaddr >> 24) & 0xFF);
                   6459:        ahd_outb(ahd, QOUTFIFO_NEXT_ADDR, busaddr & 0xFF);
                   6460:        ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 1, (busaddr >> 8) & 0xFF);
                   6461:        ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 2, (busaddr >> 16) & 0xFF);
                   6462:        ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 3, (busaddr >> 24) & 0xFF);
                   6463:        /*
                   6464:         * Setup the allowed SCSI Sequences based on operational mode.
                   6465:         * If we are a target, we'll enable select in operations once
                   6466:         * we've had a lun enabled.
                   6467:         */
                   6468:        scsiseq_template = ENAUTOATNP;
                   6469:        if ((ahd->flags & AHD_INITIATORROLE) != 0)
                   6470:                scsiseq_template |= ENRSELI;
                   6471:        ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq_template);
                   6472:
                   6473:        /* There are no busy SCBs yet. */
                   6474:        for (target = 0; target < AHD_NUM_TARGETS; target++) {
                   6475:                int lun;
                   6476:
                   6477:                for (lun = 0; lun < AHD_NUM_LUNS_NONPKT; lun++)
                   6478:                        ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(target, 'A', lun));
                   6479:        }
                   6480:
                   6481:        /*
                   6482:         * Initialize the group code to command length table.
                   6483:         * Vendor Unique codes are set to 0 so we only capture
                   6484:         * the first byte of the cdb.  These can be overridden
                   6485:         * when target mode is enabled.
                   6486:         */
                   6487:        ahd_outb(ahd, CMDSIZE_TABLE, 5);
                   6488:        ahd_outb(ahd, CMDSIZE_TABLE + 1, 9);
                   6489:        ahd_outb(ahd, CMDSIZE_TABLE + 2, 9);
                   6490:        ahd_outb(ahd, CMDSIZE_TABLE + 3, 0);
                   6491:        ahd_outb(ahd, CMDSIZE_TABLE + 4, 15);
                   6492:        ahd_outb(ahd, CMDSIZE_TABLE + 5, 11);
                   6493:        ahd_outb(ahd, CMDSIZE_TABLE + 6, 0);
                   6494:        ahd_outb(ahd, CMDSIZE_TABLE + 7, 0);
1.30      perry    6495:
1.1       fvdl     6496:        /* Tell the sequencer of our initial queue positions */
                   6497:        ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
                   6498:        ahd_outb(ahd, QOFF_CTLSTA, SCB_QSIZE_512);
                   6499:        ahd->qinfifonext = 0;
                   6500:        ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
                   6501:        ahd_set_hescb_qoff(ahd, 0);
                   6502:        ahd_set_snscb_qoff(ahd, 0);
                   6503:        ahd_set_sescb_qoff(ahd, 0);
                   6504:        ahd_set_sdscb_qoff(ahd, 0);
                   6505:
                   6506:        /*
                   6507:         * Tell the sequencer which SCB will be the next one it receives.
                   6508:         */
                   6509:        busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
                   6510:        ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
                   6511:        ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
                   6512:        ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
                   6513:        ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
                   6514:
                   6515:        /*
1.5       wiz      6516:         * Default to coalescing disabled.
1.1       fvdl     6517:         */
1.5       wiz      6518:        ahd_outw(ahd, INT_COALESCING_CMDCOUNT, 0);
1.1       fvdl     6519:        ahd_outw(ahd, CMDS_PENDING, 0);
1.5       wiz      6520:        ahd_update_coalescing_values(ahd, ahd->int_coalescing_timer,
                   6521:                                     ahd->int_coalescing_maxcmds,
                   6522:                                     ahd->int_coalescing_mincmds);
                   6523:        ahd_enable_coalescing(ahd, FALSE);
1.1       fvdl     6524:
                   6525:        ahd_loadseq(ahd);
                   6526:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   6527: }
                   6528:
                   6529: /*
                   6530:  * Setup default device and controller settings.
                   6531:  * This should only be called if our probe has
                   6532:  * determined that no configuration data is available.
                   6533:  */
                   6534: int
                   6535: ahd_default_config(struct ahd_softc *ahd)
                   6536: {
                   6537:        int     targ;
                   6538:
                   6539:        ahd->our_id = 7;
                   6540:
                   6541:        /*
                   6542:         * Allocate a tstate to house information for our
                   6543:         * initiator presence on the bus as well as the user
                   6544:         * data for any target mode initiator.
                   6545:         */
                   6546:        if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
                   6547:                printf("%s: unable to allocate ahd_tmode_tstate.  "
                   6548:                       "Failing attach\n", ahd_name(ahd));
                   6549:                return (ENOMEM);
                   6550:        }
                   6551:
                   6552:        for (targ = 0; targ < AHD_NUM_TARGETS; targ++) {
                   6553:                struct   ahd_devinfo devinfo;
                   6554:                struct   ahd_initiator_tinfo *tinfo;
                   6555:                struct   ahd_tmode_tstate *tstate;
                   6556:                uint16_t target_mask;
                   6557:
                   6558:                tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
                   6559:                                            targ, &tstate);
                   6560:                /*
                   6561:                 * We support SPC2 and SPI4.
                   6562:                 */
                   6563:                tinfo->user.protocol_version = 4;
                   6564:                tinfo->user.transport_version = 4;
                   6565:
                   6566:                target_mask = 0x01 << targ;
                   6567:                ahd->user_discenable |= target_mask;
                   6568:                tstate->discenable |= target_mask;
                   6569:                ahd->user_tagenable |= target_mask;
                   6570: #ifdef AHD_FORCE_160
                   6571:                tinfo->user.period = AHD_SYNCRATE_DT;
                   6572: #else
                   6573:                tinfo->user.period = AHD_SYNCRATE_160;
                   6574: #endif
                   6575:                tinfo->user.offset= MAX_OFFSET;
                   6576:                tinfo->user.ppr_options = MSG_EXT_PPR_RDSTRM
                   6577:                                        | MSG_EXT_PPR_WRFLOW
                   6578:                                        | MSG_EXT_PPR_HOLDMCS
                   6579:                                        | MSG_EXT_PPR_IU_REQ
                   6580:                                        | MSG_EXT_PPR_QAS_REQ
                   6581:                                        | MSG_EXT_PPR_DT_REQ;
                   6582:                if ((ahd->features & AHD_RTI) != 0)
                   6583:                        tinfo->user.ppr_options |= MSG_EXT_PPR_RTI;
                   6584:
                   6585:                tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
                   6586:
                   6587:                /*
                   6588:                 * Start out Async/Narrow/Untagged and with
                   6589:                 * conservative protocol support.
                   6590:                 */
                   6591:                tinfo->goal.protocol_version = 2;
                   6592:                tinfo->goal.transport_version = 2;
                   6593:                tinfo->curr.protocol_version = 2;
                   6594:                tinfo->curr.transport_version = 2;
                   6595:                ahd_compile_devinfo(&devinfo, ahd->our_id,
                   6596:                                    targ, CAM_LUN_WILDCARD,
                   6597:                                    'A', ROLE_INITIATOR);
                   6598:                tstate->tagenable &= ~target_mask;
                   6599:                ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
                   6600:                              AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE);
                   6601:                ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0,
                   6602:                                 /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL,
                   6603:                                 /*paused*/TRUE);
                   6604:        }
                   6605:        return (0);
                   6606: }
                   6607:
                   6608: /*
                   6609:  * Parse device configuration information.
                   6610:  */
                   6611: int
                   6612: ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc)
                   6613: {
                   6614:        int targ;
                   6615:        int max_targ;
                   6616:
                   6617:        max_targ = sc->max_targets & CFMAXTARG;
                   6618:        ahd->our_id = sc->brtime_id & CFSCSIID;
                   6619:
                   6620:        /*
                   6621:         * Allocate a tstate to house information for our
                   6622:         * initiator presence on the bus as well as the user
                   6623:         * data for any target mode initiator.
                   6624:         */
                   6625:        if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
                   6626:                printf("%s: unable to allocate ahd_tmode_tstate.  "
                   6627:                       "Failing attach\n", ahd_name(ahd));
                   6628:                return (ENOMEM);
                   6629:        }
                   6630:
                   6631:        for (targ = 0; targ < max_targ; targ++) {
                   6632:                struct   ahd_devinfo devinfo;
                   6633:                struct   ahd_initiator_tinfo *tinfo;
                   6634:                struct   ahd_transinfo *user_tinfo;
                   6635:                struct   ahd_tmode_tstate *tstate;
                   6636:                uint16_t target_mask;
                   6637:
                   6638:                tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
                   6639:                                            targ, &tstate);
                   6640:                user_tinfo = &tinfo->user;
                   6641:
                   6642:                /*
                   6643:                 * We support SPC2 and SPI4.
                   6644:                 */
                   6645:                tinfo->user.protocol_version = 4;
                   6646:                tinfo->user.transport_version = 4;
                   6647:
                   6648:                target_mask = 0x01 << targ;
                   6649:                ahd->user_discenable &= ~target_mask;
                   6650:                tstate->discenable &= ~target_mask;
                   6651:                ahd->user_tagenable &= ~target_mask;
                   6652:                if (sc->device_flags[targ] & CFDISC) {
                   6653:                        tstate->discenable |= target_mask;
                   6654:                        ahd->user_discenable |= target_mask;
                   6655:                        ahd->user_tagenable |= target_mask;
                   6656:                } else {
                   6657:                        /*
                   6658:                         * Cannot be packetized without disconnection.
                   6659:                         */
                   6660:                        sc->device_flags[targ] &= ~CFPACKETIZED;
                   6661:                }
                   6662:
                   6663:                user_tinfo->ppr_options = 0;
                   6664:                user_tinfo->period = (sc->device_flags[targ] & CFXFER);
                   6665:                if (user_tinfo->period < CFXFER_ASYNC) {
                   6666:                        if (user_tinfo->period <= AHD_PERIOD_10MHz)
                   6667:                                user_tinfo->ppr_options |= MSG_EXT_PPR_DT_REQ;
                   6668:                        user_tinfo->offset = MAX_OFFSET;
                   6669:                } else  {
                   6670:                        user_tinfo->offset = 0;
                   6671:                        user_tinfo->period = AHD_ASYNC_XFER_PERIOD;
                   6672:                }
                   6673: #ifdef AHD_FORCE_160
                   6674:                if (user_tinfo->period <= AHD_SYNCRATE_160)
                   6675:                        user_tinfo->period = AHD_SYNCRATE_DT;
                   6676: #endif
                   6677:
                   6678:                if ((sc->device_flags[targ] & CFPACKETIZED) != 0) {
                   6679:                        user_tinfo->ppr_options |= MSG_EXT_PPR_RDSTRM
                   6680:                                                |  MSG_EXT_PPR_WRFLOW
                   6681:                                                |  MSG_EXT_PPR_HOLDMCS
                   6682:                                                |  MSG_EXT_PPR_IU_REQ;
                   6683:                        if ((ahd->features & AHD_RTI) != 0)
                   6684:                                user_tinfo->ppr_options |= MSG_EXT_PPR_RTI;
                   6685:                }
                   6686:
                   6687:                if ((sc->device_flags[targ] & CFQAS) != 0)
                   6688:                        user_tinfo->ppr_options |= MSG_EXT_PPR_QAS_REQ;
                   6689:
                   6690:                if ((sc->device_flags[targ] & CFWIDEB) != 0)
                   6691:                        user_tinfo->width = MSG_EXT_WDTR_BUS_16_BIT;
                   6692:                else
                   6693:                        user_tinfo->width = MSG_EXT_WDTR_BUS_8_BIT;
                   6694: #ifdef AHD_DEBUG
                   6695:                if ((ahd_debug & AHD_SHOW_MISC) != 0)
                   6696:                        printf("(%d): %x:%x:%x:%x\n", targ, user_tinfo->width,
                   6697:                               user_tinfo->period, user_tinfo->offset,
                   6698:                               user_tinfo->ppr_options);
                   6699: #endif
                   6700:                /*
                   6701:                 * Start out Async/Narrow/Untagged and with
                   6702:                 * conservative protocol support.
                   6703:                 */
                   6704:                tstate->tagenable &= ~target_mask;
                   6705:                tinfo->goal.protocol_version = 2;
                   6706:                tinfo->goal.transport_version = 2;
                   6707:                tinfo->curr.protocol_version = 2;
                   6708:                tinfo->curr.transport_version = 2;
                   6709:                ahd_compile_devinfo(&devinfo, ahd->our_id,
                   6710:                                    targ, CAM_LUN_WILDCARD,
                   6711:                                    'A', ROLE_INITIATOR);
                   6712:                ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
                   6713:                              AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE);
                   6714:                ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0,
                   6715:                                 /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL,
                   6716:                                 /*paused*/TRUE);
                   6717:        }
                   6718:
                   6719:        ahd->flags &= ~AHD_SPCHK_ENB_A;
                   6720:        if (sc->bios_control & CFSPARITY)
                   6721:                ahd->flags |= AHD_SPCHK_ENB_A;
                   6722:
                   6723:        ahd->flags &= ~AHD_RESET_BUS_A;
                   6724:        if (sc->bios_control & CFRESETB)
                   6725:                ahd->flags |= AHD_RESET_BUS_A;
                   6726:
                   6727:        ahd->flags &= ~AHD_EXTENDED_TRANS_A;
                   6728:        if (sc->bios_control & CFEXTEND)
                   6729:                ahd->flags |= AHD_EXTENDED_TRANS_A;
                   6730:
                   6731:        ahd->flags &= ~AHD_BIOS_ENABLED;
                   6732:        if ((sc->bios_control & CFBIOSSTATE) == CFBS_ENABLED)
                   6733:                ahd->flags |= AHD_BIOS_ENABLED;
                   6734:
                   6735:        ahd->flags &= ~AHD_STPWLEVEL_A;
                   6736:        if ((sc->adapter_control & CFSTPWLEVEL) != 0)
                   6737:                ahd->flags |= AHD_STPWLEVEL_A;
                   6738:
                   6739:        return (0);
                   6740: }
                   6741:
1.9       thorpej  6742: /*
                   6743:  * Parse device configuration information.
                   6744:  */
                   6745: int
                   6746: ahd_parse_vpddata(struct ahd_softc *ahd, struct vpd_config *vpd)
                   6747: {
                   6748:        int error;
                   6749:
                   6750:        error = ahd_verify_vpd_cksum(vpd);
                   6751:        if (error == 0)
                   6752:                return (EINVAL);
                   6753:        if ((vpd->bios_flags & VPDBOOTHOST) != 0)
                   6754:                ahd->flags |= AHD_BOOT_CHANNEL;
                   6755:        return (0);
                   6756: }
                   6757:
1.1       fvdl     6758: void
                   6759: ahd_intr_enable(struct ahd_softc *ahd, int enable)
                   6760: {
                   6761:        u_int hcntrl;
                   6762:
                   6763:        hcntrl = ahd_inb(ahd, HCNTRL);
                   6764:        hcntrl &= ~INTEN;
                   6765:        ahd->pause &= ~INTEN;
                   6766:        ahd->unpause &= ~INTEN;
                   6767:        if (enable) {
                   6768:                hcntrl |= INTEN;
                   6769:                ahd->pause |= INTEN;
                   6770:                ahd->unpause |= INTEN;
                   6771:        }
                   6772:        ahd_outb(ahd, HCNTRL, hcntrl);
                   6773: }
                   6774:
                   6775: void
1.5       wiz      6776: ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds,
1.1       fvdl     6777:                             u_int mincmds)
                   6778: {
                   6779:        if (timer > AHD_TIMER_MAX_US)
                   6780:                timer = AHD_TIMER_MAX_US;
1.5       wiz      6781:        ahd->int_coalescing_timer = timer;
1.1       fvdl     6782:
1.5       wiz      6783:        if (maxcmds > AHD_INT_COALESCING_MAXCMDS_MAX)
                   6784:                maxcmds = AHD_INT_COALESCING_MAXCMDS_MAX;
                   6785:        if (mincmds > AHD_INT_COALESCING_MINCMDS_MAX)
                   6786:                mincmds = AHD_INT_COALESCING_MINCMDS_MAX;
                   6787:        ahd->int_coalescing_maxcmds = maxcmds;
                   6788:        ahd_outw(ahd, INT_COALESCING_TIMER, timer / AHD_TIMER_US_PER_TICK);
                   6789:        ahd_outb(ahd, INT_COALESCING_MAXCMDS, -maxcmds);
                   6790:        ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds);
1.1       fvdl     6791: }
                   6792:
                   6793: void
1.5       wiz      6794: ahd_enable_coalescing(struct ahd_softc *ahd, int enable)
1.1       fvdl     6795: {
                   6796:
1.5       wiz      6797:        ahd->hs_mailbox &= ~ENINT_COALESCE;
1.1       fvdl     6798:        if (enable)
1.5       wiz      6799:                ahd->hs_mailbox |= ENINT_COALESCE;
1.1       fvdl     6800:        ahd_outb(ahd, HS_MAILBOX, ahd->hs_mailbox);
                   6801:        ahd_flush_device_writes(ahd);
                   6802:        ahd_run_qoutfifo(ahd);
                   6803: }
                   6804:
                   6805: /*
                   6806:  * Ensure that the card is paused in a location
                   6807:  * outside of all critical sections and that all
                   6808:  * pending work is completed prior to returning.
                   6809:  * This routine should only be called from outside
                   6810:  * an interrupt context.
                   6811:  */
                   6812: void
                   6813: ahd_pause_and_flushwork(struct ahd_softc *ahd)
                   6814: {
1.9       thorpej  6815:        u_int intstat;
                   6816:        u_int maxloops;
                   6817:        u_int qfreeze_cnt;
1.1       fvdl     6818:
                   6819:        maxloops = 1000;
                   6820:        ahd->flags |= AHD_ALL_INTERRUPTS;
1.9       thorpej  6821:        ahd_pause(ahd);
                   6822:        /*
                   6823:         * Increment the QFreeze Count so that the sequencer
                   6824:         * will not start new selections.  We do this only
                   6825:         * until we are safely paused without further selections
                   6826:         * pending.
                   6827:         */
                   6828:        ahd_outw(ahd, QFREEZE_COUNT, ahd_inw(ahd, QFREEZE_COUNT) + 1);
                   6829:        ahd_outb(ahd, SEQ_FLAGS2, ahd_inb(ahd, SEQ_FLAGS2) | SELECTOUT_QFROZEN);
1.1       fvdl     6830:        do {
                   6831:                struct scb *waiting_scb;
                   6832:
1.9       thorpej  6833:                ahd_unpause(ahd);
1.1       fvdl     6834:                ahd_intr(ahd);
                   6835:                ahd_pause(ahd);
                   6836:                ahd_clear_critical_section(ahd);
1.9       thorpej  6837:                intstat = ahd_inb(ahd, INTSTAT);
1.1       fvdl     6838:                ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   6839:                if ((ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0)
                   6840:                        ahd_outb(ahd, SCSISEQ0,
                   6841:                                 ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
                   6842:                /*
                   6843:                 * In the non-packetized case, the sequencer (for Rev A),
                   6844:                 * relies on ENSELO remaining set after SELDO.  The hardware
                   6845:                 * auto-clears ENSELO in the packetized case.
                   6846:                 */
                   6847:                waiting_scb = ahd_lookup_scb(ahd,
                   6848:                                             ahd_inw(ahd, WAITING_TID_HEAD));
                   6849:                if (waiting_scb != NULL
                   6850:                 && (waiting_scb->flags & SCB_PACKETIZED) == 0
                   6851:                 && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0)
                   6852:                        ahd_outb(ahd, SCSISEQ0,
                   6853:                                 ahd_inb(ahd, SCSISEQ0) | ENSELO);
                   6854:        } while (--maxloops
                   6855:                 && (intstat != 0xFF || (ahd->features & AHD_REMOVABLE) == 0)
                   6856:                 && ((intstat & INT_PEND) != 0
1.9       thorpej  6857:                  || (ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
                   6858:                  || (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0));
1.1       fvdl     6859:        if (maxloops == 0) {
                   6860:                printf("Infinite interrupt loop, INTSTAT = %x",
                   6861:                      ahd_inb(ahd, INTSTAT));
                   6862:        }
1.9       thorpej  6863:        qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT);
                   6864:        if (qfreeze_cnt == 0) {
                   6865:                printf("%s: ahd_pause_and_flushwork with 0 qfreeze count!\n",
                   6866:                       ahd_name(ahd));
                   6867:        } else {
                   6868:                qfreeze_cnt--;
                   6869:        }
                   6870:        ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt);
                   6871:        if (qfreeze_cnt == 0)
                   6872:                ahd_outb(ahd, SEQ_FLAGS2,
                   6873:                         ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN);
1.1       fvdl     6874:
                   6875:        ahd_flush_qoutfifo(ahd);
                   6876:
                   6877:        ahd_platform_flushwork(ahd);
                   6878:        ahd->flags &= ~AHD_ALL_INTERRUPTS;
                   6879: }
                   6880:
                   6881: int
                   6882: ahd_suspend(struct ahd_softc *ahd)
                   6883: {
                   6884:
                   6885:        ahd_pause_and_flushwork(ahd);
                   6886:
1.15      thorpej  6887:        if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
                   6888:                ahd_unpause(ahd);
1.1       fvdl     6889:                return (EBUSY);
                   6890:        }
                   6891:        ahd_shutdown(ahd);
                   6892:        return (0);
                   6893: }
                   6894:
                   6895: int
                   6896: ahd_resume(struct ahd_softc *ahd)
                   6897: {
                   6898:
1.15      thorpej  6899:        ahd_reset(ahd, /*reinit*/TRUE);
                   6900:        ahd_intr_enable(ahd, TRUE);
                   6901:        ahd_restart(ahd);
1.1       fvdl     6902:        return (0);
                   6903: }
                   6904:
                   6905: /************************** Busy Target Table *********************************/
                   6906: /*
                   6907:  * Set SCBPTR to the SCB that contains the busy
                   6908:  * table entry for TCL.  Return the offset into
                   6909:  * the SCB that contains the entry for TCL.
                   6910:  * saved_scbid is dereferenced and set to the
1.64      andvar   6911:  * scbid that should be restored once manipulation
1.1       fvdl     6912:  * of the TCL entry is complete.
                   6913:  */
1.33      perry    6914: static inline u_int
1.1       fvdl     6915: ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl)
                   6916: {
                   6917:        /*
                   6918:         * Index to the SCB that contains the busy entry.
                   6919:         */
                   6920:        AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                   6921:        *saved_scbid = ahd_get_scbptr(ahd);
                   6922:        ahd_set_scbptr(ahd, TCL_LUN(tcl)
                   6923:                     | ((TCL_TARGET_OFFSET(tcl) & 0xC) << 4));
                   6924:
                   6925:        /*
                   6926:         * And now calculate the SCB offset to the entry.
                   6927:         * Each entry is 2 bytes wide, hence the
                   6928:         * multiplication by 2.
                   6929:         */
                   6930:        return (((TCL_TARGET_OFFSET(tcl) & 0x3) << 1) + SCB_DISCONNECTED_LISTS);
                   6931: }
                   6932:
                   6933: /*
                   6934:  * Return the untagged transaction id for a given target/channel lun.
                   6935:  */
                   6936: u_int
                   6937: ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl)
                   6938: {
                   6939:        u_int scbid;
                   6940:        u_int scb_offset;
                   6941:        u_int saved_scbptr;
1.30      perry    6942:
1.1       fvdl     6943:        scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
                   6944:        scbid = ahd_inw_scbram(ahd, scb_offset);
                   6945:        ahd_set_scbptr(ahd, saved_scbptr);
                   6946:        return (scbid);
                   6947: }
                   6948:
                   6949: void
                   6950: ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid)
                   6951: {
                   6952:        u_int scb_offset;
                   6953:        u_int saved_scbptr;
1.30      perry    6954:
1.1       fvdl     6955:        scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
                   6956:        ahd_outw(ahd, scb_offset, scbid);
                   6957:        ahd_set_scbptr(ahd, saved_scbptr);
                   6958: }
                   6959:
                   6960: /************************** SCB and SCB queue management **********************/
                   6961: int
1.36      christos 6962: ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target,
                   6963:              char channel, int lun, u_int tag, role_t role)
1.1       fvdl     6964: {
                   6965:        int targ = SCB_GET_TARGET(ahd, scb);
                   6966:        char chan = SCB_GET_CHANNEL(ahd, scb);
                   6967:        int slun = SCB_GET_LUN(scb);
                   6968:        int match;
                   6969:
                   6970:        match = ((chan == channel) || (channel == ALL_CHANNELS));
                   6971:        if (match != 0)
                   6972:                match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
                   6973:        if (match != 0)
                   6974:                match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
                   6975:        if (match != 0) {
                   6976: #if AHD_TARGET_MODE
                   6977:                int group;
                   6978:
                   6979:                group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
                   6980:                if (role == ROLE_INITIATOR) {
                   6981:                        match = (group != XPT_FC_GROUP_TMODE)
                   6982:                              && ((tag == SCB_GET_TAG(scb))
                   6983:                               || (tag == SCB_LIST_NULL));
                   6984:                } else if (role == ROLE_TARGET) {
                   6985:                        match = (group == XPT_FC_GROUP_TMODE)
                   6986:                              && ((tag == scb->io_ctx->csio.tag_id)
                   6987:                               || (tag == SCB_LIST_NULL));
                   6988:                }
                   6989: #else /* !AHD_TARGET_MODE */
                   6990:                match = ((tag == SCB_GET_TAG(scb)) || (tag == SCB_LIST_NULL));
                   6991: #endif /* AHD_TARGET_MODE */
                   6992:        }
                   6993:
                   6994:        return match;
                   6995: }
                   6996:
                   6997: void
                   6998: ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
                   6999: {
                   7000:        int     target;
                   7001:        char    channel;
                   7002:        int     lun;
                   7003:
                   7004:        target = SCB_GET_TARGET(ahd, scb);
                   7005:        lun = SCB_GET_LUN(scb);
                   7006:        channel = SCB_GET_CHANNEL(ahd, scb);
1.30      perry    7007:
1.1       fvdl     7008:        ahd_search_qinfifo(ahd, target, channel, lun,
                   7009:                           /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,
                   7010:                           CAM_REQUEUE_REQ, SEARCH_COMPLETE);
                   7011:
                   7012:        ahd_platform_freeze_devq(ahd, scb);
                   7013: }
                   7014:
                   7015: void
                   7016: ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, struct scb *scb)
                   7017: {
                   7018:        struct scb      *prev_scb;
                   7019:        ahd_mode_state   saved_modes;
                   7020:
                   7021:        saved_modes = ahd_save_modes(ahd);
                   7022:        ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
                   7023:        prev_scb = NULL;
                   7024:        if (ahd_qinfifo_count(ahd) != 0) {
                   7025:                u_int prev_tag;
                   7026:                u_int prev_pos;
                   7027:
                   7028:                prev_pos = AHD_QIN_WRAP(ahd->qinfifonext - 1);
                   7029:                prev_tag = ahd->qinfifo[prev_pos];
                   7030:                prev_scb = ahd_lookup_scb(ahd, prev_tag);
                   7031:        }
                   7032:        ahd_qinfifo_requeue(ahd, prev_scb, scb);
                   7033:        ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
                   7034:        ahd_restore_modes(ahd, saved_modes);
                   7035: }
                   7036:
                   7037: static void
                   7038: ahd_qinfifo_requeue(struct ahd_softc *ahd, struct scb *prev_scb,
                   7039:                    struct scb *scb)
                   7040: {
                   7041:        if (prev_scb == NULL) {
                   7042:                uint32_t busaddr;
                   7043:
                   7044:                busaddr = ahd_le32toh(scb->hscb->hscb_busaddr);
                   7045:                ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
                   7046:                ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
                   7047:                ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
                   7048:                ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
                   7049:        } else {
                   7050:                prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr;
1.30      perry    7051:                ahd_sync_scb(ahd, prev_scb,
1.1       fvdl     7052:                             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   7053:        }
                   7054:        ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb);
                   7055:        ahd->qinfifonext++;
                   7056:        scb->hscb->next_hscb_busaddr = ahd->next_queued_hscb->hscb_busaddr;
                   7057:        ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   7058: }
                   7059:
                   7060: static int
                   7061: ahd_qinfifo_count(struct ahd_softc *ahd)
                   7062: {
                   7063:        u_int qinpos;
                   7064:        u_int wrap_qinpos;
                   7065:        u_int wrap_qinfifonext;
                   7066:
                   7067:        AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
                   7068:        qinpos = ahd_get_snscb_qoff(ahd);
                   7069:        wrap_qinpos = AHD_QIN_WRAP(qinpos);
                   7070:        wrap_qinfifonext = AHD_QIN_WRAP(ahd->qinfifonext);
                   7071:        if (wrap_qinfifonext >= wrap_qinpos)
                   7072:                return (wrap_qinfifonext - wrap_qinpos);
                   7073:        else
                   7074:                return (wrap_qinfifonext
                   7075:                      + NUM_ELEMENTS(ahd->qinfifo) - wrap_qinpos);
                   7076: }
                   7077:
                   7078: void
                   7079: ahd_reset_cmds_pending(struct ahd_softc *ahd)
                   7080: {
                   7081:        struct          scb *scb;
                   7082:        ahd_mode_state  saved_modes;
                   7083:        u_int           pending_cmds;
                   7084:
                   7085:        saved_modes = ahd_save_modes(ahd);
                   7086:        ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
                   7087:
                   7088:        /*
                   7089:         * Don't count any commands as outstanding that the
                   7090:         * sequencer has already marked for completion.
                   7091:         */
                   7092:        ahd_flush_qoutfifo(ahd);
                   7093:
                   7094:        pending_cmds = 0;
                   7095:        LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
                   7096:                pending_cmds++;
                   7097:        }
                   7098:        ahd_outw(ahd, CMDS_PENDING, pending_cmds - ahd_qinfifo_count(ahd));
                   7099:        ahd_restore_modes(ahd, saved_modes);
                   7100:        ahd->flags &= ~AHD_UPDATE_PEND_CMDS;
                   7101: }
                   7102:
                   7103: int
                   7104: ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
                   7105:                   int lun, u_int tag, role_t role, uint32_t status,
                   7106:                   ahd_search_action action)
                   7107: {
                   7108:        struct scb      *scb;
                   7109:        struct scb      *prev_scb;
                   7110:        ahd_mode_state   saved_modes;
                   7111:        u_int            qinstart;
                   7112:        u_int            qinpos;
                   7113:        u_int            qintail;
                   7114:        u_int            tid_next;
                   7115:        u_int            tid_prev;
                   7116:        u_int            scbid;
                   7117:        u_int            savedscbptr;
                   7118:        uint32_t         busaddr;
                   7119:        int              found;
                   7120:        int              targets;
                   7121:        int              pending_cmds;
                   7122:
                   7123:        /* Must be in CCHAN mode */
                   7124:        saved_modes = ahd_save_modes(ahd);
                   7125:        ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
                   7126:
                   7127:        /*
                   7128:         * Halt any pending SCB DMA.  The sequencer will reinitiate
1.4       wiz      7129:         * this DMA if the qinfifo is not empty once we unpause.
1.1       fvdl     7130:         */
                   7131:        if ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN|CCSCBDIR))
                   7132:            == (CCARREN|CCSCBEN|CCSCBDIR)) {
                   7133:                ahd_outb(ahd, CCSCBCTL,
                   7134:                         ahd_inb(ahd, CCSCBCTL) & ~(CCARREN|CCSCBEN));
                   7135:                while ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0)
                   7136:                        ;
                   7137:        }
                   7138:        /* Determine sequencer's position in the qinfifo. */
                   7139:        qintail = AHD_QIN_WRAP(ahd->qinfifonext);
                   7140:        qinstart = ahd_get_snscb_qoff(ahd);
                   7141:        qinpos = AHD_QIN_WRAP(qinstart);
                   7142:        found = 0;
                   7143:        prev_scb = NULL;
                   7144:
                   7145:        pending_cmds = 0;
                   7146:        LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
                   7147:                pending_cmds++;
                   7148:        }
1.46      christos 7149:        (void)ahd_qinfifo_count(ahd);
1.1       fvdl     7150:
                   7151:        if (action == SEARCH_PRINT) {
                   7152:                printf("qinstart = 0x%x qinfifonext = 0x%x\n",
                   7153:                       qinstart, ahd->qinfifonext);
                   7154:        }
                   7155:
                   7156:        /*
                   7157:         * Start with an empty queue.  Entries that are not chosen
                   7158:         * for removal will be re-added to the queue as we go.
                   7159:         */
                   7160:        ahd->qinfifonext = qinstart;
                   7161:        busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
                   7162:        ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
                   7163:        ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
                   7164:        ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
                   7165:        ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
                   7166:
                   7167:        while (qinpos != qintail) {
                   7168:                scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]);
                   7169:                if (scb == NULL) {
                   7170:                        panic("Loop 1\n");
                   7171:                }
                   7172:
                   7173:                if (ahd_match_scb(ahd, scb, target, channel, lun, tag, role)) {
                   7174:                        /*
                   7175:                         * We found an scb that needs to be acted on.
                   7176:                         */
                   7177:                        found++;
                   7178:                        switch (action) {
                   7179:                        case SEARCH_COMPLETE:
                   7180:                        {
1.43      tsutsui  7181:                                cam_status ostat;
                   7182:                                cam_status cstat;
1.1       fvdl     7183:
                   7184:                                ostat = ahd_get_scsi_status(scb);
                   7185:                                if (ostat == CAM_REQ_INPROG)
                   7186:                                        ahd_set_scsi_status(scb, status);
                   7187:                                cstat = ahd_get_transaction_status(scb);
                   7188:                                if (cstat != CAM_REQ_CMP)
                   7189:                                        ahd_freeze_scb(scb);
                   7190:                                if ((scb->flags & SCB_ACTIVE) == 0)
                   7191:                                        printf("Inactive SCB in qinfifo\n");
1.45      mrg      7192:                                if ((cam_status)scb->xs->error != CAM_REQ_CMP)
1.44      tsutsui  7193:                                        printf("SEARCH_COMPLETE(0x%x):"
                   7194:                                               " ostat 0x%x, cstat 0x%x, "
                   7195:                                               "xs_error 0x%x\n",
                   7196:                                               SCB_GET_TAG(scb), ostat, cstat,
                   7197:                                               scb->xs->error);
1.1       fvdl     7198:                                ahd_done(ahd, scb);
                   7199:
                   7200:                                /* FALLTHROUGH */
                   7201:                        }
                   7202:                        case SEARCH_REMOVE:
                   7203:                                break;
                   7204:                        case SEARCH_PRINT:
                   7205:                                printf(" 0x%x", ahd->qinfifo[qinpos]);
                   7206:                                /* FALLTHROUGH */
                   7207:                        case SEARCH_COUNT:
                   7208:                                ahd_qinfifo_requeue(ahd, prev_scb, scb);
                   7209:                                prev_scb = scb;
                   7210:                                break;
                   7211:                        }
                   7212:                } else {
                   7213:                        ahd_qinfifo_requeue(ahd, prev_scb, scb);
                   7214:                        prev_scb = scb;
                   7215:                }
                   7216:                qinpos = AHD_QIN_WRAP(qinpos+1);
                   7217:        }
                   7218:
                   7219:        ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
                   7220:
                   7221:        if (action == SEARCH_PRINT)
                   7222:                printf("\nWAITING_TID_QUEUES:\n");
                   7223:
                   7224:        /*
                   7225:         * Search waiting for selection lists.  We traverse the
                   7226:         * list of "their ids" waiting for selection and, if
                   7227:         * appropriate, traverse the SCBs of each "their id"
                   7228:         * looking for matches.
                   7229:         */
                   7230:        savedscbptr = ahd_get_scbptr(ahd);
                   7231:        tid_next = ahd_inw(ahd, WAITING_TID_HEAD);
                   7232:        tid_prev = SCB_LIST_NULL;
                   7233:        targets = 0;
                   7234:        for (scbid = tid_next; !SCBID_IS_NULL(scbid); scbid = tid_next) {
                   7235:                u_int tid_head;
                   7236:
                   7237:                /*
                   7238:                 * We limit based on the number of SCBs since
                   7239:                 * MK_MESSAGE SCBs are not in the per-tid lists.
                   7240:                 */
                   7241:                targets++;
                   7242:                if (targets > AHD_SCB_MAX) {
                   7243:                        panic("TID LIST LOOP");
                   7244:                }
                   7245:                if (scbid >= ahd->scb_data.numscbs) {
                   7246:                        printf("%s: Waiting TID List inconsistency. "
                   7247:                               "SCB index == 0x%x, yet numscbs == 0x%x.",
                   7248:                               ahd_name(ahd), scbid, ahd->scb_data.numscbs);
                   7249:                        ahd_dump_card_state(ahd);
                   7250:                        panic("for safety");
                   7251:                }
                   7252:                scb = ahd_lookup_scb(ahd, scbid);
                   7253:                if (scb == NULL) {
                   7254:                        printf("%s: SCB = 0x%x Not Active!\n",
                   7255:                               ahd_name(ahd), scbid);
                   7256:                        panic("Waiting TID List traversal\n");
                   7257:                        break;
                   7258:                }
                   7259:                ahd_set_scbptr(ahd, scbid);
                   7260:                tid_next = ahd_inw_scbram(ahd, SCB_NEXT2);
                   7261:                if (ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD,
                   7262:                                  SCB_LIST_NULL, ROLE_UNKNOWN) == 0) {
                   7263:                        tid_prev = scbid;
                   7264:                        continue;
                   7265:                }
                   7266:
                   7267:                /*
                   7268:                 * We found a list of scbs that needs to be searched.
                   7269:                 */
                   7270:                if (action == SEARCH_PRINT)
                   7271:                        printf("       %d ( ", SCB_GET_TARGET(ahd, scb));
                   7272:                tid_head = scbid;
                   7273:                found += ahd_search_scb_list(ahd, target, channel,
                   7274:                                             lun, tag, role, status,
                   7275:                                             action, &tid_head,
                   7276:                                             SCB_GET_TARGET(ahd, scb));
                   7277:                if (tid_head != scbid)
                   7278:                        ahd_stitch_tid_list(ahd, tid_prev, tid_head, tid_next);
                   7279:                if (!SCBID_IS_NULL(tid_head))
                   7280:                        tid_prev = tid_head;
                   7281:                if (action == SEARCH_PRINT)
                   7282:                        printf(")\n");
                   7283:        }
                   7284:        ahd_set_scbptr(ahd, savedscbptr);
                   7285:        ahd_restore_modes(ahd, saved_modes);
                   7286:        return (found);
                   7287: }
                   7288:
                   7289: static int
                   7290: ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel,
1.36      christos 7291:                    int lun, u_int tag, role_t role, uint32_t status,
1.1       fvdl     7292:                    ahd_search_action action, u_int *list_head, u_int tid)
                   7293: {
                   7294:        struct  scb *scb;
                   7295:        u_int   scbid;
                   7296:        u_int   next;
                   7297:        u_int   prev;
                   7298:        int     found;
                   7299:
                   7300:        AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
                   7301:        found = 0;
                   7302:        prev = SCB_LIST_NULL;
                   7303:        next = *list_head;
                   7304:        for (scbid = next; !SCBID_IS_NULL(scbid); scbid = next) {
                   7305:                if (scbid >= ahd->scb_data.numscbs) {
                   7306:                        printf("%s:SCB List inconsistency. "
                   7307:                               "SCB == 0x%x, yet numscbs == 0x%x.",
                   7308:                               ahd_name(ahd), scbid, ahd->scb_data.numscbs);
                   7309:                        ahd_dump_card_state(ahd);
                   7310:                        panic("for safety");
                   7311:                }
                   7312:                scb = ahd_lookup_scb(ahd, scbid);
                   7313:                if (scb == NULL) {
                   7314:                        printf("%s: SCB = %d Not Active!\n",
                   7315:                               ahd_name(ahd), scbid);
                   7316:                        panic("Waiting List traversal\n");
                   7317:                }
                   7318:                ahd_set_scbptr(ahd, scbid);
                   7319:                next = ahd_inw_scbram(ahd, SCB_NEXT);
                   7320:                if (ahd_match_scb(ahd, scb, target, channel,
                   7321:                                  lun, SCB_LIST_NULL, role) == 0) {
                   7322:                        prev = scbid;
                   7323:                        continue;
                   7324:                }
                   7325:                found++;
                   7326:                switch (action) {
                   7327:                case SEARCH_COMPLETE:
                   7328:                {
                   7329:                        cam_status ostat;
                   7330:                        cam_status cstat;
                   7331:
                   7332:                        ostat = ahd_get_scsi_status(scb);
                   7333:                        if (ostat == CAM_REQ_INPROG)
                   7334:                                ahd_set_scsi_status(scb, status);
                   7335:                        cstat = ahd_get_transaction_status(scb);
                   7336:                        if (cstat != CAM_REQ_CMP)
                   7337:                                ahd_freeze_scb(scb);
                   7338:                        if ((scb->flags & SCB_ACTIVE) == 0)
                   7339:                                printf("Inactive SCB in Waiting List\n");
                   7340:                        ahd_done(ahd, scb);
                   7341:                }
1.51      mrg      7342:                /* FALLTHROUGH */
1.1       fvdl     7343:                case SEARCH_REMOVE:
                   7344:                        ahd_rem_wscb(ahd, scbid, prev, next, tid);
                   7345:                        if (prev == SCB_LIST_NULL)
                   7346:                                *list_head = next;
                   7347:                        break;
                   7348:                case SEARCH_PRINT:
                   7349:                        printf("0x%x ", scbid);
1.51      mrg      7350:                        /* FALLTHROUGH */
1.1       fvdl     7351:                case SEARCH_COUNT:
                   7352:                        prev = scbid;
                   7353:                        break;
                   7354:                }
                   7355:                if (found > AHD_SCB_MAX)
                   7356:                        panic("SCB LIST LOOP");
                   7357:        }
                   7358:        if (action == SEARCH_COMPLETE
                   7359:         || action == SEARCH_REMOVE)
                   7360:                ahd_outw(ahd, CMDS_PENDING, ahd_inw(ahd, CMDS_PENDING) - found);
                   7361:        return (found);
                   7362: }
                   7363:
                   7364: static void
                   7365: ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev,
                   7366:                    u_int tid_cur, u_int tid_next)
                   7367: {
                   7368:        AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
                   7369:
                   7370:        if (SCBID_IS_NULL(tid_cur)) {
                   7371:
                   7372:                /* Bypass current TID list */
                   7373:                if (SCBID_IS_NULL(tid_prev)) {
                   7374:                        ahd_outw(ahd, WAITING_TID_HEAD, tid_next);
                   7375:                } else {
                   7376:                        ahd_set_scbptr(ahd, tid_prev);
                   7377:                        ahd_outw(ahd, SCB_NEXT2, tid_next);
                   7378:                }
                   7379:                if (SCBID_IS_NULL(tid_next))
                   7380:                        ahd_outw(ahd, WAITING_TID_TAIL, tid_prev);
                   7381:        } else {
                   7382:
                   7383:                /* Stitch through tid_cur */
                   7384:                if (SCBID_IS_NULL(tid_prev)) {
                   7385:                        ahd_outw(ahd, WAITING_TID_HEAD, tid_cur);
                   7386:                } else {
                   7387:                        ahd_set_scbptr(ahd, tid_prev);
                   7388:                        ahd_outw(ahd, SCB_NEXT2, tid_cur);
                   7389:                }
                   7390:                ahd_set_scbptr(ahd, tid_cur);
                   7391:                ahd_outw(ahd, SCB_NEXT2, tid_next);
                   7392:
                   7393:                if (SCBID_IS_NULL(tid_next))
                   7394:                        ahd_outw(ahd, WAITING_TID_TAIL, tid_cur);
                   7395:        }
                   7396: }
                   7397:
                   7398: /*
                   7399:  * Manipulate the waiting for selection list and return the
                   7400:  * scb that follows the one that we remove.
                   7401:  */
                   7402: static u_int
                   7403: ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid,
                   7404:             u_int prev, u_int next, u_int tid)
                   7405: {
                   7406:        u_int tail_offset;
                   7407:
                   7408:        AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
                   7409:        if (!SCBID_IS_NULL(prev)) {
                   7410:                ahd_set_scbptr(ahd, prev);
                   7411:                ahd_outw(ahd, SCB_NEXT, next);
                   7412:        }
                   7413:
                   7414:        /*
                   7415:         * SCBs that had MK_MESSAGE set in them will not
                   7416:         * be queued to the per-target lists, so don't
                   7417:         * blindly clear the tail pointer.
                   7418:         */
                   7419:        tail_offset = WAITING_SCB_TAILS + (2 * tid);
                   7420:        if (SCBID_IS_NULL(next)
                   7421:         && ahd_inw(ahd, tail_offset) == scbid)
                   7422:                ahd_outw(ahd, tail_offset, prev);
                   7423:        ahd_add_scb_to_free_list(ahd, scbid);
                   7424:        return (next);
                   7425: }
                   7426:
                   7427: /*
                   7428:  * Add the SCB as selected by SCBPTR onto the on chip list of
                   7429:  * free hardware SCBs.  This list is empty/unused if we are not
                   7430:  * performing SCB paging.
                   7431:  */
                   7432: static void
1.36      christos 7433: ahd_add_scb_to_free_list(struct ahd_softc *ahd, u_int scbid)
1.1       fvdl     7434: {
1.35      christos 7435: #ifdef notdef
1.1       fvdl     7436: /* XXX Need some other mechanism to designate "free". */
                   7437:        /*
                   7438:         * Invalidate the tag so that our abort
                   7439:         * routines don't think it's active.
1.35      christos 7440:         */
1.1       fvdl     7441:        ahd_outb(ahd, SCB_TAG, SCB_LIST_NULL);
1.35      christos 7442: #endif
1.1       fvdl     7443: }
                   7444:
                   7445: /******************************** Error Handling ******************************/
                   7446: /*
                   7447:  * Abort all SCBs that match the given description (target/channel/lun/tag),
                   7448:  * setting their status to the passed in status if the status has not already
                   7449:  * been modified from CAM_REQ_INPROG.  This routine assumes that the sequencer
                   7450:  * is paused before it is called.
                   7451:  */
                   7452: int
                   7453: ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
                   7454:               int lun, u_int tag, role_t role, uint32_t status)
                   7455: {
                   7456:        struct          scb *scbp;
                   7457:        struct          scb *scbp_next;
                   7458:        u_int           i, j;
                   7459:        u_int           maxtarget;
                   7460:        u_int           minlun;
                   7461:        u_int           maxlun;
                   7462:        int             found;
                   7463:        ahd_mode_state  saved_modes;
                   7464:
1.9       thorpej  7465:        /* restore this when we're done */
1.1       fvdl     7466:        saved_modes = ahd_save_modes(ahd);
1.9       thorpej  7467:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1.1       fvdl     7468:
                   7469:        found = ahd_search_qinfifo(ahd, target, channel, lun, SCB_LIST_NULL,
                   7470:                                   role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
                   7471:
                   7472:        /*
                   7473:         * Clean out the busy target table for any untagged commands.
                   7474:         */
                   7475:        i = 0;
                   7476:        maxtarget = 16;
                   7477:        if (target != CAM_TARGET_WILDCARD) {
                   7478:                i = target;
                   7479:                if (channel == 'B')
                   7480:                        i += 8;
                   7481:                maxtarget = i + 1;
                   7482:        }
                   7483:
                   7484:        if (lun == CAM_LUN_WILDCARD) {
                   7485:                minlun = 0;
                   7486:                maxlun = AHD_NUM_LUNS_NONPKT;
                   7487:        } else if (lun >= AHD_NUM_LUNS_NONPKT) {
                   7488:                minlun = maxlun = 0;
                   7489:        } else {
                   7490:                minlun = lun;
                   7491:                maxlun = lun + 1;
                   7492:        }
                   7493:
                   7494:        if (role != ROLE_TARGET) {
                   7495:                for (;i < maxtarget; i++) {
                   7496:                        for (j = minlun;j < maxlun; j++) {
                   7497:                                u_int scbid;
                   7498:                                u_int tcl;
                   7499:
                   7500:                                tcl = BUILD_TCL_RAW(i, 'A', j);
                   7501:                                scbid = ahd_find_busy_tcl(ahd, tcl);
                   7502:                                scbp = ahd_lookup_scb(ahd, scbid);
                   7503:                                if (scbp == NULL
                   7504:                                 || ahd_match_scb(ahd, scbp, target, channel,
                   7505:                                                  lun, tag, role) == 0)
                   7506:                                        continue;
                   7507:                                ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(i, 'A', j));
                   7508:                        }
                   7509:                }
                   7510:        }
                   7511:
                   7512:        /*
                   7513:         * Don't abort commands that have already completed,
                   7514:         * but haven't quite made it up to the host yet.
                   7515:         */
                   7516:        ahd_flush_qoutfifo(ahd);
                   7517:
                   7518:        /*
                   7519:         * Go through the pending CCB list and look for
                   7520:         * commands for this target that are still active.
                   7521:         * These are other tagged commands that were
                   7522:         * disconnected when the reset occurred.
                   7523:         */
                   7524:        scbp_next = LIST_FIRST(&ahd->pending_scbs);
                   7525:        while (scbp_next != NULL) {
                   7526:                scbp = scbp_next;
                   7527:                scbp_next = LIST_NEXT(scbp, pending_links);
                   7528:                if (ahd_match_scb(ahd, scbp, target, channel, lun, tag, role)) {
                   7529:                        cam_status ostat;
                   7530:
                   7531:                        ostat = ahd_get_scsi_status(scbp);
                   7532:                        if (ostat == CAM_REQ_INPROG)
                   7533:                                ahd_set_scsi_status(scbp, status);
                   7534:                        if (ahd_get_transaction_status(scbp) != CAM_REQ_CMP)
                   7535:                                ahd_freeze_scb(scbp);
                   7536:                        if ((scbp->flags & SCB_ACTIVE) == 0)
                   7537:                                printf("Inactive SCB on pending list\n");
                   7538:                        ahd_done(ahd, scbp);
                   7539:                        found++;
                   7540:                }
                   7541:        }
                   7542:        ahd_restore_modes(ahd, saved_modes);
                   7543:        ahd_platform_abort_scbs(ahd, target, channel, lun, tag, role, status);
                   7544:        ahd->flags |= AHD_UPDATE_PEND_CMDS;
                   7545:        return found;
                   7546: }
                   7547:
                   7548: static void
                   7549: ahd_reset_current_bus(struct ahd_softc *ahd)
                   7550: {
                   7551:        uint8_t scsiseq;
                   7552:
                   7553:        AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                   7554:        ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST);
                   7555:        scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO);
                   7556:        ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO);
1.19      thorpej  7557:        ahd_flush_device_writes(ahd);
1.1       fvdl     7558:        ahd_delay(AHD_BUSRESET_DELAY);
                   7559:        /* Turn off the bus reset */
                   7560:        ahd_outb(ahd, SCSISEQ0, scsiseq);
1.19      thorpej  7561:        ahd_flush_device_writes(ahd);
                   7562:        ahd_delay(AHD_BUSRESET_DELAY);
1.1       fvdl     7563:        if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) {
                   7564:                /*
                   7565:                 * 2A Razor #474
                   7566:                 * Certain chip state is not cleared for
                   7567:                 * SCSI bus resets that we initiate, so
                   7568:                 * we must reset the chip.
                   7569:                 */
1.15      thorpej  7570:                ahd_reset(ahd, /*reinit*/TRUE);
1.1       fvdl     7571:                ahd_intr_enable(ahd, /*enable*/TRUE);
                   7572:                AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                   7573:        }
                   7574:
                   7575:        ahd_clear_intstat(ahd);
                   7576: }
                   7577:
                   7578: int
                   7579: ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
                   7580: {
                   7581:        struct  ahd_devinfo devinfo;
                   7582:        u_int   initiator;
                   7583:        u_int   target;
                   7584:        u_int   max_scsiid;
                   7585:        int     found;
                   7586:        u_int   fifo;
                   7587:        u_int   next_fifo;
                   7588:
                   7589:
                   7590:        ahd->pending_device = NULL;
                   7591:
                   7592:        ahd_compile_devinfo(&devinfo,
                   7593:                            CAM_TARGET_WILDCARD,
                   7594:                            CAM_TARGET_WILDCARD,
                   7595:                            CAM_LUN_WILDCARD,
                   7596:                            channel, ROLE_UNKNOWN);
                   7597:        ahd_pause(ahd);
                   7598:
                   7599:        /* Make sure the sequencer is in a safe location. */
                   7600:        ahd_clear_critical_section(ahd);
                   7601:
                   7602: #if AHD_TARGET_MODE
                   7603:        if ((ahd->flags & AHD_TARGETROLE) != 0) {
                   7604:                ahd_run_tqinfifo(ahd, /*paused*/TRUE);
                   7605:        }
                   7606: #endif
                   7607:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   7608:
                   7609:        /*
                   7610:         * Disable selections so no automatic hardware
                   7611:         * functions will modify chip state.
                   7612:         */
                   7613:        ahd_outb(ahd, SCSISEQ0, 0);
                   7614:        ahd_outb(ahd, SCSISEQ1, 0);
                   7615:
                   7616:        /*
                   7617:         * Safely shut down our DMA engines.  Always start with
                   7618:         * the FIFO that is not currently active (if any are
                   7619:         * actively connected).
                   7620:         */
                   7621:        next_fifo = fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO;
                   7622:        if (next_fifo > CURRFIFO_1)
                   7623:                /* If disconneced, arbitrarily start with FIFO1. */
                   7624:                next_fifo = fifo = 0;
                   7625:        do {
                   7626:                next_fifo ^= CURRFIFO_1;
                   7627:                ahd_set_modes(ahd, next_fifo, next_fifo);
                   7628:                ahd_outb(ahd, DFCNTRL,
                   7629:                         ahd_inb(ahd, DFCNTRL) & ~(SCSIEN|HDMAEN));
                   7630:                while ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0)
                   7631:                        ahd_delay(10);
                   7632:                /*
                   7633:                 * Set CURRFIFO to the now inactive channel.
                   7634:                 */
                   7635:                ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   7636:                ahd_outb(ahd, DFFSTAT, next_fifo);
                   7637:        } while (next_fifo != fifo);
1.9       thorpej  7638:
1.1       fvdl     7639:        /*
                   7640:         * Reset the bus if we are initiating this reset
                   7641:         */
                   7642:        ahd_clear_msg_state(ahd);
                   7643:        ahd_outb(ahd, SIMODE1,
                   7644:                 ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST|ENBUSFREE));
1.9       thorpej  7645:
1.1       fvdl     7646:        if (initiate_reset)
                   7647:                ahd_reset_current_bus(ahd);
1.9       thorpej  7648:
1.1       fvdl     7649:        ahd_clear_intstat(ahd);
                   7650:
                   7651:        /*
                   7652:         * Clean up all the state information for the
                   7653:         * pending transactions on this bus.
                   7654:         */
                   7655:        found = ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, channel,
                   7656:                               CAM_LUN_WILDCARD, SCB_LIST_NULL,
                   7657:                               ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
                   7658:
                   7659:        /*
                   7660:         * Cleanup anything left in the FIFOs.
                   7661:         */
                   7662:        ahd_clear_fifo(ahd, 0);
                   7663:        ahd_clear_fifo(ahd, 1);
                   7664:
                   7665:        /*
                   7666:         * Revert to async/narrow transfers until we renegotiate.
                   7667:         */
                   7668:        max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7;
                   7669:        for (target = 0; target <= max_scsiid; target++) {
                   7670:
                   7671:                if (ahd->enabled_targets[target] == NULL)
                   7672:                        continue;
                   7673:                for (initiator = 0; initiator <= max_scsiid; initiator++) {
1.31      christos 7674:                        struct ahd_devinfo dinfo;
1.1       fvdl     7675:
1.31      christos 7676:                        ahd_compile_devinfo(&dinfo, target, initiator,
1.1       fvdl     7677:                                            CAM_LUN_WILDCARD,
                   7678:                                            'A', ROLE_UNKNOWN);
1.31      christos 7679:                        ahd_set_width(ahd, &dinfo, MSG_EXT_WDTR_BUS_8_BIT,
1.1       fvdl     7680:                                      AHD_TRANS_CUR, /*paused*/TRUE);
1.31      christos 7681:                        ahd_set_syncrate(ahd, &dinfo, /*period*/0,
1.1       fvdl     7682:                                         /*offset*/0, /*ppr_options*/0,
                   7683:                                         AHD_TRANS_CUR, /*paused*/TRUE);
                   7684:                }
                   7685:        }
                   7686:
                   7687: #ifdef AHD_TARGET_MODE
                   7688:        max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7;
                   7689:
                   7690:        /*
                   7691:         * Send an immediate notify ccb to all target more peripheral
                   7692:         * drivers affected by this action.
                   7693:         */
                   7694:        for (target = 0; target <= max_scsiid; target++) {
                   7695:                struct ahd_tmode_tstate* tstate;
                   7696:                u_int lun;
                   7697:
                   7698:                tstate = ahd->enabled_targets[target];
                   7699:                if (tstate == NULL)
                   7700:                        continue;
                   7701:                for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
                   7702:                        struct ahd_tmode_lstate* lstate;
                   7703:
                   7704:                        lstate = tstate->enabled_luns[lun];
                   7705:                        if (lstate == NULL)
                   7706:                                continue;
                   7707:
                   7708:                        ahd_queue_lstate_event(ahd, lstate, CAM_TARGET_WILDCARD,
                   7709:                                               EVENT_TYPE_BUS_RESET, /*arg*/0);
                   7710:                        ahd_send_lstate_events(ahd, lstate);
                   7711:                }
                   7712:        }
                   7713: #endif
                   7714:
                   7715:        /* Notify the XPT that a bus reset occurred */
                   7716:        ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
                   7717:                       CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
                   7718:        ahd_restart(ahd);
                   7719:
                   7720:        /*
                   7721:         * Freeze the SIMQ until our poller can determine that
                   7722:         * the bus reset has really gone away.  We set the initial
                   7723:         * timer to 0 to have the check performed as soon as possible
                   7724:         * from the timer context.
                   7725:         */
                   7726:        if ((ahd->flags & AHD_RESET_POLL_ACTIVE) == 0) {
                   7727:                ahd->flags |= AHD_RESET_POLL_ACTIVE;
                   7728:                ahd_freeze_simq(ahd);
                   7729:                ahd_timer_reset(&ahd->reset_timer, 0, ahd_reset_poll, ahd);
                   7730:        }
                   7731:        return (found);
                   7732: }
                   7733:
                   7734:
                   7735: #define AHD_RESET_POLL_US 1000
                   7736: static void
                   7737: ahd_reset_poll(void *arg)
                   7738: {
                   7739:        struct  ahd_softc *ahd;
                   7740:        u_int   scsiseq1;
                   7741:        u_long  l;
                   7742:        int     s;
1.30      perry    7743:
1.1       fvdl     7744:        ahd_list_lock(&l);
1.44      tsutsui  7745:        ahd = arg;
1.1       fvdl     7746:        if (ahd == NULL) {
                   7747:                printf("ahd_reset_poll: Instance %p no longer exists\n", arg);
                   7748:                ahd_list_unlock(&l);
                   7749:                return;
                   7750:        }
                   7751:        ahd_lock(ahd, &s);
                   7752:        ahd_pause(ahd);
                   7753:        ahd_update_modes(ahd);
                   7754:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   7755:        ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
                   7756:        if ((ahd_inb(ahd, SSTAT1) & SCSIRSTI) != 0) {
                   7757:                ahd_timer_reset(&ahd->reset_timer, AHD_RESET_POLL_US,
                   7758:                                ahd_reset_poll, ahd);
                   7759:                ahd_unpause(ahd);
                   7760:                ahd_unlock(ahd, &s);
                   7761:                ahd_list_unlock(&l);
                   7762:                return;
                   7763:        }
                   7764:
                   7765:        /* Reset is now low.  Complete chip reinitialization. */
                   7766:        ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST);
                   7767:        scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
                   7768:        ahd_outb(ahd, SCSISEQ1, scsiseq1 & (ENSELI|ENRSELI|ENAUTOATNP));
                   7769:        ahd_unpause(ahd);
                   7770:        ahd->flags &= ~AHD_RESET_POLL_ACTIVE;
                   7771:        ahd_unlock(ahd, &s);
                   7772:        ahd_release_simq(ahd);
                   7773:        ahd_list_unlock(&l);
                   7774: }
                   7775:
                   7776: /**************************** Statistics Processing ***************************/
                   7777: static void
                   7778: ahd_stat_timer(void *arg)
                   7779: {
                   7780:        struct  ahd_softc *ahd;
                   7781:        u_long  l;
                   7782:        int     s;
                   7783:        int     enint_coal;
1.30      perry    7784:
1.1       fvdl     7785:        ahd_list_lock(&l);
1.44      tsutsui  7786:        ahd = arg;
1.1       fvdl     7787:        if (ahd == NULL) {
                   7788:                printf("ahd_stat_timer: Instance %p no longer exists\n", arg);
                   7789:                ahd_list_unlock(&l);
                   7790:                return;
                   7791:        }
                   7792:        ahd_lock(ahd, &s);
                   7793:
1.5       wiz      7794:        enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
                   7795:        if (ahd->cmdcmplt_total > ahd->int_coalescing_threshold)
                   7796:                enint_coal |= ENINT_COALESCE;
                   7797:        else if (ahd->cmdcmplt_total < ahd->int_coalescing_stop_threshold)
                   7798:                enint_coal &= ~ENINT_COALESCE;
1.1       fvdl     7799:
1.5       wiz      7800:        if (enint_coal != (ahd->hs_mailbox & ENINT_COALESCE)) {
                   7801:                ahd_enable_coalescing(ahd, enint_coal);
1.1       fvdl     7802: #ifdef AHD_DEBUG
1.5       wiz      7803:                if ((ahd_debug & AHD_SHOW_INT_COALESCING) != 0)
                   7804:                        printf("%s: Interrupt coalescing "
1.1       fvdl     7805:                               "now %sabled. Cmds %d\n",
                   7806:                               ahd_name(ahd),
1.5       wiz      7807:                               (enint_coal & ENINT_COALESCE) ? "en" : "dis",
1.1       fvdl     7808:                               ahd->cmdcmplt_total);
                   7809: #endif
                   7810:        }
                   7811:
                   7812:        ahd->cmdcmplt_bucket = (ahd->cmdcmplt_bucket+1) & (AHD_STAT_BUCKETS-1);
                   7813:        ahd->cmdcmplt_total -= ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket];
                   7814:        ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket] = 0;
                   7815:        ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
                   7816:                        ahd_stat_timer, ahd);
                   7817:        ahd_unlock(ahd, &s);
                   7818:        ahd_list_unlock(&l);
                   7819: }
                   7820:
                   7821: /****************************** Status Processing *****************************/
                   7822: void
                   7823: ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb)
                   7824: {
                   7825:        if (scb->hscb->shared_data.istatus.scsi_status != 0) {
                   7826:                ahd_handle_scsi_status(ahd, scb);
                   7827:        } else {
                   7828:                ahd_calc_residual(ahd, scb);
                   7829:                ahd_done(ahd, scb);
                   7830:        }
                   7831: }
                   7832:
                   7833: void
                   7834: ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
                   7835: {
                   7836:        struct hardware_scb *hscb;
                   7837:        u_int  qfreeze_cnt;
                   7838:
                   7839:        /*
                   7840:         * The sequencer freezes its select-out queue
                   7841:         * anytime a SCSI status error occurs.  We must
                   7842:         * handle the error and decrement the QFREEZE count
                   7843:         * to allow the sequencer to continue.
                   7844:         */
1.30      perry    7845:        hscb = scb->hscb;
1.1       fvdl     7846:
                   7847:        /* Freeze the queue until the client sees the error. */
                   7848:        ahd_freeze_devq(ahd, scb);
                   7849:        ahd_freeze_scb(scb);
                   7850:        qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT);
                   7851:        if (qfreeze_cnt == 0) {
                   7852:                printf("%s: Bad status with 0 qfreeze count!\n", ahd_name(ahd));
                   7853:        } else {
                   7854:                qfreeze_cnt--;
                   7855:                ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt);
                   7856:        }
                   7857:        if (qfreeze_cnt == 0)
                   7858:                ahd_outb(ahd, SEQ_FLAGS2,
                   7859:                         ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN);
1.9       thorpej  7860:
1.1       fvdl     7861:        /* Don't want to clobber the original sense code */
                   7862:        if ((scb->flags & SCB_SENSE) != 0) {
                   7863:                /*
                   7864:                 * Clear the SCB_SENSE Flag and perform
                   7865:                 * a normal command completion.
                   7866:                 */
                   7867:                scb->flags &= ~SCB_SENSE;
                   7868:                ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
                   7869:                ahd_done(ahd, scb);
                   7870:                return;
                   7871:        }
                   7872:        ahd_set_scsi_status(scb, hscb->shared_data.istatus.scsi_status);
                   7873:        ahd_set_xfer_status(scb, hscb->shared_data.istatus.scsi_status);
                   7874:        switch (hscb->shared_data.istatus.scsi_status) {
                   7875:        case STATUS_PKT_SENSE:
                   7876:        {
                   7877:                struct scsi_status_iu_header *siu;
                   7878:
                   7879:                ahd_sync_sense(ahd, scb, BUS_DMASYNC_POSTREAD);
                   7880:                siu = (struct scsi_status_iu_header *)scb->sense_data;
                   7881:                ahd_set_scsi_status(scb, siu->status);
                   7882: #ifdef AHD_DEBUG
                   7883:                if ((ahd_debug & AHD_SHOW_SENSE) != 0) {
                   7884:                        ahd_print_path(ahd, scb);
                   7885:                        printf("SCB 0x%x Received PKT Status of 0x%x\n",
                   7886:                               SCB_GET_TAG(scb), siu->status);
                   7887:                }
                   7888: #endif
                   7889:                if ((siu->flags & SIU_RSPVALID) != 0) {
                   7890:                        scsipi_printaddr(scb->xs->xs_periph);
                   7891:                        if (scsi_4btoul(siu->pkt_failures_length) < 4) {
                   7892:                                printf("Unable to parse pkt_failures\n");
                   7893:                        } else {
                   7894:
                   7895:                                switch (SIU_PKTFAIL_CODE(siu)) {
                   7896:                                case SIU_PFC_NONE:
                   7897:                                        printf("No packet failure found\n");
                   7898:                                        break;
                   7899:                                case SIU_PFC_CIU_FIELDS_INVALID:
                   7900:                                        printf("Invalid Command IU Field\n");
                   7901:                                        break;
                   7902:                                case SIU_PFC_TMF_NOT_SUPPORTED:
                   7903:                                        printf("TMF not supportd\n");
                   7904:                                        break;
                   7905:                                case SIU_PFC_TMF_FAILED:
                   7906:                                        printf("TMF failed\n");
                   7907:                                        break;
                   7908:                                case SIU_PFC_INVALID_TYPE_CODE:
                   7909:                                        printf("Invalid L_Q Type code\n");
                   7910:                                        break;
                   7911:                                case SIU_PFC_ILLEGAL_REQUEST:
                   7912:                                        printf("Illegal request\n");
                   7913:                                default:
                   7914:                                        break;
                   7915:                                }
                   7916:                        }
                   7917:                        if (siu->status == SCSI_STATUS_OK)
1.44      tsutsui  7918:                                ahd_set_transaction_status(scb,
                   7919:                                    CAM_REQ_CMP_ERR);
1.1       fvdl     7920:                }
                   7921:                if ((siu->flags & SIU_SNSVALID) != 0) {
                   7922:                        scb->flags |= SCB_PKT_SENSE;
                   7923: #ifdef AHD_DEBUG
                   7924:                        if ((ahd_debug & AHD_SHOW_SENSE) != 0) {
1.44      tsutsui  7925:                                printf("Sense data available (%d)\n",
                   7926:                                       siu->sense_length[0]);
1.43      tsutsui  7927:                                printf("SK 0x%x ASC 0x%x ASCQ 0x%x\n",
1.44      tsutsui  7928:                                       ((uint8_t)scb->sense_data[
                   7929:                                        SIU_SENSE_OFFSET(siu)+2]) & 0x0F,
                   7930:                                       ((uint8_t)scb->sense_data[
                   7931:                                        SIU_SENSE_OFFSET(siu)+12]),
                   7932:                                       ((uint8_t)scb->sense_data[
                   7933:                                        SIU_SENSE_OFFSET(siu)+13]));
1.1       fvdl     7934:                        }
                   7935: #endif
                   7936:                }
                   7937:                ahd_done(ahd, scb);
                   7938:                break;
                   7939:        }
                   7940:        case SCSI_STATUS_CMD_TERMINATED:
                   7941:        case SCSI_STATUS_CHECK_COND:
                   7942:        {
                   7943:                struct ahd_devinfo devinfo;
                   7944:                struct ahd_dma_seg *sg;
1.29      thorpej  7945:                struct scsi_request_sense *sc;
1.1       fvdl     7946:                struct ahd_initiator_tinfo *targ_info;
                   7947:                struct ahd_tmode_tstate *tstate;
                   7948: #ifdef AHD_DEBUG
                   7949:                if (ahd_debug & AHD_SHOW_SENSE) {
                   7950:                        ahd_print_path(ahd, scb);
                   7951:                        printf("SCB %d: requests Check Status\n",
                   7952:                               SCB_GET_TAG(scb));
                   7953:                }
                   7954: #endif
                   7955:
                   7956:                if (ahd_perform_autosense(scb) == 0)
                   7957:                        break;
                   7958:
                   7959:                ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
                   7960:                                    SCB_GET_TARGET(ahd, scb),
                   7961:                                    SCB_GET_LUN(scb),
                   7962:                                    SCB_GET_CHANNEL(ahd, scb),
                   7963:                                    ROLE_INITIATOR);
                   7964:                targ_info = ahd_fetch_transinfo(ahd,
                   7965:                                                devinfo.channel,
                   7966:                                                devinfo.our_scsiid,
                   7967:                                                devinfo.target,
                   7968:                                                &tstate);
                   7969:                sg = scb->sg_list;
1.29      thorpej  7970:                sc = (struct scsi_request_sense *)hscb->shared_data.idata.cdb;
1.1       fvdl     7971:                /*
                   7972:                 * Save off the residual if there is one.
                   7973:                 */
                   7974:                ahd_update_residual(ahd, scb);
                   7975: #ifdef AHD_DEBUG
                   7976:                if (ahd_debug & AHD_SHOW_SENSE) {
                   7977:                        ahd_print_path(ahd, scb);
                   7978:                        printf("Sending Sense\n");
                   7979:                }
                   7980: #endif
                   7981:                scb->sg_count = 0;
                   7982:                sg = ahd_sg_setup(ahd, scb, sg, ahd_get_sense_bufaddr(ahd, scb),
                   7983:                                  ahd_get_sense_bufsize(ahd, scb),
                   7984:                                  /*last*/TRUE);
1.29      thorpej  7985:                memset(sc, 0, sizeof(*sc));
                   7986:                sc->opcode = SCSI_REQUEST_SENSE;
1.1       fvdl     7987:                sc->length = ahd_get_sense_bufsize(ahd, scb);
                   7988:
                   7989:                /*
                   7990:                 * We can't allow the target to disconnect.
                   7991:                 * This will be an untagged transaction and
                   7992:                 * having the target disconnect will make this
1.26      wiz      7993:                 * transaction indistinguishable from outstanding
1.1       fvdl     7994:                 * tagged transactions.
                   7995:                 */
                   7996:                hscb->control = 0;
                   7997:
                   7998:                /*
                   7999:                 * This request sense could be because the
                   8000:                 * the device lost power or in some other
                   8001:                 * way has lost our transfer negotiations.
                   8002:                 * Renegotiate if appropriate.  Unit attention
                   8003:                 * errors will be reported before any data
                   8004:                 * phases occur.
                   8005:                 */
                   8006:                if (ahd_get_residual(scb) == ahd_get_transfer_length(scb)) {
                   8007:                        ahd_update_neg_request(ahd, &devinfo,
                   8008:                                               tstate, targ_info,
                   8009:                                               AHD_NEG_IF_NON_ASYNC);
                   8010:                }
                   8011:                if (tstate->auto_negotiate & devinfo.target_mask) {
                   8012:                        hscb->control |= MK_MESSAGE;
                   8013:                        scb->flags &=
                   8014:                            ~(SCB_NEGOTIATE|SCB_ABORT|SCB_DEVICE_RESET);
                   8015:                        scb->flags |= SCB_AUTO_NEGOTIATE;
                   8016:                }
                   8017:                hscb->cdb_len = sizeof(*sc);
                   8018:                ahd_setup_data_scb(ahd, scb);
                   8019:                scb->flags |= SCB_SENSE;
                   8020:                ahd_queue_scb(ahd, scb);
                   8021:                /*
                   8022:                 * Ensure we have enough time to actually
                   8023:                 * retrieve the sense.
                   8024:                 */
                   8025:                ahd_scb_timer_reset(scb, 5 * 1000000);
                   8026:                break;
1.30      perry    8027:        }
1.1       fvdl     8028:        case SCSI_STATUS_OK:
1.2       fvdl     8029:                printf("%s: Interrupted for status of 0? (SCB 0x%x)\n",
1.1       fvdl     8030:                       ahd_name(ahd), SCB_GET_TAG(scb));
                   8031:                /* FALLTHROUGH */
                   8032:        default:
                   8033:                ahd_done(ahd, scb);
                   8034:                break;
                   8035:        }
                   8036: }
                   8037:
                   8038: /*
                   8039:  * Calculate the residual for a just completed SCB.
                   8040:  */
                   8041: void
                   8042: ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb)
                   8043: {
                   8044:        struct hardware_scb *hscb;
                   8045:        struct initiator_status *spkt;
                   8046:        uint32_t sgptr;
                   8047:        uint32_t resid_sgptr;
                   8048:        uint32_t resid;
                   8049:
                   8050:        /*
                   8051:         * 5 cases.
                   8052:         * 1) No residual.
                   8053:         *    SG_STATUS_VALID clear in sgptr.
                   8054:         * 2) Transferless command
                   8055:         * 3) Never performed any transfers.
                   8056:         *    sgptr has SG_FULL_RESID set.
                   8057:         * 4) No residual but target did not
                   8058:         *    save data pointers after the
                   8059:         *    last transfer, so sgptr was
                   8060:         *    never updated.
                   8061:         * 5) We have a partial residual.
                   8062:         *    Use residual_sgptr to determine
                   8063:         *    where we are.
                   8064:         */
                   8065:
                   8066:        hscb = scb->hscb;
                   8067:        sgptr = ahd_le32toh(hscb->sgptr);
                   8068:        if ((sgptr & SG_STATUS_VALID) == 0)
                   8069:                /* Case 1 */
                   8070:                return;
                   8071:        sgptr &= ~SG_STATUS_VALID;
                   8072:
                   8073:        if ((sgptr & SG_LIST_NULL) != 0)
                   8074:                /* Case 2 */
                   8075:                return;
                   8076:
                   8077:        /*
                   8078:         * Residual fields are the same in both
                   8079:         * target and initiator status packets,
                   8080:         * so we can always use the initiator fields
                   8081:         * regardless of the role for this SCB.
                   8082:         */
                   8083:        spkt = &hscb->shared_data.istatus;
                   8084:        resid_sgptr = ahd_le32toh(spkt->residual_sgptr);
                   8085:        if ((sgptr & SG_FULL_RESID) != 0) {
                   8086:                /* Case 3 */
                   8087:                resid = ahd_get_transfer_length(scb);
                   8088:        } else if ((resid_sgptr & SG_LIST_NULL) != 0) {
                   8089:                /* Case 4 */
                   8090:                return;
                   8091:        } else if ((resid_sgptr & SG_OVERRUN_RESID) != 0) {
                   8092:                ahd_print_path(ahd, scb);
                   8093:                printf("data overrun detected Tag == 0x%x.\n",
                   8094:                       SCB_GET_TAG(scb));
                   8095:                ahd_freeze_devq(ahd, scb);
                   8096:                ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
                   8097:                ahd_freeze_scb(scb);
                   8098:                return;
                   8099:        } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
                   8100:                panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
                   8101:                /* NOTREACHED */
                   8102:        } else {
                   8103:                struct ahd_dma_seg *sg;
                   8104:
                   8105:                /*
                   8106:                 * Remainder of the SG where the transfer
1.30      perry    8107:                 * stopped.
1.1       fvdl     8108:                 */
                   8109:                resid = ahd_le32toh(spkt->residual_datacnt) & AHD_SG_LEN_MASK;
                   8110:                sg = ahd_sg_bus_to_virt(ahd, scb, resid_sgptr & SG_PTR_MASK);
                   8111:
                   8112:                /* The residual sg_ptr always points to the next sg */
                   8113:                sg--;
                   8114:
                   8115:                /*
                   8116:                 * Add up the contents of all residual
                   8117:                 * SG segments that are after the SG where
                   8118:                 * the transfer stopped.
                   8119:                 */
                   8120:                while ((ahd_le32toh(sg->len) & AHD_DMA_LAST_SEG) == 0) {
                   8121:                        sg++;
                   8122:                        resid += ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
                   8123:                }
                   8124:        }
                   8125:
                   8126:        if ((scb->flags & SCB_SENSE) == 0)
1.43      tsutsui  8127:                ahd_set_residual(scb, resid);
1.1       fvdl     8128:                /*else
                   8129:                  ahd_set_sense_residual(scb, resid);*/
                   8130:
                   8131: #ifdef AHD_DEBUG
                   8132:        if ((ahd_debug & AHD_SHOW_MISC) != 0) {
                   8133:                ahd_print_path(ahd, scb);
                   8134:                printf("Handled %sResidual of %d bytes\n",
                   8135:                       (scb->flags & SCB_SENSE) ? "Sense " : "", resid);
                   8136:        }
                   8137: #endif
                   8138: }
                   8139:
                   8140: /******************************* Target Mode **********************************/
                   8141: #ifdef AHD_TARGET_MODE
                   8142: /*
                   8143:  * Add a target mode event to this lun's queue
                   8144:  */
                   8145: static void
                   8146: ahd_queue_lstate_event(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate,
                   8147:                       u_int initiator_id, u_int event_type, u_int event_arg)
                   8148: {
                   8149:        struct ahd_tmode_event *event;
                   8150:        int pending;
                   8151:
                   8152:        xpt_freeze_devq(lstate->path, /*count*/1);
                   8153:        if (lstate->event_w_idx >= lstate->event_r_idx)
                   8154:                pending = lstate->event_w_idx - lstate->event_r_idx;
                   8155:        else
                   8156:                pending = AHD_TMODE_EVENT_BUFFER_SIZE + 1
                   8157:                        - (lstate->event_r_idx - lstate->event_w_idx);
                   8158:
                   8159:        if (event_type == EVENT_TYPE_BUS_RESET
                   8160:         || event_type == MSG_BUS_DEV_RESET) {
                   8161:                /*
                   8162:                 * Any earlier events are irrelevant, so reset our buffer.
                   8163:                 * This has the effect of allowing us to deal with reset
                   8164:                 * floods (an external device holding down the reset line)
                   8165:                 * without losing the event that is really interesting.
                   8166:                 */
                   8167:                lstate->event_r_idx = 0;
                   8168:                lstate->event_w_idx = 0;
                   8169:                xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE);
                   8170:        }
                   8171:
                   8172:        if (pending == AHD_TMODE_EVENT_BUFFER_SIZE) {
                   8173:                xpt_print_path(lstate->path);
                   8174:                printf("immediate event %x:%x lost\n",
                   8175:                       lstate->event_buffer[lstate->event_r_idx].event_type,
                   8176:                       lstate->event_buffer[lstate->event_r_idx].event_arg);
                   8177:                lstate->event_r_idx++;
                   8178:                if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
                   8179:                        lstate->event_r_idx = 0;
                   8180:                xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE);
                   8181:        }
                   8182:
                   8183:        event = &lstate->event_buffer[lstate->event_w_idx];
                   8184:        event->initiator_id = initiator_id;
                   8185:        event->event_type = event_type;
                   8186:        event->event_arg = event_arg;
                   8187:        lstate->event_w_idx++;
                   8188:        if (lstate->event_w_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
                   8189:                lstate->event_w_idx = 0;
                   8190: }
                   8191:
                   8192: /*
                   8193:  * Send any target mode events queued up waiting
                   8194:  * for immediate notify resources.
                   8195:  */
                   8196: void
                   8197: ahd_send_lstate_events(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate)
                   8198: {
                   8199:        struct ccb_hdr *ccbh;
                   8200:        struct ccb_immed_notify *inot;
                   8201:
                   8202:        while (lstate->event_r_idx != lstate->event_w_idx
                   8203:            && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
                   8204:                struct ahd_tmode_event *event;
                   8205:
                   8206:                event = &lstate->event_buffer[lstate->event_r_idx];
                   8207:                SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
                   8208:                inot = (struct ccb_immed_notify *)ccbh;
                   8209:                switch (event->event_type) {
                   8210:                case EVENT_TYPE_BUS_RESET:
                   8211:                        ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
                   8212:                        break;
                   8213:                default:
                   8214:                        ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
                   8215:                        inot->message_args[0] = event->event_type;
                   8216:                        inot->message_args[1] = event->event_arg;
                   8217:                        break;
                   8218:                }
                   8219:                inot->initiator_id = event->initiator_id;
                   8220:                inot->sense_len = 0;
                   8221:                xpt_done((union ccb *)inot);
                   8222:                lstate->event_r_idx++;
                   8223:                if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
                   8224:                        lstate->event_r_idx = 0;
                   8225:        }
                   8226: }
                   8227: #endif
                   8228:
                   8229: /******************** Sequencer Program Patching/Download *********************/
                   8230:
                   8231: #ifdef AHD_DUMP_SEQ
                   8232: void
                   8233: ahd_dumpseq(struct ahd_softc* ahd)
                   8234: {
                   8235:        int i;
                   8236:        int max_prog;
                   8237:
                   8238:        max_prog = 2048;
                   8239:
                   8240:        ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
                   8241:        ahd_outb(ahd, PRGMCNT, 0);
                   8242:        ahd_outb(ahd, PRGMCNT+1, 0);
                   8243:        for (i = 0; i < max_prog; i++) {
                   8244:                uint8_t ins_bytes[4];
                   8245:
                   8246:                ahd_insb(ahd, SEQRAM, ins_bytes, 4);
                   8247:                printf("0x%08x\n", ins_bytes[0] << 24
                   8248:                                 | ins_bytes[1] << 16
                   8249:                                 | ins_bytes[2] << 8
                   8250:                                 | ins_bytes[3]);
                   8251:        }
                   8252: }
                   8253: #endif
                   8254:
1.54      jdolecek 8255: static void __noinline
1.1       fvdl     8256: ahd_loadseq(struct ahd_softc *ahd)
                   8257: {
1.59      ryo      8258:        struct  cs cs_table[NUM_CRITICAL_SECTIONS];
                   8259:        u_int   begin_set[NUM_CRITICAL_SECTIONS];
                   8260:        u_int   end_set[NUM_CRITICAL_SECTIONS];
1.56      jdolecek 8261:        const struct patch *cur_patch;
1.1       fvdl     8262:        u_int   cs_count;
                   8263:        u_int   cur_cs;
                   8264:        u_int   i;
                   8265:        int     downloaded;
                   8266:        u_int   skip_addr;
                   8267:        u_int   sg_prefetch_cnt;
                   8268:        u_int   sg_prefetch_cnt_limit;
                   8269:        u_int   sg_prefetch_align;
                   8270:        u_int   sg_size;
                   8271:        uint8_t download_consts[DOWNLOAD_CONST_COUNT];
                   8272:
                   8273:        if (bootverbose)
                   8274:                printf("%s: Downloading Sequencer Program...",
                   8275:                       ahd_name(ahd));
                   8276:
                   8277: #if DOWNLOAD_CONST_COUNT != 7
                   8278: #error "Download Const Mismatch"
                   8279: #endif
                   8280:        /*
                   8281:         * Start out with 0 critical sections
                   8282:         * that apply to this firmware load.
                   8283:         */
                   8284:        cs_count = 0;
                   8285:        cur_cs = 0;
                   8286:        memset(begin_set, 0, sizeof(begin_set));
                   8287:        memset(end_set, 0, sizeof(end_set));
                   8288:
                   8289:        /*
                   8290:         * Setup downloadable constant table.
1.30      perry    8291:         *
1.1       fvdl     8292:         * The computation for the S/G prefetch variables is
                   8293:         * a bit complicated.  We would like to always fetch
                   8294:         * in terms of cachelined sized increments.  However,
                   8295:         * if the cacheline is not an even multiple of the
                   8296:         * SG element size or is larger than our SG RAM, using
                   8297:         * just the cache size might leave us with only a portion
                   8298:         * of an SG element at the tail of a prefetch.  If the
                   8299:         * cacheline is larger than our S/G prefetch buffer less
                   8300:         * the size of an SG element, we may round down to a cacheline
                   8301:         * that doesn't contain any or all of the S/G of interest
                   8302:         * within the bounds of our S/G ram.  Provide variables to
                   8303:         * the sequencer that will allow it to handle these edge
                   8304:         * cases.
                   8305:         */
                   8306:        /* Start by aligning to the nearest cacheline. */
                   8307:        sg_prefetch_align = ahd->pci_cachesize;
                   8308:        if (sg_prefetch_align == 0)
                   8309:                sg_prefetch_align = 8;
                   8310:        /* Round down to the nearest power of 2. */
                   8311:        while (powerof2(sg_prefetch_align) == 0)
                   8312:                sg_prefetch_align--;
                   8313:        /*
                   8314:         * If the cacheline boundary is greater than half our prefetch RAM
                   8315:         * we risk not being able to fetch even a single complete S/G
                   8316:         * segment if we align to that boundary.
                   8317:         */
                   8318:        if (sg_prefetch_align > CCSGADDR_MAX/2)
                   8319:                sg_prefetch_align = CCSGADDR_MAX/2;
                   8320:        /* Start by fetching a single cacheline. */
                   8321:        sg_prefetch_cnt = sg_prefetch_align;
                   8322:        /*
                   8323:         * Increment the prefetch count by cachelines until
                   8324:         * at least one S/G element will fit.
                   8325:         */
                   8326:        sg_size = sizeof(struct ahd_dma_seg);
                   8327:        if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
                   8328:                sg_size = sizeof(struct ahd_dma64_seg);
                   8329:        while (sg_prefetch_cnt < sg_size)
                   8330:                sg_prefetch_cnt += sg_prefetch_align;
                   8331:        /*
                   8332:         * If the cacheline is not an even multiple of
                   8333:         * the S/G size, we may only get a partial S/G when
                   8334:         * we align. Add a cacheline if this is the case.
                   8335:         */
                   8336:        if ((sg_prefetch_align % sg_size) != 0
                   8337:         && (sg_prefetch_cnt < CCSGADDR_MAX))
                   8338:                sg_prefetch_cnt += sg_prefetch_align;
                   8339:        /*
                   8340:         * Lastly, compute a value that the sequencer can use
                   8341:         * to determine if the remainder of the CCSGRAM buffer
                   8342:         * has a full S/G element in it.
                   8343:         */
                   8344:        sg_prefetch_cnt_limit = -(sg_prefetch_cnt - sg_size + 1);
                   8345:        download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
                   8346:        download_consts[SG_PREFETCH_CNT_LIMIT] = sg_prefetch_cnt_limit;
                   8347:        download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_align - 1);
                   8348:        download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_align - 1);
                   8349:        download_consts[SG_SIZEOF] = sg_size;
                   8350:        download_consts[PKT_OVERRUN_BUFOFFSET] =
                   8351:                (ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256;
                   8352:        download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN;
                   8353:        cur_patch = patches;
                   8354:        downloaded = 0;
                   8355:        skip_addr = 0;
                   8356:        ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
                   8357:        ahd_outb(ahd, PRGMCNT, 0);
                   8358:        ahd_outb(ahd, PRGMCNT+1, 0);
                   8359:
                   8360:        for (i = 0; i < sizeof(seqprog)/4; i++) {
                   8361:                if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) {
                   8362:                        /*
                   8363:                         * Don't download this instruction as it
                   8364:                         * is in a patch that was removed.
                   8365:                         */
                   8366:                        continue;
                   8367:                }
                   8368:                /*
                   8369:                 * Move through the CS table until we find a CS
                   8370:                 * that might apply to this instruction.
                   8371:                 */
                   8372:                for (; cur_cs < num_critical_sections; cur_cs++) {
                   8373:                        if (critical_sections[cur_cs].end <= i) {
                   8374:                                if (begin_set[cs_count] == TRUE
                   8375:                                 && end_set[cs_count] == FALSE) {
                   8376:                                        cs_table[cs_count].end = downloaded;
1.43      tsutsui  8377:                                        end_set[cs_count] = TRUE;
1.1       fvdl     8378:                                        cs_count++;
1.43      tsutsui  8379:                                }
1.1       fvdl     8380:                                continue;
                   8381:                        }
                   8382:                        if (critical_sections[cur_cs].begin <= i
                   8383:                         && begin_set[cs_count] == FALSE) {
                   8384:                                cs_table[cs_count].begin = downloaded;
                   8385:                                begin_set[cs_count] = TRUE;
                   8386:                        }
                   8387:                        break;
                   8388:                }
                   8389:                ahd_download_instr(ahd, i, download_consts);
                   8390:                downloaded++;
                   8391:        }
                   8392:
                   8393:        ahd->num_critical_sections = cs_count;
                   8394:        if (cs_count != 0) {
                   8395:
                   8396:                cs_count *= sizeof(struct cs);
                   8397:                ahd->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
                   8398:                if (ahd->critical_sections == NULL)
                   8399:                        panic("ahd_loadseq: Could not malloc");
                   8400:                memcpy(ahd->critical_sections, cs_table, cs_count);
                   8401:        }
                   8402:        ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE);
                   8403:
                   8404:        if (bootverbose) {
                   8405:                printf(" %d instructions downloaded\n", downloaded);
                   8406:                printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
                   8407:                       ahd_name(ahd), ahd->features, ahd->bugs, ahd->flags);
                   8408:        }
                   8409: }
                   8410:
                   8411: static int
1.56      jdolecek 8412: ahd_check_patch(struct ahd_softc *ahd, const struct patch **start_patch,
1.1       fvdl     8413:                u_int start_instr, u_int *skip_addr)
                   8414: {
1.56      jdolecek 8415:        const struct    patch *cur_patch;
                   8416:        const struct    patch *last_patch;
                   8417:        u_int           num_patches;
1.1       fvdl     8418:
                   8419:        num_patches = sizeof(patches)/sizeof(struct patch);
                   8420:        last_patch = &patches[num_patches];
                   8421:        cur_patch = *start_patch;
                   8422:
                   8423:        while (cur_patch < last_patch && start_instr == cur_patch->begin) {
                   8424:
                   8425:                if (cur_patch->patch_func(ahd) == 0) {
                   8426:
                   8427:                        /* Start rejecting code */
                   8428:                        *skip_addr = start_instr + cur_patch->skip_instr;
                   8429:                        cur_patch += cur_patch->skip_patch;
                   8430:                } else {
                   8431:                        /* Accepted this patch.  Advance to the next
1.57      andvar   8432:                         * one and wait for our instruction pointer to
1.1       fvdl     8433:                         * hit this point.
                   8434:                         */
                   8435:                        cur_patch++;
                   8436:                }
                   8437:        }
                   8438:
                   8439:        *start_patch = cur_patch;
                   8440:        if (start_instr < *skip_addr)
                   8441:                /* Still skipping */
                   8442:                return (0);
                   8443:
                   8444:        return (1);
                   8445: }
                   8446:
                   8447: static u_int
                   8448: ahd_resolve_seqaddr(struct ahd_softc *ahd, u_int address)
                   8449: {
1.56      jdolecek 8450:        const struct patch *cur_patch;
1.1       fvdl     8451:        int address_offset;
                   8452:        u_int skip_addr;
                   8453:        u_int i;
                   8454:
                   8455:        address_offset = 0;
                   8456:        cur_patch = patches;
                   8457:        skip_addr = 0;
                   8458:
                   8459:        for (i = 0; i < address;) {
                   8460:
                   8461:                ahd_check_patch(ahd, &cur_patch, i, &skip_addr);
                   8462:
                   8463:                if (skip_addr > i) {
                   8464:                        int end_addr;
                   8465:
                   8466:                        end_addr = MIN(address, skip_addr);
                   8467:                        address_offset += end_addr - i;
                   8468:                        i = skip_addr;
                   8469:                } else {
                   8470:                        i++;
                   8471:                }
                   8472:        }
                   8473:        return (address - address_offset);
                   8474: }
                   8475:
                   8476: static void
                   8477: ahd_download_instr(struct ahd_softc *ahd, u_int instrptr, uint8_t *dconsts)
                   8478: {
                   8479:        union   ins_formats instr;
                   8480:        struct  ins_format1 *fmt1_ins;
                   8481:        struct  ins_format3 *fmt3_ins;
                   8482:        u_int   opcode;
                   8483:
                   8484:        /*
                   8485:         * The firmware is always compiled into a little endian format.
                   8486:         */
1.56      jdolecek 8487:        instr.integer = ahd_le32toh(*(const uint32_t*)&seqprog[instrptr * 4]);
1.1       fvdl     8488:
                   8489:        fmt1_ins = &instr.format1;
                   8490:        fmt3_ins = NULL;
                   8491:
                   8492:        /* Pull the opcode */
                   8493:        opcode = instr.format1.opcode;
                   8494:        switch (opcode) {
                   8495:        case AIC_OP_JMP:
                   8496:        case AIC_OP_JC:
                   8497:        case AIC_OP_JNC:
                   8498:        case AIC_OP_CALL:
                   8499:        case AIC_OP_JNE:
                   8500:        case AIC_OP_JNZ:
                   8501:        case AIC_OP_JE:
                   8502:        case AIC_OP_JZ:
                   8503:        {
                   8504:                fmt3_ins = &instr.format3;
                   8505:                fmt3_ins->address = ahd_resolve_seqaddr(ahd, fmt3_ins->address);
                   8506:        }
1.51      mrg      8507:        /* FALLTHROUGH */
1.1       fvdl     8508:        case AIC_OP_OR:
                   8509:        case AIC_OP_AND:
                   8510:        case AIC_OP_XOR:
                   8511:        case AIC_OP_ADD:
                   8512:        case AIC_OP_ADC:
                   8513:        case AIC_OP_BMOV:
                   8514:                if (fmt1_ins->parity != 0) {
                   8515:                        fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
                   8516:                }
                   8517:                fmt1_ins->parity = 0;
                   8518:                /* FALLTHROUGH */
                   8519:        case AIC_OP_ROL:
                   8520:        {
                   8521:                int i, count;
                   8522:
                   8523:                /* Calculate odd parity for the instruction */
                   8524:                for (i = 0, count = 0; i < 31; i++) {
                   8525:                        uint32_t mask;
                   8526:
                   8527:                        mask = 0x01 << i;
                   8528:                        if ((instr.integer & mask) != 0)
                   8529:                                count++;
                   8530:                }
                   8531:                if ((count & 0x01) == 0)
                   8532:                        instr.format1.parity = 1;
                   8533:
1.27      wiz      8534:                /* The sequencer is a little endian CPU */
1.1       fvdl     8535:                instr.integer = ahd_htole32(instr.integer);
                   8536:                ahd_outsb(ahd, SEQRAM, instr.bytes, 4);
                   8537:                break;
                   8538:        }
                   8539:        default:
                   8540:                panic("Unknown opcode encountered in seq program");
                   8541:                break;
                   8542:        }
                   8543: }
                   8544:
                   8545: static int
                   8546: ahd_probe_stack_size(struct ahd_softc *ahd)
                   8547: {
                   8548:        int last_probe;
                   8549:
                   8550:        last_probe = 0;
                   8551:        while (1) {
                   8552:                int i;
                   8553:
                   8554:                /*
                   8555:                 * We avoid using 0 as a pattern to avoid
                   8556:                 * confusion if the stack implementation
                   8557:                 * "back-fills" with zeros when "poping'
                   8558:                 * entries.
                   8559:                 */
                   8560:                for (i = 1; i <= last_probe+1; i++) {
1.43      tsutsui  8561:                        ahd_outb(ahd, STACK, i & 0xFF);
                   8562:                        ahd_outb(ahd, STACK, (i >> 8) & 0xFF);
1.1       fvdl     8563:                }
                   8564:
                   8565:                /* Verify */
                   8566:                for (i = last_probe+1; i > 0; i--) {
                   8567:                        u_int stack_entry;
                   8568:
                   8569:                        stack_entry = ahd_inb(ahd, STACK)
                   8570:                                    |(ahd_inb(ahd, STACK) << 8);
                   8571:                        if (stack_entry != i)
                   8572:                                goto sized;
                   8573:                }
                   8574:                last_probe++;
                   8575:        }
                   8576: sized:
                   8577:        return (last_probe);
                   8578: }
                   8579:
                   8580: void
1.12      thorpej  8581: ahd_dump_all_cards_state(void)
1.1       fvdl     8582: {
                   8583:        struct ahd_softc *list_ahd;
                   8584:
                   8585:        TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
                   8586:                ahd_dump_card_state(list_ahd);
                   8587:        }
                   8588: }
                   8589:
                   8590: int
                   8591: ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries,
1.36      christos 8592:                   const char *name, u_int address, u_int value,
1.1       fvdl     8593:                   u_int *cur_column, u_int wrap_point)
                   8594: {
1.47      christos 8595:        size_t  printed;
1.1       fvdl     8596:        u_int   printed_mask;
                   8597:        char    line[1024];
                   8598:
                   8599:        line[0] = 0;
                   8600:
                   8601:        if (cur_column != NULL && *cur_column >= wrap_point) {
                   8602:                printf("\n");
                   8603:                *cur_column = 0;
                   8604:        }
                   8605:        printed = snprintf(line, sizeof(line), "%s[0x%x]", name, value);
1.47      christos 8606:                printed = sizeof(line);
1.1       fvdl     8607:        if (table == NULL) {
1.48      christos 8608:                if (printed < sizeof(line))
                   8609:                    printed += snprintf(&line[printed],
1.49      christos 8610:                        (sizeof line) - printed, " ");
1.1       fvdl     8611:                printf("%s", line);
                   8612:                if (cur_column != NULL)
                   8613:                        *cur_column += printed;
                   8614:                return (printed);
                   8615:        }
                   8616:        printed_mask = 0;
                   8617:        while (printed_mask != 0xFF) {
                   8618:                int entry;
                   8619:
                   8620:                for (entry = 0; entry < num_entries; entry++) {
                   8621:                        if (((value & table[entry].mask)
                   8622:                          != table[entry].value)
                   8623:                         || ((printed_mask & table[entry].mask)
                   8624:                          == table[entry].mask))
                   8625:                                continue;
1.48      christos 8626:                        if (printed < sizeof(line))
                   8627:                            printed += snprintf(&line[printed],
                   8628:                                (sizeof line) - printed, "%s%s",
                   8629:                                    printed_mask == 0 ? ":(" : "|",
                   8630:                                    table[entry].name);
1.1       fvdl     8631:                        printed_mask |= table[entry].mask;
1.30      perry    8632:
1.1       fvdl     8633:                        break;
                   8634:                }
                   8635:                if (entry >= num_entries)
                   8636:                        break;
                   8637:        }
1.48      christos 8638:        if (printed < sizeof(line)) {
                   8639:                if (printed_mask != 0)
                   8640:                        printed += snprintf(&line[printed],
                   8641:                            (sizeof line) - printed, ") ");
                   8642:                else
                   8643:                        printed += snprintf(&line[printed],
                   8644:                            (sizeof line) - printed, " ");
                   8645:        }
1.1       fvdl     8646:        if (cur_column != NULL)
                   8647:                *cur_column += printed;
                   8648:        printf("%s", line);
                   8649:
                   8650:        return (printed);
                   8651: }
                   8652:
                   8653: void
                   8654: ahd_dump_card_state(struct ahd_softc *ahd)
                   8655: {
                   8656:        struct scb      *scb;
                   8657:        ahd_mode_state   saved_modes;
                   8658:        u_int            dffstat;
                   8659:        int              paused;
                   8660:        u_int            scb_index;
                   8661:        u_int            saved_scb_index;
                   8662:        u_int            cur_col;
                   8663:        int              i;
                   8664:
                   8665:        if (ahd_is_paused(ahd)) {
                   8666:                paused = 1;
                   8667:        } else {
                   8668:                paused = 0;
                   8669:                ahd_pause(ahd);
                   8670:        }
                   8671:        saved_modes = ahd_save_modes(ahd);
                   8672:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   8673:        printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
                   8674:               "%s: Dumping Card State at program address 0x%x Mode 0x%x\n",
1.30      perry    8675:               ahd_name(ahd),
1.1       fvdl     8676:               ahd_inb(ahd, CURADDR) | (ahd_inb(ahd, CURADDR+1) << 8),
                   8677:               ahd_build_mode_state(ahd, ahd->saved_src_mode,
                   8678:                                    ahd->saved_dst_mode));
                   8679:        if (paused)
                   8680:                printf("Card was paused\n");
1.20      thorpej  8681:
                   8682:        if (ahd_check_cmdcmpltqueues(ahd))
                   8683:                printf("Completions are pending\n");
1.1       fvdl     8684:        /*
                   8685:         * Mode independent registers.
                   8686:         */
                   8687:        cur_col = 0;
                   8688:        ahd_hs_mailbox_print(ahd_inb(ahd, LOCAL_HS_MAILBOX), &cur_col, 50);
                   8689:        ahd_intctl_print(ahd_inb(ahd, INTCTL), &cur_col, 50);
                   8690:        ahd_seqintstat_print(ahd_inb(ahd, SEQINTSTAT), &cur_col, 50);
                   8691:        ahd_saved_mode_print(ahd_inb(ahd, SAVED_MODE), &cur_col, 50);
                   8692:        ahd_dffstat_print(ahd_inb(ahd, DFFSTAT), &cur_col, 50);
                   8693:        ahd_scsisigi_print(ahd_inb(ahd, SCSISIGI), &cur_col, 50);
                   8694:        ahd_scsiphase_print(ahd_inb(ahd, SCSIPHASE), &cur_col, 50);
                   8695:        ahd_scsibus_print(ahd_inb(ahd, SCSIBUS), &cur_col, 50);
                   8696:        ahd_lastphase_print(ahd_inb(ahd, LASTPHASE), &cur_col, 50);
                   8697:        ahd_scsiseq0_print(ahd_inb(ahd, SCSISEQ0), &cur_col, 50);
                   8698:        ahd_scsiseq1_print(ahd_inb(ahd, SCSISEQ1), &cur_col, 50);
                   8699:        ahd_seqctl0_print(ahd_inb(ahd, SEQCTL0), &cur_col, 50);
                   8700:        ahd_seqintctl_print(ahd_inb(ahd, SEQINTCTL), &cur_col, 50);
                   8701:        ahd_seq_flags_print(ahd_inb(ahd, SEQ_FLAGS), &cur_col, 50);
                   8702:        ahd_seq_flags2_print(ahd_inb(ahd, SEQ_FLAGS2), &cur_col, 50);
                   8703:        ahd_sstat0_print(ahd_inb(ahd, SSTAT0), &cur_col, 50);
                   8704:        ahd_sstat1_print(ahd_inb(ahd, SSTAT1), &cur_col, 50);
                   8705:        ahd_sstat2_print(ahd_inb(ahd, SSTAT2), &cur_col, 50);
                   8706:        ahd_sstat3_print(ahd_inb(ahd, SSTAT3), &cur_col, 50);
                   8707:        ahd_perrdiag_print(ahd_inb(ahd, PERRDIAG), &cur_col, 50);
                   8708:        ahd_simode1_print(ahd_inb(ahd, SIMODE1), &cur_col, 50);
                   8709:        ahd_lqistat0_print(ahd_inb(ahd, LQISTAT0), &cur_col, 50);
                   8710:        ahd_lqistat1_print(ahd_inb(ahd, LQISTAT1), &cur_col, 50);
                   8711:        ahd_lqistat2_print(ahd_inb(ahd, LQISTAT2), &cur_col, 50);
                   8712:        ahd_lqostat0_print(ahd_inb(ahd, LQOSTAT0), &cur_col, 50);
                   8713:        ahd_lqostat1_print(ahd_inb(ahd, LQOSTAT1), &cur_col, 50);
                   8714:        ahd_lqostat2_print(ahd_inb(ahd, LQOSTAT2), &cur_col, 50);
                   8715:        printf("\n");
                   8716:        printf("\nSCB Count = %d CMDS_PENDING = %d LASTSCB 0x%x "
                   8717:               "CURRSCB 0x%x NEXTSCB 0x%x\n",
                   8718:               ahd->scb_data.numscbs, ahd_inw(ahd, CMDS_PENDING),
                   8719:               ahd_inw(ahd, LASTSCB), ahd_inw(ahd, CURRSCB),
                   8720:               ahd_inw(ahd, NEXTSCB));
                   8721:        cur_col = 0;
                   8722:        /* QINFIFO */
                   8723:        ahd_search_qinfifo(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
                   8724:                           CAM_LUN_WILDCARD, SCB_LIST_NULL,
                   8725:                           ROLE_UNKNOWN, /*status*/0, SEARCH_PRINT);
                   8726:        saved_scb_index = ahd_get_scbptr(ahd);
                   8727:        printf("Pending list:");
                   8728:        i = 0;
                   8729:        LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
                   8730:                if (i++ > AHD_SCB_MAX)
                   8731:                        break;
1.9       thorpej  8732:                /*cur_col =*/ printf("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb),
1.21      thorpej  8733:                                     ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT));
1.1       fvdl     8734:                ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
1.21      thorpej  8735:                ahd_scb_control_print(ahd_inb_scbram(ahd, SCB_CONTROL),
                   8736:                                      &cur_col, 60);
                   8737:                ahd_scb_scsiid_print(ahd_inb_scbram(ahd, SCB_SCSIID),
                   8738:                                     &cur_col, 60);
1.1       fvdl     8739:        }
                   8740:        printf("\nTotal %d\n", i);
                   8741:
                   8742:        printf("Kernel Free SCB list: ");
                   8743:        i = 0;
                   8744:        TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
                   8745:                struct scb *list_scb;
                   8746:
                   8747:                list_scb = scb;
                   8748:                do {
                   8749:                        printf("%d ", SCB_GET_TAG(list_scb));
                   8750:                        list_scb = LIST_NEXT(list_scb, collision_links);
                   8751:                } while (list_scb && i++ < AHD_SCB_MAX);
                   8752:        }
                   8753:
                   8754:        LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) {
                   8755:                if (i++ > AHD_SCB_MAX)
                   8756:                        break;
                   8757:                printf("%d ", SCB_GET_TAG(scb));
                   8758:        }
                   8759:        printf("\n");
                   8760:
                   8761:        printf("Sequencer Complete DMA-inprog list: ");
                   8762:        scb_index = ahd_inw(ahd, COMPLETE_SCB_DMAINPROG_HEAD);
                   8763:        i = 0;
                   8764:        while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
                   8765:                ahd_set_scbptr(ahd, scb_index);
                   8766:                printf("%d ", scb_index);
1.21      thorpej  8767:                scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
1.1       fvdl     8768:        }
                   8769:        printf("\n");
                   8770:
                   8771:        printf("Sequencer Complete list: ");
                   8772:        scb_index = ahd_inw(ahd, COMPLETE_SCB_HEAD);
                   8773:        i = 0;
                   8774:        while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
                   8775:                ahd_set_scbptr(ahd, scb_index);
                   8776:                printf("%d ", scb_index);
1.21      thorpej  8777:                scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
1.1       fvdl     8778:        }
                   8779:        printf("\n");
                   8780:
1.30      perry    8781:
1.1       fvdl     8782:        printf("Sequencer DMA-Up and Complete list: ");
                   8783:        scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
                   8784:        i = 0;
                   8785:        while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
                   8786:                ahd_set_scbptr(ahd, scb_index);
                   8787:                printf("%d ", scb_index);
1.21      thorpej  8788:                scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
1.1       fvdl     8789:        }
                   8790:        printf("\n");
                   8791:        ahd_set_scbptr(ahd, saved_scb_index);
                   8792:        dffstat = ahd_inb(ahd, DFFSTAT);
                   8793:        for (i = 0; i < 2; i++) {
                   8794: #ifdef AHD_DEBUG
                   8795:                struct scb *fifo_scb;
                   8796: #endif
                   8797:                u_int       fifo_scbptr;
                   8798:
                   8799:                ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
                   8800:                fifo_scbptr = ahd_get_scbptr(ahd);
1.9       thorpej  8801:                printf("\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n",
1.1       fvdl     8802:                       ahd_name(ahd), i,
                   8803:                       (dffstat & (FIFO0FREE << i)) ? "Free" : "Active",
1.9       thorpej  8804:                       ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr);
1.1       fvdl     8805:                cur_col = 0;
                   8806:                ahd_seqimode_print(ahd_inb(ahd, SEQIMODE), &cur_col, 50);
                   8807:                ahd_seqintsrc_print(ahd_inb(ahd, SEQINTSRC), &cur_col, 50);
                   8808:                ahd_dfcntrl_print(ahd_inb(ahd, DFCNTRL), &cur_col, 50);
                   8809:                ahd_dfstatus_print(ahd_inb(ahd, DFSTATUS), &cur_col, 50);
                   8810:                ahd_sg_cache_shadow_print(ahd_inb(ahd, SG_CACHE_SHADOW),
                   8811:                                          &cur_col, 50);
                   8812:                ahd_sg_state_print(ahd_inb(ahd, SG_STATE), &cur_col, 50);
                   8813:                ahd_dffsxfrctl_print(ahd_inb(ahd, DFFSXFRCTL), &cur_col, 50);
                   8814:                ahd_soffcnt_print(ahd_inb(ahd, SOFFCNT), &cur_col, 50);
                   8815:                ahd_mdffstat_print(ahd_inb(ahd, MDFFSTAT), &cur_col, 50);
                   8816:                if (cur_col > 50) {
                   8817:                        printf("\n");
                   8818:                        cur_col = 0;
                   8819:                }
                   8820:                printf("\nSHADDR = 0x%x%x, SHCNT = 0x%x ",
                   8821:                                  ahd_inl(ahd, SHADDR+4),
                   8822:                                  ahd_inl(ahd, SHADDR),
                   8823:                                  (ahd_inb(ahd, SHCNT)
                   8824:                                | (ahd_inb(ahd, SHCNT + 1) << 8)
                   8825:                                | (ahd_inb(ahd, SHCNT + 2) << 16)));
                   8826:                printf("HADDR = 0x%x%x, HCNT = 0x%x \n",
                   8827:                                  ahd_inl(ahd, HADDR+4),
                   8828:                                  ahd_inl(ahd, HADDR),
                   8829:                                  (ahd_inb(ahd, HCNT)
                   8830:                                | (ahd_inb(ahd, HCNT + 1) << 8)
                   8831:                                | (ahd_inb(ahd, HCNT + 2) << 16)));
                   8832:                ahd_ccsgctl_print(ahd_inb(ahd, CCSGCTL), &cur_col, 50);
                   8833: #ifdef AHD_DEBUG
                   8834:                if ((ahd_debug & AHD_SHOW_SG) != 0) {
                   8835:                        fifo_scb = ahd_lookup_scb(ahd, fifo_scbptr);
                   8836:                        if (fifo_scb != NULL)
                   8837:                                ahd_dump_sglist(fifo_scb);
                   8838:                }
                   8839: #endif
                   8840:        }
                   8841:        printf("\nLQIN: ");
                   8842:        for (i = 0; i < 20; i++)
                   8843:                printf("0x%x ", ahd_inb(ahd, LQIN + i));
                   8844:        printf("\n");
                   8845:        ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                   8846:        printf("%s: LQISTATE = 0x%x, LQOSTATE = 0x%x, OPTIONMODE = 0x%x\n",
                   8847:               ahd_name(ahd), ahd_inb(ahd, LQISTATE), ahd_inb(ahd, LQOSTATE),
                   8848:               ahd_inb(ahd, OPTIONMODE));
                   8849:        printf("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n",
                   8850:               ahd_name(ahd), ahd_inb(ahd, OS_SPACE_CNT),
                   8851:               ahd_inb(ahd, MAXCMDCNT));
                   8852:        ahd_simode0_print(ahd_inb(ahd, SIMODE0), &cur_col, 50);
                   8853:        printf("\n");
                   8854:        ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
                   8855:        cur_col = 0;
                   8856:        ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
                   8857:        printf("%s: REG0 == 0x%x, SINDEX = 0x%x, DINDEX = 0x%x\n",
                   8858:               ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX),
                   8859:               ahd_inw(ahd, DINDEX));
                   8860:        printf("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n",
1.21      thorpej  8861:               ahd_name(ahd), ahd_get_scbptr(ahd),
                   8862:               ahd_inw_scbram(ahd, SCB_NEXT),
                   8863:               ahd_inw_scbram(ahd, SCB_NEXT2));
1.1       fvdl     8864:        printf("CDB %x %x %x %x %x %x\n",
1.21      thorpej  8865:               ahd_inb_scbram(ahd, SCB_CDB_STORE),
                   8866:               ahd_inb_scbram(ahd, SCB_CDB_STORE+1),
                   8867:               ahd_inb_scbram(ahd, SCB_CDB_STORE+2),
                   8868:               ahd_inb_scbram(ahd, SCB_CDB_STORE+3),
                   8869:               ahd_inb_scbram(ahd, SCB_CDB_STORE+4),
                   8870:               ahd_inb_scbram(ahd, SCB_CDB_STORE+5));
1.1       fvdl     8871:        printf("STACK:");
                   8872:        for (i = 0; i < ahd->stack_size; i++) {
                   8873:                ahd->saved_stack[i] =
                   8874:                    ahd_inb(ahd, STACK)|(ahd_inb(ahd, STACK) << 8);
                   8875:                printf(" 0x%x", ahd->saved_stack[i]);
                   8876:        }
                   8877:        for (i = ahd->stack_size-1; i >= 0; i--) {
                   8878:                ahd_outb(ahd, STACK, ahd->saved_stack[i] & 0xFF);
                   8879:                ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF);
                   8880:        }
                   8881:        printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
                   8882:        ahd_platform_dump_card_state(ahd);
                   8883:        ahd_restore_modes(ahd, saved_modes);
                   8884:        if (paused == 0)
                   8885:                ahd_unpause(ahd);
                   8886: }
                   8887:
                   8888: void
                   8889: ahd_dump_scbs(struct ahd_softc *ahd)
                   8890: {
                   8891:        ahd_mode_state saved_modes;
                   8892:        u_int          saved_scb_index;
                   8893:        int            i;
                   8894:
                   8895:        saved_modes = ahd_save_modes(ahd);
                   8896:        ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
                   8897:        saved_scb_index = ahd_get_scbptr(ahd);
                   8898:        for (i = 0; i < AHD_SCB_MAX; i++) {
                   8899:                ahd_set_scbptr(ahd, i);
                   8900:                printf("%3d", i);
                   8901:                printf("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n",
1.21      thorpej  8902:                       ahd_inb_scbram(ahd, SCB_CONTROL),
                   8903:                       ahd_inb_scbram(ahd, SCB_SCSIID),
                   8904:                       ahd_inw_scbram(ahd, SCB_NEXT),
                   8905:                       ahd_inw_scbram(ahd, SCB_NEXT2),
                   8906:                       ahd_inl_scbram(ahd, SCB_SGPTR),
                   8907:                       ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR));
1.1       fvdl     8908:        }
                   8909:        printf("\n");
                   8910:        ahd_set_scbptr(ahd, saved_scb_index);
                   8911:        ahd_restore_modes(ahd, saved_modes);
                   8912: }
                   8913:
                   8914: /**************************** Flexport Logic **********************************/
                   8915: /*
                   8916:  * Read count 16bit words from 16bit word address start_addr from the
1.31      christos 8917:  * SEEPROM attached to the controller, into tbuf, using the controller's
1.9       thorpej  8918:  * SEEPROM reading state machine.  Optionally treat the data as a byte
                   8919:  * stream in terms of byte order.
1.1       fvdl     8920:  */
                   8921: int
1.31      christos 8922: ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *tbuf,
1.9       thorpej  8923:                 u_int start_addr, u_int count, int bytestream)
1.1       fvdl     8924: {
                   8925:        u_int cur_addr;
                   8926:        u_int end_addr;
                   8927:        int   error;
                   8928:
                   8929:        /*
                   8930:         * If we never make it through the loop even once,
                   8931:         * we were passed invalid arguments.
                   8932:         */
                   8933:        error = EINVAL;
                   8934:        AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                   8935:        end_addr = start_addr + count;
                   8936:        for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
1.9       thorpej  8937:
1.1       fvdl     8938:                ahd_outb(ahd, SEEADR, cur_addr);
                   8939:                ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART);
1.30      perry    8940:
1.1       fvdl     8941:                error = ahd_wait_seeprom(ahd);
                   8942:                if (error) {
1.44      tsutsui  8943:                        printf("%s: ahd_wait_seeprom timed out\n",
                   8944:                            ahd_name(ahd));
1.1       fvdl     8945:                        break;
                   8946:                }
1.9       thorpej  8947:                if (bytestream != 0) {
                   8948:                        uint8_t *bytestream_ptr;
                   8949:
1.31      christos 8950:                        bytestream_ptr = (uint8_t *)tbuf;
1.9       thorpej  8951:                        *bytestream_ptr++ = ahd_inb(ahd, SEEDAT);
                   8952:                        *bytestream_ptr = ahd_inb(ahd, SEEDAT+1);
                   8953:                } else {
                   8954:                        /*
                   8955:                         * ahd_inw() already handles machine byte order.
                   8956:                         */
1.31      christos 8957:                        *tbuf = ahd_inw(ahd, SEEDAT);
1.9       thorpej  8958:                }
1.31      christos 8959:                tbuf++;
1.1       fvdl     8960:        }
                   8961:        return (error);
                   8962: }
                   8963:
                   8964: /*
1.31      christos 8965:  * Write count 16bit words from tbuf, into SEEPROM attache to the
1.1       fvdl     8966:  * controller starting at 16bit word address start_addr, using the
                   8967:  * controller's SEEPROM writing state machine.
                   8968:  */
                   8969: int
1.31      christos 8970: ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *tbuf,
1.1       fvdl     8971:                  u_int start_addr, u_int count)
                   8972: {
                   8973:        u_int cur_addr;
                   8974:        u_int end_addr;
                   8975:        int   error;
                   8976:        int   retval;
                   8977:
                   8978:        AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                   8979:        error = ENOENT;
                   8980:
                   8981:        /* Place the chip into write-enable mode */
                   8982:        ahd_outb(ahd, SEEADR, SEEOP_EWEN_ADDR);
                   8983:        ahd_outb(ahd, SEECTL, SEEOP_EWEN | SEESTART);
                   8984:        error = ahd_wait_seeprom(ahd);
                   8985:        if (error)
                   8986:                return (error);
                   8987:
                   8988:        /*
                   8989:         * Write the data.  If we don't get throught the loop at
                   8990:         * least once, the arguments were invalid.
                   8991:         */
                   8992:        retval = EINVAL;
                   8993:        end_addr = start_addr + count;
                   8994:        for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
1.31      christos 8995:                ahd_outw(ahd, SEEDAT, *tbuf++);
1.1       fvdl     8996:                ahd_outb(ahd, SEEADR, cur_addr);
                   8997:                ahd_outb(ahd, SEECTL, SEEOP_WRITE | SEESTART);
1.30      perry    8998:
1.1       fvdl     8999:                retval = ahd_wait_seeprom(ahd);
                   9000:                if (retval)
                   9001:                        break;
                   9002:        }
                   9003:
                   9004:        /*
                   9005:         * Disable writes.
                   9006:         */
                   9007:        ahd_outb(ahd, SEEADR, SEEOP_EWDS_ADDR);
                   9008:        ahd_outb(ahd, SEECTL, SEEOP_EWDS | SEESTART);
                   9009:        error = ahd_wait_seeprom(ahd);
                   9010:        if (error)
                   9011:                return (error);
                   9012:        return (retval);
                   9013: }
                   9014:
                   9015: /*
                   9016:  * Wait ~100us for the serial eeprom to satisfy our request.
                   9017:  */
                   9018: int
                   9019: ahd_wait_seeprom(struct ahd_softc *ahd)
                   9020: {
                   9021:        int cnt;
                   9022:
                   9023:        cnt = 2000;
                   9024:        while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt)
                   9025:                ahd_delay(5);
                   9026:
                   9027:        if (cnt == 0)
                   9028:                return (ETIMEDOUT);
                   9029:        return (0);
1.9       thorpej  9030: }
                   9031:
                   9032: /*
                   9033:  * Validate the two checksums in the per_channel
                   9034:  * vital product data struct.
                   9035:  */
                   9036: int
                   9037: ahd_verify_vpd_cksum(struct vpd_config *vpd)
                   9038: {
                   9039:        int i;
                   9040:        int maxaddr;
                   9041:        uint32_t checksum;
                   9042:        uint8_t *vpdarray;
                   9043:
                   9044:        vpdarray = (uint8_t *)vpd;
                   9045:        maxaddr = offsetof(struct vpd_config, vpd_checksum);
                   9046:        checksum = 0;
                   9047:        for (i = offsetof(struct vpd_config, resource_type); i < maxaddr; i++)
                   9048:                checksum = checksum + vpdarray[i];
                   9049:        if (checksum == 0
                   9050:         || (-checksum & 0xFF) != vpd->vpd_checksum)
                   9051:                return (0);
                   9052:
                   9053:        checksum = 0;
                   9054:        maxaddr = offsetof(struct vpd_config, checksum);
                   9055:        for (i = offsetof(struct vpd_config, default_target_flags);
                   9056:             i < maxaddr; i++)
                   9057:                checksum = checksum + vpdarray[i];
                   9058:        if (checksum == 0
                   9059:         || (-checksum & 0xFF) != vpd->checksum)
                   9060:                return (0);
                   9061:        return (1);
1.1       fvdl     9062: }
                   9063:
                   9064: int
                   9065: ahd_verify_cksum(struct seeprom_config *sc)
                   9066: {
                   9067:        int i;
                   9068:        int maxaddr;
                   9069:        uint32_t checksum;
                   9070:        uint16_t *scarray;
                   9071:
                   9072:        maxaddr = (sizeof(*sc)/2) - 1;
                   9073:        checksum = 0;
                   9074:        scarray = (uint16_t *)sc;
                   9075:
                   9076:        for (i = 0; i < maxaddr; i++)
                   9077:                checksum = checksum + scarray[i];
                   9078:        if (checksum == 0
                   9079:         || (checksum & 0xFFFF) != sc->checksum) {
                   9080:                return (0);
                   9081:        } else {
                   9082:                return (1);
                   9083:        }
                   9084: }
                   9085:
                   9086: int
1.36      christos 9087: ahd_acquire_seeprom(struct ahd_softc *ahd)
1.1       fvdl     9088: {
                   9089:        /*
                   9090:         * We should be able to determine the SEEPROM type
                   9091:         * from the flexport logic, but unfortunately not
                   9092:         * all implementations have this logic and there is
1.61      msaitoh  9093:         * no programmatic method for determining if the logic
1.1       fvdl     9094:         * is present.
                   9095:         */
                   9096:
                   9097:        return (1);
                   9098: #if 0
                   9099:        uint8_t seetype;
                   9100:        int     error;
                   9101:
                   9102:        error = ahd_read_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, &seetype);
                   9103:        if (error != 0
1.43      tsutsui  9104:         || ((seetype & FLX_ROMSTAT_SEECFG) == FLX_ROMSTAT_SEE_NONE))
1.1       fvdl     9105:                return (0);
                   9106:        return (1);
                   9107: #endif
                   9108: }
                   9109:
                   9110: void
1.36      christos 9111: ahd_release_seeprom(struct ahd_softc *ahd)
1.1       fvdl     9112: {
                   9113:        /* Currently a no-op */
                   9114: }
                   9115:
                   9116: int
                   9117: ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value)
                   9118: {
                   9119:        int error;
                   9120:
                   9121:        AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                   9122:        if (addr > 7)
                   9123:                panic("ahd_write_flexport: address out of range");
                   9124:        ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3));
                   9125:        error = ahd_wait_flexport(ahd);
                   9126:        if (error != 0)
                   9127:                return (error);
                   9128:        ahd_outb(ahd, BRDDAT, value);
                   9129:        ahd_flush_device_writes(ahd);
                   9130:        ahd_outb(ahd, BRDCTL, BRDSTB|BRDEN|(addr << 3));
                   9131:        ahd_flush_device_writes(ahd);
                   9132:        ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3));
                   9133:        ahd_flush_device_writes(ahd);
                   9134:        ahd_outb(ahd, BRDCTL, 0);
                   9135:        ahd_flush_device_writes(ahd);
                   9136:        return (0);
                   9137: }
                   9138:
                   9139: int
                   9140: ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value)
                   9141: {
                   9142:        int     error;
                   9143:
                   9144:        AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                   9145:        if (addr > 7)
                   9146:                panic("ahd_read_flexport: address out of range");
                   9147:        ahd_outb(ahd, BRDCTL, BRDRW|BRDEN|(addr << 3));
                   9148:        error = ahd_wait_flexport(ahd);
                   9149:        if (error != 0)
                   9150:                return (error);
                   9151:        *value = ahd_inb(ahd, BRDDAT);
                   9152:        ahd_outb(ahd, BRDCTL, 0);
                   9153:        ahd_flush_device_writes(ahd);
                   9154:        return (0);
                   9155: }
                   9156:
                   9157: /*
                   9158:  * Wait at most 2 seconds for flexport arbitration to succeed.
                   9159:  */
                   9160: int
                   9161: ahd_wait_flexport(struct ahd_softc *ahd)
                   9162: {
                   9163:        int cnt;
                   9164:
                   9165:        AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
                   9166:        cnt = 1000000 * 2 / 5;
                   9167:        while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt)
                   9168:                ahd_delay(5);
                   9169:
                   9170:        if (cnt == 0)
                   9171:                return (ETIMEDOUT);
                   9172:        return (0);
                   9173: }
                   9174:
                   9175: /************************* Target Mode ****************************************/
                   9176: #ifdef AHD_TARGET_MODE
                   9177: cam_status
                   9178: ahd_find_tmode_devs(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb,
                   9179:                    struct ahd_tmode_tstate **tstate,
                   9180:                    struct ahd_tmode_lstate **lstate,
                   9181:                    int notfound_failure)
                   9182: {
                   9183:
                   9184:        if ((ahd->features & AHD_TARGETMODE) == 0)
                   9185:                return (CAM_REQ_INVALID);
                   9186:
                   9187:        /*
                   9188:         * Handle the 'black hole' device that sucks up
                   9189:         * requests to unattached luns on enabled targets.
                   9190:         */
                   9191:        if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
                   9192:         && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
                   9193:                *tstate = NULL;
                   9194:                *lstate = ahd->black_hole;
                   9195:        } else {
                   9196:                u_int max_id;
                   9197:
                   9198:                max_id = (ahd->features & AHD_WIDE) ? 15 : 7;
                   9199:                if (ccb->ccb_h.target_id > max_id)
                   9200:                        return (CAM_TID_INVALID);
                   9201:
                   9202:                if (ccb->ccb_h.target_lun >= AHD_NUM_LUNS)
                   9203:                        return (CAM_LUN_INVALID);
                   9204:
                   9205:                *tstate = ahd->enabled_targets[ccb->ccb_h.target_id];
                   9206:                *lstate = NULL;
                   9207:                if (*tstate != NULL)
                   9208:                        *lstate =
                   9209:                            (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
                   9210:        }
                   9211:
                   9212:        if (notfound_failure != 0 && *lstate == NULL)
                   9213:                return (CAM_PATH_INVALID);
                   9214:
                   9215:        return (CAM_REQ_CMP);
                   9216: }
                   9217:
                   9218: void
                   9219: ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
                   9220: {
                   9221: #if NOT_YET
                   9222:        struct     ahd_tmode_tstate *tstate;
                   9223:        struct     ahd_tmode_lstate *lstate;
                   9224:        struct     ccb_en_lun *cel;
                   9225:        cam_status status;
                   9226:        u_int      target;
                   9227:        u_int      lun;
                   9228:        u_int      target_mask;
                   9229:        u_long     s;
                   9230:        char       channel;
                   9231:
                   9232:        status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate, &lstate,
                   9233:                                     /*notfound_failure*/FALSE);
                   9234:
                   9235:        if (status != CAM_REQ_CMP) {
                   9236:                ccb->ccb_h.status = status;
                   9237:                return;
                   9238:        }
                   9239:
                   9240:        if ((ahd->features & AHD_MULTIROLE) != 0) {
                   9241:                u_int      our_id;
                   9242:
                   9243:                our_id = ahd->our_id;
                   9244:                if (ccb->ccb_h.target_id != our_id) {
                   9245:                        if ((ahd->features & AHD_MULTI_TID) != 0
1.43      tsutsui  9246:                         && (ahd->flags & AHD_INITIATORROLE) != 0) {
1.1       fvdl     9247:                                /*
                   9248:                                 * Only allow additional targets if
                   9249:                                 * the initiator role is disabled.
                   9250:                                 * The hardware cannot handle a re-select-in
                   9251:                                 * on the initiator id during a re-select-out
                   9252:                                 * on a different target id.
                   9253:                                 */
                   9254:                                status = CAM_TID_INVALID;
                   9255:                        } else if ((ahd->flags & AHD_INITIATORROLE) != 0
                   9256:                                || ahd->enabled_luns > 0) {
                   9257:                                /*
                   9258:                                 * Only allow our target id to change
                   9259:                                 * if the initiator role is not configured
                   9260:                                 * and there are no enabled luns which
                   9261:                                 * are attached to the currently registered
                   9262:                                 * scsi id.
                   9263:                                 */
                   9264:                                status = CAM_TID_INVALID;
                   9265:                        }
                   9266:                }
                   9267:        }
                   9268:
                   9269:        if (status != CAM_REQ_CMP) {
                   9270:                ccb->ccb_h.status = status;
                   9271:                return;
                   9272:        }
                   9273:
                   9274:        /*
                   9275:         * We now have an id that is valid.
                   9276:         * If we aren't in target mode, switch modes.
                   9277:         */
                   9278:        if ((ahd->flags & AHD_TARGETROLE) == 0
                   9279:         && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
                   9280:                u_long  s;
                   9281:
                   9282:                printf("Configuring Target Mode\n");
                   9283:                ahd_lock(ahd, &s);
                   9284:                if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
                   9285:                        ccb->ccb_h.status = CAM_BUSY;
                   9286:                        ahd_unlock(ahd, &s);
                   9287:                        return;
                   9288:                }
                   9289:                ahd->flags |= AHD_TARGETROLE;
                   9290:                if ((ahd->features & AHD_MULTIROLE) == 0)
                   9291:                        ahd->flags &= ~AHD_INITIATORROLE;
                   9292:                ahd_pause(ahd);
                   9293:                ahd_loadseq(ahd);
1.15      thorpej  9294:                ahd_restart(ahd);
1.1       fvdl     9295:                ahd_unlock(ahd, &s);
                   9296:        }
                   9297:        cel = &ccb->cel;
                   9298:        target = ccb->ccb_h.target_id;
                   9299:        lun = ccb->ccb_h.target_lun;
                   9300:        channel = SIM_CHANNEL(ahd, sim);
                   9301:        target_mask = 0x01 << target;
                   9302:        if (channel == 'B')
                   9303:                target_mask <<= 8;
                   9304:
                   9305:        if (cel->enable != 0) {
                   9306:                u_int scsiseq1;
                   9307:
                   9308:                /* Are we already enabled?? */
                   9309:                if (lstate != NULL) {
                   9310:                        xpt_print_path(ccb->ccb_h.path);
                   9311:                        printf("Lun already enabled\n");
                   9312:                        ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
                   9313:                        return;
                   9314:                }
                   9315:
                   9316:                if (cel->grp6_len != 0
                   9317:                 || cel->grp7_len != 0) {
                   9318:                        /*
                   9319:                         * Don't (yet?) support vendor
                   9320:                         * specific commands.
                   9321:                         */
                   9322:                        ccb->ccb_h.status = CAM_REQ_INVALID;
                   9323:                        printf("Non-zero Group Codes\n");
                   9324:                        return;
                   9325:                }
                   9326:
                   9327:                /*
                   9328:                 * Seems to be okay.
                   9329:                 * Setup our data structures.
                   9330:                 */
                   9331:                if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
                   9332:                        tstate = ahd_alloc_tstate(ahd, target, channel);
                   9333:                        if (tstate == NULL) {
                   9334:                                xpt_print_path(ccb->ccb_h.path);
                   9335:                                printf("Couldn't allocate tstate\n");
                   9336:                                ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
                   9337:                                return;
                   9338:                        }
                   9339:                }
                   9340:                lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
                   9341:                if (lstate == NULL) {
                   9342:                        xpt_print_path(ccb->ccb_h.path);
                   9343:                        printf("Couldn't allocate lstate\n");
                   9344:                        ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
                   9345:                        return;
                   9346:                }
                   9347:                memset(lstate, 0, sizeof(*lstate));
                   9348:                status = xpt_create_path(&lstate->path, /*periph*/NULL,
                   9349:                                         xpt_path_path_id(ccb->ccb_h.path),
                   9350:                                         xpt_path_target_id(ccb->ccb_h.path),
                   9351:                                         xpt_path_lun_id(ccb->ccb_h.path));
                   9352:                if (status != CAM_REQ_CMP) {
                   9353:                        free(lstate, M_DEVBUF);
                   9354:                        xpt_print_path(ccb->ccb_h.path);
                   9355:                        printf("Couldn't allocate path\n");
                   9356:                        ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
                   9357:                        return;
                   9358:                }
                   9359:                SLIST_INIT(&lstate->accept_tios);
                   9360:                SLIST_INIT(&lstate->immed_notifies);
                   9361:                ahd_lock(ahd, &s);
                   9362:                ahd_pause(ahd);
                   9363:                if (target != CAM_TARGET_WILDCARD) {
                   9364:                        tstate->enabled_luns[lun] = lstate;
                   9365:                        ahd->enabled_luns++;
                   9366:
                   9367:                        if ((ahd->features & AHD_MULTI_TID) != 0) {
                   9368:                                u_int targid_mask;
                   9369:
                   9370:                                targid_mask = ahd_inb(ahd, TARGID)
                   9371:                                            | (ahd_inb(ahd, TARGID + 1) << 8);
                   9372:
                   9373:                                targid_mask |= target_mask;
                   9374:                                ahd_outb(ahd, TARGID, targid_mask);
                   9375:                                ahd_outb(ahd, TARGID+1, (targid_mask >> 8));
1.30      perry    9376:
1.1       fvdl     9377:                                ahd_update_scsiid(ahd, targid_mask);
                   9378:                        } else {
                   9379:                                u_int our_id;
                   9380:                                char  channel;
                   9381:
                   9382:                                channel = SIM_CHANNEL(ahd, sim);
                   9383:                                our_id = SIM_SCSI_ID(ahd, sim);
                   9384:
                   9385:                                /*
                   9386:                                 * This can only happen if selections
                   9387:                                 * are not enabled
                   9388:                                 */
                   9389:                                if (target != our_id) {
                   9390:                                        u_int sblkctl;
                   9391:                                        char  cur_channel;
                   9392:                                        int   swap;
                   9393:
                   9394:                                        sblkctl = ahd_inb(ahd, SBLKCTL);
                   9395:                                        cur_channel = (sblkctl & SELBUSB)
                   9396:                                                    ? 'B' : 'A';
                   9397:                                        if ((ahd->features & AHD_TWIN) == 0)
                   9398:                                                cur_channel = 'A';
                   9399:                                        swap = cur_channel != channel;
                   9400:                                        ahd->our_id = target;
                   9401:
                   9402:                                        if (swap)
                   9403:                                                ahd_outb(ahd, SBLKCTL,
                   9404:                                                         sblkctl ^ SELBUSB);
                   9405:
                   9406:                                        ahd_outb(ahd, SCSIID, target);
                   9407:
                   9408:                                        if (swap)
                   9409:                                                ahd_outb(ahd, SBLKCTL, sblkctl);
                   9410:                                }
                   9411:                        }
                   9412:                } else
                   9413:                        ahd->black_hole = lstate;
                   9414:                /* Allow select-in operations */
                   9415:                if (ahd->black_hole != NULL && ahd->enabled_luns > 0) {
                   9416:                        scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
                   9417:                        scsiseq1 |= ENSELI;
                   9418:                        ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1);
                   9419:                        scsiseq1 = ahd_inb(ahd, SCSISEQ1);
                   9420:                        scsiseq1 |= ENSELI;
                   9421:                        ahd_outb(ahd, SCSISEQ1, scsiseq1);
                   9422:                }
                   9423:                ahd_unpause(ahd);
                   9424:                ahd_unlock(ahd, &s);
                   9425:                ccb->ccb_h.status = CAM_REQ_CMP;
                   9426:                xpt_print_path(ccb->ccb_h.path);
                   9427:                printf("Lun now enabled for target mode\n");
                   9428:        } else {
                   9429:                struct scb *scb;
                   9430:                int i, empty;
                   9431:
                   9432:                if (lstate == NULL) {
                   9433:                        ccb->ccb_h.status = CAM_LUN_INVALID;
                   9434:                        return;
                   9435:                }
                   9436:
                   9437:                ahd_lock(ahd, &s);
1.30      perry    9438:
1.1       fvdl     9439:                ccb->ccb_h.status = CAM_REQ_CMP;
                   9440:                LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
                   9441:                        struct ccb_hdr *ccbh;
                   9442:
                   9443:                        ccbh = &scb->io_ctx->ccb_h;
                   9444:                        if (ccbh->func_code == XPT_CONT_TARGET_IO
                   9445:                         && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
                   9446:                                printf("CTIO pending\n");
                   9447:                                ccb->ccb_h.status = CAM_REQ_INVALID;
                   9448:                                ahd_unlock(ahd, &s);
                   9449:                                return;
                   9450:                        }
                   9451:                }
                   9452:
                   9453:                if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
                   9454:                        printf("ATIOs pending\n");
                   9455:                        ccb->ccb_h.status = CAM_REQ_INVALID;
                   9456:                }
                   9457:
                   9458:                if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
                   9459:                        printf("INOTs pending\n");
                   9460:                        ccb->ccb_h.status = CAM_REQ_INVALID;
                   9461:                }
                   9462:
                   9463:                if (ccb->ccb_h.status != CAM_REQ_CMP) {
                   9464:                        ahd_unlock(ahd, &s);
                   9465:                        return;
                   9466:                }
                   9467:
                   9468:                xpt_print_path(ccb->ccb_h.path);
                   9469:                printf("Target mode disabled\n");
                   9470:                xpt_free_path(lstate->path);
                   9471:                free(lstate, M_DEVBUF);
                   9472:
                   9473:                ahd_pause(ahd);
                   9474:                /* Can we clean up the target too? */
                   9475:                if (target != CAM_TARGET_WILDCARD) {
                   9476:                        tstate->enabled_luns[lun] = NULL;
                   9477:                        ahd->enabled_luns--;
                   9478:                        for (empty = 1, i = 0; i < 8; i++)
                   9479:                                if (tstate->enabled_luns[i] != NULL) {
                   9480:                                        empty = 0;
                   9481:                                        break;
                   9482:                                }
                   9483:
                   9484:                        if (empty) {
                   9485:                                ahd_free_tstate(ahd, target, channel,
                   9486:                                                /*force*/FALSE);
                   9487:                                if (ahd->features & AHD_MULTI_TID) {
                   9488:                                        u_int targid_mask;
                   9489:
                   9490:                                        targid_mask = ahd_inb(ahd, TARGID)
                   9491:                                                    | (ahd_inb(ahd, TARGID + 1)
                   9492:                                                       << 8);
                   9493:
                   9494:                                        targid_mask &= ~target_mask;
                   9495:                                        ahd_outb(ahd, TARGID, targid_mask);
                   9496:                                        ahd_outb(ahd, TARGID+1,
1.43      tsutsui  9497:                                                 (targid_mask >> 8));
1.1       fvdl     9498:                                        ahd_update_scsiid(ahd, targid_mask);
                   9499:                                }
                   9500:                        }
                   9501:                } else {
                   9502:
                   9503:                        ahd->black_hole = NULL;
                   9504:
                   9505:                        /*
                   9506:                         * We can't allow selections without
                   9507:                         * our black hole device.
                   9508:                         */
                   9509:                        empty = TRUE;
                   9510:                }
                   9511:                if (ahd->enabled_luns == 0) {
                   9512:                        /* Disallow select-in */
                   9513:                        u_int scsiseq1;
                   9514:
                   9515:                        scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
                   9516:                        scsiseq1 &= ~ENSELI;
                   9517:                        ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1);
                   9518:                        scsiseq1 = ahd_inb(ahd, SCSISEQ1);
                   9519:                        scsiseq1 &= ~ENSELI;
                   9520:                        ahd_outb(ahd, SCSISEQ1, scsiseq1);
                   9521:
                   9522:                        if ((ahd->features & AHD_MULTIROLE) == 0) {
                   9523:                                printf("Configuring Initiator Mode\n");
                   9524:                                ahd->flags &= ~AHD_TARGETROLE;
                   9525:                                ahd->flags |= AHD_INITIATORROLE;
                   9526:                                ahd_pause(ahd);
                   9527:                                ahd_loadseq(ahd);
1.15      thorpej  9528:                                ahd_restart(ahd);
                   9529:                                /*
                   9530:                                 * Unpaused.  The extra unpause
                   9531:                                 * that follows is harmless.
                   9532:                                 */
1.1       fvdl     9533:                        }
                   9534:                }
                   9535:                ahd_unpause(ahd);
                   9536:                ahd_unlock(ahd, &s);
                   9537:        }
                   9538: #endif
                   9539: }
                   9540:
                   9541: static void
                   9542: ahd_update_scsiid(struct ahd_softc *ahd, u_int targid_mask)
                   9543: {
                   9544: #if NOT_YET
                   9545:        u_int scsiid_mask;
                   9546:        u_int scsiid;
                   9547:
                   9548:        if ((ahd->features & AHD_MULTI_TID) == 0)
                   9549:                panic("ahd_update_scsiid called on non-multitid unit\n");
                   9550:
                   9551:        /*
                   9552:         * Since we will rely on the TARGID mask
                   9553:         * for selection enables, ensure that OID
                   9554:         * in SCSIID is not set to some other ID
                   9555:         * that we don't want to allow selections on.
                   9556:         */
                   9557:        if ((ahd->features & AHD_ULTRA2) != 0)
                   9558:                scsiid = ahd_inb(ahd, SCSIID_ULTRA2);
                   9559:        else
                   9560:                scsiid = ahd_inb(ahd, SCSIID);
                   9561:        scsiid_mask = 0x1 << (scsiid & OID);
                   9562:        if ((targid_mask & scsiid_mask) == 0) {
                   9563:                u_int our_id;
                   9564:
                   9565:                /* ffs counts from 1 */
                   9566:                our_id = ffs(targid_mask);
                   9567:                if (our_id == 0)
                   9568:                        our_id = ahd->our_id;
                   9569:                else
                   9570:                        our_id--;
                   9571:                scsiid &= TID;
                   9572:                scsiid |= our_id;
                   9573:        }
                   9574:        if ((ahd->features & AHD_ULTRA2) != 0)
                   9575:                ahd_outb(ahd, SCSIID_ULTRA2, scsiid);
                   9576:        else
                   9577:                ahd_outb(ahd, SCSIID, scsiid);
                   9578: #endif
                   9579: }
                   9580:
                   9581: #ifdef AHD_TARGET_MODE
                   9582: void
                   9583: ahd_run_tqinfifo(struct ahd_softc *ahd, int paused)
                   9584: {
                   9585:        struct target_cmd *cmd;
                   9586:
                   9587:        ahd_sync_tqinfifo(ahd, BUS_DMASYNC_POSTREAD);
                   9588:        while ((cmd = &ahd->targetcmds[ahd->tqinfifonext])->cmd_valid != 0) {
                   9589:
                   9590:                /*
                   9591:                 * Only advance through the queue if we
                   9592:                 * have the resources to process the command.
                   9593:                 */
                   9594:                if (ahd_handle_target_cmd(ahd, cmd) != 0)
                   9595:                        break;
                   9596:
                   9597:                cmd->cmd_valid = 0;
                   9598:                ahd_dmamap_sync(ahd, ahd->parent_dmat /*shared_data_dmat*/,
1.7       thorpej  9599:                                ahd->shared_data_map.dmamap,
1.1       fvdl     9600:                                ahd_targetcmd_offset(ahd, ahd->tqinfifonext),
                   9601:                                sizeof(struct target_cmd),
                   9602:                                BUS_DMASYNC_PREREAD);
                   9603:                ahd->tqinfifonext++;
                   9604:
                   9605:                /*
                   9606:                 * Lazily update our position in the target mode incoming
                   9607:                 * command queue as seen by the sequencer.
                   9608:                 */
                   9609:                if ((ahd->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
                   9610:                        u_int hs_mailbox;
                   9611:
                   9612:                        hs_mailbox = ahd_inb(ahd, HS_MAILBOX);
                   9613:                        hs_mailbox &= ~HOST_TQINPOS;
                   9614:                        hs_mailbox |= ahd->tqinfifonext & HOST_TQINPOS;
                   9615:                        ahd_outb(ahd, HS_MAILBOX, hs_mailbox);
                   9616:                }
                   9617:        }
                   9618: }
                   9619: #endif
                   9620:
                   9621: static int
                   9622: ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd)
                   9623: {
                   9624:        struct    ahd_tmode_tstate *tstate;
                   9625:        struct    ahd_tmode_lstate *lstate;
                   9626:        struct    ccb_accept_tio *atio;
                   9627:        uint8_t *byte;
                   9628:        int       initiator;
                   9629:        int       target;
                   9630:        int       lun;
                   9631:
                   9632:        initiator = SCSIID_TARGET(ahd, cmd->scsiid);
                   9633:        target = SCSIID_OUR_ID(cmd->scsiid);
                   9634:        lun    = (cmd->identify & MSG_IDENTIFY_LUNMASK);
                   9635:
                   9636:        byte = cmd->bytes;
                   9637:        tstate = ahd->enabled_targets[target];
                   9638:        lstate = NULL;
                   9639:        if (tstate != NULL)
                   9640:                lstate = tstate->enabled_luns[lun];
                   9641:
                   9642:        /*
                   9643:         * Commands for disabled luns go to the black hole driver.
                   9644:         */
                   9645:        if (lstate == NULL)
                   9646:                lstate = ahd->black_hole;
                   9647:
                   9648:        atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
                   9649:        if (atio == NULL) {
                   9650:                ahd->flags |= AHD_TQINFIFO_BLOCKED;
                   9651:                /*
                   9652:                 * Wait for more ATIOs from the peripheral driver for this lun.
                   9653:                 */
                   9654:                return (1);
                   9655:        } else
                   9656:                ahd->flags &= ~AHD_TQINFIFO_BLOCKED;
                   9657: #ifdef AHD_DEBUG
                   9658:        if ((ahd_debug & AHD_SHOW_TQIN) != 0)
1.30      perry    9659:          printf("%s: incoming command from %d for %d:%d%s\n",
1.1       fvdl     9660:                 ahd_name(ahd),
                   9661:                 initiator, target, lun,
                   9662:                 lstate == ahd->black_hole ? "(Black Holed)" : "");
                   9663: #endif
                   9664:        SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
                   9665:
                   9666:        if (lstate == ahd->black_hole) {
                   9667:                /* Fill in the wildcards */
                   9668:                atio->ccb_h.target_id = target;
                   9669:                atio->ccb_h.target_lun = lun;
                   9670:        }
                   9671:
                   9672:        /*
                   9673:         * Package it up and send it off to
                   9674:         * whomever has this lun enabled.
                   9675:         */
                   9676:        atio->sense_len = 0;
                   9677:        atio->init_id = initiator;
                   9678:        if (byte[0] != 0xFF) {
                   9679:                /* Tag was included */
                   9680:                atio->tag_action = *byte++;
                   9681:                atio->tag_id = *byte++;
                   9682:                atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
                   9683:        } else {
                   9684:                atio->ccb_h.flags = 0;
                   9685:        }
                   9686:        byte++;
                   9687:
                   9688:        /* Okay.  Now determine the cdb size based on the command code */
                   9689:        switch (*byte >> CMD_GROUP_CODE_SHIFT) {
                   9690:        case 0:
                   9691:                atio->cdb_len = 6;
                   9692:                break;
                   9693:        case 1:
                   9694:        case 2:
                   9695:                atio->cdb_len = 10;
                   9696:                break;
                   9697:        case 4:
                   9698:                atio->cdb_len = 16;
                   9699:                break;
                   9700:        case 5:
                   9701:                atio->cdb_len = 12;
                   9702:                break;
                   9703:        case 3:
                   9704:        default:
                   9705:                /* Only copy the opcode. */
                   9706:                atio->cdb_len = 1;
                   9707:                printf("Reserved or VU command code type encountered\n");
                   9708:                break;
                   9709:        }
1.30      perry    9710:
1.1       fvdl     9711:        memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
                   9712:
                   9713:        atio->ccb_h.status |= CAM_CDB_RECVD;
                   9714:
                   9715:        if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
                   9716:                /*
                   9717:                 * We weren't allowed to disconnect.
                   9718:                 * We're hanging on the bus until a
                   9719:                 * continue target I/O comes in response
                   9720:                 * to this accept tio.
                   9721:                 */
                   9722: #ifdef AHD_DEBUG
                   9723:                if ((ahd_debug & AHD_SHOW_TQIN) != 0)
                   9724:                        printf("Received Immediate Command %d:%d:%d - %p\n",
                   9725:                               initiator, target, lun, ahd->pending_device);
                   9726: #endif
                   9727:                ahd->pending_device = lstate;
                   9728:                ahd_freeze_ccb((union ccb *)atio);
                   9729:                atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
                   9730:        }
                   9731:        xpt_done((union ccb*)atio);
                   9732:        return (0);
                   9733: }
                   9734:
                   9735: #endif
                   9736:
                   9737: static int
1.44      tsutsui  9738: ahd_createdmamem(bus_dma_tag_t tag, int size, int flags, bus_dmamap_t *mapp,
                   9739:     void **vaddr, bus_addr_t *baddr, bus_dma_segment_t *seg, int *nseg,
                   9740:     const char *myname, const char *what)
1.1       fvdl     9741: {
                   9742:        int error, level = 0;
                   9743:
                   9744:        if ((error = bus_dmamem_alloc(tag, size, PAGE_SIZE, 0,
1.32      bouyer   9745:                                      seg, 1, nseg, BUS_DMA_WAITOK)) != 0) {
1.1       fvdl     9746:                printf("%s: failed to allocate DMA mem for %s, error = %d\n",
                   9747:                        myname, what, error);
                   9748:                goto out;
                   9749:        }
                   9750:        level++;
                   9751:
                   9752:        if ((error = bus_dmamem_map(tag, seg, *nseg, size, vaddr,
1.32      bouyer   9753:                                    BUS_DMA_WAITOK|BUS_DMA_COHERENT)) != 0) {
1.1       fvdl     9754:                printf("%s: failed to map DMA mem for %s, error = %d\n",
                   9755:                        myname, what, error);
                   9756:                goto out;
                   9757:        }
                   9758:        level++;
                   9759:
                   9760:        if ((error = bus_dmamap_create(tag, size, 1, size, 0,
1.32      bouyer   9761:                                       BUS_DMA_WAITOK | flags, mapp)) != 0) {
1.43      tsutsui  9762:                printf("%s: failed to create DMA map for %s, error = %d\n",
1.1       fvdl     9763:                        myname, what, error);
                   9764:                goto out;
1.43      tsutsui  9765:        }
1.1       fvdl     9766:        level++;
                   9767:
                   9768:
                   9769:        if ((error = bus_dmamap_load(tag, *mapp, *vaddr, size, NULL,
1.32      bouyer   9770:                                     BUS_DMA_WAITOK)) != 0) {
1.43      tsutsui  9771:                printf("%s: failed to load DMA map for %s, error = %d\n",
1.1       fvdl     9772:                        myname, what, error);
                   9773:                goto out;
1.43      tsutsui  9774:        }
1.1       fvdl     9775:
                   9776:        *baddr = (*mapp)->dm_segs[0].ds_addr;
                   9777:
                   9778:        return 0;
                   9779: out:
                   9780:        printf("ahd_createdmamem error (%d)\n", level);
                   9781:        switch (level) {
                   9782:        case 3:
                   9783:                bus_dmamap_destroy(tag, *mapp);
                   9784:                /* FALLTHROUGH */
                   9785:        case 2:
                   9786:                bus_dmamem_unmap(tag, *vaddr, size);
                   9787:                /* FALLTHROUGH */
                   9788:        case 1:
                   9789:                bus_dmamem_free(tag, seg, *nseg);
                   9790:                break;
                   9791:        default:
                   9792:                break;
                   9793:        }
                   9794:
                   9795:        return error;
                   9796: }
                   9797:
                   9798: static void
1.44      tsutsui  9799: ahd_freedmamem(bus_dma_tag_t tag, int size, bus_dmamap_t map, void *vaddr,
                   9800:     bus_dma_segment_t *seg, int nseg)
1.1       fvdl     9801: {
                   9802:
                   9803:        bus_dmamap_unload(tag, map);
                   9804:        bus_dmamap_destroy(tag, map);
                   9805:        bus_dmamem_unmap(tag, vaddr, size);
                   9806:        bus_dmamem_free(tag, seg, nseg);
                   9807: }

CVSweb <webmaster@jp.NetBSD.org>