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