diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/scsi/aic7xxx/aic7xxx_pci.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/scsi/aic7xxx/aic7xxx_pci.c')
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_pci.c | 2407 |
1 files changed, 2407 insertions, 0 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c new file mode 100644 index 000000000000..7ddcc97fb243 --- /dev/null +++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c | |||
@@ -0,0 +1,2407 @@ | |||
1 | /* | ||
2 | * Product specific probe and attach routines for: | ||
3 | * 3940, 2940, aic7895, aic7890, aic7880, | ||
4 | * aic7870, aic7860 and aic7850 SCSI controllers | ||
5 | * | ||
6 | * Copyright (c) 1994-2001 Justin T. Gibbs. | ||
7 | * Copyright (c) 2000-2001 Adaptec Inc. | ||
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, this list of conditions, and the following disclaimer, | ||
15 | * without modification. | ||
16 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
17 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
18 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
19 | * including a substantially similar Disclaimer requirement for further | ||
20 | * binary redistribution. | ||
21 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
22 | * of any contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * Alternatively, this software may be distributed under the terms of the | ||
26 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
27 | * Software Foundation. | ||
28 | * | ||
29 | * NO WARRANTY | ||
30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
34 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
35 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
36 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
37 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
38 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
39 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
40 | * POSSIBILITY OF SUCH DAMAGES. | ||
41 | * | ||
42 | * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#69 $ | ||
43 | * | ||
44 | * $FreeBSD$ | ||
45 | */ | ||
46 | |||
47 | #ifdef __linux__ | ||
48 | #include "aic7xxx_osm.h" | ||
49 | #include "aic7xxx_inline.h" | ||
50 | #include "aic7xxx_93cx6.h" | ||
51 | #else | ||
52 | #include <dev/aic7xxx/aic7xxx_osm.h> | ||
53 | #include <dev/aic7xxx/aic7xxx_inline.h> | ||
54 | #include <dev/aic7xxx/aic7xxx_93cx6.h> | ||
55 | #endif | ||
56 | |||
57 | #include "aic7xxx_pci.h" | ||
58 | |||
59 | static __inline uint64_t | ||
60 | ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) | ||
61 | { | ||
62 | uint64_t id; | ||
63 | |||
64 | id = subvendor | ||
65 | | (subdevice << 16) | ||
66 | | ((uint64_t)vendor << 32) | ||
67 | | ((uint64_t)device << 48); | ||
68 | |||
69 | return (id); | ||
70 | } | ||
71 | |||
72 | #define AHC_PCI_IOADDR PCIR_MAPS /* I/O Address */ | ||
73 | #define AHC_PCI_MEMADDR (PCIR_MAPS + 4) /* Mem I/O Address */ | ||
74 | |||
75 | #define DEVID_9005_TYPE(id) ((id) & 0xF) | ||
76 | #define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */ | ||
77 | #define DEVID_9005_TYPE_AAA 0x3 /* RAID Card */ | ||
78 | #define DEVID_9005_TYPE_SISL 0x5 /* Container ROMB */ | ||
79 | #define DEVID_9005_TYPE_MB 0xF /* On Motherboard */ | ||
80 | |||
81 | #define DEVID_9005_MAXRATE(id) (((id) & 0x30) >> 4) | ||
82 | #define DEVID_9005_MAXRATE_U160 0x0 | ||
83 | #define DEVID_9005_MAXRATE_ULTRA2 0x1 | ||
84 | #define DEVID_9005_MAXRATE_ULTRA 0x2 | ||
85 | #define DEVID_9005_MAXRATE_FAST 0x3 | ||
86 | |||
87 | #define DEVID_9005_MFUNC(id) (((id) & 0x40) >> 6) | ||
88 | |||
89 | #define DEVID_9005_CLASS(id) (((id) & 0xFF00) >> 8) | ||
90 | #define DEVID_9005_CLASS_SPI 0x0 /* Parallel SCSI */ | ||
91 | |||
92 | #define SUBID_9005_TYPE(id) ((id) & 0xF) | ||
93 | #define SUBID_9005_TYPE_MB 0xF /* On Motherboard */ | ||
94 | #define SUBID_9005_TYPE_CARD 0x0 /* Standard Card */ | ||
95 | #define SUBID_9005_TYPE_LCCARD 0x1 /* Low Cost Card */ | ||
96 | #define SUBID_9005_TYPE_RAID 0x3 /* Combined with Raid */ | ||
97 | |||
98 | #define SUBID_9005_TYPE_KNOWN(id) \ | ||
99 | ((((id) & 0xF) == SUBID_9005_TYPE_MB) \ | ||
100 | || (((id) & 0xF) == SUBID_9005_TYPE_CARD) \ | ||
101 | || (((id) & 0xF) == SUBID_9005_TYPE_LCCARD) \ | ||
102 | || (((id) & 0xF) == SUBID_9005_TYPE_RAID)) | ||
103 | |||
104 | #define SUBID_9005_MAXRATE(id) (((id) & 0x30) >> 4) | ||
105 | #define SUBID_9005_MAXRATE_ULTRA2 0x0 | ||
106 | #define SUBID_9005_MAXRATE_ULTRA 0x1 | ||
107 | #define SUBID_9005_MAXRATE_U160 0x2 | ||
108 | #define SUBID_9005_MAXRATE_RESERVED 0x3 | ||
109 | |||
110 | #define SUBID_9005_SEEPTYPE(id) \ | ||
111 | ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \ | ||
112 | ? ((id) & 0xC0) >> 6 \ | ||
113 | : ((id) & 0x300) >> 8) | ||
114 | #define SUBID_9005_SEEPTYPE_NONE 0x0 | ||
115 | #define SUBID_9005_SEEPTYPE_1K 0x1 | ||
116 | #define SUBID_9005_SEEPTYPE_2K_4K 0x2 | ||
117 | #define SUBID_9005_SEEPTYPE_RESERVED 0x3 | ||
118 | #define SUBID_9005_AUTOTERM(id) \ | ||
119 | ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \ | ||
120 | ? (((id) & 0x400) >> 10) == 0 \ | ||
121 | : (((id) & 0x40) >> 6) == 0) | ||
122 | |||
123 | #define SUBID_9005_NUMCHAN(id) \ | ||
124 | ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \ | ||
125 | ? ((id) & 0x300) >> 8 \ | ||
126 | : ((id) & 0xC00) >> 10) | ||
127 | |||
128 | #define SUBID_9005_LEGACYCONN(id) \ | ||
129 | ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \ | ||
130 | ? 0 \ | ||
131 | : ((id) & 0x80) >> 7) | ||
132 | |||
133 | #define SUBID_9005_MFUNCENB(id) \ | ||
134 | ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \ | ||
135 | ? ((id) & 0x800) >> 11 \ | ||
136 | : ((id) & 0x1000) >> 12) | ||
137 | /* | ||
138 | * Informational only. Should use chip register to be | ||
139 | * certain, but may be use in identification strings. | ||
140 | */ | ||
141 | #define SUBID_9005_CARD_SCSIWIDTH_MASK 0x2000 | ||
142 | #define SUBID_9005_CARD_PCIWIDTH_MASK 0x4000 | ||
143 | #define SUBID_9005_CARD_SEDIFF_MASK 0x8000 | ||
144 | |||
145 | static ahc_device_setup_t ahc_aic785X_setup; | ||
146 | static ahc_device_setup_t ahc_aic7860_setup; | ||
147 | static ahc_device_setup_t ahc_apa1480_setup; | ||
148 | static ahc_device_setup_t ahc_aic7870_setup; | ||
149 | static ahc_device_setup_t ahc_aha394X_setup; | ||
150 | static ahc_device_setup_t ahc_aha494X_setup; | ||
151 | static ahc_device_setup_t ahc_aha398X_setup; | ||
152 | static ahc_device_setup_t ahc_aic7880_setup; | ||
153 | static ahc_device_setup_t ahc_aha2940Pro_setup; | ||
154 | static ahc_device_setup_t ahc_aha394XU_setup; | ||
155 | static ahc_device_setup_t ahc_aha398XU_setup; | ||
156 | static ahc_device_setup_t ahc_aic7890_setup; | ||
157 | static ahc_device_setup_t ahc_aic7892_setup; | ||
158 | static ahc_device_setup_t ahc_aic7895_setup; | ||
159 | static ahc_device_setup_t ahc_aic7896_setup; | ||
160 | static ahc_device_setup_t ahc_aic7899_setup; | ||
161 | static ahc_device_setup_t ahc_aha29160C_setup; | ||
162 | static ahc_device_setup_t ahc_raid_setup; | ||
163 | static ahc_device_setup_t ahc_aha394XX_setup; | ||
164 | static ahc_device_setup_t ahc_aha494XX_setup; | ||
165 | static ahc_device_setup_t ahc_aha398XX_setup; | ||
166 | |||
167 | struct ahc_pci_identity ahc_pci_ident_table [] = | ||
168 | { | ||
169 | /* aic7850 based controllers */ | ||
170 | { | ||
171 | ID_AHA_2902_04_10_15_20C_30C, | ||
172 | ID_ALL_MASK, | ||
173 | "Adaptec 2902/04/10/15/20C/30C SCSI adapter", | ||
174 | ahc_aic785X_setup | ||
175 | }, | ||
176 | /* aic7860 based controllers */ | ||
177 | { | ||
178 | ID_AHA_2930CU, | ||
179 | ID_ALL_MASK, | ||
180 | "Adaptec 2930CU SCSI adapter", | ||
181 | ahc_aic7860_setup | ||
182 | }, | ||
183 | { | ||
184 | ID_AHA_1480A & ID_DEV_VENDOR_MASK, | ||
185 | ID_DEV_VENDOR_MASK, | ||
186 | "Adaptec 1480A Ultra SCSI adapter", | ||
187 | ahc_apa1480_setup | ||
188 | }, | ||
189 | { | ||
190 | ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK, | ||
191 | ID_DEV_VENDOR_MASK, | ||
192 | "Adaptec 2940A Ultra SCSI adapter", | ||
193 | ahc_aic7860_setup | ||
194 | }, | ||
195 | { | ||
196 | ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK, | ||
197 | ID_DEV_VENDOR_MASK, | ||
198 | "Adaptec 2940A/CN Ultra SCSI adapter", | ||
199 | ahc_aic7860_setup | ||
200 | }, | ||
201 | { | ||
202 | ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK, | ||
203 | ID_DEV_VENDOR_MASK, | ||
204 | "Adaptec 2930C Ultra SCSI adapter (VAR)", | ||
205 | ahc_aic7860_setup | ||
206 | }, | ||
207 | /* aic7870 based controllers */ | ||
208 | { | ||
209 | ID_AHA_2940, | ||
210 | ID_ALL_MASK, | ||
211 | "Adaptec 2940 SCSI adapter", | ||
212 | ahc_aic7870_setup | ||
213 | }, | ||
214 | { | ||
215 | ID_AHA_3940, | ||
216 | ID_ALL_MASK, | ||
217 | "Adaptec 3940 SCSI adapter", | ||
218 | ahc_aha394X_setup | ||
219 | }, | ||
220 | { | ||
221 | ID_AHA_398X, | ||
222 | ID_ALL_MASK, | ||
223 | "Adaptec 398X SCSI RAID adapter", | ||
224 | ahc_aha398X_setup | ||
225 | }, | ||
226 | { | ||
227 | ID_AHA_2944, | ||
228 | ID_ALL_MASK, | ||
229 | "Adaptec 2944 SCSI adapter", | ||
230 | ahc_aic7870_setup | ||
231 | }, | ||
232 | { | ||
233 | ID_AHA_3944, | ||
234 | ID_ALL_MASK, | ||
235 | "Adaptec 3944 SCSI adapter", | ||
236 | ahc_aha394X_setup | ||
237 | }, | ||
238 | { | ||
239 | ID_AHA_4944, | ||
240 | ID_ALL_MASK, | ||
241 | "Adaptec 4944 SCSI adapter", | ||
242 | ahc_aha494X_setup | ||
243 | }, | ||
244 | /* aic7880 based controllers */ | ||
245 | { | ||
246 | ID_AHA_2940U & ID_DEV_VENDOR_MASK, | ||
247 | ID_DEV_VENDOR_MASK, | ||
248 | "Adaptec 2940 Ultra SCSI adapter", | ||
249 | ahc_aic7880_setup | ||
250 | }, | ||
251 | { | ||
252 | ID_AHA_3940U & ID_DEV_VENDOR_MASK, | ||
253 | ID_DEV_VENDOR_MASK, | ||
254 | "Adaptec 3940 Ultra SCSI adapter", | ||
255 | ahc_aha394XU_setup | ||
256 | }, | ||
257 | { | ||
258 | ID_AHA_2944U & ID_DEV_VENDOR_MASK, | ||
259 | ID_DEV_VENDOR_MASK, | ||
260 | "Adaptec 2944 Ultra SCSI adapter", | ||
261 | ahc_aic7880_setup | ||
262 | }, | ||
263 | { | ||
264 | ID_AHA_3944U & ID_DEV_VENDOR_MASK, | ||
265 | ID_DEV_VENDOR_MASK, | ||
266 | "Adaptec 3944 Ultra SCSI adapter", | ||
267 | ahc_aha394XU_setup | ||
268 | }, | ||
269 | { | ||
270 | ID_AHA_398XU & ID_DEV_VENDOR_MASK, | ||
271 | ID_DEV_VENDOR_MASK, | ||
272 | "Adaptec 398X Ultra SCSI RAID adapter", | ||
273 | ahc_aha398XU_setup | ||
274 | }, | ||
275 | { | ||
276 | /* | ||
277 | * XXX Don't know the slot numbers | ||
278 | * so we can't identify channels | ||
279 | */ | ||
280 | ID_AHA_4944U & ID_DEV_VENDOR_MASK, | ||
281 | ID_DEV_VENDOR_MASK, | ||
282 | "Adaptec 4944 Ultra SCSI adapter", | ||
283 | ahc_aic7880_setup | ||
284 | }, | ||
285 | { | ||
286 | ID_AHA_2930U & ID_DEV_VENDOR_MASK, | ||
287 | ID_DEV_VENDOR_MASK, | ||
288 | "Adaptec 2930 Ultra SCSI adapter", | ||
289 | ahc_aic7880_setup | ||
290 | }, | ||
291 | { | ||
292 | ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK, | ||
293 | ID_DEV_VENDOR_MASK, | ||
294 | "Adaptec 2940 Pro Ultra SCSI adapter", | ||
295 | ahc_aha2940Pro_setup | ||
296 | }, | ||
297 | { | ||
298 | ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK, | ||
299 | ID_DEV_VENDOR_MASK, | ||
300 | "Adaptec 2940/CN Ultra SCSI adapter", | ||
301 | ahc_aic7880_setup | ||
302 | }, | ||
303 | /* Ignore all SISL (AAC on MB) based controllers. */ | ||
304 | { | ||
305 | ID_9005_SISL_ID, | ||
306 | ID_9005_SISL_MASK, | ||
307 | NULL, | ||
308 | NULL | ||
309 | }, | ||
310 | /* aic7890 based controllers */ | ||
311 | { | ||
312 | ID_AHA_2930U2, | ||
313 | ID_ALL_MASK, | ||
314 | "Adaptec 2930 Ultra2 SCSI adapter", | ||
315 | ahc_aic7890_setup | ||
316 | }, | ||
317 | { | ||
318 | ID_AHA_2940U2B, | ||
319 | ID_ALL_MASK, | ||
320 | "Adaptec 2940B Ultra2 SCSI adapter", | ||
321 | ahc_aic7890_setup | ||
322 | }, | ||
323 | { | ||
324 | ID_AHA_2940U2_OEM, | ||
325 | ID_ALL_MASK, | ||
326 | "Adaptec 2940 Ultra2 SCSI adapter (OEM)", | ||
327 | ahc_aic7890_setup | ||
328 | }, | ||
329 | { | ||
330 | ID_AHA_2940U2, | ||
331 | ID_ALL_MASK, | ||
332 | "Adaptec 2940 Ultra2 SCSI adapter", | ||
333 | ahc_aic7890_setup | ||
334 | }, | ||
335 | { | ||
336 | ID_AHA_2950U2B, | ||
337 | ID_ALL_MASK, | ||
338 | "Adaptec 2950 Ultra2 SCSI adapter", | ||
339 | ahc_aic7890_setup | ||
340 | }, | ||
341 | { | ||
342 | ID_AIC7890_ARO, | ||
343 | ID_ALL_MASK, | ||
344 | "Adaptec aic7890/91 Ultra2 SCSI adapter (ARO)", | ||
345 | ahc_aic7890_setup | ||
346 | }, | ||
347 | { | ||
348 | ID_AAA_131U2, | ||
349 | ID_ALL_MASK, | ||
350 | "Adaptec AAA-131 Ultra2 RAID adapter", | ||
351 | ahc_aic7890_setup | ||
352 | }, | ||
353 | /* aic7892 based controllers */ | ||
354 | { | ||
355 | ID_AHA_29160, | ||
356 | ID_ALL_MASK, | ||
357 | "Adaptec 29160 Ultra160 SCSI adapter", | ||
358 | ahc_aic7892_setup | ||
359 | }, | ||
360 | { | ||
361 | ID_AHA_29160_CPQ, | ||
362 | ID_ALL_MASK, | ||
363 | "Adaptec (Compaq OEM) 29160 Ultra160 SCSI adapter", | ||
364 | ahc_aic7892_setup | ||
365 | }, | ||
366 | { | ||
367 | ID_AHA_29160N, | ||
368 | ID_ALL_MASK, | ||
369 | "Adaptec 29160N Ultra160 SCSI adapter", | ||
370 | ahc_aic7892_setup | ||
371 | }, | ||
372 | { | ||
373 | ID_AHA_29160C, | ||
374 | ID_ALL_MASK, | ||
375 | "Adaptec 29160C Ultra160 SCSI adapter", | ||
376 | ahc_aha29160C_setup | ||
377 | }, | ||
378 | { | ||
379 | ID_AHA_29160B, | ||
380 | ID_ALL_MASK, | ||
381 | "Adaptec 29160B Ultra160 SCSI adapter", | ||
382 | ahc_aic7892_setup | ||
383 | }, | ||
384 | { | ||
385 | ID_AHA_19160B, | ||
386 | ID_ALL_MASK, | ||
387 | "Adaptec 19160B Ultra160 SCSI adapter", | ||
388 | ahc_aic7892_setup | ||
389 | }, | ||
390 | { | ||
391 | ID_AIC7892_ARO, | ||
392 | ID_ALL_MASK, | ||
393 | "Adaptec aic7892 Ultra160 SCSI adapter (ARO)", | ||
394 | ahc_aic7892_setup | ||
395 | }, | ||
396 | /* aic7895 based controllers */ | ||
397 | { | ||
398 | ID_AHA_2940U_DUAL, | ||
399 | ID_ALL_MASK, | ||
400 | "Adaptec 2940/DUAL Ultra SCSI adapter", | ||
401 | ahc_aic7895_setup | ||
402 | }, | ||
403 | { | ||
404 | ID_AHA_3940AU, | ||
405 | ID_ALL_MASK, | ||
406 | "Adaptec 3940A Ultra SCSI adapter", | ||
407 | ahc_aic7895_setup | ||
408 | }, | ||
409 | { | ||
410 | ID_AHA_3944AU, | ||
411 | ID_ALL_MASK, | ||
412 | "Adaptec 3944A Ultra SCSI adapter", | ||
413 | ahc_aic7895_setup | ||
414 | }, | ||
415 | { | ||
416 | ID_AIC7895_ARO, | ||
417 | ID_AIC7895_ARO_MASK, | ||
418 | "Adaptec aic7895 Ultra SCSI adapter (ARO)", | ||
419 | ahc_aic7895_setup | ||
420 | }, | ||
421 | /* aic7896/97 based controllers */ | ||
422 | { | ||
423 | ID_AHA_3950U2B_0, | ||
424 | ID_ALL_MASK, | ||
425 | "Adaptec 3950B Ultra2 SCSI adapter", | ||
426 | ahc_aic7896_setup | ||
427 | }, | ||
428 | { | ||
429 | ID_AHA_3950U2B_1, | ||
430 | ID_ALL_MASK, | ||
431 | "Adaptec 3950B Ultra2 SCSI adapter", | ||
432 | ahc_aic7896_setup | ||
433 | }, | ||
434 | { | ||
435 | ID_AHA_3950U2D_0, | ||
436 | ID_ALL_MASK, | ||
437 | "Adaptec 3950D Ultra2 SCSI adapter", | ||
438 | ahc_aic7896_setup | ||
439 | }, | ||
440 | { | ||
441 | ID_AHA_3950U2D_1, | ||
442 | ID_ALL_MASK, | ||
443 | "Adaptec 3950D Ultra2 SCSI adapter", | ||
444 | ahc_aic7896_setup | ||
445 | }, | ||
446 | { | ||
447 | ID_AIC7896_ARO, | ||
448 | ID_ALL_MASK, | ||
449 | "Adaptec aic7896/97 Ultra2 SCSI adapter (ARO)", | ||
450 | ahc_aic7896_setup | ||
451 | }, | ||
452 | /* aic7899 based controllers */ | ||
453 | { | ||
454 | ID_AHA_3960D, | ||
455 | ID_ALL_MASK, | ||
456 | "Adaptec 3960D Ultra160 SCSI adapter", | ||
457 | ahc_aic7899_setup | ||
458 | }, | ||
459 | { | ||
460 | ID_AHA_3960D_CPQ, | ||
461 | ID_ALL_MASK, | ||
462 | "Adaptec (Compaq OEM) 3960D Ultra160 SCSI adapter", | ||
463 | ahc_aic7899_setup | ||
464 | }, | ||
465 | { | ||
466 | ID_AIC7899_ARO, | ||
467 | ID_ALL_MASK, | ||
468 | "Adaptec aic7899 Ultra160 SCSI adapter (ARO)", | ||
469 | ahc_aic7899_setup | ||
470 | }, | ||
471 | /* Generic chip probes for devices we don't know 'exactly' */ | ||
472 | { | ||
473 | ID_AIC7850 & ID_DEV_VENDOR_MASK, | ||
474 | ID_DEV_VENDOR_MASK, | ||
475 | "Adaptec aic7850 SCSI adapter", | ||
476 | ahc_aic785X_setup | ||
477 | }, | ||
478 | { | ||
479 | ID_AIC7855 & ID_DEV_VENDOR_MASK, | ||
480 | ID_DEV_VENDOR_MASK, | ||
481 | "Adaptec aic7855 SCSI adapter", | ||
482 | ahc_aic785X_setup | ||
483 | }, | ||
484 | { | ||
485 | ID_AIC7859 & ID_DEV_VENDOR_MASK, | ||
486 | ID_DEV_VENDOR_MASK, | ||
487 | "Adaptec aic7859 SCSI adapter", | ||
488 | ahc_aic7860_setup | ||
489 | }, | ||
490 | { | ||
491 | ID_AIC7860 & ID_DEV_VENDOR_MASK, | ||
492 | ID_DEV_VENDOR_MASK, | ||
493 | "Adaptec aic7860 Ultra SCSI adapter", | ||
494 | ahc_aic7860_setup | ||
495 | }, | ||
496 | { | ||
497 | ID_AIC7870 & ID_DEV_VENDOR_MASK, | ||
498 | ID_DEV_VENDOR_MASK, | ||
499 | "Adaptec aic7870 SCSI adapter", | ||
500 | ahc_aic7870_setup | ||
501 | }, | ||
502 | { | ||
503 | ID_AIC7880 & ID_DEV_VENDOR_MASK, | ||
504 | ID_DEV_VENDOR_MASK, | ||
505 | "Adaptec aic7880 Ultra SCSI adapter", | ||
506 | ahc_aic7880_setup | ||
507 | }, | ||
508 | { | ||
509 | ID_AIC7890 & ID_9005_GENERIC_MASK, | ||
510 | ID_9005_GENERIC_MASK, | ||
511 | "Adaptec aic7890/91 Ultra2 SCSI adapter", | ||
512 | ahc_aic7890_setup | ||
513 | }, | ||
514 | { | ||
515 | ID_AIC7892 & ID_9005_GENERIC_MASK, | ||
516 | ID_9005_GENERIC_MASK, | ||
517 | "Adaptec aic7892 Ultra160 SCSI adapter", | ||
518 | ahc_aic7892_setup | ||
519 | }, | ||
520 | { | ||
521 | ID_AIC7895 & ID_DEV_VENDOR_MASK, | ||
522 | ID_DEV_VENDOR_MASK, | ||
523 | "Adaptec aic7895 Ultra SCSI adapter", | ||
524 | ahc_aic7895_setup | ||
525 | }, | ||
526 | { | ||
527 | ID_AIC7896 & ID_9005_GENERIC_MASK, | ||
528 | ID_9005_GENERIC_MASK, | ||
529 | "Adaptec aic7896/97 Ultra2 SCSI adapter", | ||
530 | ahc_aic7896_setup | ||
531 | }, | ||
532 | { | ||
533 | ID_AIC7899 & ID_9005_GENERIC_MASK, | ||
534 | ID_9005_GENERIC_MASK, | ||
535 | "Adaptec aic7899 Ultra160 SCSI adapter", | ||
536 | ahc_aic7899_setup | ||
537 | }, | ||
538 | { | ||
539 | ID_AIC7810 & ID_DEV_VENDOR_MASK, | ||
540 | ID_DEV_VENDOR_MASK, | ||
541 | "Adaptec aic7810 RAID memory controller", | ||
542 | ahc_raid_setup | ||
543 | }, | ||
544 | { | ||
545 | ID_AIC7815 & ID_DEV_VENDOR_MASK, | ||
546 | ID_DEV_VENDOR_MASK, | ||
547 | "Adaptec aic7815 RAID memory controller", | ||
548 | ahc_raid_setup | ||
549 | } | ||
550 | }; | ||
551 | |||
552 | const u_int ahc_num_pci_devs = NUM_ELEMENTS(ahc_pci_ident_table); | ||
553 | |||
554 | #define AHC_394X_SLOT_CHANNEL_A 4 | ||
555 | #define AHC_394X_SLOT_CHANNEL_B 5 | ||
556 | |||
557 | #define AHC_398X_SLOT_CHANNEL_A 4 | ||
558 | #define AHC_398X_SLOT_CHANNEL_B 8 | ||
559 | #define AHC_398X_SLOT_CHANNEL_C 12 | ||
560 | |||
561 | #define AHC_494X_SLOT_CHANNEL_A 4 | ||
562 | #define AHC_494X_SLOT_CHANNEL_B 5 | ||
563 | #define AHC_494X_SLOT_CHANNEL_C 6 | ||
564 | #define AHC_494X_SLOT_CHANNEL_D 7 | ||
565 | |||
566 | #define DEVCONFIG 0x40 | ||
567 | #define PCIERRGENDIS 0x80000000ul | ||
568 | #define SCBSIZE32 0x00010000ul /* aic789X only */ | ||
569 | #define REXTVALID 0x00001000ul /* ultra cards only */ | ||
570 | #define MPORTMODE 0x00000400ul /* aic7870+ only */ | ||
571 | #define RAMPSM 0x00000200ul /* aic7870+ only */ | ||
572 | #define VOLSENSE 0x00000100ul | ||
573 | #define PCI64BIT 0x00000080ul /* 64Bit PCI bus (Ultra2 Only)*/ | ||
574 | #define SCBRAMSEL 0x00000080ul | ||
575 | #define MRDCEN 0x00000040ul | ||
576 | #define EXTSCBTIME 0x00000020ul /* aic7870 only */ | ||
577 | #define EXTSCBPEN 0x00000010ul /* aic7870 only */ | ||
578 | #define BERREN 0x00000008ul | ||
579 | #define DACEN 0x00000004ul | ||
580 | #define STPWLEVEL 0x00000002ul | ||
581 | #define DIFACTNEGEN 0x00000001ul /* aic7870 only */ | ||
582 | |||
583 | #define CSIZE_LATTIME 0x0c | ||
584 | #define CACHESIZE 0x0000003ful /* only 5 bits */ | ||
585 | #define LATTIME 0x0000ff00ul | ||
586 | |||
587 | /* PCI STATUS definitions */ | ||
588 | #define DPE 0x80 | ||
589 | #define SSE 0x40 | ||
590 | #define RMA 0x20 | ||
591 | #define RTA 0x10 | ||
592 | #define STA 0x08 | ||
593 | #define DPR 0x01 | ||
594 | |||
595 | static int ahc_9005_subdevinfo_valid(uint16_t vendor, uint16_t device, | ||
596 | uint16_t subvendor, uint16_t subdevice); | ||
597 | static int ahc_ext_scbram_present(struct ahc_softc *ahc); | ||
598 | static void ahc_scbram_config(struct ahc_softc *ahc, int enable, | ||
599 | int pcheck, int fast, int large); | ||
600 | static void ahc_probe_ext_scbram(struct ahc_softc *ahc); | ||
601 | static void check_extport(struct ahc_softc *ahc, u_int *sxfrctl1); | ||
602 | static void ahc_parse_pci_eeprom(struct ahc_softc *ahc, | ||
603 | struct seeprom_config *sc); | ||
604 | static void configure_termination(struct ahc_softc *ahc, | ||
605 | struct seeprom_descriptor *sd, | ||
606 | u_int adapter_control, | ||
607 | u_int *sxfrctl1); | ||
608 | |||
609 | static void ahc_new_term_detect(struct ahc_softc *ahc, | ||
610 | int *enableSEC_low, | ||
611 | int *enableSEC_high, | ||
612 | int *enablePRI_low, | ||
613 | int *enablePRI_high, | ||
614 | int *eeprom_present); | ||
615 | static void aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present, | ||
616 | int *internal68_present, | ||
617 | int *externalcable_present, | ||
618 | int *eeprom_present); | ||
619 | static void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present, | ||
620 | int *externalcable_present, | ||
621 | int *eeprom_present); | ||
622 | static void write_brdctl(struct ahc_softc *ahc, uint8_t value); | ||
623 | static uint8_t read_brdctl(struct ahc_softc *ahc); | ||
624 | static void ahc_pci_intr(struct ahc_softc *ahc); | ||
625 | static int ahc_pci_chip_init(struct ahc_softc *ahc); | ||
626 | static int ahc_pci_suspend(struct ahc_softc *ahc); | ||
627 | static int ahc_pci_resume(struct ahc_softc *ahc); | ||
628 | |||
629 | static int | ||
630 | ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor, | ||
631 | uint16_t subdevice, uint16_t subvendor) | ||
632 | { | ||
633 | int result; | ||
634 | |||
635 | /* Default to invalid. */ | ||
636 | result = 0; | ||
637 | if (vendor == 0x9005 | ||
638 | && subvendor == 0x9005 | ||
639 | && subdevice != device | ||
640 | && SUBID_9005_TYPE_KNOWN(subdevice) != 0) { | ||
641 | |||
642 | switch (SUBID_9005_TYPE(subdevice)) { | ||
643 | case SUBID_9005_TYPE_MB: | ||
644 | break; | ||
645 | case SUBID_9005_TYPE_CARD: | ||
646 | case SUBID_9005_TYPE_LCCARD: | ||
647 | /* | ||
648 | * Currently only trust Adaptec cards to | ||
649 | * get the sub device info correct. | ||
650 | */ | ||
651 | if (DEVID_9005_TYPE(device) == DEVID_9005_TYPE_HBA) | ||
652 | result = 1; | ||
653 | break; | ||
654 | case SUBID_9005_TYPE_RAID: | ||
655 | break; | ||
656 | default: | ||
657 | break; | ||
658 | } | ||
659 | } | ||
660 | return (result); | ||
661 | } | ||
662 | |||
663 | struct ahc_pci_identity * | ||
664 | ahc_find_pci_device(ahc_dev_softc_t pci) | ||
665 | { | ||
666 | uint64_t full_id; | ||
667 | uint16_t device; | ||
668 | uint16_t vendor; | ||
669 | uint16_t subdevice; | ||
670 | uint16_t subvendor; | ||
671 | struct ahc_pci_identity *entry; | ||
672 | u_int i; | ||
673 | |||
674 | vendor = ahc_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2); | ||
675 | device = ahc_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2); | ||
676 | subvendor = ahc_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2); | ||
677 | subdevice = ahc_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2); | ||
678 | full_id = ahc_compose_id(device, vendor, subdevice, subvendor); | ||
679 | |||
680 | /* | ||
681 | * If the second function is not hooked up, ignore it. | ||
682 | * Unfortunately, not all MB vendors implement the | ||
683 | * subdevice ID as per the Adaptec spec, so do our best | ||
684 | * to sanity check it prior to accepting the subdevice | ||
685 | * ID as valid. | ||
686 | */ | ||
687 | if (ahc_get_pci_function(pci) > 0 | ||
688 | && ahc_9005_subdevinfo_valid(vendor, device, subvendor, subdevice) | ||
689 | && SUBID_9005_MFUNCENB(subdevice) == 0) | ||
690 | return (NULL); | ||
691 | |||
692 | for (i = 0; i < ahc_num_pci_devs; i++) { | ||
693 | entry = &ahc_pci_ident_table[i]; | ||
694 | if (entry->full_id == (full_id & entry->id_mask)) { | ||
695 | /* Honor exclusion entries. */ | ||
696 | if (entry->name == NULL) | ||
697 | return (NULL); | ||
698 | return (entry); | ||
699 | } | ||
700 | } | ||
701 | return (NULL); | ||
702 | } | ||
703 | |||
704 | int | ||
705 | ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) | ||
706 | { | ||
707 | u_long l; | ||
708 | u_int command; | ||
709 | u_int our_id; | ||
710 | u_int sxfrctl1; | ||
711 | u_int scsiseq; | ||
712 | u_int dscommand0; | ||
713 | uint32_t devconfig; | ||
714 | int error; | ||
715 | uint8_t sblkctl; | ||
716 | |||
717 | our_id = 0; | ||
718 | error = entry->setup(ahc); | ||
719 | if (error != 0) | ||
720 | return (error); | ||
721 | ahc->chip |= AHC_PCI; | ||
722 | ahc->description = entry->name; | ||
723 | |||
724 | pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0); | ||
725 | |||
726 | error = ahc_pci_map_registers(ahc); | ||
727 | if (error != 0) | ||
728 | return (error); | ||
729 | |||
730 | /* | ||
731 | * Before we continue probing the card, ensure that | ||
732 | * its interrupts are *disabled*. We don't want | ||
733 | * a misstep to hang the machine in an interrupt | ||
734 | * storm. | ||
735 | */ | ||
736 | ahc_intr_enable(ahc, FALSE); | ||
737 | |||
738 | devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4); | ||
739 | |||
740 | /* | ||
741 | * If we need to support high memory, enable dual | ||
742 | * address cycles. This bit must be set to enable | ||
743 | * high address bit generation even if we are on a | ||
744 | * 64bit bus (PCI64BIT set in devconfig). | ||
745 | */ | ||
746 | if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { | ||
747 | |||
748 | if (bootverbose) | ||
749 | printf("%s: Enabling 39Bit Addressing\n", | ||
750 | ahc_name(ahc)); | ||
751 | devconfig |= DACEN; | ||
752 | } | ||
753 | |||
754 | /* Ensure that pci error generation, a test feature, is disabled. */ | ||
755 | devconfig |= PCIERRGENDIS; | ||
756 | |||
757 | ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4); | ||
758 | |||
759 | /* Ensure busmastering is enabled */ | ||
760 | command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2); | ||
761 | command |= PCIM_CMD_BUSMASTEREN; | ||
762 | |||
763 | ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/2); | ||
764 | |||
765 | /* On all PCI adapters, we allow SCB paging */ | ||
766 | ahc->flags |= AHC_PAGESCBS; | ||
767 | |||
768 | error = ahc_softc_init(ahc); | ||
769 | if (error != 0) | ||
770 | return (error); | ||
771 | |||
772 | /* | ||
773 | * Disable PCI parity error checking. Users typically | ||
774 | * do this to work around broken PCI chipsets that get | ||
775 | * the parity timing wrong and thus generate lots of spurious | ||
776 | * errors. The chip only allows us to disable *all* parity | ||
777 | * error reporting when doing this, so CIO bus, scb ram, and | ||
778 | * scratch ram parity errors will be ignored too. | ||
779 | */ | ||
780 | if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0) | ||
781 | ahc->seqctl |= FAILDIS; | ||
782 | |||
783 | ahc->bus_intr = ahc_pci_intr; | ||
784 | ahc->bus_chip_init = ahc_pci_chip_init; | ||
785 | ahc->bus_suspend = ahc_pci_suspend; | ||
786 | ahc->bus_resume = ahc_pci_resume; | ||
787 | |||
788 | /* Remeber how the card was setup in case there is no SEEPROM */ | ||
789 | if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) { | ||
790 | ahc_pause(ahc); | ||
791 | if ((ahc->features & AHC_ULTRA2) != 0) | ||
792 | our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID; | ||
793 | else | ||
794 | our_id = ahc_inb(ahc, SCSIID) & OID; | ||
795 | sxfrctl1 = ahc_inb(ahc, SXFRCTL1) & STPWEN; | ||
796 | scsiseq = ahc_inb(ahc, SCSISEQ); | ||
797 | } else { | ||
798 | sxfrctl1 = STPWEN; | ||
799 | our_id = 7; | ||
800 | scsiseq = 0; | ||
801 | } | ||
802 | |||
803 | error = ahc_reset(ahc, /*reinit*/FALSE); | ||
804 | if (error != 0) | ||
805 | return (ENXIO); | ||
806 | |||
807 | if ((ahc->features & AHC_DT) != 0) { | ||
808 | u_int sfunct; | ||
809 | |||
810 | /* Perform ALT-Mode Setup */ | ||
811 | sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE; | ||
812 | ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE); | ||
813 | ahc_outb(ahc, OPTIONMODE, | ||
814 | OPTIONMODE_DEFAULTS|AUTOACKEN|BUSFREEREV|EXPPHASEDIS); | ||
815 | ahc_outb(ahc, SFUNCT, sfunct); | ||
816 | |||
817 | /* Normal mode setup */ | ||
818 | ahc_outb(ahc, CRCCONTROL1, CRCVALCHKEN|CRCENDCHKEN|CRCREQCHKEN | ||
819 | |TARGCRCENDEN); | ||
820 | } | ||
821 | |||
822 | dscommand0 = ahc_inb(ahc, DSCOMMAND0); | ||
823 | dscommand0 |= MPARCKEN|CACHETHEN; | ||
824 | if ((ahc->features & AHC_ULTRA2) != 0) { | ||
825 | |||
826 | /* | ||
827 | * DPARCKEN doesn't work correctly on | ||
828 | * some MBs so don't use it. | ||
829 | */ | ||
830 | dscommand0 &= ~DPARCKEN; | ||
831 | } | ||
832 | |||
833 | /* | ||
834 | * Handle chips that must have cache line | ||
835 | * streaming (dis/en)abled. | ||
836 | */ | ||
837 | if ((ahc->bugs & AHC_CACHETHEN_DIS_BUG) != 0) | ||
838 | dscommand0 |= CACHETHEN; | ||
839 | |||
840 | if ((ahc->bugs & AHC_CACHETHEN_BUG) != 0) | ||
841 | dscommand0 &= ~CACHETHEN; | ||
842 | |||
843 | ahc_outb(ahc, DSCOMMAND0, dscommand0); | ||
844 | |||
845 | ahc->pci_cachesize = | ||
846 | ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, | ||
847 | /*bytes*/1) & CACHESIZE; | ||
848 | ahc->pci_cachesize *= 4; | ||
849 | |||
850 | if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0 | ||
851 | && ahc->pci_cachesize == 4) { | ||
852 | |||
853 | ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, | ||
854 | 0, /*bytes*/1); | ||
855 | ahc->pci_cachesize = 0; | ||
856 | } | ||
857 | |||
858 | /* | ||
859 | * We cannot perform ULTRA speeds without the presense | ||
860 | * of the external precision resistor. | ||
861 | */ | ||
862 | if ((ahc->features & AHC_ULTRA) != 0) { | ||
863 | uint32_t devconfig; | ||
864 | |||
865 | devconfig = ahc_pci_read_config(ahc->dev_softc, | ||
866 | DEVCONFIG, /*bytes*/4); | ||
867 | if ((devconfig & REXTVALID) == 0) | ||
868 | ahc->features &= ~AHC_ULTRA; | ||
869 | } | ||
870 | |||
871 | /* See if we have a SEEPROM and perform auto-term */ | ||
872 | check_extport(ahc, &sxfrctl1); | ||
873 | |||
874 | /* | ||
875 | * Take the LED out of diagnostic mode | ||
876 | */ | ||
877 | sblkctl = ahc_inb(ahc, SBLKCTL); | ||
878 | ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON))); | ||
879 | |||
880 | if ((ahc->features & AHC_ULTRA2) != 0) { | ||
881 | ahc_outb(ahc, DFF_THRSH, RD_DFTHRSH_MAX|WR_DFTHRSH_MAX); | ||
882 | } else { | ||
883 | ahc_outb(ahc, DSPCISTATUS, DFTHRSH_100); | ||
884 | } | ||
885 | |||
886 | if (ahc->flags & AHC_USEDEFAULTS) { | ||
887 | /* | ||
888 | * PCI Adapter default setup | ||
889 | * Should only be used if the adapter does not have | ||
890 | * a SEEPROM. | ||
891 | */ | ||
892 | /* See if someone else set us up already */ | ||
893 | if ((ahc->flags & AHC_NO_BIOS_INIT) == 0 | ||
894 | && scsiseq != 0) { | ||
895 | printf("%s: Using left over BIOS settings\n", | ||
896 | ahc_name(ahc)); | ||
897 | ahc->flags &= ~AHC_USEDEFAULTS; | ||
898 | ahc->flags |= AHC_BIOS_ENABLED; | ||
899 | } else { | ||
900 | /* | ||
901 | * Assume only one connector and always turn | ||
902 | * on termination. | ||
903 | */ | ||
904 | our_id = 0x07; | ||
905 | sxfrctl1 = STPWEN; | ||
906 | } | ||
907 | ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI); | ||
908 | |||
909 | ahc->our_id = our_id; | ||
910 | } | ||
911 | |||
912 | /* | ||
913 | * Take a look to see if we have external SRAM. | ||
914 | * We currently do not attempt to use SRAM that is | ||
915 | * shared among multiple controllers. | ||
916 | */ | ||
917 | ahc_probe_ext_scbram(ahc); | ||
918 | |||
919 | /* | ||
920 | * Record our termination setting for the | ||
921 | * generic initialization routine. | ||
922 | */ | ||
923 | if ((sxfrctl1 & STPWEN) != 0) | ||
924 | ahc->flags |= AHC_TERM_ENB_A; | ||
925 | |||
926 | /* | ||
927 | * Save chip register configuration data for chip resets | ||
928 | * that occur during runtime and resume events. | ||
929 | */ | ||
930 | ahc->bus_softc.pci_softc.devconfig = | ||
931 | ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4); | ||
932 | ahc->bus_softc.pci_softc.command = | ||
933 | ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1); | ||
934 | ahc->bus_softc.pci_softc.csize_lattime = | ||
935 | ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1); | ||
936 | ahc->bus_softc.pci_softc.dscommand0 = ahc_inb(ahc, DSCOMMAND0); | ||
937 | ahc->bus_softc.pci_softc.dspcistatus = ahc_inb(ahc, DSPCISTATUS); | ||
938 | if ((ahc->features & AHC_DT) != 0) { | ||
939 | u_int sfunct; | ||
940 | |||
941 | sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE; | ||
942 | ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE); | ||
943 | ahc->bus_softc.pci_softc.optionmode = ahc_inb(ahc, OPTIONMODE); | ||
944 | ahc->bus_softc.pci_softc.targcrccnt = ahc_inw(ahc, TARGCRCCNT); | ||
945 | ahc_outb(ahc, SFUNCT, sfunct); | ||
946 | ahc->bus_softc.pci_softc.crccontrol1 = | ||
947 | ahc_inb(ahc, CRCCONTROL1); | ||
948 | } | ||
949 | if ((ahc->features & AHC_MULTI_FUNC) != 0) | ||
950 | ahc->bus_softc.pci_softc.scbbaddr = ahc_inb(ahc, SCBBADDR); | ||
951 | |||
952 | if ((ahc->features & AHC_ULTRA2) != 0) | ||
953 | ahc->bus_softc.pci_softc.dff_thrsh = ahc_inb(ahc, DFF_THRSH); | ||
954 | |||
955 | /* Core initialization */ | ||
956 | error = ahc_init(ahc); | ||
957 | if (error != 0) | ||
958 | return (error); | ||
959 | |||
960 | /* | ||
961 | * Allow interrupts now that we are completely setup. | ||
962 | */ | ||
963 | error = ahc_pci_map_int(ahc); | ||
964 | if (error != 0) | ||
965 | return (error); | ||
966 | |||
967 | ahc_list_lock(&l); | ||
968 | /* | ||
969 | * Link this softc in with all other ahc instances. | ||
970 | */ | ||
971 | ahc_softc_insert(ahc); | ||
972 | ahc_list_unlock(&l); | ||
973 | return (0); | ||
974 | } | ||
975 | |||
976 | /* | ||
977 | * Test for the presense of external sram in an | ||
978 | * "unshared" configuration. | ||
979 | */ | ||
980 | static int | ||
981 | ahc_ext_scbram_present(struct ahc_softc *ahc) | ||
982 | { | ||
983 | u_int chip; | ||
984 | int ramps; | ||
985 | int single_user; | ||
986 | uint32_t devconfig; | ||
987 | |||
988 | chip = ahc->chip & AHC_CHIPID_MASK; | ||
989 | devconfig = ahc_pci_read_config(ahc->dev_softc, | ||
990 | DEVCONFIG, /*bytes*/4); | ||
991 | single_user = (devconfig & MPORTMODE) != 0; | ||
992 | |||
993 | if ((ahc->features & AHC_ULTRA2) != 0) | ||
994 | ramps = (ahc_inb(ahc, DSCOMMAND0) & RAMPS) != 0; | ||
995 | else if (chip == AHC_AIC7895 || chip == AHC_AIC7895C) | ||
996 | /* | ||
997 | * External SCBRAM arbitration is flakey | ||
998 | * on these chips. Unfortunately this means | ||
999 | * we don't use the extra SCB ram space on the | ||
1000 | * 3940AUW. | ||
1001 | */ | ||
1002 | ramps = 0; | ||
1003 | else if (chip >= AHC_AIC7870) | ||
1004 | ramps = (devconfig & RAMPSM) != 0; | ||
1005 | else | ||
1006 | ramps = 0; | ||
1007 | |||
1008 | if (ramps && single_user) | ||
1009 | return (1); | ||
1010 | return (0); | ||
1011 | } | ||
1012 | |||
1013 | /* | ||
1014 | * Enable external scbram. | ||
1015 | */ | ||
1016 | static void | ||
1017 | ahc_scbram_config(struct ahc_softc *ahc, int enable, int pcheck, | ||
1018 | int fast, int large) | ||
1019 | { | ||
1020 | uint32_t devconfig; | ||
1021 | |||
1022 | if (ahc->features & AHC_MULTI_FUNC) { | ||
1023 | /* | ||
1024 | * Set the SCB Base addr (highest address bit) | ||
1025 | * depending on which channel we are. | ||
1026 | */ | ||
1027 | ahc_outb(ahc, SCBBADDR, ahc_get_pci_function(ahc->dev_softc)); | ||
1028 | } | ||
1029 | |||
1030 | ahc->flags &= ~AHC_LSCBS_ENABLED; | ||
1031 | if (large) | ||
1032 | ahc->flags |= AHC_LSCBS_ENABLED; | ||
1033 | devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4); | ||
1034 | if ((ahc->features & AHC_ULTRA2) != 0) { | ||
1035 | u_int dscommand0; | ||
1036 | |||
1037 | dscommand0 = ahc_inb(ahc, DSCOMMAND0); | ||
1038 | if (enable) | ||
1039 | dscommand0 &= ~INTSCBRAMSEL; | ||
1040 | else | ||
1041 | dscommand0 |= INTSCBRAMSEL; | ||
1042 | if (large) | ||
1043 | dscommand0 &= ~USCBSIZE32; | ||
1044 | else | ||
1045 | dscommand0 |= USCBSIZE32; | ||
1046 | ahc_outb(ahc, DSCOMMAND0, dscommand0); | ||
1047 | } else { | ||
1048 | if (fast) | ||
1049 | devconfig &= ~EXTSCBTIME; | ||
1050 | else | ||
1051 | devconfig |= EXTSCBTIME; | ||
1052 | if (enable) | ||
1053 | devconfig &= ~SCBRAMSEL; | ||
1054 | else | ||
1055 | devconfig |= SCBRAMSEL; | ||
1056 | if (large) | ||
1057 | devconfig &= ~SCBSIZE32; | ||
1058 | else | ||
1059 | devconfig |= SCBSIZE32; | ||
1060 | } | ||
1061 | if (pcheck) | ||
1062 | devconfig |= EXTSCBPEN; | ||
1063 | else | ||
1064 | devconfig &= ~EXTSCBPEN; | ||
1065 | |||
1066 | ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4); | ||
1067 | } | ||
1068 | |||
1069 | /* | ||
1070 | * Take a look to see if we have external SRAM. | ||
1071 | * We currently do not attempt to use SRAM that is | ||
1072 | * shared among multiple controllers. | ||
1073 | */ | ||
1074 | static void | ||
1075 | ahc_probe_ext_scbram(struct ahc_softc *ahc) | ||
1076 | { | ||
1077 | int num_scbs; | ||
1078 | int test_num_scbs; | ||
1079 | int enable; | ||
1080 | int pcheck; | ||
1081 | int fast; | ||
1082 | int large; | ||
1083 | |||
1084 | enable = FALSE; | ||
1085 | pcheck = FALSE; | ||
1086 | fast = FALSE; | ||
1087 | large = FALSE; | ||
1088 | num_scbs = 0; | ||
1089 | |||
1090 | if (ahc_ext_scbram_present(ahc) == 0) | ||
1091 | goto done; | ||
1092 | |||
1093 | /* | ||
1094 | * Probe for the best parameters to use. | ||
1095 | */ | ||
1096 | ahc_scbram_config(ahc, /*enable*/TRUE, pcheck, fast, large); | ||
1097 | num_scbs = ahc_probe_scbs(ahc); | ||
1098 | if (num_scbs == 0) { | ||
1099 | /* The SRAM wasn't really present. */ | ||
1100 | goto done; | ||
1101 | } | ||
1102 | enable = TRUE; | ||
1103 | |||
1104 | /* | ||
1105 | * Clear any outstanding parity error | ||
1106 | * and ensure that parity error reporting | ||
1107 | * is enabled. | ||
1108 | */ | ||
1109 | ahc_outb(ahc, SEQCTL, 0); | ||
1110 | ahc_outb(ahc, CLRINT, CLRPARERR); | ||
1111 | ahc_outb(ahc, CLRINT, CLRBRKADRINT); | ||
1112 | |||
1113 | /* Now see if we can do parity */ | ||
1114 | ahc_scbram_config(ahc, enable, /*pcheck*/TRUE, fast, large); | ||
1115 | num_scbs = ahc_probe_scbs(ahc); | ||
1116 | if ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0 | ||
1117 | || (ahc_inb(ahc, ERROR) & MPARERR) == 0) | ||
1118 | pcheck = TRUE; | ||
1119 | |||
1120 | /* Clear any resulting parity error */ | ||
1121 | ahc_outb(ahc, CLRINT, CLRPARERR); | ||
1122 | ahc_outb(ahc, CLRINT, CLRBRKADRINT); | ||
1123 | |||
1124 | /* Now see if we can do fast timing */ | ||
1125 | ahc_scbram_config(ahc, enable, pcheck, /*fast*/TRUE, large); | ||
1126 | test_num_scbs = ahc_probe_scbs(ahc); | ||
1127 | if (test_num_scbs == num_scbs | ||
1128 | && ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0 | ||
1129 | || (ahc_inb(ahc, ERROR) & MPARERR) == 0)) | ||
1130 | fast = TRUE; | ||
1131 | |||
1132 | /* | ||
1133 | * See if we can use large SCBs and still maintain | ||
1134 | * the same overall count of SCBs. | ||
1135 | */ | ||
1136 | if ((ahc->features & AHC_LARGE_SCBS) != 0) { | ||
1137 | ahc_scbram_config(ahc, enable, pcheck, fast, /*large*/TRUE); | ||
1138 | test_num_scbs = ahc_probe_scbs(ahc); | ||
1139 | if (test_num_scbs >= num_scbs) { | ||
1140 | large = TRUE; | ||
1141 | num_scbs = test_num_scbs; | ||
1142 | if (num_scbs >= 64) { | ||
1143 | /* | ||
1144 | * We have enough space to move the | ||
1145 | * "busy targets table" into SCB space | ||
1146 | * and make it qualify all the way to the | ||
1147 | * lun level. | ||
1148 | */ | ||
1149 | ahc->flags |= AHC_SCB_BTT; | ||
1150 | } | ||
1151 | } | ||
1152 | } | ||
1153 | done: | ||
1154 | /* | ||
1155 | * Disable parity error reporting until we | ||
1156 | * can load instruction ram. | ||
1157 | */ | ||
1158 | ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS); | ||
1159 | /* Clear any latched parity error */ | ||
1160 | ahc_outb(ahc, CLRINT, CLRPARERR); | ||
1161 | ahc_outb(ahc, CLRINT, CLRBRKADRINT); | ||
1162 | if (bootverbose && enable) { | ||
1163 | printf("%s: External SRAM, %s access%s, %dbytes/SCB\n", | ||
1164 | ahc_name(ahc), fast ? "fast" : "slow", | ||
1165 | pcheck ? ", parity checking enabled" : "", | ||
1166 | large ? 64 : 32); | ||
1167 | } | ||
1168 | ahc_scbram_config(ahc, enable, pcheck, fast, large); | ||
1169 | } | ||
1170 | |||
1171 | /* | ||
1172 | * Perform some simple tests that should catch situations where | ||
1173 | * our registers are invalidly mapped. | ||
1174 | */ | ||
1175 | int | ||
1176 | ahc_pci_test_register_access(struct ahc_softc *ahc) | ||
1177 | { | ||
1178 | int error; | ||
1179 | u_int status1; | ||
1180 | uint32_t cmd; | ||
1181 | uint8_t hcntrl; | ||
1182 | |||
1183 | error = EIO; | ||
1184 | |||
1185 | /* | ||
1186 | * Enable PCI error interrupt status, but suppress NMIs | ||
1187 | * generated by SERR raised due to target aborts. | ||
1188 | */ | ||
1189 | cmd = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2); | ||
1190 | ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, | ||
1191 | cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2); | ||
1192 | |||
1193 | /* | ||
1194 | * First a simple test to see if any | ||
1195 | * registers can be read. Reading | ||
1196 | * HCNTRL has no side effects and has | ||
1197 | * at least one bit that is guaranteed to | ||
1198 | * be zero so it is a good register to | ||
1199 | * use for this test. | ||
1200 | */ | ||
1201 | hcntrl = ahc_inb(ahc, HCNTRL); | ||
1202 | if (hcntrl == 0xFF) | ||
1203 | goto fail; | ||
1204 | |||
1205 | /* | ||
1206 | * Next create a situation where write combining | ||
1207 | * or read prefetching could be initiated by the | ||
1208 | * CPU or host bridge. Our device does not support | ||
1209 | * either, so look for data corruption and/or flagged | ||
1210 | * PCI errors. First pause without causing another | ||
1211 | * chip reset. | ||
1212 | */ | ||
1213 | hcntrl &= ~CHIPRST; | ||
1214 | ahc_outb(ahc, HCNTRL, hcntrl|PAUSE); | ||
1215 | while (ahc_is_paused(ahc) == 0) | ||
1216 | ; | ||
1217 | |||
1218 | /* Clear any PCI errors that occurred before our driver attached. */ | ||
1219 | status1 = ahc_pci_read_config(ahc->dev_softc, | ||
1220 | PCIR_STATUS + 1, /*bytes*/1); | ||
1221 | ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, | ||
1222 | status1, /*bytes*/1); | ||
1223 | ahc_outb(ahc, CLRINT, CLRPARERR); | ||
1224 | |||
1225 | ahc_outb(ahc, SEQCTL, PERRORDIS); | ||
1226 | ahc_outb(ahc, SCBPTR, 0); | ||
1227 | ahc_outl(ahc, SCB_BASE, 0x5aa555aa); | ||
1228 | if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa) | ||
1229 | goto fail; | ||
1230 | |||
1231 | status1 = ahc_pci_read_config(ahc->dev_softc, | ||
1232 | PCIR_STATUS + 1, /*bytes*/1); | ||
1233 | if ((status1 & STA) != 0) | ||
1234 | goto fail; | ||
1235 | |||
1236 | error = 0; | ||
1237 | |||
1238 | fail: | ||
1239 | /* Silently clear any latched errors. */ | ||
1240 | status1 = ahc_pci_read_config(ahc->dev_softc, | ||
1241 | PCIR_STATUS + 1, /*bytes*/1); | ||
1242 | ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, | ||
1243 | status1, /*bytes*/1); | ||
1244 | ahc_outb(ahc, CLRINT, CLRPARERR); | ||
1245 | ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS); | ||
1246 | ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2); | ||
1247 | return (error); | ||
1248 | } | ||
1249 | |||
1250 | /* | ||
1251 | * Check the external port logic for a serial eeprom | ||
1252 | * and termination/cable detection contrls. | ||
1253 | */ | ||
1254 | static void | ||
1255 | check_extport(struct ahc_softc *ahc, u_int *sxfrctl1) | ||
1256 | { | ||
1257 | struct seeprom_descriptor sd; | ||
1258 | struct seeprom_config *sc; | ||
1259 | int have_seeprom; | ||
1260 | int have_autoterm; | ||
1261 | |||
1262 | sd.sd_ahc = ahc; | ||
1263 | sd.sd_control_offset = SEECTL; | ||
1264 | sd.sd_status_offset = SEECTL; | ||
1265 | sd.sd_dataout_offset = SEECTL; | ||
1266 | sc = ahc->seep_config; | ||
1267 | |||
1268 | /* | ||
1269 | * For some multi-channel devices, the c46 is simply too | ||
1270 | * small to work. For the other controller types, we can | ||
1271 | * get our information from either SEEPROM type. Set the | ||
1272 | * type to start our probe with accordingly. | ||
1273 | */ | ||
1274 | if (ahc->flags & AHC_LARGE_SEEPROM) | ||
1275 | sd.sd_chip = C56_66; | ||
1276 | else | ||
1277 | sd.sd_chip = C46; | ||
1278 | |||
1279 | sd.sd_MS = SEEMS; | ||
1280 | sd.sd_RDY = SEERDY; | ||
1281 | sd.sd_CS = SEECS; | ||
1282 | sd.sd_CK = SEECK; | ||
1283 | sd.sd_DO = SEEDO; | ||
1284 | sd.sd_DI = SEEDI; | ||
1285 | |||
1286 | have_seeprom = ahc_acquire_seeprom(ahc, &sd); | ||
1287 | if (have_seeprom) { | ||
1288 | |||
1289 | if (bootverbose) | ||
1290 | printf("%s: Reading SEEPROM...", ahc_name(ahc)); | ||
1291 | |||
1292 | for (;;) { | ||
1293 | u_int start_addr; | ||
1294 | |||
1295 | start_addr = 32 * (ahc->channel - 'A'); | ||
1296 | |||
1297 | have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc, | ||
1298 | start_addr, | ||
1299 | sizeof(*sc)/2); | ||
1300 | |||
1301 | if (have_seeprom) | ||
1302 | have_seeprom = ahc_verify_cksum(sc); | ||
1303 | |||
1304 | if (have_seeprom != 0 || sd.sd_chip == C56_66) { | ||
1305 | if (bootverbose) { | ||
1306 | if (have_seeprom == 0) | ||
1307 | printf ("checksum error\n"); | ||
1308 | else | ||
1309 | printf ("done.\n"); | ||
1310 | } | ||
1311 | break; | ||
1312 | } | ||
1313 | sd.sd_chip = C56_66; | ||
1314 | } | ||
1315 | ahc_release_seeprom(&sd); | ||
1316 | } | ||
1317 | |||
1318 | if (!have_seeprom) { | ||
1319 | /* | ||
1320 | * Pull scratch ram settings and treat them as | ||
1321 | * if they are the contents of an seeprom if | ||
1322 | * the 'ADPT' signature is found in SCB2. | ||
1323 | * We manually compose the data as 16bit values | ||
1324 | * to avoid endian issues. | ||
1325 | */ | ||
1326 | ahc_outb(ahc, SCBPTR, 2); | ||
1327 | if (ahc_inb(ahc, SCB_BASE) == 'A' | ||
1328 | && ahc_inb(ahc, SCB_BASE + 1) == 'D' | ||
1329 | && ahc_inb(ahc, SCB_BASE + 2) == 'P' | ||
1330 | && ahc_inb(ahc, SCB_BASE + 3) == 'T') { | ||
1331 | uint16_t *sc_data; | ||
1332 | int i; | ||
1333 | |||
1334 | sc_data = (uint16_t *)sc; | ||
1335 | for (i = 0; i < 32; i++, sc_data++) { | ||
1336 | int j; | ||
1337 | |||
1338 | j = i * 2; | ||
1339 | *sc_data = ahc_inb(ahc, SRAM_BASE + j) | ||
1340 | | ahc_inb(ahc, SRAM_BASE + j + 1) << 8; | ||
1341 | } | ||
1342 | have_seeprom = ahc_verify_cksum(sc); | ||
1343 | if (have_seeprom) | ||
1344 | ahc->flags |= AHC_SCB_CONFIG_USED; | ||
1345 | } | ||
1346 | /* | ||
1347 | * Clear any SCB parity errors in case this data and | ||
1348 | * its associated parity was not initialized by the BIOS | ||
1349 | */ | ||
1350 | ahc_outb(ahc, CLRINT, CLRPARERR); | ||
1351 | ahc_outb(ahc, CLRINT, CLRBRKADRINT); | ||
1352 | } | ||
1353 | |||
1354 | if (!have_seeprom) { | ||
1355 | if (bootverbose) | ||
1356 | printf("%s: No SEEPROM available.\n", ahc_name(ahc)); | ||
1357 | ahc->flags |= AHC_USEDEFAULTS; | ||
1358 | free(ahc->seep_config, M_DEVBUF); | ||
1359 | ahc->seep_config = NULL; | ||
1360 | sc = NULL; | ||
1361 | } else { | ||
1362 | ahc_parse_pci_eeprom(ahc, sc); | ||
1363 | } | ||
1364 | |||
1365 | /* | ||
1366 | * Cards that have the external logic necessary to talk to | ||
1367 | * a SEEPROM, are almost certain to have the remaining logic | ||
1368 | * necessary for auto-termination control. This assumption | ||
1369 | * hasn't failed yet... | ||
1370 | */ | ||
1371 | have_autoterm = have_seeprom; | ||
1372 | |||
1373 | /* | ||
1374 | * Some low-cost chips have SEEPROM and auto-term control built | ||
1375 | * in, instead of using a GAL. They can tell us directly | ||
1376 | * if the termination logic is enabled. | ||
1377 | */ | ||
1378 | if ((ahc->features & AHC_SPIOCAP) != 0) { | ||
1379 | if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) == 0) | ||
1380 | have_autoterm = FALSE; | ||
1381 | } | ||
1382 | |||
1383 | if (have_autoterm) { | ||
1384 | ahc->flags |= AHC_HAS_TERM_LOGIC; | ||
1385 | ahc_acquire_seeprom(ahc, &sd); | ||
1386 | configure_termination(ahc, &sd, sc->adapter_control, sxfrctl1); | ||
1387 | ahc_release_seeprom(&sd); | ||
1388 | } else if (have_seeprom) { | ||
1389 | *sxfrctl1 &= ~STPWEN; | ||
1390 | if ((sc->adapter_control & CFSTERM) != 0) | ||
1391 | *sxfrctl1 |= STPWEN; | ||
1392 | if (bootverbose) | ||
1393 | printf("%s: Low byte termination %sabled\n", | ||
1394 | ahc_name(ahc), | ||
1395 | (*sxfrctl1 & STPWEN) ? "en" : "dis"); | ||
1396 | } | ||
1397 | } | ||
1398 | |||
1399 | static void | ||
1400 | ahc_parse_pci_eeprom(struct ahc_softc *ahc, struct seeprom_config *sc) | ||
1401 | { | ||
1402 | /* | ||
1403 | * Put the data we've collected down into SRAM | ||
1404 | * where ahc_init will find it. | ||
1405 | */ | ||
1406 | int i; | ||
1407 | int max_targ = sc->max_targets & CFMAXTARG; | ||
1408 | u_int scsi_conf; | ||
1409 | uint16_t discenable; | ||
1410 | uint16_t ultraenb; | ||
1411 | |||
1412 | discenable = 0; | ||
1413 | ultraenb = 0; | ||
1414 | if ((sc->adapter_control & CFULTRAEN) != 0) { | ||
1415 | /* | ||
1416 | * Determine if this adapter has a "newstyle" | ||
1417 | * SEEPROM format. | ||
1418 | */ | ||
1419 | for (i = 0; i < max_targ; i++) { | ||
1420 | if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0) { | ||
1421 | ahc->flags |= AHC_NEWEEPROM_FMT; | ||
1422 | break; | ||
1423 | } | ||
1424 | } | ||
1425 | } | ||
1426 | |||
1427 | for (i = 0; i < max_targ; i++) { | ||
1428 | u_int scsirate; | ||
1429 | uint16_t target_mask; | ||
1430 | |||
1431 | target_mask = 0x01 << i; | ||
1432 | if (sc->device_flags[i] & CFDISC) | ||
1433 | discenable |= target_mask; | ||
1434 | if ((ahc->flags & AHC_NEWEEPROM_FMT) != 0) { | ||
1435 | if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0) | ||
1436 | ultraenb |= target_mask; | ||
1437 | } else if ((sc->adapter_control & CFULTRAEN) != 0) { | ||
1438 | ultraenb |= target_mask; | ||
1439 | } | ||
1440 | if ((sc->device_flags[i] & CFXFER) == 0x04 | ||
1441 | && (ultraenb & target_mask) != 0) { | ||
1442 | /* Treat 10MHz as a non-ultra speed */ | ||
1443 | sc->device_flags[i] &= ~CFXFER; | ||
1444 | ultraenb &= ~target_mask; | ||
1445 | } | ||
1446 | if ((ahc->features & AHC_ULTRA2) != 0) { | ||
1447 | u_int offset; | ||
1448 | |||
1449 | if (sc->device_flags[i] & CFSYNCH) | ||
1450 | offset = MAX_OFFSET_ULTRA2; | ||
1451 | else | ||
1452 | offset = 0; | ||
1453 | ahc_outb(ahc, TARG_OFFSET + i, offset); | ||
1454 | |||
1455 | /* | ||
1456 | * The ultra enable bits contain the | ||
1457 | * high bit of the ultra2 sync rate | ||
1458 | * field. | ||
1459 | */ | ||
1460 | scsirate = (sc->device_flags[i] & CFXFER) | ||
1461 | | ((ultraenb & target_mask) ? 0x8 : 0x0); | ||
1462 | if (sc->device_flags[i] & CFWIDEB) | ||
1463 | scsirate |= WIDEXFER; | ||
1464 | } else { | ||
1465 | scsirate = (sc->device_flags[i] & CFXFER) << 4; | ||
1466 | if (sc->device_flags[i] & CFSYNCH) | ||
1467 | scsirate |= SOFS; | ||
1468 | if (sc->device_flags[i] & CFWIDEB) | ||
1469 | scsirate |= WIDEXFER; | ||
1470 | } | ||
1471 | ahc_outb(ahc, TARG_SCSIRATE + i, scsirate); | ||
1472 | } | ||
1473 | ahc->our_id = sc->brtime_id & CFSCSIID; | ||
1474 | |||
1475 | scsi_conf = (ahc->our_id & 0x7); | ||
1476 | if (sc->adapter_control & CFSPARITY) | ||
1477 | scsi_conf |= ENSPCHK; | ||
1478 | if (sc->adapter_control & CFRESETB) | ||
1479 | scsi_conf |= RESET_SCSI; | ||
1480 | |||
1481 | ahc->flags |= (sc->adapter_control & CFBOOTCHAN) >> CFBOOTCHANSHIFT; | ||
1482 | |||
1483 | if (sc->bios_control & CFEXTEND) | ||
1484 | ahc->flags |= AHC_EXTENDED_TRANS_A; | ||
1485 | |||
1486 | if (sc->bios_control & CFBIOSEN) | ||
1487 | ahc->flags |= AHC_BIOS_ENABLED; | ||
1488 | if (ahc->features & AHC_ULTRA | ||
1489 | && (ahc->flags & AHC_NEWEEPROM_FMT) == 0) { | ||
1490 | /* Should we enable Ultra mode? */ | ||
1491 | if (!(sc->adapter_control & CFULTRAEN)) | ||
1492 | /* Treat us as a non-ultra card */ | ||
1493 | ultraenb = 0; | ||
1494 | } | ||
1495 | |||
1496 | if (sc->signature == CFSIGNATURE | ||
1497 | || sc->signature == CFSIGNATURE2) { | ||
1498 | uint32_t devconfig; | ||
1499 | |||
1500 | /* Honor the STPWLEVEL settings */ | ||
1501 | devconfig = ahc_pci_read_config(ahc->dev_softc, | ||
1502 | DEVCONFIG, /*bytes*/4); | ||
1503 | devconfig &= ~STPWLEVEL; | ||
1504 | if ((sc->bios_control & CFSTPWLEVEL) != 0) | ||
1505 | devconfig |= STPWLEVEL; | ||
1506 | ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, | ||
1507 | devconfig, /*bytes*/4); | ||
1508 | } | ||
1509 | /* Set SCSICONF info */ | ||
1510 | ahc_outb(ahc, SCSICONF, scsi_conf); | ||
1511 | ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff)); | ||
1512 | ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff)); | ||
1513 | ahc_outb(ahc, ULTRA_ENB, ultraenb & 0xff); | ||
1514 | ahc_outb(ahc, ULTRA_ENB + 1, (ultraenb >> 8) & 0xff); | ||
1515 | } | ||
1516 | |||
1517 | static void | ||
1518 | configure_termination(struct ahc_softc *ahc, | ||
1519 | struct seeprom_descriptor *sd, | ||
1520 | u_int adapter_control, | ||
1521 | u_int *sxfrctl1) | ||
1522 | { | ||
1523 | uint8_t brddat; | ||
1524 | |||
1525 | brddat = 0; | ||
1526 | |||
1527 | /* | ||
1528 | * Update the settings in sxfrctl1 to match the | ||
1529 | * termination settings | ||
1530 | */ | ||
1531 | *sxfrctl1 = 0; | ||
1532 | |||
1533 | /* | ||
1534 | * SEECS must be on for the GALS to latch | ||
1535 | * the data properly. Be sure to leave MS | ||
1536 | * on or we will release the seeprom. | ||
1537 | */ | ||
1538 | SEEPROM_OUTB(sd, sd->sd_MS | sd->sd_CS); | ||
1539 | if ((adapter_control & CFAUTOTERM) != 0 | ||
1540 | || (ahc->features & AHC_NEW_TERMCTL) != 0) { | ||
1541 | int internal50_present; | ||
1542 | int internal68_present; | ||
1543 | int externalcable_present; | ||
1544 | int eeprom_present; | ||
1545 | int enableSEC_low; | ||
1546 | int enableSEC_high; | ||
1547 | int enablePRI_low; | ||
1548 | int enablePRI_high; | ||
1549 | int sum; | ||
1550 | |||
1551 | enableSEC_low = 0; | ||
1552 | enableSEC_high = 0; | ||
1553 | enablePRI_low = 0; | ||
1554 | enablePRI_high = 0; | ||
1555 | if ((ahc->features & AHC_NEW_TERMCTL) != 0) { | ||
1556 | ahc_new_term_detect(ahc, &enableSEC_low, | ||
1557 | &enableSEC_high, | ||
1558 | &enablePRI_low, | ||
1559 | &enablePRI_high, | ||
1560 | &eeprom_present); | ||
1561 | if ((adapter_control & CFSEAUTOTERM) == 0) { | ||
1562 | if (bootverbose) | ||
1563 | printf("%s: Manual SE Termination\n", | ||
1564 | ahc_name(ahc)); | ||
1565 | enableSEC_low = (adapter_control & CFSELOWTERM); | ||
1566 | enableSEC_high = | ||
1567 | (adapter_control & CFSEHIGHTERM); | ||
1568 | } | ||
1569 | if ((adapter_control & CFAUTOTERM) == 0) { | ||
1570 | if (bootverbose) | ||
1571 | printf("%s: Manual LVD Termination\n", | ||
1572 | ahc_name(ahc)); | ||
1573 | enablePRI_low = (adapter_control & CFSTERM); | ||
1574 | enablePRI_high = (adapter_control & CFWSTERM); | ||
1575 | } | ||
1576 | /* Make the table calculations below happy */ | ||
1577 | internal50_present = 0; | ||
1578 | internal68_present = 1; | ||
1579 | externalcable_present = 1; | ||
1580 | } else if ((ahc->features & AHC_SPIOCAP) != 0) { | ||
1581 | aic785X_cable_detect(ahc, &internal50_present, | ||
1582 | &externalcable_present, | ||
1583 | &eeprom_present); | ||
1584 | /* Can never support a wide connector. */ | ||
1585 | internal68_present = 0; | ||
1586 | } else { | ||
1587 | aic787X_cable_detect(ahc, &internal50_present, | ||
1588 | &internal68_present, | ||
1589 | &externalcable_present, | ||
1590 | &eeprom_present); | ||
1591 | } | ||
1592 | |||
1593 | if ((ahc->features & AHC_WIDE) == 0) | ||
1594 | internal68_present = 0; | ||
1595 | |||
1596 | if (bootverbose | ||
1597 | && (ahc->features & AHC_ULTRA2) == 0) { | ||
1598 | printf("%s: internal 50 cable %s present", | ||
1599 | ahc_name(ahc), | ||
1600 | internal50_present ? "is":"not"); | ||
1601 | |||
1602 | if ((ahc->features & AHC_WIDE) != 0) | ||
1603 | printf(", internal 68 cable %s present", | ||
1604 | internal68_present ? "is":"not"); | ||
1605 | printf("\n%s: external cable %s present\n", | ||
1606 | ahc_name(ahc), | ||
1607 | externalcable_present ? "is":"not"); | ||
1608 | } | ||
1609 | if (bootverbose) | ||
1610 | printf("%s: BIOS eeprom %s present\n", | ||
1611 | ahc_name(ahc), eeprom_present ? "is" : "not"); | ||
1612 | |||
1613 | if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) { | ||
1614 | /* | ||
1615 | * The 50 pin connector is a separate bus, | ||
1616 | * so force it to always be terminated. | ||
1617 | * In the future, perform current sensing | ||
1618 | * to determine if we are in the middle of | ||
1619 | * a properly terminated bus. | ||
1620 | */ | ||
1621 | internal50_present = 0; | ||
1622 | } | ||
1623 | |||
1624 | /* | ||
1625 | * Now set the termination based on what | ||
1626 | * we found. | ||
1627 | * Flash Enable = BRDDAT7 | ||
1628 | * Secondary High Term Enable = BRDDAT6 | ||
1629 | * Secondary Low Term Enable = BRDDAT5 (7890) | ||
1630 | * Primary High Term Enable = BRDDAT4 (7890) | ||
1631 | */ | ||
1632 | if ((ahc->features & AHC_ULTRA2) == 0 | ||
1633 | && (internal50_present != 0) | ||
1634 | && (internal68_present != 0) | ||
1635 | && (externalcable_present != 0)) { | ||
1636 | printf("%s: Illegal cable configuration!!. " | ||
1637 | "Only two connectors on the " | ||
1638 | "adapter may be used at a " | ||
1639 | "time!\n", ahc_name(ahc)); | ||
1640 | |||
1641 | /* | ||
1642 | * Pretend there are no cables in the hope | ||
1643 | * that having all of the termination on | ||
1644 | * gives us a more stable bus. | ||
1645 | */ | ||
1646 | internal50_present = 0; | ||
1647 | internal68_present = 0; | ||
1648 | externalcable_present = 0; | ||
1649 | } | ||
1650 | |||
1651 | if ((ahc->features & AHC_WIDE) != 0 | ||
1652 | && ((externalcable_present == 0) | ||
1653 | || (internal68_present == 0) | ||
1654 | || (enableSEC_high != 0))) { | ||
1655 | brddat |= BRDDAT6; | ||
1656 | if (bootverbose) { | ||
1657 | if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) | ||
1658 | printf("%s: 68 pin termination " | ||
1659 | "Enabled\n", ahc_name(ahc)); | ||
1660 | else | ||
1661 | printf("%s: %sHigh byte termination " | ||
1662 | "Enabled\n", ahc_name(ahc), | ||
1663 | enableSEC_high ? "Secondary " | ||
1664 | : ""); | ||
1665 | } | ||
1666 | } | ||
1667 | |||
1668 | sum = internal50_present + internal68_present | ||
1669 | + externalcable_present; | ||
1670 | if (sum < 2 || (enableSEC_low != 0)) { | ||
1671 | if ((ahc->features & AHC_ULTRA2) != 0) | ||
1672 | brddat |= BRDDAT5; | ||
1673 | else | ||
1674 | *sxfrctl1 |= STPWEN; | ||
1675 | if (bootverbose) { | ||
1676 | if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) | ||
1677 | printf("%s: 50 pin termination " | ||
1678 | "Enabled\n", ahc_name(ahc)); | ||
1679 | else | ||
1680 | printf("%s: %sLow byte termination " | ||
1681 | "Enabled\n", ahc_name(ahc), | ||
1682 | enableSEC_low ? "Secondary " | ||
1683 | : ""); | ||
1684 | } | ||
1685 | } | ||
1686 | |||
1687 | if (enablePRI_low != 0) { | ||
1688 | *sxfrctl1 |= STPWEN; | ||
1689 | if (bootverbose) | ||
1690 | printf("%s: Primary Low Byte termination " | ||
1691 | "Enabled\n", ahc_name(ahc)); | ||
1692 | } | ||
1693 | |||
1694 | /* | ||
1695 | * Setup STPWEN before setting up the rest of | ||
1696 | * the termination per the tech note on the U160 cards. | ||
1697 | */ | ||
1698 | ahc_outb(ahc, SXFRCTL1, *sxfrctl1); | ||
1699 | |||
1700 | if (enablePRI_high != 0) { | ||
1701 | brddat |= BRDDAT4; | ||
1702 | if (bootverbose) | ||
1703 | printf("%s: Primary High Byte " | ||
1704 | "termination Enabled\n", | ||
1705 | ahc_name(ahc)); | ||
1706 | } | ||
1707 | |||
1708 | write_brdctl(ahc, brddat); | ||
1709 | |||
1710 | } else { | ||
1711 | if ((adapter_control & CFSTERM) != 0) { | ||
1712 | *sxfrctl1 |= STPWEN; | ||
1713 | |||
1714 | if (bootverbose) | ||
1715 | printf("%s: %sLow byte termination Enabled\n", | ||
1716 | ahc_name(ahc), | ||
1717 | (ahc->features & AHC_ULTRA2) ? "Primary " | ||
1718 | : ""); | ||
1719 | } | ||
1720 | |||
1721 | if ((adapter_control & CFWSTERM) != 0 | ||
1722 | && (ahc->features & AHC_WIDE) != 0) { | ||
1723 | brddat |= BRDDAT6; | ||
1724 | if (bootverbose) | ||
1725 | printf("%s: %sHigh byte termination Enabled\n", | ||
1726 | ahc_name(ahc), | ||
1727 | (ahc->features & AHC_ULTRA2) | ||
1728 | ? "Secondary " : ""); | ||
1729 | } | ||
1730 | |||
1731 | /* | ||
1732 | * Setup STPWEN before setting up the rest of | ||
1733 | * the termination per the tech note on the U160 cards. | ||
1734 | */ | ||
1735 | ahc_outb(ahc, SXFRCTL1, *sxfrctl1); | ||
1736 | |||
1737 | if ((ahc->features & AHC_WIDE) != 0) | ||
1738 | write_brdctl(ahc, brddat); | ||
1739 | } | ||
1740 | SEEPROM_OUTB(sd, sd->sd_MS); /* Clear CS */ | ||
1741 | } | ||
1742 | |||
1743 | static void | ||
1744 | ahc_new_term_detect(struct ahc_softc *ahc, int *enableSEC_low, | ||
1745 | int *enableSEC_high, int *enablePRI_low, | ||
1746 | int *enablePRI_high, int *eeprom_present) | ||
1747 | { | ||
1748 | uint8_t brdctl; | ||
1749 | |||
1750 | /* | ||
1751 | * BRDDAT7 = Eeprom | ||
1752 | * BRDDAT6 = Enable Secondary High Byte termination | ||
1753 | * BRDDAT5 = Enable Secondary Low Byte termination | ||
1754 | * BRDDAT4 = Enable Primary high byte termination | ||
1755 | * BRDDAT3 = Enable Primary low byte termination | ||
1756 | */ | ||
1757 | brdctl = read_brdctl(ahc); | ||
1758 | *eeprom_present = brdctl & BRDDAT7; | ||
1759 | *enableSEC_high = (brdctl & BRDDAT6); | ||
1760 | *enableSEC_low = (brdctl & BRDDAT5); | ||
1761 | *enablePRI_high = (brdctl & BRDDAT4); | ||
1762 | *enablePRI_low = (brdctl & BRDDAT3); | ||
1763 | } | ||
1764 | |||
1765 | static void | ||
1766 | aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present, | ||
1767 | int *internal68_present, int *externalcable_present, | ||
1768 | int *eeprom_present) | ||
1769 | { | ||
1770 | uint8_t brdctl; | ||
1771 | |||
1772 | /* | ||
1773 | * First read the status of our cables. | ||
1774 | * Set the rom bank to 0 since the | ||
1775 | * bank setting serves as a multiplexor | ||
1776 | * for the cable detection logic. | ||
1777 | * BRDDAT5 controls the bank switch. | ||
1778 | */ | ||
1779 | write_brdctl(ahc, 0); | ||
1780 | |||
1781 | /* | ||
1782 | * Now read the state of the internal | ||
1783 | * connectors. BRDDAT6 is INT50 and | ||
1784 | * BRDDAT7 is INT68. | ||
1785 | */ | ||
1786 | brdctl = read_brdctl(ahc); | ||
1787 | *internal50_present = (brdctl & BRDDAT6) ? 0 : 1; | ||
1788 | *internal68_present = (brdctl & BRDDAT7) ? 0 : 1; | ||
1789 | |||
1790 | /* | ||
1791 | * Set the rom bank to 1 and determine | ||
1792 | * the other signals. | ||
1793 | */ | ||
1794 | write_brdctl(ahc, BRDDAT5); | ||
1795 | |||
1796 | /* | ||
1797 | * Now read the state of the external | ||
1798 | * connectors. BRDDAT6 is EXT68 and | ||
1799 | * BRDDAT7 is EPROMPS. | ||
1800 | */ | ||
1801 | brdctl = read_brdctl(ahc); | ||
1802 | *externalcable_present = (brdctl & BRDDAT6) ? 0 : 1; | ||
1803 | *eeprom_present = (brdctl & BRDDAT7) ? 1 : 0; | ||
1804 | } | ||
1805 | |||
1806 | static void | ||
1807 | aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present, | ||
1808 | int *externalcable_present, int *eeprom_present) | ||
1809 | { | ||
1810 | uint8_t brdctl; | ||
1811 | uint8_t spiocap; | ||
1812 | |||
1813 | spiocap = ahc_inb(ahc, SPIOCAP); | ||
1814 | spiocap &= ~SOFTCMDEN; | ||
1815 | spiocap |= EXT_BRDCTL; | ||
1816 | ahc_outb(ahc, SPIOCAP, spiocap); | ||
1817 | ahc_outb(ahc, BRDCTL, BRDRW|BRDCS); | ||
1818 | ahc_flush_device_writes(ahc); | ||
1819 | ahc_delay(500); | ||
1820 | ahc_outb(ahc, BRDCTL, 0); | ||
1821 | ahc_flush_device_writes(ahc); | ||
1822 | ahc_delay(500); | ||
1823 | brdctl = ahc_inb(ahc, BRDCTL); | ||
1824 | *internal50_present = (brdctl & BRDDAT5) ? 0 : 1; | ||
1825 | *externalcable_present = (brdctl & BRDDAT6) ? 0 : 1; | ||
1826 | *eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0; | ||
1827 | } | ||
1828 | |||
1829 | int | ||
1830 | ahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd) | ||
1831 | { | ||
1832 | int wait; | ||
1833 | |||
1834 | if ((ahc->features & AHC_SPIOCAP) != 0 | ||
1835 | && (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0) | ||
1836 | return (0); | ||
1837 | |||
1838 | /* | ||
1839 | * Request access of the memory port. When access is | ||
1840 | * granted, SEERDY will go high. We use a 1 second | ||
1841 | * timeout which should be near 1 second more than | ||
1842 | * is needed. Reason: after the chip reset, there | ||
1843 | * should be no contention. | ||
1844 | */ | ||
1845 | SEEPROM_OUTB(sd, sd->sd_MS); | ||
1846 | wait = 1000; /* 1 second timeout in msec */ | ||
1847 | while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) { | ||
1848 | ahc_delay(1000); /* delay 1 msec */ | ||
1849 | } | ||
1850 | if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) { | ||
1851 | SEEPROM_OUTB(sd, 0); | ||
1852 | return (0); | ||
1853 | } | ||
1854 | return(1); | ||
1855 | } | ||
1856 | |||
1857 | void | ||
1858 | ahc_release_seeprom(struct seeprom_descriptor *sd) | ||
1859 | { | ||
1860 | /* Release access to the memory port and the serial EEPROM. */ | ||
1861 | SEEPROM_OUTB(sd, 0); | ||
1862 | } | ||
1863 | |||
1864 | static void | ||
1865 | write_brdctl(struct ahc_softc *ahc, uint8_t value) | ||
1866 | { | ||
1867 | uint8_t brdctl; | ||
1868 | |||
1869 | if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { | ||
1870 | brdctl = BRDSTB; | ||
1871 | if (ahc->channel == 'B') | ||
1872 | brdctl |= BRDCS; | ||
1873 | } else if ((ahc->features & AHC_ULTRA2) != 0) { | ||
1874 | brdctl = 0; | ||
1875 | } else { | ||
1876 | brdctl = BRDSTB|BRDCS; | ||
1877 | } | ||
1878 | ahc_outb(ahc, BRDCTL, brdctl); | ||
1879 | ahc_flush_device_writes(ahc); | ||
1880 | brdctl |= value; | ||
1881 | ahc_outb(ahc, BRDCTL, brdctl); | ||
1882 | ahc_flush_device_writes(ahc); | ||
1883 | if ((ahc->features & AHC_ULTRA2) != 0) | ||
1884 | brdctl |= BRDSTB_ULTRA2; | ||
1885 | else | ||
1886 | brdctl &= ~BRDSTB; | ||
1887 | ahc_outb(ahc, BRDCTL, brdctl); | ||
1888 | ahc_flush_device_writes(ahc); | ||
1889 | if ((ahc->features & AHC_ULTRA2) != 0) | ||
1890 | brdctl = 0; | ||
1891 | else | ||
1892 | brdctl &= ~BRDCS; | ||
1893 | ahc_outb(ahc, BRDCTL, brdctl); | ||
1894 | } | ||
1895 | |||
1896 | static uint8_t | ||
1897 | read_brdctl(struct ahc_softc *ahc) | ||
1898 | { | ||
1899 | uint8_t brdctl; | ||
1900 | uint8_t value; | ||
1901 | |||
1902 | if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { | ||
1903 | brdctl = BRDRW; | ||
1904 | if (ahc->channel == 'B') | ||
1905 | brdctl |= BRDCS; | ||
1906 | } else if ((ahc->features & AHC_ULTRA2) != 0) { | ||
1907 | brdctl = BRDRW_ULTRA2; | ||
1908 | } else { | ||
1909 | brdctl = BRDRW|BRDCS; | ||
1910 | } | ||
1911 | ahc_outb(ahc, BRDCTL, brdctl); | ||
1912 | ahc_flush_device_writes(ahc); | ||
1913 | value = ahc_inb(ahc, BRDCTL); | ||
1914 | ahc_outb(ahc, BRDCTL, 0); | ||
1915 | return (value); | ||
1916 | } | ||
1917 | |||
1918 | static void | ||
1919 | ahc_pci_intr(struct ahc_softc *ahc) | ||
1920 | { | ||
1921 | u_int error; | ||
1922 | u_int status1; | ||
1923 | |||
1924 | error = ahc_inb(ahc, ERROR); | ||
1925 | if ((error & PCIERRSTAT) == 0) | ||
1926 | return; | ||
1927 | |||
1928 | status1 = ahc_pci_read_config(ahc->dev_softc, | ||
1929 | PCIR_STATUS + 1, /*bytes*/1); | ||
1930 | |||
1931 | printf("%s: PCI error Interrupt at seqaddr = 0x%x\n", | ||
1932 | ahc_name(ahc), | ||
1933 | ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); | ||
1934 | |||
1935 | if (status1 & DPE) { | ||
1936 | ahc->pci_target_perr_count++; | ||
1937 | printf("%s: Data Parity Error Detected during address " | ||
1938 | "or write data phase\n", ahc_name(ahc)); | ||
1939 | } | ||
1940 | if (status1 & SSE) { | ||
1941 | printf("%s: Signal System Error Detected\n", ahc_name(ahc)); | ||
1942 | } | ||
1943 | if (status1 & RMA) { | ||
1944 | printf("%s: Received a Master Abort\n", ahc_name(ahc)); | ||
1945 | } | ||
1946 | if (status1 & RTA) { | ||
1947 | printf("%s: Received a Target Abort\n", ahc_name(ahc)); | ||
1948 | } | ||
1949 | if (status1 & STA) { | ||
1950 | printf("%s: Signaled a Target Abort\n", ahc_name(ahc)); | ||
1951 | } | ||
1952 | if (status1 & DPR) { | ||
1953 | printf("%s: Data Parity Error has been reported via PERR#\n", | ||
1954 | ahc_name(ahc)); | ||
1955 | } | ||
1956 | |||
1957 | /* Clear latched errors. */ | ||
1958 | ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, | ||
1959 | status1, /*bytes*/1); | ||
1960 | |||
1961 | if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) { | ||
1962 | printf("%s: Latched PCIERR interrupt with " | ||
1963 | "no status bits set\n", ahc_name(ahc)); | ||
1964 | } else { | ||
1965 | ahc_outb(ahc, CLRINT, CLRPARERR); | ||
1966 | } | ||
1967 | |||
1968 | if (ahc->pci_target_perr_count > AHC_PCI_TARGET_PERR_THRESH) { | ||
1969 | printf( | ||
1970 | "%s: WARNING WARNING WARNING WARNING\n" | ||
1971 | "%s: Too many PCI parity errors observed as a target.\n" | ||
1972 | "%s: Some device on this bus is generating bad parity.\n" | ||
1973 | "%s: This is an error *observed by*, not *generated by*, this controller.\n" | ||
1974 | "%s: PCI parity error checking has been disabled.\n" | ||
1975 | "%s: WARNING WARNING WARNING WARNING\n", | ||
1976 | ahc_name(ahc), ahc_name(ahc), ahc_name(ahc), | ||
1977 | ahc_name(ahc), ahc_name(ahc), ahc_name(ahc)); | ||
1978 | ahc->seqctl |= FAILDIS; | ||
1979 | ahc_outb(ahc, SEQCTL, ahc->seqctl); | ||
1980 | } | ||
1981 | ahc_unpause(ahc); | ||
1982 | } | ||
1983 | |||
1984 | static int | ||
1985 | ahc_pci_chip_init(struct ahc_softc *ahc) | ||
1986 | { | ||
1987 | ahc_outb(ahc, DSCOMMAND0, ahc->bus_softc.pci_softc.dscommand0); | ||
1988 | ahc_outb(ahc, DSPCISTATUS, ahc->bus_softc.pci_softc.dspcistatus); | ||
1989 | if ((ahc->features & AHC_DT) != 0) { | ||
1990 | u_int sfunct; | ||
1991 | |||
1992 | sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE; | ||
1993 | ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE); | ||
1994 | ahc_outb(ahc, OPTIONMODE, ahc->bus_softc.pci_softc.optionmode); | ||
1995 | ahc_outw(ahc, TARGCRCCNT, ahc->bus_softc.pci_softc.targcrccnt); | ||
1996 | ahc_outb(ahc, SFUNCT, sfunct); | ||
1997 | ahc_outb(ahc, CRCCONTROL1, | ||
1998 | ahc->bus_softc.pci_softc.crccontrol1); | ||
1999 | } | ||
2000 | if ((ahc->features & AHC_MULTI_FUNC) != 0) | ||
2001 | ahc_outb(ahc, SCBBADDR, ahc->bus_softc.pci_softc.scbbaddr); | ||
2002 | |||
2003 | if ((ahc->features & AHC_ULTRA2) != 0) | ||
2004 | ahc_outb(ahc, DFF_THRSH, ahc->bus_softc.pci_softc.dff_thrsh); | ||
2005 | |||
2006 | return (ahc_chip_init(ahc)); | ||
2007 | } | ||
2008 | |||
2009 | static int | ||
2010 | ahc_pci_suspend(struct ahc_softc *ahc) | ||
2011 | { | ||
2012 | return (ahc_suspend(ahc)); | ||
2013 | } | ||
2014 | |||
2015 | static int | ||
2016 | ahc_pci_resume(struct ahc_softc *ahc) | ||
2017 | { | ||
2018 | |||
2019 | pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0); | ||
2020 | |||
2021 | /* | ||
2022 | * We assume that the OS has restored our register | ||
2023 | * mappings, etc. Just update the config space registers | ||
2024 | * that the OS doesn't know about and rely on our chip | ||
2025 | * reset handler to handle the rest. | ||
2026 | */ | ||
2027 | ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4, | ||
2028 | ahc->bus_softc.pci_softc.devconfig); | ||
2029 | ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1, | ||
2030 | ahc->bus_softc.pci_softc.command); | ||
2031 | ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1, | ||
2032 | ahc->bus_softc.pci_softc.csize_lattime); | ||
2033 | if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) { | ||
2034 | struct seeprom_descriptor sd; | ||
2035 | u_int sxfrctl1; | ||
2036 | |||
2037 | sd.sd_ahc = ahc; | ||
2038 | sd.sd_control_offset = SEECTL; | ||
2039 | sd.sd_status_offset = SEECTL; | ||
2040 | sd.sd_dataout_offset = SEECTL; | ||
2041 | |||
2042 | ahc_acquire_seeprom(ahc, &sd); | ||
2043 | configure_termination(ahc, &sd, | ||
2044 | ahc->seep_config->adapter_control, | ||
2045 | &sxfrctl1); | ||
2046 | ahc_release_seeprom(&sd); | ||
2047 | } | ||
2048 | return (ahc_resume(ahc)); | ||
2049 | } | ||
2050 | |||
2051 | static int | ||
2052 | ahc_aic785X_setup(struct ahc_softc *ahc) | ||
2053 | { | ||
2054 | ahc_dev_softc_t pci; | ||
2055 | uint8_t rev; | ||
2056 | |||
2057 | pci = ahc->dev_softc; | ||
2058 | ahc->channel = 'A'; | ||
2059 | ahc->chip = AHC_AIC7850; | ||
2060 | ahc->features = AHC_AIC7850_FE; | ||
2061 | ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; | ||
2062 | rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1); | ||
2063 | if (rev >= 1) | ||
2064 | ahc->bugs |= AHC_PCI_2_1_RETRY_BUG; | ||
2065 | ahc->instruction_ram_size = 512; | ||
2066 | return (0); | ||
2067 | } | ||
2068 | |||
2069 | static int | ||
2070 | ahc_aic7860_setup(struct ahc_softc *ahc) | ||
2071 | { | ||
2072 | ahc_dev_softc_t pci; | ||
2073 | uint8_t rev; | ||
2074 | |||
2075 | pci = ahc->dev_softc; | ||
2076 | ahc->channel = 'A'; | ||
2077 | ahc->chip = AHC_AIC7860; | ||
2078 | ahc->features = AHC_AIC7860_FE; | ||
2079 | ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; | ||
2080 | rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1); | ||
2081 | if (rev >= 1) | ||
2082 | ahc->bugs |= AHC_PCI_2_1_RETRY_BUG; | ||
2083 | ahc->instruction_ram_size = 512; | ||
2084 | return (0); | ||
2085 | } | ||
2086 | |||
2087 | static int | ||
2088 | ahc_apa1480_setup(struct ahc_softc *ahc) | ||
2089 | { | ||
2090 | int error; | ||
2091 | |||
2092 | error = ahc_aic7860_setup(ahc); | ||
2093 | if (error != 0) | ||
2094 | return (error); | ||
2095 | ahc->features |= AHC_REMOVABLE; | ||
2096 | return (0); | ||
2097 | } | ||
2098 | |||
2099 | static int | ||
2100 | ahc_aic7870_setup(struct ahc_softc *ahc) | ||
2101 | { | ||
2102 | |||
2103 | ahc->channel = 'A'; | ||
2104 | ahc->chip = AHC_AIC7870; | ||
2105 | ahc->features = AHC_AIC7870_FE; | ||
2106 | ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; | ||
2107 | ahc->instruction_ram_size = 512; | ||
2108 | return (0); | ||
2109 | } | ||
2110 | |||
2111 | static int | ||
2112 | ahc_aha394X_setup(struct ahc_softc *ahc) | ||
2113 | { | ||
2114 | int error; | ||
2115 | |||
2116 | error = ahc_aic7870_setup(ahc); | ||
2117 | if (error == 0) | ||
2118 | error = ahc_aha394XX_setup(ahc); | ||
2119 | return (error); | ||
2120 | } | ||
2121 | |||
2122 | static int | ||
2123 | ahc_aha398X_setup(struct ahc_softc *ahc) | ||
2124 | { | ||
2125 | int error; | ||
2126 | |||
2127 | error = ahc_aic7870_setup(ahc); | ||
2128 | if (error == 0) | ||
2129 | error = ahc_aha398XX_setup(ahc); | ||
2130 | return (error); | ||
2131 | } | ||
2132 | |||
2133 | static int | ||
2134 | ahc_aha494X_setup(struct ahc_softc *ahc) | ||
2135 | { | ||
2136 | int error; | ||
2137 | |||
2138 | error = ahc_aic7870_setup(ahc); | ||
2139 | if (error == 0) | ||
2140 | error = ahc_aha494XX_setup(ahc); | ||
2141 | return (error); | ||
2142 | } | ||
2143 | |||
2144 | static int | ||
2145 | ahc_aic7880_setup(struct ahc_softc *ahc) | ||
2146 | { | ||
2147 | ahc_dev_softc_t pci; | ||
2148 | uint8_t rev; | ||
2149 | |||
2150 | pci = ahc->dev_softc; | ||
2151 | ahc->channel = 'A'; | ||
2152 | ahc->chip = AHC_AIC7880; | ||
2153 | ahc->features = AHC_AIC7880_FE; | ||
2154 | ahc->bugs |= AHC_TMODE_WIDEODD_BUG; | ||
2155 | rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1); | ||
2156 | if (rev >= 1) { | ||
2157 | ahc->bugs |= AHC_PCI_2_1_RETRY_BUG; | ||
2158 | } else { | ||
2159 | ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; | ||
2160 | } | ||
2161 | ahc->instruction_ram_size = 512; | ||
2162 | return (0); | ||
2163 | } | ||
2164 | |||
2165 | static int | ||
2166 | ahc_aha2940Pro_setup(struct ahc_softc *ahc) | ||
2167 | { | ||
2168 | |||
2169 | ahc->flags |= AHC_INT50_SPEEDFLEX; | ||
2170 | return (ahc_aic7880_setup(ahc)); | ||
2171 | } | ||
2172 | |||
2173 | static int | ||
2174 | ahc_aha394XU_setup(struct ahc_softc *ahc) | ||
2175 | { | ||
2176 | int error; | ||
2177 | |||
2178 | error = ahc_aic7880_setup(ahc); | ||
2179 | if (error == 0) | ||
2180 | error = ahc_aha394XX_setup(ahc); | ||
2181 | return (error); | ||
2182 | } | ||
2183 | |||
2184 | static int | ||
2185 | ahc_aha398XU_setup(struct ahc_softc *ahc) | ||
2186 | { | ||
2187 | int error; | ||
2188 | |||
2189 | error = ahc_aic7880_setup(ahc); | ||
2190 | if (error == 0) | ||
2191 | error = ahc_aha398XX_setup(ahc); | ||
2192 | return (error); | ||
2193 | } | ||
2194 | |||
2195 | static int | ||
2196 | ahc_aic7890_setup(struct ahc_softc *ahc) | ||
2197 | { | ||
2198 | ahc_dev_softc_t pci; | ||
2199 | uint8_t rev; | ||
2200 | |||
2201 | pci = ahc->dev_softc; | ||
2202 | ahc->channel = 'A'; | ||
2203 | ahc->chip = AHC_AIC7890; | ||
2204 | ahc->features = AHC_AIC7890_FE; | ||
2205 | ahc->flags |= AHC_NEWEEPROM_FMT; | ||
2206 | rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1); | ||
2207 | if (rev == 0) | ||
2208 | ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG; | ||
2209 | ahc->instruction_ram_size = 768; | ||
2210 | return (0); | ||
2211 | } | ||
2212 | |||
2213 | static int | ||
2214 | ahc_aic7892_setup(struct ahc_softc *ahc) | ||
2215 | { | ||
2216 | |||
2217 | ahc->channel = 'A'; | ||
2218 | ahc->chip = AHC_AIC7892; | ||
2219 | ahc->features = AHC_AIC7892_FE; | ||
2220 | ahc->flags |= AHC_NEWEEPROM_FMT; | ||
2221 | ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG; | ||
2222 | ahc->instruction_ram_size = 1024; | ||
2223 | return (0); | ||
2224 | } | ||
2225 | |||
2226 | static int | ||
2227 | ahc_aic7895_setup(struct ahc_softc *ahc) | ||
2228 | { | ||
2229 | ahc_dev_softc_t pci; | ||
2230 | uint8_t rev; | ||
2231 | |||
2232 | pci = ahc->dev_softc; | ||
2233 | ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A'; | ||
2234 | /* | ||
2235 | * The 'C' revision of the aic7895 has a few additional features. | ||
2236 | */ | ||
2237 | rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1); | ||
2238 | if (rev >= 4) { | ||
2239 | ahc->chip = AHC_AIC7895C; | ||
2240 | ahc->features = AHC_AIC7895C_FE; | ||
2241 | } else { | ||
2242 | u_int command; | ||
2243 | |||
2244 | ahc->chip = AHC_AIC7895; | ||
2245 | ahc->features = AHC_AIC7895_FE; | ||
2246 | |||
2247 | /* | ||
2248 | * The BIOS disables the use of MWI transactions | ||
2249 | * since it does not have the MWI bug work around | ||
2250 | * we have. Disabling MWI reduces performance, so | ||
2251 | * turn it on again. | ||
2252 | */ | ||
2253 | command = ahc_pci_read_config(pci, PCIR_COMMAND, /*bytes*/1); | ||
2254 | command |= PCIM_CMD_MWRICEN; | ||
2255 | ahc_pci_write_config(pci, PCIR_COMMAND, command, /*bytes*/1); | ||
2256 | ahc->bugs |= AHC_PCI_MWI_BUG; | ||
2257 | } | ||
2258 | /* | ||
2259 | * XXX Does CACHETHEN really not work??? What about PCI retry? | ||
2260 | * on C level chips. Need to test, but for now, play it safe. | ||
2261 | */ | ||
2262 | ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_PCI_2_1_RETRY_BUG | ||
2263 | | AHC_CACHETHEN_BUG; | ||
2264 | |||
2265 | #if 0 | ||
2266 | uint32_t devconfig; | ||
2267 | |||
2268 | /* | ||
2269 | * Cachesize must also be zero due to stray DAC | ||
2270 | * problem when sitting behind some bridges. | ||
2271 | */ | ||
2272 | ahc_pci_write_config(pci, CSIZE_LATTIME, 0, /*bytes*/1); | ||
2273 | devconfig = ahc_pci_read_config(pci, DEVCONFIG, /*bytes*/1); | ||
2274 | devconfig |= MRDCEN; | ||
2275 | ahc_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1); | ||
2276 | #endif | ||
2277 | ahc->flags |= AHC_NEWEEPROM_FMT; | ||
2278 | ahc->instruction_ram_size = 512; | ||
2279 | return (0); | ||
2280 | } | ||
2281 | |||
2282 | static int | ||
2283 | ahc_aic7896_setup(struct ahc_softc *ahc) | ||
2284 | { | ||
2285 | ahc_dev_softc_t pci; | ||
2286 | |||
2287 | pci = ahc->dev_softc; | ||
2288 | ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A'; | ||
2289 | ahc->chip = AHC_AIC7896; | ||
2290 | ahc->features = AHC_AIC7896_FE; | ||
2291 | ahc->flags |= AHC_NEWEEPROM_FMT; | ||
2292 | ahc->bugs |= AHC_CACHETHEN_DIS_BUG; | ||
2293 | ahc->instruction_ram_size = 768; | ||
2294 | return (0); | ||
2295 | } | ||
2296 | |||
2297 | static int | ||
2298 | ahc_aic7899_setup(struct ahc_softc *ahc) | ||
2299 | { | ||
2300 | ahc_dev_softc_t pci; | ||
2301 | |||
2302 | pci = ahc->dev_softc; | ||
2303 | ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A'; | ||
2304 | ahc->chip = AHC_AIC7899; | ||
2305 | ahc->features = AHC_AIC7899_FE; | ||
2306 | ahc->flags |= AHC_NEWEEPROM_FMT; | ||
2307 | ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG; | ||
2308 | ahc->instruction_ram_size = 1024; | ||
2309 | return (0); | ||
2310 | } | ||
2311 | |||
2312 | static int | ||
2313 | ahc_aha29160C_setup(struct ahc_softc *ahc) | ||
2314 | { | ||
2315 | int error; | ||
2316 | |||
2317 | error = ahc_aic7899_setup(ahc); | ||
2318 | if (error != 0) | ||
2319 | return (error); | ||
2320 | ahc->features |= AHC_REMOVABLE; | ||
2321 | return (0); | ||
2322 | } | ||
2323 | |||
2324 | static int | ||
2325 | ahc_raid_setup(struct ahc_softc *ahc) | ||
2326 | { | ||
2327 | printf("RAID functionality unsupported\n"); | ||
2328 | return (ENXIO); | ||
2329 | } | ||
2330 | |||
2331 | static int | ||
2332 | ahc_aha394XX_setup(struct ahc_softc *ahc) | ||
2333 | { | ||
2334 | ahc_dev_softc_t pci; | ||
2335 | |||
2336 | pci = ahc->dev_softc; | ||
2337 | switch (ahc_get_pci_slot(pci)) { | ||
2338 | case AHC_394X_SLOT_CHANNEL_A: | ||
2339 | ahc->channel = 'A'; | ||
2340 | break; | ||
2341 | case AHC_394X_SLOT_CHANNEL_B: | ||
2342 | ahc->channel = 'B'; | ||
2343 | break; | ||
2344 | default: | ||
2345 | printf("adapter at unexpected slot %d\n" | ||
2346 | "unable to map to a channel\n", | ||
2347 | ahc_get_pci_slot(pci)); | ||
2348 | ahc->channel = 'A'; | ||
2349 | } | ||
2350 | return (0); | ||
2351 | } | ||
2352 | |||
2353 | static int | ||
2354 | ahc_aha398XX_setup(struct ahc_softc *ahc) | ||
2355 | { | ||
2356 | ahc_dev_softc_t pci; | ||
2357 | |||
2358 | pci = ahc->dev_softc; | ||
2359 | switch (ahc_get_pci_slot(pci)) { | ||
2360 | case AHC_398X_SLOT_CHANNEL_A: | ||
2361 | ahc->channel = 'A'; | ||
2362 | break; | ||
2363 | case AHC_398X_SLOT_CHANNEL_B: | ||
2364 | ahc->channel = 'B'; | ||
2365 | break; | ||
2366 | case AHC_398X_SLOT_CHANNEL_C: | ||
2367 | ahc->channel = 'C'; | ||
2368 | break; | ||
2369 | default: | ||
2370 | printf("adapter at unexpected slot %d\n" | ||
2371 | "unable to map to a channel\n", | ||
2372 | ahc_get_pci_slot(pci)); | ||
2373 | ahc->channel = 'A'; | ||
2374 | break; | ||
2375 | } | ||
2376 | ahc->flags |= AHC_LARGE_SEEPROM; | ||
2377 | return (0); | ||
2378 | } | ||
2379 | |||
2380 | static int | ||
2381 | ahc_aha494XX_setup(struct ahc_softc *ahc) | ||
2382 | { | ||
2383 | ahc_dev_softc_t pci; | ||
2384 | |||
2385 | pci = ahc->dev_softc; | ||
2386 | switch (ahc_get_pci_slot(pci)) { | ||
2387 | case AHC_494X_SLOT_CHANNEL_A: | ||
2388 | ahc->channel = 'A'; | ||
2389 | break; | ||
2390 | case AHC_494X_SLOT_CHANNEL_B: | ||
2391 | ahc->channel = 'B'; | ||
2392 | break; | ||
2393 | case AHC_494X_SLOT_CHANNEL_C: | ||
2394 | ahc->channel = 'C'; | ||
2395 | break; | ||
2396 | case AHC_494X_SLOT_CHANNEL_D: | ||
2397 | ahc->channel = 'D'; | ||
2398 | break; | ||
2399 | default: | ||
2400 | printf("adapter at unexpected slot %d\n" | ||
2401 | "unable to map to a channel\n", | ||
2402 | ahc_get_pci_slot(pci)); | ||
2403 | ahc->channel = 'A'; | ||
2404 | } | ||
2405 | ahc->flags |= AHC_LARGE_SEEPROM; | ||
2406 | return (0); | ||
2407 | } | ||