adwlib.c revision 40024
1/* 2 * Low level routines for Second Generation 3 * Advanced Systems Inc. SCSI controllers chips 4 * 5 * Copyright (c) 1998 Justin Gibbs. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions, and the following disclaimer, 13 * without modification, immediately at the beginning of the file. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $Id$ 33 */ 34/* 35 * Ported from: 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#include <sys/queue.h> 47#include <sys/systm.h> 48 49#include <machine/bus_pio.h> 50#include <machine/bus_memio.h> 51#include <machine/bus.h> 52#include <machine/clock.h> 53 54#include <cam/cam.h> 55#include <cam/scsi/scsi_all.h> 56 57#include <dev/advansys/adwlib.h> 58 59struct adw_eeprom adw_default_eeprom = { 60 ADW_EEPROM_BIOS_ENABLE, /* cfg_lsw */ 61 0x0000, /* cfg_msw */ 62 0xFFFF, /* disc_enable */ 63 0xFFFF, /* wdtr_able */ 64 0xFFFF, /* sdtr_able */ 65 0xFFFF, /* start_motor */ 66 0xFFFF, /* tagqng_able */ 67 0xFFFF, /* bios_scan */ 68 0, /* scam_tolerant */ 69 7, /* adapter_scsi_id */ 70 0, /* bios_boot_delay */ 71 3, /* scsi_reset_delay */ 72 0, /* bios_id_lun */ 73 0, /* termination */ 74 0, /* reserved1 */ 75 { /* Bios Ctrl */ 76 1, 1, 1, 1, 1, 77 1, 1, 1, 1, 1, 78 }, 79 0xFFFF, /* ultra_able */ 80 0, /* reserved2 */ 81 ADW_DEF_MAX_HOST_QNG, /* max_host_qng */ 82 ADW_DEF_MAX_DVC_QNG, /* max_dvc_qng */ 83 0, /* dvc_cntl */ 84 0, /* bug_fix */ 85 { 0, 0, 0 }, /* serial_number */ 86 0, /* check_sum */ 87 { /* oem_name[16] */ 88 0, 0, 0, 0, 0, 0, 0, 0, 89 0, 0, 0, 0, 0, 0, 0, 0 90 }, 91 0, /* dvc_err_code */ 92 0, /* adv_err_code */ 93 0, /* adv_err_addr */ 94 0, /* saved_dvc_err_code */ 95 0, /* saved_adv_err_code */ 96 0, /* saved_adv_err_addr */ 97 0 /* num_of_err */ 98}; 99 100static u_int16_t adw_eeprom_read_16(struct adw_softc *adw, int addr); 101static void adw_eeprom_write_16(struct adw_softc *adw, int addr, 102 u_int data); 103static void adw_eeprom_wait(struct adw_softc *adw); 104 105int 106adw_find_signature(bus_space_tag_t tag, bus_space_handle_t bsh) 107{ 108 if (bus_space_read_1(tag, bsh, ADW_SIGNATURE_BYTE) == ADW_CHIP_ID_BYTE 109 && bus_space_read_2(tag, bsh, ADW_SIGNATURE_WORD) == ADW_CHIP_ID_WORD) 110 return (1); 111 return (0); 112} 113 114/* 115 * Reset Chip. 116 */ 117void 118adw_reset_chip(struct adw_softc *adw) 119{ 120 adw_outw(adw, ADW_CTRL_REG, ADW_CTRL_REG_CMD_RESET); 121 DELAY(100); 122 adw_outw(adw, ADW_CTRL_REG, ADW_CTRL_REG_CMD_WR_IO_REG); 123 124 /* 125 * Initialize Chip registers. 126 */ 127 adw_outb(adw, ADW_MEM_CFG, 128 adw_inb(adw, ADW_MEM_CFG) | ADW_MEM_CFG_RAM_SZ_8KB); 129 130 adw_outw(adw, ADW_SCSI_CFG1, 131 adw_inw(adw, ADW_SCSI_CFG1) & ~ADW_SCSI_CFG1_BIG_ENDIAN); 132 133 /* 134 * Setting the START_CTL_EM_FU 3:2 bits sets a FIFO threshold 135 * of 128 bytes. This register is only accessible to the host. 136 */ 137 adw_outb(adw, ADW_DMA_CFG0, 138 ADW_DMA_CFG0_START_CTL_EM_FU|ADW_DMA_CFG0_READ_CMD_MRM); 139} 140 141/* 142 * Read the specified EEPROM location 143 */ 144static u_int16_t 145adw_eeprom_read_16(struct adw_softc *adw, int addr) 146{ 147 adw_outw(adw, ADW_EEP_CMD, ADW_EEP_CMD_READ | addr); 148 adw_eeprom_wait(adw); 149 return (adw_inw(adw, ADW_EEP_DATA)); 150} 151 152static void 153adw_eeprom_write_16(struct adw_softc *adw, int addr, u_int data) 154{ 155 adw_outw(adw, ADW_EEP_DATA, data); 156 adw_outw(adw, ADW_EEP_CMD, ADW_EEP_CMD_WRITE | addr); 157 adw_eeprom_wait(adw); 158} 159 160/* 161 * Wait for and EEPROM command to complete 162 */ 163static void 164adw_eeprom_wait(struct adw_softc *adw) 165{ 166 int i; 167 168 for (i = 0; i < ADW_EEP_DELAY_MS; i++) { 169 if ((adw_inw(adw, ADW_EEP_CMD) & ADW_EEP_CMD_DONE) != 0) 170 break; 171 DELAY(1000); 172 } 173 if (i == ADW_EEP_DELAY_MS) 174 panic("%s: Timedout Reading EEPROM", adw_name(adw)); 175} 176 177/* 178 * Read EEPROM configuration into the specified buffer. 179 * 180 * Return a checksum based on the EEPROM configuration read. 181 */ 182u_int16_t 183adw_eeprom_read(struct adw_softc *adw, struct adw_eeprom *eep_buf) 184{ 185 u_int16_t *wbuf; 186 u_int16_t wval; 187 u_int16_t chksum; 188 int eep_addr; 189 190 wbuf = (u_int16_t *)eep_buf; 191 chksum = 0; 192 193 for (eep_addr = ADW_EEP_DVC_CFG_BEGIN; 194 eep_addr < ADW_EEP_DVC_CFG_END; 195 eep_addr++, wbuf++) { 196 wval = adw_eeprom_read_16(adw, eep_addr); 197 chksum += wval; 198 *wbuf = wval; 199 } 200 201 /* checksum field is not counted in the checksum */ 202 *wbuf = adw_eeprom_read_16(adw, eep_addr); 203 wbuf++; 204 205 /* Driver seeprom variables are not included in the checksum */ 206 for (eep_addr = ADW_EEP_DVC_CTL_BEGIN; 207 eep_addr < ADW_EEP_MAX_WORD_ADDR; 208 eep_addr++, wbuf++) 209 *wbuf = adw_eeprom_read_16(adw, eep_addr); 210 211 return (chksum); 212} 213 214void 215adw_eeprom_write(struct adw_softc *adw, struct adw_eeprom *eep_buf) 216{ 217 u_int16_t *wbuf; 218 u_int16_t addr; 219 u_int16_t chksum; 220 221 wbuf = (u_int16_t *)eep_buf; 222 chksum = 0; 223 224 adw_outw(adw, ADW_EEP_CMD, ADW_EEP_CMD_WRITE_ABLE); 225 adw_eeprom_wait(adw); 226 227 /* 228 * Write EEPROM until checksum. 229 */ 230 for (addr = ADW_EEP_DVC_CFG_BEGIN; 231 addr < ADW_EEP_DVC_CFG_END; addr++, wbuf++) { 232 chksum += *wbuf; 233 adw_eeprom_write_16(adw, addr, *wbuf); 234 } 235 236 /* 237 * Write calculated EEPROM checksum 238 */ 239 adw_eeprom_write_16(adw, addr, chksum); 240 241 /* skip over buffer's checksum */ 242 wbuf++; 243 244 /* 245 * Write the rest. 246 */ 247 for (addr = ADW_EEP_DVC_CTL_BEGIN; 248 addr < ADW_EEP_MAX_WORD_ADDR; addr++, wbuf++) 249 adw_eeprom_write_16(adw, addr, *wbuf); 250 251 adw_outw(adw, ADW_EEP_CMD, ADW_EEP_CMD_WRITE_DISABLE); 252 adw_eeprom_wait(adw); 253} 254 255int 256adw_init_chip(struct adw_softc *adw, u_int term_scsicfg1) 257{ 258 u_int8_t biosmem[ADW_MC_BIOSLEN]; 259 u_int16_t *mcodebuf; 260 u_int addr; 261 u_int end_addr; 262 u_int checksum; 263 u_int scsicfg1; 264 u_int i; 265 266 /* 267 * Save the RISC memory BIOS region before writing the microcode. 268 * The BIOS may already be loaded and using its RISC LRAM region 269 * so its region must be saved and restored. 270 */ 271 for (addr = 0; addr < ADW_MC_BIOSLEN; addr++) 272 biosmem[addr] = adw_lram_read_8(adw, ADW_MC_BIOSMEM + addr); 273 274 /* 275 * Load the Microcode. Casting here was less work than 276 * reformatting the supplied microcode into an array of 277 * 16bit values... 278 */ 279 mcodebuf = (u_int16_t *)adw_mcode; 280 adw_outw(adw, ADW_RAM_ADDR, 0); 281 for (addr = 0; addr < adw_mcode_size/2; addr++) 282 adw_outw(adw, ADW_RAM_DATA, mcodebuf[addr]); 283 284 /* 285 * Clear the rest of LRAM. 286 */ 287 for (; addr < ADW_CONDOR_MEMSIZE/2; addr++) 288 adw_outw(adw, ADW_RAM_DATA, 0); 289 290 /* 291 * Verify the microcode checksum. 292 */ 293 checksum = 0; 294 adw_outw(adw, ADW_RAM_ADDR, 0); 295 for (addr = 0; addr < adw_mcode_size/2; addr++) 296 checksum += adw_inw(adw, ADW_RAM_DATA); 297 298 if (checksum != adw_mcode_chksum) { 299 printf("%s: Firmware load failed!\n", adw_name(adw)); 300 return (-1); 301 } 302 303 /* 304 * Restore the RISC memory BIOS region. 305 */ 306 for (addr = 0; addr < ADW_MC_BIOSLEN; addr++) 307 adw_lram_write_8(adw, addr + ADW_MC_BIOSLEN, biosmem[addr]); 308 309 /* 310 * Calculate and write the microcode code checksum to 311 * the microcode code checksum location. 312 */ 313 addr = adw_lram_read_16(adw, ADW_MC_CODE_BEGIN_ADDR) / 2; 314 end_addr = adw_lram_read_16(adw, ADW_MC_CODE_END_ADDR) / 2; 315 checksum = 0; 316 for (; addr < end_addr; addr++) 317 checksum += mcodebuf[addr]; 318 adw_lram_write_16(adw, ADW_MC_CODE_CHK_SUM, checksum); 319 320 /* 321 * Initialize microcode operating variables 322 */ 323 adw_lram_write_16(adw, ADW_MC_ADAPTER_SCSI_ID, adw->initiator_id); 324 325 /* 326 * Leave WDTR and SDTR negotiation disabled until the XPT has 327 * informed us of device capabilities, but do set the ultra mask 328 * in case we receive an SDTR request from the target before we 329 * negotiate. We turn on tagged queuing at the microcode level 330 * for all devices, and modulate this on a per command basis. 331 */ 332 adw_lram_write_16(adw, ADW_MC_ULTRA_ABLE, adw->user_ultra); 333 adw_lram_write_16(adw, ADW_MC_DISC_ENABLE, adw->user_discenb); 334 adw_lram_write_16(adw, ADW_MC_TAGQNG_ABLE, ~0); 335 336 /* 337 * Set SCSI_CFG0 Microcode Default Value. 338 * 339 * The microcode will set the SCSI_CFG0 register using this value 340 * after it is started. 341 */ 342 adw_lram_write_16(adw, ADW_MC_DEFAULT_SCSI_CFG0, 343 ADW_SCSI_CFG0_PARITY_EN|ADW_SCSI_CFG0_SEL_TMO_LONG| 344 ADW_SCSI_CFG0_OUR_ID_EN|adw->initiator_id); 345 346 /* 347 * Determine SCSI_CFG1 Microcode Default Value. 348 * 349 * The microcode will set the SCSI_CFG1 register using this value 350 * after it is started below. 351 */ 352 scsicfg1 = adw_inw(adw, ADW_SCSI_CFG1); 353 354 /* 355 * If all three connectors are in use, return an error. 356 */ 357 if ((scsicfg1 & ADW_SCSI_CFG1_ILLEGAL_CABLE_CONF_A_MASK) == 0 358 || (scsicfg1 & ADW_SCSI_CFG1_ILLEGAL_CABLE_CONF_B_MASK) == 0) { 359 printf("%s: Illegal Cable Config!\n", adw_name(adw)); 360 printf("%s: Only Two Ports may be used at a time!\n", 361 adw_name(adw)); 362 return (-1); 363 } 364 365 /* 366 * If the internal narrow cable is reversed all of the SCSI_CTRL 367 * register signals will be set. Check for and return an error if 368 * this condition is found. 369 */ 370 if ((adw_inw(adw, ADW_SCSI_CTRL) & 0x3F07) == 0x3F07) { 371 printf("%s: Illegal Cable Config!\n", adw_name(adw)); 372 printf("%s: Internal cable is reversed!\n", adw_name(adw)); 373 return (-1); 374 } 375 376 /* 377 * If this is a differential board and a single-ended device 378 * is attached to one of the connectors, return an error. 379 */ 380 if ((scsicfg1 & ADW_SCSI_CFG1_DIFF_MODE) != 0 381 && (scsicfg1 & ADW_SCSI_CFG1_DIFF_SENSE) == 0) { 382 printf("%s: A Single Ended Device is attached to our " 383 "differential bus!\n", adw_name(adw)); 384 return (-1); 385 } 386 387 /* 388 * Perform automatic termination control if desired. 389 */ 390 if (term_scsicfg1 == 0) { 391 switch(scsicfg1 & ADW_SCSI_CFG1_CABLE_DETECT) { 392 case (ADW_SCSI_CFG1_INT16_MASK|ADW_SCSI_CFG1_INT8_MASK): 393 case (ADW_SCSI_CFG1_INT16_MASK| 394 ADW_SCSI_CFG1_INT8_MASK|ADW_SCSI_CFG1_EXT8_MASK): 395 case (ADW_SCSI_CFG1_INT16_MASK| 396 ADW_SCSI_CFG1_INT8_MASK|ADW_SCSI_CFG1_EXT16_MASK): 397 case (ADW_SCSI_CFG1_INT16_MASK| 398 ADW_SCSI_CFG1_EXT8_MASK|ADW_SCSI_CFG1_EXT16_MASK): 399 case (ADW_SCSI_CFG1_INT8_MASK| 400 ADW_SCSI_CFG1_EXT8_MASK|ADW_SCSI_CFG1_EXT16_MASK): 401 case (ADW_SCSI_CFG1_INT16_MASK|ADW_SCSI_CFG1_INT8_MASK| 402 ADW_SCSI_CFG1_EXT8_MASK|ADW_SCSI_CFG1_EXT16_MASK): 403 /* Two out of three cables missing. Both on. */ 404 term_scsicfg1 |= ADW_SCSI_CFG1_TERM_CTL_L 405 | ADW_SCSI_CFG1_TERM_CTL_H; 406 break; 407 case (ADW_SCSI_CFG1_INT16_MASK): 408 case (ADW_SCSI_CFG1_INT16_MASK|ADW_SCSI_CFG1_EXT8_MASK): 409 case (ADW_SCSI_CFG1_INT16_MASK|ADW_SCSI_CFG1_EXT16_MASK): 410 case (ADW_SCSI_CFG1_INT8_MASK|ADW_SCSI_CFG1_EXT16_MASK): 411 case (ADW_SCSI_CFG1_EXT8_MASK|ADW_SCSI_CFG1_EXT16_MASK): 412 /* No two 16bit cables present. High on. */ 413 term_scsicfg1 |= ADW_SCSI_CFG1_TERM_CTL_H; 414 break; 415 case (ADW_SCSI_CFG1_INT8_MASK): 416 case (ADW_SCSI_CFG1_INT8_MASK|ADW_SCSI_CFG1_EXT8_MASK): 417 /* Wide -> Wide or Narrow -> Wide. Both off */ 418 break; 419 } 420 } 421 422 /* Tell the user about our decission */ 423 switch (term_scsicfg1 & ADW_SCSI_CFG1_TERM_CTL_MASK) { 424 case ADW_SCSI_CFG1_TERM_CTL_MASK: 425 printf("High & Low Termination Enabled, "); 426 break; 427 case ADW_SCSI_CFG1_TERM_CTL_H: 428 printf("High Termination Enabled, "); 429 break; 430 case ADW_SCSI_CFG1_TERM_CTL_L: 431 printf("Low Termination Enabled, "); 432 break; 433 default: 434 break; 435 } 436 437 /* 438 * Invert the TERM_CTL_H and TERM_CTL_L bits and then 439 * set 'scsicfg1'. The TERM_POL bit does not need to be 440 * referenced, because the hardware internally inverts 441 * the Termination High and Low bits if TERM_POL is set. 442 */ 443 term_scsicfg1 = ~term_scsicfg1 & ADW_SCSI_CFG1_TERM_CTL_MASK; 444 scsicfg1 &= ~ADW_SCSI_CFG1_TERM_CTL_MASK; 445 scsicfg1 |= term_scsicfg1 | ADW_SCSI_CFG1_TERM_CTL_MANUAL; 446 447 /* 448 * Set SCSI_CFG1 Microcode Default Value 449 * 450 * Set filter value and possibly modified termination control 451 * bits in the Microcode SCSI_CFG1 Register Value. 452 * 453 * The microcode will set the SCSI_CFG1 register using this value 454 * after it is started below. 455 */ 456 adw_lram_write_16(adw, ADW_MC_DEFAULT_SCSI_CFG1, 457 scsicfg1 | ADW_SCSI_CFG1_FLTR_11_TO_20NS); 458 459 /* 460 * Only accept selections on our initiator target id. 461 * This may change in target mode scenarios... 462 */ 463 adw_lram_write_16(adw, ADW_MC_DEFAULT_SEL_MASK, 464 (0x01 << adw->initiator_id)); 465 466 /* 467 * Link all the RISC Queue Lists together in a doubly-linked 468 * NULL terminated list. 469 * 470 * Skip the NULL (0) queue which is not used. 471 */ 472 for (i = 1, addr = ADW_MC_RISC_Q_LIST_BASE + ADW_MC_RISC_Q_LIST_SIZE; 473 i < ADW_MC_RISC_Q_TOTAL_CNT; 474 i++, addr += ADW_MC_RISC_Q_LIST_SIZE) { 475 476 /* 477 * Set the current RISC Queue List's 478 * RQL_FWD and RQL_BWD pointers in a 479 * one word write and set the state 480 * (RQL_STATE) to free. 481 */ 482 adw_lram_write_16(adw, addr, ((i + 1) | ((i - 1) << 8))); 483 adw_lram_write_8(adw, addr + RQL_STATE, ADW_MC_QS_FREE); 484 } 485 486 /* 487 * Set the Host and RISC Queue List pointers. 488 * 489 * Both sets of pointers are initialized with the same values: 490 * ADW_MC_RISC_Q_FIRST(0x01) and ADW_MC_RISC_Q_LAST (0xFF). 491 */ 492 adw_lram_write_8(adw, ADW_MC_HOST_NEXT_READY, ADW_MC_RISC_Q_FIRST); 493 adw_lram_write_8(adw, ADW_MC_HOST_NEXT_DONE, ADW_MC_RISC_Q_LAST); 494 495 adw_lram_write_8(adw, ADW_MC_RISC_NEXT_READY, ADW_MC_RISC_Q_FIRST); 496 adw_lram_write_8(adw, ADW_MC_RISC_NEXT_DONE, ADW_MC_RISC_Q_LAST); 497 498 /* 499 * Set up the last RISC Queue List (255) with a NULL forward pointer. 500 */ 501 adw_lram_write_16(adw, addr, (ADW_MC_NULL_Q + ((i - 1) << 8))); 502 adw_lram_write_8(adw, addr + RQL_STATE, ADW_MC_QS_FREE); 503 504 adw_outb(adw, ADW_INTR_ENABLES, 505 ADW_INTR_ENABLE_HOST_INTR|ADW_INTR_ENABLE_GLOBAL_INTR); 506 507 adw_outw(adw, ADW_PC, adw_lram_read_16(adw, ADW_MC_CODE_BEGIN_ADDR)); 508 509 return (0); 510} 511 512/* 513 * Send an idle command to the chip and optionally wait for completion. 514 */ 515void 516adw_idle_cmd_send(struct adw_softc *adw, adw_idle_cmd_t cmd, u_int parameter) 517{ 518 int s; 519 520 adw->idle_command_cmp = 0; 521 522 s = splcam(); 523 524 if (adw->idle_cmd != ADW_IDLE_CMD_COMPLETED) 525 printf("%s: Warning! Overlapped Idle Commands Attempted\n", 526 adw_name(adw)); 527 adw->idle_cmd = cmd; 528 adw->idle_cmd_param = parameter; 529 530 /* 531 * Write the idle command value after the idle command parameter 532 * has been written to avoid a race condition. If the order is not 533 * followed, the microcode may process the idle command before the 534 * parameters have been written to LRAM. 535 */ 536 adw_lram_write_16(adw, ADW_MC_IDLE_PARA_STAT, parameter); 537 adw_lram_write_16(adw, ADW_MC_IDLE_CMD, cmd); 538 splx(s); 539} 540 541/* Wait for an idle command to complete */ 542adw_idle_cmd_status_t 543adw_idle_cmd_wait(struct adw_softc *adw) 544{ 545 u_int timeout; 546 adw_idle_cmd_status_t status; 547 int s; 548 549 /* Wait for up to 10 seconds for the command to complete */ 550 timeout = 10000; 551 while (--timeout) { 552 if (adw->idle_command_cmp != 0) 553 break; 554 DELAY(1000); 555 } 556 557 if (timeout == 0) 558 panic("%s: Idle Command Timed Out!\n", adw_name(adw)); 559 s = splcam(); 560 status = adw_lram_read_16(adw, ADW_MC_IDLE_PARA_STAT); 561 splx(s); 562 return (status); 563} 564