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