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