1 /* $NetBSD: ahc_pci.c,v 1.14 1997/04/13 20:14:20 cgd Exp $ */ 2 3 /* 4 * Product specific probe and attach routines for: 5 * 3940, 2940, aic7880, aic7870, aic7860 and aic7850 SCSI controllers 6 * 7 * Copyright (c) 1995, 1996 Justin T. Gibbs. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice immediately at the beginning of the file, without modification, 15 * this list of conditions, and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 26 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * from Id: aic7870.c,v 1.37 1996/06/08 06:55:55 gibbs Exp 35 */ 36 37 #if defined(__FreeBSD__) 38 #include <pci.h> 39 #endif 40 #if NPCI > 0 || defined(__NetBSD__) 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/malloc.h> 44 #include <sys/kernel.h> 45 #include <sys/queue.h> 46 #if defined(__NetBSD__) 47 #include <sys/device.h> 48 #include <machine/bus.h> 49 #include <machine/intr.h> 50 #endif /* defined(__NetBSD__) */ 51 52 #include <scsi/scsi_all.h> 53 #include <scsi/scsiconf.h> 54 55 #if defined(__FreeBSD__) 56 57 #include <pci/pcireg.h> 58 #include <pci/pcivar.h> 59 60 #include <machine/clock.h> 61 62 #include <i386/scsi/aic7xxx.h> 63 #include <i386/scsi/93cx6.h> 64 65 #include <dev/aic7xxx/aic7xxx_reg.h> 66 67 #define PCI_BASEADR0 PCI_MAP_REG_START 68 69 #elif defined(__NetBSD__) 70 71 #include <dev/pci/pcireg.h> 72 #include <dev/pci/pcivar.h> 73 74 #include <dev/ic/aic7xxxreg.h> 75 #include <dev/ic/aic7xxxvar.h> 76 #include <dev/ic/smc93cx6var.h> 77 78 /* 79 * Under normal circumstances, these messages are unnecessary 80 * and not terribly cosmetic. 81 */ 82 #ifdef DEBUG 83 #define bootverbose 1 84 #else 85 #define bootverbose 0 86 #endif 87 88 #define PCI_BASEADR_IO 0x10 89 #define PCI_BASEADR_MEM 0x14 90 91 #endif /* defined(__NetBSD__) */ 92 93 #define PCI_DEVICE_ID_ADAPTEC_3940U 0x82789004ul 94 #define PCI_DEVICE_ID_ADAPTEC_2944U 0x84789004ul 95 #define PCI_DEVICE_ID_ADAPTEC_2940U 0x81789004ul 96 #define PCI_DEVICE_ID_ADAPTEC_2940AU 0x61789004ul 97 #define PCI_DEVICE_ID_ADAPTEC_3940 0x72789004ul 98 #define PCI_DEVICE_ID_ADAPTEC_2944 0x74789004ul 99 #define PCI_DEVICE_ID_ADAPTEC_2940 0x71789004ul 100 #define PCI_DEVICE_ID_ADAPTEC_AIC7880 0x80789004ul 101 #define PCI_DEVICE_ID_ADAPTEC_AIC7870 0x70789004ul 102 #define PCI_DEVICE_ID_ADAPTEC_AIC7860 0x60789004ul 103 #define PCI_DEVICE_ID_ADAPTEC_AIC7855 0x55789004ul 104 #define PCI_DEVICE_ID_ADAPTEC_AIC7850 0x50789004ul 105 106 #define DEVCONFIG 0x40 107 #define MPORTMODE 0x00000400ul /* aic7870 only */ 108 #define RAMPSM 0x00000200ul /* aic7870 only */ 109 #define VOLSENSE 0x00000100ul 110 #define SCBRAMSEL 0x00000080ul 111 #define MRDCEN 0x00000040ul 112 #define EXTSCBTIME 0x00000020ul /* aic7870 only */ 113 #define EXTSCBPEN 0x00000010ul /* aic7870 only */ 114 #define BERREN 0x00000008ul 115 #define DACEN 0x00000004ul 116 #define STPWLEVEL 0x00000002ul 117 #define DIFACTNEGEN 0x00000001ul /* aic7870 only */ 118 119 #define CSIZE_LATTIME 0x0c 120 #define CACHESIZE 0x0000003ful /* only 5 bits */ 121 #define LATTIME 0x0000ff00ul 122 123 /* 124 * Define the format of the aic78X0 SEEPROM registers (16 bits). 125 * 126 */ 127 128 struct seeprom_config { 129 130 /* 131 * SCSI ID Configuration Flags 132 */ 133 #define CFXFER 0x0007 /* synchronous transfer rate */ 134 #define CFSYNCH 0x0008 /* enable synchronous transfer */ 135 #define CFDISC 0x0010 /* enable disconnection */ 136 #define CFWIDEB 0x0020 /* wide bus device */ 137 /* UNUSED 0x00C0 */ 138 #define CFSTART 0x0100 /* send start unit SCSI command */ 139 #define CFINCBIOS 0x0200 /* include in BIOS scan */ 140 #define CFRNFOUND 0x0400 /* report even if not found */ 141 /* UNUSED 0xf800 */ 142 u_int16_t device_flags[16]; /* words 0-15 */ 143 144 /* 145 * BIOS Control Bits 146 */ 147 #define CFSUPREM 0x0001 /* support all removeable drives */ 148 #define CFSUPREMB 0x0002 /* support removeable drives for boot only */ 149 #define CFBIOSEN 0x0004 /* BIOS enabled */ 150 /* UNUSED 0x0008 */ 151 #define CFSM2DRV 0x0010 /* support more than two drives */ 152 /* UNUSED 0x0060 */ 153 #define CFEXTEND 0x0080 /* extended translation enabled */ 154 /* UNUSED 0xff00 */ 155 u_int16_t bios_control; /* word 16 */ 156 157 /* 158 * Host Adapter Control Bits 159 */ 160 /* UNUSED 0x0001 */ 161 #define CFULTRAEN 0x0002 /* Ultra SCSI speed enable (Ultra cards) */ 162 #define CFSTERM 0x0004 /* SCSI low byte termination (non-wide cards) */ 163 #define CFWSTERM 0x0008 /* SCSI high byte termination (wide card) */ 164 #define CFSPARITY 0x0010 /* SCSI parity */ 165 /* UNUSED 0x0020 */ 166 #define CFRESETB 0x0040 /* reset SCSI bus at IC initialization */ 167 /* UNUSED 0xff80 */ 168 u_int16_t adapter_control; /* word 17 */ 169 170 /* 171 * Bus Release, Host Adapter ID 172 */ 173 #define CFSCSIID 0x000f /* host adapter SCSI ID */ 174 /* UNUSED 0x00f0 */ 175 #define CFBRTIME 0xff00 /* bus release time */ 176 u_int16_t brtime_id; /* word 18 */ 177 178 /* 179 * Maximum targets 180 */ 181 #define CFMAXTARG 0x00ff /* maximum targets */ 182 /* UNUSED 0xff00 */ 183 u_int16_t max_targets; /* word 19 */ 184 185 u_int16_t res_1[11]; /* words 20-30 */ 186 u_int16_t checksum; /* word 31 */ 187 }; 188 189 static void load_seeprom __P((struct ahc_data *ahc)); 190 static int acquire_seeprom __P((struct seeprom_descriptor *sd)); 191 static void release_seeprom __P((struct seeprom_descriptor *sd)); 192 193 static u_char aic3940_count; 194 195 #if defined(__FreeBSD__) 196 197 static char* aic7870_probe __P((pcici_t tag, pcidi_t type)); 198 static void aic7870_attach __P((pcici_t config_id, int unit)); 199 200 static struct pci_device ahc_pci_driver = { 201 "ahc", 202 aic7870_probe, 203 aic7870_attach, 204 &ahc_unit, 205 NULL 206 }; 207 208 DATA_SET (pcidevice_set, ahc_pci_driver); 209 210 static char* 211 aic7870_probe (pcici_t tag, pcidi_t type) 212 { 213 switch(type) { 214 case PCI_DEVICE_ID_ADAPTEC_3940U: 215 return ("Adaptec 3940 Ultra SCSI host adapter"); 216 break; 217 case PCI_DEVICE_ID_ADAPTEC_3940: 218 return ("Adaptec 3940 SCSI host adapter"); 219 break; 220 case PCI_DEVICE_ID_ADAPTEC_2944U: 221 return ("Adaptec 2944 Ultra SCSI host adapter"); 222 break; 223 case PCI_DEVICE_ID_ADAPTEC_2940U: 224 return ("Adaptec 2940 Ultra SCSI host adapter"); 225 break; 226 case PCI_DEVICE_ID_ADAPTEC_2944: 227 return ("Adaptec 2944 SCSI host adapter"); 228 break; 229 case PCI_DEVICE_ID_ADAPTEC_2940: 230 return ("Adaptec 2940 SCSI host adapter"); 231 break; 232 case PCI_DEVICE_ID_ADAPTEC_2940AU: 233 return ("Adaptec 2940A Ultra SCSI host adapter"); 234 break; 235 case PCI_DEVICE_ID_ADAPTEC_AIC7880: 236 return ("Adaptec aic7880 Ultra SCSI host adapter"); 237 break; 238 case PCI_DEVICE_ID_ADAPTEC_AIC7870: 239 return ("Adaptec aic7870 SCSI host adapter"); 240 break; 241 case PCI_DEVICE_ID_ADAPTEC_AIC7860: 242 return ("Adaptec aic7860 SCSI host adapter"); 243 break; 244 case PCI_DEVICE_ID_ADAPTEC_AIC7855: 245 return ("Adaptec aic7855 SCSI host adapter"); 246 break; 247 case PCI_DEVICE_ID_ADAPTEC_AIC7850: 248 return ("Adaptec aic7850 SCSI host adapter"); 249 break; 250 default: 251 break; 252 } 253 return (0); 254 255 } 256 257 #elif defined(__NetBSD__) 258 259 #ifdef __BROKEN_INDIRECT_CONFIG 260 int ahc_pci_probe __P((struct device *, void *, void *)); 261 #else 262 int ahc_pci_probe __P((struct device *, struct cfdata *, void *)); 263 #endif 264 void ahc_pci_attach __P((struct device *, struct device *, void *)); 265 266 struct cfattach ahc_pci_ca = { 267 sizeof(struct ahc_data), ahc_pci_probe, ahc_pci_attach 268 }; 269 270 int 271 ahc_pci_probe(parent, match, aux) 272 struct device *parent; 273 #ifdef __BROKEN_INDIRECT_CONFIG 274 void *match; 275 #else 276 struct cfdata *match; 277 #endif 278 void *aux; 279 { 280 struct pci_attach_args *pa = aux; 281 282 switch (pa->pa_id) { 283 case PCI_DEVICE_ID_ADAPTEC_3940U: 284 case PCI_DEVICE_ID_ADAPTEC_2944U: 285 case PCI_DEVICE_ID_ADAPTEC_2940U: 286 case PCI_DEVICE_ID_ADAPTEC_2940AU: 287 case PCI_DEVICE_ID_ADAPTEC_3940: 288 case PCI_DEVICE_ID_ADAPTEC_2944: 289 case PCI_DEVICE_ID_ADAPTEC_2940: 290 case PCI_DEVICE_ID_ADAPTEC_AIC7880: 291 case PCI_DEVICE_ID_ADAPTEC_AIC7870: 292 case PCI_DEVICE_ID_ADAPTEC_AIC7860: 293 case PCI_DEVICE_ID_ADAPTEC_AIC7855: 294 case PCI_DEVICE_ID_ADAPTEC_AIC7850: 295 return 1; 296 } 297 return 0; 298 } 299 #endif /* defined(__NetBSD__) */ 300 301 #if defined(__FreeBSD__) 302 static void 303 aic7870_attach(config_id, unit) 304 pcici_t config_id; 305 int unit; 306 #elif defined(__NetBSD__) 307 void 308 ahc_pci_attach(parent, self, aux) 309 struct device *parent, *self; 310 void *aux; 311 #endif 312 { 313 #if defined(__FreeBSD__) 314 u_long io_port; 315 int unit = ahc->sc_dev.dv_unit; 316 #elif defined(__NetBSD__) 317 struct pci_attach_args *pa = aux; 318 struct ahc_data *ahc = (void *)self; 319 bus_space_tag_t st, iot, memt; 320 bus_space_handle_t sh, ioh, memh; 321 int ioh_valid, memh_valid; 322 pci_intr_handle_t ih; 323 const char *intrstr; 324 #endif 325 u_long id; 326 unsigned opri = 0; 327 ahc_type ahc_t = AHC_NONE; 328 ahc_flag ahc_f = AHC_FNONE; 329 #if defined(__FreeBSD__) 330 struct ahc_data *ahc; 331 #endif 332 u_char ultra_enb = 0; 333 u_char our_id = 0; 334 335 #if defined(__FreeBSD__) 336 if(!(io_port = pci_conf_read(config_id, PCI_BASEADR0))) 337 return; 338 /* 339 * The first bit of PCI_BASEADR0 is always 340 * set hence we mask it off. 341 */ 342 io_port &= 0xfffffffe; 343 #elif defined(__NetBSD__) 344 ioh_valid = (pci_mapreg_map(pa, PCI_BASEADR_IO, 345 PCI_MAPREG_TYPE_IO, 0, 346 &iot, &ioh, NULL, NULL) == 0); 347 memh_valid = (pci_mapreg_map(pa, PCI_BASEADR_MEM, 348 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, 349 &memt, &memh, NULL, NULL) == 0); 350 351 if (memh_valid) { 352 st = memt; 353 sh = memh; 354 } else if (ioh_valid) { 355 st = iot; 356 sh = ioh; 357 } else { 358 printf(": unable to map registers\n"); 359 return; 360 } 361 printf("\n"); 362 #endif 363 364 #if defined(__FreeBSD__) 365 switch ((id = pci_conf_read(config_id, PCI_ID_REG))) { 366 #elif defined(__NetBSD__) 367 switch (id = pa->pa_id) { 368 #endif 369 case PCI_DEVICE_ID_ADAPTEC_3940U: 370 case PCI_DEVICE_ID_ADAPTEC_3940: 371 if (id == PCI_DEVICE_ID_ADAPTEC_3940U) 372 ahc_t = AHC_394U; 373 else 374 ahc_t = AHC_394; 375 aic3940_count++; 376 if(!(aic3940_count & 0x01)) 377 /* Even count implies second channel */ 378 ahc_f |= AHC_CHNLB; 379 break; 380 case PCI_DEVICE_ID_ADAPTEC_2944U: 381 case PCI_DEVICE_ID_ADAPTEC_2940U: 382 ahc_t = AHC_294U; 383 break; 384 case PCI_DEVICE_ID_ADAPTEC_2944: 385 case PCI_DEVICE_ID_ADAPTEC_2940: 386 ahc_t = AHC_294; 387 break; 388 case PCI_DEVICE_ID_ADAPTEC_2940AU: 389 ahc_t = AHC_294AU; 390 break; 391 case PCI_DEVICE_ID_ADAPTEC_AIC7880: 392 ahc_t = AHC_AIC7880; 393 break; 394 case PCI_DEVICE_ID_ADAPTEC_AIC7870: 395 ahc_t = AHC_AIC7870; 396 break; 397 case PCI_DEVICE_ID_ADAPTEC_AIC7860: 398 ahc_t = AHC_AIC7860; 399 break; 400 case PCI_DEVICE_ID_ADAPTEC_AIC7855: 401 case PCI_DEVICE_ID_ADAPTEC_AIC7850: 402 ahc_t = AHC_AIC7850; 403 break; 404 default: 405 break; 406 } 407 408 /* On all PCI adapters, we allow SCB paging */ 409 ahc_f |= AHC_PAGESCBS; 410 411 /* Remeber how the card was setup in case there is no SEEPROM */ 412 #if defined(__FreeBSD__) 413 our_id = inb(SCSIID + io_port) & OID; 414 if(ahc_t & AHC_ULTRA) 415 ultra_enb = inb(SXFRCTL0 + io_port) & ULTRAEN; 416 #else 417 our_id = bus_space_read_1(st, sh, SCSIID) & OID; 418 if(ahc_t & AHC_ULTRA) 419 ultra_enb = bus_space_read_1(st, sh, SXFRCTL0) & ULTRAEN; 420 #endif 421 422 #if defined(__FreeBSD__) 423 ahc_reset(io_port); 424 #elif defined(__NetBSD__) 425 ahc_reset(ahc->sc_dev.dv_xname, st, sh); 426 #endif 427 428 if(ahc_t & AHC_AIC7870){ 429 #if defined(__FreeBSD__) 430 u_long devconfig = pci_conf_read(config_id, DEVCONFIG); 431 #elif defined(__NetBSD__) 432 u_long devconfig = 433 pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG); 434 #endif 435 436 if(devconfig & (RAMPSM)) { 437 /* 438 * External SRAM present. Have the probe walk 439 * the SCBs to see how much SRAM we have and set 440 * the number of SCBs accordingly. We have to 441 * turn off SCBRAMSEL to access the external 442 * SCB SRAM. 443 * 444 * It seems that early versions of the aic7870 445 * didn't use these bits, hence the hack for the 446 * 3940 above. I would guess that recent 3940s 447 * using later aic7870 or aic7880 chips do 448 * actually set RAMPSM. 449 * 450 * The documentation isn't clear, but it sounds 451 * like the value written to devconfig must not 452 * have RAMPSM set. The second sixteen bits of 453 * the register are R/O anyway, so it shouldn't 454 * affect RAMPSM either way. 455 */ 456 devconfig &= ~(RAMPSM|SCBRAMSEL); 457 #if defined(__FreeBSD__) 458 pci_conf_write(config_id, DEVCONFIG, devconfig); 459 #elif defined(__NetBSD__) 460 pci_conf_write(pa->pa_pc, pa->pa_tag, 461 DEVCONFIG, devconfig); 462 #endif 463 } 464 } 465 466 #if defined(__FreeBSD__) 467 if(!(ahc = ahc_alloc(unit, io_port, ahc_t, ahc_f))) 468 return; /* XXX PCI code should take return status */ 469 470 if(!(pci_map_int(config_id, ahc_intr, (void *)ahc, &bio_imask))) { 471 ahc_free(ahc); 472 return; 473 } 474 #elif defined(__NetBSD__) 475 ahc_construct(ahc, st, sh, ahc_t, ahc_f); 476 477 if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin, 478 pa->pa_intrline, &ih)) { 479 printf("%s: couldn't map interrupt\n", ahc->sc_dev.dv_xname); 480 ahc_free(ahc); 481 return; 482 } 483 intrstr = pci_intr_string(pa->pa_pc, ih); 484 #if defined(__OpenBSD__) 485 ahc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahc_intr, ahc, 486 ahc->sc_dev.dv_xname); 487 #else 488 ahc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahc_intr, ahc); 489 #endif 490 if (ahc->sc_ih == NULL) { 491 printf("%s: couldn't establish interrupt", 492 ahc->sc_dev.dv_xname); 493 if (intrstr != NULL) 494 printf(" at %s", intrstr); 495 printf("\n"); 496 ahc_free(ahc); 497 return; 498 } 499 if (intrstr != NULL) 500 printf("%s: interrupting at %s\n", ahc->sc_dev.dv_xname, 501 intrstr); 502 #endif 503 /* 504 * Protect ourself from spurrious interrupts during 505 * intialization. 506 */ 507 opri = splbio(); 508 509 /* 510 * Do aic7870/aic7880/aic7850 specific initialization 511 */ 512 { 513 u_char sblkctl; 514 char *id_string; 515 516 switch(ahc->type) { 517 case AHC_394U: 518 case AHC_294U: 519 case AHC_AIC7880: 520 { 521 id_string = "aic7880 "; 522 load_seeprom(ahc); 523 break; 524 } 525 case AHC_394: 526 case AHC_294: 527 case AHC_AIC7870: 528 { 529 id_string = "aic7870 "; 530 load_seeprom(ahc); 531 break; 532 } 533 case AHC_294AU: 534 case AHC_AIC7860: 535 { 536 id_string = "aic7860 "; 537 load_seeprom(ahc); 538 break; 539 } 540 case AHC_AIC7850: 541 { 542 id_string = "aic7850 "; 543 /* 544 * Use defaults, if the chip wasn't initialized by 545 * a BIOS. 546 */ 547 ahc->flags |= AHC_USEDEFAULTS; 548 break; 549 } 550 default: 551 { 552 printf("ahc: Unknown controller type. Ignoring.\n"); 553 ahc_free(ahc); 554 splx(opri); 555 return; 556 } 557 } 558 559 /* 560 * Take the LED out of diagnostic mode 561 */ 562 sblkctl = AHC_INB(ahc, SBLKCTL); 563 AHC_OUTB(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON))); 564 565 /* 566 * I don't know where this is set in the SEEPROM or by the 567 * BIOS, so we default to 100%. 568 */ 569 AHC_OUTB(ahc, DSPCISTATUS, DFTHRSH_100); 570 571 if(ahc->flags & AHC_USEDEFAULTS) { 572 /* 573 * PCI Adapter default setup 574 * Should only be used if the adapter does not have 575 * an SEEPROM. 576 */ 577 /* See if someone else set us up already */ 578 u_long i; 579 for(i = TARG_SCRATCH; i < 0x60; i++) { 580 if(AHC_INB(ahc, i) != 0x00) 581 break; 582 } 583 if(i == TARG_SCRATCH) { 584 /* 585 * Try looking for all ones. You can get 586 * either. 587 */ 588 for (i = TARG_SCRATCH; i < 0x60; i++) { 589 if(AHC_INB(ahc, i) != 0xff) 590 break; 591 } 592 } 593 if((i != 0x60) && (our_id != 0)) { 594 printf("%s: Using left over BIOS settings\n", 595 ahc_name(ahc)); 596 ahc->flags &= ~AHC_USEDEFAULTS; 597 } 598 else 599 our_id = 0x07; 600 AHC_OUTB(ahc, SCSICONF, 601 (our_id & 0x07)|ENSPCHK|RESET_SCSI); 602 /* In case we are a wide card */ 603 AHC_OUTB(ahc, SCSICONF + 1, our_id); 604 605 if(!ultra_enb || (ahc->flags & AHC_USEDEFAULTS)) { 606 /* 607 * If there wasn't a BIOS or the board 608 * wasn't in this mode to begin with, 609 * turn off ultra. 610 */ 611 ahc->type &= ~AHC_ULTRA; 612 } 613 } 614 615 printf("%s: %s", ahc_name(ahc), id_string); 616 } 617 618 if(ahc_init(ahc)){ 619 ahc_free(ahc); 620 splx(opri); 621 return; /* XXX PCI code should take return status */ 622 } 623 splx(opri); 624 625 ahc_attach(ahc); 626 } 627 628 /* 629 * Read the SEEPROM. Return 0 on failure 630 */ 631 void 632 load_seeprom(ahc) 633 struct ahc_data *ahc; 634 { 635 struct seeprom_descriptor sd; 636 struct seeprom_config sc; 637 u_short *scarray = (u_short *)≻ 638 u_short checksum = 0; 639 u_char scsi_conf; 640 u_char host_id; 641 int have_seeprom; 642 643 #if defined(__FreeBSD__) 644 sd.sd_iobase = ahc->baseport + SEECTL; 645 #elif defined(__NetBSD__) 646 sd.sd_st = ahc->sc_st; 647 sd.sd_sh = ahc->sc_sh; 648 sd.sd_offset = SEECTL; 649 #endif 650 sd.sd_MS = SEEMS; 651 sd.sd_RDY = SEERDY; 652 sd.sd_CS = SEECS; 653 sd.sd_CK = SEECK; 654 sd.sd_DO = SEEDO; 655 sd.sd_DI = SEEDI; 656 657 if(bootverbose) 658 printf("%s: Reading SEEPROM...", ahc_name(ahc)); 659 have_seeprom = acquire_seeprom(&sd); 660 if (have_seeprom) { 661 have_seeprom = read_seeprom(&sd, 662 (u_int16_t *)&sc, 663 ahc->flags & AHC_CHNLB, 664 sizeof(sc)/2); 665 release_seeprom(&sd); 666 if (have_seeprom) { 667 /* Check checksum */ 668 int i; 669 670 for (i = 0;i < (sizeof(sc)/2 - 1);i = i + 1) 671 checksum = checksum + scarray[i]; 672 if (checksum != sc.checksum) { 673 if(bootverbose) 674 printf ("checksum error"); 675 have_seeprom = 0; 676 } 677 else if(bootverbose) 678 printf("done.\n"); 679 } 680 } 681 if (!have_seeprom) { 682 if(bootverbose) 683 printf("\n%s: No SEEPROM availible\n", ahc_name(ahc)); 684 ahc->flags |= AHC_USEDEFAULTS; 685 } 686 else { 687 /* 688 * Put the data we've collected down into SRAM 689 * where ahc_init will find it. 690 */ 691 int i; 692 int max_targ = sc.max_targets & CFMAXTARG; 693 694 for(i = 0; i < max_targ; i++){ 695 u_char target_settings; 696 target_settings = (sc.device_flags[i] & CFXFER) << 4; 697 if (sc.device_flags[i] & CFSYNCH) 698 target_settings |= SOFS; 699 if (sc.device_flags[i] & CFWIDEB) 700 target_settings |= WIDEXFER; 701 if (sc.device_flags[i] & CFDISC) 702 ahc->discenable |= (0x01 << i); 703 AHC_OUTB(ahc, TARG_SCRATCH+i, target_settings); 704 } 705 AHC_OUTB(ahc, DISC_DSB, ~(ahc->discenable & 0xff)); 706 AHC_OUTB(ahc, DISC_DSB + 1, ~((ahc->discenable >> 8) & 0xff)); 707 708 host_id = sc.brtime_id & CFSCSIID; 709 710 scsi_conf = (host_id & 0x7); 711 if(sc.adapter_control & CFSPARITY) 712 scsi_conf |= ENSPCHK; 713 if(sc.adapter_control & CFRESETB) 714 scsi_conf |= RESET_SCSI; 715 716 if(ahc->type & AHC_ULTRA) { 717 /* Should we enable Ultra mode? */ 718 if(!(sc.adapter_control & CFULTRAEN)) 719 /* Treat us as a non-ultra card */ 720 ahc->type &= ~AHC_ULTRA; 721 } 722 /* Set the host ID */ 723 AHC_OUTB(ahc, SCSICONF, scsi_conf); 724 /* In case we are a wide card */ 725 AHC_OUTB(ahc, SCSICONF + 1, host_id); 726 } 727 } 728 729 static int 730 acquire_seeprom(sd) 731 struct seeprom_descriptor *sd; 732 { 733 int wait; 734 735 /* 736 * Request access of the memory port. When access is 737 * granted, SEERDY will go high. We use a 1 second 738 * timeout which should be near 1 second more than 739 * is needed. Reason: after the chip reset, there 740 * should be no contention. 741 */ 742 SEEPROM_OUTB(sd, sd->sd_MS); 743 wait = 1000; /* 1 second timeout in msec */ 744 while (--wait && ((SEEPROM_INB(sd) & sd->sd_RDY) == 0)) { 745 DELAY (1000); /* delay 1 msec */ 746 } 747 if ((SEEPROM_INB(sd) & sd->sd_RDY) == 0) { 748 SEEPROM_OUTB(sd, 0); 749 return (0); 750 } 751 return(1); 752 } 753 754 static void 755 release_seeprom(sd) 756 struct seeprom_descriptor *sd; 757 { 758 /* Release access to the memory port and the serial EEPROM. */ 759 SEEPROM_OUTB(sd, 0); 760 } 761 762 #endif /* NPCI > 0 */ 763