1 /* $OpenBSD: ahd_pci.c,v 1.21 2012/12/05 23:20:19 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2004 Milos Urbanek, Kenneth R. Westerback & Marco Peereboom 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 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 */ 29 30 /* 31 * Product specific probe and attach routines for: 32 * aic7901 and aic7902 SCSI controllers 33 * 34 * Copyright (c) 1994-2001 Justin T. Gibbs. 35 * Copyright (c) 2000-2002 Adaptec Inc. 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions, and the following disclaimer, 43 * without modification. 44 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 45 * substantially similar to the "NO WARRANTY" disclaimer below 46 * ("Disclaimer") and any redistribution must be conditioned upon 47 * including a substantially similar Disclaimer requirement for further 48 * binary redistribution. 49 * 3. Neither the names of the above-listed copyright holders nor the names 50 * of any contributors may be used to endorse or promote products derived 51 * from this software without specific prior written permission. 52 * 53 * Alternatively, this software may be distributed under the terms of the 54 * GNU General Public License ("GPL") version 2 as published by the Free 55 * Software Foundation. 56 * 57 * NO WARRANTY 58 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 59 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 60 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 61 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 62 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 66 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 67 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 68 * POSSIBILITY OF SUCH DAMAGES. 69 * 70 */ 71 72 #include <dev/ic/aic79xx_openbsd.h> 73 #include <dev/ic/aic79xx_inline.h> 74 #include <dev/ic/aic79xx.h> 75 76 #include <dev/pci/pcivar.h> 77 78 __inline uint64_t ahd_compose_id(u_int, u_int, u_int, u_int); 79 __inline uint64_t 80 ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) 81 { 82 uint64_t id; 83 84 id = subvendor 85 | (subdevice << 16) 86 | ((uint64_t)vendor << 32) 87 | ((uint64_t)device << 48); 88 89 return (id); 90 } 91 92 #define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull 93 #define ID_ALL_IROC_MASK 0xFF7FFFFFFFFFFFFFull 94 #define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull 95 #define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull 96 #define ID_9005_GENERIC_IROC_MASK 0xFF70FFFF00000000ull 97 98 #define ID_AIC7901 0x800F9005FFFF9005ull 99 #define ID_AHA_29320A 0x8000900500609005ull 100 #define ID_AHA_29320ALP 0x8017900500449005ull 101 #define ID_AHA_29320LPE 0x8017900500459005ull 102 103 #define ID_AIC7901A 0x801E9005FFFF9005ull 104 #define ID_AHA_29320LP 0x8014900500449005ull 105 106 #define ID_AIC7902 0x801F9005FFFF9005ull 107 #define ID_AIC7902_B 0x801D9005FFFF9005ull 108 #define ID_AHA_39320 0x8010900500409005ull 109 #define ID_AHA_29320 0x8012900500429005ull 110 #define ID_AHA_29320B 0x8013900500439005ull 111 #define ID_AHA_39320_B 0x8015900500409005ull 112 #define ID_AHA_39320_B_DELL 0x8015900501681028ull 113 #define ID_AHA_39320A 0x8016900500409005ull 114 #define ID_AHA_39320D 0x8011900500419005ull 115 #define ID_AHA_39320D_B 0x801C900500419005ull 116 #define ID_AHA_39320D_HP 0x8011900500AC0E11ull 117 #define ID_AHA_39320D_B_HP 0x801C900500AC0E11ull 118 #define ID_AIC7902_PCI_REV_A4 0x3 119 #define ID_AIC7902_PCI_REV_B0 0x10 120 #define SUBID_HP 0x0E11 121 122 #define DEVID_9005_HOSTRAID(id) ((id) & 0x80) 123 124 #define DEVID_9005_TYPE(id) ((id) & 0xF) 125 #define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */ 126 #define DEVID_9005_TYPE_HBA_2EXT 0x1 /* 2 External Ports */ 127 #define DEVID_9005_TYPE_MB 0xF /* On Motherboard */ 128 129 #define DEVID_9005_MFUNC(id) ((id) & 0x10) 130 131 #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000) 132 133 #define SUBID_9005_TYPE(id) ((id) & 0xF) 134 #define SUBID_9005_TYPE_HBA 0x0 /* Standard Card */ 135 #define SUBID_9005_TYPE_MB 0xF /* On Motherboard */ 136 137 #define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0) 138 139 #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20) 140 141 #define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6) 142 #define SUBID_9005_SEEPTYPE_NONE 0x0 143 #define SUBID_9005_SEEPTYPE_4K 0x1 144 145 ahd_device_setup_t ahd_aic7901_setup; 146 ahd_device_setup_t ahd_aic7901A_setup; 147 ahd_device_setup_t ahd_aic7902_setup; 148 ahd_device_setup_t ahd_aic790X_setup; 149 150 struct ahd_pci_identity ahd_pci_ident_table [] = 151 { 152 /* aic7901 based controllers */ 153 { 154 ID_AHA_29320A, 155 ID_ALL_MASK, 156 ahd_aic7901_setup 157 }, 158 { 159 ID_AHA_29320ALP, 160 ID_ALL_MASK, 161 ahd_aic7901_setup 162 }, 163 { 164 ID_AHA_29320LPE, 165 ID_ALL_MASK, 166 ahd_aic7901_setup 167 }, 168 /* aic7901A based controllers */ 169 { 170 ID_AHA_29320LP, 171 ID_ALL_MASK, 172 ahd_aic7901A_setup 173 }, 174 /* aic7902 based controllers */ 175 { 176 ID_AHA_29320, 177 ID_ALL_MASK, 178 ahd_aic7902_setup 179 }, 180 { 181 ID_AHA_29320B, 182 ID_ALL_MASK, 183 ahd_aic7902_setup 184 }, 185 { 186 ID_AHA_39320, 187 ID_ALL_MASK, 188 ahd_aic7902_setup 189 }, 190 { 191 ID_AHA_39320_B, 192 ID_ALL_MASK, 193 ahd_aic7902_setup 194 }, 195 { 196 ID_AHA_39320_B_DELL, 197 ID_ALL_MASK, 198 ahd_aic7902_setup 199 }, 200 { 201 ID_AHA_39320A, 202 ID_ALL_MASK, 203 ahd_aic7902_setup 204 }, 205 { 206 ID_AHA_39320D, 207 ID_ALL_MASK, 208 ahd_aic7902_setup 209 }, 210 { 211 ID_AHA_39320D_HP, 212 ID_ALL_MASK, 213 ahd_aic7902_setup 214 }, 215 { 216 ID_AHA_39320D_B, 217 ID_ALL_MASK, 218 ahd_aic7902_setup 219 }, 220 { 221 ID_AHA_39320D_B_HP, 222 ID_ALL_MASK, 223 ahd_aic7902_setup 224 }, 225 /* Generic chip probes for devices we don't know 'exactly' */ 226 { 227 ID_AIC7901 & ID_9005_GENERIC_MASK, 228 ID_9005_GENERIC_MASK, 229 ahd_aic7901_setup 230 }, 231 { 232 ID_AIC7901A & ID_DEV_VENDOR_MASK, 233 ID_DEV_VENDOR_MASK, 234 ahd_aic7901A_setup 235 }, 236 { 237 ID_AIC7902 & ID_9005_GENERIC_MASK, 238 ID_9005_GENERIC_MASK, 239 ahd_aic7902_setup 240 } 241 }; 242 243 const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table); 244 245 #define DEVCONFIG 0x40 246 #define PCIXINITPAT 0x0000E000ul 247 #define PCIXINIT_PCI33_66 0x0000E000ul 248 #define PCIXINIT_PCIX50_66 0x0000C000ul 249 #define PCIXINIT_PCIX66_100 0x0000A000ul 250 #define PCIXINIT_PCIX100_133 0x00008000ul 251 #define PCI_BUS_MODES_INDEX(devconfig) \ 252 (((devconfig) & PCIXINITPAT) >> 13) 253 254 static const char *pci_bus_modes[] = 255 { 256 "PCI bus mode unknown", 257 "PCI bus mode unknown", 258 "PCI bus mode unknown", 259 "PCI bus mode unknown", 260 "PCI-X 101-133MHz", 261 "PCI-X 67-100MHz", 262 "PCI-X 50-66MHz", 263 "PCI 33 or 66MHz" 264 }; 265 266 #define TESTMODE 0x00000800ul 267 #define IRDY_RST 0x00000200ul 268 #define FRAME_RST 0x00000100ul 269 #define PCI64BIT 0x00000080ul 270 #define MRDCEN 0x00000040ul 271 #define ENDIANSEL 0x00000020ul 272 #define MIXQWENDIANEN 0x00000008ul 273 #define DACEN 0x00000004ul 274 #define STPWLEVEL 0x00000002ul 275 #define QWENDIANSEL 0x00000001ul 276 277 #define DEVCONFIG1 0x44 278 #define PREQDIS 0x01 279 280 #define CSIZE_LATTIME 0x0c 281 #define CACHESIZE 0x000000fful 282 #define LATTIME 0x0000ff00ul 283 284 int ahd_pci_probe(struct device *, void *, void *); 285 void ahd_pci_attach(struct device *, struct device *, void *); 286 287 struct cfattach ahd_pci_ca = { 288 sizeof(struct ahd_softc), ahd_pci_probe, ahd_pci_attach 289 }; 290 291 int ahd_check_extport(struct ahd_softc *ahd); 292 void ahd_configure_termination(struct ahd_softc *ahd, 293 u_int adapter_control); 294 void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat); 295 296 const struct ahd_pci_identity * 297 ahd_find_pci_device(pcireg_t id, pcireg_t subid) 298 { 299 const struct ahd_pci_identity *entry; 300 u_int64_t full_id; 301 u_int i; 302 303 full_id = ahd_compose_id(PCI_PRODUCT(id), PCI_VENDOR(id), 304 PCI_PRODUCT(subid), PCI_VENDOR(subid)); 305 306 /* 307 * If we are configured to attach to HostRAID 308 * controllers, mask out the IROC/HostRAID bit 309 * in the 310 */ 311 if (ahd_attach_to_HostRAID_controllers) 312 full_id &= ID_ALL_IROC_MASK; 313 314 for (i = 0; i < ahd_num_pci_devs; i++) { 315 entry = &ahd_pci_ident_table[i]; 316 if (entry->full_id == (full_id & entry->id_mask)) { 317 return (entry); 318 } 319 } 320 return (NULL); 321 } 322 323 int 324 ahd_pci_probe(struct device *parent, void *match, void *aux) 325 { 326 const struct ahd_pci_identity *entry; 327 struct pci_attach_args *pa = aux; 328 pcireg_t subid; 329 330 subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); 331 entry = ahd_find_pci_device(pa->pa_id, subid); 332 return entry != NULL ? 1 : 0; 333 } 334 335 void 336 ahd_pci_attach(struct device *parent, struct device *self, void *aux) 337 { 338 const struct ahd_pci_identity *entry; 339 struct pci_attach_args *pa = aux; 340 struct ahd_softc *ahd = (void *)self; 341 pci_intr_handle_t ih; 342 const char *intrstr; 343 pcireg_t devconfig, memtype, subid; 344 uint16_t device, subvendor; 345 int error, ioh_valid, ioh2_valid, l, memh_valid; 346 347 ahd->dev_softc = pa; 348 ahd->parent_dmat = pa->pa_dmat; 349 350 if (ahd_alloc(ahd, ahd->sc_dev.dv_xname) == NULL) 351 return; 352 353 subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); 354 entry = ahd_find_pci_device(pa->pa_id, subid); 355 if (entry == NULL) 356 return; 357 358 /* 359 * Record if this is a HostRAID board. 360 */ 361 device = PCI_PRODUCT(pa->pa_id); 362 if (DEVID_9005_HOSTRAID(device)) 363 ahd->flags |= AHD_HOSTRAID_BOARD; 364 365 /* 366 * Record if this is an HP board. 367 */ 368 subvendor = PCI_VENDOR(subid); 369 if (subvendor == SUBID_HP) 370 ahd->flags |= AHD_HP_BOARD; 371 372 error = entry->setup(ahd, pa); 373 if (error != 0) 374 return; 375 376 /* XXX ahc on sparc64 needs this twice */ 377 devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG); 378 379 if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) { 380 ahd->chip |= AHD_PCI; 381 /* Disable PCIX workarounds when running in PCI mode. */ 382 ahd->bugs &= ~AHD_PCIX_BUG_MASK; 383 } else { 384 ahd->chip |= AHD_PCIX; 385 } 386 ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)]; 387 388 memh_valid = ioh_valid = ioh2_valid = 0; 389 390 if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIX, 391 &ahd->pcix_off, NULL)) { 392 if (ahd->chip & AHD_PCIX) 393 printf("%s: warning: can't find PCI-X capability\n", 394 ahd_name(ahd)); 395 ahd->chip &= ~AHD_PCIX; 396 ahd->chip |= AHD_PCI; 397 ahd->bugs &= ~AHD_PCIX_BUG_MASK; 398 } 399 400 /* 401 * Map PCI registers 402 */ 403 if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) == 0) { 404 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, 405 AHD_PCI_MEMADDR); 406 switch (memtype) { 407 case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: 408 case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: 409 memh_valid = (pci_mapreg_map(pa, AHD_PCI_MEMADDR, 410 memtype, 0, &ahd->tags[0], &ahd->bshs[0], NULL, 411 NULL, 0) == 0); 412 if (memh_valid) { 413 ahd->tags[1] = ahd->tags[0]; 414 bus_space_subregion(ahd->tags[0], ahd->bshs[0], 415 /*offset*/0x100, /*size*/0x100, 416 &ahd->bshs[1]); 417 if (ahd_pci_test_register_access(ahd) != 0) 418 memh_valid = 0; 419 } 420 break; 421 default: 422 memh_valid = 0; 423 printf("%s: unknown memory type: 0x%x\n", 424 ahd_name(ahd), memtype); 425 break; 426 } 427 428 #ifdef AHD_DEBUG 429 printf("%s: doing memory mapping tag0 0x%x, tag1 0x%x, shs0 " 430 "0x%lx, shs1 0x%lx\n", ahd_name(ahd), ahd->tags[0], 431 ahd->tags[1], ahd->bshs[0], ahd->bshs[1]); 432 #endif 433 } 434 435 if (!memh_valid) { 436 /* First BAR */ 437 ioh_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR, 438 PCI_MAPREG_TYPE_IO, 0, &ahd->tags[0], &ahd->bshs[0], NULL, 439 NULL, 0) == 0); 440 441 /* 2nd BAR */ 442 ioh2_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR1, 443 PCI_MAPREG_TYPE_IO, 0, &ahd->tags[1], &ahd->bshs[1], NULL, 444 NULL, 0) == 0); 445 446 #ifdef AHD_DEBUG 447 printf("%s: doing io mapping tag0 0x%x, tag1 0x%x, shs0 0x%lx, " 448 "shs1 0x%lx\n", ahd_name(ahd), ahd->tags[0], ahd->tags[1], 449 ahd->bshs[0], ahd->bshs[1]); 450 #endif 451 } 452 453 if (memh_valid == 0 && (ioh_valid == 0 || ioh2_valid == 0)) { 454 printf("%s: unable to map registers\n", ahd_name(ahd)); 455 return; 456 } 457 458 /* 459 * Set Power State D0. 460 */ 461 pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); 462 463 /* 464 * Should we bother disabling 39Bit addressing 465 * based on installed memory? 466 */ 467 if (sizeof(bus_addr_t) > 4) 468 ahd->flags |= AHD_39BIT_ADDRESSING; 469 470 /* 471 * If we need to support high memory, enable dual 472 * address cycles. This bit must be set to enable 473 * high address bit generation even if we are on a 474 * 64bit bus (PCI64BIT set in devconfig). 475 */ 476 if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) { 477 if (bootverbose) 478 printf("%s: Enabling 39Bit Addressing\n", 479 ahd_name(ahd)); 480 devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG); 481 devconfig |= DACEN; 482 pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG, devconfig); 483 } 484 485 ahd_softc_init(ahd); 486 487 /* 488 * Map the interrupts routines 489 */ 490 ahd->bus_intr = ahd_pci_intr; 491 492 error = ahd_reset(ahd, /*reinit*/FALSE); 493 if (error != 0) { 494 ahd_free(ahd); 495 return; 496 } 497 498 if (pci_intr_map(pa, &ih)) { 499 printf("%s: couldn't map interrupt\n", ahd_name(ahd)); 500 ahd_free(ahd); 501 return; 502 } 503 intrstr = pci_intr_string(pa->pa_pc, ih); 504 ahd->ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, 505 ahd_platform_intr, ahd, ahd->sc_dev.dv_xname); 506 if (ahd->ih == NULL) { 507 printf("%s: couldn't establish interrupt", ahd_name(ahd)); 508 if (intrstr != NULL) 509 printf(" at %s", intrstr); 510 printf("\n"); 511 ahd_free(ahd); 512 return; 513 } 514 if (intrstr != NULL) 515 printf(": %s\n", intrstr); 516 517 /* Get the size of the cache */ 518 ahd->pci_cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG); 519 ahd->pci_cachesize *= 4; 520 521 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); 522 /* See if we have a SEEPROM and perform auto-term */ 523 error = ahd_check_extport(ahd); 524 if (error != 0) 525 return; 526 527 /* Core initialization */ 528 error = ahd_init(ahd); 529 if (error != 0) 530 return; 531 532 ahd_list_lock(&l); 533 /* 534 * Link this softc in with all other ahd instances. 535 */ 536 ahd_softc_insert(ahd); 537 ahd_list_unlock(&l); 538 539 /* complete the attach */ 540 ahd_attach(ahd); 541 } 542 543 /* 544 * Perform some simple tests that should catch situations where 545 * our registers are invalidly mapped. 546 */ 547 int 548 ahd_pci_test_register_access(struct ahd_softc *ahd) 549 { 550 const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc; 551 const pcitag_t tag = ahd->dev_softc->pa_tag; 552 pcireg_t cmd; 553 u_int targpcistat; 554 pcireg_t pci_status1; 555 int error; 556 uint8_t hcntrl; 557 558 error = EIO; 559 560 /* 561 * Enable PCI error interrupt status, but suppress NMIs 562 * generated by SERR raised due to target aborts. 563 */ 564 cmd = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 565 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, 566 cmd & ~PCI_COMMAND_SERR_ENABLE); 567 568 /* 569 * First a simple test to see if any 570 * registers can be read. Reading 571 * HCNTRL has no side effects and has 572 * at least one bit that is guaranteed to 573 * be zero so it is a good register to 574 * use for this test. 575 */ 576 hcntrl = ahd_inb(ahd, HCNTRL); 577 if (hcntrl == 0xFF) 578 goto fail; 579 580 /* 581 * Next create a situation where write combining 582 * or read prefetching could be initiated by the 583 * CPU or host bridge. Our device does not support 584 * either, so look for data corruption and/or flaged 585 * PCI errors. First pause without causing another 586 * chip reset. 587 */ 588 hcntrl &= ~CHIPRST; 589 ahd_outb(ahd, HCNTRL, hcntrl|PAUSE); 590 while (ahd_is_paused(ahd) == 0) 591 ; 592 593 /* Clear any PCI errors that occurred before our driver attached. */ 594 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); 595 targpcistat = ahd_inb(ahd, TARGPCISTAT); 596 ahd_outb(ahd, TARGPCISTAT, targpcistat); 597 pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 598 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, pci_status1); 599 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); 600 ahd_outb(ahd, CLRINT, CLRPCIINT); 601 602 ahd_outb(ahd, SEQCTL0, PERRORDIS); 603 ahd_outl(ahd, SRAM_BASE, 0x5aa555aa); 604 if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa) 605 goto fail; 606 607 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) { 608 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); 609 targpcistat = ahd_inb(ahd, TARGPCISTAT); 610 if ((targpcistat & STA) != 0) 611 goto fail; 612 } 613 614 error = 0; 615 616 fail: 617 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) { 618 619 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); 620 targpcistat = ahd_inb(ahd, TARGPCISTAT); 621 622 /* Silently clear any latched errors. */ 623 ahd_outb(ahd, TARGPCISTAT, targpcistat); 624 pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 625 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, pci_status1); 626 ahd_outb(ahd, CLRINT, CLRPCIINT); 627 } 628 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS); 629 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmd); 630 return (error); 631 } 632 633 /* 634 * Check the external port logic for a serial eeprom 635 * and termination/cable detection contrls. 636 */ 637 int 638 ahd_check_extport(struct ahd_softc *ahd) 639 { 640 struct vpd_config vpd; 641 struct seeprom_config *sc; 642 u_int adapter_control; 643 int have_seeprom; 644 int error; 645 646 sc = ahd->seep_config; 647 have_seeprom = ahd_acquire_seeprom(ahd); 648 if (have_seeprom) { 649 u_int start_addr; 650 651 /* 652 * Fetch VPD for this function and parse it. 653 */ 654 if (bootverbose) 655 printf("%s: Reading VPD from SEEPROM...", 656 ahd_name(ahd)); 657 658 /* Address is always in units of 16bit words */ 659 start_addr = ((2 * sizeof(*sc)) 660 + (sizeof(vpd) * (ahd->channel - 'A'))) / 2; 661 662 error = ahd_read_seeprom(ahd, (uint16_t *)&vpd, 663 start_addr, sizeof(vpd)/2, 664 /*bytestream*/TRUE); 665 if (error == 0) 666 error = ahd_parse_vpddata(ahd, &vpd); 667 if (bootverbose) 668 printf("%s: VPD parsing %s\n", 669 ahd_name(ahd), 670 error == 0 ? "successful" : "failed"); 671 672 if (bootverbose) 673 printf("%s: Reading SEEPROM...", ahd_name(ahd)); 674 675 /* Address is always in units of 16bit words */ 676 start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A'); 677 678 error = ahd_read_seeprom(ahd, (uint16_t *)sc, 679 start_addr, sizeof(*sc)/2, 680 /*bytestream*/FALSE); 681 682 if (error != 0) { 683 printf("Unable to read SEEPROM\n"); 684 have_seeprom = 0; 685 } else { 686 have_seeprom = ahd_verify_cksum(sc); 687 688 if (bootverbose) { 689 if (have_seeprom == 0) 690 printf ("checksum error\n"); 691 else 692 printf ("done.\n"); 693 } 694 } 695 ahd_release_seeprom(ahd); 696 } 697 698 if (!have_seeprom) { 699 u_int nvram_scb; 700 701 /* 702 * Pull scratch ram settings and treat them as 703 * if they are the contents of an seeprom if 704 * the 'ADPT', 'BIOS', or 'ASPI' signature is found 705 * in SCB 0xFF. We manually compose the data as 16bit 706 * values to avoid endian issues. 707 */ 708 ahd_set_scbptr(ahd, 0xFF); 709 nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET); 710 if (nvram_scb != 0xFF 711 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A' 712 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D' 713 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P' 714 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T') 715 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B' 716 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I' 717 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O' 718 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S') 719 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A' 720 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S' 721 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P' 722 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) { 723 uint16_t *sc_data; 724 int i; 725 726 ahd_set_scbptr(ahd, nvram_scb); 727 sc_data = (uint16_t *)sc; 728 for (i = 0; i < 64; i += 2) 729 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i); 730 have_seeprom = ahd_verify_cksum(sc); 731 if (have_seeprom) 732 ahd->flags |= AHD_SCB_CONFIG_USED; 733 } 734 } 735 736 #ifdef AHD_DEBUG 737 if (have_seeprom != 0 738 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) { 739 uint16_t *sc_data; 740 int i; 741 742 printf("%s: Seeprom Contents:", ahd_name(ahd)); 743 sc_data = (uint16_t *)sc; 744 for (i = 0; i < (sizeof(*sc)); i += 2) 745 printf("\n\t0x%.4x", sc_data[i]); 746 printf("\n"); 747 } 748 #endif 749 750 if (!have_seeprom) { 751 if (bootverbose) 752 printf("%s: No SEEPROM available.\n", ahd_name(ahd)); 753 ahd->flags |= AHD_USEDEFAULTS; 754 error = ahd_default_config(ahd); 755 adapter_control = CFAUTOTERM|CFSEAUTOTERM; 756 free(ahd->seep_config, M_DEVBUF); 757 ahd->seep_config = NULL; 758 } else { 759 error = ahd_parse_cfgdata(ahd, sc); 760 adapter_control = sc->adapter_control; 761 } 762 if (error != 0) 763 return (error); 764 765 ahd_configure_termination(ahd, adapter_control); 766 767 return (0); 768 } 769 770 void 771 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control) 772 { 773 const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc; 774 const pcitag_t tag = ahd->dev_softc->pa_tag; 775 int error; 776 u_int sxfrctl1; 777 uint8_t termctl; 778 pcireg_t devconfig; 779 780 devconfig = pci_conf_read(pc, tag, DEVCONFIG); 781 devconfig &= ~STPWLEVEL; 782 if ((ahd->flags & AHD_STPWLEVEL_A) != 0) 783 devconfig |= STPWLEVEL; 784 if (bootverbose) 785 printf("%s: STPWLEVEL is %s\n", 786 ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off"); 787 pci_conf_write(pc, tag, DEVCONFIG, devconfig); 788 789 /* Make sure current sensing is off. */ 790 if ((ahd->flags & AHD_CURRENT_SENSING) != 0) { 791 (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0); 792 } 793 794 /* 795 * Read to sense. Write to set. 796 */ 797 error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl); 798 if ((adapter_control & CFAUTOTERM) == 0) { 799 if (bootverbose) 800 printf("%s: Manual Primary Termination\n", 801 ahd_name(ahd)); 802 termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH); 803 if ((adapter_control & CFSTERM) != 0) 804 termctl |= FLX_TERMCTL_ENPRILOW; 805 if ((adapter_control & CFWSTERM) != 0) 806 termctl |= FLX_TERMCTL_ENPRIHIGH; 807 } else if (error != 0) { 808 printf("%s: Primary Auto-Term Sensing failed! " 809 "Using Defaults.\n", ahd_name(ahd)); 810 termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH; 811 } 812 813 if ((adapter_control & CFSEAUTOTERM) == 0) { 814 if (bootverbose) 815 printf("%s: Manual Secondary Termination\n", 816 ahd_name(ahd)); 817 termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH); 818 if ((adapter_control & CFSELOWTERM) != 0) 819 termctl |= FLX_TERMCTL_ENSECLOW; 820 if ((adapter_control & CFSEHIGHTERM) != 0) 821 termctl |= FLX_TERMCTL_ENSECHIGH; 822 } else if (error != 0) { 823 printf("%s: Secondary Auto-Term Sensing failed! " 824 "Using Defaults.\n", ahd_name(ahd)); 825 termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH; 826 } 827 828 /* 829 * Now set the termination based on what we found. 830 */ 831 sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN; 832 ahd->flags &= ~AHD_TERM_ENB_A; 833 if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) { 834 ahd->flags |= AHD_TERM_ENB_A; 835 sxfrctl1 |= STPWEN; 836 } 837 /* Must set the latch once in order to be effective. */ 838 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN); 839 ahd_outb(ahd, SXFRCTL1, sxfrctl1); 840 841 error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl); 842 if (error != 0) { 843 printf("%s: Unable to set termination settings!\n", 844 ahd_name(ahd)); 845 } else if (bootverbose) { 846 printf("%s: Primary High byte termination %sabled\n", 847 ahd_name(ahd), 848 (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis"); 849 850 printf("%s: Primary Low byte termination %sabled\n", 851 ahd_name(ahd), 852 (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis"); 853 854 printf("%s: Secondary High byte termination %sabled\n", 855 ahd_name(ahd), 856 (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis"); 857 858 printf("%s: Secondary Low byte termination %sabled\n", 859 ahd_name(ahd), 860 (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis"); 861 } 862 return; 863 } 864 865 #define DPE 0x80 866 #define SSE 0x40 867 #define RMA 0x20 868 #define RTA 0x10 869 #define STA 0x08 870 #define DPR 0x01 871 872 static const char *split_status_source[] = 873 { 874 "DFF0", 875 "DFF1", 876 "OVLY", 877 "CMC", 878 }; 879 880 static const char *pci_status_source[] = 881 { 882 "DFF0", 883 "DFF1", 884 "SG", 885 "CMC", 886 "OVLY", 887 "NONE", 888 "MSI", 889 "TARG" 890 }; 891 892 static const char *split_status_strings[] = 893 { 894 "%s: Received split response in %s.\n", 895 "%s: Received split completion error message in %s\n", 896 "%s: Receive overrun in %s\n", 897 "%s: Count not complete in %s\n", 898 "%s: Split completion data bucket in %s\n", 899 "%s: Split completion address error in %s\n", 900 "%s: Split completion byte count error in %s\n", 901 "%s: Signaled Target-abort to early terminate a split in %s\n" 902 }; 903 904 static const char *pci_status_strings[] = 905 { 906 "%s: Data Parity Error has been reported via PERR# in %s\n", 907 "%s: Target initial wait state error in %s\n", 908 "%s: Split completion read data parity error in %s\n", 909 "%s: Split completion address attribute parity error in %s\n", 910 "%s: Received a Target Abort in %s\n", 911 "%s: Received a Master Abort in %s\n", 912 "%s: Signal System Error Detected in %s\n", 913 "%s: Address or Write Phase Parity Error Detected in %s.\n" 914 }; 915 916 void 917 ahd_pci_intr(struct ahd_softc *ahd) 918 { 919 const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc; 920 const pcitag_t tag = ahd->dev_softc->pa_tag; 921 uint8_t pci_status[8]; 922 ahd_mode_state saved_modes; 923 pcireg_t pci_status1; 924 u_int intstat; 925 u_int i; 926 u_int reg; 927 928 intstat = ahd_inb(ahd, INTSTAT); 929 930 if ((intstat & SPLTINT) != 0) 931 ahd_pci_split_intr(ahd, intstat); 932 933 if ((intstat & PCIINT) == 0) 934 return; 935 936 printf("%s: PCI error Interrupt\n", ahd_name(ahd)); 937 saved_modes = ahd_save_modes(ahd); 938 ahd_dump_card_state(ahd); 939 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG); 940 for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) { 941 942 if (i == 5) 943 continue; 944 pci_status[i] = ahd_inb(ahd, reg); 945 /* Clear latched errors. So our interrupt deasserts. */ 946 ahd_outb(ahd, reg, pci_status[i]); 947 } 948 949 for (i = 0; i < 8; i++) { 950 u_int bit; 951 952 if (i == 5) 953 continue; 954 955 for (bit = 0; bit < 8; bit++) { 956 957 if ((pci_status[i] & (0x1 << bit)) != 0) { 958 static const char *s; 959 960 s = pci_status_strings[bit]; 961 if (i == 7/*TARG*/ && bit == 3) 962 s = "%s: Signaled Target Abort\n"; 963 printf(s, ahd_name(ahd), pci_status_source[i]); 964 } 965 } 966 } 967 pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 968 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG , pci_status1); 969 970 ahd_restore_modes(ahd, saved_modes); 971 ahd_outb(ahd, CLRINT, CLRPCIINT); 972 ahd_unpause(ahd); 973 974 return; 975 } 976 977 void 978 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat) 979 { 980 const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc; 981 const pcitag_t tag = ahd->dev_softc->pa_tag; 982 uint8_t split_status[4]; 983 uint8_t split_status1[4]; 984 uint8_t sg_split_status[2]; 985 uint8_t sg_split_status1[2]; 986 ahd_mode_state saved_modes; 987 u_int i; 988 pcireg_t pcix_status; 989 990 /* 991 * Check for splits in all modes. Modes 0 and 1 992 * additionally have SG engine splits to look at. 993 */ 994 pcix_status = pci_conf_read(pc, tag, ahd->pcix_off + 0x04); 995 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n", 996 ahd_name(ahd), pcix_status); 997 998 saved_modes = ahd_save_modes(ahd); 999 for (i = 0; i < 4; i++) { 1000 ahd_set_modes(ahd, i, i); 1001 1002 split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0); 1003 split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1); 1004 /* Clear latched errors. So our interrupt deasserts. */ 1005 ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]); 1006 ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]); 1007 if (i > 1) 1008 continue; 1009 sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0); 1010 sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1); 1011 /* Clear latched errors. So our interrupt deasserts. */ 1012 ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]); 1013 ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]); 1014 } 1015 1016 for (i = 0; i < 4; i++) { 1017 u_int bit; 1018 1019 for (bit = 0; bit < 8; bit++) { 1020 1021 if ((split_status[i] & (0x1 << bit)) != 0) { 1022 static const char *s; 1023 1024 s = split_status_strings[bit]; 1025 printf(s, ahd_name(ahd), 1026 split_status_source[i]); 1027 } 1028 1029 if (i > 1) 1030 continue; 1031 1032 if ((sg_split_status[i] & (0x1 << bit)) != 0) { 1033 static const char *s; 1034 1035 s = split_status_strings[bit]; 1036 printf(s, ahd_name(ahd), "SG"); 1037 } 1038 } 1039 } 1040 /* 1041 * Clear PCI-X status bits. 1042 */ 1043 pci_conf_write(pc, tag, ahd->pcix_off + 0x04, pcix_status); 1044 ahd_outb(ahd, CLRINT, CLRSPLTINT); 1045 ahd_restore_modes(ahd, saved_modes); 1046 } 1047 1048 int 1049 ahd_aic7901_setup(struct ahd_softc *ahd, struct pci_attach_args *pa) 1050 { 1051 1052 ahd->chip = AHD_AIC7901; 1053 ahd->features = AHD_AIC7901_FE; 1054 return (ahd_aic790X_setup(ahd, pa)); 1055 } 1056 1057 int 1058 ahd_aic7901A_setup(struct ahd_softc *ahd, struct pci_attach_args *pa) 1059 { 1060 1061 ahd->chip = AHD_AIC7901A; 1062 ahd->features = AHD_AIC7901A_FE; 1063 return (ahd_aic790X_setup(ahd, pa)); 1064 } 1065 1066 int 1067 ahd_aic7902_setup(struct ahd_softc *ahd, struct pci_attach_args *pa) 1068 { 1069 ahd->chip = AHD_AIC7902; 1070 ahd->features = AHD_AIC7902_FE; 1071 return (ahd_aic790X_setup(ahd, pa)); 1072 } 1073 1074 int 1075 ahd_aic790X_setup(struct ahd_softc *ahd, struct pci_attach_args *pa) 1076 { 1077 u_int rev; 1078 1079 rev = PCI_REVISION(pa->pa_class); 1080 #ifdef AHD_DEBUG 1081 printf("\n%s: aic7902 chip revision 0x%x\n", ahd_name(ahd), rev); 1082 #endif 1083 if (rev < ID_AIC7902_PCI_REV_A4) { 1084 printf("%s: Unable to attach to unsupported chip revision %d\n", 1085 ahd_name(ahd), rev); 1086 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 0); 1087 return (ENXIO); 1088 } 1089 1090 ahd->channel = (pa->pa_function == 1) ? 'B' : 'A'; 1091 if (rev < ID_AIC7902_PCI_REV_B0) { 1092 /* 1093 * Enable A series workarounds. 1094 */ 1095 ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG 1096 | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG 1097 | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG 1098 | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG 1099 | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG 1100 | AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG 1101 | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG 1102 | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG 1103 | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG 1104 | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG 1105 | AHD_FAINT_LED_BUG; 1106 1107 /* 1108 * IO Cell parameter setup. 1109 */ 1110 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29); 1111 1112 if ((ahd->flags & AHD_HP_BOARD) == 0) 1113 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA); 1114 } else { 1115 pcireg_t devconfig1; 1116 1117 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS 1118 | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY; 1119 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG 1120 | AHD_BUSFREEREV_BUG; 1121 1122 /* 1123 * Some issues have been resolved in the 7901B. 1124 */ 1125 if ((ahd->features & AHD_MULTI_FUNC) != 0) 1126 ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG; 1127 1128 /* 1129 * IO Cell parameter setup. 1130 */ 1131 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29); 1132 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB); 1133 AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF); 1134 1135 /* 1136 * Set the PREQDIS bit for H2B which disables some workaround 1137 * that doesn't work on regular PCI busses. 1138 * XXX - Find out exactly what this does from the hardware 1139 * folks! 1140 */ 1141 devconfig1 = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG1); 1142 pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG1, devconfig1|PREQDIS); 1143 devconfig1 = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG1); 1144 } 1145 1146 return (0); 1147 } 1148