[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     ! 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