root/dev/ic/advlib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. AscInitASC_SOFTC
  2. AscInitFromEEP
  3. AscInitFromASC_SOFTC
  4. AscInitDriver
  5. AscFindSignature
  6. AscInitLram
  7. AscReInitLram
  8. AscInitQLinkVar
  9. AscResetChipAndScsiBus
  10. AscGetChipBusType
  11. AscSetBank
  12. AscStartChip
  13. AscStopChip
  14. AscGetChipVersion
  15. AscSetChipScsiID
  16. AscGetChipScsiCtrl
  17. AscSetRunChipSynRegAtID
  18. AscSetChipSynRegAtID
  19. AscHostReqRiscHalt
  20. AscIsChipHalted
  21. AscSetChipIH
  22. AscReadLramByte
  23. AscWriteLramByte
  24. AscReadLramWord
  25. AscWriteLramWord
  26. AscReadLramDWord
  27. AscWriteLramDWord
  28. AscMemWordSetLram
  29. AscMemWordCopyToLram
  30. AscMemWordCopyFromLram
  31. AscMemDWordCopyToLram
  32. AscMemSumLramWord
  33. AscTestExternalLram
  34. AscInitMicroCodeVar
  35. AscLoadMicroCode
  36. AscGetOnePhyAddr
  37. AscGetSGList
  38. AscWriteEEPCmdReg
  39. AscWriteEEPDataReg
  40. AscWaitEEPRead
  41. AscWaitEEPWrite
  42. AscReadEEPWord
  43. AscWriteEEPWord
  44. AscGetEEPConfig
  45. AscSetEEPConfig
  46. AscSetEEPConfigOnce
  47. AscPrintEEPConfig
  48. AscISR
  49. AscIsrQDone
  50. AscIsrChipHalted
  51. AscWaitTixISRDone
  52. AscWaitISRDone
  53. _AscCopyLramScsiDoneQ
  54. AscGetQDoneInfo
  55. AscToggleIRQAct
  56. AscDisableInterrupt
  57. AscEnableInterrupt
  58. AscGetChipIRQ
  59. AscSetChipIRQ
  60. AscAckInterrupt
  61. AscGetMaxDmaCount
  62. AscGetIsaDmaChannel
  63. AscSetIsaDmaChannel
  64. AscGetIsaDmaSpeed
  65. AscSetIsaDmaSpeed
  66. AscHandleExtMsgIn
  67. AscMsgOutSDTR
  68. AscSetChipSDTR
  69. AscCalSDTRData
  70. AscGetSynPeriodIndex
  71. AscExeScsiQueue
  72. AscSendScsiQueue
  73. AscPutReadySgListQueue
  74. AscPutReadyQueue
  75. AscPutSCSIQ
  76. AscSgListToQueue
  77. AscGetNumOfFreeQueue
  78. AscAllocFreeQueue
  79. AscAllocMultipleFreeQueue
  80. AscStopQueueExe
  81. AscStartQueueExe
  82. AscCleanUpBusyQueue
  83. _AscWaitQDone
  84. AscCleanUpDiscQueue
  85. AscAbortCCB
  86. AscRiscHaltedAbortCCB
  87. AscRiscHaltedAbortTIX
  88. AscResetDevice
  89. AscResetBus
  90. AscSetLibErrorCode
  91. AscInquiryHandling
  92. AscTagQueuingSafe
  93. AscAsyncFix
  94. AscCompareString
  95. DvcEnterCritical
  96. DvcLeaveCritical
  97. DvcSleepMilliSecond
  98. DvcDelayMicroSecond
  99. DvcDelayNanoSecond

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

/* [<][>][^][v][top][bottom][index][help] */