Annotation of sys/dev/pci/ahc_pci.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ahc_pci.c,v 1.51 2007/05/14 01:37:50 deraadt Exp $ */
2: /*
3: * Product specific probe and attach routines for:
4: * 3940, 2940, aic7895, aic7890, aic7880,
5: * aic7870, aic7860 and aic7850 SCSI controllers
6: *
7: * Copyright (c) 1994-2001 Justin T. Gibbs.
8: * Copyright (c) 2000-2001 Adaptec Inc.
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, this list of conditions, and the following disclaimer,
16: * without modification.
17: * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18: * substantially similar to the "NO WARRANTY" disclaimer below
19: * ("Disclaimer") and any redistribution must be conditioned upon
20: * including a substantially similar Disclaimer requirement for further
21: * binary redistribution.
22: * 3. Neither the names of the above-listed copyright holders nor the names
23: * of any contributors may be used to endorse or promote products derived
24: * from this software without specific prior written permission.
25: *
26: * Alternatively, this software may be distributed under the terms of the
27: * GNU General Public License ("GPL") version 2 as published by the Free
28: * Software Foundation.
29: *
30: * NO WARRANTY
31: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35: * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41: * POSSIBILITY OF SUCH DAMAGES.
42: *
43: * $Id: ahc_pci.c,v 1.51 2007/05/14 01:37:50 deraadt Exp $
44: *
45: * //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#57 $
46: *
47: * $FreeBSD: /repoman/r/ncvs/src/sys/dev/aic7xxx/aic7xxx_pci.c,v 1.22 2003/01/20 20:44:55 gibbs Exp $
48: */
49: /*
50: * Ported from FreeBSD by Pascal Renauld, Network Storage Solutions, Inc. - April 2003
51: */
52:
53: #include <sys/cdefs.h>
54: /* __KERNEL_RCSID(0, "$NetBSD: ahc_pci.c,v 1.43 2003/08/18 09:16:22 taca Exp $"); */
55:
56: #include <sys/param.h>
57: #include <sys/systm.h>
58: #include <sys/malloc.h>
59: #include <sys/kernel.h>
60: #include <sys/queue.h>
61: #include <sys/device.h>
62: #include <sys/reboot.h>
63:
64: #include <machine/bus.h>
65: #include <machine/intr.h>
66:
67: #include <dev/pci/pcireg.h>
68: #include <dev/pci/pcivar.h>
69:
70: #define AHC_PCI_IOADDR PCI_MAPREG_START /* I/O Address */
71: #define AHC_PCI_MEMADDR (PCI_MAPREG_START + 4) /* Mem I/O Address */
72:
73: #include <dev/ic/aic7xxx_openbsd.h>
74: #include <dev/ic/aic7xxx_inline.h>
75:
76: #include <dev/ic/smc93cx6var.h>
77:
78: #ifndef __i386__
79: #define AHC_ALLOW_MEMIO
80: #endif
81:
82: static __inline uint64_t
83: ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
84: {
85: uint64_t id;
86:
87: id = subvendor
88: | (subdevice << 16)
89: | ((uint64_t)vendor << 32)
90: | ((uint64_t)device << 48);
91:
92: return (id);
93: }
94:
95: #define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull
96: #define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull
97: #define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull
98: #define ID_9005_SISL_MASK 0x000FFFFF00000000ull
99: #define ID_9005_SISL_ID 0x0005900500000000ull
100: #define ID_AIC7850 0x5078900400000000ull
101: #define ID_AHA_2902_04_10_15_20_30C 0x5078900478509004ull
102: #define ID_AIC7855 0x5578900400000000ull
103: #define ID_AIC7859 0x3860900400000000ull
104: #define ID_AHA_2930CU 0x3860900438699004ull
105: #define ID_AIC7860 0x6078900400000000ull
106: #define ID_AIC7860C 0x6078900478609004ull
107: #define ID_AHA_1480A 0x6075900400000000ull
108: #define ID_AHA_2940AU_0 0x6178900400000000ull
109: #define ID_AHA_2940AU_1 0x6178900478619004ull
110: #define ID_AHA_2940AU_CN 0x2178900478219004ull
111: #define ID_AHA_2930C_VAR 0x6038900438689004ull
112:
113: #define ID_AIC7870 0x7078900400000000ull
114: #define ID_AHA_2940 0x7178900400000000ull
115: #define ID_AHA_3940 0x7278900400000000ull
116: #define ID_AHA_398X 0x7378900400000000ull
117: #define ID_AHA_2944 0x7478900400000000ull
118: #define ID_AHA_3944 0x7578900400000000ull
119: #define ID_AHA_4944 0x7678900400000000ull
120:
121: #define ID_AIC7880 0x8078900400000000ull
122: #define ID_AIC7880_B 0x8078900478809004ull
123: #define ID_AHA_2940U 0x8178900400000000ull
124: #define ID_AHA_3940U 0x8278900400000000ull
125: #define ID_AHA_2944U 0x8478900400000000ull
126: #define ID_AHA_3944U 0x8578900400000000ull
127: #define ID_AHA_398XU 0x8378900400000000ull
128: #define ID_AHA_4944U 0x8678900400000000ull
129: #define ID_AHA_2940UB 0x8178900478819004ull
130: #define ID_AHA_2930U 0x8878900478889004ull
131: #define ID_AHA_2940U_PRO 0x8778900478879004ull
132: #define ID_AHA_2940U_CN 0x0078900478009004ull
133:
134: #define ID_AIC7895 0x7895900478959004ull
135: #define ID_AIC7895_ARO 0x7890900478939004ull
136: #define ID_AIC7895_ARO_MASK 0xFFF0FFFFFFFFFFFFull
137: #define ID_AHA_2940U_DUAL 0x7895900478919004ull
138: #define ID_AHA_3940AU 0x7895900478929004ull
139: #define ID_AHA_3944AU 0x7895900478949004ull
140:
141: #define ID_AIC7890 0x001F9005000F9005ull
142: #define ID_AIC7890_ARO 0x00139005000F9005ull
143: #define ID_AAA_131U2 0x0013900500039005ull
144: #define ID_AHA_2930U2 0x0011900501819005ull
145: #define ID_AHA_2940U2B 0x00109005A1009005ull
146: #define ID_AHA_2940U2_OEM 0x0010900521809005ull
147: #define ID_AHA_2940U2 0x00109005A1809005ull
148: #define ID_AHA_2950U2B 0x00109005E1009005ull
149:
150: #define ID_AIC7892 0x008F9005FFFF9005ull
151: #define ID_AIC7892_ARO 0x00839005FFFF9005ull
152: #define ID_AHA_2915LP 0x0082900502109005ull
153: #define ID_AHA_29160 0x00809005E2A09005ull
154: #define ID_AHA_29160_CPQ 0x00809005E2A00E11ull
155: #define ID_AHA_29160N 0x0080900562A09005ull
156: #define ID_AHA_29160C 0x0080900562209005ull
157: #define ID_AHA_29160B 0x00809005E2209005ull
158: #define ID_AHA_19160B 0x0081900562A19005ull
159:
160: #define ID_AIC7896 0x005F9005FFFF9005ull
161: #define ID_AIC7896_ARO 0x00539005FFFF9005ull
162: #define ID_AHA_3950U2B_0 0x00509005FFFF9005ull
163: #define ID_AHA_3950U2B_1 0x00509005F5009005ull
164: #define ID_AHA_3950U2D_0 0x00519005FFFF9005ull
165: #define ID_AHA_3950U2D_1 0x00519005B5009005ull
166:
167: #define ID_AIC7899 0x00CF9005FFFF9005ull
168: #define ID_AIC7899_ARO 0x00C39005FFFF9005ull
169: #define ID_AHA_3960D 0x00C09005F6209005ull
170: #define ID_AHA_3960D_CPQ 0x00C09005F6200E11ull
171:
172: #define ID_AIC7810 0x1078900400000000ull
173: #define ID_AIC7815 0x7815900400000000ull
174:
175: #define DEVID_9005_TYPE(id) ((id) & 0xF)
176: #define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */
177: #define DEVID_9005_TYPE_AAA 0x3 /* RAID Card */
178: #define DEVID_9005_TYPE_SISL 0x5 /* Container ROMB */
179: #define DEVID_9005_TYPE_MB 0xF /* On Motherboard */
180:
181: #define DEVID_9005_MAXRATE(id) (((id) & 0x30) >> 4)
182: #define DEVID_9005_MAXRATE_U160 0x0
183: #define DEVID_9005_MAXRATE_ULTRA2 0x1
184: #define DEVID_9005_MAXRATE_ULTRA 0x2
185: #define DEVID_9005_MAXRATE_FAST 0x3
186:
187: #define DEVID_9005_MFUNC(id) (((id) & 0x40) >> 6)
188:
189: #define DEVID_9005_CLASS(id) (((id) & 0xFF00) >> 8)
190: #define DEVID_9005_CLASS_SPI 0x0 /* Parallel SCSI */
191:
192: #define SUBID_9005_TYPE(id) ((id) & 0xF)
193: #define SUBID_9005_TYPE_MB 0xF /* On Motherboard */
194: #define SUBID_9005_TYPE_CARD 0x0 /* Standard Card */
195: #define SUBID_9005_TYPE_LCCARD 0x1 /* Low Cost Card */
196: #define SUBID_9005_TYPE_RAID 0x3 /* Combined with Raid */
197:
198: #define SUBID_9005_TYPE_KNOWN(id) \
199: ((((id) & 0xF) == SUBID_9005_TYPE_MB) \
200: || (((id) & 0xF) == SUBID_9005_TYPE_CARD) \
201: || (((id) & 0xF) == SUBID_9005_TYPE_LCCARD) \
202: || (((id) & 0xF) == SUBID_9005_TYPE_RAID))
203:
204: #define SUBID_9005_MAXRATE(id) (((id) & 0x30) >> 4)
205: #define SUBID_9005_MAXRATE_ULTRA2 0x0
206: #define SUBID_9005_MAXRATE_ULTRA 0x1
207: #define SUBID_9005_MAXRATE_U160 0x2
208: #define SUBID_9005_MAXRATE_RESERVED 0x3
209:
210: #define SUBID_9005_SEEPTYPE(id) \
211: ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
212: ? ((id) & 0xC0) >> 6 \
213: : ((id) & 0x300) >> 8)
214: #define SUBID_9005_SEEPTYPE_NONE 0x0
215: #define SUBID_9005_SEEPTYPE_1K 0x1
216: #define SUBID_9005_SEEPTYPE_2K_4K 0x2
217: #define SUBID_9005_SEEPTYPE_RESERVED 0x3
218: #define SUBID_9005_AUTOTERM(id) \
219: ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
220: ? (((id) & 0x400) >> 10) == 0 \
221: : (((id) & 0x40) >> 6) == 0)
222:
223: #define SUBID_9005_NUMCHAN(id) \
224: ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
225: ? ((id) & 0x300) >> 8 \
226: : ((id) & 0xC00) >> 10)
227:
228: #define SUBID_9005_LEGACYCONN(id) \
229: ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
230: ? 0 \
231: : ((id) & 0x80) >> 7)
232:
233: #define SUBID_9005_MFUNCENB(id) \
234: ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
235: ? ((id) & 0x800) >> 11 \
236: : ((id) & 0x1000) >> 12)
237: /*
238: * Informational only. Should use chip register to be
239: * certain, but may be use in identification strings.
240: */
241: #define SUBID_9005_CARD_SCSIWIDTH_MASK 0x2000
242: #define SUBID_9005_CARD_PCIWIDTH_MASK 0x4000
243: #define SUBID_9005_CARD_SEDIFF_MASK 0x8000
244:
245: static ahc_device_setup_t ahc_aic785X_setup;
246: static ahc_device_setup_t ahc_aic7860_setup;
247: static ahc_device_setup_t ahc_apa1480_setup;
248: static ahc_device_setup_t ahc_aic7870_setup;
249: static ahc_device_setup_t ahc_aha394X_setup;
250: static ahc_device_setup_t ahc_aha494X_setup;
251: static ahc_device_setup_t ahc_aha398X_setup;
252: static ahc_device_setup_t ahc_aic7880_setup;
253: static ahc_device_setup_t ahc_aha2940Pro_setup;
254: static ahc_device_setup_t ahc_aha394XU_setup;
255: static ahc_device_setup_t ahc_aha398XU_setup;
256: static ahc_device_setup_t ahc_aic7890_setup;
257: static ahc_device_setup_t ahc_aic7892_setup;
258: static ahc_device_setup_t ahc_aic7895_setup;
259: static ahc_device_setup_t ahc_aic7896_setup;
260: static ahc_device_setup_t ahc_aic7899_setup;
261: static ahc_device_setup_t ahc_aha29160C_setup;
262: static ahc_device_setup_t ahc_raid_setup;
263: static ahc_device_setup_t ahc_aha394XX_setup;
264: static ahc_device_setup_t ahc_aha494XX_setup;
265: static ahc_device_setup_t ahc_aha398XX_setup;
266:
267: struct ahc_pci_identity ahc_pci_ident_table [] =
268: {
269: /* aic7850 based controllers */
270: {
271: ID_AHA_2902_04_10_15_20_30C,
272: ID_ALL_MASK,
273: ahc_aic785X_setup
274: },
275: /* aic7860 based controllers */
276: {
277: ID_AHA_2930CU,
278: ID_ALL_MASK,
279: ahc_aic7860_setup
280: },
281: {
282: ID_AHA_1480A & ID_DEV_VENDOR_MASK,
283: ID_DEV_VENDOR_MASK,
284: ahc_apa1480_setup
285: },
286: {
287: ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK,
288: ID_DEV_VENDOR_MASK,
289: ahc_aic7860_setup
290: },
291: {
292: ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK,
293: ID_DEV_VENDOR_MASK,
294: ahc_aic7860_setup
295: },
296: {
297: ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK,
298: ID_DEV_VENDOR_MASK,
299: ahc_aic7860_setup
300: },
301: /* aic7870 based controllers */
302: {
303: ID_AHA_2940,
304: ID_ALL_MASK,
305: ahc_aic7870_setup
306: },
307: {
308: ID_AHA_3940,
309: ID_ALL_MASK,
310: ahc_aha394X_setup
311: },
312: {
313: ID_AHA_398X,
314: ID_ALL_MASK,
315: ahc_aha398X_setup
316: },
317: {
318: ID_AHA_2944,
319: ID_ALL_MASK,
320: ahc_aic7870_setup
321: },
322: {
323: ID_AHA_3944,
324: ID_ALL_MASK,
325: ahc_aha394X_setup
326: },
327: {
328: ID_AHA_4944,
329: ID_ALL_MASK,
330: ahc_aha494X_setup
331: },
332: /* aic7880 based controllers */
333: {
334: ID_AHA_2940U & ID_DEV_VENDOR_MASK,
335: ID_DEV_VENDOR_MASK,
336: ahc_aic7880_setup
337: },
338: {
339: ID_AHA_3940U & ID_DEV_VENDOR_MASK,
340: ID_DEV_VENDOR_MASK,
341: ahc_aha394XU_setup
342: },
343: {
344: ID_AHA_2944U & ID_DEV_VENDOR_MASK,
345: ID_DEV_VENDOR_MASK,
346: ahc_aic7880_setup
347: },
348: {
349: ID_AHA_3944U & ID_DEV_VENDOR_MASK,
350: ID_DEV_VENDOR_MASK,
351: ahc_aha394XU_setup
352: },
353: {
354: ID_AHA_398XU & ID_DEV_VENDOR_MASK,
355: ID_DEV_VENDOR_MASK,
356: ahc_aha398XU_setup
357: },
358: {
359: /*
360: * XXX Don't know the slot numbers
361: * so we can't identify channels
362: */
363: ID_AHA_4944U & ID_DEV_VENDOR_MASK,
364: ID_DEV_VENDOR_MASK,
365: ahc_aic7880_setup
366: },
367: {
368: ID_AHA_2930U & ID_DEV_VENDOR_MASK,
369: ID_DEV_VENDOR_MASK,
370: ahc_aic7880_setup
371: },
372: {
373: ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK,
374: ID_DEV_VENDOR_MASK,
375: ahc_aha2940Pro_setup
376: },
377: {
378: ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK,
379: ID_DEV_VENDOR_MASK,
380: ahc_aic7880_setup
381: },
382: /* Ignore all SISL (AAC on MB) based controllers. */
383: {
384: ID_9005_SISL_ID,
385: ID_9005_SISL_MASK,
386: NULL
387: },
388: /* aic7890 based controllers */
389: {
390: ID_AHA_2930U2,
391: ID_ALL_MASK,
392: ahc_aic7890_setup
393: },
394: {
395: ID_AHA_2940U2B,
396: ID_ALL_MASK,
397: ahc_aic7890_setup
398: },
399: {
400: ID_AHA_2940U2_OEM,
401: ID_ALL_MASK,
402: ahc_aic7890_setup
403: },
404: {
405: ID_AHA_2940U2,
406: ID_ALL_MASK,
407: ahc_aic7890_setup
408: },
409: {
410: ID_AHA_2950U2B,
411: ID_ALL_MASK,
412: ahc_aic7890_setup
413: },
414: {
415: ID_AIC7890_ARO,
416: ID_ALL_MASK,
417: ahc_aic7890_setup
418: },
419: {
420: ID_AAA_131U2,
421: ID_ALL_MASK,
422: ahc_aic7890_setup
423: },
424: /* aic7892 based controllers */
425: {
426: ID_AHA_29160,
427: ID_ALL_MASK,
428: ahc_aic7892_setup
429: },
430: {
431: ID_AHA_29160_CPQ,
432: ID_ALL_MASK,
433: ahc_aic7892_setup
434: },
435: {
436: ID_AHA_29160N,
437: ID_ALL_MASK,
438: ahc_aic7892_setup
439: },
440: {
441: ID_AHA_29160C,
442: ID_ALL_MASK,
443: ahc_aha29160C_setup
444: },
445: {
446: ID_AHA_29160B,
447: ID_ALL_MASK,
448: ahc_aic7892_setup
449: },
450: {
451: ID_AHA_19160B,
452: ID_ALL_MASK,
453: ahc_aic7892_setup
454: },
455: {
456: ID_AIC7892_ARO,
457: ID_ALL_MASK,
458: ahc_aic7892_setup
459: },
460: {
461: ID_AHA_2915LP,
462: ID_ALL_MASK,
463: ahc_aic7892_setup
464: },
465: /* aic7895 based controllers */
466: {
467: ID_AHA_2940U_DUAL,
468: ID_ALL_MASK,
469: ahc_aic7895_setup
470: },
471: {
472: ID_AHA_3940AU,
473: ID_ALL_MASK,
474: ahc_aic7895_setup
475: },
476: {
477: ID_AHA_3944AU,
478: ID_ALL_MASK,
479: ahc_aic7895_setup
480: },
481: {
482: ID_AIC7895_ARO,
483: ID_AIC7895_ARO_MASK,
484: ahc_aic7895_setup
485: },
486: /* aic7896/97 based controllers */
487: {
488: ID_AHA_3950U2B_0,
489: ID_ALL_MASK,
490: ahc_aic7896_setup
491: },
492: {
493: ID_AHA_3950U2B_1,
494: ID_ALL_MASK,
495: ahc_aic7896_setup
496: },
497: {
498: ID_AHA_3950U2D_0,
499: ID_ALL_MASK,
500: ahc_aic7896_setup
501: },
502: {
503: ID_AHA_3950U2D_1,
504: ID_ALL_MASK,
505: ahc_aic7896_setup
506: },
507: {
508: ID_AIC7896_ARO,
509: ID_ALL_MASK,
510: ahc_aic7896_setup
511: },
512: /* aic7899 based controllers */
513: {
514: ID_AHA_3960D,
515: ID_ALL_MASK,
516: ahc_aic7899_setup
517: },
518: {
519: ID_AHA_3960D_CPQ,
520: ID_ALL_MASK,
521: ahc_aic7899_setup
522: },
523: {
524: ID_AIC7899_ARO,
525: ID_ALL_MASK,
526: ahc_aic7899_setup
527: },
528: /* Generic chip probes for devices we don't know 'exactly' */
529: {
530: ID_AIC7850 & ID_DEV_VENDOR_MASK,
531: ID_DEV_VENDOR_MASK,
532: ahc_aic785X_setup
533: },
534: {
535: ID_AIC7855 & ID_DEV_VENDOR_MASK,
536: ID_DEV_VENDOR_MASK,
537: ahc_aic785X_setup
538: },
539: {
540: ID_AIC7859 & ID_DEV_VENDOR_MASK,
541: ID_DEV_VENDOR_MASK,
542: ahc_aic7860_setup
543: },
544: {
545: ID_AIC7860 & ID_DEV_VENDOR_MASK,
546: ID_DEV_VENDOR_MASK,
547: ahc_aic7860_setup
548: },
549: {
550: ID_AIC7870 & ID_DEV_VENDOR_MASK,
551: ID_DEV_VENDOR_MASK,
552: ahc_aic7870_setup
553: },
554: {
555: ID_AIC7880 & ID_DEV_VENDOR_MASK,
556: ID_DEV_VENDOR_MASK,
557: ahc_aic7880_setup
558: },
559: {
560: ID_AIC7890 & ID_9005_GENERIC_MASK,
561: ID_9005_GENERIC_MASK,
562: ahc_aic7890_setup
563: },
564: {
565: ID_AIC7892 & ID_9005_GENERIC_MASK,
566: ID_9005_GENERIC_MASK,
567: ahc_aic7892_setup
568: },
569: {
570: ID_AIC7895 & ID_DEV_VENDOR_MASK,
571: ID_DEV_VENDOR_MASK,
572: ahc_aic7895_setup
573: },
574: {
575: ID_AIC7896 & ID_9005_GENERIC_MASK,
576: ID_9005_GENERIC_MASK,
577: ahc_aic7896_setup
578: },
579: {
580: ID_AIC7899 & ID_9005_GENERIC_MASK,
581: ID_9005_GENERIC_MASK,
582: ahc_aic7899_setup
583: },
584: {
585: ID_AIC7810 & ID_DEV_VENDOR_MASK,
586: ID_DEV_VENDOR_MASK,
587: ahc_raid_setup
588: },
589: {
590: ID_AIC7815 & ID_DEV_VENDOR_MASK,
591: ID_DEV_VENDOR_MASK,
592: ahc_raid_setup
593: }
594: };
595:
596: #define AHC_394X_SLOT_CHANNEL_A 4
597: #define AHC_394X_SLOT_CHANNEL_B 5
598:
599: #define AHC_398X_SLOT_CHANNEL_A 4
600: #define AHC_398X_SLOT_CHANNEL_B 8
601: #define AHC_398X_SLOT_CHANNEL_C 12
602:
603: #define AHC_494X_SLOT_CHANNEL_A 4
604: #define AHC_494X_SLOT_CHANNEL_B 5
605: #define AHC_494X_SLOT_CHANNEL_C 6
606: #define AHC_494X_SLOT_CHANNEL_D 7
607:
608: #define DEVCONFIG 0x40
609: #define PCIERRGENDIS 0x80000000ul
610: #define SCBSIZE32 0x00010000ul /* aic789X only */
611: #define REXTVALID 0x00001000ul /* ultra cards only */
612: #define MPORTMODE 0x00000400ul /* aic7870+ only */
613: #define RAMPSM 0x00000200ul /* aic7870+ only */
614: #define VOLSENSE 0x00000100ul
615: #define PCI64BIT 0x00000080ul /* 64Bit PCI bus (Ultra2 Only)*/
616: #define SCBRAMSEL 0x00000080ul
617: #define MRDCEN 0x00000040ul
618: #define EXTSCBTIME 0x00000020ul /* aic7870 only */
619: #define EXTSCBPEN 0x00000010ul /* aic7870 only */
620: #define BERREN 0x00000008ul
621: #define DACEN 0x00000004ul
622: #define STPWLEVEL 0x00000002ul
623: #define DIFACTNEGEN 0x00000001ul /* aic7870 only */
624:
625: #define CSIZE_LATTIME 0x0c
626: #define CACHESIZE 0x0000003ful /* only 5 bits */
627: #define LATTIME 0x0000ff00ul
628:
629: /* PCI STATUS definitions */
630: #define DPE 0x80
631: #define SSE 0x40
632: #define RMA 0x20
633: #define RTA 0x10
634: #define STA 0x08
635: #define DPR 0x01
636:
637: static int ahc_9005_subdevinfo_valid(uint16_t vendor, uint16_t device,
638: uint16_t subvendor, uint16_t subdevice);
639: static int ahc_ext_scbram_present(struct ahc_softc *ahc);
640: static void ahc_scbram_config(struct ahc_softc *ahc, int enable,
641: int pcheck, int fast, int large);
642: static void ahc_probe_ext_scbram(struct ahc_softc *ahc);
643: static int ahc_pci_chip_init(struct ahc_softc *ahc);
644:
645: int ahc_pci_probe(struct device *, void *, void *);
646: void ahc_pci_attach(struct device *, struct device *, void *);
647:
648:
649: struct cfattach ahc_pci_ca = {
650: sizeof(struct ahc_softc), ahc_pci_probe, ahc_pci_attach
651: };
652:
653: const struct ahc_pci_identity *
654: ahc_find_pci_device(id, subid, func)
655: pcireg_t id, subid;
656: u_int func;
657: {
658: u_int64_t full_id;
659: const struct ahc_pci_identity *entry;
660: u_int i;
661:
662: full_id = ahc_compose_id(PCI_PRODUCT(id), PCI_VENDOR(id),
663: PCI_PRODUCT(subid), PCI_VENDOR(subid));
664:
665: /*
666: * If the second function is not hooked up, ignore it.
667: * Unfortunately, not all MB vendors implement the
668: * subdevice ID as per the Adaptec spec, so do our best
669: * to sanity check it prior to accepting the subdevice
670: * ID as valid.
671: */
672: if (func > 0
673: && ahc_9005_subdevinfo_valid(PCI_VENDOR(id), PCI_PRODUCT(id),
674: PCI_VENDOR(subid), PCI_PRODUCT(subid))
675: && SUBID_9005_MFUNCENB(PCI_PRODUCT(subid)) == 0)
676: return (NULL);
677:
678: for (i = 0; i < NUM_ELEMENTS(ahc_pci_ident_table); i++) {
679: entry = &ahc_pci_ident_table[i];
680: if (entry->full_id == (full_id & entry->id_mask))
681: return (entry);
682: }
683: return (NULL);
684: }
685:
686: int
687: ahc_pci_probe(parent, match, aux)
688: struct device *parent;
689: void *match, *aux;
690: {
691: struct pci_attach_args *pa = aux;
692: const struct ahc_pci_identity *entry;
693: pcireg_t subid;
694:
695: subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
696: entry = ahc_find_pci_device(pa->pa_id, subid, pa->pa_function);
697: return (entry != NULL && entry->setup != NULL) ? 1 : 0;
698: }
699:
700: void
701: ahc_pci_attach(parent, self, aux)
702: struct device *parent, *self;
703: void *aux;
704: {
705: struct pci_attach_args *pa = aux;
706: const struct ahc_pci_identity *entry;
707: struct ahc_softc *ahc = (void *)self;
708: pcireg_t command;
709: u_int our_id = 0;
710: u_int sxfrctl1;
711: u_int scsiseq;
712: u_int sblkctl;
713: uint8_t dscommand0;
714: uint32_t devconfig;
715: int error;
716: pcireg_t subid;
717: int ioh_valid;
718: bus_space_tag_t st, iot;
719: bus_space_handle_t sh, ioh;
720: #ifdef AHC_ALLOW_MEMIO
721: int memh_valid;
722: bus_space_tag_t memt;
723: bus_space_handle_t memh;
724: pcireg_t memtype;
725: #endif
726: pci_intr_handle_t ih;
727: const char *intrstr;
728: struct ahc_pci_busdata *bd;
729: int i;
730:
731: /*
732: * Instead of ahc_alloc() as in FreeBSD, do the few relevant
733: * initializations manually.
734: */
735: LIST_INIT(&ahc->pending_scbs);
736: ahc->channel = 'A';
737: ahc->seqctl = FASTMODE;
738: for (i = 0; i < AHC_NUM_TARGETS; i++)
739: TAILQ_INIT(&ahc->untagged_queues[i]);
740:
741: /*
742: * SCSI_IS_SCSIBUS_B() must returns false until sc_channel_b
743: * has been properly initialized. XXX Breaks if >254 scsi buses.
744: */
745: ahc->sc_channel_b.scsibus = 0xff;
746:
747: ahc->dev_softc = pa;
748:
749: ahc_set_name(ahc, ahc->sc_dev.dv_xname);
750: ahc->parent_dmat = pa->pa_dmat;
751:
752: subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
753: entry = ahc_find_pci_device(pa->pa_id, subid, pa->pa_function);
754: if (entry == NULL)
755: return;
756:
757: /* Keep information about the PCI bus */
758: bd = malloc(sizeof (struct ahc_pci_busdata), M_DEVBUF, M_NOWAIT);
759: if (bd == NULL) {
760: printf("%s: unable to allocate bus-specific data\n", ahc_name(ahc));
761: return;
762: }
763: memset(bd, 0, sizeof(struct ahc_pci_busdata));
764:
765: bd->pc = pa->pa_pc;
766: bd->tag = pa->pa_tag;
767: bd->func = pa->pa_function;
768: bd->dev = pa->pa_device;
769: bd->class = pa->pa_class;
770:
771: ahc->bd = bd;
772:
773: error = entry->setup(ahc);
774: if (error != 0)
775: return;
776:
777: ioh_valid = 0;
778:
779: #ifdef AHC_ALLOW_MEMIO
780: memh_valid = 0;
781: memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, AHC_PCI_MEMADDR);
782: switch (memtype) {
783: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
784: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
785: memh_valid = (pci_mapreg_map(pa, AHC_PCI_MEMADDR,
786: memtype, 0, &memt, &memh, NULL, NULL, 0) == 0);
787: break;
788: default:
789: memh_valid = 0;
790: }
791: if (memh_valid == 0)
792: #endif
793: ioh_valid = (pci_mapreg_map(pa, AHC_PCI_IOADDR,
794: PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL, 0) == 0);
795: #if 0
796: printf("%s: mem mapping: memt 0x%x, memh 0x%x, iot 0x%x, ioh 0x%lx\n",
797: ahc_name(ahc), memt, (u_int32_t)memh, (u_int32_t)iot, ioh);
798: #endif
799:
800: if (ioh_valid) {
801: st = iot;
802: sh = ioh;
803: #ifdef AHC_ALLOW_MEMIO
804: } else if (memh_valid) {
805: st = memt;
806: sh = memh;
807: #endif
808: } else {
809: printf(": unable to map registers\n");
810: return;
811: }
812: ahc->tag = st;
813: ahc->bsh = sh;
814:
815: ahc->chip |= AHC_PCI;
816: /*
817: * Before we continue probing the card, ensure that
818: * its interrupts are *disabled*. We don't want
819: * a misstep to hang the machine in an interrupt
820: * storm.
821: */
822: ahc_intr_enable(ahc, FALSE);
823:
824: /*
825: * XXX somehow reading this once fails on some sparc64 systems.
826: * This may be a problem in the sparc64 PCI code. Doing it
827: * twice works around it.
828: */
829: devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
830: devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
831:
832: /*
833: * If we need to support high memory, enable dual
834: * address cycles. This bit must be set to enable
835: * high address bit generation even if we are on a
836: * 64bit bus (PCI64BIT set in devconfig).
837: */
838: if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
839:
840: if (1/*bootverbose*/)
841: printf("%s: Enabling 39Bit Addressing\n",
842: ahc_name(ahc));
843: devconfig |= DACEN;
844: }
845:
846: /* Ensure that pci error generation, a test feature, is disabled. */
847: devconfig |= PCIERRGENDIS;
848:
849: pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG, devconfig);
850:
851: /*
852: * Disable PCI parity error reporting. Users typically
853: * do this to work around broken PCI chipsets that get
854: * the parity timing wrong and thus generate lots of spurious
855: * errors.
856: */
857: if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0) {
858: command = pci_conf_read(pa->pa_pc, pa->pa_tag,
859: PCI_COMMAND_STATUS_REG);
860: pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
861: command & ~PCI_COMMAND_PARITY_ENABLE);
862: }
863:
864: /* On all PCI adapters, we allow SCB paging */
865: ahc->flags |= AHC_PAGESCBS;
866: error = ahc_softc_init(ahc);
867: if (error != 0)
868: goto error_out;
869:
870: ahc->bus_intr = ahc_pci_intr;
871: ahc->bus_chip_init = ahc_pci_chip_init;
872:
873: /* Remember how the card was setup in case there is no SEEPROM */
874: if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) {
875: ahc_pause(ahc);
876: if ((ahc->features & AHC_ULTRA2) != 0)
877: our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
878: else
879: our_id = ahc_inb(ahc, SCSIID) & OID;
880: sxfrctl1 = ahc_inb(ahc, SXFRCTL1) & STPWEN;
881: scsiseq = ahc_inb(ahc, SCSISEQ);
882: } else {
883: sxfrctl1 = STPWEN;
884: our_id = 7;
885: scsiseq = 0;
886: }
887:
888: error = ahc_reset(ahc, /*reinit*/FALSE);
889: if (error != 0)
890: goto error_out;
891:
892: if ((ahc->features & AHC_DT) != 0) {
893: u_int sfunct;
894:
895: /* Perform ALT-Mode Setup */
896: sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
897: ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
898: ahc_outb(ahc, OPTIONMODE,
899: OPTIONMODE_DEFAULTS|AUTOACKEN|BUSFREEREV|EXPPHASEDIS);
900: ahc_outb(ahc, SFUNCT, sfunct);
901:
902: /* Normal mode setup */
903: ahc_outb(ahc, CRCCONTROL1, CRCVALCHKEN|CRCENDCHKEN|CRCREQCHKEN
904: |TARGCRCENDEN);
905: }
906:
907: if (pci_intr_map(pa, &ih)) {
908: printf("%s: couldn't map interrupt\n", ahc_name(ahc));
909: ahc_free(ahc);
910: return;
911: }
912: intrstr = pci_intr_string(pa->pa_pc, ih);
913: ahc->ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
914: ahc_platform_intr, ahc, ahc->sc_dev.dv_xname);
915: if (ahc->ih == NULL) {
916: printf(": couldn't establish interrupt");
917: if (intrstr != NULL)
918: printf(" at %s", intrstr);
919: printf("\n");
920: ahc_free(ahc);
921: return;
922: } else
923: printf(": %s\n", intrstr ? intrstr : "?");
924:
925: dscommand0 = ahc_inb(ahc, DSCOMMAND0);
926: dscommand0 |= MPARCKEN|CACHETHEN;
927: if ((ahc->features & AHC_ULTRA2) != 0) {
928:
929: /*
930: * DPARCKEN doesn't work correctly on
931: * some MBs so don't use it.
932: */
933: dscommand0 &= ~DPARCKEN;
934: }
935:
936: /*
937: * Handle chips that must have cache line
938: * streaming (dis/en)abled.
939: */
940: if ((ahc->bugs & AHC_CACHETHEN_DIS_BUG) != 0)
941: dscommand0 |= CACHETHEN;
942:
943: if ((ahc->bugs & AHC_CACHETHEN_BUG) != 0)
944: dscommand0 &= ~CACHETHEN;
945:
946: ahc_outb(ahc, DSCOMMAND0, dscommand0);
947:
948: ahc->pci_cachesize =
949: pci_conf_read(pa->pa_pc, pa->pa_tag, CSIZE_LATTIME) & CACHESIZE;
950: ahc->pci_cachesize *= 4;
951:
952: if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0
953: && ahc->pci_cachesize == 4) {
954: pci_conf_write(pa->pa_pc, pa->pa_tag, CSIZE_LATTIME, 0);
955: ahc->pci_cachesize = 0;
956: }
957:
958: /*
959: * We cannot perform ULTRA speeds without the presence
960: * of the external precision resistor.
961: */
962: if ((ahc->features & AHC_ULTRA) != 0) {
963: uint32_t devconfig;
964:
965: devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
966: if ((devconfig & REXTVALID) == 0)
967: ahc->features &= ~AHC_ULTRA;
968: }
969:
970: ahc->seep_config = malloc(sizeof(*ahc->seep_config),
971: M_DEVBUF, M_NOWAIT);
972: if (ahc->seep_config == NULL)
973: goto error_out;
974:
975: memset(ahc->seep_config, 0, sizeof(*ahc->seep_config));
976:
977: /* See if we have a SEEPROM and perform auto-term */
978: ahc_check_extport(ahc, &sxfrctl1);
979:
980: /*
981: * Take the LED out of diagnostic mode
982: */
983: sblkctl = ahc_inb(ahc, SBLKCTL);
984: ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));
985:
986: if ((ahc->features & AHC_ULTRA2) != 0) {
987: ahc_outb(ahc, DFF_THRSH, RD_DFTHRSH_MAX|WR_DFTHRSH_MAX);
988: } else {
989: ahc_outb(ahc, DSPCISTATUS, DFTHRSH_100);
990: }
991:
992: if (ahc->flags & AHC_USEDEFAULTS) {
993: /*
994: * PCI Adapter default setup
995: * Should only be used if the adapter does not have
996: * a SEEPROM.
997: */
998: /* See if someone else set us up already */
999: if ((ahc->flags & AHC_NO_BIOS_INIT) == 0
1000: && scsiseq != 0) {
1001: printf("%s: Using left over BIOS settings\n",
1002: ahc_name(ahc));
1003: ahc->flags &= ~AHC_USEDEFAULTS;
1004: ahc->flags |= AHC_BIOS_ENABLED;
1005: } else {
1006: /*
1007: * Assume only one connector and always turn
1008: * on termination.
1009: */
1010: our_id = 0x07;
1011: sxfrctl1 = STPWEN;
1012: }
1013: ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI);
1014:
1015: ahc->our_id = our_id;
1016: }
1017:
1018: /*
1019: * Take a look to see if we have external SRAM.
1020: * We currently do not attempt to use SRAM that is
1021: * shared among multiple controllers.
1022: */
1023: ahc_probe_ext_scbram(ahc);
1024:
1025: /*
1026: * Record our termination setting for the
1027: * generic initialization routine.
1028: */
1029: if ((sxfrctl1 & STPWEN) != 0)
1030: ahc->flags |= AHC_TERM_ENB_A;
1031:
1032: /*
1033: * Save chip register configuration data for chip resets
1034: * that occur during runtime and resume events.
1035: */
1036: ahc->bus_softc.pci_softc.devconfig =
1037: pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
1038: ahc->bus_softc.pci_softc.command =
1039: pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
1040: ahc->bus_softc.pci_softc.csize_lattime =
1041: pci_conf_read(pa->pa_pc, pa->pa_tag, CSIZE_LATTIME);
1042: ahc->bus_softc.pci_softc.dscommand0 = ahc_inb(ahc, DSCOMMAND0);
1043: ahc->bus_softc.pci_softc.dspcistatus = ahc_inb(ahc, DSPCISTATUS);
1044: if ((ahc->features & AHC_DT) != 0) {
1045: u_int sfunct;
1046:
1047: sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
1048: ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
1049: ahc->bus_softc.pci_softc.optionmode = ahc_inb(ahc, OPTIONMODE);
1050: ahc->bus_softc.pci_softc.targcrccnt = ahc_inw(ahc, TARGCRCCNT);
1051: ahc_outb(ahc, SFUNCT, sfunct);
1052: ahc->bus_softc.pci_softc.crccontrol1 =
1053: ahc_inb(ahc, CRCCONTROL1);
1054: }
1055: if ((ahc->features & AHC_MULTI_FUNC) != 0)
1056: ahc->bus_softc.pci_softc.scbbaddr = ahc_inb(ahc, SCBBADDR);
1057:
1058: if ((ahc->features & AHC_ULTRA2) != 0)
1059: ahc->bus_softc.pci_softc.dff_thrsh = ahc_inb(ahc, DFF_THRSH);
1060:
1061: /* Core initialization */
1062: if (ahc_init(ahc))
1063: goto error_out;
1064:
1065: ahc_attach(ahc);
1066:
1067: return;
1068:
1069: error_out:
1070: ahc_free(ahc);
1071: return;
1072: }
1073:
1074: static int
1075: ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor,
1076: uint16_t subdevice, uint16_t subvendor)
1077: {
1078: int result;
1079:
1080: /* Default to invalid. */
1081: result = 0;
1082: if (vendor == 0x9005
1083: && subvendor == 0x9005
1084: && subdevice != device
1085: && SUBID_9005_TYPE_KNOWN(subdevice) != 0) {
1086:
1087: switch (SUBID_9005_TYPE(subdevice)) {
1088: case SUBID_9005_TYPE_MB:
1089: break;
1090: case SUBID_9005_TYPE_CARD:
1091: case SUBID_9005_TYPE_LCCARD:
1092: /*
1093: * Currently only trust Adaptec cards to
1094: * get the sub device info correct.
1095: */
1096: if (DEVID_9005_TYPE(device) == DEVID_9005_TYPE_HBA)
1097: result = 1;
1098: break;
1099: case SUBID_9005_TYPE_RAID:
1100: break;
1101: default:
1102: break;
1103: }
1104: }
1105: return (result);
1106: }
1107:
1108:
1109: /*
1110: * Test for the presense of external sram in an
1111: * "unshared" configuration.
1112: */
1113: static int
1114: ahc_ext_scbram_present(struct ahc_softc *ahc)
1115: {
1116: u_int chip;
1117: int ramps;
1118: int single_user;
1119: uint32_t devconfig;
1120:
1121: chip = ahc->chip & AHC_CHIPID_MASK;
1122: devconfig = pci_conf_read(ahc->bd->pc, ahc->bd->tag, DEVCONFIG);
1123: single_user = (devconfig & MPORTMODE) != 0;
1124:
1125: if ((ahc->features & AHC_ULTRA2) != 0)
1126: ramps = (ahc_inb(ahc, DSCOMMAND0) & RAMPS) != 0;
1127: else if (chip == AHC_AIC7895 || chip == AHC_AIC7895C)
1128: /*
1129: * External SCBRAM arbitration is flakey
1130: * on these chips. Unfortunately this means
1131: * we don't use the extra SCB ram space on the
1132: * 3940AUW.
1133: */
1134: ramps = 0;
1135: else if (chip >= AHC_AIC7870)
1136: ramps = (devconfig & RAMPSM) != 0;
1137: else
1138: ramps = 0;
1139:
1140: if (ramps && single_user)
1141: return (1);
1142: return (0);
1143: }
1144:
1145: /*
1146: * Enable external scbram.
1147: */
1148: static void
1149: ahc_scbram_config(struct ahc_softc *ahc, int enable, int pcheck,
1150: int fast, int large)
1151: {
1152: uint32_t devconfig;
1153:
1154: if (ahc->features & AHC_MULTI_FUNC) {
1155: /*
1156: * Set the SCB Base addr (highest address bit)
1157: * depending on which channel we are.
1158: */
1159: ahc_outb(ahc, SCBBADDR, ahc->bd->func);
1160: }
1161:
1162: ahc->flags &= ~AHC_LSCBS_ENABLED;
1163: if (large)
1164: ahc->flags |= AHC_LSCBS_ENABLED;
1165: devconfig = pci_conf_read(ahc->bd->pc, ahc->bd->tag, DEVCONFIG);
1166: if ((ahc->features & AHC_ULTRA2) != 0) {
1167: u_int dscommand0;
1168:
1169: dscommand0 = ahc_inb(ahc, DSCOMMAND0);
1170: if (enable)
1171: dscommand0 &= ~INTSCBRAMSEL;
1172: else
1173: dscommand0 |= INTSCBRAMSEL;
1174: if (large)
1175: dscommand0 &= ~USCBSIZE32;
1176: else
1177: dscommand0 |= USCBSIZE32;
1178: ahc_outb(ahc, DSCOMMAND0, dscommand0);
1179: } else {
1180: if (fast)
1181: devconfig &= ~EXTSCBTIME;
1182: else
1183: devconfig |= EXTSCBTIME;
1184: if (enable)
1185: devconfig &= ~SCBRAMSEL;
1186: else
1187: devconfig |= SCBRAMSEL;
1188: if (large)
1189: devconfig &= ~SCBSIZE32;
1190: else
1191: devconfig |= SCBSIZE32;
1192: }
1193: if (pcheck)
1194: devconfig |= EXTSCBPEN;
1195: else
1196: devconfig &= ~EXTSCBPEN;
1197:
1198: pci_conf_write(ahc->bd->pc, ahc->bd->tag, DEVCONFIG, devconfig);
1199: }
1200:
1201: /*
1202: * Take a look to see if we have external SRAM.
1203: * We currently do not attempt to use SRAM that is
1204: * shared among multiple controllers.
1205: */
1206: static void
1207: ahc_probe_ext_scbram(struct ahc_softc *ahc)
1208: {
1209: int num_scbs;
1210: int test_num_scbs;
1211: int enable;
1212: int pcheck;
1213: int fast;
1214: int large;
1215:
1216: enable = FALSE;
1217: pcheck = FALSE;
1218: fast = FALSE;
1219: large = FALSE;
1220: num_scbs = 0;
1221:
1222: if (ahc_ext_scbram_present(ahc) == 0)
1223: goto done;
1224:
1225: /*
1226: * Probe for the best parameters to use.
1227: */
1228: ahc_scbram_config(ahc, /*enable*/TRUE, pcheck, fast, large);
1229: num_scbs = ahc_probe_scbs(ahc);
1230: if (num_scbs == 0) {
1231: /* The SRAM wasn't really present. */
1232: goto done;
1233: }
1234: enable = TRUE;
1235:
1236: /*
1237: * Clear any outstanding parity error
1238: * and ensure that parity error reporting
1239: * is enabled.
1240: */
1241: ahc_outb(ahc, SEQCTL, 0);
1242: ahc_outb(ahc, CLRINT, CLRPARERR);
1243: ahc_outb(ahc, CLRINT, CLRBRKADRINT);
1244:
1245: /* Now see if we can do parity */
1246: ahc_scbram_config(ahc, enable, /*pcheck*/TRUE, fast, large);
1247: num_scbs = ahc_probe_scbs(ahc);
1248: if ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0
1249: || (ahc_inb(ahc, ERROR) & MPARERR) == 0)
1250: pcheck = TRUE;
1251:
1252: /* Clear any resulting parity error */
1253: ahc_outb(ahc, CLRINT, CLRPARERR);
1254: ahc_outb(ahc, CLRINT, CLRBRKADRINT);
1255:
1256: /* Now see if we can do fast timing */
1257: ahc_scbram_config(ahc, enable, pcheck, /*fast*/TRUE, large);
1258: test_num_scbs = ahc_probe_scbs(ahc);
1259: if (test_num_scbs == num_scbs
1260: && ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0
1261: || (ahc_inb(ahc, ERROR) & MPARERR) == 0))
1262: fast = TRUE;
1263:
1264: /*
1265: * See if we can use large SCBs and still maintain
1266: * the same overall count of SCBs.
1267: */
1268: if ((ahc->features & AHC_LARGE_SCBS) != 0) {
1269: ahc_scbram_config(ahc, enable, pcheck, fast, /*large*/TRUE);
1270: test_num_scbs = ahc_probe_scbs(ahc);
1271: if (test_num_scbs >= num_scbs) {
1272: large = TRUE;
1273: num_scbs = test_num_scbs;
1274: if (num_scbs >= 64) {
1275: /*
1276: * We have enough space to move the
1277: * "busy targets table" into SCB space
1278: * and make it qualify all the way to the
1279: * lun level.
1280: */
1281: ahc->flags |= AHC_SCB_BTT;
1282: }
1283: }
1284: }
1285: done:
1286: /*
1287: * Disable parity error reporting until we
1288: * can load instruction ram.
1289: */
1290: ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);
1291: /* Clear any latched parity error */
1292: ahc_outb(ahc, CLRINT, CLRPARERR);
1293: ahc_outb(ahc, CLRINT, CLRBRKADRINT);
1294: if (1/*bootverbose*/ && enable) {
1295: printf("%s: External SRAM, %s access%s, %dbytes/SCB\n",
1296: ahc_name(ahc), fast ? "fast" : "slow",
1297: pcheck ? ", parity checking enabled" : "",
1298: large ? 64 : 32);
1299: }
1300: ahc_scbram_config(ahc, enable, pcheck, fast, large);
1301: }
1302:
1303: #if 0
1304: /*
1305: * Perform some simple tests that should catch situations where
1306: * our registers are invalidly mapped.
1307: */
1308: int
1309: ahc_pci_test_register_access(struct ahc_softc *ahc)
1310: {
1311: int error;
1312: u_int status1;
1313: uint32_t cmd;
1314: uint8_t hcntrl;
1315:
1316: error = EIO;
1317:
1318: /*
1319: * Enable PCI error interrupt status, but suppress NMIs
1320: * generated by SERR raised due to target aborts.
1321: */
1322: cmd = pci_conf_read(ahc->bd->pc, ahc->bd->tag, PCIR_COMMAND);
1323: pci_conf_write(ahc->bd->pc, ahc->bd->tag, PCIR_COMMAND,
1324: cmd & ~PCIM_CMD_SERRESPEN);
1325:
1326: /*
1327: * First a simple test to see if any
1328: * registers can be read. Reading
1329: * HCNTRL has no side effects and has
1330: * at least one bit that is guaranteed to
1331: * be zero so it is a good register to
1332: * use for this test.
1333: */
1334: hcntrl = ahc_inb(ahc, HCNTRL);
1335: if (hcntrl == 0xFF)
1336: goto fail;
1337:
1338: /*
1339: * Next create a situation where write combining
1340: * or read prefetching could be initiated by the
1341: * CPU or host bridge. Our device does not support
1342: * either, so look for data corruption and/or flagged
1343: * PCI errors.
1344: */
1345: ahc_outb(ahc, HCNTRL, hcntrl|PAUSE);
1346: while (ahc_is_paused(ahc) == 0)
1347: ;
1348: ahc_outb(ahc, SEQCTL, PERRORDIS);
1349: ahc_outb(ahc, SCBPTR, 0);
1350: ahc_outl(ahc, SCB_BASE, 0x5aa555aa);
1351: if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa)
1352: goto fail;
1353:
1354: status1 = pci_conf_read(ahc->bd->pc, ahc->bd->tag,
1355: PCI_COMMAND_STATUS_REG + 1);
1356: if ((status1 & STA) != 0)
1357: goto fail;
1358:
1359: error = 0;
1360:
1361: fail:
1362: /* Silently clear any latched errors. */
1363: status1 = pci_conf_read(ahc->bd->pc, ahc->bd->tag, PCI_COMMAND_STATUS_REG + 1);
1364: ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
1365: status1, /*bytes*/1);
1366: ahc_outb(ahc, CLRINT, CLRPARERR);
1367: ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);
1368: ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
1369: return (error);
1370: }
1371: #endif
1372:
1373: void
1374: ahc_pci_intr(struct ahc_softc *ahc)
1375: {
1376: u_int error;
1377: u_int status1;
1378:
1379: error = ahc_inb(ahc, ERROR);
1380: if ((error & PCIERRSTAT) == 0)
1381: return;
1382:
1383: status1 = pci_conf_read(ahc->bd->pc, ahc->bd->tag, PCI_COMMAND_STATUS_REG);
1384:
1385: printf("%s: PCI error Interrupt at seqaddr = 0x%x\n",
1386: ahc_name(ahc),
1387: ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
1388:
1389: if (status1 & DPE) {
1390: printf("%s: Data Parity Error Detected during address "
1391: "or write data phase\n", ahc_name(ahc));
1392: }
1393: if (status1 & SSE) {
1394: printf("%s: Signal System Error Detected\n", ahc_name(ahc));
1395: }
1396: if (status1 & RMA) {
1397: printf("%s: Received a Master Abort\n", ahc_name(ahc));
1398: }
1399: if (status1 & RTA) {
1400: printf("%s: Received a Target Abort\n", ahc_name(ahc));
1401: }
1402: if (status1 & STA) {
1403: printf("%s: Signaled a Target Abort\n", ahc_name(ahc));
1404: }
1405: if (status1 & DPR) {
1406: printf("%s: Data Parity Error has been reported via PERR#\n",
1407: ahc_name(ahc));
1408: }
1409:
1410: /* Clear latched errors. */
1411: pci_conf_write(ahc->bd->pc, ahc->bd->tag, PCI_COMMAND_STATUS_REG, status1);
1412:
1413: if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) {
1414: printf("%s: Latched PCIERR interrupt with "
1415: "no status bits set\n", ahc_name(ahc));
1416: } else {
1417: ahc_outb(ahc, CLRINT, CLRPARERR);
1418: }
1419:
1420: ahc_unpause(ahc);
1421: }
1422:
1423: static int
1424: ahc_pci_chip_init(struct ahc_softc *ahc)
1425: {
1426: ahc_outb(ahc, DSCOMMAND0, ahc->bus_softc.pci_softc.dscommand0);
1427: ahc_outb(ahc, DSPCISTATUS, ahc->bus_softc.pci_softc.dspcistatus);
1428: if ((ahc->features & AHC_DT) != 0) {
1429: u_int sfunct;
1430:
1431: sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
1432: ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
1433: ahc_outb(ahc, OPTIONMODE, ahc->bus_softc.pci_softc.optionmode);
1434: ahc_outw(ahc, TARGCRCCNT, ahc->bus_softc.pci_softc.targcrccnt);
1435: ahc_outb(ahc, SFUNCT, sfunct);
1436: ahc_outb(ahc, CRCCONTROL1,
1437: ahc->bus_softc.pci_softc.crccontrol1);
1438: }
1439: if ((ahc->features & AHC_MULTI_FUNC) != 0)
1440: ahc_outb(ahc, SCBBADDR, ahc->bus_softc.pci_softc.scbbaddr);
1441:
1442: if ((ahc->features & AHC_ULTRA2) != 0)
1443: ahc_outb(ahc, DFF_THRSH, ahc->bus_softc.pci_softc.dff_thrsh);
1444:
1445: return (ahc_chip_init(ahc));
1446: }
1447:
1448: static int
1449: ahc_aic785X_setup(struct ahc_softc *ahc)
1450: {
1451: uint8_t rev;
1452:
1453: ahc->channel = 'A';
1454: ahc->chip = AHC_AIC7850;
1455: ahc->features = AHC_AIC7850_FE;
1456: ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
1457: rev = PCI_REVISION(ahc->bd->class);
1458: if (rev >= 1)
1459: ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
1460: ahc->instruction_ram_size = 512;
1461: return (0);
1462: }
1463:
1464: static int
1465: ahc_aic7860_setup(struct ahc_softc *ahc)
1466: {
1467: uint8_t rev;
1468:
1469: ahc->channel = 'A';
1470: ahc->chip = AHC_AIC7860;
1471: ahc->features = AHC_AIC7860_FE;
1472: ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
1473: rev = PCI_REVISION(ahc->bd->class);
1474: if (rev >= 1)
1475: ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
1476: ahc->instruction_ram_size = 512;
1477: return (0);
1478: }
1479:
1480: static int
1481: ahc_apa1480_setup(struct ahc_softc *ahc)
1482: {
1483: int error;
1484:
1485: error = ahc_aic7860_setup(ahc);
1486: if (error != 0)
1487: return (error);
1488: ahc->features |= AHC_REMOVABLE;
1489: return (0);
1490: }
1491:
1492: static int
1493: ahc_aic7870_setup(struct ahc_softc *ahc)
1494: {
1495:
1496: ahc->channel = 'A';
1497: ahc->chip = AHC_AIC7870;
1498: ahc->features = AHC_AIC7870_FE;
1499: ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
1500: ahc->instruction_ram_size = 512;
1501: return (0);
1502: }
1503:
1504: static int
1505: ahc_aha394X_setup(struct ahc_softc *ahc)
1506: {
1507: int error;
1508:
1509: error = ahc_aic7870_setup(ahc);
1510: if (error == 0)
1511: error = ahc_aha394XX_setup(ahc);
1512: return (error);
1513: }
1514:
1515: static int
1516: ahc_aha398X_setup(struct ahc_softc *ahc)
1517: {
1518: int error;
1519:
1520: error = ahc_aic7870_setup(ahc);
1521: if (error == 0)
1522: error = ahc_aha398XX_setup(ahc);
1523: return (error);
1524: }
1525:
1526: static int
1527: ahc_aha494X_setup(struct ahc_softc *ahc)
1528: {
1529: int error;
1530:
1531: error = ahc_aic7870_setup(ahc);
1532: if (error == 0)
1533: error = ahc_aha494XX_setup(ahc);
1534: return (error);
1535: }
1536:
1537: static int
1538: ahc_aic7880_setup(struct ahc_softc *ahc)
1539: {
1540: uint8_t rev;
1541:
1542: ahc->channel = 'A';
1543: ahc->chip = AHC_AIC7880;
1544: ahc->features = AHC_AIC7880_FE;
1545: ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
1546: rev = PCI_REVISION(ahc->bd->class);
1547: if (rev >= 1) {
1548: ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
1549: } else {
1550: ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
1551: }
1552: ahc->instruction_ram_size = 512;
1553: return (0);
1554: }
1555:
1556: static int
1557: ahc_aha2940Pro_setup(struct ahc_softc *ahc)
1558: {
1559:
1560: ahc->flags |= AHC_INT50_SPEEDFLEX;
1561: return (ahc_aic7880_setup(ahc));
1562: }
1563:
1564: static int
1565: ahc_aha394XU_setup(struct ahc_softc *ahc)
1566: {
1567: int error;
1568:
1569: error = ahc_aic7880_setup(ahc);
1570: if (error == 0)
1571: error = ahc_aha394XX_setup(ahc);
1572: return (error);
1573: }
1574:
1575: static int
1576: ahc_aha398XU_setup(struct ahc_softc *ahc)
1577: {
1578: int error;
1579:
1580: error = ahc_aic7880_setup(ahc);
1581: if (error == 0)
1582: error = ahc_aha398XX_setup(ahc);
1583: return (error);
1584: }
1585:
1586: static int
1587: ahc_aic7890_setup(struct ahc_softc *ahc)
1588: {
1589: uint8_t rev;
1590:
1591: ahc->channel = 'A';
1592: ahc->chip = AHC_AIC7890;
1593: ahc->features = AHC_AIC7890_FE;
1594: ahc->flags |= AHC_NEWEEPROM_FMT;
1595: rev = PCI_REVISION(ahc->bd->class);
1596: if (rev == 0)
1597: ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG;
1598: ahc->instruction_ram_size = 768;
1599: return (0);
1600: }
1601:
1602: static int
1603: ahc_aic7892_setup(struct ahc_softc *ahc)
1604: {
1605:
1606: ahc->channel = 'A';
1607: ahc->chip = AHC_AIC7892;
1608: ahc->features = AHC_AIC7892_FE;
1609: ahc->flags |= AHC_NEWEEPROM_FMT;
1610: ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
1611: ahc->instruction_ram_size = 1024;
1612: return (0);
1613: }
1614:
1615: static int
1616: ahc_aic7895_setup(struct ahc_softc *ahc)
1617: {
1618: uint8_t rev;
1619:
1620: ahc->channel = (ahc->bd->func == 1) ? 'B' : 'A';
1621: /*
1622: * The 'C' revision of the aic7895 has a few additional features.
1623: */
1624: rev = PCI_REVISION(ahc->bd->class);
1625: if (rev >= 4) {
1626: ahc->chip = AHC_AIC7895C;
1627: ahc->features = AHC_AIC7895C_FE;
1628: } else {
1629: u_int command;
1630:
1631: ahc->chip = AHC_AIC7895;
1632: ahc->features = AHC_AIC7895_FE;
1633:
1634: /*
1635: * The BIOS disables the use of MWI transactions
1636: * since it does not have the MWI bug work around
1637: * we have. Disabling MWI reduces performance, so
1638: * turn it on again.
1639: */
1640: command = pci_conf_read(ahc->bd->pc, ahc->bd->tag, PCI_COMMAND_STATUS_REG);
1641: command |= PCI_COMMAND_INVALIDATE_ENABLE;
1642: pci_conf_write(ahc->bd->pc, ahc->bd->tag, PCI_COMMAND_STATUS_REG, command);
1643: ahc->bugs |= AHC_PCI_MWI_BUG;
1644: }
1645: /*
1646: * XXX Does CACHETHEN really not work??? What about PCI retry?
1647: * on C level chips. Need to test, but for now, play it safe.
1648: */
1649: ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_PCI_2_1_RETRY_BUG
1650: | AHC_CACHETHEN_BUG;
1651:
1652: #if 0
1653: uint32_t devconfig;
1654:
1655: /*
1656: * Cachesize must also be zero due to stray DAC
1657: * problem when sitting behind some bridges.
1658: */
1659: pci_conf_write(ahc->bd->pc, ahc->bd->tag, CSIZE_LATTIME, 0);
1660: devconfig = pci_conf_read(ahc->bd->pc, ahc->bd->tag, DEVCONFIG);
1661: devconfig |= MRDCEN;
1662: pci_conf_write(ahc->bd->pc, ahc->bd->tag, DEVCONFIG, devconfig);
1663: #endif
1664: ahc->flags |= AHC_NEWEEPROM_FMT;
1665: ahc->instruction_ram_size = 512;
1666: return (0);
1667: }
1668:
1669: static int
1670: ahc_aic7896_setup(struct ahc_softc *ahc)
1671: {
1672: ahc->channel = (ahc->bd->func == 1) ? 'B' : 'A';
1673: ahc->chip = AHC_AIC7896;
1674: ahc->features = AHC_AIC7896_FE;
1675: ahc->flags |= AHC_NEWEEPROM_FMT;
1676: ahc->bugs |= AHC_CACHETHEN_DIS_BUG;
1677: ahc->instruction_ram_size = 768;
1678: return (0);
1679: }
1680:
1681: static int
1682: ahc_aic7899_setup(struct ahc_softc *ahc)
1683: {
1684: ahc->channel = (ahc->bd->func == 1) ? 'B' : 'A';
1685: ahc->chip = AHC_AIC7899;
1686: ahc->features = AHC_AIC7899_FE;
1687: ahc->flags |= AHC_NEWEEPROM_FMT;
1688: ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
1689: ahc->instruction_ram_size = 1024;
1690: return (0);
1691: }
1692:
1693: static int
1694: ahc_aha29160C_setup(struct ahc_softc *ahc)
1695: {
1696: int error;
1697:
1698: error = ahc_aic7899_setup(ahc);
1699: if (error != 0)
1700: return (error);
1701: ahc->features |= AHC_REMOVABLE;
1702: return (0);
1703: }
1704:
1705: static int
1706: ahc_raid_setup(struct ahc_softc *ahc)
1707: {
1708: printf("RAID functionality unsupported\n");
1709: return (ENXIO);
1710: }
1711:
1712: static int
1713: ahc_aha394XX_setup(struct ahc_softc *ahc)
1714: {
1715:
1716: switch (ahc->bd->dev) {
1717: case AHC_394X_SLOT_CHANNEL_A:
1718: ahc->channel = 'A';
1719: break;
1720: case AHC_394X_SLOT_CHANNEL_B:
1721: ahc->channel = 'B';
1722: break;
1723: default:
1724: printf("adapter at unexpected slot %d\n"
1725: "unable to map to a channel\n",
1726: ahc->bd->dev);
1727: ahc->channel = 'A';
1728: }
1729: return (0);
1730: }
1731:
1732: static int
1733: ahc_aha398XX_setup(struct ahc_softc *ahc)
1734: {
1735:
1736: switch (ahc->bd->dev) {
1737: case AHC_398X_SLOT_CHANNEL_A:
1738: ahc->channel = 'A';
1739: break;
1740: case AHC_398X_SLOT_CHANNEL_B:
1741: ahc->channel = 'B';
1742: break;
1743: case AHC_398X_SLOT_CHANNEL_C:
1744: ahc->channel = 'C';
1745: break;
1746: default:
1747: printf("adapter at unexpected slot %d\n"
1748: "unable to map to a channel\n",
1749: ahc->bd->dev);
1750: ahc->channel = 'A';
1751: break;
1752: }
1753: ahc->flags |= AHC_LARGE_SEEPROM;
1754: return (0);
1755: }
1756:
1757: static int
1758: ahc_aha494XX_setup(struct ahc_softc *ahc)
1759: {
1760:
1761: switch (ahc->bd->dev) {
1762: case AHC_494X_SLOT_CHANNEL_A:
1763: ahc->channel = 'A';
1764: break;
1765: case AHC_494X_SLOT_CHANNEL_B:
1766: ahc->channel = 'B';
1767: break;
1768: case AHC_494X_SLOT_CHANNEL_C:
1769: ahc->channel = 'C';
1770: break;
1771: case AHC_494X_SLOT_CHANNEL_D:
1772: ahc->channel = 'D';
1773: break;
1774: default:
1775: printf("adapter at unexpected slot %d\n"
1776: "unable to map to a channel\n",
1777: ahc->bd->dev);
1778: ahc->channel = 'A';
1779: }
1780: ahc->flags |= AHC_LARGE_SEEPROM;
1781: return (0);
1782: }
CVSweb