The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/advlib.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 6594431cf535c91252adea98ae520801


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.