1 /* $NetBSD: ahc_pci.c,v 1.21 2000/01/26 06:44:18 thorpej 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 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/malloc.h> 40 #include <sys/kernel.h> 41 #include <sys/queue.h> 42 #include <sys/device.h> 43 44 #include <machine/bus.h> 45 #include <machine/intr.h> 46 47 #include <dev/scsipi/scsi_all.h> 48 #include <dev/scsipi/scsipi_all.h> 49 #include <dev/scsipi/scsiconf.h> 50 51 #include <dev/pci/pcireg.h> 52 #include <dev/pci/pcivar.h> 53 54 #include <dev/ic/aic7xxxreg.h> 55 #include <dev/ic/aic7xxxvar.h> 56 57 /* 58 * Under normal circumstances, these messages are unnecessary 59 * and not terribly cosmetic. 60 */ 61 #ifdef DEBUG 62 #define bootverbose 1 63 #else 64 #define bootverbose 0 65 #endif 66 67 #define PCI_BASEADR_IO 0x10 68 #define PCI_BASEADR_MEM 0x14 69 70 #define PCI_DEVICE_ID_ADAPTEC_3940U 0x82789004ul 71 #define PCI_DEVICE_ID_ADAPTEC_2944U 0x84789004ul 72 #define PCI_DEVICE_ID_ADAPTEC_2940U 0x81789004ul 73 #define PCI_DEVICE_ID_ADAPTEC_2940UP 0x87789004ul 74 #define PCI_DEVICE_ID_ADAPTEC_2940AU 0x61789004ul 75 #define PCI_DEVICE_ID_ADAPTEC_3940 0x72789004ul 76 #define PCI_DEVICE_ID_ADAPTEC_2944 0x74789004ul 77 #define PCI_DEVICE_ID_ADAPTEC_2940 0x71789004ul 78 #define PCI_DEVICE_ID_ADAPTEC_AIC7880 0x80789004ul 79 #define PCI_DEVICE_ID_ADAPTEC_AIC7870 0x70789004ul 80 #define PCI_DEVICE_ID_ADAPTEC_AIC7860 0x60789004ul 81 #define PCI_DEVICE_ID_ADAPTEC_AIC7855 0x55789004ul 82 #define PCI_DEVICE_ID_ADAPTEC_AIC7850 0x50789004ul 83 84 #define DEVCONFIG 0x40 85 #define MPORTMODE 0x00000400ul /* aic7870 only */ 86 #define RAMPSM 0x00000200ul /* aic7870 only */ 87 #define VOLSENSE 0x00000100ul 88 #define SCBRAMSEL 0x00000080ul 89 #define MRDCEN 0x00000040ul 90 #define EXTSCBTIME 0x00000020ul /* aic7870 only */ 91 #define EXTSCBPEN 0x00000010ul /* aic7870 only */ 92 #define BERREN 0x00000008ul 93 #define DACEN 0x00000004ul 94 #define STPWLEVEL 0x00000002ul 95 #define DIFACTNEGEN 0x00000001ul /* aic7870 only */ 96 97 #define CSIZE_LATTIME 0x0c 98 #define CACHESIZE 0x0000003ful /* only 5 bits */ 99 #define LATTIME 0x0000ff00ul 100 101 static u_char aic3940_count; 102 103 int ahc_pci_probe __P((struct device *, struct cfdata *, void *)); 104 void ahc_pci_attach __P((struct device *, struct device *, void *)); 105 106 struct cfattach ahc_pci_ca = { 107 sizeof(struct ahc_data), ahc_pci_probe, ahc_pci_attach 108 }; 109 110 int 111 ahc_pci_probe(parent, match, aux) 112 struct device *parent; 113 struct cfdata *match; 114 void *aux; 115 { 116 struct pci_attach_args *pa = aux; 117 118 switch (pa->pa_id) { 119 case PCI_DEVICE_ID_ADAPTEC_3940U: 120 case PCI_DEVICE_ID_ADAPTEC_2944U: 121 case PCI_DEVICE_ID_ADAPTEC_2940U: 122 case PCI_DEVICE_ID_ADAPTEC_2940UP: 123 case PCI_DEVICE_ID_ADAPTEC_2940AU: 124 case PCI_DEVICE_ID_ADAPTEC_3940: 125 case PCI_DEVICE_ID_ADAPTEC_2944: 126 case PCI_DEVICE_ID_ADAPTEC_2940: 127 case PCI_DEVICE_ID_ADAPTEC_AIC7880: 128 case PCI_DEVICE_ID_ADAPTEC_AIC7870: 129 case PCI_DEVICE_ID_ADAPTEC_AIC7860: 130 case PCI_DEVICE_ID_ADAPTEC_AIC7855: 131 case PCI_DEVICE_ID_ADAPTEC_AIC7850: 132 return 1; 133 } 134 return 0; 135 } 136 137 void 138 ahc_pci_attach(parent, self, aux) 139 struct device *parent, *self; 140 void *aux; 141 { 142 struct pci_attach_args *pa = aux; 143 struct ahc_data *ahc = (void *)self; 144 bus_space_tag_t st, iot, memt; 145 bus_space_handle_t sh, ioh, memh; 146 int ioh_valid, memh_valid; 147 pci_intr_handle_t ih; 148 const char *intrstr; 149 u_long id; 150 unsigned opri = 0; 151 ahc_type ahc_t = AHC_NONE; 152 ahc_flag ahc_f = AHC_FNONE; 153 u_char ultra_enb = 0; 154 u_char our_id = 0; 155 156 ioh_valid = (pci_mapreg_map(pa, PCI_BASEADR_IO, 157 PCI_MAPREG_TYPE_IO, 0, 158 &iot, &ioh, NULL, NULL) == 0); 159 memh_valid = (pci_mapreg_map(pa, PCI_BASEADR_MEM, 160 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, 161 &memt, &memh, NULL, NULL) == 0); 162 163 if (memh_valid) { 164 st = memt; 165 sh = memh; 166 } else if (ioh_valid) { 167 st = iot; 168 sh = ioh; 169 } else { 170 printf(": unable to map registers\n"); 171 return; 172 } 173 printf("\n"); 174 175 switch (id = pa->pa_id) { 176 case PCI_DEVICE_ID_ADAPTEC_3940U: 177 case PCI_DEVICE_ID_ADAPTEC_3940: 178 if (id == PCI_DEVICE_ID_ADAPTEC_3940U) 179 ahc_t = AHC_394U; 180 else 181 ahc_t = AHC_394; 182 aic3940_count++; 183 if(!(aic3940_count & 0x01)) 184 /* Even count implies second channel */ 185 ahc_f |= AHC_CHNLB; 186 break; 187 case PCI_DEVICE_ID_ADAPTEC_2944U: 188 case PCI_DEVICE_ID_ADAPTEC_2940U: 189 case PCI_DEVICE_ID_ADAPTEC_2940UP: 190 ahc_t = AHC_294U; 191 break; 192 case PCI_DEVICE_ID_ADAPTEC_2944: 193 case PCI_DEVICE_ID_ADAPTEC_2940: 194 ahc_t = AHC_294; 195 break; 196 case PCI_DEVICE_ID_ADAPTEC_2940AU: 197 ahc_t = AHC_294AU; 198 break; 199 case PCI_DEVICE_ID_ADAPTEC_AIC7880: 200 ahc_t = AHC_AIC7880; 201 break; 202 case PCI_DEVICE_ID_ADAPTEC_AIC7870: 203 ahc_t = AHC_AIC7870; 204 break; 205 case PCI_DEVICE_ID_ADAPTEC_AIC7860: 206 ahc_t = AHC_AIC7860; 207 break; 208 case PCI_DEVICE_ID_ADAPTEC_AIC7855: 209 case PCI_DEVICE_ID_ADAPTEC_AIC7850: 210 ahc_t = AHC_AIC7850; 211 break; 212 default: 213 break; 214 } 215 216 /* On all PCI adapters, we allow SCB paging */ 217 ahc_f |= AHC_PAGESCBS; 218 219 /* Remeber how the card was setup in case there is no SEEPROM */ 220 our_id = bus_space_read_1(st, sh, SCSIID) & OID; 221 if(ahc_t & AHC_ULTRA) 222 ultra_enb = bus_space_read_1(st, sh, SXFRCTL0) & ULTRAEN; 223 224 ahc_reset(ahc->sc_dev.dv_xname, st, sh); 225 226 if(ahc_t & AHC_AIC7870){ 227 u_long devconfig = 228 pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG); 229 230 if(devconfig & (RAMPSM)) { 231 /* 232 * External SRAM present. Have the probe walk 233 * the SCBs to see how much SRAM we have and set 234 * the number of SCBs accordingly. We have to 235 * turn off SCBRAMSEL to access the external 236 * SCB SRAM. 237 * 238 * It seems that early versions of the aic7870 239 * didn't use these bits, hence the hack for the 240 * 3940 above. I would guess that recent 3940s 241 * using later aic7870 or aic7880 chips do 242 * actually set RAMPSM. 243 * 244 * The documentation isn't clear, but it sounds 245 * like the value written to devconfig must not 246 * have RAMPSM set. The second sixteen bits of 247 * the register are R/O anyway, so it shouldn't 248 * affect RAMPSM either way. 249 */ 250 devconfig &= ~(RAMPSM|SCBRAMSEL); 251 pci_conf_write(pa->pa_pc, pa->pa_tag, 252 DEVCONFIG, devconfig); 253 } 254 } 255 256 ahc_construct(ahc, st, sh, pa->pa_dmat, ahc_t, ahc_f); 257 258 if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin, 259 pa->pa_intrline, &ih)) { 260 printf("%s: couldn't map interrupt\n", ahc->sc_dev.dv_xname); 261 ahc_free(ahc); 262 return; 263 } 264 intrstr = pci_intr_string(pa->pa_pc, ih); 265 ahc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahc_intr, ahc); 266 if (ahc->sc_ih == NULL) { 267 printf("%s: couldn't establish interrupt", 268 ahc->sc_dev.dv_xname); 269 if (intrstr != NULL) 270 printf(" at %s", intrstr); 271 printf("\n"); 272 ahc_free(ahc); 273 return; 274 } 275 if (intrstr != NULL) 276 printf("%s: interrupting at %s\n", ahc->sc_dev.dv_xname, 277 intrstr); 278 279 /* 280 * Protect ourself from spurrious interrupts during 281 * intialization. 282 */ 283 opri = splbio(); 284 285 /* 286 * Do aic7870/aic7880/aic7850 specific initialization 287 */ 288 { 289 u_char sblkctl; 290 char *id_string; 291 292 switch(ahc->type) { 293 case AHC_394U: 294 case AHC_294U: 295 case AHC_AIC7880: 296 { 297 id_string = "aic7880 "; 298 ahc_load_seeprom(ahc); 299 break; 300 } 301 case AHC_394: 302 case AHC_294: 303 case AHC_AIC7870: 304 { 305 id_string = "aic7870 "; 306 ahc_load_seeprom(ahc); 307 break; 308 } 309 case AHC_294AU: 310 case AHC_AIC7860: 311 { 312 id_string = "aic7860 "; 313 ahc_load_seeprom(ahc); 314 break; 315 } 316 case AHC_AIC7850: 317 { 318 id_string = "aic7850 "; 319 /* 320 * Use defaults, if the chip wasn't initialized by 321 * a BIOS. 322 */ 323 ahc->flags |= AHC_USEDEFAULTS; 324 break; 325 } 326 default: 327 { 328 printf("ahc: Unknown controller type. Ignoring.\n"); 329 ahc_free(ahc); 330 splx(opri); 331 return; 332 } 333 } 334 335 /* 336 * Take the LED out of diagnostic mode 337 */ 338 sblkctl = AHC_INB(ahc, SBLKCTL); 339 AHC_OUTB(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON))); 340 341 /* 342 * I don't know where this is set in the SEEPROM or by the 343 * BIOS, so we default to 100%. 344 */ 345 AHC_OUTB(ahc, DSPCISTATUS, DFTHRSH_100); 346 347 if(ahc->flags & AHC_USEDEFAULTS) { 348 /* 349 * PCI Adapter default setup 350 * Should only be used if the adapter does not have 351 * an SEEPROM. 352 */ 353 /* See if someone else set us up already */ 354 u_long i; 355 for(i = TARG_SCRATCH; i < 0x60; i++) { 356 if(AHC_INB(ahc, i) != 0x00) 357 break; 358 } 359 if(i == TARG_SCRATCH) { 360 /* 361 * Try looking for all ones. You can get 362 * either. 363 */ 364 for (i = TARG_SCRATCH; i < 0x60; i++) { 365 if(AHC_INB(ahc, i) != 0xff) 366 break; 367 } 368 } 369 if((i != 0x60) && (our_id != 0)) { 370 printf("%s: Using left over BIOS settings\n", 371 ahc_name(ahc)); 372 ahc->flags &= ~AHC_USEDEFAULTS; 373 } 374 else 375 our_id = 0x07; 376 AHC_OUTB(ahc, SCSICONF, 377 (our_id & 0x07)|ENSPCHK|RESET_SCSI); 378 /* In case we are a wide card */ 379 AHC_OUTB(ahc, SCSICONF + 1, our_id); 380 381 if(!ultra_enb || (ahc->flags & AHC_USEDEFAULTS)) { 382 /* 383 * If there wasn't a BIOS or the board 384 * wasn't in this mode to begin with, 385 * turn off ultra. 386 */ 387 ahc->type &= ~AHC_ULTRA; 388 } 389 } 390 391 printf("%s: %s", ahc_name(ahc), id_string); 392 } 393 394 if(ahc_init(ahc)){ 395 ahc_free(ahc); 396 splx(opri); 397 return; /* XXX PCI code should take return status */ 398 } 399 splx(opri); 400 401 ahc_attach(ahc); 402 } 403