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

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

1.1       nbrk        1: /*     $OpenBSD: advlib.c,v 1.12 2005/09/06 02:22:37 krw Exp $ */
                      2: /*      $NetBSD: advlib.c,v 1.7 1998/10/28 20:39:46 dante Exp $        */
                      3:
                      4: /*
                      5:  * Low level routines for the Advanced Systems Inc. SCSI controllers chips
                      6:  *
                      7:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
                      8:  * All rights reserved.
                      9:  *
                     10:  * Author: Baldassare Dante Profeta <dante@mclink.it>
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *        This product includes software developed by the NetBSD
                     23:  *        Foundation, Inc. and its contributors.
                     24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     25:  *    contributors may be used to endorse or promote products derived
                     26:  *    from this software without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     38:  * POSSIBILITY OF SUCH DAMAGE.
                     39:  */
                     40: /*
                     41:  * Ported from:
                     42:  */
                     43: /*
                     44:  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
                     45:  *
                     46:  * Copyright (c) 1995-1998 Advanced System Products, Inc.
                     47:  * All Rights Reserved.
                     48:  *
                     49:  * Redistribution and use in source and binary forms, with or without
                     50:  * modification, are permitted provided that redistributions of source
                     51:  * code retain the above copyright notice and this comment without
                     52:  * modification.
                     53:  *
                     54:  */
                     55:
                     56: #include <sys/types.h>
                     57: #include <sys/param.h>
                     58: #include <sys/systm.h>
                     59: #include <sys/malloc.h>
                     60: #include <sys/kernel.h>
                     61: #include <sys/queue.h>
                     62: #include <sys/device.h>
                     63:
                     64: #include <machine/bus.h>
                     65: #include <machine/intr.h>
                     66:
                     67: #include <scsi/scsi_all.h>
                     68: #include <scsi/scsiconf.h>
                     69:
                     70: #include <uvm/uvm_extern.h>
                     71:
                     72: #include <dev/ic/adv.h>
                     73: #include <dev/ic/advlib.h>
                     74:
                     75: #include <dev/microcode/adw/advmcode.h>
                     76:
                     77:
                     78: /* #define ASC_DEBUG */
                     79:
                     80: /******************************************************************************/
                     81: /*                                Static functions                            */
                     82: /******************************************************************************/
                     83:
                     84: /* Initialization routines */
                     85: static u_int32_t AscLoadMicroCode(bus_space_tag_t, bus_space_handle_t,
                     86:                                        u_int16_t, u_int16_t *, u_int16_t);
                     87: static void AscInitLram(ASC_SOFTC *);
                     88: static void AscInitQLinkVar(ASC_SOFTC *);
                     89: static int AscResetChipAndScsiBus(bus_space_tag_t, bus_space_handle_t);
                     90: static u_int16_t AscGetChipBusType(bus_space_tag_t, bus_space_handle_t);
                     91:
                     92: /* Chip register routines */
                     93: static void AscSetBank(bus_space_tag_t, bus_space_handle_t, u_int8_t);
                     94:
                     95: /* RISC Chip routines */
                     96: static int AscStartChip(bus_space_tag_t, bus_space_handle_t);
                     97: static int AscStopChip(bus_space_tag_t, bus_space_handle_t);
                     98: static u_int8_t AscSetChipScsiID(bus_space_tag_t, bus_space_handle_t,
                     99:                                        u_int8_t);
                    100: static u_int8_t AscGetChipScsiCtrl(bus_space_tag_t, bus_space_handle_t);
                    101: static u_int8_t AscGetChipVersion(bus_space_tag_t, bus_space_handle_t,
                    102:                                        u_int16_t);
                    103: static int AscSetRunChipSynRegAtID(bus_space_tag_t, bus_space_handle_t,
                    104:                                        u_int8_t, u_int8_t);
                    105: static int AscSetChipSynRegAtID(bus_space_tag_t, bus_space_handle_t,
                    106:                                        u_int8_t, u_int8_t);
                    107: static int AscHostReqRiscHalt(bus_space_tag_t, bus_space_handle_t);
                    108: static int AscIsChipHalted(bus_space_tag_t, bus_space_handle_t);
                    109: static void AscSetChipIH(bus_space_tag_t, bus_space_handle_t, u_int16_t);
                    110:
                    111: /* Lram routines */
                    112: static u_int8_t AscReadLramByte(bus_space_tag_t, bus_space_handle_t,
                    113:                                        u_int16_t);
                    114: static void AscWriteLramByte(bus_space_tag_t, bus_space_handle_t,
                    115:                                        u_int16_t, u_int8_t);
                    116: static u_int16_t AscReadLramWord(bus_space_tag_t, bus_space_handle_t,
                    117:                                        u_int16_t);
                    118: static void AscWriteLramWord(bus_space_tag_t, bus_space_handle_t,
                    119:                                        u_int16_t, u_int16_t);
                    120: static u_int32_t AscReadLramDWord(bus_space_tag_t, bus_space_handle_t,
                    121:                                        u_int16_t);
                    122: static void AscWriteLramDWord(bus_space_tag_t, bus_space_handle_t,
                    123:                                        u_int16_t, u_int32_t);
                    124: static void AscMemWordSetLram(bus_space_tag_t, bus_space_handle_t,
                    125:                                        u_int16_t, u_int16_t, int);
                    126: static void AscMemWordCopyToLram(bus_space_tag_t, bus_space_handle_t,
                    127:                                        u_int16_t, u_int16_t *, int);
                    128: static void AscMemWordCopyFromLram(bus_space_tag_t, bus_space_handle_t,
                    129:                                        u_int16_t, u_int16_t *, int);
                    130: static void AscMemDWordCopyToLram(bus_space_tag_t, bus_space_handle_t,
                    131:                                        u_int16_t, u_int32_t *, int);
                    132: static u_int32_t AscMemSumLramWord(bus_space_tag_t, bus_space_handle_t,
                    133:                                        u_int16_t, int);
                    134: static int AscTestExternalLram(bus_space_tag_t, bus_space_handle_t);
                    135:
                    136: /* MicroCode routines */
                    137: static u_int16_t AscInitMicroCodeVar(ASC_SOFTC *);
                    138: static u_int32_t AscGetOnePhyAddr(ASC_SOFTC *, u_int8_t *, u_int32_t);
                    139: static u_int32_t AscGetSGList(ASC_SOFTC *, u_int8_t *, u_int32_t,
                    140:                                        ASC_SG_HEAD *);
                    141:
                    142: /* EEProm routines */
                    143: static int AscWriteEEPCmdReg(bus_space_tag_t, bus_space_handle_t,
                    144:                                        u_int8_t);
                    145: static int AscWriteEEPDataReg(bus_space_tag_t, bus_space_handle_t,
                    146:                                        u_int16_t);
                    147: static void AscWaitEEPRead(void);
                    148: static void AscWaitEEPWrite(void);
                    149: static u_int16_t AscReadEEPWord(bus_space_tag_t, bus_space_handle_t,
                    150:                                        u_int8_t);
                    151: static u_int16_t AscWriteEEPWord(bus_space_tag_t, bus_space_handle_t,
                    152:                                        u_int8_t, u_int16_t);
                    153: static u_int16_t AscGetEEPConfig(bus_space_tag_t, bus_space_handle_t,
                    154:                                        ASCEEP_CONFIG *, u_int16_t);
                    155: static int AscSetEEPConfig(bus_space_tag_t, bus_space_handle_t,
                    156:                                        ASCEEP_CONFIG *, u_int16_t);
                    157: static int AscSetEEPConfigOnce(bus_space_tag_t, bus_space_handle_t,
                    158:                                        ASCEEP_CONFIG *, u_int16_t);
                    159: #ifdef ASC_DEBUG
                    160: static void AscPrintEEPConfig(ASCEEP_CONFIG *, u_int16_t);
                    161: #endif
                    162:
                    163: /* Interrupt routines */
                    164: static void AscIsrChipHalted(ASC_SOFTC *);
                    165: static int AscIsrQDone(ASC_SOFTC *);
                    166: static int AscWaitTixISRDone(ASC_SOFTC *, u_int8_t);
                    167: static int AscWaitISRDone(ASC_SOFTC *);
                    168: static u_int8_t _AscCopyLramScsiDoneQ(bus_space_tag_t, bus_space_handle_t,
                    169:                                        u_int16_t, ASC_QDONE_INFO *,
                    170:                                        u_int32_t);
                    171: static void AscGetQDoneInfo(bus_space_tag_t, bus_space_handle_t, u_int16_t,
                    172:                                        ASC_QDONE_INFO *);
                    173: static void AscToggleIRQAct(bus_space_tag_t, bus_space_handle_t);
                    174: static void AscDisableInterrupt(bus_space_tag_t, bus_space_handle_t);
                    175: static void AscEnableInterrupt(bus_space_tag_t, bus_space_handle_t);
                    176: static u_int8_t AscGetChipIRQ(bus_space_tag_t, bus_space_handle_t,
                    177:                                        u_int16_t);
                    178: static u_int8_t AscSetChipIRQ(bus_space_tag_t, bus_space_handle_t,
                    179:                                        u_int8_t, u_int16_t);
                    180: static void AscAckInterrupt(bus_space_tag_t, bus_space_handle_t);
                    181: static u_int32_t AscGetMaxDmaCount(u_int16_t);
                    182: static u_int16_t AscGetIsaDmaChannel(bus_space_tag_t, bus_space_handle_t);
                    183: static u_int16_t AscSetIsaDmaChannel(bus_space_tag_t, bus_space_handle_t,
                    184:                                        u_int16_t);
                    185: static u_int8_t AscGetIsaDmaSpeed(bus_space_tag_t, bus_space_handle_t);
                    186: static u_int8_t AscSetIsaDmaSpeed(bus_space_tag_t, bus_space_handle_t,
                    187:                                        u_int8_t);
                    188:
                    189: /* Messages routines */
                    190: static void AscHandleExtMsgIn(ASC_SOFTC *, u_int16_t, u_int8_t,
                    191:                                        ASC_SCSI_BIT_ID_TYPE, int, u_int8_t);
                    192: static u_int8_t AscMsgOutSDTR(ASC_SOFTC *, u_int8_t, u_int8_t);
                    193:
                    194: /* SDTR routines */
                    195: static void AscSetChipSDTR(bus_space_tag_t, bus_space_handle_t,
                    196:                                        u_int8_t, u_int8_t);
                    197: static u_int8_t AscCalSDTRData(ASC_SOFTC *, u_int8_t, u_int8_t);
                    198: static u_int8_t AscGetSynPeriodIndex(ASC_SOFTC *, u_int8_t);
                    199:
                    200: /* Queue routines */
                    201: static int AscSendScsiQueue(ASC_SOFTC *, ASC_SCSI_Q *, u_int8_t);
                    202: static int AscSgListToQueue(int);
                    203: static u_int AscGetNumOfFreeQueue(ASC_SOFTC *, u_int8_t, u_int8_t);
                    204: static int AscPutReadyQueue(ASC_SOFTC *, ASC_SCSI_Q *, u_int8_t);
                    205: static void AscPutSCSIQ(bus_space_tag_t, bus_space_handle_t,
                    206:                                         u_int16_t, ASC_SCSI_Q *);
                    207: static int AscPutReadySgListQueue(ASC_SOFTC *, ASC_SCSI_Q *, u_int8_t);
                    208: static u_int8_t AscAllocFreeQueue(bus_space_tag_t, bus_space_handle_t,
                    209:                                        u_int8_t);
                    210: static u_int8_t AscAllocMultipleFreeQueue(bus_space_tag_t,
                    211:                                        bus_space_handle_t,
                    212:                                        u_int8_t, u_int8_t);
                    213: static int AscStopQueueExe(bus_space_tag_t, bus_space_handle_t);
                    214: static void AscStartQueueExe(bus_space_tag_t, bus_space_handle_t);
                    215: static void AscCleanUpBusyQueue(bus_space_tag_t, bus_space_handle_t);
                    216: static int _AscWaitQDone(bus_space_tag_t, bus_space_handle_t,
                    217:                                        ASC_SCSI_Q *);
                    218: static int AscCleanUpDiscQueue(bus_space_tag_t, bus_space_handle_t);
                    219:
                    220: /* Abort and Reset CCB routines */
                    221: static int AscRiscHaltedAbortCCB(ASC_SOFTC *, u_int32_t);
                    222: static int AscRiscHaltedAbortTIX(ASC_SOFTC *, u_int8_t);
                    223:
                    224: /* Error Handling routines */
                    225: static int AscSetLibErrorCode(ASC_SOFTC *, u_int16_t);
                    226:
                    227: /* Handle bugged borads routines */
                    228: static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
                    229: static void AscAsyncFix(ASC_SOFTC *, u_int8_t, ASC_SCSI_INQUIRY *);
                    230:
                    231: /* Miscellaneous routines */
                    232: static int AscCompareString(u_char *, u_char *, int);
                    233:
                    234: /* Device oriented routines */
                    235: static int DvcEnterCritical(void);
                    236: static void DvcLeaveCritical(int);
                    237: static void DvcSleepMilliSecond(u_int32_t);
                    238: //static void DvcDelayMicroSecond(u_int32_t);
                    239: static void DvcDelayNanoSecond(u_int32_t);
                    240:
                    241:
                    242: /******************************************************************************/
                    243: /*                            Initialization routines                         */
                    244: /******************************************************************************/
                    245:
                    246: /*
                    247:  * This function perform the following steps:
                    248:  * - initialize ASC_SOFTC structure with defaults values.
                    249:  * - inquire board registers to know what kind of board it is.
                    250:  * - keep track of bugged borads.
                    251:  */
                    252: void
                    253: AscInitASC_SOFTC(sc)
                    254:        ASC_SOFTC      *sc;
                    255: {
                    256:        bus_space_tag_t iot = sc->sc_iot;
                    257:        bus_space_handle_t ioh = sc->sc_ioh;
                    258:        int             i;
                    259:        u_int8_t        chip_version;
                    260:
                    261:
                    262:        ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_HALT);
                    263:        ASC_SET_CHIP_STATUS(iot, ioh, 0);
                    264:
                    265:        sc->bug_fix_cntl = 0;
                    266:        sc->pci_fix_asyn_xfer = 0;
                    267:        sc->pci_fix_asyn_xfer_always = 0;
                    268:        sc->sdtr_done = 0;
                    269:        sc->cur_total_qng = 0;
                    270:        sc->last_q_shortage = 0;
                    271:        sc->use_tagged_qng = 0;
                    272:        sc->unit_not_ready = 0;
                    273:        sc->queue_full_or_busy = 0;
                    274:        sc->host_init_sdtr_index = 0;
                    275:        sc->can_tagged_qng = 0;
                    276:        sc->cmd_qng_enabled = 0;
                    277:        sc->dvc_cntl = ASC_DEF_DVC_CNTL;
                    278:        sc->init_sdtr = 0;
                    279:        sc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
                    280:        sc->scsi_reset_wait = 3;
                    281:        sc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
                    282:        sc->max_dma_count = AscGetMaxDmaCount(sc->bus_type);
                    283:        sc->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
                    284:        sc->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
                    285:        sc->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
                    286:        sc->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
                    287:        sc->lib_version = (ASC_LIB_VERSION_MAJOR << 8) | ASC_LIB_VERSION_MINOR;
                    288:        chip_version = AscGetChipVersion(iot, ioh, sc->bus_type);
                    289:        sc->chip_version = chip_version;
                    290:        if ((sc->bus_type & ASC_IS_PCI) &&
                    291:            (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
                    292:                sc->bus_type = ASC_IS_PCI_ULTRA;
                    293:                sc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
                    294:                sc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
                    295:                sc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
                    296:                sc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
                    297:                sc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
                    298:                sc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
                    299:                sc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
                    300:                sc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
                    301:                sc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
                    302:                sc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
                    303:                sc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
                    304:                sc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
                    305:                sc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
                    306:                sc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
                    307:                sc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
                    308:                sc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
                    309:                sc->max_sdtr_index = 15;
                    310:                if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
                    311:                        ASC_SET_EXTRA_CONTROL(iot, ioh,
                    312:                                       (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
                    313:                else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050)
                    314:                        ASC_SET_EXTRA_CONTROL(iot, ioh,
                    315:                                   (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
                    316:        } else {
                    317:                sc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
                    318:                sc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
                    319:                sc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
                    320:                sc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
                    321:                sc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
                    322:                sc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
                    323:                sc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
                    324:                sc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
                    325:                sc->max_sdtr_index = 7;
                    326:        }
                    327:
                    328:        if (sc->bus_type == ASC_IS_PCI)
                    329:                ASC_SET_EXTRA_CONTROL(iot, ioh,
                    330:                                      (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
                    331:
                    332:        sc->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
                    333:        if (AscGetChipBusType(iot, ioh) == ASC_IS_ISAPNP) {
                    334:                ASC_SET_CHIP_IFC(iot, ioh, ASC_IFC_INIT_DEFAULT);
                    335:                sc->bus_type = ASC_IS_ISAPNP;
                    336:        }
                    337:        if ((sc->bus_type & ASC_IS_ISA) != 0)
                    338:                sc->isa_dma_channel = AscGetIsaDmaChannel(iot, ioh);
                    339:
                    340:        for (i = 0; i <= ASC_MAX_TID; i++) {
                    341:                sc->cur_dvc_qng[i] = 0;
                    342:                sc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
                    343:                sc->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
                    344:        }
                    345: }
                    346:
                    347:
                    348: /*
                    349:  * This function initialize some ASC_SOFTC fields with values read from
                    350:  * on-board EEProm.
                    351:  */
                    352: u_int16_t
                    353: AscInitFromEEP(sc)
                    354:        ASC_SOFTC      *sc;
                    355: {
                    356:        bus_space_tag_t iot = sc->sc_iot;
                    357:        bus_space_handle_t ioh = sc->sc_ioh;
                    358:        ASCEEP_CONFIG   eep_config_buf;
                    359:        ASCEEP_CONFIG  *eep_config;
                    360:        u_int16_t       chksum;
                    361:        u_int16_t       warn_code;
                    362:        u_int16_t       cfg_msw, cfg_lsw;
                    363:        int             i;
                    364:        int             write_eep = 0;
                    365:
                    366:
                    367:        warn_code = 0;
                    368:        AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0x00FE);
                    369:        AscStopQueueExe(iot, ioh);
                    370:        if ((AscStopChip(iot, ioh) == FALSE) ||
                    371:            (AscGetChipScsiCtrl(iot, ioh) != 0)) {
                    372:                AscResetChipAndScsiBus(iot, ioh);
                    373:                DvcSleepMilliSecond(sc->scsi_reset_wait * 1000);
                    374:        }
                    375:        if (AscIsChipHalted(iot, ioh) == FALSE)
                    376:                return (-1);
                    377:
                    378:        ASC_SET_PC_ADDR(iot, ioh, ASC_MCODE_START_ADDR);
                    379:        if (ASC_GET_PC_ADDR(iot, ioh) != ASC_MCODE_START_ADDR)
                    380:                return (-2);
                    381:
                    382:        eep_config = &eep_config_buf;
                    383:        cfg_msw = ASC_GET_CHIP_CFG_MSW(iot, ioh);
                    384:        cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh);
                    385:        if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
                    386:                cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
                    387:                warn_code |= ASC_WARN_CFG_MSW_RECOVER;
                    388:                ASC_SET_CHIP_CFG_MSW(iot, ioh, cfg_msw);
                    389:        }
                    390:        chksum = AscGetEEPConfig(iot, ioh, eep_config, sc->bus_type);
                    391: #ifdef ASC_DEBUG
                    392:        AscPrintEEPConfig(eep_config, chksum);
                    393: #endif
                    394:        if (chksum == 0)
                    395:                chksum = 0xAA55;
                    396:
                    397:        if (ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_AUTO_CONFIG) {
                    398:                warn_code |= ASC_WARN_AUTO_CONFIG;
                    399:                if (sc->chip_version == 3) {
                    400:                        if (eep_config->cfg_lsw != cfg_lsw) {
                    401:                                warn_code |= ASC_WARN_EEPROM_RECOVER;
                    402:                                eep_config->cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh);
                    403:                        }
                    404:                        if (eep_config->cfg_msw != cfg_msw) {
                    405:                                warn_code |= ASC_WARN_EEPROM_RECOVER;
                    406:                                eep_config->cfg_msw = ASC_GET_CHIP_CFG_MSW(iot, ioh);
                    407:                        }
                    408:                }
                    409:        }
                    410:        eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
                    411:        eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
                    412:
                    413:        if (chksum != eep_config->chksum) {
                    414:                if (AscGetChipVersion(iot, ioh, sc->bus_type) ==
                    415:                    ASC_CHIP_VER_PCI_ULTRA_3050) {
                    416:                        eep_config->init_sdtr = 0xFF;
                    417:                        eep_config->disc_enable = 0xFF;
                    418:                        eep_config->start_motor = 0xFF;
                    419:                        eep_config->use_cmd_qng = 0;
                    420:                        eep_config->max_total_qng = 0xF0;
                    421:                        eep_config->max_tag_qng = 0x20;
                    422:                        eep_config->cntl = 0xBFFF;
                    423:                        eep_config->chip_scsi_id = 7;
                    424:                        eep_config->no_scam = 0;
                    425:                        eep_config->adapter_info[0] = 0;
                    426:                        eep_config->adapter_info[1] = 0;
                    427:                        eep_config->adapter_info[2] = 0;
                    428:                        eep_config->adapter_info[3] = 0;
                    429: #if BYTE_ORDER == BIG_ENDIAN
                    430:                        eep_config->adapter_info[5] = 0;
                    431:                        /* Indicate EEPROM-less board. */
                    432:                        eep_config->adapter_info[4] = 0xBB;
                    433: #else
                    434:                        eep_config->adapter_info[4] = 0;
                    435:                        /* Indicate EEPROM-less board. */
                    436:                        eep_config->adapter_info[5] = 0xBB;
                    437: #endif
                    438:                } else {
                    439:                        write_eep = 1;
                    440:                        warn_code |= ASC_WARN_EEPROM_CHKSUM;
                    441:                }
                    442:        }
                    443:        sc->sdtr_enable = eep_config->init_sdtr;
                    444:        sc->disc_enable = eep_config->disc_enable;
                    445:        sc->cmd_qng_enabled = eep_config->use_cmd_qng;
                    446:        sc->isa_dma_speed = eep_config->isa_dma_speed;
                    447:        sc->start_motor = eep_config->start_motor;
                    448:        sc->dvc_cntl = eep_config->cntl;
                    449: #if BYTE_ORDER == BIG_ENDIAN
                    450:        sc->adapter_info[0] = eep_config->adapter_info[1];
                    451:        sc->adapter_info[1] = eep_config->adapter_info[0];
                    452:        sc->adapter_info[2] = eep_config->adapter_info[3];
                    453:        sc->adapter_info[3] = eep_config->adapter_info[2];
                    454:        sc->adapter_info[4] = eep_config->adapter_info[5];
                    455:        sc->adapter_info[5] = eep_config->adapter_info[4];
                    456: #else
                    457:        sc->adapter_info[0] = eep_config->adapter_info[0];
                    458:        sc->adapter_info[1] = eep_config->adapter_info[1];
                    459:        sc->adapter_info[2] = eep_config->adapter_info[2];
                    460:        sc->adapter_info[3] = eep_config->adapter_info[3];
                    461:        sc->adapter_info[4] = eep_config->adapter_info[4];
                    462:        sc->adapter_info[5] = eep_config->adapter_info[5];
                    463: #endif
                    464:
                    465:        if (!AscTestExternalLram(iot, ioh)) {
                    466:                if (((sc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
                    467:                        eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
                    468:                        eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
                    469:                } else {
                    470:                        eep_config->cfg_msw |= 0x0800;
                    471:                        cfg_msw |= 0x0800;
                    472:                        ASC_SET_CHIP_CFG_MSW(iot, ioh, cfg_msw);
                    473:                        eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
                    474:                        eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
                    475:                }
                    476:        }
                    477:        if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG)
                    478:                eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
                    479:
                    480:        if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG)
                    481:                eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
                    482:
                    483:        if (eep_config->max_tag_qng > eep_config->max_total_qng)
                    484:                eep_config->max_tag_qng = eep_config->max_total_qng;
                    485:
                    486:        if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC)
                    487:                eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
                    488:
                    489:        sc->max_total_qng = eep_config->max_total_qng;
                    490:        if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
                    491:            eep_config->use_cmd_qng) {
                    492:                eep_config->disc_enable = eep_config->use_cmd_qng;
                    493:                warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
                    494:        }
                    495:        if (sc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA))
                    496:                sc->irq_no = AscGetChipIRQ(iot, ioh, sc->bus_type);
                    497:
                    498:        eep_config->chip_scsi_id &= ASC_MAX_TID;
                    499:        sc->chip_scsi_id = eep_config->chip_scsi_id;
                    500:        if (((sc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
                    501:            !(sc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
                    502:                sc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
                    503:        }
                    504:        for (i = 0; i <= ASC_MAX_TID; i++) {
                    505:                sc->max_tag_qng[i] = eep_config->max_tag_qng;
                    506:                sc->sdtr_period_offset[i] = ASC_DEF_SDTR_OFFSET |
                    507:                        (sc->host_init_sdtr_index << 4);
                    508:        }
                    509:
                    510:        eep_config->cfg_msw = ASC_GET_CHIP_CFG_MSW(iot, ioh);
                    511:        if (write_eep) {
                    512:                AscSetEEPConfig(iot, ioh, eep_config, sc->bus_type);
                    513: #ifdef ASC_DEBUG
                    514:                AscPrintEEPConfig(eep_config, 0);
                    515: #endif
                    516:        }
                    517:
                    518:        return (warn_code);
                    519: }
                    520:
                    521:
                    522: u_int16_t
                    523: AscInitFromASC_SOFTC(sc)
                    524:        ASC_SOFTC      *sc;
                    525: {
                    526:        bus_space_tag_t iot = sc->sc_iot;
                    527:        bus_space_handle_t ioh = sc->sc_ioh;
                    528:        u_int16_t       cfg_msw;
                    529:        u_int16_t       warn_code;
                    530:        u_int16_t       pci_device_id = sc->pci_device_id;
                    531:
                    532:
                    533:        warn_code = 0;
                    534:        cfg_msw = ASC_GET_CHIP_CFG_MSW(iot, ioh);
                    535:
                    536:        if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
                    537:                cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
                    538:                warn_code |= ASC_WARN_CFG_MSW_RECOVER;
                    539:                ASC_SET_CHIP_CFG_MSW(iot, ioh, cfg_msw);
                    540:        }
                    541:        if ((sc->cmd_qng_enabled & sc->disc_enable) != sc->cmd_qng_enabled) {
                    542:                sc->disc_enable = sc->cmd_qng_enabled;
                    543:                warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
                    544:        }
                    545:        if (ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_AUTO_CONFIG) {
                    546:                warn_code |= ASC_WARN_AUTO_CONFIG;
                    547:        }
                    548:        if ((sc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
                    549:                AscSetChipIRQ(iot, ioh, sc->irq_no, sc->bus_type);
                    550:        }
                    551:        if (sc->bus_type & ASC_IS_PCI) {
                    552:                cfg_msw &= 0xFFC0;
                    553:                ASC_SET_CHIP_CFG_MSW(iot, ioh, cfg_msw);
                    554:
                    555:                if ((sc->bus_type & ASC_IS_PCI_ULTRA) != ASC_IS_PCI_ULTRA) {
                    556:                        if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
                    557:                            (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
                    558:                                sc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
                    559:                                sc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
                    560:                        }
                    561:                }
                    562:        } else if (sc->bus_type == ASC_IS_ISAPNP) {
                    563:                if (AscGetChipVersion(iot, ioh, sc->bus_type) ==
                    564:                    ASC_CHIP_VER_ASYN_BUG) {
                    565:                        sc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
                    566:                }
                    567:        }
                    568:        AscSetChipScsiID(iot, ioh, sc->chip_scsi_id);
                    569:
                    570:        if (sc->bus_type & ASC_IS_ISA) {
                    571:                AscSetIsaDmaChannel(iot, ioh, sc->isa_dma_channel);
                    572:                AscSetIsaDmaSpeed(iot, ioh, sc->isa_dma_speed);
                    573:        }
                    574:        return (warn_code);
                    575: }
                    576:
                    577:
                    578: /*
                    579:  * - Initialize RISC chip
                    580:  * - Initialize Lram
                    581:  * - Load uCode into Lram
                    582:  * - Enable Interrupts
                    583:  */
                    584: int
                    585: AscInitDriver(sc)
                    586:        ASC_SOFTC      *sc;
                    587: {
                    588:        bus_space_tag_t iot = sc->sc_iot;
                    589:        bus_space_handle_t ioh = sc->sc_ioh;
                    590:        u_int32_t       chksum;
                    591:
                    592:
                    593:        if (!AscFindSignature(iot, ioh))
                    594:                return (1);
                    595:
                    596:        AscDisableInterrupt(iot, ioh);
                    597:
                    598:        AscInitLram(sc);
                    599:        chksum = AscLoadMicroCode(iot, ioh, 0, (u_int16_t *) asc_mcode,
                    600:                                  asc_mcode_size);
                    601:        if (chksum != asc_mcode_chksum)
                    602:                return (2);
                    603:
                    604:        if (AscInitMicroCodeVar(sc) == 0)
                    605:                return (3);
                    606:
                    607:        AscEnableInterrupt(iot, ioh);
                    608:
                    609:        return (0);
                    610: }
                    611:
                    612:
                    613: int
                    614: AscFindSignature(iot, ioh)
                    615:        bus_space_tag_t iot;
                    616:        bus_space_handle_t ioh;
                    617: {
                    618:        u_int16_t       sig_word;
                    619:
                    620:        if (ASC_GET_CHIP_SIGNATURE_BYTE(iot, ioh) == ASC_1000_ID1B) {
                    621:                sig_word = ASC_GET_CHIP_SIGNATURE_WORD(iot, ioh);
                    622:                if (sig_word == ASC_1000_ID0W ||
                    623:                    sig_word == ASC_1000_ID0W_FIX)
                    624:                        return (1);
                    625:        }
                    626:        return (0);
                    627: }
                    628:
                    629:
                    630: static void
                    631: AscInitLram(sc)
                    632:        ASC_SOFTC      *sc;
                    633: {
                    634:        bus_space_tag_t iot = sc->sc_iot;
                    635:        bus_space_handle_t ioh = sc->sc_ioh;
                    636:        u_int8_t        i;
                    637:        u_int16_t       s_addr;
                    638:
                    639:
                    640:        AscMemWordSetLram(iot, ioh, ASC_QADR_BEG, 0,
                    641:                          (((sc->max_total_qng + 2 + 1) * 64) >> 1));
                    642:
                    643:        i = ASC_MIN_ACTIVE_QNO;
                    644:        s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
                    645:        AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_FWD, i + 1);
                    646:        AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_BWD, sc->max_total_qng);
                    647:        AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_QNO, i);
                    648:        i++;
                    649:        s_addr += ASC_QBLK_SIZE;
                    650:        for (; i < sc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
                    651:                AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_FWD, i + 1);
                    652:                AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_BWD, i - 1);
                    653:                AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_QNO, i);
                    654:        }
                    655:        AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_FWD, ASC_QLINK_END);
                    656:        AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_BWD, sc->max_total_qng - 1);
                    657:        AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_QNO, sc->max_total_qng);
                    658:        i++;
                    659:        s_addr += ASC_QBLK_SIZE;
                    660:        for (; i <= (u_int8_t) (sc->max_total_qng + 3); i++, s_addr += ASC_QBLK_SIZE) {
                    661:                AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_FWD, i);
                    662:                AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_BWD, i);
                    663:                AscWriteLramByte(iot, ioh, s_addr + ASC_SCSIQ_B_QNO, i);
                    664:        }
                    665: }
                    666:
                    667:
                    668: void
                    669: AscReInitLram(sc)
                    670:        ASC_SOFTC      *sc;
                    671: {
                    672:
                    673:        AscInitLram(sc);
                    674:        AscInitQLinkVar(sc);
                    675: }
                    676:
                    677:
                    678: static void
                    679: AscInitQLinkVar(sc)
                    680:        ASC_SOFTC      *sc;
                    681: {
                    682:        bus_space_tag_t iot = sc->sc_iot;
                    683:        bus_space_handle_t ioh = sc->sc_ioh;
                    684:        u_int8_t        i;
                    685:        u_int16_t       lram_addr;
                    686:
                    687:
                    688:        ASC_PUT_RISC_VAR_FREE_QHEAD(iot, ioh, 1);
                    689:        ASC_PUT_RISC_VAR_DONE_QTAIL(iot, ioh, sc->max_total_qng);
                    690:        ASC_PUT_VAR_FREE_QHEAD(iot, ioh, 1);
                    691:        ASC_PUT_VAR_DONE_QTAIL(iot, ioh, sc->max_total_qng);
                    692:        AscWriteLramByte(iot, ioh, ASCV_BUSY_QHEAD_B, sc->max_total_qng + 1);
                    693:        AscWriteLramByte(iot, ioh, ASCV_DISC1_QHEAD_B, sc->max_total_qng + 2);
                    694:        AscWriteLramByte(iot, ioh, ASCV_TOTAL_READY_Q_B, sc->max_total_qng);
                    695:        AscWriteLramWord(iot, ioh, ASCV_ASCDVC_ERR_CODE_W, 0);
                    696:        AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
                    697:        AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, 0);
                    698:        AscWriteLramByte(iot, ioh, ASCV_SCSIBUSY_B, 0);
                    699:        AscWriteLramByte(iot, ioh, ASCV_WTM_FLAG_B, 0);
                    700:        ASC_PUT_QDONE_IN_PROGRESS(iot, ioh, 0);
                    701:        lram_addr = ASC_QADR_BEG;
                    702:        for (i = 0; i < 32; i++, lram_addr += 2)
                    703:                AscWriteLramWord(iot, ioh, lram_addr, 0);
                    704: }
                    705:
                    706:
                    707: static int
                    708: AscResetChipAndScsiBus(bus_space_tag_t iot,
                    709:                       bus_space_handle_t ioh)
                    710: {
                    711:        while (ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_SCSI_RESET_ACTIVE);
                    712:
                    713:        AscStopChip(iot, ioh);
                    714:        ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_CHIP_RESET | ASC_CC_SCSI_RESET | ASC_CC_HALT);
                    715:
                    716:        DvcDelayNanoSecond(60000);
                    717:
                    718:        AscSetChipIH(iot, ioh, ASC_INS_RFLAG_WTM);
                    719:        AscSetChipIH(iot, ioh, ASC_INS_HALT);
                    720:        ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_CHIP_RESET | ASC_CC_HALT);
                    721:        ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_HALT);
                    722:
                    723:        DvcSleepMilliSecond(200);
                    724:
                    725:        ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_CLR_SCSI_RESET_INT);
                    726:        AscStartChip(iot, ioh);
                    727:
                    728:        DvcSleepMilliSecond(200);
                    729:
                    730:        return (AscIsChipHalted(iot, ioh));
                    731: }
                    732:
                    733:
                    734: static u_int16_t
                    735: AscGetChipBusType(iot, ioh)
                    736:        bus_space_tag_t iot;
                    737:        bus_space_handle_t ioh;
                    738: {
                    739:        u_int16_t       chip_ver;
                    740:
                    741:        chip_ver = ASC_GET_CHIP_VER_NO(iot, ioh);
                    742:        if ((chip_ver >= ASC_CHIP_MIN_VER_VL) &&
                    743:            (chip_ver <= ASC_CHIP_MAX_VER_VL)) {
                    744:                /*
                    745:                 * if(((iop_base & 0x0C30) == 0x0C30) || ((iop_base & 0x0C50)
                    746:                 * == 0x0C50)) return (ASC_IS_EISA);
                    747:                 */
                    748:                return (ASC_IS_VL);
                    749:        }
                    750:        if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
                    751:            (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
                    752:                if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP)
                    753:                        return (ASC_IS_ISAPNP);
                    754:
                    755:                return (ASC_IS_ISA);
                    756:        } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
                    757:                   (chip_ver <= ASC_CHIP_MAX_VER_PCI))
                    758:                return (ASC_IS_PCI);
                    759:
                    760:        return (0);
                    761: }
                    762:
                    763:
                    764: /******************************************************************************/
                    765: /*                             Chip register routines                         */
                    766: /******************************************************************************/
                    767:
                    768:
                    769: static void
                    770: AscSetBank(iot, ioh, bank)
                    771:        bus_space_tag_t iot;
                    772:        bus_space_handle_t ioh;
                    773:        u_int8_t        bank;
                    774: {
                    775:        u_int8_t        val;
                    776:
                    777:        val = ASC_GET_CHIP_CONTROL(iot, ioh) &
                    778:                (~(ASC_CC_SINGLE_STEP | ASC_CC_TEST |
                    779:                   ASC_CC_DIAG | ASC_CC_SCSI_RESET |
                    780:                   ASC_CC_CHIP_RESET));
                    781:
                    782:        switch (bank) {
                    783:        case 1:
                    784:                val |= ASC_CC_BANK_ONE;
                    785:                break;
                    786:
                    787:        case 2:
                    788:                val |= ASC_CC_DIAG | ASC_CC_BANK_ONE;
                    789:                break;
                    790:
                    791:        default:
                    792:                val &= ~ASC_CC_BANK_ONE;
                    793:        }
                    794:
                    795:        ASC_SET_CHIP_CONTROL(iot, ioh, val);
                    796:        return;
                    797: }
                    798:
                    799:
                    800: /******************************************************************************/
                    801: /*                                 Chip routines                              */
                    802: /******************************************************************************/
                    803:
                    804:
                    805: static int
                    806: AscStartChip(iot, ioh)
                    807:        bus_space_tag_t iot;
                    808:        bus_space_handle_t ioh;
                    809: {
                    810:        ASC_SET_CHIP_CONTROL(iot, ioh, 0);
                    811:        if ((ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_HALTED) != 0)
                    812:                return (0);
                    813:
                    814:        return (1);
                    815: }
                    816:
                    817:
                    818: static int
                    819: AscStopChip(iot, ioh)
                    820:        bus_space_tag_t iot;
                    821:        bus_space_handle_t ioh;
                    822: {
                    823:        u_int8_t        cc_val;
                    824:
                    825:        cc_val = ASC_GET_CHIP_CONTROL(iot, ioh) &
                    826:                (~(ASC_CC_SINGLE_STEP | ASC_CC_TEST | ASC_CC_DIAG));
                    827:        ASC_SET_CHIP_CONTROL(iot, ioh, cc_val | ASC_CC_HALT);
                    828:        AscSetChipIH(iot, ioh, ASC_INS_HALT);
                    829:        AscSetChipIH(iot, ioh, ASC_INS_RFLAG_WTM);
                    830:        if ((ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_HALTED) == 0)
                    831:                return (0);
                    832:
                    833:        return (1);
                    834: }
                    835:
                    836:
                    837: static u_int8_t
                    838: AscGetChipVersion(iot, ioh, bus_type)
                    839:        bus_space_tag_t iot;
                    840:        bus_space_handle_t ioh;
                    841:        u_int16_t       bus_type;
                    842: {
                    843:        if (bus_type & ASC_IS_EISA) {
                    844:                /*
                    845:                 * u_int16_t    eisa_iop; u_int8_t      revision;
                    846:                 *
                    847:                 * eisa_iop = ASC_GET_EISA_SLOT(iop_base) |
                    848:                 * ASC_EISA_REV_IOP_MASK; revision = inp(eisa_iop);
                    849:                 * return((ASC_CHIP_MIN_VER_EISA - 1) + revision);
                    850:                 */
                    851:        }
                    852:        return (ASC_GET_CHIP_VER_NO(iot, ioh));
                    853: }
                    854:
                    855:
                    856: static u_int8_t
                    857: AscSetChipScsiID(iot, ioh, new_id)
                    858:        bus_space_tag_t iot;
                    859:        bus_space_handle_t ioh;
                    860:        u_int8_t        new_id;
                    861: {
                    862:        u_int16_t       cfg_lsw;
                    863:
                    864:        if (ASC_GET_CHIP_SCSI_ID(iot, ioh) == new_id)
                    865:                return (new_id);
                    866:
                    867:        cfg_lsw = ASC_GET_CHIP_SCSI_ID(iot, ioh);
                    868:        cfg_lsw &= 0xF8FF;
                    869:        cfg_lsw |= (new_id & ASC_MAX_TID) << 8;
                    870:        ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg_lsw);
                    871:        return (ASC_GET_CHIP_SCSI_ID(iot, ioh));
                    872: }
                    873:
                    874:
                    875: static u_int8_t
                    876: AscGetChipScsiCtrl(iot, ioh)
                    877:        bus_space_tag_t iot;
                    878:        bus_space_handle_t ioh;
                    879: {
                    880:        u_int8_t        scsi_ctrl;
                    881:
                    882:        AscSetBank(iot, ioh, 1);
                    883:        scsi_ctrl = bus_space_read_1(iot, ioh, ASC_IOP_REG_SC);
                    884:        AscSetBank(iot, ioh, 0);
                    885:        return (scsi_ctrl);
                    886: }
                    887:
                    888:
                    889: static int
                    890: AscSetRunChipSynRegAtID(iot, ioh, tid_no, sdtr_data)
                    891:        bus_space_tag_t iot;
                    892:        bus_space_handle_t ioh;
                    893:        u_int8_t        tid_no;
                    894:        u_int8_t        sdtr_data;
                    895: {
                    896:        int             retval = FALSE;
                    897:
                    898:        if (AscHostReqRiscHalt(iot, ioh)) {
                    899:                retval = AscSetChipSynRegAtID(iot, ioh, tid_no, sdtr_data);
                    900:                AscStartChip(iot, ioh);
                    901:        }
                    902:        return (retval);
                    903: }
                    904:
                    905:
                    906: static int
                    907: AscSetChipSynRegAtID(iot, ioh, id, sdtr_data)
                    908:        bus_space_tag_t iot;
                    909:        bus_space_handle_t ioh;
                    910:        u_int8_t        id;
                    911:        u_int8_t        sdtr_data;
                    912: {
                    913:        ASC_SCSI_BIT_ID_TYPE org_id;
                    914:        int             i;
                    915:        int             sta = TRUE;
                    916:
                    917:        AscSetBank(iot, ioh, 1);
                    918:        org_id = ASC_READ_CHIP_DVC_ID(iot, ioh);
                    919:        for (i = 0; i <= ASC_MAX_TID; i++)
                    920:                if (org_id == (0x01 << i))
                    921:                        break;
                    922:
                    923:        org_id = i;
                    924:        ASC_WRITE_CHIP_DVC_ID(iot, ioh, id);
                    925:        if (ASC_READ_CHIP_DVC_ID(iot, ioh) == (0x01 << id)) {
                    926:                AscSetBank(iot, ioh, 0);
                    927:                ASC_SET_CHIP_SYN(iot, ioh, sdtr_data);
                    928:                if (ASC_GET_CHIP_SYN(iot, ioh) != sdtr_data)
                    929:                        sta = FALSE;
                    930:        } else
                    931:                sta = FALSE;
                    932:
                    933:        AscSetBank(iot, ioh, 1);
                    934:        ASC_WRITE_CHIP_DVC_ID(iot, ioh, org_id);
                    935:        AscSetBank(iot, ioh, 0);
                    936:        return (sta);
                    937: }
                    938:
                    939:
                    940: static int
                    941: AscHostReqRiscHalt(iot, ioh)
                    942:        bus_space_tag_t iot;
                    943:        bus_space_handle_t ioh;
                    944: {
                    945:        int             count = 0;
                    946:        int             retval = 0;
                    947:        u_int8_t        saved_stop_code;
                    948:
                    949:
                    950:        if (AscIsChipHalted(iot, ioh))
                    951:                return (1);
                    952:        saved_stop_code = AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B);
                    953:        AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B,
                    954:                      ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
                    955:
                    956:        do {
                    957:                if (AscIsChipHalted(iot, ioh)) {
                    958:                        retval = 1;
                    959:                        break;
                    960:                }
                    961:                DvcSleepMilliSecond(100);
                    962:        } while (count++ < 20);
                    963:
                    964:        AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, saved_stop_code);
                    965:
                    966:        return (retval);
                    967: }
                    968:
                    969:
                    970: static int
                    971: AscIsChipHalted(iot, ioh)
                    972:        bus_space_tag_t iot;
                    973:        bus_space_handle_t ioh;
                    974: {
                    975:        if ((ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_HALTED) != 0)
                    976:                if ((ASC_GET_CHIP_CONTROL(iot, ioh) & ASC_CC_HALT) != 0)
                    977:                        return (1);
                    978:
                    979:        return (0);
                    980: }
                    981:
                    982:
                    983: static void
                    984: AscSetChipIH(iot, ioh, ins_code)
                    985:        bus_space_tag_t iot;
                    986:        bus_space_handle_t ioh;
                    987:        u_int16_t       ins_code;
                    988: {
                    989:        AscSetBank(iot, ioh, 1);
                    990:        ASC_WRITE_CHIP_IH(iot, ioh, ins_code);
                    991:        AscSetBank(iot, ioh, 0);
                    992:
                    993:        return;
                    994: }
                    995:
                    996:
                    997: /******************************************************************************/
                    998: /*                                 Lram routines                              */
                    999: /******************************************************************************/
                   1000:
                   1001:
                   1002: static u_int8_t
                   1003: AscReadLramByte(iot, ioh, addr)
                   1004:        bus_space_tag_t iot;
                   1005:        bus_space_handle_t ioh;
                   1006:        u_int16_t       addr;
                   1007: {
                   1008:        u_int8_t        byte_data;
                   1009:        u_int16_t       word_data;
                   1010:
                   1011:
                   1012:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr & 0xFFFE);
                   1013:        word_data = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
                   1014:
                   1015:        if (addr & 1) {
                   1016:                /* odd address */
                   1017:                byte_data = (u_int8_t) ((word_data >> 8) & 0xFF);
                   1018:        } else {
                   1019:                /* even address */
                   1020:                byte_data = (u_int8_t) (word_data & 0xFF);
                   1021:        }
                   1022:
                   1023:        return (byte_data);
                   1024: }
                   1025:
                   1026:
                   1027: static void
                   1028: AscWriteLramByte(iot, ioh, addr, data)
                   1029:        bus_space_tag_t iot;
                   1030:        bus_space_handle_t ioh;
                   1031:        u_int16_t       addr;
                   1032:        u_int8_t        data;
                   1033: {
                   1034:        u_int16_t       word_data;
                   1035:
                   1036:
                   1037:        word_data = AscReadLramWord(iot, ioh, addr & 0xFFFE);
                   1038:
                   1039:        if (addr & 1) {
                   1040:                /* odd address */
                   1041:                word_data &= 0x00FF;
                   1042:                word_data |= (((u_int16_t) data) << 8) & 0xFF00;
                   1043:        } else {
                   1044:                /* even address */
                   1045:                word_data &= 0xFF00;
                   1046:                word_data |= ((u_int16_t) data) & 0x00FF;
                   1047:        }
                   1048:
                   1049:        AscWriteLramWord(iot, ioh, addr, word_data);
                   1050: }
                   1051:
                   1052:
                   1053: static u_int16_t
                   1054: AscReadLramWord(iot, ioh, addr)
                   1055:        bus_space_tag_t iot;
                   1056:        bus_space_handle_t ioh;
                   1057:        u_int16_t       addr;
                   1058: {
                   1059:
                   1060:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
                   1061:        return (ASC_GET_CHIP_LRAM_DATA(iot, ioh));
                   1062: }
                   1063:
                   1064:
                   1065: static void
                   1066: AscWriteLramWord(iot, ioh, addr, data)
                   1067:        bus_space_tag_t iot;
                   1068:        bus_space_handle_t ioh;
                   1069:        u_int16_t       addr;
                   1070:        u_int16_t       data;
                   1071: {
                   1072:
                   1073:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
                   1074:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, data);
                   1075: }
                   1076:
                   1077:
                   1078: static u_int32_t
                   1079: AscReadLramDWord(iot, ioh, addr)
                   1080:        bus_space_tag_t iot;
                   1081:        bus_space_handle_t ioh;
                   1082:        u_int16_t       addr;
                   1083: {
                   1084:        u_int16_t       low_word, hi_word;
                   1085:
                   1086:
                   1087:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
                   1088:        low_word = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
                   1089:        hi_word = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
                   1090:
                   1091:        return ((((u_int32_t) hi_word) << 16) | (u_int32_t) low_word);
                   1092: }
                   1093:
                   1094:
                   1095: static void
                   1096: AscWriteLramDWord(iot, ioh, addr, data)
                   1097:        bus_space_tag_t iot;
                   1098:        bus_space_handle_t ioh;
                   1099:        u_int16_t       addr;
                   1100:        u_int32_t       data;
                   1101: {
                   1102:
                   1103:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
                   1104:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, (u_int16_t) (data & 0x0000FFFF));
                   1105:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, (u_int16_t) (data >> 16));
                   1106: }
                   1107:
                   1108:
                   1109: static void
                   1110: AscMemWordSetLram(iot, ioh, s_addr, s_words, count)
                   1111:        bus_space_tag_t iot;
                   1112:        bus_space_handle_t ioh;
                   1113:        u_int16_t       s_addr;
                   1114:        u_int16_t       s_words;
                   1115:        int             count;
                   1116: {
                   1117:        int             i;
                   1118:
                   1119:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, s_addr);
                   1120:        for (i = 0; i < count; i++)
                   1121:                ASC_SET_CHIP_LRAM_DATA(iot, ioh, s_words);
                   1122: }
                   1123:
                   1124:
                   1125: static void
                   1126: AscMemWordCopyToLram(iot, ioh, s_addr, s_buffer, words)
                   1127:        bus_space_tag_t iot;
                   1128:        bus_space_handle_t ioh;
                   1129:        u_int16_t       s_addr;
                   1130:        u_int16_t      *s_buffer;
                   1131:        int             words;
                   1132: {
                   1133:        int             i;
                   1134:
                   1135:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, s_addr);
                   1136:        for (i = 0; i < words; i++, s_buffer++)
                   1137:                ASC_SET_CHIP_LRAM_DATA_NO_SWAP(iot, ioh, *s_buffer);
                   1138: }
                   1139:
                   1140:
                   1141: static void
                   1142: AscMemWordCopyFromLram(iot, ioh, s_addr, s_buffer, words)
                   1143:        bus_space_tag_t iot;
                   1144:        bus_space_handle_t ioh;
                   1145:        u_int16_t       s_addr;
                   1146:        u_int16_t      *s_buffer;
                   1147:        int             words;
                   1148: {
                   1149:        int             i;
                   1150:
                   1151:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, s_addr);
                   1152:        for (i = 0; i < words; i++, s_buffer++)
                   1153:                *s_buffer = ASC_GET_CHIP_LRAM_DATA_NO_SWAP(iot, ioh);
                   1154: }
                   1155:
                   1156:
                   1157: static void
                   1158: AscMemDWordCopyToLram(iot, ioh, s_addr, s_buffer, dwords)
                   1159:        bus_space_tag_t iot;
                   1160:        bus_space_handle_t ioh;
                   1161:        u_int16_t       s_addr;
                   1162:        u_int32_t      *s_buffer;
                   1163:        int             dwords;
                   1164: {
                   1165:        int             i;
                   1166:        u_int32_t      *pw;
                   1167:
                   1168:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, s_addr);
                   1169:
                   1170:        pw = s_buffer;
                   1171:        for (i = 0; i < dwords; i++, pw++) {
                   1172:                ASC_SET_CHIP_LRAM_DATA(iot, ioh, LO_WORD(*pw));
                   1173:                DELAY(1);
                   1174:                ASC_SET_CHIP_LRAM_DATA(iot, ioh, HI_WORD(*pw));
                   1175:        }
                   1176: }
                   1177:
                   1178:
                   1179: static u_int32_t
                   1180: AscMemSumLramWord(iot, ioh, s_addr, words)
                   1181:        bus_space_tag_t iot;
                   1182:        bus_space_handle_t ioh;
                   1183:        u_int16_t       s_addr;
                   1184:        int             words;
                   1185: {
                   1186:        u_int32_t       sum = 0L;
                   1187:        u_int16_t       i;
                   1188:
                   1189:
                   1190:        for (i = 0; i < words; i++, s_addr += 2)
                   1191:                sum += AscReadLramWord(iot, ioh, s_addr);
                   1192:
                   1193:        return (sum);
                   1194: }
                   1195:
                   1196:
                   1197: static int
                   1198: AscTestExternalLram(iot, ioh)
                   1199:        bus_space_tag_t iot;
                   1200:        bus_space_handle_t ioh;
                   1201: {
                   1202:        u_int16_t       q_addr;
                   1203:        u_int16_t       saved_word;
                   1204:        int             retval;
                   1205:
                   1206:
                   1207:        retval = 0;
                   1208:        q_addr = ASC_QNO_TO_QADDR(241);
                   1209:        saved_word = AscReadLramWord(iot, ioh, q_addr);
                   1210:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, q_addr);
                   1211:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, 0x55AA);
                   1212:        DvcSleepMilliSecond(10);
                   1213:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, q_addr);
                   1214:
                   1215:        if (ASC_GET_CHIP_LRAM_DATA(iot, ioh) == 0x55AA) {
                   1216:                retval = 1;
                   1217:                AscWriteLramWord(iot, ioh, q_addr, saved_word);
                   1218:        }
                   1219:        return (retval);
                   1220: }
                   1221:
                   1222:
                   1223: /******************************************************************************/
                   1224: /*                               MicroCode routines                           */
                   1225: /******************************************************************************/
                   1226:
                   1227:
                   1228: static u_int16_t
                   1229: AscInitMicroCodeVar(sc)
                   1230:        ASC_SOFTC      *sc;
                   1231: {
                   1232:        bus_space_tag_t iot = sc->sc_iot;
                   1233:        bus_space_handle_t ioh = sc->sc_ioh;
                   1234:        u_int32_t       phy_addr;
                   1235:        int             i;
                   1236:
                   1237:
                   1238:        for (i = 0; i <= ASC_MAX_TID; i++)
                   1239:                ASC_PUT_MCODE_INIT_SDTR_AT_ID(iot, ioh, i,
                   1240:                                              sc->sdtr_period_offset[i]);
                   1241:
                   1242:        AscInitQLinkVar(sc);
                   1243:        AscWriteLramByte(iot, ioh, ASCV_DISC_ENABLE_B, sc->disc_enable);
                   1244:        AscWriteLramByte(iot, ioh, ASCV_HOSTSCSI_ID_B,
                   1245:                         ASC_TID_TO_TARGET_ID(sc->chip_scsi_id));
                   1246:
                   1247:        if ((phy_addr = AscGetOnePhyAddr(sc, sc->overrun_buf,
                   1248:                                         ASC_OVERRUN_BSIZE)) == 0L) {
                   1249:                return (0);
                   1250:        } else {
                   1251:                phy_addr = (phy_addr & 0xFFFFFFF8ul) + 8;
                   1252:                AscWriteLramDWord(iot, ioh, ASCV_OVERRUN_PADDR_D, phy_addr);
                   1253:                AscWriteLramDWord(iot, ioh, ASCV_OVERRUN_BSIZE_D,
                   1254:                                  ASC_OVERRUN_BSIZE - 8);
                   1255:        }
                   1256:
                   1257:        sc->mcode_date = AscReadLramWord(iot, ioh, ASCV_MC_DATE_W);
                   1258:        sc->mcode_version = AscReadLramWord(iot, ioh, ASCV_MC_VER_W);
                   1259:        ASC_SET_PC_ADDR(iot, ioh, ASC_MCODE_START_ADDR);
                   1260:
                   1261:        if (ASC_GET_PC_ADDR(iot, ioh) != ASC_MCODE_START_ADDR) {
                   1262:                return (0);
                   1263:        }
                   1264:        if (AscStartChip(iot, ioh) != 1) {
                   1265:                return (0);
                   1266:        }
                   1267:        return (1);
                   1268: }
                   1269:
                   1270:
                   1271: static u_int32_t
                   1272: AscLoadMicroCode(iot, ioh, s_addr, mcode_buf, mcode_size)
                   1273:        bus_space_tag_t iot;
                   1274:        bus_space_handle_t ioh;
                   1275:        u_int16_t       s_addr;
                   1276:        u_int16_t      *mcode_buf;
                   1277:        u_int16_t       mcode_size;
                   1278: {
                   1279:        u_int32_t       chksum;
                   1280:        u_int16_t       mcode_word_size;
                   1281:        u_int16_t       mcode_chksum;
                   1282:
                   1283:        mcode_word_size = mcode_size >> 1;
                   1284:        /* clear board memory */
                   1285:        AscMemWordSetLram(iot, ioh, s_addr, 0, mcode_word_size);
                   1286:        /* copy uCode to board memory */
                   1287:        AscMemWordCopyToLram(iot, ioh, s_addr, mcode_buf, mcode_word_size);
                   1288:        chksum = AscMemSumLramWord(iot, ioh, s_addr, mcode_word_size);
                   1289:        mcode_chksum = AscMemSumLramWord(iot, ioh, ASC_CODE_SEC_BEG,
                   1290:                           ((mcode_size - s_addr - ASC_CODE_SEC_BEG) >> 1));
                   1291:        AscWriteLramWord(iot, ioh, ASCV_MCODE_CHKSUM_W, mcode_chksum);
                   1292:        AscWriteLramWord(iot, ioh, ASCV_MCODE_SIZE_W, mcode_size);
                   1293:
                   1294:        return (chksum);
                   1295: }
                   1296:
                   1297:
                   1298: static u_int32_t
                   1299: AscGetOnePhyAddr(sc, buf_addr, buf_size)
                   1300:        ASC_SOFTC      *sc;
                   1301:        u_int8_t       *buf_addr;
                   1302:        u_int32_t       buf_size;
                   1303: {
                   1304:        ASC_MIN_SG_HEAD sg_head;
                   1305:
                   1306:        sg_head.entry_cnt = ASC_MIN_SG_LIST;
                   1307:        if (AscGetSGList(sc, buf_addr, buf_size, (ASC_SG_HEAD *) & sg_head) !=
                   1308:            buf_size) {
                   1309:                return (0L);
                   1310:        }
                   1311:        if (sg_head.entry_cnt > 1) {
                   1312:                return (0L);
                   1313:        }
                   1314:        return (sg_head.sg_list[0].addr);
                   1315: }
                   1316:
                   1317:
                   1318: static u_int32_t
                   1319: AscGetSGList(sc, buf_addr, buf_len, asc_sg_head_ptr)
                   1320:        ASC_SOFTC      *sc;
                   1321:        u_int8_t       *buf_addr;
                   1322:        u_int32_t       buf_len;
                   1323:        ASC_SG_HEAD    *asc_sg_head_ptr;
                   1324: {
                   1325:        u_int32_t       buf_size;
                   1326:
                   1327:        buf_size = buf_len;
                   1328:        asc_sg_head_ptr->entry_cnt = 1;
                   1329:        asc_sg_head_ptr->sg_list[0].addr = (u_int32_t) buf_addr;
                   1330:        asc_sg_head_ptr->sg_list[0].bytes = buf_size;
                   1331:
                   1332:        return (buf_size);
                   1333: }
                   1334:
                   1335:
                   1336: /******************************************************************************/
                   1337: /*                                 EEProm routines                            */
                   1338: /******************************************************************************/
                   1339:
                   1340:
                   1341: static int
                   1342: AscWriteEEPCmdReg(iot, ioh, cmd_reg)
                   1343:        bus_space_tag_t iot;
                   1344:        bus_space_handle_t ioh;
                   1345:        u_int8_t        cmd_reg;
                   1346: {
                   1347:        u_int8_t        read_back;
                   1348:        int             retry;
                   1349:
                   1350:        retry = 0;
                   1351:
                   1352:        while (TRUE) {
                   1353:                ASC_SET_CHIP_EEP_CMD(iot, ioh, cmd_reg);
                   1354:                DvcSleepMilliSecond(1);
                   1355:                read_back = ASC_GET_CHIP_EEP_CMD(iot, ioh);
                   1356:                if (read_back == cmd_reg)
                   1357:                        return (1);
                   1358:
                   1359:                if (retry++ > ASC_EEP_MAX_RETRY)
                   1360:                        return (0);
                   1361:        }
                   1362: }
                   1363:
                   1364:
                   1365: static int
                   1366: AscWriteEEPDataReg(iot, ioh, data_reg)
                   1367:        bus_space_tag_t iot;
                   1368:        bus_space_handle_t ioh;
                   1369:        u_int16_t       data_reg;
                   1370: {
                   1371:        u_int16_t       read_back;
                   1372:        int             retry;
                   1373:
                   1374:        retry = 0;
                   1375:        while (TRUE) {
                   1376:                ASC_SET_CHIP_EEP_DATA(iot, ioh, data_reg);
                   1377:                DvcSleepMilliSecond(1);
                   1378:                read_back = ASC_GET_CHIP_EEP_DATA(iot, ioh);
                   1379:                if (read_back == data_reg)
                   1380:                        return (1);
                   1381:
                   1382:                if (retry++ > ASC_EEP_MAX_RETRY)
                   1383:                        return (0);
                   1384:        }
                   1385: }
                   1386:
                   1387:
                   1388: static void
                   1389: AscWaitEEPRead(void)
                   1390: {
                   1391:
                   1392:        DvcSleepMilliSecond(1);
                   1393: }
                   1394:
                   1395:
                   1396: static void
                   1397: AscWaitEEPWrite(void)
                   1398: {
                   1399:
                   1400:        DvcSleepMilliSecond(1);
                   1401: }
                   1402:
                   1403:
                   1404: static u_int16_t
                   1405: AscReadEEPWord(iot, ioh, addr)
                   1406:        bus_space_tag_t iot;
                   1407:        bus_space_handle_t ioh;
                   1408:        u_int8_t        addr;
                   1409: {
                   1410:        u_int16_t       read_wval;
                   1411:        u_int8_t        cmd_reg;
                   1412:
                   1413:        AscWriteEEPCmdReg(iot, ioh, ASC_EEP_CMD_WRITE_DISABLE);
                   1414:        AscWaitEEPRead();
                   1415:        cmd_reg = addr | ASC_EEP_CMD_READ;
                   1416:        AscWriteEEPCmdReg(iot, ioh, cmd_reg);
                   1417:        AscWaitEEPRead();
                   1418:        read_wval = ASC_GET_CHIP_EEP_DATA(iot, ioh);
                   1419:        AscWaitEEPRead();
                   1420:
                   1421:        return (read_wval);
                   1422: }
                   1423:
                   1424:
                   1425: static u_int16_t
                   1426: AscWriteEEPWord(iot, ioh, addr, word_val)
                   1427:        bus_space_tag_t iot;
                   1428:        bus_space_handle_t ioh;
                   1429:        u_int8_t        addr;
                   1430:        u_int16_t       word_val;
                   1431: {
                   1432:        u_int16_t       read_wval;
                   1433:
                   1434:        read_wval = AscReadEEPWord(iot, ioh, addr);
                   1435:        if (read_wval != word_val) {
                   1436:                AscWriteEEPCmdReg(iot, ioh, ASC_EEP_CMD_WRITE_ABLE);
                   1437:                AscWaitEEPRead();
                   1438:                AscWriteEEPDataReg(iot, ioh, word_val);
                   1439:                AscWaitEEPRead();
                   1440:                AscWriteEEPCmdReg(iot, ioh, ASC_EEP_CMD_WRITE | addr);
                   1441:                AscWaitEEPWrite();
                   1442:                AscWriteEEPCmdReg(iot, ioh, ASC_EEP_CMD_WRITE_DISABLE);
                   1443:                AscWaitEEPRead();
                   1444:                return (AscReadEEPWord(iot, ioh, addr));
                   1445:        }
                   1446:        return (read_wval);
                   1447: }
                   1448:
                   1449:
                   1450: static u_int16_t
                   1451: AscGetEEPConfig(iot, ioh, cfg_buf, bus_type)
                   1452:        bus_space_tag_t iot;
                   1453:        bus_space_handle_t ioh;
                   1454:        ASCEEP_CONFIG  *cfg_buf;
                   1455:        u_int16_t       bus_type;
                   1456: {
                   1457:        u_int16_t       wval;
                   1458:        u_int16_t       sum;
                   1459:        u_int16_t      *wbuf;
                   1460:        int             cfg_beg;
                   1461:        int             cfg_end;
                   1462:        int             s_addr;
                   1463:        int             isa_pnp_wsize;
                   1464:
                   1465:
                   1466:        wbuf = (u_int16_t *) cfg_buf;
                   1467:        sum = 0;
                   1468:        isa_pnp_wsize = 0;
                   1469:
                   1470:        for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
                   1471:                wval = AscReadEEPWord(iot, ioh, s_addr);
                   1472:                sum += wval;
                   1473:                *wbuf = wval;
                   1474:        }
                   1475:
                   1476:        if (bus_type & ASC_IS_VL) {
                   1477:                cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
                   1478:                cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
                   1479:        } else {
                   1480:                cfg_beg = ASC_EEP_DVC_CFG_BEG;
                   1481:                cfg_end = ASC_EEP_MAX_DVC_ADDR;
                   1482:        }
                   1483:
                   1484:        for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
                   1485:                wval = AscReadEEPWord(iot, ioh, s_addr);
                   1486:                sum += wval;
                   1487:                *wbuf = wval;
                   1488:        }
                   1489:
                   1490:        *wbuf = AscReadEEPWord(iot, ioh, s_addr);
                   1491:
                   1492:        return (sum);
                   1493: }
                   1494:
                   1495:
                   1496: static int
                   1497: AscSetEEPConfig(iot, ioh, cfg_buf, bus_type)
                   1498:        bus_space_tag_t iot;
                   1499:        bus_space_handle_t ioh;
                   1500:        ASCEEP_CONFIG  *cfg_buf;
                   1501:        u_int16_t       bus_type;
                   1502: {
                   1503:        int             retry;
                   1504:        int             n_error;
                   1505:
                   1506:        retry = 0;
                   1507:        while (TRUE) {
                   1508:                if ((n_error = AscSetEEPConfigOnce(iot, ioh, cfg_buf, bus_type)) == 0)
                   1509:                        break;
                   1510:
                   1511:                if (++retry > ASC_EEP_MAX_RETRY)
                   1512:                        break;
                   1513:        }
                   1514:
                   1515:        return (n_error);
                   1516: }
                   1517:
                   1518:
                   1519: static int
                   1520: AscSetEEPConfigOnce(iot, ioh, cfg_buf, bus_type)
                   1521:        bus_space_tag_t iot;
                   1522:        bus_space_handle_t ioh;
                   1523:        ASCEEP_CONFIG  *cfg_buf;
                   1524:        u_int16_t       bus_type;
                   1525: {
                   1526:        int             n_error;
                   1527:        u_int16_t      *wbuf;
                   1528:        u_int16_t       sum;
                   1529:        int             s_addr;
                   1530:        int             cfg_beg;
                   1531:        int             cfg_end;
                   1532:
                   1533:        wbuf = (u_int16_t *) cfg_buf;
                   1534:        n_error = 0;
                   1535:        sum = 0;
                   1536:
                   1537:        for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
                   1538:                sum += *wbuf;
                   1539:                if (*wbuf != AscWriteEEPWord(iot, ioh, s_addr, *wbuf))
                   1540:                        n_error++;
                   1541:        }
                   1542:
                   1543:        if (bus_type & ASC_IS_VL) {
                   1544:                cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
                   1545:                cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
                   1546:        } else {
                   1547:                cfg_beg = ASC_EEP_DVC_CFG_BEG;
                   1548:                cfg_end = ASC_EEP_MAX_DVC_ADDR;
                   1549:        }
                   1550:
                   1551:        for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
                   1552:                sum += *wbuf;
                   1553:                if (*wbuf != AscWriteEEPWord(iot, ioh, s_addr, *wbuf))
                   1554:                        n_error++;
                   1555:        }
                   1556:
                   1557:        *wbuf = sum;
                   1558:        if (sum != AscWriteEEPWord(iot, ioh, s_addr, sum))
                   1559:                n_error++;
                   1560:
                   1561:        wbuf = (u_int16_t *) cfg_buf;
                   1562:        for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
                   1563:                if (*wbuf != AscReadEEPWord(iot, ioh, s_addr))
                   1564:                        n_error++;
                   1565:        }
                   1566:
                   1567:        for (s_addr = cfg_beg; s_addr <= cfg_end; s_addr++, wbuf++) {
                   1568:                if (*wbuf != AscReadEEPWord(iot, ioh, s_addr))
                   1569:                        n_error++;
                   1570:        }
                   1571:
                   1572:        return (n_error);
                   1573: }
                   1574:
                   1575:
                   1576: #ifdef ASC_DEBUG
                   1577: static void
                   1578: AscPrintEEPConfig(eep_config, chksum)
                   1579:        ASCEEP_CONFIG   *eep_config;
                   1580:        u_int16_t       chksum;
                   1581: {
                   1582:        printf("---- ASC EEprom settings ----\n");
                   1583:        printf("cfg_lsw = 0x%x\n", eep_config->cfg_lsw);
                   1584:        printf("cfg_msw = 0x%x\n", eep_config->cfg_msw);
                   1585:        printf("init_sdtr = 0x%x\n", eep_config->init_sdtr);
                   1586:        printf("disc_enable = 0x%x\n", eep_config->disc_enable);
                   1587:        printf("use_cmd_qng = %d\n", eep_config->use_cmd_qng);
                   1588:        printf("start_motor = 0x%x\n", eep_config->start_motor);
                   1589:        printf("max_total_qng = 0x%x\n", eep_config->max_total_qng);
                   1590:        printf("max_tag_qng = 0x%x\n", eep_config->max_tag_qng);
                   1591:        printf("bios_scan = 0x%x\n", eep_config->bios_scan);
                   1592:        printf("power_up_wait = 0x%x\n", eep_config->power_up_wait);
                   1593:        printf("no_scam = %d\n", eep_config->no_scam);
                   1594:        printf("chip_scsi_id = %d\n", eep_config->chip_scsi_id);
                   1595:        printf("isa_dma_speed = %d\n", eep_config->isa_dma_speed);
                   1596:        printf("cntl = 0x%x\n", eep_config->cntl);
                   1597: #if BYTE_ORDER == BIG_ENDIAN
                   1598:        printf("adapter_info[0] = 0x%x\n", eep_config->adapter_info[1]);
                   1599:        printf("adapter_info[1] = 0x%x\n", eep_config->adapter_info[0]);
                   1600:        printf("adapter_info[2] = 0x%x\n", eep_config->adapter_info[3]);
                   1601:        printf("adapter_info[3] = 0x%x\n", eep_config->adapter_info[2]);
                   1602:        printf("adapter_info[4] = 0x%x\n", eep_config->adapter_info[5]);
                   1603:        printf("adapter_info[5] = 0x%x\n", eep_config->adapter_info[4]);
                   1604: #else
                   1605:        printf("adapter_info[0] = 0x%x\n", eep_config->adapter_info[0]);
                   1606:        printf("adapter_info[1] = 0x%x\n", eep_config->adapter_info[1]);
                   1607:        printf("adapter_info[2] = 0x%x\n", eep_config->adapter_info[2]);
                   1608:        printf("adapter_info[3] = 0x%x\n", eep_config->adapter_info[3]);
                   1609:        printf("adapter_info[4] = 0x%x\n", eep_config->adapter_info[4]);
                   1610:        printf("adapter_info[5] = 0x%x\n", eep_config->adapter_info[5]);
                   1611: #endif
                   1612:        printf("checksum = 0x%x\n", eep_config->chksum);
                   1613:        printf("calculated checksum = 0x%x\n", chksum);
                   1614:        printf("-----------------------------\n");
                   1615: }
                   1616: #endif
                   1617:
                   1618:
                   1619: /******************************************************************************/
                   1620: /*                               Interrupt routines                           */
                   1621: /******************************************************************************/
                   1622:
                   1623:
                   1624: int
                   1625: AscISR(sc)
                   1626:        ASC_SOFTC      *sc;
                   1627: {
                   1628:        bus_space_tag_t iot = sc->sc_iot;
                   1629:        bus_space_handle_t ioh = sc->sc_ioh;
                   1630:        u_int16_t       chipstat;
                   1631:        u_int16_t       saved_ram_addr;
                   1632:        u_int8_t        ctrl_reg;
                   1633:        u_int8_t        saved_ctrl_reg;
                   1634:        int             int_pending;
                   1635:        int             status;
                   1636:        u_int8_t        host_flag;
                   1637:
                   1638:
                   1639:        int_pending = FALSE;
                   1640:
                   1641:        ctrl_reg = ASC_GET_CHIP_CONTROL(iot, ioh);
                   1642:        saved_ctrl_reg = ctrl_reg & (~(ASC_CC_SCSI_RESET | ASC_CC_CHIP_RESET |
                   1643:                           ASC_CC_SINGLE_STEP | ASC_CC_DIAG | ASC_CC_TEST));
                   1644:        chipstat = ASC_GET_CHIP_STATUS(iot, ioh);
                   1645:        if (chipstat & ASC_CSW_SCSI_RESET_LATCH) {
                   1646:                if (!(sc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
                   1647:                        int_pending = TRUE;
                   1648:                        sc->sdtr_done = 0;
                   1649:                        saved_ctrl_reg &= (u_int8_t) (~ASC_CC_HALT);
                   1650:
                   1651:                        while (ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_SCSI_RESET_ACTIVE);
                   1652:
                   1653:                        ASC_SET_CHIP_CONTROL(iot, ioh, (ASC_CC_CHIP_RESET | ASC_CC_HALT));
                   1654:                        ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_HALT);
                   1655:                        ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_CLR_SCSI_RESET_INT);
                   1656:                        ASC_SET_CHIP_STATUS(iot, ioh, 0);
                   1657:                        chipstat = ASC_GET_CHIP_STATUS(iot, ioh);
                   1658:                }
                   1659:        }
                   1660:        saved_ram_addr = ASC_GET_CHIP_LRAM_ADDR(iot, ioh);
                   1661:        host_flag = AscReadLramByte(iot, ioh, ASCV_HOST_FLAG_B) &
                   1662:                (u_int8_t) (~ASC_HOST_FLAG_IN_ISR);
                   1663:        AscWriteLramByte(iot, ioh, ASCV_HOST_FLAG_B,
                   1664:                         (host_flag | ASC_HOST_FLAG_IN_ISR));
                   1665:
                   1666:        if ((chipstat & ASC_CSW_INT_PENDING) || (int_pending)) {
                   1667:                AscAckInterrupt(iot, ioh);
                   1668:                int_pending = TRUE;
                   1669:
                   1670:                if ((chipstat & ASC_CSW_HALTED) &&
                   1671:                    (ctrl_reg & ASC_CC_SINGLE_STEP)) {
                   1672:                        AscIsrChipHalted(sc);
                   1673:                        saved_ctrl_reg &= ~ASC_CC_HALT;
                   1674:                } else {
                   1675:                        if (sc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) {
                   1676:                                while (((status = AscIsrQDone(sc)) & 0x01) != 0);
                   1677:                        } else {
                   1678:                                do {
                   1679:                                        if ((status = AscIsrQDone(sc)) == 1)
                   1680:                                                break;
                   1681:                                } while (status == 0x11);
                   1682:                        }
                   1683:
                   1684:                        if (status & 0x80)
                   1685:                                int_pending = -1;
                   1686:                }
                   1687:        }
                   1688:        AscWriteLramByte(iot, ioh, ASCV_HOST_FLAG_B, host_flag);
                   1689:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, saved_ram_addr);
                   1690:        ASC_SET_CHIP_CONTROL(iot, ioh, saved_ctrl_reg);
                   1691:
                   1692:        return (1);
                   1693:        /* return(int_pending); */
                   1694: }
                   1695:
                   1696:
                   1697: static int
                   1698: AscIsrQDone(sc)
                   1699:        ASC_SOFTC      *sc;
                   1700: {
                   1701:        u_int8_t        next_qp;
                   1702:        u_int8_t        n_q_used;
                   1703:        u_int8_t        sg_list_qp;
                   1704:        u_int8_t        sg_queue_cnt;
                   1705:        u_int8_t        q_cnt;
                   1706:        u_int8_t        done_q_tail;
                   1707:        u_int8_t        tid_no;
                   1708:        ASC_SCSI_BIT_ID_TYPE scsi_busy;
                   1709:        ASC_SCSI_BIT_ID_TYPE target_id;
                   1710:        bus_space_tag_t iot = sc->sc_iot;
                   1711:        bus_space_handle_t ioh = sc->sc_ioh;
                   1712:        u_int16_t       q_addr;
                   1713:        u_int16_t       sg_q_addr;
                   1714:        u_int8_t        cur_target_qng;
                   1715:        ASC_QDONE_INFO  scsiq_buf;
                   1716:        ASC_QDONE_INFO *scsiq;
                   1717:        ASC_ISR_CALLBACK asc_isr_callback;
                   1718:
                   1719:
                   1720:        asc_isr_callback = (ASC_ISR_CALLBACK) sc->isr_callback;
                   1721:        n_q_used = 1;
                   1722:        scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
                   1723:        done_q_tail = ASC_GET_VAR_DONE_QTAIL(iot, ioh);
                   1724:        q_addr = ASC_QNO_TO_QADDR(done_q_tail);
                   1725:        next_qp = AscReadLramByte(iot, ioh, (q_addr + ASC_SCSIQ_B_FWD));
                   1726:
                   1727:        if (next_qp != ASC_QLINK_END) {
                   1728:                ASC_PUT_VAR_DONE_QTAIL(iot, ioh, next_qp);
                   1729:                q_addr = ASC_QNO_TO_QADDR(next_qp);
                   1730:                sg_queue_cnt = _AscCopyLramScsiDoneQ(iot, ioh, q_addr, scsiq,
                   1731:                                                     sc->max_dma_count);
                   1732:                AscWriteLramByte(iot, ioh, (q_addr + ASC_SCSIQ_B_STATUS),
                   1733:                      (scsiq->q_status & ~(ASC_QS_READY | ASC_QS_ABORTED)));
                   1734:                tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
                   1735:                target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
                   1736:                if ((scsiq->cntl & ASC_QC_SG_HEAD) != 0) {
                   1737:                        sg_q_addr = q_addr;
                   1738:                        sg_list_qp = next_qp;
                   1739:                        for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
                   1740:                                sg_list_qp = AscReadLramByte(iot, ioh,
                   1741:                                               sg_q_addr + ASC_SCSIQ_B_FWD);
                   1742:                                sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
                   1743:                                if (sg_list_qp == ASC_QLINK_END) {
                   1744:                                        AscSetLibErrorCode(sc, ASCQ_ERR_SG_Q_LINKS);
                   1745:                                        scsiq->d3.done_stat = ASC_QD_WITH_ERROR;
                   1746:                                        scsiq->d3.host_stat = ASC_QHSTA_D_QDONE_SG_LIST_CORRUPTED;
                   1747:                                        panic("AscIsrQDone: Corrupted SG list encountered");
                   1748:                                }
                   1749:                                AscWriteLramByte(iot, ioh,
                   1750:                                sg_q_addr + ASC_SCSIQ_B_STATUS, ASC_QS_FREE);
                   1751:                        }
                   1752:                        n_q_used = sg_queue_cnt + 1;
                   1753:                        ASC_PUT_VAR_DONE_QTAIL(iot, ioh, sg_list_qp);
                   1754:                }
                   1755:                if (sc->queue_full_or_busy & target_id) {
                   1756:                        cur_target_qng = AscReadLramByte(iot, ioh,
                   1757:                                        ASC_QADR_BEG + scsiq->d2.target_ix);
                   1758:
                   1759:                        if (cur_target_qng < sc->max_dvc_qng[tid_no]) {
                   1760:                                scsi_busy = AscReadLramByte(iot, ioh, ASCV_SCSIBUSY_B);
                   1761:                                scsi_busy &= ~target_id;
                   1762:                                AscWriteLramByte(iot, ioh, ASCV_SCSIBUSY_B, scsi_busy);
                   1763:                                sc->queue_full_or_busy &= ~target_id;
                   1764:                        }
                   1765:                }
                   1766:                if (sc->cur_total_qng >= n_q_used) {
                   1767:                        sc->cur_total_qng -= n_q_used;
                   1768:                        if (sc->cur_dvc_qng[tid_no] != 0) {
                   1769:                                sc->cur_dvc_qng[tid_no]--;
                   1770:                        }
                   1771:                } else {
                   1772:                        AscSetLibErrorCode(sc, ASCQ_ERR_CUR_QNG);
                   1773:                        scsiq->d3.done_stat = ASC_QD_WITH_ERROR;
                   1774:                        panic("AscIsrQDone: Attempting to free more queues than are active");
                   1775:                }
                   1776:
                   1777:                if ((scsiq->d2.ccb_ptr == 0UL) || ((scsiq->q_status & ASC_QS_ABORTED) != 0)) {
                   1778:                        return (0x11);
                   1779:                } else if (scsiq->q_status == ASC_QS_DONE) {
                   1780:                        scsiq->remain_bytes += scsiq->extra_bytes;
                   1781:
                   1782:                        if (scsiq->d3.done_stat == ASC_QD_WITH_ERROR) {
                   1783:                                if (scsiq->d3.host_stat == ASC_QHSTA_M_DATA_OVER_RUN) {
                   1784:                                        if ((scsiq->cntl & (ASC_QC_DATA_IN | ASC_QC_DATA_OUT)) == 0) {
                   1785:                                                scsiq->d3.done_stat = ASC_QD_NO_ERROR;
                   1786:                                                scsiq->d3.host_stat = ASC_QHSTA_NO_ERROR;
                   1787:                                        }
                   1788:                                } else if (scsiq->d3.host_stat == ASC_QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
                   1789:                                        AscStopChip(iot, ioh);
                   1790:                                        ASC_SET_CHIP_CONTROL(iot, ioh, (ASC_CC_SCSI_RESET | ASC_CC_HALT));
                   1791:                                        DvcDelayNanoSecond(60000);
                   1792:                                        ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_HALT);
                   1793:                                        ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_CLR_SCSI_RESET_INT);
                   1794:                                        ASC_SET_CHIP_STATUS(iot, ioh, 0);
                   1795:                                        ASC_SET_CHIP_CONTROL(iot, ioh, 0);
                   1796:                                }
                   1797:                        }
                   1798:                        (*asc_isr_callback) (sc, scsiq);
                   1799:
                   1800:                        return (1);
                   1801:                } else {
                   1802:                        AscSetLibErrorCode(sc, ASCQ_ERR_Q_STATUS);
                   1803:                        panic("AscIsrQDone: completed scsiq with unknown status");
                   1804:
                   1805:                        return (0x80);
                   1806:                }
                   1807:        }
                   1808:        return (0);
                   1809: }
                   1810:
                   1811:
                   1812: /*
                   1813:  * handle all the conditions that may halt the board
                   1814:  * waiting us to intervene
                   1815:  */
                   1816: static void
                   1817: AscIsrChipHalted(sc)
                   1818:        ASC_SOFTC      *sc;
                   1819: {
                   1820:        bus_space_tag_t iot = sc->sc_iot;
                   1821:        bus_space_handle_t ioh = sc->sc_ioh;
                   1822:        EXT_MSG         out_msg;
                   1823:        u_int16_t       int_halt_code;
                   1824:        u_int16_t       halt_q_addr;
                   1825:        u_int8_t        halt_qp;
                   1826:        u_int8_t        target_ix;
                   1827:        u_int8_t        tag_code;
                   1828:        u_int8_t        q_status;
                   1829:        u_int8_t        q_cntl;
                   1830:        u_int8_t        tid_no;
                   1831:        u_int8_t        cur_dvc_qng;
                   1832:        u_int8_t        asyn_sdtr;
                   1833:        u_int8_t        scsi_status;
                   1834:        u_int8_t        sdtr_data;
                   1835:        ASC_SCSI_BIT_ID_TYPE scsi_busy;
                   1836:        ASC_SCSI_BIT_ID_TYPE target_id;
                   1837:
                   1838:
                   1839:        int_halt_code = AscReadLramWord(iot, ioh, ASCV_HALTCODE_W);
                   1840:
                   1841:        halt_qp = AscReadLramByte(iot, ioh, ASCV_CURCDB_B);
                   1842:        halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
                   1843:        target_ix = AscReadLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_TARGET_IX);
                   1844:        q_cntl = AscReadLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_CNTL);
                   1845:        tid_no = ASC_TIX_TO_TID(target_ix);
                   1846:        target_id = ASC_TID_TO_TARGET_ID(tid_no);
                   1847:
                   1848:        if (sc->pci_fix_asyn_xfer & target_id) {
                   1849:                asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
                   1850:        } else {
                   1851:                asyn_sdtr = 0;
                   1852:        }
                   1853:
                   1854:        if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
                   1855:                if (sc->pci_fix_asyn_xfer & target_id) {
                   1856:                        AscSetChipSDTR(iot, ioh, 0, tid_no);
                   1857:                        sc->sdtr_data[tid_no] = 0;
                   1858:                }
                   1859:                AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
                   1860:        } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
                   1861:                if (sc->pci_fix_asyn_xfer & target_id) {
                   1862:                        AscSetChipSDTR(iot, ioh, asyn_sdtr, tid_no);
                   1863:                        sc->sdtr_data[tid_no] = asyn_sdtr;
                   1864:                }
                   1865:                AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
                   1866:        } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
                   1867:                AscHandleExtMsgIn(sc, halt_q_addr, q_cntl, target_id,
                   1868:                                  tid_no, asyn_sdtr);
                   1869:                AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
                   1870:        } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
                   1871:                q_cntl |= ASC_QC_REQ_SENSE;
                   1872:
                   1873:                if (sc->init_sdtr & target_id) {
                   1874:                        sc->sdtr_done &= ~target_id;
                   1875:
                   1876:                        sdtr_data = ASC_GET_MCODE_INIT_SDTR_AT_ID(iot, ioh, tid_no);
                   1877:                        q_cntl |= ASC_QC_MSG_OUT;
                   1878:                        AscMsgOutSDTR(sc, sc->sdtr_period_tbl[(sdtr_data >> 4) &
                   1879:                                                  (sc->max_sdtr_index - 1)],
                   1880:                                      (sdtr_data & ASC_SYN_MAX_OFFSET));
                   1881:                }
                   1882:                AscWriteLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_CNTL, q_cntl);
                   1883:
                   1884:                tag_code = AscReadLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_TAG_CODE);
                   1885:                tag_code &= 0xDC;
                   1886:
                   1887:                if ((sc->pci_fix_asyn_xfer & target_id) &&
                   1888:                    !(sc->pci_fix_asyn_xfer_always & target_id)) {
                   1889:                        tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT |
                   1890:                                     ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
                   1891:                }
                   1892:                AscWriteLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_TAG_CODE, tag_code);
                   1893:
                   1894:                q_status = AscReadLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_STATUS);
                   1895:                q_status |= ASC_QS_READY | ASC_QS_BUSY;
                   1896:
                   1897:                AscWriteLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_STATUS, q_status);
                   1898:
                   1899:                scsi_busy = AscReadLramByte(iot, ioh, ASCV_SCSIBUSY_B);
                   1900:                scsi_busy &= ~target_id;
                   1901:                AscWriteLramByte(iot, ioh, ASCV_SCSIBUSY_B, scsi_busy);
                   1902:
                   1903:                AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
                   1904:        } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
                   1905:                AscMemWordCopyFromLram(iot, ioh, ASCV_MSGOUT_BEG,
                   1906:                             (u_int16_t *) & out_msg, sizeof(EXT_MSG) >> 1);
                   1907:
                   1908:                if ((out_msg.msg_type == MS_EXTEND) &&
                   1909:                    (out_msg.msg_len == MS_SDTR_LEN) &&
                   1910:                    (out_msg.msg_req == MS_SDTR_CODE)) {
                   1911:                        sc->init_sdtr &= ~target_id;
                   1912:                        sc->sdtr_done &= ~target_id;
                   1913:                        AscSetChipSDTR(iot, ioh, asyn_sdtr, tid_no);
                   1914:                        sc->sdtr_data[tid_no] = asyn_sdtr;
                   1915:                }
                   1916:                q_cntl &= ~ASC_QC_MSG_OUT;
                   1917:                AscWriteLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_CNTL, q_cntl);
                   1918:                AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
                   1919:        } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
                   1920:                scsi_status = AscReadLramByte(iot, ioh,
                   1921:                                       halt_q_addr + ASC_SCSIQ_SCSI_STATUS);
                   1922:                cur_dvc_qng = AscReadLramByte(iot, ioh, target_ix + ASC_QADR_BEG);
                   1923:
                   1924:                if ((cur_dvc_qng > 0) && (sc->cur_dvc_qng[tid_no] > 0)) {
                   1925:                        scsi_busy = AscReadLramByte(iot, ioh, ASCV_SCSIBUSY_B);
                   1926:                        scsi_busy |= target_id;
                   1927:                        AscWriteLramByte(iot, ioh, ASCV_SCSIBUSY_B, scsi_busy);
                   1928:                        sc->queue_full_or_busy |= target_id;
                   1929:
                   1930:                        if (scsi_status == SS_QUEUE_FULL) {
                   1931:                                if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
                   1932:                                        cur_dvc_qng -= 1;
                   1933:                                        sc->max_dvc_qng[tid_no] = cur_dvc_qng;
                   1934:
                   1935:                                        AscWriteLramByte(iot, ioh,
                   1936:                                                         tid_no + ASCV_MAX_DVC_QNG_BEG, cur_dvc_qng);
                   1937:
                   1938: #if ASC_QUEUE_FLOW_CONTROL
                   1939:                                        if ((sc->device[tid_no] != NULL) &&
                   1940:                                            (sc->device[tid_no]->queue_curr_depth > cur_dvc_qng)) {
                   1941:                                                sc->device[tid_no]->queue_curr_depth = cur_dvc_qng;
                   1942:                                        }
                   1943: #endif                         /* ASC_QUEUE_FLOW_CONTROL */
                   1944:                                }
                   1945:                        }
                   1946:                }
                   1947:                AscWriteLramWord(iot, ioh, ASCV_HALTCODE_W, 0);
                   1948:        }
                   1949:        return;
                   1950: }
                   1951:
                   1952:
                   1953: static int
                   1954: AscWaitTixISRDone(sc, target_ix)
                   1955:        ASC_SOFTC      *sc;
                   1956:        u_int8_t        target_ix;
                   1957: {
                   1958:        u_int8_t        cur_req;
                   1959:        u_int8_t        tid_no;
                   1960:        int             i = 0;
                   1961:
                   1962:        tid_no = ASC_TIX_TO_TID(target_ix);
                   1963:        while (i++ < 10) {
                   1964:                if ((cur_req = sc->cur_dvc_qng[tid_no]) == 0)
                   1965:                        break;
                   1966:
                   1967:                DvcSleepMilliSecond(1000L);
                   1968:                if (sc->cur_dvc_qng[tid_no] == cur_req)
                   1969:                        break;
                   1970:        }
                   1971:        return (1);
                   1972: }
                   1973:
                   1974: static int
                   1975: AscWaitISRDone(sc)
                   1976:        ASC_SOFTC      *sc;
                   1977: {
                   1978:        int             tid;
                   1979:
                   1980:        for (tid = 0; tid <= ASC_MAX_TID; tid++)
                   1981:                AscWaitTixISRDone(sc, ASC_TID_TO_TIX(tid));
                   1982:
                   1983:        return (1);
                   1984: }
                   1985:
                   1986:
                   1987: static u_int8_t
                   1988: _AscCopyLramScsiDoneQ(iot, ioh, q_addr, scsiq, max_dma_count)
                   1989:        bus_space_tag_t iot;
                   1990:        bus_space_handle_t ioh;
                   1991:        u_int16_t       q_addr;
                   1992:        ASC_QDONE_INFO *scsiq;
                   1993:        u_int32_t       max_dma_count;
                   1994: {
                   1995:        u_int16_t       _val;
                   1996:        u_int8_t        sg_queue_cnt;
                   1997:
                   1998:        AscGetQDoneInfo(iot, ioh, q_addr + ASC_SCSIQ_DONE_INFO_BEG, scsiq);
                   1999:
                   2000:        _val = AscReadLramWord(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS);
                   2001:        scsiq->q_status = LO_BYTE(_val);
                   2002:        scsiq->q_no = HI_BYTE(_val);
                   2003:        _val = AscReadLramWord(iot, ioh, q_addr + ASC_SCSIQ_B_CNTL);
                   2004:        scsiq->cntl = LO_BYTE(_val);
                   2005:        sg_queue_cnt = HI_BYTE(_val);
                   2006:        _val = AscReadLramWord(iot, ioh, q_addr + ASC_SCSIQ_B_SENSE_LEN);
                   2007:        scsiq->sense_len = LO_BYTE(_val);
                   2008:        scsiq->extra_bytes = HI_BYTE(_val);
                   2009:        scsiq->remain_bytes = AscReadLramWord(iot, ioh,
                   2010:                                     q_addr + ASC_SCSIQ_DW_REMAIN_XFER_CNT);
                   2011:        scsiq->remain_bytes &= max_dma_count;
                   2012:
                   2013:        return (sg_queue_cnt);
                   2014: }
                   2015:
                   2016:
                   2017: static void
                   2018: AscGetQDoneInfo(iot, ioh, addr, scsiq)
                   2019:        bus_space_tag_t iot;
                   2020:        bus_space_handle_t ioh;
                   2021:        u_int16_t       addr;
                   2022:        ASC_QDONE_INFO  *scsiq;
                   2023: {
                   2024:        u_int16_t       val;
                   2025:
                   2026:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
                   2027:
                   2028:        val = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
                   2029:        scsiq->d2.ccb_ptr = MAKELONG(val, ASC_GET_CHIP_LRAM_DATA(iot, ioh));
                   2030:        val = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
                   2031:        scsiq->d2.target_ix = LO_BYTE(val);
                   2032:        scsiq->d2.flag = HI_BYTE(val);
                   2033:        val = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
                   2034:        scsiq->d2.cdb_len = LO_BYTE(val);
                   2035:        scsiq->d2.tag_code = HI_BYTE(val);
                   2036:        scsiq->d2.vm_id = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
                   2037:
                   2038:        val = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
                   2039:        scsiq->d3.done_stat = LO_BYTE(val);
                   2040:        scsiq->d3.host_stat = HI_BYTE(val);
                   2041:        val = ASC_GET_CHIP_LRAM_DATA(iot, ioh);
                   2042:        scsiq->d3.scsi_stat = LO_BYTE(val);
                   2043:        scsiq->d3.scsi_msg = HI_BYTE(val);
                   2044: }
                   2045:
                   2046:
                   2047: static void
                   2048: AscToggleIRQAct(iot, ioh)
                   2049:        bus_space_tag_t iot;
                   2050:        bus_space_handle_t ioh;
                   2051: {
                   2052:
                   2053:        ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_IRQ_ACT);
                   2054:        ASC_SET_CHIP_STATUS(iot, ioh, 0);
                   2055: }
                   2056:
                   2057:
                   2058: static void
                   2059: AscDisableInterrupt(iot, ioh)
                   2060:        bus_space_tag_t iot;
                   2061:        bus_space_handle_t ioh;
                   2062: {
                   2063:        u_int16_t       cfg;
                   2064:
                   2065:        cfg = ASC_GET_CHIP_CFG_LSW(iot, ioh);
                   2066:        ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg & (~ASC_CFG0_HOST_INT_ON));
                   2067: }
                   2068:
                   2069:
                   2070: static void
                   2071: AscEnableInterrupt(iot, ioh)
                   2072:        bus_space_tag_t iot;
                   2073:        bus_space_handle_t ioh;
                   2074: {
                   2075:        u_int16_t       cfg;
                   2076:
                   2077:        cfg = ASC_GET_CHIP_CFG_LSW(iot, ioh);
                   2078:        ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg | ASC_CFG0_HOST_INT_ON);
                   2079: }
                   2080:
                   2081:
                   2082: static u_int8_t
                   2083: AscGetChipIRQ(iot, ioh, bus_type)
                   2084:        bus_space_tag_t iot;
                   2085:        bus_space_handle_t ioh;
                   2086:        u_int16_t       bus_type;
                   2087: {
                   2088:        u_int16_t       cfg_lsw;
                   2089:        u_int8_t        chip_irq;
                   2090:
                   2091:
                   2092:        if (bus_type & ASC_IS_EISA) {
                   2093:                /*
                   2094:                 * cfg_lsw = AscGetEisaChipCfg(iot, ioh); chip_irq =
                   2095:                 * ((cfg_lsw >> 8) & 0x07) + 10; if((chip_irq == 13) ||
                   2096:                 * (chip_irq > 15)) return (0); return(chip_irq);
                   2097:                 */
                   2098:        }
                   2099:        if ((bus_type & ASC_IS_VL) != 0) {
                   2100:                cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh);
                   2101:                chip_irq = (cfg_lsw >> 2) & 0x07;
                   2102:                if ((chip_irq == 0) ||
                   2103:                    (chip_irq == 4) ||
                   2104:                    (chip_irq == 7)) {
                   2105:                        return (0);
                   2106:                }
                   2107:                return (chip_irq + (ASC_MIN_IRQ_NO - 1));
                   2108:        }
                   2109:        cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh);
                   2110:        chip_irq = (cfg_lsw >> 2) & 0x03;
                   2111:        if (chip_irq == 3)
                   2112:                chip_irq += 2;
                   2113:        return (chip_irq + ASC_MIN_IRQ_NO);
                   2114: }
                   2115:
                   2116:
                   2117: static u_int8_t
                   2118: AscSetChipIRQ(iot, ioh, irq_no, bus_type)
                   2119:        bus_space_tag_t iot;
                   2120:        bus_space_handle_t ioh;
                   2121:        u_int8_t        irq_no;
                   2122:        u_int16_t       bus_type;
                   2123: {
                   2124:        u_int16_t       cfg_lsw;
                   2125:
                   2126:
                   2127:        if (bus_type & ASC_IS_VL) {
                   2128:                if (irq_no) {
                   2129:                        if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO))
                   2130:                                irq_no = 0;
                   2131:                        else
                   2132:                                irq_no -= ASC_MIN_IRQ_NO - 1;
                   2133:                }
                   2134:
                   2135:                cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh) & 0xFFE3;
                   2136:                cfg_lsw |= 0x0010;
                   2137:                ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg_lsw);
                   2138:                AscToggleIRQAct(iot, ioh);
                   2139:                cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh) & 0xFFE0;
                   2140:                cfg_lsw |= (irq_no & 0x07) << 2;
                   2141:                ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg_lsw);
                   2142:                AscToggleIRQAct(iot, ioh);
                   2143:
                   2144:                return (AscGetChipIRQ(iot, ioh, bus_type));
                   2145:        }
                   2146:        if (bus_type & ASC_IS_ISA) {
                   2147:                if (irq_no == 15)
                   2148:                        irq_no -= 2;
                   2149:                irq_no -= ASC_MIN_IRQ_NO;
                   2150:                cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh) & 0xFFF3;
                   2151:                cfg_lsw |= (irq_no & 0x03) << 2;
                   2152:                ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg_lsw);
                   2153:
                   2154:                return (AscGetChipIRQ(iot, ioh, bus_type));
                   2155:        }
                   2156:        return (0);
                   2157: }
                   2158:
                   2159:
                   2160: static void
                   2161: AscAckInterrupt(iot, ioh)
                   2162:        bus_space_tag_t iot;
                   2163:        bus_space_handle_t ioh;
                   2164: {
                   2165:        u_int8_t        host_flag;
                   2166:        u_int8_t        risc_flag;
                   2167:        u_int16_t       loop;
                   2168:
                   2169:
                   2170:        loop = 0;
                   2171:        do {
                   2172:                risc_flag = AscReadLramByte(iot, ioh, ASCV_RISC_FLAG_B);
                   2173:                if (loop++ > 0x7FFF)
                   2174:                        break;
                   2175:        } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
                   2176:
                   2177:        host_flag = AscReadLramByte(iot, ioh, ASCV_HOST_FLAG_B) &
                   2178:                (~ASC_HOST_FLAG_ACK_INT);
                   2179:        AscWriteLramByte(iot, ioh, ASCV_HOST_FLAG_B,
                   2180:                         host_flag | ASC_HOST_FLAG_ACK_INT);
                   2181:        ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_INT_ACK);
                   2182:
                   2183:        loop = 0;
                   2184:        while (ASC_GET_CHIP_STATUS(iot, ioh) & ASC_CSW_INT_PENDING) {
                   2185:                ASC_SET_CHIP_STATUS(iot, ioh, ASC_CIW_INT_ACK);
                   2186:                if (loop++ > 3)
                   2187:                        break;
                   2188:        }
                   2189:
                   2190:        AscWriteLramByte(iot, ioh, ASCV_HOST_FLAG_B, host_flag);
                   2191: }
                   2192:
                   2193:
                   2194: static u_int32_t
                   2195: AscGetMaxDmaCount(bus_type)
                   2196:        u_int16_t       bus_type;
                   2197: {
                   2198:        if (bus_type & ASC_IS_ISA)
                   2199:                return (ASC_MAX_ISA_DMA_COUNT);
                   2200:        else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
                   2201:                return (ASC_MAX_VL_DMA_COUNT);
                   2202:        return (ASC_MAX_PCI_DMA_COUNT);
                   2203: }
                   2204:
                   2205:
                   2206: static u_int16_t
                   2207: AscGetIsaDmaChannel(iot, ioh)
                   2208:        bus_space_tag_t iot;
                   2209:        bus_space_handle_t ioh;
                   2210: {
                   2211:        u_int16_t       channel;
                   2212:
                   2213:        channel = ASC_GET_CHIP_CFG_LSW(iot, ioh) & 0x0003;
                   2214:        if (channel == 0x03)
                   2215:                return (0);
                   2216:        else if (channel == 0x00)
                   2217:                return (7);
                   2218:        return (channel + 4);
                   2219: }
                   2220:
                   2221:
                   2222: static u_int16_t
                   2223: AscSetIsaDmaChannel(iot, ioh, dma_channel)
                   2224:        bus_space_tag_t iot;
                   2225:        bus_space_handle_t ioh;
                   2226:        u_int16_t       dma_channel;
                   2227: {
                   2228:        u_int16_t       cfg_lsw;
                   2229:        u_int8_t        value;
                   2230:
                   2231:        if ((dma_channel >= 5) && (dma_channel <= 7)) {
                   2232:                if (dma_channel == 7)
                   2233:                        value = 0x00;
                   2234:                else
                   2235:                        value = dma_channel - 4;
                   2236:                cfg_lsw = ASC_GET_CHIP_CFG_LSW(iot, ioh) & 0xFFFC;
                   2237:                cfg_lsw |= value;
                   2238:                ASC_SET_CHIP_CFG_LSW(iot, ioh, cfg_lsw);
                   2239:                return (AscGetIsaDmaChannel(iot, ioh));
                   2240:        }
                   2241:        return (0);
                   2242: }
                   2243:
                   2244:
                   2245: static u_int8_t
                   2246: AscGetIsaDmaSpeed(iot, ioh)
                   2247:        bus_space_tag_t iot;
                   2248:        bus_space_handle_t ioh;
                   2249: {
                   2250:        u_int8_t        speed_value;
                   2251:
                   2252:        AscSetBank(iot, ioh, 1);
                   2253:        speed_value = ASC_READ_CHIP_DMA_SPEED(iot, ioh);
                   2254:        speed_value &= 0x07;
                   2255:        AscSetBank(iot, ioh, 0);
                   2256:        return (speed_value);
                   2257: }
                   2258:
                   2259:
                   2260: static u_int8_t
                   2261: AscSetIsaDmaSpeed(iot, ioh, speed_value)
                   2262:        bus_space_tag_t iot;
                   2263:        bus_space_handle_t ioh;
                   2264:        u_int8_t        speed_value;
                   2265: {
                   2266:        speed_value &= 0x07;
                   2267:        AscSetBank(iot, ioh, 1);
                   2268:        ASC_WRITE_CHIP_DMA_SPEED(iot, ioh, speed_value);
                   2269:        AscSetBank(iot, ioh, 0);
                   2270:        return (AscGetIsaDmaSpeed(iot, ioh));
                   2271: }
                   2272:
                   2273:
                   2274: /******************************************************************************/
                   2275: /*                              Messages routines                             */
                   2276: /******************************************************************************/
                   2277:
                   2278:
                   2279: static void
                   2280: AscHandleExtMsgIn(sc, halt_q_addr, q_cntl, target_id, tid_no, asyn_sdtr)
                   2281:        ASC_SOFTC      *sc;
                   2282:        u_int16_t       halt_q_addr;
                   2283:        u_int8_t        q_cntl;
                   2284:        ASC_SCSI_BIT_ID_TYPE target_id;
                   2285:        int             tid_no;
                   2286:        u_int8_t        asyn_sdtr;
                   2287: {
                   2288:        bus_space_tag_t iot = sc->sc_iot;
                   2289:        bus_space_handle_t ioh = sc->sc_ioh;
                   2290:        EXT_MSG         ext_msg;
                   2291:        u_int8_t        sdtr_data;
                   2292:        int             sdtr_accept;
                   2293:
                   2294:
                   2295:        AscMemWordCopyFromLram(iot, ioh, ASCV_MSGIN_BEG,
                   2296:                             (u_int16_t *) & ext_msg, sizeof(EXT_MSG) >> 1);
                   2297:
                   2298:        if (ext_msg.msg_type == MS_EXTEND &&
                   2299:            ext_msg.msg_req == MS_SDTR_CODE &&
                   2300:            ext_msg.msg_len == MS_SDTR_LEN) {
                   2301:                sdtr_accept = TRUE;
                   2302:
                   2303:                if (ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET) {
                   2304:                        sdtr_accept = FALSE;
                   2305:                        ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
                   2306:                }
                   2307:                if ((ext_msg.xfer_period <
                   2308:                     sc->sdtr_period_tbl[sc->host_init_sdtr_index]) ||
                   2309:                    (ext_msg.xfer_period >
                   2310:                     sc->sdtr_period_tbl[sc->max_sdtr_index])) {
                   2311:                        sdtr_accept = FALSE;
                   2312:                        ext_msg.xfer_period = sc->sdtr_period_tbl[sc->host_init_sdtr_index];
                   2313:                }
                   2314:                if (sdtr_accept) {
                   2315:                        sdtr_data = AscCalSDTRData(sc, ext_msg.xfer_period,
                   2316:                                                   ext_msg.req_ack_offset);
                   2317:                        if (sdtr_data == 0xFF) {
                   2318:                                q_cntl |= ASC_QC_MSG_OUT;
                   2319:                                sc->init_sdtr &= ~target_id;
                   2320:                                sc->sdtr_done &= ~target_id;
                   2321:                                AscSetChipSDTR(iot, ioh, asyn_sdtr, tid_no);
                   2322:                                sc->sdtr_data[tid_no] = asyn_sdtr;
                   2323:                        }
                   2324:                }
                   2325:                if (ext_msg.req_ack_offset == 0) {
                   2326:                        q_cntl &= ~ASC_QC_MSG_OUT;
                   2327:                        sc->init_sdtr &= ~target_id;
                   2328:                        sc->sdtr_done &= ~target_id;
                   2329:                        AscSetChipSDTR(iot, ioh, asyn_sdtr, tid_no);
                   2330:                } else {
                   2331:                        if (sdtr_accept && (q_cntl & ASC_QC_MSG_OUT)) {
                   2332:                                q_cntl &= ~ASC_QC_MSG_OUT;
                   2333:                                sc->sdtr_done |= target_id;
                   2334:                                sc->init_sdtr |= target_id;
                   2335:                                sc->pci_fix_asyn_xfer &= ~target_id;
                   2336:                                sdtr_data = AscCalSDTRData(sc, ext_msg.xfer_period,
                   2337:                                                    ext_msg.req_ack_offset);
                   2338:                                AscSetChipSDTR(iot, ioh, sdtr_data, tid_no);
                   2339:                                sc->sdtr_data[tid_no] = sdtr_data;
                   2340:                        } else {
                   2341:                                q_cntl |= ASC_QC_MSG_OUT;
                   2342:                                AscMsgOutSDTR(sc, ext_msg.xfer_period,
                   2343:                                              ext_msg.req_ack_offset);
                   2344:                                sc->pci_fix_asyn_xfer &= ~target_id;
                   2345:                                sdtr_data = AscCalSDTRData(sc, ext_msg.xfer_period,
                   2346:                                                    ext_msg.req_ack_offset);
                   2347:                                AscSetChipSDTR(iot, ioh, sdtr_data, tid_no);
                   2348:                                sc->sdtr_data[tid_no] = sdtr_data;
                   2349:                                sc->sdtr_done |= target_id;
                   2350:                                sc->init_sdtr |= target_id;
                   2351:                        }
                   2352:                }
                   2353:        } else if (ext_msg.msg_type == MS_EXTEND &&
                   2354:                   ext_msg.msg_req == MS_WDTR_CODE &&
                   2355:                   ext_msg.msg_len == MS_WDTR_LEN) {
                   2356:                ext_msg.wdtr_width = 0;
                   2357:                AscMemWordCopyToLram(iot, ioh, ASCV_MSGOUT_BEG,
                   2358:                             (u_int16_t *) & ext_msg, sizeof(EXT_MSG) >> 1);
                   2359:                q_cntl |= ASC_QC_MSG_OUT;
                   2360:        } else {
                   2361:                ext_msg.msg_type = M1_MSG_REJECT;
                   2362:                AscMemWordCopyToLram(iot, ioh, ASCV_MSGOUT_BEG,
                   2363:                             (u_int16_t *) & ext_msg, sizeof(EXT_MSG) >> 1);
                   2364:                q_cntl |= ASC_QC_MSG_OUT;
                   2365:        }
                   2366:
                   2367:        AscWriteLramByte(iot, ioh, halt_q_addr + ASC_SCSIQ_B_CNTL, q_cntl);
                   2368: }
                   2369:
                   2370:
                   2371: static u_int8_t
                   2372: AscMsgOutSDTR(sc, sdtr_period, sdtr_offset)
                   2373:        ASC_SOFTC      *sc;
                   2374:        u_int8_t        sdtr_period;
                   2375:        u_int8_t        sdtr_offset;
                   2376: {
                   2377:        bus_space_tag_t iot = sc->sc_iot;
                   2378:        bus_space_handle_t ioh = sc->sc_ioh;
                   2379:        EXT_MSG         sdtr_buf;
                   2380:        u_int8_t        sdtr_period_index;
                   2381:
                   2382:
                   2383:        sdtr_buf.msg_type = MS_EXTEND;
                   2384:        sdtr_buf.msg_len = MS_SDTR_LEN;
                   2385:        sdtr_buf.msg_req = MS_SDTR_CODE;
                   2386:        sdtr_buf.xfer_period = sdtr_period;
                   2387:        sdtr_offset &= ASC_SYN_MAX_OFFSET;
                   2388:        sdtr_buf.req_ack_offset = sdtr_offset;
                   2389:        if ((sdtr_period_index = AscGetSynPeriodIndex(sc, sdtr_period)) <=
                   2390:            sc->max_sdtr_index) {
                   2391:                AscMemWordCopyToLram(iot, ioh, ASCV_MSGOUT_BEG,
                   2392:                            (u_int16_t *) & sdtr_buf, sizeof(EXT_MSG) >> 1);
                   2393:                return ((sdtr_period_index << 4) | sdtr_offset);
                   2394:        } else {
                   2395:                sdtr_buf.req_ack_offset = 0;
                   2396:                AscMemWordCopyToLram(iot, ioh, ASCV_MSGOUT_BEG,
                   2397:                            (u_int16_t *) & sdtr_buf, sizeof(EXT_MSG) >> 1);
                   2398:                return (0);
                   2399:        }
                   2400: }
                   2401:
                   2402:
                   2403: /******************************************************************************/
                   2404: /*                                  SDTR routines                             */
                   2405: /******************************************************************************/
                   2406:
                   2407:
                   2408: static void
                   2409: AscSetChipSDTR(iot, ioh, sdtr_data, tid_no)
                   2410:        bus_space_tag_t iot;
                   2411:        bus_space_handle_t ioh;
                   2412:        u_int8_t        sdtr_data;
                   2413:        u_int8_t        tid_no;
                   2414: {
                   2415:        AscSetChipSynRegAtID(iot, ioh, tid_no, sdtr_data);
                   2416:        AscWriteLramByte(iot, ioh, tid_no + ASCV_SDTR_DONE_BEG, sdtr_data);
                   2417: }
                   2418:
                   2419:
                   2420: static u_int8_t
                   2421: AscCalSDTRData(sc, sdtr_period, syn_offset)
                   2422:        ASC_SOFTC      *sc;
                   2423:        u_int8_t        sdtr_period;
                   2424:        u_int8_t        syn_offset;
                   2425: {
                   2426:        u_int8_t        byte;
                   2427:        u_int8_t        sdtr_period_ix;
                   2428:
                   2429:        sdtr_period_ix = AscGetSynPeriodIndex(sc, sdtr_period);
                   2430:        if (sdtr_period_ix > sc->max_sdtr_index)
                   2431:                return (0xFF);
                   2432:
                   2433:        byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
                   2434:        return (byte);
                   2435: }
                   2436:
                   2437:
                   2438: static u_int8_t
                   2439: AscGetSynPeriodIndex(sc, syn_time)
                   2440:        ASC_SOFTC      *sc;
                   2441:        u_int8_t        syn_time;
                   2442: {
                   2443:        u_int8_t       *period_table;
                   2444:        int             max_index;
                   2445:        int             min_index;
                   2446:        int             i;
                   2447:
                   2448:        period_table = sc->sdtr_period_tbl;
                   2449:        max_index = sc->max_sdtr_index;
                   2450:        min_index = sc->host_init_sdtr_index;
                   2451:        if ((syn_time <= period_table[max_index])) {
                   2452:                for (i = min_index; i < (max_index - 1); i++) {
                   2453:                        if (syn_time <= period_table[i])
                   2454:                                return (i);
                   2455:                }
                   2456:
                   2457:                return (max_index);
                   2458:        } else
                   2459:                return (max_index + 1);
                   2460: }
                   2461:
                   2462:
                   2463: /******************************************************************************/
                   2464: /*                                 Queue routines                             */
                   2465: /******************************************************************************/
                   2466:
                   2467: /*
                   2468:  * Send a command to the board
                   2469:  */
                   2470: int
                   2471: AscExeScsiQueue(sc, scsiq)
                   2472:        ASC_SOFTC      *sc;
                   2473:        ASC_SCSI_Q     *scsiq;
                   2474: {
                   2475:        bus_space_tag_t iot = sc->sc_iot;
                   2476:        bus_space_handle_t ioh = sc->sc_ioh;
                   2477:        ASC_SG_HEAD    *sg_head = scsiq->sg_head;
                   2478:        int             retval;
                   2479:        int             n_q_required;
                   2480:        int             disable_syn_offset_one_fix;
                   2481:        int             i;
                   2482:        u_int32_t       addr;
                   2483:        u_int16_t       sg_entry_cnt = 0;
                   2484:        u_int16_t       sg_entry_cnt_minus_one = 0;
                   2485:        u_int8_t        target_ix;
                   2486:        u_int8_t        tid_no;
                   2487:        u_int8_t        sdtr_data;
                   2488:        u_int8_t        extra_bytes;
                   2489:        u_int8_t        scsi_cmd;
                   2490:        u_int32_t       data_cnt;
                   2491:
                   2492:
                   2493:        scsiq->q1.q_no = 0;
                   2494:        if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0)
                   2495:                scsiq->q1.extra_bytes = 0;
                   2496:
                   2497:        retval = ASC_BUSY;
                   2498:        target_ix = scsiq->q2.target_ix;
                   2499:        tid_no = ASC_TIX_TO_TID(target_ix);
                   2500:        n_q_required = 1;
                   2501:
                   2502:        if (scsiq->cdbptr[0] == SCSICMD_RequestSense)
                   2503:                if ((sc->init_sdtr & scsiq->q1.target_id) != 0) {
                   2504:                        sc->sdtr_done &= ~scsiq->q1.target_id;
                   2505:                        sdtr_data = ASC_GET_MCODE_INIT_SDTR_AT_ID(iot, ioh, tid_no);
                   2506:                        AscMsgOutSDTR(sc, sc->sdtr_period_tbl[(sdtr_data >> 4) &
                   2507:                                                  (sc->max_sdtr_index - 1)],
                   2508:                                      sdtr_data & ASC_SYN_MAX_OFFSET);
                   2509:                        scsiq->q1.cntl |= (ASC_QC_MSG_OUT | ASC_QC_URGENT);
                   2510:                }
                   2511:        /*
                   2512:         * if there is just one segment into S/G list then
                   2513:         * map it as it was a single request, filling
                   2514:         * data_addr and data_cnt of ASC_SCSIQ structure.
                   2515:         */
                   2516:        if ((scsiq->q1.cntl & ASC_QC_SG_HEAD) != 0) {
                   2517:                sg_entry_cnt = sg_head->entry_cnt;
                   2518:
                   2519:                if (sg_entry_cnt < 1)
                   2520:                        panic("AscExeScsiQueue: Queue with QC_SG_HEAD set but %d segs.",
                   2521:                              sg_entry_cnt);
                   2522:
                   2523:                if (sg_entry_cnt > ASC_MAX_SG_LIST)
                   2524:                        panic("AscExeScsiQueue: Queue with too many segs.");
                   2525:
                   2526:                if (sg_entry_cnt == 1) {
                   2527:                        scsiq->q1.data_addr = sg_head->sg_list[0].addr;
                   2528:                        scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
                   2529:                        scsiq->q1.cntl &= ~(ASC_QC_SG_HEAD | ASC_QC_SG_SWAP_QUEUE);
                   2530:                }
                   2531:                sg_entry_cnt_minus_one = sg_entry_cnt - 1;
                   2532:        }
                   2533:        scsi_cmd = scsiq->cdbptr[0];
                   2534:        disable_syn_offset_one_fix = FALSE;
                   2535:        if ((sc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
                   2536:            !(sc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
                   2537:                if (scsiq->q1.cntl & ASC_QC_SG_HEAD) {
                   2538:                        data_cnt = 0;
                   2539:                        for (i = 0; i < sg_entry_cnt; i++)
                   2540:                                data_cnt += sg_head->sg_list[i].bytes;
                   2541:                } else {
                   2542:                        data_cnt = scsiq->q1.data_cnt;
                   2543:                }
                   2544:
                   2545:                if (data_cnt != 0ul) {
                   2546:                        if (data_cnt < 512ul) {
                   2547:                                disable_syn_offset_one_fix = TRUE;
                   2548:                        } else {
                   2549:                                if (scsi_cmd == SCSICMD_Inquiry ||
                   2550:                                    scsi_cmd == SCSICMD_RequestSense ||
                   2551:                                    scsi_cmd == SCSICMD_ReadCapacity ||
                   2552:                                    scsi_cmd == SCSICMD_ReadTOC ||
                   2553:                                    scsi_cmd == SCSICMD_ModeSelect6 ||
                   2554:                                    scsi_cmd == SCSICMD_ModeSense6 ||
                   2555:                                    scsi_cmd == SCSICMD_ModeSelect10 ||
                   2556:                                    scsi_cmd == SCSICMD_ModeSense10) {
                   2557:                                        disable_syn_offset_one_fix = TRUE;
                   2558:                                }
                   2559:                        }
                   2560:                }
                   2561:        }
                   2562:        if (disable_syn_offset_one_fix) {
                   2563:                scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
                   2564:                scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
                   2565:                                       ASC_TAG_FLAG_DISABLE_DISCONNECT);
                   2566:        } else {
                   2567:                scsiq->q2.tag_code &= 0x23;
                   2568:        }
                   2569:
                   2570:        if ((scsiq->q1.cntl & ASC_QC_SG_HEAD) != 0) {
                   2571:                if (sc->bug_fix_cntl) {
                   2572:                        if (sc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
                   2573:                                if ((scsi_cmd == SCSICMD_Read6) || (scsi_cmd == SCSICMD_Read10)) {
                   2574:                                        addr = sg_head->sg_list[sg_entry_cnt_minus_one].addr +
                   2575:                                                sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
                   2576:                                        extra_bytes = addr & 0x0003;
                   2577:                                        if ((extra_bytes != 0) &&
                   2578:                                            ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0)) {
                   2579:                                                scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
                   2580:                                                scsiq->q1.extra_bytes = extra_bytes;
                   2581:                                                sg_head->sg_list[sg_entry_cnt_minus_one].bytes -=
                   2582:                                                        extra_bytes;
                   2583:                                        }
                   2584:                                }
                   2585:                        }
                   2586:                }
                   2587:                sg_head->entry_to_copy = sg_head->entry_cnt;
                   2588:                n_q_required = AscSgListToQueue(sg_entry_cnt);
                   2589:                if ((AscGetNumOfFreeQueue(sc, target_ix, n_q_required) >= n_q_required)
                   2590:                    || ((scsiq->q1.cntl & ASC_QC_URGENT) != 0)) {
                   2591:                        retval = AscSendScsiQueue(sc, scsiq, n_q_required);
                   2592:                }
                   2593:        } else {
                   2594:                if (sc->bug_fix_cntl) {
                   2595:                        if (sc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
                   2596:                                if ((scsi_cmd == SCSICMD_Read6) || (scsi_cmd == SCSICMD_Read10)) {
                   2597:                                        addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
                   2598:                                        extra_bytes = addr & 0x0003;
                   2599:                                        if ((extra_bytes != 0) &&
                   2600:                                            ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0)) {
                   2601:                                                if ((scsiq->q1.data_cnt & 0x01FF) == 0) {
                   2602:                                                        scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
                   2603:                                                        scsiq->q1.data_cnt -= extra_bytes;
                   2604:                                                        scsiq->q1.extra_bytes = extra_bytes;
                   2605:                                                }
                   2606:                                        }
                   2607:                                }
                   2608:                        }
                   2609:                }
                   2610:                n_q_required = 1;
                   2611:                if ((AscGetNumOfFreeQueue(sc, target_ix, 1) >= 1) ||
                   2612:                    ((scsiq->q1.cntl & ASC_QC_URGENT) != 0)) {
                   2613:                        retval = AscSendScsiQueue(sc, scsiq, n_q_required);
                   2614:                }
                   2615:        }
                   2616:
                   2617:        return (retval);
                   2618: }
                   2619:
                   2620:
                   2621: static int
                   2622: AscSendScsiQueue(sc, scsiq, n_q_required)
                   2623:        ASC_SOFTC      *sc;
                   2624:        ASC_SCSI_Q     *scsiq;
                   2625:        u_int8_t        n_q_required;
                   2626: {
                   2627:        bus_space_tag_t iot = sc->sc_iot;
                   2628:        bus_space_handle_t ioh = sc->sc_ioh;
                   2629:        u_int8_t        free_q_head;
                   2630:        u_int8_t        next_qp;
                   2631:        u_int8_t        tid_no;
                   2632:        u_int8_t        target_ix;
                   2633:        int             retval;
                   2634:
                   2635:
                   2636:        target_ix = scsiq->q2.target_ix;
                   2637:        tid_no = ASC_TIX_TO_TID(target_ix);
                   2638:        retval = ASC_BUSY;
                   2639:        free_q_head = ASC_GET_VAR_FREE_QHEAD(iot, ioh);
                   2640:
                   2641:        if ((next_qp = AscAllocMultipleFreeQueue(iot, ioh, free_q_head, n_q_required))
                   2642:            != ASC_QLINK_END) {
                   2643:                if (n_q_required > 1) {
                   2644:                        sc->last_q_shortage = 0;
                   2645:                        scsiq->sg_head->queue_cnt = n_q_required - 1;
                   2646:                }
                   2647:                scsiq->q1.q_no = free_q_head;
                   2648:
                   2649:                if ((retval = AscPutReadySgListQueue(sc, scsiq, free_q_head)) == ASC_NOERROR) {
                   2650:                        ASC_PUT_VAR_FREE_QHEAD(iot, ioh, next_qp);
                   2651:                        sc->cur_total_qng += n_q_required;
                   2652:                        sc->cur_dvc_qng[tid_no]++;
                   2653:                }
                   2654:        }
                   2655:        return (retval);
                   2656: }
                   2657:
                   2658:
                   2659: static int
                   2660: AscPutReadySgListQueue(sc, scsiq, q_no)
                   2661:        ASC_SOFTC      *sc;
                   2662:        ASC_SCSI_Q     *scsiq;
                   2663:        u_int8_t        q_no;
                   2664: {
                   2665:        bus_space_tag_t iot = sc->sc_iot;
                   2666:        bus_space_handle_t ioh = sc->sc_ioh;
                   2667:        int             retval;
                   2668:        int             i;
                   2669:        ASC_SG_HEAD    *sg_head;
                   2670:        ASC_SG_LIST_Q   scsi_sg_q;
                   2671:        u_int32_t       saved_data_addr;
                   2672:        u_int32_t       saved_data_cnt;
                   2673:        u_int16_t       sg_list_dwords;
                   2674:        u_int16_t       sg_index;
                   2675:        u_int16_t       sg_entry_cnt;
                   2676:        u_int16_t       q_addr;
                   2677:        u_int8_t        next_qp;
                   2678:
                   2679:
                   2680:        saved_data_addr = scsiq->q1.data_addr;
                   2681:        saved_data_cnt = scsiq->q1.data_cnt;
                   2682:
                   2683:        if ((sg_head = scsiq->sg_head) != 0) {
                   2684:                scsiq->q1.data_addr = sg_head->sg_list[0].addr;
                   2685:                scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
                   2686:                sg_entry_cnt = sg_head->entry_cnt - 1;
                   2687:                if (sg_entry_cnt != 0) {
                   2688:                        q_addr = ASC_QNO_TO_QADDR(q_no);
                   2689:                        sg_index = 1;
                   2690:                        scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
                   2691:                        scsi_sg_q.sg_head_qp = q_no;
                   2692:                        scsi_sg_q.cntl = ASC_QCSG_SG_XFER_LIST;
                   2693:
                   2694:                        for (i = 0; i < sg_head->queue_cnt; i++) {
                   2695:                                scsi_sg_q.seq_no = i + 1;
                   2696:                                if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
                   2697:                                        sg_list_dwords = ASC_SG_LIST_PER_Q * 2;
                   2698:                                        sg_entry_cnt -= ASC_SG_LIST_PER_Q;
                   2699:                                        if (i == 0) {
                   2700:                                                scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
                   2701:                                                scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
                   2702:                                        } else {
                   2703:                                                scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
                   2704:                                                scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
                   2705:                                        }
                   2706:                                } else {
                   2707:                                        scsi_sg_q.cntl |= ASC_QCSG_SG_XFER_END;
                   2708:                                        sg_list_dwords = sg_entry_cnt << 1;
                   2709:                                        if (i == 0) {
                   2710:                                                scsi_sg_q.sg_list_cnt = sg_entry_cnt;
                   2711:                                                scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
                   2712:                                        } else {
                   2713:                                                scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
                   2714:                                                scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
                   2715:                                        }
                   2716:
                   2717:                                        sg_entry_cnt = 0;
                   2718:                                }
                   2719:
                   2720:                                next_qp = AscReadLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_FWD);
                   2721:                                scsi_sg_q.q_no = next_qp;
                   2722:                                q_addr = ASC_QNO_TO_QADDR(next_qp);
                   2723:
                   2724:                                /*
                   2725:                                 * Tell the board how many entries are in the S/G list
                   2726:                                 */
                   2727:                                AscMemWordCopyToLram(iot, ioh, q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
                   2728:                                                        (u_int16_t *) & scsi_sg_q,
                   2729:                                                        sizeof(ASC_SG_LIST_Q) >> 1);
                   2730:                                /*
                   2731:                                 * Tell the board the addresses of the S/G list segments
                   2732:                                 */
                   2733:                                AscMemDWordCopyToLram(iot, ioh, q_addr + ASC_SGQ_LIST_BEG,
                   2734:                                                        (u_int32_t *) & sg_head->sg_list[sg_index],
                   2735:                                                        sg_list_dwords);
                   2736:                                sg_index += ASC_SG_LIST_PER_Q;
                   2737:                        }
                   2738:                }
                   2739:        }
                   2740:        retval = AscPutReadyQueue(sc, scsiq, q_no);
                   2741:        scsiq->q1.data_addr = saved_data_addr;
                   2742:        scsiq->q1.data_cnt = saved_data_cnt;
                   2743:        return (retval);
                   2744: }
                   2745:
                   2746:
                   2747: static int
                   2748: AscPutReadyQueue(sc, scsiq, q_no)
                   2749:        ASC_SOFTC      *sc;
                   2750:        ASC_SCSI_Q     *scsiq;
                   2751:        u_int8_t        q_no;
                   2752: {
                   2753:        bus_space_tag_t iot = sc->sc_iot;
                   2754:        bus_space_handle_t ioh = sc->sc_ioh;
                   2755:        u_int16_t       q_addr;
                   2756:        u_int8_t        tid_no;
                   2757:        u_int8_t        sdtr_data;
                   2758:        u_int8_t        syn_period_ix;
                   2759:        u_int8_t        syn_offset;
                   2760:
                   2761:
                   2762:        if (((sc->init_sdtr & scsiq->q1.target_id) != 0) &&
                   2763:            ((sc->sdtr_done & scsiq->q1.target_id) == 0)) {
                   2764:                tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
                   2765:                sdtr_data = ASC_GET_MCODE_INIT_SDTR_AT_ID(iot, ioh, tid_no);
                   2766:                syn_period_ix = (sdtr_data >> 4) & (sc->max_sdtr_index - 1);
                   2767:                syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
                   2768:                AscMsgOutSDTR(sc, sc->sdtr_period_tbl[syn_period_ix], syn_offset);
                   2769:                scsiq->q1.cntl |= ASC_QC_MSG_OUT;
                   2770:        }
                   2771:        q_addr = ASC_QNO_TO_QADDR(q_no);
                   2772:
                   2773:        if ((scsiq->q1.target_id & sc->use_tagged_qng) == 0) {
                   2774:                scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
                   2775:        }
                   2776:        scsiq->q1.status = ASC_QS_FREE;
                   2777:        AscMemWordCopyToLram(iot, ioh, q_addr + ASC_SCSIQ_CDB_BEG,
                   2778:                       (u_int16_t *) scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
                   2779:
                   2780:        AscPutSCSIQ(iot, ioh, q_addr + ASC_SCSIQ_CPY_BEG, scsiq);
                   2781:
                   2782:        /*
                   2783:         * Let's start the command
                   2784:         */
                   2785:        AscWriteLramWord(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS,
                   2786:                         (scsiq->q1.q_no << 8) | ASC_QS_READY);
                   2787:
                   2788:        return (ASC_NOERROR);
                   2789: }
                   2790:
                   2791:
                   2792: static void
                   2793: AscPutSCSIQ(iot, ioh, addr, scsiq)
                   2794:        bus_space_tag_t         iot;
                   2795:        bus_space_handle_t      ioh;
                   2796:        u_int16_t               addr;
                   2797:        ASC_SCSI_Q              *scsiq;
                   2798: {
                   2799:        u_int16_t       val;
                   2800:
                   2801:
                   2802:        ASC_SET_CHIP_LRAM_ADDR(iot, ioh, addr);
                   2803:
                   2804:        /* ASC_SCSIQ_1 */
                   2805:        val = MAKEWORD(scsiq->q1.cntl, scsiq->q1.sg_queue_cnt);
                   2806:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2807:        val = MAKEWORD(scsiq->q1.target_id, scsiq->q1.target_lun);
                   2808:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2809:        val = LO_WORD(scsiq->q1.data_addr);
                   2810:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2811:        val = HI_WORD(scsiq->q1.data_addr);
                   2812:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2813:        val = LO_WORD(scsiq->q1.data_cnt);
                   2814:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2815:        val = HI_WORD(scsiq->q1.data_cnt);
                   2816:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2817:        val = LO_WORD(scsiq->q1.sense_addr);
                   2818:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2819:        val = HI_WORD(scsiq->q1.sense_addr);
                   2820:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2821:        val = MAKEWORD(scsiq->q1.sense_len, scsiq->q1.extra_bytes);
                   2822:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2823:
                   2824:        /* ASC_SCSIQ_2 */
                   2825:        val = LO_WORD(scsiq->q2.ccb_ptr);
                   2826:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2827:        val = HI_WORD(scsiq->q2.ccb_ptr);
                   2828:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2829:        val = MAKEWORD(scsiq->q2.target_ix, scsiq->q2.flag);
                   2830:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2831:        val = MAKEWORD(scsiq->q2.cdb_len, scsiq->q2.tag_code);
                   2832:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, val);
                   2833:        ASC_SET_CHIP_LRAM_DATA(iot, ioh, scsiq->q2.vm_id);
                   2834: }
                   2835:
                   2836:
                   2837: static int
                   2838: AscSgListToQueue(sg_list)
                   2839:        int             sg_list;
                   2840: {
                   2841:        int             n_sg_list_qs;
                   2842:
                   2843:        n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
                   2844:        if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
                   2845:                n_sg_list_qs++;
                   2846:
                   2847:        return (n_sg_list_qs + 1);
                   2848: }
                   2849:
                   2850:
                   2851: static u_int
                   2852: AscGetNumOfFreeQueue(sc, target_ix, n_qs)
                   2853:        ASC_SOFTC      *sc;
                   2854:        u_int8_t        target_ix;
                   2855:        u_int8_t        n_qs;
                   2856: {
                   2857:        u_int           cur_used_qs;
                   2858:        u_int           cur_free_qs;
                   2859:
                   2860:
                   2861:        if (n_qs == 1) {
                   2862:                cur_used_qs = sc->cur_total_qng +
                   2863:                        sc->last_q_shortage +
                   2864:                        ASC_MIN_FREE_Q;
                   2865:        } else {
                   2866:                cur_used_qs = sc->cur_total_qng + ASC_MIN_FREE_Q;
                   2867:        }
                   2868:
                   2869:        if ((cur_used_qs + n_qs) <= sc->max_total_qng) {
                   2870:                cur_free_qs = sc->max_total_qng - cur_used_qs;
                   2871:                return (cur_free_qs);
                   2872:        }
                   2873:        if (n_qs > 1)
                   2874:                if ((n_qs > sc->last_q_shortage) &&
                   2875:                    (n_qs <= (sc->max_total_qng - ASC_MIN_FREE_Q))) {
                   2876:                        sc->last_q_shortage = n_qs;
                   2877:                }
                   2878:        return (0);
                   2879: }
                   2880:
                   2881:
                   2882: static u_int8_t
                   2883: AscAllocFreeQueue(iot, ioh, free_q_head)
                   2884:        bus_space_tag_t iot;
                   2885:        bus_space_handle_t ioh;
                   2886:        u_int8_t        free_q_head;
                   2887: {
                   2888:        u_int16_t       q_addr;
                   2889:        u_int8_t        next_qp;
                   2890:        u_int8_t        q_status;
                   2891:
                   2892:
                   2893:        q_addr = ASC_QNO_TO_QADDR(free_q_head);
                   2894:        q_status = AscReadLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS);
                   2895:        next_qp = AscReadLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_FWD);
                   2896:        if (((q_status & ASC_QS_READY) == 0) && (next_qp != ASC_QLINK_END))
                   2897:                return (next_qp);
                   2898:
                   2899:        return (ASC_QLINK_END);
                   2900: }
                   2901:
                   2902:
                   2903: static u_int8_t
                   2904: AscAllocMultipleFreeQueue(iot, ioh, free_q_head, n_free_q)
                   2905:        bus_space_tag_t iot;
                   2906:        bus_space_handle_t ioh;
                   2907:        u_int8_t        free_q_head;
                   2908:        u_int8_t        n_free_q;
                   2909: {
                   2910:        u_int8_t        i;
                   2911:
                   2912:        for (i = 0; i < n_free_q; i++) {
                   2913:                free_q_head = AscAllocFreeQueue(iot, ioh, free_q_head);
                   2914:                if (free_q_head == ASC_QLINK_END)
                   2915:                        break;
                   2916:        }
                   2917:
                   2918:        return (free_q_head);
                   2919: }
                   2920:
                   2921:
                   2922: static int
                   2923: AscStopQueueExe(iot, ioh)
                   2924:        bus_space_tag_t iot;
                   2925:        bus_space_handle_t ioh;
                   2926: {
                   2927:        int             count = 0;
                   2928:
                   2929:        if (AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B) == 0) {
                   2930:                AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, ASC_STOP_REQ_RISC_STOP);
                   2931:                do {
                   2932:                        if (AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B) &
                   2933:                            ASC_STOP_ACK_RISC_STOP)
                   2934:                                return (1);
                   2935:
                   2936:                        DvcSleepMilliSecond(100);
                   2937:                } while (count++ < 20);
                   2938:        }
                   2939:        return (0);
                   2940: }
                   2941:
                   2942:
                   2943: static void
                   2944: AscStartQueueExe(iot, ioh)
                   2945:        bus_space_tag_t iot;
                   2946:        bus_space_handle_t ioh;
                   2947: {
                   2948:
                   2949:        if (AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B) != 0)
                   2950:                AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, 0);
                   2951: }
                   2952:
                   2953:
                   2954: static void
                   2955: AscCleanUpBusyQueue(iot, ioh)
                   2956:        bus_space_tag_t iot;
                   2957:        bus_space_handle_t ioh;
                   2958: {
                   2959:        int             count = 0;
                   2960:        u_int8_t        stop_code;
                   2961:
                   2962:
                   2963:        if (AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B) != 0) {
                   2964:                AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, ASC_STOP_CLEAN_UP_BUSY_Q);
                   2965:                do {
                   2966:                        stop_code = AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B);
                   2967:                        if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0)
                   2968:                                break;
                   2969:
                   2970:                        DvcSleepMilliSecond(100);
                   2971:                } while (count++ < 20);
                   2972:        }
                   2973: }
                   2974:
                   2975:
                   2976: static int
                   2977: _AscWaitQDone(iot, ioh, scsiq)
                   2978:        bus_space_tag_t iot;
                   2979:        bus_space_handle_t ioh;
                   2980:        ASC_SCSI_Q     *scsiq;
                   2981: {
                   2982:        u_int16_t       q_addr;
                   2983:        u_int8_t        q_status;
                   2984:        int             count = 0;
                   2985:
                   2986:        while (scsiq->q1.q_no == 0);
                   2987:
                   2988:        q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
                   2989:        do {
                   2990:                q_status = AscReadLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS);
                   2991:                DvcSleepMilliSecond(100L);
                   2992:                if (count++ > 30)
                   2993:                        return (0);
                   2994:
                   2995:        } while ((q_status & ASC_QS_READY) != 0);
                   2996:
                   2997:        return (1);
                   2998: }
                   2999:
                   3000:
                   3001: static int
                   3002: AscCleanUpDiscQueue(iot, ioh)
                   3003:        bus_space_tag_t iot;
                   3004:        bus_space_handle_t ioh;
                   3005: {
                   3006:        int             count;
                   3007:        u_int8_t        stop_code;
                   3008:
                   3009:        count = 0;
                   3010:        if (AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B) != 0) {
                   3011:                AscWriteLramByte(iot, ioh, ASCV_STOP_CODE_B, ASC_STOP_CLEAN_UP_DISC_Q);
                   3012:                do {
                   3013:                        stop_code = AscReadLramByte(iot, ioh, ASCV_STOP_CODE_B);
                   3014:                        if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0)
                   3015:                                break;
                   3016:
                   3017:                        DvcSleepMilliSecond(100);
                   3018:                } while (count++ < 20);
                   3019:        }
                   3020:        return (1);
                   3021: }
                   3022:
                   3023:
                   3024: /******************************************************************************/
                   3025: /*                           Abort and Reset CCB routines                     */
                   3026: /******************************************************************************/
                   3027:
                   3028:
                   3029: int
                   3030: AscAbortCCB(sc, ccb)
                   3031:        ASC_SOFTC      *sc;
                   3032:        u_int32_t       ccb;
                   3033: {
                   3034:        bus_space_tag_t iot = sc->sc_iot;
                   3035:        bus_space_handle_t ioh = sc->sc_ioh;
                   3036:        int             retval;
                   3037:        ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
                   3038:
                   3039:
                   3040:        retval = -1;
                   3041:        saved_unit_not_ready = sc->unit_not_ready;
                   3042:        sc->unit_not_ready = 0xFF;
                   3043:        AscWaitISRDone(sc);
                   3044:        if (AscStopQueueExe(iot, ioh) == 1) {
                   3045:                if (AscRiscHaltedAbortCCB(sc, ccb) == 1) {
                   3046:                        retval = 1;
                   3047:                        AscCleanUpBusyQueue(iot, ioh);
                   3048:                        AscStartQueueExe(iot, ioh);
                   3049:                } else {
                   3050:                        retval = 0;
                   3051:                        AscStartQueueExe(iot, ioh);
                   3052:                }
                   3053:        }
                   3054:        sc->unit_not_ready = saved_unit_not_ready;
                   3055:
                   3056:        return (retval);
                   3057: }
                   3058:
                   3059:
                   3060: static int
                   3061: AscRiscHaltedAbortCCB(sc, ccb)
                   3062:        ASC_SOFTC      *sc;
                   3063:        u_int32_t       ccb;
                   3064: {
                   3065:        bus_space_tag_t iot = sc->sc_iot;
                   3066:        bus_space_handle_t ioh = sc->sc_ioh;
                   3067:        u_int16_t       q_addr;
                   3068:        u_int8_t        q_no;
                   3069:        ASC_QDONE_INFO  scsiq_buf;
                   3070:        ASC_QDONE_INFO *scsiq;
                   3071:        ASC_ISR_CALLBACK asc_isr_callback;
                   3072:        int             last_int_level;
                   3073:
                   3074:
                   3075:        asc_isr_callback = (ASC_ISR_CALLBACK) sc->isr_callback;
                   3076:        last_int_level = DvcEnterCritical();
                   3077:        scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
                   3078:
                   3079:        for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= sc->max_total_qng; q_no++) {
                   3080:                q_addr = ASC_QNO_TO_QADDR(q_no);
                   3081:                scsiq->d2.ccb_ptr = AscReadLramDWord(iot, ioh,
                   3082:                                               q_addr + ASC_SCSIQ_D_CCBPTR);
                   3083:                if (scsiq->d2.ccb_ptr == ccb) {
                   3084:                        _AscCopyLramScsiDoneQ(iot, ioh, q_addr, scsiq, sc->max_dma_count);
                   3085:                        if (((scsiq->q_status & ASC_QS_READY) != 0)
                   3086:                            && ((scsiq->q_status & ASC_QS_ABORTED) == 0)
                   3087:                          && ((scsiq->cntl & ASC_QCSG_SG_XFER_LIST) == 0)) {
                   3088:                                scsiq->q_status |= ASC_QS_ABORTED;
                   3089:                                scsiq->d3.done_stat = ASC_QD_ABORTED_BY_HOST;
                   3090:                                AscWriteLramDWord(iot, ioh, q_addr + ASC_SCSIQ_D_CCBPTR, 0L);
                   3091:                                AscWriteLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS,
                   3092:                                                 scsiq->q_status);
                   3093:                                (*asc_isr_callback) (sc, scsiq);
                   3094:                                DvcLeaveCritical(last_int_level);
                   3095:                                return (1);
                   3096:                        }
                   3097:                }
                   3098:        }
                   3099:
                   3100:        DvcLeaveCritical(last_int_level);
                   3101:        return (0);
                   3102: }
                   3103:
                   3104:
                   3105: static int
                   3106: AscRiscHaltedAbortTIX(sc, target_ix)
                   3107:        ASC_SOFTC      *sc;
                   3108:        u_int8_t        target_ix;
                   3109: {
                   3110:        bus_space_tag_t iot = sc->sc_iot;
                   3111:        bus_space_handle_t ioh = sc->sc_ioh;
                   3112:        u_int16_t       q_addr;
                   3113:        u_int8_t        q_no;
                   3114:        ASC_QDONE_INFO  scsiq_buf;
                   3115:        ASC_QDONE_INFO *scsiq;
                   3116:        ASC_ISR_CALLBACK asc_isr_callback;
                   3117:        int             last_int_level;
                   3118:
                   3119:
                   3120:        asc_isr_callback = (ASC_ISR_CALLBACK) sc->isr_callback;
                   3121:        last_int_level = DvcEnterCritical();
                   3122:        scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
                   3123:        for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= sc->max_total_qng; q_no++) {
                   3124:                q_addr = ASC_QNO_TO_QADDR(q_no);
                   3125:                _AscCopyLramScsiDoneQ(iot, ioh, q_addr, scsiq, sc->max_dma_count);
                   3126:                if (((scsiq->q_status & ASC_QS_READY) != 0) &&
                   3127:                    ((scsiq->q_status & ASC_QS_ABORTED) == 0) &&
                   3128:                    ((scsiq->cntl & ASC_QCSG_SG_XFER_LIST) == 0)) {
                   3129:                        if (scsiq->d2.target_ix == target_ix) {
                   3130:                                scsiq->q_status |= ASC_QS_ABORTED;
                   3131:                                scsiq->d3.done_stat = ASC_QD_ABORTED_BY_HOST;
                   3132:                                AscWriteLramDWord(iot, ioh, q_addr + ASC_SCSIQ_D_CCBPTR, 0L);
                   3133:                                AscWriteLramByte(iot, ioh, q_addr + ASC_SCSIQ_B_STATUS,
                   3134:                                                 scsiq->q_status);
                   3135:                                (*asc_isr_callback) (sc, scsiq);
                   3136:                        }
                   3137:                }
                   3138:        }
                   3139:        DvcLeaveCritical(last_int_level);
                   3140:        return (1);
                   3141: }
                   3142:
                   3143:
                   3144: /*
                   3145:  * AscResetDevice calls _AscWaitQDone which requires interrupt enabled,
                   3146:  * so we cannot use this function with the actual NetBSD SCSI layer
                   3147:  * because at boot time interrupts are disabled.
                   3148:  */
                   3149: int
                   3150: AscResetDevice(sc, target_ix)
                   3151:        ASC_SOFTC      *sc;
                   3152:        u_char          target_ix;
                   3153: {
                   3154:        bus_space_tag_t iot = sc->sc_iot;
                   3155:        bus_space_handle_t ioh = sc->sc_ioh;
                   3156:        int             retval;
                   3157:        u_int8_t        tid_no;
                   3158:        ASC_SCSI_BIT_ID_TYPE target_id;
                   3159:        int             i;
                   3160:        ASC_SCSI_REQ_Q  scsiq_buf;
                   3161:        ASC_SCSI_REQ_Q *scsiq;
                   3162:        u_int8_t       *buf;
                   3163:        ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
                   3164:
                   3165:
                   3166:        tid_no = ASC_TIX_TO_TID(target_ix);
                   3167:        target_id = ASC_TID_TO_TARGET_ID(tid_no);
                   3168:        saved_unit_not_ready = sc->unit_not_ready;
                   3169:        sc->unit_not_ready = target_id;
                   3170:        retval = ASC_ERROR;
                   3171:
                   3172:        AscWaitTixISRDone(sc, target_ix);
                   3173:
                   3174:        if (AscStopQueueExe(iot, ioh) == 1) {
                   3175:                if (AscRiscHaltedAbortTIX(sc, target_ix) == 1) {
                   3176:                        AscCleanUpBusyQueue(iot, ioh);
                   3177:                        AscStartQueueExe(iot, ioh);
                   3178:                        AscWaitTixISRDone(sc, target_ix);
                   3179:                        retval = ASC_NOERROR;
                   3180:                        scsiq = (ASC_SCSI_REQ_Q *) & scsiq_buf;
                   3181:                        buf = (u_char *) & scsiq_buf;
                   3182:                        for (i = 0; i < sizeof(ASC_SCSI_REQ_Q); i++)
                   3183:                                *buf++ = 0x00;
                   3184:                        scsiq->q1.status = (u_char) ASC_QS_READY;
                   3185:                        scsiq->q2.cdb_len = 6;
                   3186:                        scsiq->q2.tag_code = M2_QTAG_MSG_SIMPLE;
                   3187:                        scsiq->q1.target_id = target_id;
                   3188:                        scsiq->q2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0);
                   3189:                        scsiq->cdbptr = (u_int8_t *) scsiq->cdb;
                   3190:                        scsiq->q1.cntl = ASC_QC_NO_CALLBACK | ASC_QC_MSG_OUT | ASC_QC_URGENT;
                   3191:                        AscWriteLramByte(iot, ioh, ASCV_MSGOUT_BEG, M1_BUS_DVC_RESET);
                   3192:                        sc->unit_not_ready &= ~target_id;
                   3193:                        sc->sdtr_done |= target_id;
                   3194:                        if (AscExeScsiQueue(sc, (ASC_SCSI_Q *) scsiq) == ASC_NOERROR) {
                   3195:                                sc->unit_not_ready = target_id;
                   3196:                                DvcSleepMilliSecond(1000);
                   3197:                                _AscWaitQDone(iot, ioh, (ASC_SCSI_Q *) scsiq);
                   3198:                                if (AscStopQueueExe(iot, ioh) == ASC_NOERROR) {
                   3199:                                        AscCleanUpDiscQueue(iot, ioh);
                   3200:                                        AscStartQueueExe(iot, ioh);
                   3201:                                        if (sc->pci_fix_asyn_xfer & target_id)
                   3202:                                                AscSetRunChipSynRegAtID(iot, ioh, tid_no,
                   3203:                                                                ASYN_SDTR_DATA_FIX_PCI_REV_AB);
                   3204:                                        AscWaitTixISRDone(sc, target_ix);
                   3205:                                }
                   3206:                        } else
                   3207:                                retval = ASC_BUSY;
                   3208:                        sc->sdtr_done &= ~target_id;
                   3209:                } else {
                   3210:                        retval = ASC_ERROR;
                   3211:                        AscStartQueueExe(iot, ioh);
                   3212:                }
                   3213:        }
                   3214:        sc->unit_not_ready = saved_unit_not_ready;
                   3215:        return (retval);
                   3216: }
                   3217:
                   3218:
                   3219: int
                   3220: AscResetBus(sc)
                   3221:        ASC_SOFTC      *sc;
                   3222: {
                   3223:        bus_space_tag_t iot = sc->sc_iot;
                   3224:        bus_space_handle_t ioh = sc->sc_ioh;
                   3225:        int             retval;
                   3226:        int             i;
                   3227:
                   3228:
                   3229:        sc->unit_not_ready = 0xFF;
                   3230:        retval = ASC_NOERROR;
                   3231:
                   3232:        AscWaitISRDone(sc);
                   3233:        AscStopQueueExe(iot, ioh);
                   3234:        sc->sdtr_done = 0;
                   3235:        AscResetChipAndScsiBus(iot, ioh);
                   3236:        DvcSleepMilliSecond((u_long) ((u_int16_t) sc->scsi_reset_wait * 1000));
                   3237:        AscReInitLram(sc);
                   3238:        for (i = 0; i <= ASC_MAX_TID; i++) {
                   3239:                sc->cur_dvc_qng[i] = 0;
                   3240:                if (sc->pci_fix_asyn_xfer & (ASC_SCSI_BIT_ID_TYPE) (0x01 << i))
                   3241:                        AscSetChipSynRegAtID(iot, ioh, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB);
                   3242:        }
                   3243:
                   3244:        ASC_SET_PC_ADDR(iot, ioh, ASC_MCODE_START_ADDR);
                   3245:        if (ASC_GET_PC_ADDR(iot, ioh) != ASC_MCODE_START_ADDR)
                   3246:                retval = ASC_ERROR;
                   3247:
                   3248:        if (AscStartChip(iot, ioh) == 0)
                   3249:                retval = ASC_ERROR;
                   3250:
                   3251:        AscStartQueueExe(iot, ioh);
                   3252:        sc->unit_not_ready = 0;
                   3253:        sc->queue_full_or_busy = 0;
                   3254:        return (retval);
                   3255: }
                   3256:
                   3257:
                   3258: /******************************************************************************/
                   3259: /*                            Error Handling routines                         */
                   3260: /******************************************************************************/
                   3261:
                   3262:
                   3263: static int
                   3264: AscSetLibErrorCode(sc, err_code)
                   3265:        ASC_SOFTC      *sc;
                   3266:        u_int16_t       err_code;
                   3267: {
                   3268:        /*
                   3269:         * if(sc->err_code == 0) { sc->err_code = err_code;
                   3270:         */ AscWriteLramWord(sc->sc_iot, sc->sc_ioh, ASCV_ASCDVC_ERR_CODE_W,
                   3271:                               err_code);
                   3272:        /*
                   3273:         * }
                   3274:         */
                   3275:        return (err_code);
                   3276: }
                   3277:
                   3278:
                   3279: /******************************************************************************/
                   3280: /*                            Handle bugged borads routines                   */
                   3281: /******************************************************************************/
                   3282:
                   3283:
                   3284: void
                   3285: AscInquiryHandling(sc, tid_no, inq)
                   3286:        ASC_SOFTC      *sc;
                   3287:        u_int8_t        tid_no;
                   3288:        ASC_SCSI_INQUIRY *inq;
                   3289: {
                   3290:        bus_space_tag_t iot = sc->sc_iot;
                   3291:        bus_space_handle_t ioh = sc->sc_ioh;
                   3292:        ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
                   3293:        ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
                   3294:
                   3295:
                   3296:        orig_init_sdtr = sc->init_sdtr;
                   3297:        orig_use_tagged_qng = sc->use_tagged_qng;
                   3298:
                   3299:        sc->init_sdtr &= ~tid_bit;
                   3300:        sc->can_tagged_qng &= ~tid_bit;
                   3301:        sc->use_tagged_qng &= ~tid_bit;
                   3302:
                   3303:        if (inq->byte3.rsp_data_fmt >= 2 || inq->byte2.ansi_apr_ver >= 2) {
                   3304:                if ((sc->sdtr_enable & tid_bit) && inq->byte7.Sync)
                   3305:                        sc->init_sdtr |= tid_bit;
                   3306:
                   3307:                if ((sc->cmd_qng_enabled & tid_bit) && inq->byte7.CmdQue)
                   3308:                        if (AscTagQueuingSafe(inq)) {
                   3309:                                sc->use_tagged_qng |= tid_bit;
                   3310:                                sc->can_tagged_qng |= tid_bit;
                   3311:                        }
                   3312:        }
                   3313:        if (orig_use_tagged_qng != sc->use_tagged_qng) {
                   3314:                AscWriteLramByte(iot, ioh, ASCV_DISC_ENABLE_B,
                   3315:                                 sc->disc_enable);
                   3316:                AscWriteLramByte(iot, ioh, ASCV_USE_TAGGED_QNG_B,
                   3317:                                 sc->use_tagged_qng);
                   3318:                AscWriteLramByte(iot, ioh, ASCV_CAN_TAGGED_QNG_B,
                   3319:                                 sc->can_tagged_qng);
                   3320:
                   3321:                sc->max_dvc_qng[tid_no] =
                   3322:                        sc->max_tag_qng[tid_no];
                   3323:                AscWriteLramByte(iot, ioh, ASCV_MAX_DVC_QNG_BEG + tid_no,
                   3324:                                 sc->max_dvc_qng[tid_no]);
                   3325:        }
                   3326:        if (orig_init_sdtr != sc->init_sdtr)
                   3327:                AscAsyncFix(sc, tid_no, inq);
                   3328: }
                   3329:
                   3330:
                   3331: static int
                   3332: AscTagQueuingSafe(inq)
                   3333:        ASC_SCSI_INQUIRY *inq;
                   3334: {
                   3335:        if ((inq->add_len >= 32) &&
                   3336:            (AscCompareString(inq->vendor_id, "QUANTUM XP34301", 15) == 0) &&
                   3337:            (AscCompareString(inq->product_rev_level, "1071", 4) == 0)) {
                   3338:                return 0;
                   3339:        }
                   3340:        return 1;
                   3341: }
                   3342:
                   3343:
                   3344: static void
                   3345: AscAsyncFix(sc, tid_no, inq)
                   3346:        ASC_SOFTC      *sc;
                   3347:        u_int8_t        tid_no;
                   3348:        ASC_SCSI_INQUIRY *inq;
                   3349: {
                   3350:        u_int8_t        dvc_type;
                   3351:        ASC_SCSI_BIT_ID_TYPE tid_bits;
                   3352:
                   3353:
                   3354:        dvc_type = inq->byte0.peri_dvc_type;
                   3355:        tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
                   3356:
                   3357:        if (sc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
                   3358:                if (!(sc->init_sdtr & tid_bits)) {
                   3359:                        if ((dvc_type == SCSI_TYPE_CDROM) &&
                   3360:                        (AscCompareString(inq->vendor_id, "HP ", 3) == 0)) {
                   3361:                                sc->pci_fix_asyn_xfer_always |= tid_bits;
                   3362:                        }
                   3363:                        sc->pci_fix_asyn_xfer |= tid_bits;
                   3364:                        if ((dvc_type == SCSI_TYPE_PROC) ||
                   3365:                            (dvc_type == SCSI_TYPE_SCANNER)) {
                   3366:                                sc->pci_fix_asyn_xfer &= ~tid_bits;
                   3367:                        }
                   3368:                        if ((dvc_type == SCSI_TYPE_SASD) &&
                   3369:                            (AscCompareString(inq->vendor_id, "TANDBERG", 8) == 0) &&
                   3370:                            (AscCompareString(inq->product_id, " TDC 36", 7) == 0)) {
                   3371:                                sc->pci_fix_asyn_xfer &= ~tid_bits;
                   3372:                        }
                   3373:                        if ((dvc_type == SCSI_TYPE_SASD) &&
                   3374:                            (AscCompareString(inq->vendor_id, "WANGTEK ", 8) == 0)) {
                   3375:                                sc->pci_fix_asyn_xfer &= ~tid_bits;
                   3376:                        }
                   3377:                        if ((dvc_type == SCSI_TYPE_CDROM) &&
                   3378:                            (AscCompareString(inq->vendor_id, "NEC       ", 8) == 0) &&
                   3379:                            (AscCompareString(inq->product_id, "CD-ROM DRIVE    ", 16) == 0)) {
                   3380:                                sc->pci_fix_asyn_xfer &= ~tid_bits;
                   3381:                        }
                   3382:                        if ((dvc_type == SCSI_TYPE_CDROM) &&
                   3383:                            (AscCompareString(inq->vendor_id, "YAMAHA", 6) == 0) &&
                   3384:                            (AscCompareString(inq->product_id, "CDR400", 6) == 0)) {
                   3385:                                sc->pci_fix_asyn_xfer &= ~tid_bits;
                   3386:                        }
                   3387:                        if (sc->pci_fix_asyn_xfer & tid_bits) {
                   3388:                                AscSetRunChipSynRegAtID(sc->sc_iot, sc->sc_ioh, tid_no,
                   3389:                                             ASYN_SDTR_DATA_FIX_PCI_REV_AB);
                   3390:                        }
                   3391:                }
                   3392:        }
                   3393: }
                   3394:
                   3395:
                   3396: /******************************************************************************/
                   3397: /*                              Miscellaneous routines                        */
                   3398: /******************************************************************************/
                   3399:
                   3400:
                   3401: static int
                   3402: AscCompareString(str1, str2, len)
                   3403:        u_char         *str1;
                   3404:        u_char         *str2;
                   3405:        int             len;
                   3406: {
                   3407:        int             i;
                   3408:        int             diff;
                   3409:
                   3410:        for (i = 0; i < len; i++) {
                   3411:                diff = (int) (str1[i] - str2[i]);
                   3412:                if (diff != 0)
                   3413:                        return (diff);
                   3414:        }
                   3415:
                   3416:        return (0);
                   3417: }
                   3418:
                   3419:
                   3420: /******************************************************************************/
                   3421: /*                            Device oriented routines                        */
                   3422: /******************************************************************************/
                   3423:
                   3424:
                   3425: static int
                   3426: DvcEnterCritical(void)
                   3427: {
                   3428:        int             s;
                   3429:
                   3430:        s = splbio();
                   3431:        return (s);
                   3432: }
                   3433:
                   3434:
                   3435: static void
                   3436: DvcLeaveCritical(s)
                   3437:        int             s;
                   3438: {
                   3439:
                   3440:        splx(s);
                   3441: }
                   3442:
                   3443:
                   3444: static void
                   3445: DvcSleepMilliSecond(n)
                   3446:        u_int32_t       n;
                   3447: {
                   3448:
                   3449:        DELAY(n * 1000);
                   3450: }
                   3451:
                   3452: #ifdef UNUSED
                   3453: static void
                   3454: DvcDelayMicroSecond(n)
                   3455:        u_int32_t       n;
                   3456: {
                   3457:
                   3458:        DELAY(n);
                   3459: }
                   3460: #endif
                   3461:
                   3462: static void
                   3463: DvcDelayNanoSecond(n)
                   3464:        u_int32_t       n;
                   3465: {
                   3466:
                   3467:        DELAY((n + 999) / 1000);
                   3468: }

CVSweb