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