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