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