ahc_pci.c revision 1.21 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