xref: /openbsd/sys/dev/pci/ahd_pci.c (revision 898184e3)
1 /*	$OpenBSD: ahd_pci.c,v 1.21 2012/12/05 23:20:19 deraadt Exp $	*/
2 
3 /*
4  * Copyright (c) 2004 Milos Urbanek, Kenneth R. Westerback & Marco Peereboom
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  */
29 
30 /*
31  * Product specific probe and attach routines for:
32  *	aic7901 and aic7902 SCSI controllers
33  *
34  * Copyright (c) 1994-2001 Justin T. Gibbs.
35  * Copyright (c) 2000-2002 Adaptec Inc.
36  * All rights reserved.
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  * 1. Redistributions of source code must retain the above copyright
42  *    notice, this list of conditions, and the following disclaimer,
43  *    without modification.
44  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
45  *    substantially similar to the "NO WARRANTY" disclaimer below
46  *    ("Disclaimer") and any redistribution must be conditioned upon
47  *    including a substantially similar Disclaimer requirement for further
48  *    binary redistribution.
49  * 3. Neither the names of the above-listed copyright holders nor the names
50  *    of any contributors may be used to endorse or promote products derived
51  *    from this software without specific prior written permission.
52  *
53  * Alternatively, this software may be distributed under the terms of the
54  * GNU General Public License ("GPL") version 2 as published by the Free
55  * Software Foundation.
56  *
57  * NO WARRANTY
58  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
59  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
60  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
61  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
62  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
66  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
67  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
68  * POSSIBILITY OF SUCH DAMAGES.
69  *
70  */
71 
72 #include <dev/ic/aic79xx_openbsd.h>
73 #include <dev/ic/aic79xx_inline.h>
74 #include <dev/ic/aic79xx.h>
75 
76 #include <dev/pci/pcivar.h>
77 
78 __inline uint64_t ahd_compose_id(u_int, u_int, u_int, u_int);
79 __inline uint64_t
80 ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
81 {
82 	uint64_t id;
83 
84 	id = subvendor
85 	   | (subdevice << 16)
86 	   | ((uint64_t)vendor << 32)
87 	   | ((uint64_t)device << 48);
88 
89 	return (id);
90 }
91 
92 #define ID_ALL_MASK			0xFFFFFFFFFFFFFFFFull
93 #define ID_ALL_IROC_MASK		0xFF7FFFFFFFFFFFFFull
94 #define ID_DEV_VENDOR_MASK		0xFFFFFFFF00000000ull
95 #define ID_9005_GENERIC_MASK		0xFFF0FFFF00000000ull
96 #define ID_9005_GENERIC_IROC_MASK	0xFF70FFFF00000000ull
97 
98 #define ID_AIC7901			0x800F9005FFFF9005ull
99 #define ID_AHA_29320A			0x8000900500609005ull
100 #define ID_AHA_29320ALP			0x8017900500449005ull
101 #define ID_AHA_29320LPE			0x8017900500459005ull
102 
103 #define ID_AIC7901A			0x801E9005FFFF9005ull
104 #define ID_AHA_29320LP			0x8014900500449005ull
105 
106 #define ID_AIC7902			0x801F9005FFFF9005ull
107 #define ID_AIC7902_B			0x801D9005FFFF9005ull
108 #define ID_AHA_39320			0x8010900500409005ull
109 #define ID_AHA_29320			0x8012900500429005ull
110 #define ID_AHA_29320B			0x8013900500439005ull
111 #define ID_AHA_39320_B			0x8015900500409005ull
112 #define ID_AHA_39320_B_DELL		0x8015900501681028ull
113 #define ID_AHA_39320A			0x8016900500409005ull
114 #define ID_AHA_39320D			0x8011900500419005ull
115 #define ID_AHA_39320D_B			0x801C900500419005ull
116 #define ID_AHA_39320D_HP		0x8011900500AC0E11ull
117 #define ID_AHA_39320D_B_HP		0x801C900500AC0E11ull
118 #define ID_AIC7902_PCI_REV_A4		0x3
119 #define ID_AIC7902_PCI_REV_B0		0x10
120 #define SUBID_HP			0x0E11
121 
122 #define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
123 
124 #define DEVID_9005_TYPE(id) ((id) & 0xF)
125 #define		DEVID_9005_TYPE_HBA		0x0	/* Standard Card */
126 #define		DEVID_9005_TYPE_HBA_2EXT	0x1	/* 2 External Ports */
127 #define		DEVID_9005_TYPE_MB		0xF	/* On Motherboard */
128 
129 #define DEVID_9005_MFUNC(id) ((id) & 0x10)
130 
131 #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
132 
133 #define SUBID_9005_TYPE(id) ((id) & 0xF)
134 #define		SUBID_9005_TYPE_HBA		0x0	/* Standard Card */
135 #define		SUBID_9005_TYPE_MB		0xF	/* On Motherboard */
136 
137 #define SUBID_9005_AUTOTERM(id)	(((id) & 0x10) == 0)
138 
139 #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
140 
141 #define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6)
142 #define		SUBID_9005_SEEPTYPE_NONE	0x0
143 #define		SUBID_9005_SEEPTYPE_4K		0x1
144 
145 ahd_device_setup_t ahd_aic7901_setup;
146 ahd_device_setup_t ahd_aic7901A_setup;
147 ahd_device_setup_t ahd_aic7902_setup;
148 ahd_device_setup_t ahd_aic790X_setup;
149 
150 struct ahd_pci_identity ahd_pci_ident_table [] =
151 {
152 	/* aic7901 based controllers */
153 	{
154 		ID_AHA_29320A,
155 		ID_ALL_MASK,
156 		ahd_aic7901_setup
157 	},
158 	{
159 		ID_AHA_29320ALP,
160 		ID_ALL_MASK,
161 		ahd_aic7901_setup
162 	},
163 	{
164 		ID_AHA_29320LPE,
165 		ID_ALL_MASK,
166 		ahd_aic7901_setup
167 	},
168 	/* aic7901A based controllers */
169 	{
170 		ID_AHA_29320LP,
171 		ID_ALL_MASK,
172 		ahd_aic7901A_setup
173 	},
174 	/* aic7902 based controllers */
175 	{
176 		ID_AHA_29320,
177 		ID_ALL_MASK,
178 		ahd_aic7902_setup
179 	},
180 	{
181 		ID_AHA_29320B,
182 		ID_ALL_MASK,
183 		ahd_aic7902_setup
184 	},
185 	{
186 		ID_AHA_39320,
187 		ID_ALL_MASK,
188 		ahd_aic7902_setup
189 	},
190 	{
191 		ID_AHA_39320_B,
192 		ID_ALL_MASK,
193 		ahd_aic7902_setup
194 	},
195 	{
196 		ID_AHA_39320_B_DELL,
197 		ID_ALL_MASK,
198 		ahd_aic7902_setup
199 	},
200 	{
201 		ID_AHA_39320A,
202 		ID_ALL_MASK,
203 		ahd_aic7902_setup
204 	},
205 	{
206 		ID_AHA_39320D,
207 		ID_ALL_MASK,
208 		ahd_aic7902_setup
209 	},
210 	{
211 		ID_AHA_39320D_HP,
212 		ID_ALL_MASK,
213 		ahd_aic7902_setup
214 	},
215 	{
216 		ID_AHA_39320D_B,
217 		ID_ALL_MASK,
218 		ahd_aic7902_setup
219 	},
220 	{
221 		ID_AHA_39320D_B_HP,
222 		ID_ALL_MASK,
223 		ahd_aic7902_setup
224 	},
225 	/* Generic chip probes for devices we don't know 'exactly' */
226 	{
227 		ID_AIC7901 & ID_9005_GENERIC_MASK,
228 		ID_9005_GENERIC_MASK,
229 		ahd_aic7901_setup
230 	},
231 	{
232 		ID_AIC7901A & ID_DEV_VENDOR_MASK,
233 		ID_DEV_VENDOR_MASK,
234 		ahd_aic7901A_setup
235 	},
236 	{
237 		ID_AIC7902 & ID_9005_GENERIC_MASK,
238 		ID_9005_GENERIC_MASK,
239 		ahd_aic7902_setup
240 	}
241 };
242 
243 const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
244 
245 #define			DEVCONFIG		0x40
246 #define			PCIXINITPAT		0x0000E000ul
247 #define			PCIXINIT_PCI33_66	0x0000E000ul
248 #define			PCIXINIT_PCIX50_66	0x0000C000ul
249 #define			PCIXINIT_PCIX66_100	0x0000A000ul
250 #define			PCIXINIT_PCIX100_133	0x00008000ul
251 #define	PCI_BUS_MODES_INDEX(devconfig)	\
252 	(((devconfig) & PCIXINITPAT) >> 13)
253 
254 static const char *pci_bus_modes[] =
255 {
256 	"PCI bus mode unknown",
257 	"PCI bus mode unknown",
258 	"PCI bus mode unknown",
259 	"PCI bus mode unknown",
260 	"PCI-X 101-133MHz",
261 	"PCI-X 67-100MHz",
262 	"PCI-X 50-66MHz",
263 	"PCI 33 or 66MHz"
264 };
265 
266 #define		TESTMODE	0x00000800ul
267 #define		IRDY_RST	0x00000200ul
268 #define		FRAME_RST	0x00000100ul
269 #define		PCI64BIT	0x00000080ul
270 #define		MRDCEN		0x00000040ul
271 #define		ENDIANSEL	0x00000020ul
272 #define		MIXQWENDIANEN	0x00000008ul
273 #define		DACEN		0x00000004ul
274 #define		STPWLEVEL	0x00000002ul
275 #define		QWENDIANSEL	0x00000001ul
276 
277 #define	DEVCONFIG1		0x44
278 #define		PREQDIS		0x01
279 
280 #define	CSIZE_LATTIME		0x0c
281 #define		CACHESIZE	0x000000fful
282 #define		LATTIME		0x0000ff00ul
283 
284 int	ahd_pci_probe(struct device *, void *, void *);
285 void	ahd_pci_attach(struct device *, struct device *, void *);
286 
287 struct cfattach ahd_pci_ca = {
288 	        sizeof(struct ahd_softc), ahd_pci_probe, ahd_pci_attach
289 };
290 
291 int	ahd_check_extport(struct ahd_softc *ahd);
292 void	ahd_configure_termination(struct ahd_softc *ahd,
293 					  u_int adapter_control);
294 void	ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
295 
296 const struct ahd_pci_identity *
297 ahd_find_pci_device(pcireg_t id, pcireg_t subid)
298 {
299 	const struct ahd_pci_identity *entry;
300 	u_int64_t full_id;
301 	u_int i;
302 
303 	full_id = ahd_compose_id(PCI_PRODUCT(id), PCI_VENDOR(id),
304 	    PCI_PRODUCT(subid), PCI_VENDOR(subid));
305 
306 	/*
307 	 * If we are configured to attach to HostRAID
308 	 * controllers, mask out the IROC/HostRAID bit
309 	 * in the
310 	 */
311 	if (ahd_attach_to_HostRAID_controllers)
312 		full_id &= ID_ALL_IROC_MASK;
313 
314 	for (i = 0; i < ahd_num_pci_devs; i++) {
315 		entry = &ahd_pci_ident_table[i];
316 		if (entry->full_id == (full_id & entry->id_mask)) {
317 			return (entry);
318 		}
319 	}
320 	return (NULL);
321 }
322 
323 int
324 ahd_pci_probe(struct device *parent, void *match, void *aux)
325 {
326 	const struct ahd_pci_identity *entry;
327 	struct pci_attach_args *pa = aux;
328 	pcireg_t subid;
329 
330 	subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
331 	entry = ahd_find_pci_device(pa->pa_id, subid);
332 	return entry != NULL ? 1 : 0;
333 }
334 
335 void
336 ahd_pci_attach(struct device *parent, struct device *self, void *aux)
337 {
338 	const struct ahd_pci_identity *entry;
339 	struct pci_attach_args *pa = aux;
340 	struct ahd_softc *ahd = (void *)self;
341 	pci_intr_handle_t ih;
342 	const char *intrstr;
343 	pcireg_t devconfig, memtype, subid;
344 	uint16_t device, subvendor;
345 	int error, ioh_valid, ioh2_valid, l, memh_valid;
346 
347 	ahd->dev_softc = pa;
348 	ahd->parent_dmat = pa->pa_dmat;
349 
350 	if (ahd_alloc(ahd, ahd->sc_dev.dv_xname) == NULL)
351 		return;
352 
353 	subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
354 	entry = ahd_find_pci_device(pa->pa_id, subid);
355 	if (entry == NULL)
356 		return;
357 
358 	/*
359 	 * Record if this is a HostRAID board.
360 	 */
361 	device = PCI_PRODUCT(pa->pa_id);
362 	if (DEVID_9005_HOSTRAID(device))
363 		ahd->flags |= AHD_HOSTRAID_BOARD;
364 
365 	/*
366 	 * Record if this is an HP board.
367 	 */
368 	subvendor = PCI_VENDOR(subid);
369 	if (subvendor == SUBID_HP)
370 		ahd->flags |= AHD_HP_BOARD;
371 
372 	error = entry->setup(ahd, pa);
373 	if (error != 0)
374 		return;
375 
376 	/* XXX ahc on sparc64 needs this twice */
377 	devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
378 
379 	if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
380 		ahd->chip |= AHD_PCI;
381 		/* Disable PCIX workarounds when running in PCI mode. */
382 		ahd->bugs &= ~AHD_PCIX_BUG_MASK;
383 	} else {
384 		ahd->chip |= AHD_PCIX;
385 	}
386 	ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
387 
388 	memh_valid = ioh_valid = ioh2_valid = 0;
389 
390 	if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIX,
391 	    &ahd->pcix_off, NULL)) {
392 		if (ahd->chip & AHD_PCIX)
393 			printf("%s: warning: can't find PCI-X capability\n",
394 			    ahd_name(ahd));
395 		ahd->chip &= ~AHD_PCIX;
396 		ahd->chip |= AHD_PCI;
397 		ahd->bugs &= ~AHD_PCIX_BUG_MASK;
398 	}
399 
400 	/*
401 	 * Map PCI registers
402 	 */
403 	if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) == 0) {
404 		memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag,
405 		    AHD_PCI_MEMADDR);
406 		switch (memtype) {
407 		case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
408 		case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
409 			memh_valid = (pci_mapreg_map(pa, AHD_PCI_MEMADDR,
410 			    memtype, 0, &ahd->tags[0], &ahd->bshs[0], NULL,
411 			    NULL, 0) == 0);
412 			if (memh_valid) {
413 				ahd->tags[1] = ahd->tags[0];
414 				bus_space_subregion(ahd->tags[0], ahd->bshs[0],
415 				    /*offset*/0x100, /*size*/0x100,
416 				    &ahd->bshs[1]);
417 				if (ahd_pci_test_register_access(ahd) != 0)
418 					memh_valid = 0;
419 			}
420 			break;
421 		default:
422 			memh_valid = 0;
423 			printf("%s: unknown memory type: 0x%x\n",
424 			ahd_name(ahd), memtype);
425 			break;
426 		}
427 
428 #ifdef AHD_DEBUG
429 		printf("%s: doing memory mapping tag0 0x%x, tag1 0x%x, shs0 "
430 		    "0x%lx, shs1 0x%lx\n", ahd_name(ahd), ahd->tags[0],
431 		    ahd->tags[1], ahd->bshs[0], ahd->bshs[1]);
432 #endif
433 	}
434 
435 	if (!memh_valid) {
436 		/* First BAR */
437 		ioh_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR,
438 		    PCI_MAPREG_TYPE_IO, 0, &ahd->tags[0], &ahd->bshs[0], NULL,
439 		    NULL, 0) == 0);
440 
441 		/* 2nd BAR */
442 		ioh2_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR1,
443 		    PCI_MAPREG_TYPE_IO, 0, &ahd->tags[1], &ahd->bshs[1], NULL,
444 		    NULL, 0) == 0);
445 
446 #ifdef AHD_DEBUG
447 		printf("%s: doing io mapping tag0 0x%x, tag1 0x%x, shs0 0x%lx, "
448 		    "shs1 0x%lx\n", ahd_name(ahd), ahd->tags[0], ahd->tags[1],
449 		    ahd->bshs[0], ahd->bshs[1]);
450 #endif
451 	}
452 
453 	if (memh_valid == 0 && (ioh_valid == 0 || ioh2_valid == 0)) {
454 		printf("%s: unable to map registers\n", ahd_name(ahd));
455 		return;
456 	}
457 
458 	/*
459 	 * Set Power State D0.
460 	 */
461 	pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
462 
463 	/*
464 	 * Should we bother disabling 39Bit addressing
465 	 * based on installed memory?
466 	 */
467 	if (sizeof(bus_addr_t) > 4)
468 		ahd->flags |= AHD_39BIT_ADDRESSING;
469 
470 	/*
471 	 * If we need to support high memory, enable dual
472 	 * address cycles.  This bit must be set to enable
473 	 * high address bit generation even if we are on a
474 	 * 64bit bus (PCI64BIT set in devconfig).
475 	 */
476 	if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
477 		if (bootverbose)
478 			printf("%s: Enabling 39Bit Addressing\n",
479 			       ahd_name(ahd));
480 		devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
481 		devconfig |= DACEN;
482 		pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG, devconfig);
483 	}
484 
485 	ahd_softc_init(ahd);
486 
487 	/*
488 	 * Map the interrupts routines
489 	 */
490 	ahd->bus_intr = ahd_pci_intr;
491 
492 	error = ahd_reset(ahd, /*reinit*/FALSE);
493 	if (error != 0) {
494 		ahd_free(ahd);
495 		return;
496 	}
497 
498 	if (pci_intr_map(pa, &ih)) {
499 		printf("%s: couldn't map interrupt\n", ahd_name(ahd));
500 		ahd_free(ahd);
501 		return;
502 	}
503 	intrstr = pci_intr_string(pa->pa_pc, ih);
504 	ahd->ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
505 	    ahd_platform_intr, ahd, ahd->sc_dev.dv_xname);
506 	if (ahd->ih == NULL) {
507 		printf("%s: couldn't establish interrupt", ahd_name(ahd));
508 		if (intrstr != NULL)
509 			printf(" at %s", intrstr);
510 		printf("\n");
511 		ahd_free(ahd);
512 		return;
513 	}
514 	if (intrstr != NULL)
515 		printf(": %s\n", intrstr);
516 
517 	/* Get the size of the cache */
518 	ahd->pci_cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
519 	ahd->pci_cachesize *= 4;
520 
521 	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
522 	/* See if we have a SEEPROM and perform auto-term */
523 	error = ahd_check_extport(ahd);
524 	if (error != 0)
525 		return;
526 
527 	/* Core initialization */
528 	error = ahd_init(ahd);
529 	if (error != 0)
530 		return;
531 
532 	ahd_list_lock(&l);
533 	/*
534 	 * Link this softc in with all other ahd instances.
535 	 */
536 	ahd_softc_insert(ahd);
537 	ahd_list_unlock(&l);
538 
539 	/* complete the attach */
540 	ahd_attach(ahd);
541 }
542 
543 /*
544  * Perform some simple tests that should catch situations where
545  * our registers are invalidly mapped.
546  */
547 int
548 ahd_pci_test_register_access(struct ahd_softc *ahd)
549 {
550 	const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
551 	const pcitag_t tag = ahd->dev_softc->pa_tag;
552 	pcireg_t cmd;
553 	u_int	 targpcistat;
554 	pcireg_t pci_status1;
555 	int	 error;
556 	uint8_t	 hcntrl;
557 
558 	error = EIO;
559 
560 	/*
561 	 * Enable PCI error interrupt status, but suppress NMIs
562 	 * generated by SERR raised due to target aborts.
563 	 */
564 	cmd = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
565 	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
566 	    cmd & ~PCI_COMMAND_SERR_ENABLE);
567 
568 	/*
569 	 * First a simple test to see if any
570 	 * registers can be read.  Reading
571 	 * HCNTRL has no side effects and has
572 	 * at least one bit that is guaranteed to
573 	 * be zero so it is a good register to
574 	 * use for this test.
575 	 */
576 	hcntrl = ahd_inb(ahd, HCNTRL);
577 	if (hcntrl == 0xFF)
578 		goto fail;
579 
580 	/*
581 	 * Next create a situation where write combining
582 	 * or read prefetching could be initiated by the
583 	 * CPU or host bridge.  Our device does not support
584 	 * either, so look for data corruption and/or flaged
585 	 * PCI errors.  First pause without causing another
586 	 * chip reset.
587 	 */
588 	hcntrl &= ~CHIPRST;
589 	ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
590 	while (ahd_is_paused(ahd) == 0)
591 		;
592 
593 	/* Clear any PCI errors that occurred before our driver attached. */
594 	ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
595 	targpcistat = ahd_inb(ahd, TARGPCISTAT);
596 	ahd_outb(ahd, TARGPCISTAT, targpcistat);
597 	pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
598 	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, pci_status1);
599 	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
600 	ahd_outb(ahd, CLRINT, CLRPCIINT);
601 
602 	ahd_outb(ahd, SEQCTL0, PERRORDIS);
603 	ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
604 	if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
605 		goto fail;
606 
607 	if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
608 		ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
609 		targpcistat = ahd_inb(ahd, TARGPCISTAT);
610 		if ((targpcistat & STA) != 0)
611 			goto fail;
612 	}
613 
614 	error = 0;
615 
616 fail:
617 	if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
618 
619 		ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
620 		targpcistat = ahd_inb(ahd, TARGPCISTAT);
621 
622 		/* Silently clear any latched errors. */
623 		ahd_outb(ahd, TARGPCISTAT, targpcistat);
624 		pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
625 		pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, pci_status1);
626 		ahd_outb(ahd, CLRINT, CLRPCIINT);
627 	}
628 	ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
629 	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmd);
630 	return (error);
631 }
632 
633 /*
634  * Check the external port logic for a serial eeprom
635  * and termination/cable detection contrls.
636  */
637 int
638 ahd_check_extport(struct ahd_softc *ahd)
639 {
640 	struct	vpd_config vpd;
641 	struct	seeprom_config *sc;
642 	u_int	adapter_control;
643 	int	have_seeprom;
644 	int	error;
645 
646 	sc = ahd->seep_config;
647 	have_seeprom = ahd_acquire_seeprom(ahd);
648 	if (have_seeprom) {
649 		u_int start_addr;
650 
651 		/*
652 		 * Fetch VPD for this function and parse it.
653 		 */
654 		if (bootverbose)
655 			printf("%s: Reading VPD from SEEPROM...",
656 			       ahd_name(ahd));
657 
658 		/* Address is always in units of 16bit words */
659 		start_addr = ((2 * sizeof(*sc))
660 			    + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
661 
662 		error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
663 					 start_addr, sizeof(vpd)/2,
664 					 /*bytestream*/TRUE);
665 		if (error == 0)
666 			error = ahd_parse_vpddata(ahd, &vpd);
667 		if (bootverbose)
668 			printf("%s: VPD parsing %s\n",
669 			       ahd_name(ahd),
670 			       error == 0 ? "successful" : "failed");
671 
672 		if (bootverbose)
673 			printf("%s: Reading SEEPROM...", ahd_name(ahd));
674 
675 		/* Address is always in units of 16bit words */
676 		start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
677 
678 		error = ahd_read_seeprom(ahd, (uint16_t *)sc,
679 					 start_addr, sizeof(*sc)/2,
680 					 /*bytestream*/FALSE);
681 
682 		if (error != 0) {
683 			printf("Unable to read SEEPROM\n");
684 			have_seeprom = 0;
685 		} else {
686 			have_seeprom = ahd_verify_cksum(sc);
687 
688 			if (bootverbose) {
689 				if (have_seeprom == 0)
690 					printf ("checksum error\n");
691 				else
692 					printf ("done.\n");
693 			}
694 		}
695 		ahd_release_seeprom(ahd);
696 	}
697 
698 	if (!have_seeprom) {
699 		u_int	  nvram_scb;
700 
701 		/*
702 		 * Pull scratch ram settings and treat them as
703 		 * if they are the contents of an seeprom if
704 		 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
705 		 * in SCB 0xFF.  We manually compose the data as 16bit
706 		 * values to avoid endian issues.
707 		 */
708 		ahd_set_scbptr(ahd, 0xFF);
709 		nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
710 		if (nvram_scb != 0xFF
711 		 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
712 		   && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
713 		   && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
714 		   && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
715 		  || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
716 		   && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
717 		   && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
718 		   && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
719 		  || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
720 		   && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
721 		   && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
722 		   && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
723 			uint16_t *sc_data;
724 			int	  i;
725 
726 			ahd_set_scbptr(ahd, nvram_scb);
727 			sc_data = (uint16_t *)sc;
728 			for (i = 0; i < 64; i += 2)
729 				*sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
730 			have_seeprom = ahd_verify_cksum(sc);
731 			if (have_seeprom)
732 				ahd->flags |= AHD_SCB_CONFIG_USED;
733 		}
734 	}
735 
736 #ifdef AHD_DEBUG
737 	if (have_seeprom != 0
738 	 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
739 		uint16_t *sc_data;
740 		int	  i;
741 
742 		printf("%s: Seeprom Contents:", ahd_name(ahd));
743 		sc_data = (uint16_t *)sc;
744 		for (i = 0; i < (sizeof(*sc)); i += 2)
745 			printf("\n\t0x%.4x", sc_data[i]);
746 		printf("\n");
747 	}
748 #endif
749 
750 	if (!have_seeprom) {
751 		if (bootverbose)
752 			printf("%s: No SEEPROM available.\n", ahd_name(ahd));
753 		ahd->flags |= AHD_USEDEFAULTS;
754 		error = ahd_default_config(ahd);
755 		adapter_control = CFAUTOTERM|CFSEAUTOTERM;
756 		free(ahd->seep_config, M_DEVBUF);
757 		ahd->seep_config = NULL;
758 	} else {
759 		error = ahd_parse_cfgdata(ahd, sc);
760 		adapter_control = sc->adapter_control;
761 	}
762 	if (error != 0)
763 		return (error);
764 
765 	ahd_configure_termination(ahd, adapter_control);
766 
767 	return (0);
768 }
769 
770 void
771 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
772 {
773 	const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
774 	const pcitag_t tag = ahd->dev_softc->pa_tag;
775 	int	 error;
776 	u_int	 sxfrctl1;
777 	uint8_t	 termctl;
778 	pcireg_t devconfig;
779 
780 	devconfig = pci_conf_read(pc, tag, DEVCONFIG);
781 	devconfig &= ~STPWLEVEL;
782 	if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
783 		devconfig |= STPWLEVEL;
784 	if (bootverbose)
785 		printf("%s: STPWLEVEL is %s\n",
786 		       ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
787 	pci_conf_write(pc, tag, DEVCONFIG, devconfig);
788 
789 	/* Make sure current sensing is off. */
790 	if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
791 		(void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
792 	}
793 
794 	/*
795 	 * Read to sense.  Write to set.
796 	 */
797 	error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
798 	if ((adapter_control & CFAUTOTERM) == 0) {
799 		if (bootverbose)
800 			printf("%s: Manual Primary Termination\n",
801 			       ahd_name(ahd));
802 		termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
803 		if ((adapter_control & CFSTERM) != 0)
804 			termctl |= FLX_TERMCTL_ENPRILOW;
805 		if ((adapter_control & CFWSTERM) != 0)
806 			termctl |= FLX_TERMCTL_ENPRIHIGH;
807 	} else if (error != 0) {
808 		printf("%s: Primary Auto-Term Sensing failed! "
809 		       "Using Defaults.\n", ahd_name(ahd));
810 		termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
811 	}
812 
813 	if ((adapter_control & CFSEAUTOTERM) == 0) {
814 		if (bootverbose)
815 			printf("%s: Manual Secondary Termination\n",
816 			       ahd_name(ahd));
817 		termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
818 		if ((adapter_control & CFSELOWTERM) != 0)
819 			termctl |= FLX_TERMCTL_ENSECLOW;
820 		if ((adapter_control & CFSEHIGHTERM) != 0)
821 			termctl |= FLX_TERMCTL_ENSECHIGH;
822 	} else if (error != 0) {
823 		printf("%s: Secondary Auto-Term Sensing failed! "
824 		       "Using Defaults.\n", ahd_name(ahd));
825 		termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
826 	}
827 
828 	/*
829 	 * Now set the termination based on what we found.
830 	 */
831 	sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
832 	ahd->flags &= ~AHD_TERM_ENB_A;
833 	if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
834 		ahd->flags |= AHD_TERM_ENB_A;
835 		sxfrctl1 |= STPWEN;
836 	}
837 	/* Must set the latch once in order to be effective. */
838 	ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
839 	ahd_outb(ahd, SXFRCTL1, sxfrctl1);
840 
841 	error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
842 	if (error != 0) {
843 		printf("%s: Unable to set termination settings!\n",
844 		       ahd_name(ahd));
845 	} else if (bootverbose) {
846 		printf("%s: Primary High byte termination %sabled\n",
847 		       ahd_name(ahd),
848 		       (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
849 
850 		printf("%s: Primary Low byte termination %sabled\n",
851 		       ahd_name(ahd),
852 		       (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
853 
854 		printf("%s: Secondary High byte termination %sabled\n",
855 		       ahd_name(ahd),
856 		       (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
857 
858 		printf("%s: Secondary Low byte termination %sabled\n",
859 		       ahd_name(ahd),
860 		       (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
861 	}
862 	return;
863 }
864 
865 #define	DPE	0x80
866 #define SSE	0x40
867 #define	RMA	0x20
868 #define	RTA	0x10
869 #define STA	0x08
870 #define DPR	0x01
871 
872 static const char *split_status_source[] =
873 {
874 	"DFF0",
875 	"DFF1",
876 	"OVLY",
877 	"CMC",
878 };
879 
880 static const char *pci_status_source[] =
881 {
882 	"DFF0",
883 	"DFF1",
884 	"SG",
885 	"CMC",
886 	"OVLY",
887 	"NONE",
888 	"MSI",
889 	"TARG"
890 };
891 
892 static const char *split_status_strings[] =
893 {
894 	"%s: Received split response in %s.\n",
895 	"%s: Received split completion error message in %s\n",
896 	"%s: Receive overrun in %s\n",
897 	"%s: Count not complete in %s\n",
898 	"%s: Split completion data bucket in %s\n",
899 	"%s: Split completion address error in %s\n",
900 	"%s: Split completion byte count error in %s\n",
901 	"%s: Signaled Target-abort to early terminate a split in %s\n"
902 };
903 
904 static const char *pci_status_strings[] =
905 {
906 	"%s: Data Parity Error has been reported via PERR# in %s\n",
907 	"%s: Target initial wait state error in %s\n",
908 	"%s: Split completion read data parity error in %s\n",
909 	"%s: Split completion address attribute parity error in %s\n",
910 	"%s: Received a Target Abort in %s\n",
911 	"%s: Received a Master Abort in %s\n",
912 	"%s: Signal System Error Detected in %s\n",
913 	"%s: Address or Write Phase Parity Error Detected in %s.\n"
914 };
915 
916 void
917 ahd_pci_intr(struct ahd_softc *ahd)
918 {
919 	const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
920 	const pcitag_t tag = ahd->dev_softc->pa_tag;
921 	uint8_t		pci_status[8];
922 	ahd_mode_state	saved_modes;
923 	pcireg_t	pci_status1;
924 	u_int		intstat;
925 	u_int		i;
926 	u_int		reg;
927 
928 	intstat = ahd_inb(ahd, INTSTAT);
929 
930 	if ((intstat & SPLTINT) != 0)
931 		ahd_pci_split_intr(ahd, intstat);
932 
933 	if ((intstat & PCIINT) == 0)
934 		return;
935 
936 	printf("%s: PCI error Interrupt\n", ahd_name(ahd));
937 	saved_modes = ahd_save_modes(ahd);
938 	ahd_dump_card_state(ahd);
939 	ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
940 	for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
941 
942 		if (i == 5)
943 			continue;
944 		pci_status[i] = ahd_inb(ahd, reg);
945 		/* Clear latched errors.  So our interrupt deasserts. */
946 		ahd_outb(ahd, reg, pci_status[i]);
947 	}
948 
949 	for (i = 0; i < 8; i++) {
950 		u_int bit;
951 
952 		if (i == 5)
953 			continue;
954 
955 		for (bit = 0; bit < 8; bit++) {
956 
957 			if ((pci_status[i] & (0x1 << bit)) != 0) {
958 				static const char *s;
959 
960 				s = pci_status_strings[bit];
961 				if (i == 7/*TARG*/ && bit == 3)
962 					s = "%s: Signaled Target Abort\n";
963 				printf(s, ahd_name(ahd), pci_status_source[i]);
964 			}
965 		}
966 	}
967 	pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
968 	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG , pci_status1);
969 
970 	ahd_restore_modes(ahd, saved_modes);
971 	ahd_outb(ahd, CLRINT, CLRPCIINT);
972 	ahd_unpause(ahd);
973 
974 	return;
975 }
976 
977 void
978 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
979 {
980 	const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
981 	const pcitag_t tag = ahd->dev_softc->pa_tag;
982 	uint8_t		split_status[4];
983 	uint8_t		split_status1[4];
984 	uint8_t		sg_split_status[2];
985 	uint8_t		sg_split_status1[2];
986 	ahd_mode_state	saved_modes;
987 	u_int		i;
988 	pcireg_t	pcix_status;
989 
990 	/*
991 	 * Check for splits in all modes.  Modes 0 and 1
992 	 * additionally have SG engine splits to look at.
993 	 */
994 	pcix_status = pci_conf_read(pc, tag, ahd->pcix_off + 0x04);
995 	printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
996 	       ahd_name(ahd), pcix_status);
997 
998 	saved_modes = ahd_save_modes(ahd);
999 	for (i = 0; i < 4; i++) {
1000 		ahd_set_modes(ahd, i, i);
1001 
1002 		split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
1003 		split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
1004 		/* Clear latched errors.  So our interrupt deasserts. */
1005 		ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
1006 		ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
1007 		if (i > 1)
1008 			continue;
1009 		sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
1010 		sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
1011 		/* Clear latched errors.  So our interrupt deasserts. */
1012 		ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
1013 		ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
1014 	}
1015 
1016 	for (i = 0; i < 4; i++) {
1017 		u_int bit;
1018 
1019 		for (bit = 0; bit < 8; bit++) {
1020 
1021 			if ((split_status[i] & (0x1 << bit)) != 0) {
1022 				static const char *s;
1023 
1024 				s = split_status_strings[bit];
1025 				printf(s, ahd_name(ahd),
1026 				       split_status_source[i]);
1027 			}
1028 
1029 			if (i > 1)
1030 				continue;
1031 
1032 			if ((sg_split_status[i] & (0x1 << bit)) != 0) {
1033 				static const char *s;
1034 
1035 				s = split_status_strings[bit];
1036 				printf(s, ahd_name(ahd), "SG");
1037 			}
1038 		}
1039 	}
1040 	/*
1041 	 * Clear PCI-X status bits.
1042 	 */
1043 	pci_conf_write(pc, tag, ahd->pcix_off + 0x04, pcix_status);
1044 	ahd_outb(ahd, CLRINT, CLRSPLTINT);
1045 	ahd_restore_modes(ahd, saved_modes);
1046 }
1047 
1048 int
1049 ahd_aic7901_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
1050 {
1051 
1052 	ahd->chip = AHD_AIC7901;
1053 	ahd->features = AHD_AIC7901_FE;
1054 	return (ahd_aic790X_setup(ahd, pa));
1055 }
1056 
1057 int
1058 ahd_aic7901A_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
1059 {
1060 
1061 	ahd->chip = AHD_AIC7901A;
1062 	ahd->features = AHD_AIC7901A_FE;
1063 	return (ahd_aic790X_setup(ahd, pa));
1064 }
1065 
1066 int
1067 ahd_aic7902_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
1068 {
1069 	ahd->chip = AHD_AIC7902;
1070 	ahd->features = AHD_AIC7902_FE;
1071 	return (ahd_aic790X_setup(ahd, pa));
1072 }
1073 
1074 int
1075 ahd_aic790X_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
1076 {
1077 	u_int rev;
1078 
1079 	rev = PCI_REVISION(pa->pa_class);
1080 #ifdef AHD_DEBUG
1081 	printf("\n%s: aic7902 chip revision 0x%x\n", ahd_name(ahd), rev);
1082 #endif
1083 	if (rev < ID_AIC7902_PCI_REV_A4) {
1084 		printf("%s: Unable to attach to unsupported chip revision %d\n",
1085 		       ahd_name(ahd), rev);
1086 		pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 0);
1087 		return (ENXIO);
1088 	}
1089 
1090 	ahd->channel = (pa->pa_function == 1) ? 'B' : 'A';
1091 	if (rev < ID_AIC7902_PCI_REV_B0) {
1092 		/*
1093 		 * Enable A series workarounds.
1094 		 */
1095 		ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
1096 			  |  AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
1097 			  |  AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
1098 			  |  AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
1099 			  |  AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
1100 			  |  AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
1101 			  |  AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
1102 			  |  AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
1103 			  |  AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
1104 			  |  AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
1105 			  |  AHD_FAINT_LED_BUG;
1106 
1107 		/*
1108 		 * IO Cell parameter setup.
1109 		 */
1110 		AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
1111 
1112 		if ((ahd->flags & AHD_HP_BOARD) == 0)
1113 			AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
1114 	} else {
1115 		pcireg_t devconfig1;
1116 
1117 		ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
1118 			      |  AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
1119 		ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG
1120 		    	  |  AHD_BUSFREEREV_BUG;
1121 
1122 		/*
1123 		 * Some issues have been resolved in the 7901B.
1124 		 */
1125 		if ((ahd->features & AHD_MULTI_FUNC) != 0)
1126 			ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
1127 
1128 		/*
1129 		 * IO Cell parameter setup.
1130 		 */
1131 		AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
1132 		AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
1133 		AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
1134 
1135 		/*
1136 		 * Set the PREQDIS bit for H2B which disables some workaround
1137 		 * that doesn't work on regular PCI busses.
1138 		 * XXX - Find out exactly what this does from the hardware
1139 		 * 	 folks!
1140 		 */
1141 		devconfig1 = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG1);
1142 		pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG1, devconfig1|PREQDIS);
1143 		devconfig1 = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG1);
1144 	}
1145 
1146 	return (0);
1147 }
1148