1 /* 2 * Low level routines for the Advanced Systems Inc. SCSI controllers chips 3 * 4 * Copyright (c) 1996-1997, 1999-2000 Justin Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification, immediately at the beginning of the file. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * $FreeBSD: src/sys/dev/advansys/advlib.c,v 1.15.2.1 2000/04/14 13:32:49 nyan Exp $ 32 */ 33 /* 34 * Ported from: 35 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters 36 * 37 * Copyright (c) 1995-1996 Advanced System Products, Inc. 38 * All Rights Reserved. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that redistributions of source 42 * code retain the above copyright notice and this comment without 43 * modification. 44 */ 45 46 #include <sys/param.h> 47 #include <sys/kernel.h> 48 #include <sys/systm.h> 49 #include <sys/thread2.h> 50 #include <sys/bus.h> 51 #include <sys/rman.h> 52 53 #include <machine/clock.h> 54 55 #include <bus/cam/cam.h> 56 #include <bus/cam/cam_ccb.h> 57 #include <bus/cam/cam_sim.h> 58 #include <bus/cam/cam_xpt_sim.h> 59 60 #include <bus/cam/scsi/scsi_all.h> 61 #include <bus/cam/scsi/scsi_message.h> 62 #include <bus/cam/scsi/scsi_da.h> 63 #include <bus/cam/scsi/scsi_cd.h> 64 65 #include <vm/vm.h> 66 #include <vm/vm_param.h> 67 #include <vm/pmap.h> 68 69 #include "advansys.h" 70 #include "advmcode.h" 71 72 struct adv_quirk_entry { 73 struct scsi_inquiry_pattern inq_pat; 74 u_int8_t quirks; 75 #define ADV_QUIRK_FIX_ASYN_XFER_ALWAYS 0x01 76 #define ADV_QUIRK_FIX_ASYN_XFER 0x02 77 }; 78 79 static struct adv_quirk_entry adv_quirk_table[] = 80 { 81 { 82 { T_CDROM, SIP_MEDIA_REMOVABLE, "HP", "*", "*" }, 83 ADV_QUIRK_FIX_ASYN_XFER_ALWAYS|ADV_QUIRK_FIX_ASYN_XFER 84 }, 85 { 86 { T_CDROM, SIP_MEDIA_REMOVABLE, "NEC", "CD-ROM DRIVE", "*" }, 87 0 88 }, 89 { 90 { 91 T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, 92 "TANDBERG", " TDC 36", "*" 93 }, 94 0 95 }, 96 { 97 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "WANGTEK", "*", "*" }, 98 0 99 }, 100 { 101 { 102 T_PROCESSOR, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, 103 "*", "*", "*" 104 }, 105 0 106 }, 107 { 108 { 109 T_SCANNER, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, 110 "*", "*", "*" 111 }, 112 0 113 }, 114 { 115 /* Default quirk entry */ 116 { 117 T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, 118 /*vendor*/"*", /*product*/"*", /*revision*/"*" 119 }, 120 ADV_QUIRK_FIX_ASYN_XFER, 121 } 122 }; 123 124 /* 125 * Allowable periods in ns 126 */ 127 static u_int8_t adv_sdtr_period_tbl[] = 128 { 129 25, 130 30, 131 35, 132 40, 133 50, 134 60, 135 70, 136 85 137 }; 138 139 static u_int8_t adv_sdtr_period_tbl_ultra[] = 140 { 141 12, 142 19, 143 25, 144 32, 145 38, 146 44, 147 50, 148 57, 149 63, 150 69, 151 75, 152 82, 153 88, 154 94, 155 100, 156 107 157 }; 158 159 struct ext_msg { 160 u_int8_t msg_type; 161 u_int8_t msg_len; 162 u_int8_t msg_req; 163 union { 164 struct { 165 u_int8_t sdtr_xfer_period; 166 u_int8_t sdtr_req_ack_offset; 167 } sdtr; 168 struct { 169 u_int8_t wdtr_width; 170 } wdtr; 171 struct { 172 u_int8_t mdp[4]; 173 } mdp; 174 } u_ext_msg; 175 u_int8_t res; 176 }; 177 178 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period 179 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset 180 #define wdtr_width u_ext_msg.wdtr.wdtr_width 181 #define mdp_b3 u_ext_msg.mdp_b3 182 #define mdp_b2 u_ext_msg.mdp_b2 183 #define mdp_b1 u_ext_msg.mdp_b1 184 #define mdp_b0 u_ext_msg.mdp_b0 185 186 /* 187 * Some of the early PCI adapters have problems with 188 * async transfers. Instead use an offset of 1. 189 */ 190 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41 191 192 /* LRAM routines */ 193 static void adv_read_lram_16_multi(struct adv_softc *adv, u_int16_t s_addr, 194 u_int16_t *buffer, int count); 195 static void adv_write_lram_16_multi(struct adv_softc *adv, 196 u_int16_t s_addr, u_int16_t *buffer, 197 int count); 198 static void adv_mset_lram_16(struct adv_softc *adv, u_int16_t s_addr, 199 u_int16_t set_value, int count); 200 static u_int32_t adv_msum_lram_16(struct adv_softc *adv, u_int16_t s_addr, 201 int count); 202 203 static int adv_write_and_verify_lram_16(struct adv_softc *adv, 204 u_int16_t addr, u_int16_t value); 205 static u_int32_t adv_read_lram_32(struct adv_softc *adv, u_int16_t addr); 206 207 208 static void adv_write_lram_32(struct adv_softc *adv, u_int16_t addr, 209 u_int32_t value); 210 static void adv_write_lram_32_multi(struct adv_softc *adv, 211 u_int16_t s_addr, u_int32_t *buffer, 212 int count); 213 214 /* EEPROM routines */ 215 static u_int16_t adv_read_eeprom_16(struct adv_softc *adv, u_int8_t addr); 216 static u_int16_t adv_write_eeprom_16(struct adv_softc *adv, u_int8_t addr, 217 u_int16_t value); 218 static int adv_write_eeprom_cmd_reg(struct adv_softc *adv, 219 u_int8_t cmd_reg); 220 static int adv_set_eeprom_config_once(struct adv_softc *adv, 221 struct adv_eeprom_config *eeconfig); 222 223 /* Initialization */ 224 static u_int32_t adv_load_microcode(struct adv_softc *adv, u_int16_t s_addr, 225 u_int16_t *mcode_buf, u_int16_t mcode_size); 226 227 static void adv_reinit_lram(struct adv_softc *adv); 228 static void adv_init_lram(struct adv_softc *adv); 229 static int adv_init_microcode_var(struct adv_softc *adv); 230 static void adv_init_qlink_var(struct adv_softc *adv); 231 232 /* Interrupts */ 233 static void adv_disable_interrupt(struct adv_softc *adv); 234 static void adv_enable_interrupt(struct adv_softc *adv); 235 static void adv_toggle_irq_act(struct adv_softc *adv); 236 237 /* Chip Control */ 238 static int adv_host_req_chip_halt(struct adv_softc *adv); 239 static void adv_set_chip_ih(struct adv_softc *adv, u_int16_t ins_code); 240 #if 0 /* UNUSED */ 241 static u_int8_t adv_get_chip_scsi_ctrl(struct adv_softc *adv); 242 #endif 243 244 /* Queue handling and execution */ 245 static __inline int 246 adv_sgcount_to_qcount(int sgcount); 247 248 static __inline int 249 adv_sgcount_to_qcount(int sgcount) 250 { 251 int n_sg_list_qs; 252 253 n_sg_list_qs = ((sgcount - 1) / ADV_SG_LIST_PER_Q); 254 if (((sgcount - 1) % ADV_SG_LIST_PER_Q) != 0) 255 n_sg_list_qs++; 256 return (n_sg_list_qs + 1); 257 } 258 259 static void adv_get_q_info(struct adv_softc *adv, u_int16_t s_addr, 260 u_int16_t *inbuf, int words); 261 static u_int adv_get_num_free_queues(struct adv_softc *adv, u_int8_t n_qs); 262 static u_int8_t adv_alloc_free_queues(struct adv_softc *adv, 263 u_int8_t free_q_head, u_int8_t n_free_q); 264 static u_int8_t adv_alloc_free_queue(struct adv_softc *adv, 265 u_int8_t free_q_head); 266 static int adv_send_scsi_queue(struct adv_softc *adv, 267 struct adv_scsi_q *scsiq, 268 u_int8_t n_q_required); 269 static void adv_put_ready_sg_list_queue(struct adv_softc *adv, 270 struct adv_scsi_q *scsiq, 271 u_int q_no); 272 static void adv_put_ready_queue(struct adv_softc *adv, 273 struct adv_scsi_q *scsiq, u_int q_no); 274 static void adv_put_scsiq(struct adv_softc *adv, u_int16_t s_addr, 275 u_int16_t *buffer, int words); 276 277 /* Messages */ 278 static void adv_handle_extmsg_in(struct adv_softc *adv, 279 u_int16_t halt_q_addr, u_int8_t q_cntl, 280 target_bit_vector target_id, 281 int tid); 282 static void adv_msgout_sdtr(struct adv_softc *adv, u_int8_t sdtr_period, 283 u_int8_t sdtr_offset); 284 static void adv_set_sdtr_reg_at_id(struct adv_softc *adv, int id, 285 u_int8_t sdtr_data); 286 287 288 /* Exported functions first */ 289 290 void 291 advasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) 292 { 293 struct adv_softc *adv; 294 295 adv = (struct adv_softc *)callback_arg; 296 switch (code) { 297 case AC_FOUND_DEVICE: 298 { 299 struct ccb_getdev *cgd; 300 target_bit_vector target_mask; 301 int num_entries; 302 caddr_t match; 303 struct adv_quirk_entry *entry; 304 struct adv_target_transinfo* tinfo; 305 306 cgd = (struct ccb_getdev *)arg; 307 308 target_mask = ADV_TID_TO_TARGET_MASK(cgd->ccb_h.target_id); 309 310 num_entries = NELEM(adv_quirk_table); 311 match = cam_quirkmatch((caddr_t)&cgd->inq_data, 312 (caddr_t)adv_quirk_table, 313 num_entries, sizeof(*adv_quirk_table), 314 scsi_inquiry_match); 315 316 if (match == NULL) 317 panic("advasync: device didn't match wildcard entry!!"); 318 319 entry = (struct adv_quirk_entry *)match; 320 321 if (adv->bug_fix_control & ADV_BUG_FIX_ASYN_USE_SYN) { 322 if ((entry->quirks & ADV_QUIRK_FIX_ASYN_XFER_ALWAYS)!=0) 323 adv->fix_asyn_xfer_always |= target_mask; 324 else 325 adv->fix_asyn_xfer_always &= ~target_mask; 326 /* 327 * We start out life with all bits set and clear them 328 * after we've determined that the fix isn't necessary. 329 * It may well be that we've already cleared a target 330 * before the full inquiry session completes, so don't 331 * gratuitously set a target bit even if it has this 332 * quirk. But, if the quirk exonerates a device, clear 333 * the bit now. 334 */ 335 if ((entry->quirks & ADV_QUIRK_FIX_ASYN_XFER) == 0) 336 adv->fix_asyn_xfer &= ~target_mask; 337 } 338 /* 339 * Reset our sync settings now that we've determined 340 * what quirks are in effect for the device. 341 */ 342 tinfo = &adv->tinfo[cgd->ccb_h.target_id]; 343 adv_set_syncrate(adv, cgd->ccb_h.path, 344 cgd->ccb_h.target_id, 345 tinfo->current.period, 346 tinfo->current.offset, 347 ADV_TRANS_CUR); 348 break; 349 } 350 case AC_LOST_DEVICE: 351 { 352 u_int target_mask; 353 354 if (adv->bug_fix_control & ADV_BUG_FIX_ASYN_USE_SYN) { 355 target_mask = 0x01 << xpt_path_target_id(path); 356 adv->fix_asyn_xfer |= target_mask; 357 } 358 359 /* 360 * Revert to async transfers 361 * for the next device. 362 */ 363 adv_set_syncrate(adv, /*path*/NULL, 364 xpt_path_target_id(path), 365 /*period*/0, 366 /*offset*/0, 367 ADV_TRANS_GOAL|ADV_TRANS_CUR); 368 } 369 default: 370 break; 371 } 372 } 373 374 void 375 adv_set_bank(struct adv_softc *adv, u_int8_t bank) 376 { 377 u_int8_t control; 378 379 /* 380 * Start out with the bank reset to 0 381 */ 382 control = ADV_INB(adv, ADV_CHIP_CTRL) 383 & (~(ADV_CC_SINGLE_STEP | ADV_CC_TEST 384 | ADV_CC_DIAG | ADV_CC_SCSI_RESET 385 | ADV_CC_CHIP_RESET | ADV_CC_BANK_ONE)); 386 if (bank == 1) { 387 control |= ADV_CC_BANK_ONE; 388 } else if (bank == 2) { 389 control |= ADV_CC_DIAG | ADV_CC_BANK_ONE; 390 } 391 ADV_OUTB(adv, ADV_CHIP_CTRL, control); 392 } 393 394 u_int8_t 395 adv_read_lram_8(struct adv_softc *adv, u_int16_t addr) 396 { 397 u_int8_t byte_data; 398 u_int16_t word_data; 399 400 /* 401 * LRAM is accessed on 16bit boundaries. 402 */ 403 ADV_OUTW(adv, ADV_LRAM_ADDR, addr & 0xFFFE); 404 word_data = ADV_INW(adv, ADV_LRAM_DATA); 405 if (addr & 1) { 406 #if BYTE_ORDER == BIG_ENDIAN 407 byte_data = (u_int8_t)(word_data & 0xFF); 408 #else 409 byte_data = (u_int8_t)((word_data >> 8) & 0xFF); 410 #endif 411 } else { 412 #if BYTE_ORDER == BIG_ENDIAN 413 byte_data = (u_int8_t)((word_data >> 8) & 0xFF); 414 #else 415 byte_data = (u_int8_t)(word_data & 0xFF); 416 #endif 417 } 418 return (byte_data); 419 } 420 421 void 422 adv_write_lram_8(struct adv_softc *adv, u_int16_t addr, u_int8_t value) 423 { 424 u_int16_t word_data; 425 426 word_data = adv_read_lram_16(adv, addr & 0xFFFE); 427 if (addr & 1) { 428 word_data &= 0x00FF; 429 word_data |= (((u_int8_t)value << 8) & 0xFF00); 430 } else { 431 word_data &= 0xFF00; 432 word_data |= ((u_int8_t)value & 0x00FF); 433 } 434 adv_write_lram_16(adv, addr & 0xFFFE, word_data); 435 } 436 437 438 u_int16_t 439 adv_read_lram_16(struct adv_softc *adv, u_int16_t addr) 440 { 441 ADV_OUTW(adv, ADV_LRAM_ADDR, addr); 442 return (ADV_INW(adv, ADV_LRAM_DATA)); 443 } 444 445 void 446 adv_write_lram_16(struct adv_softc *adv, u_int16_t addr, u_int16_t value) 447 { 448 ADV_OUTW(adv, ADV_LRAM_ADDR, addr); 449 ADV_OUTW(adv, ADV_LRAM_DATA, value); 450 } 451 452 /* 453 * Determine if there is a board at "iobase" by looking 454 * for the AdvanSys signatures. Return 1 if a board is 455 * found, 0 otherwise. 456 */ 457 int 458 adv_find_signature(bus_space_tag_t tag, bus_space_handle_t bsh) 459 { 460 u_int16_t signature; 461 462 if (bus_space_read_1(tag, bsh, ADV_SIGNATURE_BYTE) == ADV_1000_ID1B) { 463 signature = bus_space_read_2(tag, bsh, ADV_SIGNATURE_WORD); 464 if ((signature == ADV_1000_ID0W) 465 || (signature == ADV_1000_ID0W_FIX)) 466 return (1); 467 } 468 return (0); 469 } 470 471 void 472 adv_lib_init(struct adv_softc *adv) 473 { 474 if ((adv->type & ADV_ULTRA) != 0) { 475 adv->sdtr_period_tbl = adv_sdtr_period_tbl_ultra; 476 adv->sdtr_period_tbl_size = sizeof(adv_sdtr_period_tbl_ultra); 477 } else { 478 adv->sdtr_period_tbl = adv_sdtr_period_tbl; 479 adv->sdtr_period_tbl_size = sizeof(adv_sdtr_period_tbl); 480 } 481 } 482 483 u_int16_t 484 adv_get_eeprom_config(struct adv_softc *adv, struct 485 adv_eeprom_config *eeprom_config) 486 { 487 u_int16_t sum; 488 u_int16_t *wbuf; 489 u_int8_t cfg_beg; 490 u_int8_t cfg_end; 491 u_int8_t s_addr; 492 493 wbuf = (u_int16_t *)eeprom_config; 494 sum = 0; 495 496 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { 497 *wbuf = adv_read_eeprom_16(adv, s_addr); 498 sum += *wbuf; 499 } 500 501 if (adv->type & ADV_VL) { 502 cfg_beg = ADV_EEPROM_CFG_BEG_VL; 503 cfg_end = ADV_EEPROM_MAX_ADDR_VL; 504 } else { 505 cfg_beg = ADV_EEPROM_CFG_BEG; 506 cfg_end = ADV_EEPROM_MAX_ADDR; 507 } 508 509 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { 510 *wbuf = adv_read_eeprom_16(adv, s_addr); 511 sum += *wbuf; 512 #ifdef ADV_DEBUG_EEPROM 513 kprintf("Addr 0x%x: 0x%04x\n", s_addr, *wbuf); 514 #endif 515 } 516 *wbuf = adv_read_eeprom_16(adv, s_addr); 517 return (sum); 518 } 519 520 int 521 adv_set_eeprom_config(struct adv_softc *adv, 522 struct adv_eeprom_config *eeprom_config) 523 { 524 int retry; 525 526 retry = 0; 527 while (1) { 528 if (adv_set_eeprom_config_once(adv, eeprom_config) == 0) { 529 break; 530 } 531 if (++retry > ADV_EEPROM_MAX_RETRY) { 532 break; 533 } 534 } 535 return (retry > ADV_EEPROM_MAX_RETRY); 536 } 537 538 int 539 adv_reset_chip(struct adv_softc *adv, int reset_bus) 540 { 541 adv_stop_chip(adv); 542 ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_CHIP_RESET | ADV_CC_HALT 543 | (reset_bus ? ADV_CC_SCSI_RESET : 0)); 544 DELAY(60); 545 546 adv_set_chip_ih(adv, ADV_INS_RFLAG_WTM); 547 adv_set_chip_ih(adv, ADV_INS_HALT); 548 549 if (reset_bus) 550 ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_CHIP_RESET | ADV_CC_HALT); 551 552 ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT); 553 if (reset_bus) 554 DELAY(200 * 1000); 555 556 ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_CLR_SCSI_RESET_INT); 557 ADV_OUTW(adv, ADV_CHIP_STATUS, 0); 558 return (adv_is_chip_halted(adv)); 559 } 560 561 int 562 adv_test_external_lram(struct adv_softc* adv) 563 { 564 u_int16_t q_addr; 565 u_int16_t saved_value; 566 int success; 567 568 success = 0; 569 570 q_addr = ADV_QNO_TO_QADDR(241); 571 saved_value = adv_read_lram_16(adv, q_addr); 572 if (adv_write_and_verify_lram_16(adv, q_addr, 0x55AA) == 0) { 573 success = 1; 574 adv_write_lram_16(adv, q_addr, saved_value); 575 } 576 return (success); 577 } 578 579 580 int 581 adv_init_lram_and_mcode(struct adv_softc *adv) 582 { 583 u_int32_t retval; 584 585 adv_disable_interrupt(adv); 586 587 adv_init_lram(adv); 588 589 retval = adv_load_microcode(adv, 0, (u_int16_t *)adv_mcode, 590 adv_mcode_size); 591 if (retval != adv_mcode_chksum) { 592 kprintf("adv%d: Microcode download failed checksum!\n", 593 adv->unit); 594 return (1); 595 } 596 597 if (adv_init_microcode_var(adv) != 0) 598 return (1); 599 600 adv_enable_interrupt(adv); 601 return (0); 602 } 603 604 u_int8_t 605 adv_get_chip_irq(struct adv_softc *adv) 606 { 607 u_int16_t cfg_lsw; 608 u_int8_t chip_irq; 609 610 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW); 611 612 if ((adv->type & ADV_VL) != 0) { 613 chip_irq = (u_int8_t)(((cfg_lsw >> 2) & 0x07)); 614 if ((chip_irq == 0) || 615 (chip_irq == 4) || 616 (chip_irq == 7)) { 617 return (0); 618 } 619 return (chip_irq + (ADV_MIN_IRQ_NO - 1)); 620 } 621 chip_irq = (u_int8_t)(((cfg_lsw >> 2) & 0x03)); 622 if (chip_irq == 3) 623 chip_irq += 2; 624 return (chip_irq + ADV_MIN_IRQ_NO); 625 } 626 627 u_int8_t 628 adv_set_chip_irq(struct adv_softc *adv, u_int8_t irq_no) 629 { 630 u_int16_t cfg_lsw; 631 632 if ((adv->type & ADV_VL) != 0) { 633 if (irq_no != 0) { 634 if ((irq_no < ADV_MIN_IRQ_NO) 635 || (irq_no > ADV_MAX_IRQ_NO)) { 636 irq_no = 0; 637 } else { 638 irq_no -= ADV_MIN_IRQ_NO - 1; 639 } 640 } 641 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW) & 0xFFE3; 642 cfg_lsw |= 0x0010; 643 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw); 644 adv_toggle_irq_act(adv); 645 646 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW) & 0xFFE0; 647 cfg_lsw |= (irq_no & 0x07) << 2; 648 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw); 649 adv_toggle_irq_act(adv); 650 } else if ((adv->type & ADV_ISA) != 0) { 651 if (irq_no == 15) 652 irq_no -= 2; 653 irq_no -= ADV_MIN_IRQ_NO; 654 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW) & 0xFFF3; 655 cfg_lsw |= (irq_no & 0x03) << 2; 656 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw); 657 } 658 return (adv_get_chip_irq(adv)); 659 } 660 661 void 662 adv_set_chip_scsiid(struct adv_softc *adv, int new_id) 663 { 664 u_int16_t cfg_lsw; 665 666 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW); 667 if (ADV_CONFIG_SCSIID(cfg_lsw) == new_id) 668 return; 669 cfg_lsw &= ~ADV_CFG_LSW_SCSIID; 670 cfg_lsw |= (new_id & ADV_MAX_TID) << ADV_CFG_LSW_SCSIID_SHIFT; 671 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw); 672 } 673 674 int 675 adv_execute_scsi_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq, 676 u_int32_t datalen) 677 { 678 struct adv_target_transinfo* tinfo; 679 u_int32_t *p_data_addr; 680 u_int32_t *p_data_bcount; 681 int disable_syn_offset_one_fix; 682 int retval; 683 u_int n_q_required; 684 u_int32_t addr; 685 u_int8_t sg_entry_cnt; 686 u_int8_t target_ix; 687 u_int8_t sg_entry_cnt_minus_one; 688 u_int8_t tid_no; 689 690 scsiq->q1.q_no = 0; 691 retval = 1; /* Default to error case */ 692 target_ix = scsiq->q2.target_ix; 693 tid_no = ADV_TIX_TO_TID(target_ix); 694 tinfo = &adv->tinfo[tid_no]; 695 696 if (scsiq->cdbptr[0] == REQUEST_SENSE) { 697 /* Renegotiate if appropriate. */ 698 adv_set_syncrate(adv, /*struct cam_path */NULL, 699 tid_no, /*period*/0, /*offset*/0, 700 ADV_TRANS_CUR); 701 if (tinfo->current.period != tinfo->goal.period) { 702 adv_msgout_sdtr(adv, tinfo->goal.period, 703 tinfo->goal.offset); 704 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT); 705 } 706 } 707 708 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { 709 sg_entry_cnt = scsiq->sg_head->entry_cnt; 710 sg_entry_cnt_minus_one = sg_entry_cnt - 1; 711 712 #ifdef DIAGNOSTIC 713 if (sg_entry_cnt <= 1) 714 panic("adv_execute_scsi_queue: Queue " 715 "with QC_SG_HEAD set but %d segs.", sg_entry_cnt); 716 717 if (sg_entry_cnt > ADV_MAX_SG_LIST) 718 panic("adv_execute_scsi_queue: " 719 "Queue with too many segs."); 720 721 if ((adv->type & (ADV_ISA | ADV_VL | ADV_EISA)) != 0) { 722 int i; 723 724 for (i = 0; i < sg_entry_cnt_minus_one; i++) { 725 addr = scsiq->sg_head->sg_list[i].addr + 726 scsiq->sg_head->sg_list[i].bytes; 727 728 if ((addr & 0x0003) != 0) 729 panic("adv_execute_scsi_queue: SG " 730 "with odd address or byte count"); 731 } 732 } 733 #endif 734 p_data_addr = 735 &scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].addr; 736 p_data_bcount = 737 &scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].bytes; 738 739 n_q_required = adv_sgcount_to_qcount(sg_entry_cnt); 740 scsiq->sg_head->queue_cnt = n_q_required - 1; 741 } else { 742 p_data_addr = &scsiq->q1.data_addr; 743 p_data_bcount = &scsiq->q1.data_cnt; 744 n_q_required = 1; 745 } 746 747 disable_syn_offset_one_fix = FALSE; 748 749 if ((adv->fix_asyn_xfer & scsiq->q1.target_id) != 0 750 && (adv->fix_asyn_xfer_always & scsiq->q1.target_id) == 0) { 751 752 if (datalen != 0) { 753 if (datalen < 512) { 754 disable_syn_offset_one_fix = TRUE; 755 } else { 756 if (scsiq->cdbptr[0] == INQUIRY 757 || scsiq->cdbptr[0] == REQUEST_SENSE 758 || scsiq->cdbptr[0] == READ_CAPACITY 759 || scsiq->cdbptr[0] == MODE_SELECT_6 760 || scsiq->cdbptr[0] == MODE_SENSE_6 761 || scsiq->cdbptr[0] == MODE_SENSE_10 762 || scsiq->cdbptr[0] == MODE_SELECT_10 763 || scsiq->cdbptr[0] == READ_TOC) { 764 disable_syn_offset_one_fix = TRUE; 765 } 766 } 767 } 768 } 769 770 if (disable_syn_offset_one_fix) { 771 scsiq->q2.tag_code &= 772 ~(MSG_SIMPLE_Q_TAG|MSG_HEAD_OF_Q_TAG|MSG_ORDERED_Q_TAG); 773 scsiq->q2.tag_code |= (ADV_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 774 | ADV_TAG_FLAG_DISABLE_DISCONNECT); 775 } 776 777 if ((adv->bug_fix_control & ADV_BUG_FIX_IF_NOT_DWB) != 0 778 && (scsiq->cdbptr[0] == READ_10 || scsiq->cdbptr[0] == READ_6)) { 779 u_int8_t extra_bytes; 780 781 addr = *p_data_addr + *p_data_bcount; 782 extra_bytes = addr & 0x0003; 783 if (extra_bytes != 0 784 && ((scsiq->q1.cntl & QC_SG_HEAD) != 0 785 || (scsiq->q1.data_cnt & 0x01FF) == 0)) { 786 scsiq->q2.tag_code |= ADV_TAG_FLAG_EXTRA_BYTES; 787 scsiq->q1.extra_bytes = extra_bytes; 788 *p_data_bcount -= extra_bytes; 789 } 790 } 791 792 if ((adv_get_num_free_queues(adv, n_q_required) >= n_q_required) 793 || ((scsiq->q1.cntl & QC_URGENT) != 0)) 794 retval = adv_send_scsi_queue(adv, scsiq, n_q_required); 795 796 return (retval); 797 } 798 799 800 u_int8_t 801 adv_copy_lram_doneq(struct adv_softc *adv, u_int16_t q_addr, 802 struct adv_q_done_info *scsiq, u_int32_t max_dma_count) 803 { 804 u_int16_t val; 805 u_int8_t sg_queue_cnt; 806 807 adv_get_q_info(adv, q_addr + ADV_SCSIQ_DONE_INFO_BEG, 808 (u_int16_t *)scsiq, 809 (sizeof(scsiq->d2) + sizeof(scsiq->d3)) / 2); 810 811 #if BYTE_ORDER == BIG_ENDIAN 812 adv_adj_endian_qdone_info(scsiq); 813 #endif 814 815 val = adv_read_lram_16(adv, q_addr + ADV_SCSIQ_B_STATUS); 816 scsiq->q_status = val & 0xFF; 817 scsiq->q_no = (val >> 8) & 0XFF; 818 819 val = adv_read_lram_16(adv, q_addr + ADV_SCSIQ_B_CNTL); 820 scsiq->cntl = val & 0xFF; 821 sg_queue_cnt = (val >> 8) & 0xFF; 822 823 val = adv_read_lram_16(adv,q_addr + ADV_SCSIQ_B_SENSE_LEN); 824 scsiq->sense_len = val & 0xFF; 825 scsiq->extra_bytes = (val >> 8) & 0xFF; 826 827 /* 828 * Due to a bug in accessing LRAM on the 940UA, the residual 829 * is split into separate high and low 16bit quantities. 830 */ 831 scsiq->remain_bytes = 832 adv_read_lram_16(adv, q_addr + ADV_SCSIQ_DW_REMAIN_XFER_CNT); 833 scsiq->remain_bytes |= 834 adv_read_lram_16(adv, q_addr + ADV_SCSIQ_W_ALT_DC1) << 16; 835 836 /* 837 * XXX Is this just a safeguard or will the counter really 838 * have bogus upper bits? 839 */ 840 scsiq->remain_bytes &= max_dma_count; 841 842 return (sg_queue_cnt); 843 } 844 845 int 846 adv_start_chip(struct adv_softc *adv) 847 { 848 ADV_OUTB(adv, ADV_CHIP_CTRL, 0); 849 if ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_HALTED) != 0) 850 return (0); 851 return (1); 852 } 853 854 int 855 adv_stop_execution(struct adv_softc *adv) 856 { 857 int count; 858 859 count = 0; 860 if (adv_read_lram_8(adv, ADV_STOP_CODE_B) == 0) { 861 adv_write_lram_8(adv, ADV_STOP_CODE_B, 862 ADV_STOP_REQ_RISC_STOP); 863 do { 864 if (adv_read_lram_8(adv, ADV_STOP_CODE_B) & 865 ADV_STOP_ACK_RISC_STOP) { 866 return (1); 867 } 868 DELAY(1000); 869 } while (count++ < 20); 870 } 871 return (0); 872 } 873 874 int 875 adv_is_chip_halted(struct adv_softc *adv) 876 { 877 if ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_HALTED) != 0) { 878 if ((ADV_INB(adv, ADV_CHIP_CTRL) & ADV_CC_HALT) != 0) { 879 return (1); 880 } 881 } 882 return (0); 883 } 884 885 /* 886 * XXX The numeric constants and the loops in this routine 887 * need to be documented. 888 */ 889 void 890 adv_ack_interrupt(struct adv_softc *adv) 891 { 892 u_int8_t host_flag; 893 u_int8_t risc_flag; 894 int loop; 895 896 loop = 0; 897 do { 898 risc_flag = adv_read_lram_8(adv, ADVV_RISC_FLAG_B); 899 if (loop++ > 0x7FFF) { 900 break; 901 } 902 } while ((risc_flag & ADV_RISC_FLAG_GEN_INT) != 0); 903 904 host_flag = adv_read_lram_8(adv, ADVV_HOST_FLAG_B); 905 adv_write_lram_8(adv, ADVV_HOST_FLAG_B, 906 host_flag | ADV_HOST_FLAG_ACK_INT); 907 908 ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_INT_ACK); 909 loop = 0; 910 while (ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_INT_PENDING) { 911 ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_INT_ACK); 912 if (loop++ > 3) { 913 break; 914 } 915 } 916 917 adv_write_lram_8(adv, ADVV_HOST_FLAG_B, host_flag); 918 } 919 920 /* 921 * Handle all conditions that may halt the chip waiting 922 * for us to intervene. 923 */ 924 void 925 adv_isr_chip_halted(struct adv_softc *adv) 926 { 927 u_int16_t int_halt_code; 928 u_int16_t halt_q_addr; 929 target_bit_vector target_mask; 930 target_bit_vector scsi_busy; 931 u_int8_t halt_qp; 932 u_int8_t target_ix; 933 u_int8_t q_cntl; 934 u_int8_t tid_no; 935 936 int_halt_code = adv_read_lram_16(adv, ADVV_HALTCODE_W); 937 halt_qp = adv_read_lram_8(adv, ADVV_CURCDB_B); 938 halt_q_addr = ADV_QNO_TO_QADDR(halt_qp); 939 target_ix = adv_read_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_TARGET_IX); 940 q_cntl = adv_read_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL); 941 tid_no = ADV_TIX_TO_TID(target_ix); 942 target_mask = ADV_TID_TO_TARGET_MASK(tid_no); 943 if (int_halt_code == ADV_HALT_DISABLE_ASYN_USE_SYN_FIX) { 944 /* 945 * Temporarily disable the async fix by removing 946 * this target from the list of affected targets, 947 * setting our async rate, and then putting us 948 * back into the mask. 949 */ 950 adv->fix_asyn_xfer &= ~target_mask; 951 adv_set_syncrate(adv, /*struct cam_path */NULL, 952 tid_no, /*period*/0, /*offset*/0, 953 ADV_TRANS_ACTIVE); 954 adv->fix_asyn_xfer |= target_mask; 955 } else if (int_halt_code == ADV_HALT_ENABLE_ASYN_USE_SYN_FIX) { 956 adv_set_syncrate(adv, /*struct cam_path */NULL, 957 tid_no, /*period*/0, /*offset*/0, 958 ADV_TRANS_ACTIVE); 959 } else if (int_halt_code == ADV_HALT_EXTMSG_IN) { 960 adv_handle_extmsg_in(adv, halt_q_addr, q_cntl, 961 target_mask, tid_no); 962 } else if (int_halt_code == ADV_HALT_CHK_CONDITION) { 963 struct adv_target_transinfo* tinfo; 964 union ccb *ccb; 965 u_int32_t cinfo_index; 966 u_int8_t tag_code; 967 u_int8_t q_status; 968 969 tinfo = &adv->tinfo[tid_no]; 970 q_cntl |= QC_REQ_SENSE; 971 972 /* Renegotiate if appropriate. */ 973 adv_set_syncrate(adv, /*struct cam_path */NULL, 974 tid_no, /*period*/0, /*offset*/0, 975 ADV_TRANS_CUR); 976 if (tinfo->current.period != tinfo->goal.period) { 977 adv_msgout_sdtr(adv, tinfo->goal.period, 978 tinfo->goal.offset); 979 q_cntl |= QC_MSG_OUT; 980 } 981 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL, q_cntl); 982 983 /* Don't tag request sense commands */ 984 tag_code = adv_read_lram_8(adv, 985 halt_q_addr + ADV_SCSIQ_B_TAG_CODE); 986 tag_code &= 987 ~(MSG_SIMPLE_Q_TAG|MSG_HEAD_OF_Q_TAG|MSG_ORDERED_Q_TAG); 988 989 if ((adv->fix_asyn_xfer & target_mask) != 0 990 && (adv->fix_asyn_xfer_always & target_mask) == 0) { 991 tag_code |= (ADV_TAG_FLAG_DISABLE_DISCONNECT 992 | ADV_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX); 993 } 994 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_TAG_CODE, 995 tag_code); 996 q_status = adv_read_lram_8(adv, 997 halt_q_addr + ADV_SCSIQ_B_STATUS); 998 q_status |= (QS_READY | QS_BUSY); 999 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_STATUS, 1000 q_status); 1001 /* 1002 * Freeze the devq until we can handle the sense condition. 1003 */ 1004 cinfo_index = 1005 adv_read_lram_32(adv, halt_q_addr + ADV_SCSIQ_D_CINFO_IDX); 1006 ccb = adv->ccb_infos[cinfo_index].ccb; 1007 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 1008 ccb->ccb_h.status |= CAM_DEV_QFRZN; 1009 adv_abort_ccb(adv, tid_no, ADV_TIX_TO_LUN(target_ix), 1010 /*ccb*/NULL, CAM_REQUEUE_REQ, 1011 /*queued_only*/TRUE); 1012 scsi_busy = adv_read_lram_8(adv, ADVV_SCSIBUSY_B); 1013 scsi_busy &= ~target_mask; 1014 adv_write_lram_8(adv, ADVV_SCSIBUSY_B, scsi_busy); 1015 /* 1016 * Ensure we have enough time to actually 1017 * retrieve the sense. 1018 */ 1019 callout_reset(&ccb->ccb_h.timeout_ch, 5 * hz, adv_timeout, ccb); 1020 } else if (int_halt_code == ADV_HALT_SDTR_REJECTED) { 1021 struct ext_msg out_msg; 1022 1023 adv_read_lram_16_multi(adv, ADVV_MSGOUT_BEG, 1024 (u_int16_t *) &out_msg, 1025 sizeof(out_msg)/2); 1026 1027 if ((out_msg.msg_type == MSG_EXTENDED) 1028 && (out_msg.msg_len == MSG_EXT_SDTR_LEN) 1029 && (out_msg.msg_req == MSG_EXT_SDTR)) { 1030 1031 /* Revert to Async */ 1032 adv_set_syncrate(adv, /*struct cam_path */NULL, 1033 tid_no, /*period*/0, /*offset*/0, 1034 ADV_TRANS_GOAL|ADV_TRANS_ACTIVE); 1035 } 1036 q_cntl &= ~QC_MSG_OUT; 1037 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL, q_cntl); 1038 } else if (int_halt_code == ADV_HALT_SS_QUEUE_FULL) { 1039 u_int8_t scsi_status; 1040 union ccb *ccb; 1041 u_int32_t cinfo_index; 1042 1043 scsi_status = adv_read_lram_8(adv, halt_q_addr 1044 + ADV_SCSIQ_SCSI_STATUS); 1045 cinfo_index = 1046 adv_read_lram_32(adv, halt_q_addr + ADV_SCSIQ_D_CINFO_IDX); 1047 ccb = adv->ccb_infos[cinfo_index].ccb; 1048 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 1049 ccb->ccb_h.status |= CAM_DEV_QFRZN|CAM_SCSI_STATUS_ERROR; 1050 ccb->csio.scsi_status = SCSI_STATUS_QUEUE_FULL; 1051 adv_abort_ccb(adv, tid_no, ADV_TIX_TO_LUN(target_ix), 1052 /*ccb*/NULL, CAM_REQUEUE_REQ, 1053 /*queued_only*/TRUE); 1054 scsi_busy = adv_read_lram_8(adv, ADVV_SCSIBUSY_B); 1055 scsi_busy &= ~target_mask; 1056 adv_write_lram_8(adv, ADVV_SCSIBUSY_B, scsi_busy); 1057 } else { 1058 kprintf("Unhandled Halt Code %x\n", int_halt_code); 1059 } 1060 adv_write_lram_16(adv, ADVV_HALTCODE_W, 0); 1061 } 1062 1063 void 1064 adv_sdtr_to_period_offset(struct adv_softc *adv, 1065 u_int8_t sync_data, u_int8_t *period, 1066 u_int8_t *offset, int tid) 1067 { 1068 if (adv->fix_asyn_xfer & ADV_TID_TO_TARGET_MASK(tid) 1069 && (sync_data == ASYN_SDTR_DATA_FIX_PCI_REV_AB)) { 1070 *period = *offset = 0; 1071 } else { 1072 *period = adv->sdtr_period_tbl[((sync_data >> 4) & 0xF)]; 1073 *offset = sync_data & 0xF; 1074 } 1075 } 1076 1077 void 1078 adv_set_syncrate(struct adv_softc *adv, struct cam_path *path, 1079 u_int tid, u_int period, u_int offset, u_int type) 1080 { 1081 struct adv_target_transinfo* tinfo; 1082 u_int old_period; 1083 u_int old_offset; 1084 u_int8_t sdtr_data; 1085 1086 tinfo = &adv->tinfo[tid]; 1087 1088 /* Filter our input */ 1089 sdtr_data = adv_period_offset_to_sdtr(adv, &period, 1090 &offset, tid); 1091 1092 old_period = tinfo->current.period; 1093 old_offset = tinfo->current.offset; 1094 1095 if ((type & ADV_TRANS_CUR) != 0 1096 && ((old_period != period || old_offset != offset) 1097 || period == 0 || offset == 0) /*Changes in asyn fix settings*/) { 1098 int halted; 1099 1100 crit_enter(); 1101 halted = adv_is_chip_halted(adv); 1102 if (halted == 0) 1103 /* Must halt the chip first */ 1104 adv_host_req_chip_halt(adv); 1105 1106 /* Update current hardware settings */ 1107 adv_set_sdtr_reg_at_id(adv, tid, sdtr_data); 1108 1109 /* 1110 * If a target can run in sync mode, we don't need 1111 * to check it for sync problems. 1112 */ 1113 if (offset != 0) 1114 adv->fix_asyn_xfer &= ~ADV_TID_TO_TARGET_MASK(tid); 1115 1116 if (halted == 0) 1117 /* Start the chip again */ 1118 adv_start_chip(adv); 1119 1120 crit_exit(); 1121 tinfo->current.period = period; 1122 tinfo->current.offset = offset; 1123 1124 if (path != NULL) { 1125 /* 1126 * Tell the SCSI layer about the 1127 * new transfer parameters. 1128 */ 1129 struct ccb_trans_settings neg; 1130 memset(&neg, 0, sizeof (neg)); 1131 struct ccb_trans_settings_spi *spi = 1132 &neg.xport_specific.spi; 1133 1134 neg.protocol = PROTO_SCSI; 1135 neg.protocol_version = SCSI_REV_2; 1136 neg.transport = XPORT_SPI; 1137 neg.transport_version = 2; 1138 1139 spi->sync_offset = offset; 1140 spi->sync_period = period; 1141 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; 1142 spi->valid |= CTS_SPI_VALID_SYNC_RATE; 1143 xpt_setup_ccb(&neg.ccb_h, path, /*priority*/1); 1144 xpt_async(AC_TRANSFER_NEG, path, &neg); 1145 } 1146 } 1147 1148 if ((type & ADV_TRANS_GOAL) != 0) { 1149 tinfo->goal.period = period; 1150 tinfo->goal.offset = offset; 1151 } 1152 1153 if ((type & ADV_TRANS_USER) != 0) { 1154 tinfo->user.period = period; 1155 tinfo->user.offset = offset; 1156 } 1157 } 1158 1159 u_int8_t 1160 adv_period_offset_to_sdtr(struct adv_softc *adv, u_int *period, 1161 u_int *offset, int tid) 1162 { 1163 u_int i; 1164 u_int dummy_offset; 1165 u_int dummy_period; 1166 1167 if (offset == NULL) { 1168 dummy_offset = 0; 1169 offset = &dummy_offset; 1170 } 1171 1172 if (period == NULL) { 1173 dummy_period = 0; 1174 period = &dummy_period; 1175 } 1176 1177 *offset = MIN(ADV_SYN_MAX_OFFSET, *offset); 1178 if (*period != 0 && *offset != 0) { 1179 for (i = 0; i < adv->sdtr_period_tbl_size; i++) { 1180 if (*period <= adv->sdtr_period_tbl[i]) { 1181 /* 1182 * When responding to a target that requests 1183 * sync, the requested rate may fall between 1184 * two rates that we can output, but still be 1185 * a rate that we can receive. Because of this, 1186 * we want to respond to the target with 1187 * the same rate that it sent to us even 1188 * if the period we use to send data to it 1189 * is lower. Only lower the response period 1190 * if we must. 1191 */ 1192 if (i == 0 /* Our maximum rate */) 1193 *period = adv->sdtr_period_tbl[0]; 1194 return ((i << 4) | *offset); 1195 } 1196 } 1197 } 1198 1199 /* Must go async */ 1200 *period = 0; 1201 *offset = 0; 1202 if (adv->fix_asyn_xfer & ADV_TID_TO_TARGET_MASK(tid)) 1203 return (ASYN_SDTR_DATA_FIX_PCI_REV_AB); 1204 return (0); 1205 } 1206 1207 /* Internal Routines */ 1208 1209 static void 1210 adv_read_lram_16_multi(struct adv_softc *adv, u_int16_t s_addr, 1211 u_int16_t *buffer, int count) 1212 { 1213 ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr); 1214 ADV_INSW(adv, ADV_LRAM_DATA, buffer, count); 1215 } 1216 1217 static void 1218 adv_write_lram_16_multi(struct adv_softc *adv, u_int16_t s_addr, 1219 u_int16_t *buffer, int count) 1220 { 1221 ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr); 1222 ADV_OUTSW(adv, ADV_LRAM_DATA, buffer, count); 1223 } 1224 1225 static void 1226 adv_mset_lram_16(struct adv_softc *adv, u_int16_t s_addr, 1227 u_int16_t set_value, int count) 1228 { 1229 ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr); 1230 bus_space_set_multi_2(adv->tag, adv->bsh, ADV_LRAM_DATA, 1231 set_value, count); 1232 } 1233 1234 static u_int32_t 1235 adv_msum_lram_16(struct adv_softc *adv, u_int16_t s_addr, int count) 1236 { 1237 u_int32_t sum; 1238 int i; 1239 1240 sum = 0; 1241 ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr); 1242 for (i = 0; i < count; i++) 1243 sum += ADV_INW(adv, ADV_LRAM_DATA); 1244 return (sum); 1245 } 1246 1247 static int 1248 adv_write_and_verify_lram_16(struct adv_softc *adv, u_int16_t addr, 1249 u_int16_t value) 1250 { 1251 int retval; 1252 1253 retval = 0; 1254 ADV_OUTW(adv, ADV_LRAM_ADDR, addr); 1255 ADV_OUTW(adv, ADV_LRAM_DATA, value); 1256 DELAY(10000); 1257 ADV_OUTW(adv, ADV_LRAM_ADDR, addr); 1258 if (value != ADV_INW(adv, ADV_LRAM_DATA)) 1259 retval = 1; 1260 return (retval); 1261 } 1262 1263 static u_int32_t 1264 adv_read_lram_32(struct adv_softc *adv, u_int16_t addr) 1265 { 1266 u_int16_t val_low, val_high; 1267 1268 ADV_OUTW(adv, ADV_LRAM_ADDR, addr); 1269 1270 #if BYTE_ORDER == BIG_ENDIAN 1271 val_high = ADV_INW(adv, ADV_LRAM_DATA); 1272 val_low = ADV_INW(adv, ADV_LRAM_DATA); 1273 #else 1274 val_low = ADV_INW(adv, ADV_LRAM_DATA); 1275 val_high = ADV_INW(adv, ADV_LRAM_DATA); 1276 #endif 1277 1278 return (((u_int32_t)val_high << 16) | (u_int32_t)val_low); 1279 } 1280 1281 static void 1282 adv_write_lram_32(struct adv_softc *adv, u_int16_t addr, u_int32_t value) 1283 { 1284 ADV_OUTW(adv, ADV_LRAM_ADDR, addr); 1285 1286 #if BYTE_ORDER == BIG_ENDIAN 1287 ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)((value >> 16) & 0xFFFF)); 1288 ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)(value & 0xFFFF)); 1289 #else 1290 ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)(value & 0xFFFF)); 1291 ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)((value >> 16) & 0xFFFF)); 1292 #endif 1293 } 1294 1295 static void 1296 adv_write_lram_32_multi(struct adv_softc *adv, u_int16_t s_addr, 1297 u_int32_t *buffer, int count) 1298 { 1299 ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr); 1300 ADV_OUTSW(adv, ADV_LRAM_DATA, (u_int16_t *)buffer, count * 2); 1301 } 1302 1303 static u_int16_t 1304 adv_read_eeprom_16(struct adv_softc *adv, u_int8_t addr) 1305 { 1306 u_int16_t read_wval; 1307 u_int8_t cmd_reg; 1308 1309 adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE_DISABLE); 1310 DELAY(1000); 1311 cmd_reg = addr | ADV_EEPROM_CMD_READ; 1312 adv_write_eeprom_cmd_reg(adv, cmd_reg); 1313 DELAY(1000); 1314 read_wval = ADV_INW(adv, ADV_EEPROM_DATA); 1315 DELAY(1000); 1316 return (read_wval); 1317 } 1318 1319 static u_int16_t 1320 adv_write_eeprom_16(struct adv_softc *adv, u_int8_t addr, u_int16_t value) 1321 { 1322 u_int16_t read_value; 1323 1324 read_value = adv_read_eeprom_16(adv, addr); 1325 if (read_value != value) { 1326 adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE_ENABLE); 1327 DELAY(1000); 1328 1329 ADV_OUTW(adv, ADV_EEPROM_DATA, value); 1330 DELAY(1000); 1331 1332 adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE | addr); 1333 DELAY(20 * 1000); 1334 1335 adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE_DISABLE); 1336 DELAY(1000); 1337 read_value = adv_read_eeprom_16(adv, addr); 1338 } 1339 return (read_value); 1340 } 1341 1342 static int 1343 adv_write_eeprom_cmd_reg(struct adv_softc *adv, u_int8_t cmd_reg) 1344 { 1345 u_int8_t read_back; 1346 int retry; 1347 1348 retry = 0; 1349 while (1) { 1350 ADV_OUTB(adv, ADV_EEPROM_CMD, cmd_reg); 1351 DELAY(1000); 1352 read_back = ADV_INB(adv, ADV_EEPROM_CMD); 1353 if (read_back == cmd_reg) { 1354 return (1); 1355 } 1356 if (retry++ > ADV_EEPROM_MAX_RETRY) { 1357 return (0); 1358 } 1359 } 1360 } 1361 1362 static int 1363 adv_set_eeprom_config_once(struct adv_softc *adv, 1364 struct adv_eeprom_config *eeprom_config) 1365 { 1366 int n_error; 1367 u_int16_t *wbuf; 1368 u_int16_t sum; 1369 u_int8_t s_addr; 1370 u_int8_t cfg_beg; 1371 u_int8_t cfg_end; 1372 1373 wbuf = (u_int16_t *)eeprom_config; 1374 n_error = 0; 1375 sum = 0; 1376 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { 1377 sum += *wbuf; 1378 if (*wbuf != adv_write_eeprom_16(adv, s_addr, *wbuf)) { 1379 n_error++; 1380 } 1381 } 1382 if (adv->type & ADV_VL) { 1383 cfg_beg = ADV_EEPROM_CFG_BEG_VL; 1384 cfg_end = ADV_EEPROM_MAX_ADDR_VL; 1385 } else { 1386 cfg_beg = ADV_EEPROM_CFG_BEG; 1387 cfg_end = ADV_EEPROM_MAX_ADDR; 1388 } 1389 1390 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { 1391 sum += *wbuf; 1392 if (*wbuf != adv_write_eeprom_16(adv, s_addr, *wbuf)) { 1393 n_error++; 1394 } 1395 } 1396 *wbuf = sum; 1397 if (sum != adv_write_eeprom_16(adv, s_addr, sum)) { 1398 n_error++; 1399 } 1400 wbuf = (u_int16_t *)eeprom_config; 1401 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { 1402 if (*wbuf != adv_read_eeprom_16(adv, s_addr)) { 1403 n_error++; 1404 } 1405 } 1406 for (s_addr = cfg_beg; s_addr <= cfg_end; s_addr++, wbuf++) { 1407 if (*wbuf != adv_read_eeprom_16(adv, s_addr)) { 1408 n_error++; 1409 } 1410 } 1411 return (n_error); 1412 } 1413 1414 static u_int32_t 1415 adv_load_microcode(struct adv_softc *adv, u_int16_t s_addr, 1416 u_int16_t *mcode_buf, u_int16_t mcode_size) 1417 { 1418 u_int32_t chksum; 1419 u_int16_t mcode_lram_size; 1420 u_int16_t mcode_chksum; 1421 1422 mcode_lram_size = mcode_size >> 1; 1423 /* XXX Why zero the memory just before you write the whole thing?? */ 1424 adv_mset_lram_16(adv, s_addr, 0, mcode_lram_size); 1425 adv_write_lram_16_multi(adv, s_addr, mcode_buf, mcode_lram_size); 1426 1427 chksum = adv_msum_lram_16(adv, s_addr, mcode_lram_size); 1428 mcode_chksum = (u_int16_t)adv_msum_lram_16(adv, ADV_CODE_SEC_BEG, 1429 ((mcode_size - s_addr 1430 - ADV_CODE_SEC_BEG) >> 1)); 1431 adv_write_lram_16(adv, ADVV_MCODE_CHKSUM_W, mcode_chksum); 1432 adv_write_lram_16(adv, ADVV_MCODE_SIZE_W, mcode_size); 1433 return (chksum); 1434 } 1435 1436 static void 1437 adv_reinit_lram(struct adv_softc *adv) { 1438 adv_init_lram(adv); 1439 adv_init_qlink_var(adv); 1440 } 1441 1442 static void 1443 adv_init_lram(struct adv_softc *adv) 1444 { 1445 u_int8_t i; 1446 u_int16_t s_addr; 1447 1448 adv_mset_lram_16(adv, ADV_QADR_BEG, 0, 1449 (((adv->max_openings + 2 + 1) * 64) >> 1)); 1450 1451 i = ADV_MIN_ACTIVE_QNO; 1452 s_addr = ADV_QADR_BEG + ADV_QBLK_SIZE; 1453 1454 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, i + 1); 1455 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, adv->max_openings); 1456 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, i); 1457 i++; 1458 s_addr += ADV_QBLK_SIZE; 1459 for (; i < adv->max_openings; i++, s_addr += ADV_QBLK_SIZE) { 1460 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, i + 1); 1461 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, i - 1); 1462 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, i); 1463 } 1464 1465 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, ADV_QLINK_END); 1466 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, adv->max_openings - 1); 1467 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, adv->max_openings); 1468 i++; 1469 s_addr += ADV_QBLK_SIZE; 1470 1471 for (; i <= adv->max_openings + 3; i++, s_addr += ADV_QBLK_SIZE) { 1472 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, i); 1473 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, i); 1474 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, i); 1475 } 1476 } 1477 1478 static int 1479 adv_init_microcode_var(struct adv_softc *adv) 1480 { 1481 int i; 1482 1483 for (i = 0; i <= ADV_MAX_TID; i++) { 1484 1485 /* Start out async all around */ 1486 adv_set_syncrate(adv, /*path*/NULL, 1487 i, 0, 0, 1488 ADV_TRANS_GOAL|ADV_TRANS_CUR); 1489 } 1490 1491 adv_init_qlink_var(adv); 1492 1493 adv_write_lram_8(adv, ADVV_DISC_ENABLE_B, adv->disc_enable); 1494 adv_write_lram_8(adv, ADVV_HOSTSCSI_ID_B, 0x01 << adv->scsi_id); 1495 1496 adv_write_lram_32(adv, ADVV_OVERRUN_PADDR_D, adv->overrun_physbase); 1497 1498 adv_write_lram_32(adv, ADVV_OVERRUN_BSIZE_D, ADV_OVERRUN_BSIZE); 1499 1500 ADV_OUTW(adv, ADV_REG_PROG_COUNTER, ADV_MCODE_START_ADDR); 1501 if (ADV_INW(adv, ADV_REG_PROG_COUNTER) != ADV_MCODE_START_ADDR) { 1502 kprintf("adv%d: Unable to set program counter. Aborting.\n", 1503 adv->unit); 1504 return (1); 1505 } 1506 return (0); 1507 } 1508 1509 static void 1510 adv_init_qlink_var(struct adv_softc *adv) 1511 { 1512 int i; 1513 u_int16_t lram_addr; 1514 1515 adv_write_lram_8(adv, ADVV_NEXTRDY_B, 1); 1516 adv_write_lram_8(adv, ADVV_DONENEXT_B, adv->max_openings); 1517 1518 adv_write_lram_16(adv, ADVV_FREE_Q_HEAD_W, 1); 1519 adv_write_lram_16(adv, ADVV_DONE_Q_TAIL_W, adv->max_openings); 1520 1521 adv_write_lram_8(adv, ADVV_BUSY_QHEAD_B, 1522 (u_int8_t)((int) adv->max_openings + 1)); 1523 adv_write_lram_8(adv, ADVV_DISC1_QHEAD_B, 1524 (u_int8_t)((int) adv->max_openings + 2)); 1525 1526 adv_write_lram_8(adv, ADVV_TOTAL_READY_Q_B, adv->max_openings); 1527 1528 adv_write_lram_16(adv, ADVV_ASCDVC_ERR_CODE_W, 0); 1529 adv_write_lram_16(adv, ADVV_HALTCODE_W, 0); 1530 adv_write_lram_8(adv, ADVV_STOP_CODE_B, 0); 1531 adv_write_lram_8(adv, ADVV_SCSIBUSY_B, 0); 1532 adv_write_lram_8(adv, ADVV_WTM_FLAG_B, 0); 1533 adv_write_lram_8(adv, ADVV_Q_DONE_IN_PROGRESS_B, 0); 1534 1535 lram_addr = ADV_QADR_BEG; 1536 for (i = 0; i < 32; i++, lram_addr += 2) 1537 adv_write_lram_16(adv, lram_addr, 0); 1538 } 1539 1540 static void 1541 adv_disable_interrupt(struct adv_softc *adv) 1542 { 1543 u_int16_t cfg; 1544 1545 cfg = ADV_INW(adv, ADV_CONFIG_LSW); 1546 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg & ~ADV_CFG_LSW_HOST_INT_ON); 1547 } 1548 1549 static void 1550 adv_enable_interrupt(struct adv_softc *adv) 1551 { 1552 u_int16_t cfg; 1553 1554 cfg = ADV_INW(adv, ADV_CONFIG_LSW); 1555 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg | ADV_CFG_LSW_HOST_INT_ON); 1556 } 1557 1558 static void 1559 adv_toggle_irq_act(struct adv_softc *adv) 1560 { 1561 ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_IRQ_ACT); 1562 ADV_OUTW(adv, ADV_CHIP_STATUS, 0); 1563 } 1564 1565 void 1566 adv_start_execution(struct adv_softc *adv) 1567 { 1568 if (adv_read_lram_8(adv, ADV_STOP_CODE_B) != 0) { 1569 adv_write_lram_8(adv, ADV_STOP_CODE_B, 0); 1570 } 1571 } 1572 1573 int 1574 adv_stop_chip(struct adv_softc *adv) 1575 { 1576 u_int8_t cc_val; 1577 1578 cc_val = ADV_INB(adv, ADV_CHIP_CTRL) 1579 & (~(ADV_CC_SINGLE_STEP | ADV_CC_TEST | ADV_CC_DIAG)); 1580 ADV_OUTB(adv, ADV_CHIP_CTRL, cc_val | ADV_CC_HALT); 1581 adv_set_chip_ih(adv, ADV_INS_HALT); 1582 adv_set_chip_ih(adv, ADV_INS_RFLAG_WTM); 1583 if ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_HALTED) == 0) { 1584 return (0); 1585 } 1586 return (1); 1587 } 1588 1589 static int 1590 adv_host_req_chip_halt(struct adv_softc *adv) 1591 { 1592 int count; 1593 u_int8_t saved_stop_code; 1594 1595 if (adv_is_chip_halted(adv)) 1596 return (1); 1597 1598 count = 0; 1599 saved_stop_code = adv_read_lram_8(adv, ADVV_STOP_CODE_B); 1600 adv_write_lram_8(adv, ADVV_STOP_CODE_B, 1601 ADV_STOP_HOST_REQ_RISC_HALT | ADV_STOP_REQ_RISC_STOP); 1602 while (adv_is_chip_halted(adv) == 0 1603 && count++ < 2000) 1604 ; 1605 1606 adv_write_lram_8(adv, ADVV_STOP_CODE_B, saved_stop_code); 1607 return (count < 2000); 1608 } 1609 1610 static void 1611 adv_set_chip_ih(struct adv_softc *adv, u_int16_t ins_code) 1612 { 1613 adv_set_bank(adv, 1); 1614 ADV_OUTW(adv, ADV_REG_IH, ins_code); 1615 adv_set_bank(adv, 0); 1616 } 1617 1618 #if 0 /* UNUSED */ 1619 static u_int8_t 1620 adv_get_chip_scsi_ctrl(struct adv_softc *adv) 1621 { 1622 u_int8_t scsi_ctrl; 1623 1624 adv_set_bank(adv, 1); 1625 scsi_ctrl = ADV_INB(adv, ADV_REG_SC); 1626 adv_set_bank(adv, 0); 1627 return (scsi_ctrl); 1628 } 1629 #endif 1630 1631 /* 1632 * XXX Looks like more padding issues in this routine as well. 1633 * There has to be a way to turn this into an insw. 1634 */ 1635 static void 1636 adv_get_q_info(struct adv_softc *adv, u_int16_t s_addr, 1637 u_int16_t *inbuf, int words) 1638 { 1639 int i; 1640 1641 ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr); 1642 for (i = 0; i < words; i++, inbuf++) { 1643 if (i == 5) { 1644 continue; 1645 } 1646 *inbuf = ADV_INW(adv, ADV_LRAM_DATA); 1647 } 1648 } 1649 1650 static u_int 1651 adv_get_num_free_queues(struct adv_softc *adv, u_int8_t n_qs) 1652 { 1653 u_int cur_used_qs; 1654 u_int cur_free_qs; 1655 1656 cur_used_qs = adv->cur_active + ADV_MIN_FREE_Q; 1657 1658 if ((cur_used_qs + n_qs) <= adv->max_openings) { 1659 cur_free_qs = adv->max_openings - cur_used_qs; 1660 return (cur_free_qs); 1661 } 1662 adv->openings_needed = n_qs; 1663 return (0); 1664 } 1665 1666 static u_int8_t 1667 adv_alloc_free_queues(struct adv_softc *adv, u_int8_t free_q_head, 1668 u_int8_t n_free_q) 1669 { 1670 int i; 1671 1672 for (i = 0; i < n_free_q; i++) { 1673 free_q_head = adv_alloc_free_queue(adv, free_q_head); 1674 if (free_q_head == ADV_QLINK_END) 1675 break; 1676 } 1677 return (free_q_head); 1678 } 1679 1680 static u_int8_t 1681 adv_alloc_free_queue(struct adv_softc *adv, u_int8_t free_q_head) 1682 { 1683 u_int16_t q_addr; 1684 u_int8_t next_qp; 1685 u_int8_t q_status; 1686 1687 next_qp = ADV_QLINK_END; 1688 q_addr = ADV_QNO_TO_QADDR(free_q_head); 1689 q_status = adv_read_lram_8(adv, q_addr + ADV_SCSIQ_B_STATUS); 1690 1691 if ((q_status & QS_READY) == 0) 1692 next_qp = adv_read_lram_8(adv, q_addr + ADV_SCSIQ_B_FWD); 1693 1694 return (next_qp); 1695 } 1696 1697 static int 1698 adv_send_scsi_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq, 1699 u_int8_t n_q_required) 1700 { 1701 u_int8_t free_q_head; 1702 u_int8_t next_qp; 1703 int retval; 1704 1705 retval = 1; 1706 free_q_head = adv_read_lram_16(adv, ADVV_FREE_Q_HEAD_W) & 0xFF; 1707 if ((next_qp = adv_alloc_free_queues(adv, free_q_head, n_q_required)) 1708 != ADV_QLINK_END) { 1709 scsiq->q1.q_no = free_q_head; 1710 1711 /* 1712 * Now that we know our Q number, point our sense 1713 * buffer pointer to a bus dma mapped area where 1714 * we can dma the data to. 1715 */ 1716 scsiq->q1.sense_addr = adv->sense_physbase 1717 + ((free_q_head - 1) * sizeof(struct scsi_sense_data)); 1718 adv_put_ready_sg_list_queue(adv, scsiq, free_q_head); 1719 adv_write_lram_16(adv, ADVV_FREE_Q_HEAD_W, next_qp); 1720 adv->cur_active += n_q_required; 1721 retval = 0; 1722 } 1723 return (retval); 1724 } 1725 1726 1727 static void 1728 adv_put_ready_sg_list_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq, 1729 u_int q_no) 1730 { 1731 u_int8_t sg_list_dwords; 1732 u_int8_t sg_index, i; 1733 u_int8_t sg_entry_cnt; 1734 u_int8_t next_qp; 1735 u_int16_t q_addr; 1736 struct adv_sg_head *sg_head; 1737 struct adv_sg_list_q scsi_sg_q; 1738 1739 sg_head = scsiq->sg_head; 1740 1741 if (sg_head) { 1742 sg_entry_cnt = sg_head->entry_cnt - 1; 1743 #ifdef DIAGNOSTIC 1744 if (sg_entry_cnt == 0) 1745 panic("adv_put_ready_sg_list_queue: ScsiQ with " 1746 "a SG list but only one element"); 1747 if ((scsiq->q1.cntl & QC_SG_HEAD) == 0) 1748 panic("adv_put_ready_sg_list_queue: ScsiQ with " 1749 "a SG list but QC_SG_HEAD not set"); 1750 #endif 1751 q_addr = ADV_QNO_TO_QADDR(q_no); 1752 sg_index = 1; 1753 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt; 1754 scsi_sg_q.sg_head_qp = q_no; 1755 scsi_sg_q.cntl = QCSG_SG_XFER_LIST; 1756 for (i = 0; i < sg_head->queue_cnt; i++) { 1757 u_int8_t segs_this_q; 1758 1759 if (sg_entry_cnt > ADV_SG_LIST_PER_Q) 1760 segs_this_q = ADV_SG_LIST_PER_Q; 1761 else { 1762 /* This will be the last segment then */ 1763 segs_this_q = sg_entry_cnt; 1764 scsi_sg_q.cntl |= QCSG_SG_XFER_END; 1765 } 1766 scsi_sg_q.seq_no = i + 1; 1767 sg_list_dwords = segs_this_q << 1; 1768 if (i == 0) { 1769 scsi_sg_q.sg_list_cnt = segs_this_q; 1770 scsi_sg_q.sg_cur_list_cnt = segs_this_q; 1771 } else { 1772 scsi_sg_q.sg_list_cnt = segs_this_q - 1; 1773 scsi_sg_q.sg_cur_list_cnt = segs_this_q - 1; 1774 } 1775 next_qp = adv_read_lram_8(adv, q_addr + ADV_SCSIQ_B_FWD); 1776 scsi_sg_q.q_no = next_qp; 1777 q_addr = ADV_QNO_TO_QADDR(next_qp); 1778 1779 adv_write_lram_16_multi(adv, 1780 q_addr + ADV_SCSIQ_SGHD_CPY_BEG, 1781 (u_int16_t *)&scsi_sg_q, 1782 sizeof(scsi_sg_q) >> 1); 1783 adv_write_lram_32_multi(adv, q_addr + ADV_SGQ_LIST_BEG, 1784 (u_int32_t *)&sg_head->sg_list[sg_index], 1785 sg_list_dwords); 1786 sg_entry_cnt -= segs_this_q; 1787 sg_index += ADV_SG_LIST_PER_Q; 1788 } 1789 } 1790 adv_put_ready_queue(adv, scsiq, q_no); 1791 } 1792 1793 static void 1794 adv_put_ready_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq, 1795 u_int q_no) 1796 { 1797 struct adv_target_transinfo* tinfo; 1798 u_int q_addr; 1799 u_int tid_no; 1800 1801 tid_no = ADV_TIX_TO_TID(scsiq->q2.target_ix); 1802 tinfo = &adv->tinfo[tid_no]; 1803 if ((tinfo->current.period != tinfo->goal.period) 1804 || (tinfo->current.offset != tinfo->goal.offset)) { 1805 1806 adv_msgout_sdtr(adv, tinfo->goal.period, tinfo->goal.offset); 1807 scsiq->q1.cntl |= QC_MSG_OUT; 1808 } 1809 q_addr = ADV_QNO_TO_QADDR(q_no); 1810 1811 scsiq->q1.status = QS_FREE; 1812 1813 adv_write_lram_16_multi(adv, q_addr + ADV_SCSIQ_CDB_BEG, 1814 (u_int16_t *)scsiq->cdbptr, 1815 scsiq->q2.cdb_len >> 1); 1816 1817 #if BYTE_ORDER == BIG_ENDIAN 1818 adv_adj_scsiq_endian(scsiq); 1819 #endif 1820 1821 adv_put_scsiq(adv, q_addr + ADV_SCSIQ_CPY_BEG, 1822 (u_int16_t *) &scsiq->q1.cntl, 1823 ((sizeof(scsiq->q1) + sizeof(scsiq->q2)) / 2) - 1); 1824 1825 #if defined(CC_WRITE_IO_COUNT) && CC_WRITE_IO_COUNT 1826 adv_write_lram_16(adv, q_addr + ADV_SCSIQ_W_REQ_COUNT, 1827 adv->req_count); 1828 #endif 1829 1830 #if defined(CC_CLEAR_DMA_REMAIN) && CC_CLEAR_DMA_REMAIN 1831 1832 adv_write_lram_32(adv, q_addr + ADV_SCSIQ_DW_REMAIN_XFER_ADDR, 0); 1833 adv_write_lram_32(adv, q_addr + ADV_SCSIQ_DW_REMAIN_XFER_CNT, 0); 1834 #endif 1835 1836 adv_write_lram_16(adv, q_addr + ADV_SCSIQ_B_STATUS, 1837 (scsiq->q1.q_no << 8) | QS_READY); 1838 } 1839 1840 static void 1841 adv_put_scsiq(struct adv_softc *adv, u_int16_t s_addr, 1842 u_int16_t *buffer, int words) 1843 { 1844 int i; 1845 1846 /* 1847 * XXX This routine makes *gross* assumptions 1848 * about padding in the data structures. 1849 * Either the data structures should have explicit 1850 * padding members added, or they should have padding 1851 * turned off via compiler attributes depending on 1852 * which yields better overall performance. My hunch 1853 * would be that turning off padding would be the 1854 * faster approach as an outsw is much faster than 1855 * this crude loop and accessing un-aligned data 1856 * members isn't *that* expensive. The other choice 1857 * would be to modify the ASC script so that the 1858 * the adv_scsiq_1 structure can be re-arranged so 1859 * padding isn't required. 1860 */ 1861 ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr); 1862 for (i = 0; i < words; i++, buffer++) { 1863 if (i == 2 || i == 10) { 1864 continue; 1865 } 1866 ADV_OUTW(adv, ADV_LRAM_DATA, *buffer); 1867 } 1868 } 1869 1870 static void 1871 adv_handle_extmsg_in(struct adv_softc *adv, u_int16_t halt_q_addr, 1872 u_int8_t q_cntl, target_bit_vector target_mask, 1873 int tid_no) 1874 { 1875 struct ext_msg ext_msg; 1876 1877 adv_read_lram_16_multi(adv, ADVV_MSGIN_BEG, (u_int16_t *) &ext_msg, 1878 sizeof(ext_msg) >> 1); 1879 if ((ext_msg.msg_type == MSG_EXTENDED) 1880 && (ext_msg.msg_req == MSG_EXT_SDTR) 1881 && (ext_msg.msg_len == MSG_EXT_SDTR_LEN)) { 1882 union ccb *ccb; 1883 struct adv_target_transinfo* tinfo; 1884 u_int32_t cinfo_index; 1885 u_int period; 1886 u_int offset; 1887 int sdtr_accept; 1888 u_int8_t orig_offset; 1889 1890 cinfo_index = 1891 adv_read_lram_32(adv, halt_q_addr + ADV_SCSIQ_D_CINFO_IDX); 1892 ccb = adv->ccb_infos[cinfo_index].ccb; 1893 tinfo = &adv->tinfo[tid_no]; 1894 sdtr_accept = TRUE; 1895 1896 orig_offset = ext_msg.req_ack_offset; 1897 if (ext_msg.xfer_period < tinfo->goal.period) { 1898 sdtr_accept = FALSE; 1899 ext_msg.xfer_period = tinfo->goal.period; 1900 } 1901 1902 /* Perform range checking */ 1903 period = ext_msg.xfer_period; 1904 offset = ext_msg.req_ack_offset; 1905 adv_period_offset_to_sdtr(adv, &period, &offset, tid_no); 1906 ext_msg.xfer_period = period; 1907 ext_msg.req_ack_offset = offset; 1908 1909 /* Record our current sync settings */ 1910 adv_set_syncrate(adv, ccb->ccb_h.path, 1911 tid_no, ext_msg.xfer_period, 1912 ext_msg.req_ack_offset, 1913 ADV_TRANS_GOAL|ADV_TRANS_ACTIVE); 1914 1915 /* Offset too high or large period forced async */ 1916 if (orig_offset != ext_msg.req_ack_offset) 1917 sdtr_accept = FALSE; 1918 1919 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) { 1920 /* Valid response to our requested negotiation */ 1921 q_cntl &= ~QC_MSG_OUT; 1922 } else { 1923 /* Must Respond */ 1924 q_cntl |= QC_MSG_OUT; 1925 adv_msgout_sdtr(adv, ext_msg.xfer_period, 1926 ext_msg.req_ack_offset); 1927 } 1928 1929 } else if (ext_msg.msg_type == MSG_EXTENDED 1930 && ext_msg.msg_req == MSG_EXT_WDTR 1931 && ext_msg.msg_len == MSG_EXT_WDTR_LEN) { 1932 1933 ext_msg.wdtr_width = 0; 1934 adv_write_lram_16_multi(adv, ADVV_MSGOUT_BEG, 1935 (u_int16_t *)&ext_msg, 1936 sizeof(ext_msg) >> 1); 1937 q_cntl |= QC_MSG_OUT; 1938 } else { 1939 1940 ext_msg.msg_type = MSG_MESSAGE_REJECT; 1941 adv_write_lram_16_multi(adv, ADVV_MSGOUT_BEG, 1942 (u_int16_t *)&ext_msg, 1943 sizeof(ext_msg) >> 1); 1944 q_cntl |= QC_MSG_OUT; 1945 } 1946 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL, q_cntl); 1947 } 1948 1949 static void 1950 adv_msgout_sdtr(struct adv_softc *adv, u_int8_t sdtr_period, 1951 u_int8_t sdtr_offset) 1952 { 1953 struct ext_msg sdtr_buf; 1954 1955 sdtr_buf.msg_type = MSG_EXTENDED; 1956 sdtr_buf.msg_len = MSG_EXT_SDTR_LEN; 1957 sdtr_buf.msg_req = MSG_EXT_SDTR; 1958 sdtr_buf.xfer_period = sdtr_period; 1959 sdtr_offset &= ADV_SYN_MAX_OFFSET; 1960 sdtr_buf.req_ack_offset = sdtr_offset; 1961 adv_write_lram_16_multi(adv, ADVV_MSGOUT_BEG, 1962 (u_int16_t *) &sdtr_buf, 1963 sizeof(sdtr_buf) / 2); 1964 } 1965 1966 int 1967 adv_abort_ccb(struct adv_softc *adv, int target, int lun, union ccb *ccb, 1968 u_int32_t status, int queued_only) 1969 { 1970 u_int16_t q_addr; 1971 u_int8_t q_no; 1972 struct adv_q_done_info scsiq_buf; 1973 struct adv_q_done_info *scsiq; 1974 u_int8_t target_ix; 1975 int count; 1976 1977 scsiq = &scsiq_buf; 1978 target_ix = ADV_TIDLUN_TO_IX(target, lun); 1979 count = 0; 1980 for (q_no = ADV_MIN_ACTIVE_QNO; q_no <= adv->max_openings; q_no++) { 1981 struct adv_ccb_info *ccb_info; 1982 q_addr = ADV_QNO_TO_QADDR(q_no); 1983 1984 adv_copy_lram_doneq(adv, q_addr, scsiq, adv->max_dma_count); 1985 ccb_info = &adv->ccb_infos[scsiq->d2.ccb_index]; 1986 if (((scsiq->q_status & QS_READY) != 0) 1987 && ((scsiq->q_status & QS_ABORTED) == 0) 1988 && ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0) 1989 && (scsiq->d2.target_ix == target_ix) 1990 && (queued_only == 0 1991 || !(scsiq->q_status & (QS_DISC1|QS_DISC2|QS_BUSY|QS_DONE))) 1992 && (ccb == NULL || (ccb == ccb_info->ccb))) { 1993 union ccb *aborted_ccb; 1994 struct adv_ccb_info *cinfo; 1995 1996 scsiq->q_status |= QS_ABORTED; 1997 adv_write_lram_8(adv, q_addr + ADV_SCSIQ_B_STATUS, 1998 scsiq->q_status); 1999 aborted_ccb = ccb_info->ccb; 2000 /* Don't clobber earlier error codes */ 2001 if ((aborted_ccb->ccb_h.status & CAM_STATUS_MASK) 2002 == CAM_REQ_INPROG) 2003 aborted_ccb->ccb_h.status |= status; 2004 cinfo = (struct adv_ccb_info *) 2005 aborted_ccb->ccb_h.ccb_cinfo_ptr; 2006 cinfo->state |= ACCB_ABORT_QUEUED; 2007 count++; 2008 } 2009 } 2010 return (count); 2011 } 2012 2013 int 2014 adv_reset_bus(struct adv_softc *adv, int initiate_bus_reset) 2015 { 2016 int count; 2017 int i; 2018 union ccb *ccb; 2019 2020 i = 200; 2021 while ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_SCSI_RESET_ACTIVE) != 0 2022 && i--) 2023 DELAY(1000); 2024 adv_reset_chip(adv, initiate_bus_reset); 2025 adv_reinit_lram(adv); 2026 for (i = 0; i <= ADV_MAX_TID; i++) 2027 adv_set_syncrate(adv, NULL, i, /*period*/0, 2028 /*offset*/0, ADV_TRANS_CUR); 2029 ADV_OUTW(adv, ADV_REG_PROG_COUNTER, ADV_MCODE_START_ADDR); 2030 2031 /* Tell the XPT layer that a bus reset occured */ 2032 if (adv->path != NULL) 2033 xpt_async(AC_BUS_RESET, adv->path, NULL); 2034 2035 count = 0; 2036 while ((ccb = (union ccb *)LIST_FIRST(&adv->pending_ccbs)) != NULL) { 2037 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) 2038 ccb->ccb_h.status |= CAM_SCSI_BUS_RESET; 2039 adv_done(adv, ccb, QD_ABORTED_BY_HOST, 0, 0, 0); 2040 count++; 2041 } 2042 2043 adv_start_chip(adv); 2044 return (count); 2045 } 2046 2047 static void 2048 adv_set_sdtr_reg_at_id(struct adv_softc *adv, int tid, u_int8_t sdtr_data) 2049 { 2050 int orig_id; 2051 2052 adv_set_bank(adv, 1); 2053 orig_id = ffs(ADV_INB(adv, ADV_HOST_SCSIID)) - 1; 2054 ADV_OUTB(adv, ADV_HOST_SCSIID, tid); 2055 if (ADV_INB(adv, ADV_HOST_SCSIID) == (0x01 << tid)) { 2056 adv_set_bank(adv, 0); 2057 ADV_OUTB(adv, ADV_SYN_OFFSET, sdtr_data); 2058 } 2059 adv_set_bank(adv, 1); 2060 ADV_OUTB(adv, ADV_HOST_SCSIID, orig_id); 2061 adv_set_bank(adv, 0); 2062 } 2063