xref: /netbsd-src/sys/dev/pci/ahc_pci.c (revision 89c5a767f8fc7a4633b2d409966e2becbb98ff92)
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