162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Product specific probe and attach routines for:
362306a36Sopenharmony_ci *      3940, 2940, aic7895, aic7890, aic7880,
462306a36Sopenharmony_ci *	aic7870, aic7860 and aic7850 SCSI controllers
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (c) 1994-2001 Justin T. Gibbs.
762306a36Sopenharmony_ci * Copyright (c) 2000-2001 Adaptec Inc.
862306a36Sopenharmony_ci * All rights reserved.
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without
1162306a36Sopenharmony_ci * modification, are permitted provided that the following conditions
1262306a36Sopenharmony_ci * are met:
1362306a36Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright
1462306a36Sopenharmony_ci *    notice, this list of conditions, and the following disclaimer,
1562306a36Sopenharmony_ci *    without modification.
1662306a36Sopenharmony_ci * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1762306a36Sopenharmony_ci *    substantially similar to the "NO WARRANTY" disclaimer below
1862306a36Sopenharmony_ci *    ("Disclaimer") and any redistribution must be conditioned upon
1962306a36Sopenharmony_ci *    including a substantially similar Disclaimer requirement for further
2062306a36Sopenharmony_ci *    binary redistribution.
2162306a36Sopenharmony_ci * 3. Neither the names of the above-listed copyright holders nor the names
2262306a36Sopenharmony_ci *    of any contributors may be used to endorse or promote products derived
2362306a36Sopenharmony_ci *    from this software without specific prior written permission.
2462306a36Sopenharmony_ci *
2562306a36Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the
2662306a36Sopenharmony_ci * GNU General Public License ("GPL") version 2 as published by the Free
2762306a36Sopenharmony_ci * Software Foundation.
2862306a36Sopenharmony_ci *
2962306a36Sopenharmony_ci * NO WARRANTY
3062306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3162306a36Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3262306a36Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3362306a36Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3462306a36Sopenharmony_ci * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3562306a36Sopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3662306a36Sopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3762306a36Sopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3862306a36Sopenharmony_ci * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
3962306a36Sopenharmony_ci * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4062306a36Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGES.
4162306a36Sopenharmony_ci *
4262306a36Sopenharmony_ci * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#79 $
4362306a36Sopenharmony_ci */
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#include "aic7xxx_osm.h"
4662306a36Sopenharmony_ci#include "aic7xxx_inline.h"
4762306a36Sopenharmony_ci#include "aic7xxx_93cx6.h"
4862306a36Sopenharmony_ci#include "aic7xxx_pci.h"
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic inline uint64_t
5162306a36Sopenharmony_ciahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	uint64_t id;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	id = subvendor
5662306a36Sopenharmony_ci	   | (subdevice << 16)
5762306a36Sopenharmony_ci	   | ((uint64_t)vendor << 32)
5862306a36Sopenharmony_ci	   | ((uint64_t)device << 48);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	return (id);
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci#define AHC_PCI_IOADDR	PCIR_MAPS	/* I/O Address */
6462306a36Sopenharmony_ci#define AHC_PCI_MEMADDR	(PCIR_MAPS + 4)	/* Mem I/O Address */
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#define DEVID_9005_TYPE(id) ((id) & 0xF)
6762306a36Sopenharmony_ci#define		DEVID_9005_TYPE_HBA		0x0	/* Standard Card */
6862306a36Sopenharmony_ci#define		DEVID_9005_TYPE_AAA		0x3	/* RAID Card */
6962306a36Sopenharmony_ci#define		DEVID_9005_TYPE_SISL		0x5	/* Container ROMB */
7062306a36Sopenharmony_ci#define		DEVID_9005_TYPE_MB		0xF	/* On Motherboard */
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci#define DEVID_9005_MAXRATE(id) (((id) & 0x30) >> 4)
7362306a36Sopenharmony_ci#define		DEVID_9005_MAXRATE_U160		0x0
7462306a36Sopenharmony_ci#define		DEVID_9005_MAXRATE_ULTRA2	0x1
7562306a36Sopenharmony_ci#define		DEVID_9005_MAXRATE_ULTRA	0x2
7662306a36Sopenharmony_ci#define		DEVID_9005_MAXRATE_FAST		0x3
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci#define DEVID_9005_MFUNC(id) (((id) & 0x40) >> 6)
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#define DEVID_9005_CLASS(id) (((id) & 0xFF00) >> 8)
8162306a36Sopenharmony_ci#define		DEVID_9005_CLASS_SPI		0x0	/* Parallel SCSI */
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci#define SUBID_9005_TYPE(id) ((id) & 0xF)
8462306a36Sopenharmony_ci#define		SUBID_9005_TYPE_MB		0xF	/* On Motherboard */
8562306a36Sopenharmony_ci#define		SUBID_9005_TYPE_CARD		0x0	/* Standard Card */
8662306a36Sopenharmony_ci#define		SUBID_9005_TYPE_LCCARD		0x1	/* Low Cost Card */
8762306a36Sopenharmony_ci#define		SUBID_9005_TYPE_RAID		0x3	/* Combined with Raid */
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#define SUBID_9005_TYPE_KNOWN(id)			\
9062306a36Sopenharmony_ci	  ((((id) & 0xF) == SUBID_9005_TYPE_MB)		\
9162306a36Sopenharmony_ci	|| (((id) & 0xF) == SUBID_9005_TYPE_CARD)	\
9262306a36Sopenharmony_ci	|| (((id) & 0xF) == SUBID_9005_TYPE_LCCARD)	\
9362306a36Sopenharmony_ci	|| (((id) & 0xF) == SUBID_9005_TYPE_RAID))
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci#define SUBID_9005_MAXRATE(id) (((id) & 0x30) >> 4)
9662306a36Sopenharmony_ci#define		SUBID_9005_MAXRATE_ULTRA2	0x0
9762306a36Sopenharmony_ci#define		SUBID_9005_MAXRATE_ULTRA	0x1
9862306a36Sopenharmony_ci#define		SUBID_9005_MAXRATE_U160		0x2
9962306a36Sopenharmony_ci#define		SUBID_9005_MAXRATE_RESERVED	0x3
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci#define SUBID_9005_SEEPTYPE(id)						\
10262306a36Sopenharmony_ci	((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB)			\
10362306a36Sopenharmony_ci	 ? ((id) & 0xC0) >> 6						\
10462306a36Sopenharmony_ci	 : ((id) & 0x300) >> 8)
10562306a36Sopenharmony_ci#define		SUBID_9005_SEEPTYPE_NONE	0x0
10662306a36Sopenharmony_ci#define		SUBID_9005_SEEPTYPE_1K		0x1
10762306a36Sopenharmony_ci#define		SUBID_9005_SEEPTYPE_2K_4K	0x2
10862306a36Sopenharmony_ci#define		SUBID_9005_SEEPTYPE_RESERVED	0x3
10962306a36Sopenharmony_ci#define SUBID_9005_AUTOTERM(id)						\
11062306a36Sopenharmony_ci	((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB)			\
11162306a36Sopenharmony_ci	 ? (((id) & 0x400) >> 10) == 0					\
11262306a36Sopenharmony_ci	 : (((id) & 0x40) >> 6) == 0)
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci#define SUBID_9005_NUMCHAN(id)						\
11562306a36Sopenharmony_ci	((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB)			\
11662306a36Sopenharmony_ci	 ? ((id) & 0x300) >> 8						\
11762306a36Sopenharmony_ci	 : ((id) & 0xC00) >> 10)
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#define SUBID_9005_LEGACYCONN(id)					\
12062306a36Sopenharmony_ci	((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB)			\
12162306a36Sopenharmony_ci	 ? 0								\
12262306a36Sopenharmony_ci	 : ((id) & 0x80) >> 7)
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci#define SUBID_9005_MFUNCENB(id)						\
12562306a36Sopenharmony_ci	((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB)			\
12662306a36Sopenharmony_ci	 ? ((id) & 0x800) >> 11						\
12762306a36Sopenharmony_ci	 : ((id) & 0x1000) >> 12)
12862306a36Sopenharmony_ci/*
12962306a36Sopenharmony_ci * Informational only. Should use chip register to be
13062306a36Sopenharmony_ci * certain, but may be use in identification strings.
13162306a36Sopenharmony_ci */
13262306a36Sopenharmony_ci#define SUBID_9005_CARD_SCSIWIDTH_MASK	0x2000
13362306a36Sopenharmony_ci#define SUBID_9005_CARD_PCIWIDTH_MASK	0x4000
13462306a36Sopenharmony_ci#define SUBID_9005_CARD_SEDIFF_MASK	0x8000
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic785X_setup;
13762306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic7860_setup;
13862306a36Sopenharmony_cistatic ahc_device_setup_t ahc_apa1480_setup;
13962306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic7870_setup;
14062306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic7870h_setup;
14162306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha394X_setup;
14262306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha394Xh_setup;
14362306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha494X_setup;
14462306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha494Xh_setup;
14562306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha398X_setup;
14662306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic7880_setup;
14762306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic7880h_setup;
14862306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha2940Pro_setup;
14962306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha394XU_setup;
15062306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha394XUh_setup;
15162306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha398XU_setup;
15262306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic7890_setup;
15362306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic7892_setup;
15462306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic7895_setup;
15562306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic7895h_setup;
15662306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic7896_setup;
15762306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aic7899_setup;
15862306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha29160C_setup;
15962306a36Sopenharmony_cistatic ahc_device_setup_t ahc_raid_setup;
16062306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha394XX_setup;
16162306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha494XX_setup;
16262306a36Sopenharmony_cistatic ahc_device_setup_t ahc_aha398XX_setup;
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cistatic const struct ahc_pci_identity ahc_pci_ident_table[] = {
16562306a36Sopenharmony_ci	/* aic7850 based controllers */
16662306a36Sopenharmony_ci	{
16762306a36Sopenharmony_ci		ID_AHA_2902_04_10_15_20C_30C,
16862306a36Sopenharmony_ci		ID_ALL_MASK,
16962306a36Sopenharmony_ci		"Adaptec 2902/04/10/15/20C/30C SCSI adapter",
17062306a36Sopenharmony_ci		ahc_aic785X_setup
17162306a36Sopenharmony_ci	},
17262306a36Sopenharmony_ci	/* aic7860 based controllers */
17362306a36Sopenharmony_ci	{
17462306a36Sopenharmony_ci		ID_AHA_2930CU,
17562306a36Sopenharmony_ci		ID_ALL_MASK,
17662306a36Sopenharmony_ci		"Adaptec 2930CU SCSI adapter",
17762306a36Sopenharmony_ci		ahc_aic7860_setup
17862306a36Sopenharmony_ci	},
17962306a36Sopenharmony_ci	{
18062306a36Sopenharmony_ci		ID_AHA_1480A & ID_DEV_VENDOR_MASK,
18162306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
18262306a36Sopenharmony_ci		"Adaptec 1480A Ultra SCSI adapter",
18362306a36Sopenharmony_ci		ahc_apa1480_setup
18462306a36Sopenharmony_ci	},
18562306a36Sopenharmony_ci	{
18662306a36Sopenharmony_ci		ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK,
18762306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
18862306a36Sopenharmony_ci		"Adaptec 2940A Ultra SCSI adapter",
18962306a36Sopenharmony_ci		ahc_aic7860_setup
19062306a36Sopenharmony_ci	},
19162306a36Sopenharmony_ci	{
19262306a36Sopenharmony_ci		ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK,
19362306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
19462306a36Sopenharmony_ci		"Adaptec 2940A/CN Ultra SCSI adapter",
19562306a36Sopenharmony_ci		ahc_aic7860_setup
19662306a36Sopenharmony_ci	},
19762306a36Sopenharmony_ci	{
19862306a36Sopenharmony_ci		ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK,
19962306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
20062306a36Sopenharmony_ci		"Adaptec 2930C Ultra SCSI adapter (VAR)",
20162306a36Sopenharmony_ci		ahc_aic7860_setup
20262306a36Sopenharmony_ci	},
20362306a36Sopenharmony_ci	/* aic7870 based controllers */
20462306a36Sopenharmony_ci	{
20562306a36Sopenharmony_ci		ID_AHA_2940,
20662306a36Sopenharmony_ci		ID_ALL_MASK,
20762306a36Sopenharmony_ci		"Adaptec 2940 SCSI adapter",
20862306a36Sopenharmony_ci		ahc_aic7870_setup
20962306a36Sopenharmony_ci	},
21062306a36Sopenharmony_ci	{
21162306a36Sopenharmony_ci		ID_AHA_3940,
21262306a36Sopenharmony_ci		ID_ALL_MASK,
21362306a36Sopenharmony_ci		"Adaptec 3940 SCSI adapter",
21462306a36Sopenharmony_ci		ahc_aha394X_setup
21562306a36Sopenharmony_ci	},
21662306a36Sopenharmony_ci	{
21762306a36Sopenharmony_ci		ID_AHA_398X,
21862306a36Sopenharmony_ci		ID_ALL_MASK,
21962306a36Sopenharmony_ci		"Adaptec 398X SCSI RAID adapter",
22062306a36Sopenharmony_ci		ahc_aha398X_setup
22162306a36Sopenharmony_ci	},
22262306a36Sopenharmony_ci	{
22362306a36Sopenharmony_ci		ID_AHA_2944,
22462306a36Sopenharmony_ci		ID_ALL_MASK,
22562306a36Sopenharmony_ci		"Adaptec 2944 SCSI adapter",
22662306a36Sopenharmony_ci		ahc_aic7870h_setup
22762306a36Sopenharmony_ci	},
22862306a36Sopenharmony_ci	{
22962306a36Sopenharmony_ci		ID_AHA_3944,
23062306a36Sopenharmony_ci		ID_ALL_MASK,
23162306a36Sopenharmony_ci		"Adaptec 3944 SCSI adapter",
23262306a36Sopenharmony_ci		ahc_aha394Xh_setup
23362306a36Sopenharmony_ci	},
23462306a36Sopenharmony_ci	{
23562306a36Sopenharmony_ci		ID_AHA_4944,
23662306a36Sopenharmony_ci		ID_ALL_MASK,
23762306a36Sopenharmony_ci		"Adaptec 4944 SCSI adapter",
23862306a36Sopenharmony_ci		ahc_aha494Xh_setup
23962306a36Sopenharmony_ci	},
24062306a36Sopenharmony_ci	/* aic7880 based controllers */
24162306a36Sopenharmony_ci	{
24262306a36Sopenharmony_ci		ID_AHA_2940U & ID_DEV_VENDOR_MASK,
24362306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
24462306a36Sopenharmony_ci		"Adaptec 2940 Ultra SCSI adapter",
24562306a36Sopenharmony_ci		ahc_aic7880_setup
24662306a36Sopenharmony_ci	},
24762306a36Sopenharmony_ci	{
24862306a36Sopenharmony_ci		ID_AHA_3940U & ID_DEV_VENDOR_MASK,
24962306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
25062306a36Sopenharmony_ci		"Adaptec 3940 Ultra SCSI adapter",
25162306a36Sopenharmony_ci		ahc_aha394XU_setup
25262306a36Sopenharmony_ci	},
25362306a36Sopenharmony_ci	{
25462306a36Sopenharmony_ci		ID_AHA_2944U & ID_DEV_VENDOR_MASK,
25562306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
25662306a36Sopenharmony_ci		"Adaptec 2944 Ultra SCSI adapter",
25762306a36Sopenharmony_ci		ahc_aic7880h_setup
25862306a36Sopenharmony_ci	},
25962306a36Sopenharmony_ci	{
26062306a36Sopenharmony_ci		ID_AHA_3944U & ID_DEV_VENDOR_MASK,
26162306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
26262306a36Sopenharmony_ci		"Adaptec 3944 Ultra SCSI adapter",
26362306a36Sopenharmony_ci		ahc_aha394XUh_setup
26462306a36Sopenharmony_ci	},
26562306a36Sopenharmony_ci	{
26662306a36Sopenharmony_ci		ID_AHA_398XU & ID_DEV_VENDOR_MASK,
26762306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
26862306a36Sopenharmony_ci		"Adaptec 398X Ultra SCSI RAID adapter",
26962306a36Sopenharmony_ci		ahc_aha398XU_setup
27062306a36Sopenharmony_ci	},
27162306a36Sopenharmony_ci	{
27262306a36Sopenharmony_ci		/*
27362306a36Sopenharmony_ci		 * XXX Don't know the slot numbers
27462306a36Sopenharmony_ci		 * so we can't identify channels
27562306a36Sopenharmony_ci		 */
27662306a36Sopenharmony_ci		ID_AHA_4944U & ID_DEV_VENDOR_MASK,
27762306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
27862306a36Sopenharmony_ci		"Adaptec 4944 Ultra SCSI adapter",
27962306a36Sopenharmony_ci		ahc_aic7880h_setup
28062306a36Sopenharmony_ci	},
28162306a36Sopenharmony_ci	{
28262306a36Sopenharmony_ci		ID_AHA_2930U & ID_DEV_VENDOR_MASK,
28362306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
28462306a36Sopenharmony_ci		"Adaptec 2930 Ultra SCSI adapter",
28562306a36Sopenharmony_ci		ahc_aic7880_setup
28662306a36Sopenharmony_ci	},
28762306a36Sopenharmony_ci	{
28862306a36Sopenharmony_ci		ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK,
28962306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
29062306a36Sopenharmony_ci		"Adaptec 2940 Pro Ultra SCSI adapter",
29162306a36Sopenharmony_ci		ahc_aha2940Pro_setup
29262306a36Sopenharmony_ci	},
29362306a36Sopenharmony_ci	{
29462306a36Sopenharmony_ci		ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK,
29562306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
29662306a36Sopenharmony_ci		"Adaptec 2940/CN Ultra SCSI adapter",
29762306a36Sopenharmony_ci		ahc_aic7880_setup
29862306a36Sopenharmony_ci	},
29962306a36Sopenharmony_ci	/* Ignore all SISL (AAC on MB) based controllers. */
30062306a36Sopenharmony_ci	{
30162306a36Sopenharmony_ci		ID_9005_SISL_ID,
30262306a36Sopenharmony_ci		ID_9005_SISL_MASK,
30362306a36Sopenharmony_ci		NULL,
30462306a36Sopenharmony_ci		NULL
30562306a36Sopenharmony_ci	},
30662306a36Sopenharmony_ci	/* aic7890 based controllers */
30762306a36Sopenharmony_ci	{
30862306a36Sopenharmony_ci		ID_AHA_2930U2,
30962306a36Sopenharmony_ci		ID_ALL_MASK,
31062306a36Sopenharmony_ci		"Adaptec 2930 Ultra2 SCSI adapter",
31162306a36Sopenharmony_ci		ahc_aic7890_setup
31262306a36Sopenharmony_ci	},
31362306a36Sopenharmony_ci	{
31462306a36Sopenharmony_ci		ID_AHA_2940U2B,
31562306a36Sopenharmony_ci		ID_ALL_MASK,
31662306a36Sopenharmony_ci		"Adaptec 2940B Ultra2 SCSI adapter",
31762306a36Sopenharmony_ci		ahc_aic7890_setup
31862306a36Sopenharmony_ci	},
31962306a36Sopenharmony_ci	{
32062306a36Sopenharmony_ci		ID_AHA_2940U2_OEM,
32162306a36Sopenharmony_ci		ID_ALL_MASK,
32262306a36Sopenharmony_ci		"Adaptec 2940 Ultra2 SCSI adapter (OEM)",
32362306a36Sopenharmony_ci		ahc_aic7890_setup
32462306a36Sopenharmony_ci	},
32562306a36Sopenharmony_ci	{
32662306a36Sopenharmony_ci		ID_AHA_2940U2,
32762306a36Sopenharmony_ci		ID_ALL_MASK,
32862306a36Sopenharmony_ci		"Adaptec 2940 Ultra2 SCSI adapter",
32962306a36Sopenharmony_ci		ahc_aic7890_setup
33062306a36Sopenharmony_ci	},
33162306a36Sopenharmony_ci	{
33262306a36Sopenharmony_ci		ID_AHA_2950U2B,
33362306a36Sopenharmony_ci		ID_ALL_MASK,
33462306a36Sopenharmony_ci		"Adaptec 2950 Ultra2 SCSI adapter",
33562306a36Sopenharmony_ci		ahc_aic7890_setup
33662306a36Sopenharmony_ci	},
33762306a36Sopenharmony_ci	{
33862306a36Sopenharmony_ci		ID_AIC7890_ARO,
33962306a36Sopenharmony_ci		ID_ALL_MASK,
34062306a36Sopenharmony_ci		"Adaptec aic7890/91 Ultra2 SCSI adapter (ARO)",
34162306a36Sopenharmony_ci		ahc_aic7890_setup
34262306a36Sopenharmony_ci	},
34362306a36Sopenharmony_ci	{
34462306a36Sopenharmony_ci		ID_AAA_131U2,
34562306a36Sopenharmony_ci		ID_ALL_MASK,
34662306a36Sopenharmony_ci		"Adaptec AAA-131 Ultra2 RAID adapter",
34762306a36Sopenharmony_ci		ahc_aic7890_setup
34862306a36Sopenharmony_ci	},
34962306a36Sopenharmony_ci	/* aic7892 based controllers */
35062306a36Sopenharmony_ci	{
35162306a36Sopenharmony_ci		ID_AHA_29160,
35262306a36Sopenharmony_ci		ID_ALL_MASK,
35362306a36Sopenharmony_ci		"Adaptec 29160 Ultra160 SCSI adapter",
35462306a36Sopenharmony_ci		ahc_aic7892_setup
35562306a36Sopenharmony_ci	},
35662306a36Sopenharmony_ci	{
35762306a36Sopenharmony_ci		ID_AHA_29160_CPQ,
35862306a36Sopenharmony_ci		ID_ALL_MASK,
35962306a36Sopenharmony_ci		"Adaptec (Compaq OEM) 29160 Ultra160 SCSI adapter",
36062306a36Sopenharmony_ci		ahc_aic7892_setup
36162306a36Sopenharmony_ci	},
36262306a36Sopenharmony_ci	{
36362306a36Sopenharmony_ci		ID_AHA_29160N,
36462306a36Sopenharmony_ci		ID_ALL_MASK,
36562306a36Sopenharmony_ci		"Adaptec 29160N Ultra160 SCSI adapter",
36662306a36Sopenharmony_ci		ahc_aic7892_setup
36762306a36Sopenharmony_ci	},
36862306a36Sopenharmony_ci	{
36962306a36Sopenharmony_ci		ID_AHA_29160C,
37062306a36Sopenharmony_ci		ID_ALL_MASK,
37162306a36Sopenharmony_ci		"Adaptec 29160C Ultra160 SCSI adapter",
37262306a36Sopenharmony_ci		ahc_aha29160C_setup
37362306a36Sopenharmony_ci	},
37462306a36Sopenharmony_ci	{
37562306a36Sopenharmony_ci		ID_AHA_29160B,
37662306a36Sopenharmony_ci		ID_ALL_MASK,
37762306a36Sopenharmony_ci		"Adaptec 29160B Ultra160 SCSI adapter",
37862306a36Sopenharmony_ci		ahc_aic7892_setup
37962306a36Sopenharmony_ci	},
38062306a36Sopenharmony_ci	{
38162306a36Sopenharmony_ci		ID_AHA_19160B,
38262306a36Sopenharmony_ci		ID_ALL_MASK,
38362306a36Sopenharmony_ci		"Adaptec 19160B Ultra160 SCSI adapter",
38462306a36Sopenharmony_ci		ahc_aic7892_setup
38562306a36Sopenharmony_ci	},
38662306a36Sopenharmony_ci	{
38762306a36Sopenharmony_ci		ID_AIC7892_ARO,
38862306a36Sopenharmony_ci		ID_ALL_MASK,
38962306a36Sopenharmony_ci		"Adaptec aic7892 Ultra160 SCSI adapter (ARO)",
39062306a36Sopenharmony_ci		ahc_aic7892_setup
39162306a36Sopenharmony_ci	},
39262306a36Sopenharmony_ci	{
39362306a36Sopenharmony_ci		ID_AHA_2915_30LP,
39462306a36Sopenharmony_ci		ID_ALL_MASK,
39562306a36Sopenharmony_ci		"Adaptec 2915/30LP Ultra160 SCSI adapter",
39662306a36Sopenharmony_ci		ahc_aic7892_setup
39762306a36Sopenharmony_ci	},
39862306a36Sopenharmony_ci	/* aic7895 based controllers */
39962306a36Sopenharmony_ci	{
40062306a36Sopenharmony_ci		ID_AHA_2940U_DUAL,
40162306a36Sopenharmony_ci		ID_ALL_MASK,
40262306a36Sopenharmony_ci		"Adaptec 2940/DUAL Ultra SCSI adapter",
40362306a36Sopenharmony_ci		ahc_aic7895_setup
40462306a36Sopenharmony_ci	},
40562306a36Sopenharmony_ci	{
40662306a36Sopenharmony_ci		ID_AHA_3940AU,
40762306a36Sopenharmony_ci		ID_ALL_MASK,
40862306a36Sopenharmony_ci		"Adaptec 3940A Ultra SCSI adapter",
40962306a36Sopenharmony_ci		ahc_aic7895_setup
41062306a36Sopenharmony_ci	},
41162306a36Sopenharmony_ci	{
41262306a36Sopenharmony_ci		ID_AHA_3944AU,
41362306a36Sopenharmony_ci		ID_ALL_MASK,
41462306a36Sopenharmony_ci		"Adaptec 3944A Ultra SCSI adapter",
41562306a36Sopenharmony_ci		ahc_aic7895h_setup
41662306a36Sopenharmony_ci	},
41762306a36Sopenharmony_ci	{
41862306a36Sopenharmony_ci		ID_AIC7895_ARO,
41962306a36Sopenharmony_ci		ID_AIC7895_ARO_MASK,
42062306a36Sopenharmony_ci		"Adaptec aic7895 Ultra SCSI adapter (ARO)",
42162306a36Sopenharmony_ci		ahc_aic7895_setup
42262306a36Sopenharmony_ci	},
42362306a36Sopenharmony_ci	/* aic7896/97 based controllers */
42462306a36Sopenharmony_ci	{
42562306a36Sopenharmony_ci		ID_AHA_3950U2B_0,
42662306a36Sopenharmony_ci		ID_ALL_MASK,
42762306a36Sopenharmony_ci		"Adaptec 3950B Ultra2 SCSI adapter",
42862306a36Sopenharmony_ci		ahc_aic7896_setup
42962306a36Sopenharmony_ci	},
43062306a36Sopenharmony_ci	{
43162306a36Sopenharmony_ci		ID_AHA_3950U2B_1,
43262306a36Sopenharmony_ci		ID_ALL_MASK,
43362306a36Sopenharmony_ci		"Adaptec 3950B Ultra2 SCSI adapter",
43462306a36Sopenharmony_ci		ahc_aic7896_setup
43562306a36Sopenharmony_ci	},
43662306a36Sopenharmony_ci	{
43762306a36Sopenharmony_ci		ID_AHA_3950U2D_0,
43862306a36Sopenharmony_ci		ID_ALL_MASK,
43962306a36Sopenharmony_ci		"Adaptec 3950D Ultra2 SCSI adapter",
44062306a36Sopenharmony_ci		ahc_aic7896_setup
44162306a36Sopenharmony_ci	},
44262306a36Sopenharmony_ci	{
44362306a36Sopenharmony_ci		ID_AHA_3950U2D_1,
44462306a36Sopenharmony_ci		ID_ALL_MASK,
44562306a36Sopenharmony_ci		"Adaptec 3950D Ultra2 SCSI adapter",
44662306a36Sopenharmony_ci		ahc_aic7896_setup
44762306a36Sopenharmony_ci	},
44862306a36Sopenharmony_ci	{
44962306a36Sopenharmony_ci		ID_AIC7896_ARO,
45062306a36Sopenharmony_ci		ID_ALL_MASK,
45162306a36Sopenharmony_ci		"Adaptec aic7896/97 Ultra2 SCSI adapter (ARO)",
45262306a36Sopenharmony_ci		ahc_aic7896_setup
45362306a36Sopenharmony_ci	},
45462306a36Sopenharmony_ci	/* aic7899 based controllers */
45562306a36Sopenharmony_ci	{
45662306a36Sopenharmony_ci		ID_AHA_3960D,
45762306a36Sopenharmony_ci		ID_ALL_MASK,
45862306a36Sopenharmony_ci		"Adaptec 3960D Ultra160 SCSI adapter",
45962306a36Sopenharmony_ci		ahc_aic7899_setup
46062306a36Sopenharmony_ci	},
46162306a36Sopenharmony_ci	{
46262306a36Sopenharmony_ci		ID_AHA_3960D_CPQ,
46362306a36Sopenharmony_ci		ID_ALL_MASK,
46462306a36Sopenharmony_ci		"Adaptec (Compaq OEM) 3960D Ultra160 SCSI adapter",
46562306a36Sopenharmony_ci		ahc_aic7899_setup
46662306a36Sopenharmony_ci	},
46762306a36Sopenharmony_ci	{
46862306a36Sopenharmony_ci		ID_AIC7899_ARO,
46962306a36Sopenharmony_ci		ID_ALL_MASK,
47062306a36Sopenharmony_ci		"Adaptec aic7899 Ultra160 SCSI adapter (ARO)",
47162306a36Sopenharmony_ci		ahc_aic7899_setup
47262306a36Sopenharmony_ci	},
47362306a36Sopenharmony_ci	/* Generic chip probes for devices we don't know 'exactly' */
47462306a36Sopenharmony_ci	{
47562306a36Sopenharmony_ci		ID_AIC7850 & ID_DEV_VENDOR_MASK,
47662306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
47762306a36Sopenharmony_ci		"Adaptec aic7850 SCSI adapter",
47862306a36Sopenharmony_ci		ahc_aic785X_setup
47962306a36Sopenharmony_ci	},
48062306a36Sopenharmony_ci	{
48162306a36Sopenharmony_ci		ID_AIC7855 & ID_DEV_VENDOR_MASK,
48262306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
48362306a36Sopenharmony_ci		"Adaptec aic7855 SCSI adapter",
48462306a36Sopenharmony_ci		ahc_aic785X_setup
48562306a36Sopenharmony_ci	},
48662306a36Sopenharmony_ci	{
48762306a36Sopenharmony_ci		ID_AIC7859 & ID_DEV_VENDOR_MASK,
48862306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
48962306a36Sopenharmony_ci		"Adaptec aic7859 SCSI adapter",
49062306a36Sopenharmony_ci		ahc_aic7860_setup
49162306a36Sopenharmony_ci	},
49262306a36Sopenharmony_ci	{
49362306a36Sopenharmony_ci		ID_AIC7860 & ID_DEV_VENDOR_MASK,
49462306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
49562306a36Sopenharmony_ci		"Adaptec aic7860 Ultra SCSI adapter",
49662306a36Sopenharmony_ci		ahc_aic7860_setup
49762306a36Sopenharmony_ci	},
49862306a36Sopenharmony_ci	{
49962306a36Sopenharmony_ci		ID_AIC7870 & ID_DEV_VENDOR_MASK,
50062306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
50162306a36Sopenharmony_ci		"Adaptec aic7870 SCSI adapter",
50262306a36Sopenharmony_ci		ahc_aic7870_setup
50362306a36Sopenharmony_ci	},
50462306a36Sopenharmony_ci	{
50562306a36Sopenharmony_ci		ID_AIC7880 & ID_DEV_VENDOR_MASK,
50662306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
50762306a36Sopenharmony_ci		"Adaptec aic7880 Ultra SCSI adapter",
50862306a36Sopenharmony_ci		ahc_aic7880_setup
50962306a36Sopenharmony_ci	},
51062306a36Sopenharmony_ci	{
51162306a36Sopenharmony_ci		ID_AIC7890 & ID_9005_GENERIC_MASK,
51262306a36Sopenharmony_ci		ID_9005_GENERIC_MASK,
51362306a36Sopenharmony_ci		"Adaptec aic7890/91 Ultra2 SCSI adapter",
51462306a36Sopenharmony_ci		ahc_aic7890_setup
51562306a36Sopenharmony_ci	},
51662306a36Sopenharmony_ci	{
51762306a36Sopenharmony_ci		ID_AIC7892 & ID_9005_GENERIC_MASK,
51862306a36Sopenharmony_ci		ID_9005_GENERIC_MASK,
51962306a36Sopenharmony_ci		"Adaptec aic7892 Ultra160 SCSI adapter",
52062306a36Sopenharmony_ci		ahc_aic7892_setup
52162306a36Sopenharmony_ci	},
52262306a36Sopenharmony_ci	{
52362306a36Sopenharmony_ci		ID_AIC7895 & ID_DEV_VENDOR_MASK,
52462306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
52562306a36Sopenharmony_ci		"Adaptec aic7895 Ultra SCSI adapter",
52662306a36Sopenharmony_ci		ahc_aic7895_setup
52762306a36Sopenharmony_ci	},
52862306a36Sopenharmony_ci	{
52962306a36Sopenharmony_ci		ID_AIC7896 & ID_9005_GENERIC_MASK,
53062306a36Sopenharmony_ci		ID_9005_GENERIC_MASK,
53162306a36Sopenharmony_ci		"Adaptec aic7896/97 Ultra2 SCSI adapter",
53262306a36Sopenharmony_ci		ahc_aic7896_setup
53362306a36Sopenharmony_ci	},
53462306a36Sopenharmony_ci	{
53562306a36Sopenharmony_ci		ID_AIC7899 & ID_9005_GENERIC_MASK,
53662306a36Sopenharmony_ci		ID_9005_GENERIC_MASK,
53762306a36Sopenharmony_ci		"Adaptec aic7899 Ultra160 SCSI adapter",
53862306a36Sopenharmony_ci		ahc_aic7899_setup
53962306a36Sopenharmony_ci	},
54062306a36Sopenharmony_ci	{
54162306a36Sopenharmony_ci		ID_AIC7810 & ID_DEV_VENDOR_MASK,
54262306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
54362306a36Sopenharmony_ci		"Adaptec aic7810 RAID memory controller",
54462306a36Sopenharmony_ci		ahc_raid_setup
54562306a36Sopenharmony_ci	},
54662306a36Sopenharmony_ci	{
54762306a36Sopenharmony_ci		ID_AIC7815 & ID_DEV_VENDOR_MASK,
54862306a36Sopenharmony_ci		ID_DEV_VENDOR_MASK,
54962306a36Sopenharmony_ci		"Adaptec aic7815 RAID memory controller",
55062306a36Sopenharmony_ci		ahc_raid_setup
55162306a36Sopenharmony_ci	}
55262306a36Sopenharmony_ci};
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_cistatic const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table);
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci#define AHC_394X_SLOT_CHANNEL_A	4
55762306a36Sopenharmony_ci#define AHC_394X_SLOT_CHANNEL_B	5
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci#define AHC_398X_SLOT_CHANNEL_A	4
56062306a36Sopenharmony_ci#define AHC_398X_SLOT_CHANNEL_B	8
56162306a36Sopenharmony_ci#define AHC_398X_SLOT_CHANNEL_C	12
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci#define AHC_494X_SLOT_CHANNEL_A	4
56462306a36Sopenharmony_ci#define AHC_494X_SLOT_CHANNEL_B	5
56562306a36Sopenharmony_ci#define AHC_494X_SLOT_CHANNEL_C	6
56662306a36Sopenharmony_ci#define AHC_494X_SLOT_CHANNEL_D	7
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci#define	DEVCONFIG		0x40
56962306a36Sopenharmony_ci#define		PCIERRGENDIS	0x80000000ul
57062306a36Sopenharmony_ci#define		SCBSIZE32	0x00010000ul	/* aic789X only */
57162306a36Sopenharmony_ci#define		REXTVALID	0x00001000ul	/* ultra cards only */
57262306a36Sopenharmony_ci#define		MPORTMODE	0x00000400ul	/* aic7870+ only */
57362306a36Sopenharmony_ci#define		RAMPSM		0x00000200ul	/* aic7870+ only */
57462306a36Sopenharmony_ci#define		VOLSENSE	0x00000100ul
57562306a36Sopenharmony_ci#define		PCI64BIT	0x00000080ul	/* 64Bit PCI bus (Ultra2 Only)*/
57662306a36Sopenharmony_ci#define		SCBRAMSEL	0x00000080ul
57762306a36Sopenharmony_ci#define		MRDCEN		0x00000040ul
57862306a36Sopenharmony_ci#define		EXTSCBTIME	0x00000020ul	/* aic7870 only */
57962306a36Sopenharmony_ci#define		EXTSCBPEN	0x00000010ul	/* aic7870 only */
58062306a36Sopenharmony_ci#define		BERREN		0x00000008ul
58162306a36Sopenharmony_ci#define		DACEN		0x00000004ul
58262306a36Sopenharmony_ci#define		STPWLEVEL	0x00000002ul
58362306a36Sopenharmony_ci#define		DIFACTNEGEN	0x00000001ul	/* aic7870 only */
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci#define	CSIZE_LATTIME		0x0c
58662306a36Sopenharmony_ci#define		CACHESIZE	0x0000003ful	/* only 5 bits */
58762306a36Sopenharmony_ci#define		LATTIME		0x0000ff00ul
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci/* PCI STATUS definitions */
59062306a36Sopenharmony_ci#define	DPE	0x80
59162306a36Sopenharmony_ci#define SSE	0x40
59262306a36Sopenharmony_ci#define	RMA	0x20
59362306a36Sopenharmony_ci#define	RTA	0x10
59462306a36Sopenharmony_ci#define STA	0x08
59562306a36Sopenharmony_ci#define DPR	0x01
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_cistatic int ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor,
59862306a36Sopenharmony_ci				     uint16_t subdevice, uint16_t subvendor);
59962306a36Sopenharmony_cistatic int ahc_ext_scbram_present(struct ahc_softc *ahc);
60062306a36Sopenharmony_cistatic void ahc_scbram_config(struct ahc_softc *ahc, int enable,
60162306a36Sopenharmony_ci				  int pcheck, int fast, int large);
60262306a36Sopenharmony_cistatic void ahc_probe_ext_scbram(struct ahc_softc *ahc);
60362306a36Sopenharmony_cistatic void check_extport(struct ahc_softc *ahc, u_int *sxfrctl1);
60462306a36Sopenharmony_cistatic void ahc_parse_pci_eeprom(struct ahc_softc *ahc,
60562306a36Sopenharmony_ci				 struct seeprom_config *sc);
60662306a36Sopenharmony_cistatic void configure_termination(struct ahc_softc *ahc,
60762306a36Sopenharmony_ci				  struct seeprom_descriptor *sd,
60862306a36Sopenharmony_ci				  u_int adapter_control,
60962306a36Sopenharmony_ci	 			  u_int *sxfrctl1);
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_cistatic void ahc_new_term_detect(struct ahc_softc *ahc,
61262306a36Sopenharmony_ci				int *enableSEC_low,
61362306a36Sopenharmony_ci				int *enableSEC_high,
61462306a36Sopenharmony_ci				int *enablePRI_low,
61562306a36Sopenharmony_ci				int *enablePRI_high,
61662306a36Sopenharmony_ci				int *eeprom_present);
61762306a36Sopenharmony_cistatic void aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
61862306a36Sopenharmony_ci				 int *internal68_present,
61962306a36Sopenharmony_ci				 int *externalcable_present,
62062306a36Sopenharmony_ci				 int *eeprom_present);
62162306a36Sopenharmony_cistatic void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
62262306a36Sopenharmony_ci				 int *externalcable_present,
62362306a36Sopenharmony_ci				 int *eeprom_present);
62462306a36Sopenharmony_cistatic void    write_brdctl(struct ahc_softc *ahc, uint8_t value);
62562306a36Sopenharmony_cistatic uint8_t read_brdctl(struct ahc_softc *ahc);
62662306a36Sopenharmony_cistatic void ahc_pci_intr(struct ahc_softc *ahc);
62762306a36Sopenharmony_cistatic int  ahc_pci_chip_init(struct ahc_softc *ahc);
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_cistatic int
63062306a36Sopenharmony_ciahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor,
63162306a36Sopenharmony_ci			  uint16_t subdevice, uint16_t subvendor)
63262306a36Sopenharmony_ci{
63362306a36Sopenharmony_ci	int result;
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci	/* Default to invalid. */
63662306a36Sopenharmony_ci	result = 0;
63762306a36Sopenharmony_ci	if (vendor == 0x9005
63862306a36Sopenharmony_ci	 && subvendor == 0x9005
63962306a36Sopenharmony_ci         && subdevice != device
64062306a36Sopenharmony_ci         && SUBID_9005_TYPE_KNOWN(subdevice) != 0) {
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci		switch (SUBID_9005_TYPE(subdevice)) {
64362306a36Sopenharmony_ci		case SUBID_9005_TYPE_MB:
64462306a36Sopenharmony_ci			break;
64562306a36Sopenharmony_ci		case SUBID_9005_TYPE_CARD:
64662306a36Sopenharmony_ci		case SUBID_9005_TYPE_LCCARD:
64762306a36Sopenharmony_ci			/*
64862306a36Sopenharmony_ci			 * Currently only trust Adaptec cards to
64962306a36Sopenharmony_ci			 * get the sub device info correct.
65062306a36Sopenharmony_ci			 */
65162306a36Sopenharmony_ci			if (DEVID_9005_TYPE(device) == DEVID_9005_TYPE_HBA)
65262306a36Sopenharmony_ci				result = 1;
65362306a36Sopenharmony_ci			break;
65462306a36Sopenharmony_ci		case SUBID_9005_TYPE_RAID:
65562306a36Sopenharmony_ci			break;
65662306a36Sopenharmony_ci		default:
65762306a36Sopenharmony_ci			break;
65862306a36Sopenharmony_ci		}
65962306a36Sopenharmony_ci	}
66062306a36Sopenharmony_ci	return (result);
66162306a36Sopenharmony_ci}
66262306a36Sopenharmony_ci
66362306a36Sopenharmony_ciconst struct ahc_pci_identity *
66462306a36Sopenharmony_ciahc_find_pci_device(ahc_dev_softc_t pci)
66562306a36Sopenharmony_ci{
66662306a36Sopenharmony_ci	uint64_t  full_id;
66762306a36Sopenharmony_ci	uint16_t  device;
66862306a36Sopenharmony_ci	uint16_t  vendor;
66962306a36Sopenharmony_ci	uint16_t  subdevice;
67062306a36Sopenharmony_ci	uint16_t  subvendor;
67162306a36Sopenharmony_ci	const struct ahc_pci_identity *entry;
67262306a36Sopenharmony_ci	u_int	  i;
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_ci	vendor = ahc_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
67562306a36Sopenharmony_ci	device = ahc_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
67662306a36Sopenharmony_ci	subvendor = ahc_pci_read_config(pci, PCI_SUBSYSTEM_VENDOR_ID, /*bytes*/2);
67762306a36Sopenharmony_ci	subdevice = ahc_pci_read_config(pci, PCI_SUBSYSTEM_ID, /*bytes*/2);
67862306a36Sopenharmony_ci	full_id = ahc_compose_id(device, vendor, subdevice, subvendor);
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	/*
68162306a36Sopenharmony_ci	 * If the second function is not hooked up, ignore it.
68262306a36Sopenharmony_ci	 * Unfortunately, not all MB vendors implement the
68362306a36Sopenharmony_ci	 * subdevice ID as per the Adaptec spec, so do our best
68462306a36Sopenharmony_ci	 * to sanity check it prior to accepting the subdevice
68562306a36Sopenharmony_ci	 * ID as valid.
68662306a36Sopenharmony_ci	 */
68762306a36Sopenharmony_ci	if (ahc_get_pci_function(pci) > 0
68862306a36Sopenharmony_ci	 && ahc_9005_subdevinfo_valid(device, vendor, subdevice, subvendor)
68962306a36Sopenharmony_ci	 && SUBID_9005_MFUNCENB(subdevice) == 0)
69062306a36Sopenharmony_ci		return (NULL);
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	for (i = 0; i < ahc_num_pci_devs; i++) {
69362306a36Sopenharmony_ci		entry = &ahc_pci_ident_table[i];
69462306a36Sopenharmony_ci		if (entry->full_id == (full_id & entry->id_mask)) {
69562306a36Sopenharmony_ci			/* Honor exclusion entries. */
69662306a36Sopenharmony_ci			if (entry->name == NULL)
69762306a36Sopenharmony_ci				return (NULL);
69862306a36Sopenharmony_ci			return (entry);
69962306a36Sopenharmony_ci		}
70062306a36Sopenharmony_ci	}
70162306a36Sopenharmony_ci	return (NULL);
70262306a36Sopenharmony_ci}
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_ciint
70562306a36Sopenharmony_ciahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
70662306a36Sopenharmony_ci{
70762306a36Sopenharmony_ci	u_int	 command;
70862306a36Sopenharmony_ci	u_int	 our_id;
70962306a36Sopenharmony_ci	u_int	 sxfrctl1;
71062306a36Sopenharmony_ci	u_int	 scsiseq;
71162306a36Sopenharmony_ci	u_int	 dscommand0;
71262306a36Sopenharmony_ci	uint32_t devconfig;
71362306a36Sopenharmony_ci	int	 error;
71462306a36Sopenharmony_ci	uint8_t	 sblkctl;
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	our_id = 0;
71762306a36Sopenharmony_ci	error = entry->setup(ahc);
71862306a36Sopenharmony_ci	if (error != 0)
71962306a36Sopenharmony_ci		return (error);
72062306a36Sopenharmony_ci	ahc->chip |= AHC_PCI;
72162306a36Sopenharmony_ci	ahc->description = entry->name;
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci	pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);
72462306a36Sopenharmony_ci
72562306a36Sopenharmony_ci	error = ahc_pci_map_registers(ahc);
72662306a36Sopenharmony_ci	if (error != 0)
72762306a36Sopenharmony_ci		return (error);
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci	/*
73062306a36Sopenharmony_ci	 * Before we continue probing the card, ensure that
73162306a36Sopenharmony_ci	 * its interrupts are *disabled*.  We don't want
73262306a36Sopenharmony_ci	 * a misstep to hang the machine in an interrupt
73362306a36Sopenharmony_ci	 * storm.
73462306a36Sopenharmony_ci	 */
73562306a36Sopenharmony_ci	ahc_intr_enable(ahc, FALSE);
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci	/*
74062306a36Sopenharmony_ci	 * If we need to support high memory, enable dual
74162306a36Sopenharmony_ci	 * address cycles.  This bit must be set to enable
74262306a36Sopenharmony_ci	 * high address bit generation even if we are on a
74362306a36Sopenharmony_ci	 * 64bit bus (PCI64BIT set in devconfig).
74462306a36Sopenharmony_ci	 */
74562306a36Sopenharmony_ci	if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
74662306a36Sopenharmony_ci
74762306a36Sopenharmony_ci		if (bootverbose)
74862306a36Sopenharmony_ci			printk("%s: Enabling 39Bit Addressing\n",
74962306a36Sopenharmony_ci			       ahc_name(ahc));
75062306a36Sopenharmony_ci		devconfig |= DACEN;
75162306a36Sopenharmony_ci	}
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci	/* Ensure that pci error generation, a test feature, is disabled. */
75462306a36Sopenharmony_ci	devconfig |= PCIERRGENDIS;
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci	ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci	/* Ensure busmastering is enabled */
75962306a36Sopenharmony_ci	command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
76062306a36Sopenharmony_ci	command |= PCIM_CMD_BUSMASTEREN;
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_ci	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci	/* On all PCI adapters, we allow SCB paging */
76562306a36Sopenharmony_ci	ahc->flags |= AHC_PAGESCBS;
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ci	error = ahc_softc_init(ahc);
76862306a36Sopenharmony_ci	if (error != 0)
76962306a36Sopenharmony_ci		return (error);
77062306a36Sopenharmony_ci
77162306a36Sopenharmony_ci	/*
77262306a36Sopenharmony_ci	 * Disable PCI parity error checking.  Users typically
77362306a36Sopenharmony_ci	 * do this to work around broken PCI chipsets that get
77462306a36Sopenharmony_ci	 * the parity timing wrong and thus generate lots of spurious
77562306a36Sopenharmony_ci	 * errors.  The chip only allows us to disable *all* parity
77662306a36Sopenharmony_ci	 * error reporting when doing this, so CIO bus, scb ram, and
77762306a36Sopenharmony_ci	 * scratch ram parity errors will be ignored too.
77862306a36Sopenharmony_ci	 */
77962306a36Sopenharmony_ci	if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0)
78062306a36Sopenharmony_ci		ahc->seqctl |= FAILDIS;
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci	ahc->bus_intr = ahc_pci_intr;
78362306a36Sopenharmony_ci	ahc->bus_chip_init = ahc_pci_chip_init;
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci	/* Remember how the card was setup in case there is no SEEPROM */
78662306a36Sopenharmony_ci	if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) {
78762306a36Sopenharmony_ci		ahc_pause(ahc);
78862306a36Sopenharmony_ci		if ((ahc->features & AHC_ULTRA2) != 0)
78962306a36Sopenharmony_ci			our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
79062306a36Sopenharmony_ci		else
79162306a36Sopenharmony_ci			our_id = ahc_inb(ahc, SCSIID) & OID;
79262306a36Sopenharmony_ci		sxfrctl1 = ahc_inb(ahc, SXFRCTL1) & STPWEN;
79362306a36Sopenharmony_ci		scsiseq = ahc_inb(ahc, SCSISEQ);
79462306a36Sopenharmony_ci	} else {
79562306a36Sopenharmony_ci		sxfrctl1 = STPWEN;
79662306a36Sopenharmony_ci		our_id = 7;
79762306a36Sopenharmony_ci		scsiseq = 0;
79862306a36Sopenharmony_ci	}
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_ci	error = ahc_reset(ahc, /*reinit*/FALSE);
80162306a36Sopenharmony_ci	if (error != 0)
80262306a36Sopenharmony_ci		return (ENXIO);
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	if ((ahc->features & AHC_DT) != 0) {
80562306a36Sopenharmony_ci		u_int sfunct;
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci		/* Perform ALT-Mode Setup */
80862306a36Sopenharmony_ci		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
80962306a36Sopenharmony_ci		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
81062306a36Sopenharmony_ci		ahc_outb(ahc, OPTIONMODE,
81162306a36Sopenharmony_ci			 OPTIONMODE_DEFAULTS|AUTOACKEN|BUSFREEREV|EXPPHASEDIS);
81262306a36Sopenharmony_ci		ahc_outb(ahc, SFUNCT, sfunct);
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci		/* Normal mode setup */
81562306a36Sopenharmony_ci		ahc_outb(ahc, CRCCONTROL1, CRCVALCHKEN|CRCENDCHKEN|CRCREQCHKEN
81662306a36Sopenharmony_ci					  |TARGCRCENDEN);
81762306a36Sopenharmony_ci	}
81862306a36Sopenharmony_ci
81962306a36Sopenharmony_ci	dscommand0 = ahc_inb(ahc, DSCOMMAND0);
82062306a36Sopenharmony_ci	dscommand0 |= MPARCKEN|CACHETHEN;
82162306a36Sopenharmony_ci	if ((ahc->features & AHC_ULTRA2) != 0) {
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ci		/*
82462306a36Sopenharmony_ci		 * DPARCKEN doesn't work correctly on
82562306a36Sopenharmony_ci		 * some MBs so don't use it.
82662306a36Sopenharmony_ci		 */
82762306a36Sopenharmony_ci		dscommand0 &= ~DPARCKEN;
82862306a36Sopenharmony_ci	}
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci	/*
83162306a36Sopenharmony_ci	 * Handle chips that must have cache line
83262306a36Sopenharmony_ci	 * streaming (dis/en)abled.
83362306a36Sopenharmony_ci	 */
83462306a36Sopenharmony_ci	if ((ahc->bugs & AHC_CACHETHEN_DIS_BUG) != 0)
83562306a36Sopenharmony_ci		dscommand0 |= CACHETHEN;
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci	if ((ahc->bugs & AHC_CACHETHEN_BUG) != 0)
83862306a36Sopenharmony_ci		dscommand0 &= ~CACHETHEN;
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_ci	ahc_outb(ahc, DSCOMMAND0, dscommand0);
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci	ahc->pci_cachesize =
84362306a36Sopenharmony_ci	    ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME,
84462306a36Sopenharmony_ci				/*bytes*/1) & CACHESIZE;
84562306a36Sopenharmony_ci	ahc->pci_cachesize *= 4;
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci	if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0
84862306a36Sopenharmony_ci	 && ahc->pci_cachesize == 4) {
84962306a36Sopenharmony_ci
85062306a36Sopenharmony_ci		ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME,
85162306a36Sopenharmony_ci				     0, /*bytes*/1);
85262306a36Sopenharmony_ci		ahc->pci_cachesize = 0;
85362306a36Sopenharmony_ci	}
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_ci	/*
85662306a36Sopenharmony_ci	 * We cannot perform ULTRA speeds without the presence
85762306a36Sopenharmony_ci	 * of the external precision resistor.
85862306a36Sopenharmony_ci	 */
85962306a36Sopenharmony_ci	if ((ahc->features & AHC_ULTRA) != 0) {
86062306a36Sopenharmony_ci		uint32_t devconfig;
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ci		devconfig = ahc_pci_read_config(ahc->dev_softc,
86362306a36Sopenharmony_ci						DEVCONFIG, /*bytes*/4);
86462306a36Sopenharmony_ci		if ((devconfig & REXTVALID) == 0)
86562306a36Sopenharmony_ci			ahc->features &= ~AHC_ULTRA;
86662306a36Sopenharmony_ci	}
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci	/* See if we have a SEEPROM and perform auto-term */
86962306a36Sopenharmony_ci	check_extport(ahc, &sxfrctl1);
87062306a36Sopenharmony_ci
87162306a36Sopenharmony_ci	/*
87262306a36Sopenharmony_ci	 * Take the LED out of diagnostic mode
87362306a36Sopenharmony_ci	 */
87462306a36Sopenharmony_ci	sblkctl = ahc_inb(ahc, SBLKCTL);
87562306a36Sopenharmony_ci	ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci	if ((ahc->features & AHC_ULTRA2) != 0) {
87862306a36Sopenharmony_ci		ahc_outb(ahc, DFF_THRSH, RD_DFTHRSH_MAX|WR_DFTHRSH_MAX);
87962306a36Sopenharmony_ci	} else {
88062306a36Sopenharmony_ci		ahc_outb(ahc, DSPCISTATUS, DFTHRSH_100);
88162306a36Sopenharmony_ci	}
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci	if (ahc->flags & AHC_USEDEFAULTS) {
88462306a36Sopenharmony_ci		/*
88562306a36Sopenharmony_ci		 * PCI Adapter default setup
88662306a36Sopenharmony_ci		 * Should only be used if the adapter does not have
88762306a36Sopenharmony_ci		 * a SEEPROM.
88862306a36Sopenharmony_ci		 */
88962306a36Sopenharmony_ci		/* See if someone else set us up already */
89062306a36Sopenharmony_ci		if ((ahc->flags & AHC_NO_BIOS_INIT) == 0
89162306a36Sopenharmony_ci		 && scsiseq != 0) {
89262306a36Sopenharmony_ci			printk("%s: Using left over BIOS settings\n",
89362306a36Sopenharmony_ci				ahc_name(ahc));
89462306a36Sopenharmony_ci			ahc->flags &= ~AHC_USEDEFAULTS;
89562306a36Sopenharmony_ci			ahc->flags |= AHC_BIOS_ENABLED;
89662306a36Sopenharmony_ci		} else {
89762306a36Sopenharmony_ci			/*
89862306a36Sopenharmony_ci			 * Assume only one connector and always turn
89962306a36Sopenharmony_ci			 * on termination.
90062306a36Sopenharmony_ci			 */
90162306a36Sopenharmony_ci 			our_id = 0x07;
90262306a36Sopenharmony_ci			sxfrctl1 = STPWEN;
90362306a36Sopenharmony_ci		}
90462306a36Sopenharmony_ci		ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI);
90562306a36Sopenharmony_ci
90662306a36Sopenharmony_ci		ahc->our_id = our_id;
90762306a36Sopenharmony_ci	}
90862306a36Sopenharmony_ci
90962306a36Sopenharmony_ci	/*
91062306a36Sopenharmony_ci	 * Take a look to see if we have external SRAM.
91162306a36Sopenharmony_ci	 * We currently do not attempt to use SRAM that is
91262306a36Sopenharmony_ci	 * shared among multiple controllers.
91362306a36Sopenharmony_ci	 */
91462306a36Sopenharmony_ci	ahc_probe_ext_scbram(ahc);
91562306a36Sopenharmony_ci
91662306a36Sopenharmony_ci	/*
91762306a36Sopenharmony_ci	 * Record our termination setting for the
91862306a36Sopenharmony_ci	 * generic initialization routine.
91962306a36Sopenharmony_ci	 */
92062306a36Sopenharmony_ci	if ((sxfrctl1 & STPWEN) != 0)
92162306a36Sopenharmony_ci		ahc->flags |= AHC_TERM_ENB_A;
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_ci	/*
92462306a36Sopenharmony_ci	 * Save chip register configuration data for chip resets
92562306a36Sopenharmony_ci	 * that occur during runtime and resume events.
92662306a36Sopenharmony_ci	 */
92762306a36Sopenharmony_ci	ahc->bus_softc.pci_softc.devconfig =
92862306a36Sopenharmony_ci	    ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
92962306a36Sopenharmony_ci	ahc->bus_softc.pci_softc.command =
93062306a36Sopenharmony_ci	    ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1);
93162306a36Sopenharmony_ci	ahc->bus_softc.pci_softc.csize_lattime =
93262306a36Sopenharmony_ci	    ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1);
93362306a36Sopenharmony_ci	ahc->bus_softc.pci_softc.dscommand0 = ahc_inb(ahc, DSCOMMAND0);
93462306a36Sopenharmony_ci	ahc->bus_softc.pci_softc.dspcistatus = ahc_inb(ahc, DSPCISTATUS);
93562306a36Sopenharmony_ci	if ((ahc->features & AHC_DT) != 0) {
93662306a36Sopenharmony_ci		u_int sfunct;
93762306a36Sopenharmony_ci
93862306a36Sopenharmony_ci		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
93962306a36Sopenharmony_ci		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
94062306a36Sopenharmony_ci		ahc->bus_softc.pci_softc.optionmode = ahc_inb(ahc, OPTIONMODE);
94162306a36Sopenharmony_ci		ahc->bus_softc.pci_softc.targcrccnt = ahc_inw(ahc, TARGCRCCNT);
94262306a36Sopenharmony_ci		ahc_outb(ahc, SFUNCT, sfunct);
94362306a36Sopenharmony_ci		ahc->bus_softc.pci_softc.crccontrol1 =
94462306a36Sopenharmony_ci		    ahc_inb(ahc, CRCCONTROL1);
94562306a36Sopenharmony_ci	}
94662306a36Sopenharmony_ci	if ((ahc->features & AHC_MULTI_FUNC) != 0)
94762306a36Sopenharmony_ci		ahc->bus_softc.pci_softc.scbbaddr = ahc_inb(ahc, SCBBADDR);
94862306a36Sopenharmony_ci
94962306a36Sopenharmony_ci	if ((ahc->features & AHC_ULTRA2) != 0)
95062306a36Sopenharmony_ci		ahc->bus_softc.pci_softc.dff_thrsh = ahc_inb(ahc, DFF_THRSH);
95162306a36Sopenharmony_ci
95262306a36Sopenharmony_ci	/* Core initialization */
95362306a36Sopenharmony_ci	error = ahc_init(ahc);
95462306a36Sopenharmony_ci	if (error != 0)
95562306a36Sopenharmony_ci		return (error);
95662306a36Sopenharmony_ci	ahc->init_level++;
95762306a36Sopenharmony_ci
95862306a36Sopenharmony_ci	/*
95962306a36Sopenharmony_ci	 * Allow interrupts now that we are completely setup.
96062306a36Sopenharmony_ci	 */
96162306a36Sopenharmony_ci	return ahc_pci_map_int(ahc);
96262306a36Sopenharmony_ci}
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci/*
96562306a36Sopenharmony_ci * Test for the presence of external sram in an
96662306a36Sopenharmony_ci * "unshared" configuration.
96762306a36Sopenharmony_ci */
96862306a36Sopenharmony_cistatic int
96962306a36Sopenharmony_ciahc_ext_scbram_present(struct ahc_softc *ahc)
97062306a36Sopenharmony_ci{
97162306a36Sopenharmony_ci	u_int chip;
97262306a36Sopenharmony_ci	int ramps;
97362306a36Sopenharmony_ci	int single_user;
97462306a36Sopenharmony_ci	uint32_t devconfig;
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci	chip = ahc->chip & AHC_CHIPID_MASK;
97762306a36Sopenharmony_ci	devconfig = ahc_pci_read_config(ahc->dev_softc,
97862306a36Sopenharmony_ci					DEVCONFIG, /*bytes*/4);
97962306a36Sopenharmony_ci	single_user = (devconfig & MPORTMODE) != 0;
98062306a36Sopenharmony_ci
98162306a36Sopenharmony_ci	if ((ahc->features & AHC_ULTRA2) != 0)
98262306a36Sopenharmony_ci		ramps = (ahc_inb(ahc, DSCOMMAND0) & RAMPS) != 0;
98362306a36Sopenharmony_ci	else if (chip == AHC_AIC7895 || chip == AHC_AIC7895C)
98462306a36Sopenharmony_ci		/*
98562306a36Sopenharmony_ci		 * External SCBRAM arbitration is flakey
98662306a36Sopenharmony_ci		 * on these chips.  Unfortunately this means
98762306a36Sopenharmony_ci		 * we don't use the extra SCB ram space on the
98862306a36Sopenharmony_ci		 * 3940AUW.
98962306a36Sopenharmony_ci		 */
99062306a36Sopenharmony_ci		ramps = 0;
99162306a36Sopenharmony_ci	else if (chip >= AHC_AIC7870)
99262306a36Sopenharmony_ci		ramps = (devconfig & RAMPSM) != 0;
99362306a36Sopenharmony_ci	else
99462306a36Sopenharmony_ci		ramps = 0;
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci	if (ramps && single_user)
99762306a36Sopenharmony_ci		return (1);
99862306a36Sopenharmony_ci	return (0);
99962306a36Sopenharmony_ci}
100062306a36Sopenharmony_ci
100162306a36Sopenharmony_ci/*
100262306a36Sopenharmony_ci * Enable external scbram.
100362306a36Sopenharmony_ci */
100462306a36Sopenharmony_cistatic void
100562306a36Sopenharmony_ciahc_scbram_config(struct ahc_softc *ahc, int enable, int pcheck,
100662306a36Sopenharmony_ci		  int fast, int large)
100762306a36Sopenharmony_ci{
100862306a36Sopenharmony_ci	uint32_t devconfig;
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci	if (ahc->features & AHC_MULTI_FUNC) {
101162306a36Sopenharmony_ci		/*
101262306a36Sopenharmony_ci		 * Set the SCB Base addr (highest address bit)
101362306a36Sopenharmony_ci		 * depending on which channel we are.
101462306a36Sopenharmony_ci		 */
101562306a36Sopenharmony_ci		ahc_outb(ahc, SCBBADDR, ahc_get_pci_function(ahc->dev_softc));
101662306a36Sopenharmony_ci	}
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_ci	ahc->flags &= ~AHC_LSCBS_ENABLED;
101962306a36Sopenharmony_ci	if (large)
102062306a36Sopenharmony_ci		ahc->flags |= AHC_LSCBS_ENABLED;
102162306a36Sopenharmony_ci	devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
102262306a36Sopenharmony_ci	if ((ahc->features & AHC_ULTRA2) != 0) {
102362306a36Sopenharmony_ci		u_int dscommand0;
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_ci		dscommand0 = ahc_inb(ahc, DSCOMMAND0);
102662306a36Sopenharmony_ci		if (enable)
102762306a36Sopenharmony_ci			dscommand0 &= ~INTSCBRAMSEL;
102862306a36Sopenharmony_ci		else
102962306a36Sopenharmony_ci			dscommand0 |= INTSCBRAMSEL;
103062306a36Sopenharmony_ci		if (large)
103162306a36Sopenharmony_ci			dscommand0 &= ~USCBSIZE32;
103262306a36Sopenharmony_ci		else
103362306a36Sopenharmony_ci			dscommand0 |= USCBSIZE32;
103462306a36Sopenharmony_ci		ahc_outb(ahc, DSCOMMAND0, dscommand0);
103562306a36Sopenharmony_ci	} else {
103662306a36Sopenharmony_ci		if (fast)
103762306a36Sopenharmony_ci			devconfig &= ~EXTSCBTIME;
103862306a36Sopenharmony_ci		else
103962306a36Sopenharmony_ci			devconfig |= EXTSCBTIME;
104062306a36Sopenharmony_ci		if (enable)
104162306a36Sopenharmony_ci			devconfig &= ~SCBRAMSEL;
104262306a36Sopenharmony_ci		else
104362306a36Sopenharmony_ci			devconfig |= SCBRAMSEL;
104462306a36Sopenharmony_ci		if (large)
104562306a36Sopenharmony_ci			devconfig &= ~SCBSIZE32;
104662306a36Sopenharmony_ci		else
104762306a36Sopenharmony_ci			devconfig |= SCBSIZE32;
104862306a36Sopenharmony_ci	}
104962306a36Sopenharmony_ci	if (pcheck)
105062306a36Sopenharmony_ci		devconfig |= EXTSCBPEN;
105162306a36Sopenharmony_ci	else
105262306a36Sopenharmony_ci		devconfig &= ~EXTSCBPEN;
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_ci	ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
105562306a36Sopenharmony_ci}
105662306a36Sopenharmony_ci
105762306a36Sopenharmony_ci/*
105862306a36Sopenharmony_ci * Take a look to see if we have external SRAM.
105962306a36Sopenharmony_ci * We currently do not attempt to use SRAM that is
106062306a36Sopenharmony_ci * shared among multiple controllers.
106162306a36Sopenharmony_ci */
106262306a36Sopenharmony_cistatic void
106362306a36Sopenharmony_ciahc_probe_ext_scbram(struct ahc_softc *ahc)
106462306a36Sopenharmony_ci{
106562306a36Sopenharmony_ci	int num_scbs;
106662306a36Sopenharmony_ci	int test_num_scbs;
106762306a36Sopenharmony_ci	int enable;
106862306a36Sopenharmony_ci	int pcheck;
106962306a36Sopenharmony_ci	int fast;
107062306a36Sopenharmony_ci	int large;
107162306a36Sopenharmony_ci
107262306a36Sopenharmony_ci	enable = FALSE;
107362306a36Sopenharmony_ci	pcheck = FALSE;
107462306a36Sopenharmony_ci	fast = FALSE;
107562306a36Sopenharmony_ci	large = FALSE;
107662306a36Sopenharmony_ci	num_scbs = 0;
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_ci	if (ahc_ext_scbram_present(ahc) == 0)
107962306a36Sopenharmony_ci		goto done;
108062306a36Sopenharmony_ci
108162306a36Sopenharmony_ci	/*
108262306a36Sopenharmony_ci	 * Probe for the best parameters to use.
108362306a36Sopenharmony_ci	 */
108462306a36Sopenharmony_ci	ahc_scbram_config(ahc, /*enable*/TRUE, pcheck, fast, large);
108562306a36Sopenharmony_ci	num_scbs = ahc_probe_scbs(ahc);
108662306a36Sopenharmony_ci	if (num_scbs == 0) {
108762306a36Sopenharmony_ci		/* The SRAM wasn't really present. */
108862306a36Sopenharmony_ci		goto done;
108962306a36Sopenharmony_ci	}
109062306a36Sopenharmony_ci	enable = TRUE;
109162306a36Sopenharmony_ci
109262306a36Sopenharmony_ci	/*
109362306a36Sopenharmony_ci	 * Clear any outstanding parity error
109462306a36Sopenharmony_ci	 * and ensure that parity error reporting
109562306a36Sopenharmony_ci	 * is enabled.
109662306a36Sopenharmony_ci	 */
109762306a36Sopenharmony_ci	ahc_outb(ahc, SEQCTL, 0);
109862306a36Sopenharmony_ci	ahc_outb(ahc, CLRINT, CLRPARERR);
109962306a36Sopenharmony_ci	ahc_outb(ahc, CLRINT, CLRBRKADRINT);
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_ci	/* Now see if we can do parity */
110262306a36Sopenharmony_ci	ahc_scbram_config(ahc, enable, /*pcheck*/TRUE, fast, large);
110362306a36Sopenharmony_ci	num_scbs = ahc_probe_scbs(ahc);
110462306a36Sopenharmony_ci	if ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0
110562306a36Sopenharmony_ci	 || (ahc_inb(ahc, ERROR) & MPARERR) == 0)
110662306a36Sopenharmony_ci		pcheck = TRUE;
110762306a36Sopenharmony_ci
110862306a36Sopenharmony_ci	/* Clear any resulting parity error */
110962306a36Sopenharmony_ci	ahc_outb(ahc, CLRINT, CLRPARERR);
111062306a36Sopenharmony_ci	ahc_outb(ahc, CLRINT, CLRBRKADRINT);
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_ci	/* Now see if we can do fast timing */
111362306a36Sopenharmony_ci	ahc_scbram_config(ahc, enable, pcheck, /*fast*/TRUE, large);
111462306a36Sopenharmony_ci	test_num_scbs = ahc_probe_scbs(ahc);
111562306a36Sopenharmony_ci	if (test_num_scbs == num_scbs
111662306a36Sopenharmony_ci	 && ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0
111762306a36Sopenharmony_ci	  || (ahc_inb(ahc, ERROR) & MPARERR) == 0))
111862306a36Sopenharmony_ci		fast = TRUE;
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci	/*
112162306a36Sopenharmony_ci	 * See if we can use large SCBs and still maintain
112262306a36Sopenharmony_ci	 * the same overall count of SCBs.
112362306a36Sopenharmony_ci	 */
112462306a36Sopenharmony_ci	if ((ahc->features & AHC_LARGE_SCBS) != 0) {
112562306a36Sopenharmony_ci		ahc_scbram_config(ahc, enable, pcheck, fast, /*large*/TRUE);
112662306a36Sopenharmony_ci		test_num_scbs = ahc_probe_scbs(ahc);
112762306a36Sopenharmony_ci		if (test_num_scbs >= num_scbs) {
112862306a36Sopenharmony_ci			large = TRUE;
112962306a36Sopenharmony_ci			num_scbs = test_num_scbs;
113062306a36Sopenharmony_ci	 		if (num_scbs >= 64) {
113162306a36Sopenharmony_ci				/*
113262306a36Sopenharmony_ci				 * We have enough space to move the
113362306a36Sopenharmony_ci				 * "busy targets table" into SCB space
113462306a36Sopenharmony_ci				 * and make it qualify all the way to the
113562306a36Sopenharmony_ci				 * lun level.
113662306a36Sopenharmony_ci				 */
113762306a36Sopenharmony_ci				ahc->flags |= AHC_SCB_BTT;
113862306a36Sopenharmony_ci			}
113962306a36Sopenharmony_ci		}
114062306a36Sopenharmony_ci	}
114162306a36Sopenharmony_cidone:
114262306a36Sopenharmony_ci	/*
114362306a36Sopenharmony_ci	 * Disable parity error reporting until we
114462306a36Sopenharmony_ci	 * can load instruction ram.
114562306a36Sopenharmony_ci	 */
114662306a36Sopenharmony_ci	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);
114762306a36Sopenharmony_ci	/* Clear any latched parity error */
114862306a36Sopenharmony_ci	ahc_outb(ahc, CLRINT, CLRPARERR);
114962306a36Sopenharmony_ci	ahc_outb(ahc, CLRINT, CLRBRKADRINT);
115062306a36Sopenharmony_ci	if (bootverbose && enable) {
115162306a36Sopenharmony_ci		printk("%s: External SRAM, %s access%s, %dbytes/SCB\n",
115262306a36Sopenharmony_ci		       ahc_name(ahc), fast ? "fast" : "slow",
115362306a36Sopenharmony_ci		       pcheck ? ", parity checking enabled" : "",
115462306a36Sopenharmony_ci		       large ? 64 : 32);
115562306a36Sopenharmony_ci	}
115662306a36Sopenharmony_ci	ahc_scbram_config(ahc, enable, pcheck, fast, large);
115762306a36Sopenharmony_ci}
115862306a36Sopenharmony_ci
115962306a36Sopenharmony_ci/*
116062306a36Sopenharmony_ci * Perform some simple tests that should catch situations where
116162306a36Sopenharmony_ci * our registers are invalidly mapped.
116262306a36Sopenharmony_ci */
116362306a36Sopenharmony_ciint
116462306a36Sopenharmony_ciahc_pci_test_register_access(struct ahc_softc *ahc)
116562306a36Sopenharmony_ci{
116662306a36Sopenharmony_ci	int	 error;
116762306a36Sopenharmony_ci	u_int	 status1;
116862306a36Sopenharmony_ci	uint32_t cmd;
116962306a36Sopenharmony_ci	uint8_t	 hcntrl;
117062306a36Sopenharmony_ci
117162306a36Sopenharmony_ci	error = EIO;
117262306a36Sopenharmony_ci
117362306a36Sopenharmony_ci	/*
117462306a36Sopenharmony_ci	 * Enable PCI error interrupt status, but suppress NMIs
117562306a36Sopenharmony_ci	 * generated by SERR raised due to target aborts.
117662306a36Sopenharmony_ci	 */
117762306a36Sopenharmony_ci	cmd = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
117862306a36Sopenharmony_ci	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
117962306a36Sopenharmony_ci			     cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
118062306a36Sopenharmony_ci
118162306a36Sopenharmony_ci	/*
118262306a36Sopenharmony_ci	 * First a simple test to see if any
118362306a36Sopenharmony_ci	 * registers can be read.  Reading
118462306a36Sopenharmony_ci	 * HCNTRL has no side effects and has
118562306a36Sopenharmony_ci	 * at least one bit that is guaranteed to
118662306a36Sopenharmony_ci	 * be zero so it is a good register to
118762306a36Sopenharmony_ci	 * use for this test.
118862306a36Sopenharmony_ci	 */
118962306a36Sopenharmony_ci	hcntrl = ahc_inb(ahc, HCNTRL);
119062306a36Sopenharmony_ci
119162306a36Sopenharmony_ci	if (hcntrl == 0xFF)
119262306a36Sopenharmony_ci		goto fail;
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_ci	if ((hcntrl & CHIPRST) != 0) {
119562306a36Sopenharmony_ci		/*
119662306a36Sopenharmony_ci		 * The chip has not been initialized since
119762306a36Sopenharmony_ci		 * PCI/EISA/VLB bus reset.  Don't trust
119862306a36Sopenharmony_ci		 * "left over BIOS data".
119962306a36Sopenharmony_ci		 */
120062306a36Sopenharmony_ci		ahc->flags |= AHC_NO_BIOS_INIT;
120162306a36Sopenharmony_ci	}
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci	/*
120462306a36Sopenharmony_ci	 * Next create a situation where write combining
120562306a36Sopenharmony_ci	 * or read prefetching could be initiated by the
120662306a36Sopenharmony_ci	 * CPU or host bridge.  Our device does not support
120762306a36Sopenharmony_ci	 * either, so look for data corruption and/or flagged
120862306a36Sopenharmony_ci	 * PCI errors.  First pause without causing another
120962306a36Sopenharmony_ci	 * chip reset.
121062306a36Sopenharmony_ci	 */
121162306a36Sopenharmony_ci	hcntrl &= ~CHIPRST;
121262306a36Sopenharmony_ci	ahc_outb(ahc, HCNTRL, hcntrl|PAUSE);
121362306a36Sopenharmony_ci	while (ahc_is_paused(ahc) == 0)
121462306a36Sopenharmony_ci		;
121562306a36Sopenharmony_ci
121662306a36Sopenharmony_ci	/* Clear any PCI errors that occurred before our driver attached. */
121762306a36Sopenharmony_ci	status1 = ahc_pci_read_config(ahc->dev_softc,
121862306a36Sopenharmony_ci				      PCIR_STATUS + 1, /*bytes*/1);
121962306a36Sopenharmony_ci	ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
122062306a36Sopenharmony_ci			     status1, /*bytes*/1);
122162306a36Sopenharmony_ci	ahc_outb(ahc, CLRINT, CLRPARERR);
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci	ahc_outb(ahc, SEQCTL, PERRORDIS);
122462306a36Sopenharmony_ci	ahc_outb(ahc, SCBPTR, 0);
122562306a36Sopenharmony_ci	ahc_outl(ahc, SCB_BASE, 0x5aa555aa);
122662306a36Sopenharmony_ci	if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa)
122762306a36Sopenharmony_ci		goto fail;
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci	status1 = ahc_pci_read_config(ahc->dev_softc,
123062306a36Sopenharmony_ci				      PCIR_STATUS + 1, /*bytes*/1);
123162306a36Sopenharmony_ci	if ((status1 & STA) != 0)
123262306a36Sopenharmony_ci		goto fail;
123362306a36Sopenharmony_ci
123462306a36Sopenharmony_ci	error = 0;
123562306a36Sopenharmony_ci
123662306a36Sopenharmony_cifail:
123762306a36Sopenharmony_ci	/* Silently clear any latched errors. */
123862306a36Sopenharmony_ci	status1 = ahc_pci_read_config(ahc->dev_softc,
123962306a36Sopenharmony_ci				      PCIR_STATUS + 1, /*bytes*/1);
124062306a36Sopenharmony_ci	ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
124162306a36Sopenharmony_ci			     status1, /*bytes*/1);
124262306a36Sopenharmony_ci	ahc_outb(ahc, CLRINT, CLRPARERR);
124362306a36Sopenharmony_ci	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);
124462306a36Sopenharmony_ci	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
124562306a36Sopenharmony_ci	return (error);
124662306a36Sopenharmony_ci}
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_ci/*
124962306a36Sopenharmony_ci * Check the external port logic for a serial eeprom
125062306a36Sopenharmony_ci * and termination/cable detection contrls.
125162306a36Sopenharmony_ci */
125262306a36Sopenharmony_cistatic void
125362306a36Sopenharmony_cicheck_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
125462306a36Sopenharmony_ci{
125562306a36Sopenharmony_ci	struct	seeprom_descriptor sd;
125662306a36Sopenharmony_ci	struct	seeprom_config *sc;
125762306a36Sopenharmony_ci	int	have_seeprom;
125862306a36Sopenharmony_ci	int	have_autoterm;
125962306a36Sopenharmony_ci
126062306a36Sopenharmony_ci	sd.sd_ahc = ahc;
126162306a36Sopenharmony_ci	sd.sd_control_offset = SEECTL;
126262306a36Sopenharmony_ci	sd.sd_status_offset = SEECTL;
126362306a36Sopenharmony_ci	sd.sd_dataout_offset = SEECTL;
126462306a36Sopenharmony_ci	sc = ahc->seep_config;
126562306a36Sopenharmony_ci
126662306a36Sopenharmony_ci	/*
126762306a36Sopenharmony_ci	 * For some multi-channel devices, the c46 is simply too
126862306a36Sopenharmony_ci	 * small to work.  For the other controller types, we can
126962306a36Sopenharmony_ci	 * get our information from either SEEPROM type.  Set the
127062306a36Sopenharmony_ci	 * type to start our probe with accordingly.
127162306a36Sopenharmony_ci	 */
127262306a36Sopenharmony_ci	if (ahc->flags & AHC_LARGE_SEEPROM)
127362306a36Sopenharmony_ci		sd.sd_chip = C56_66;
127462306a36Sopenharmony_ci	else
127562306a36Sopenharmony_ci		sd.sd_chip = C46;
127662306a36Sopenharmony_ci
127762306a36Sopenharmony_ci	sd.sd_MS = SEEMS;
127862306a36Sopenharmony_ci	sd.sd_RDY = SEERDY;
127962306a36Sopenharmony_ci	sd.sd_CS = SEECS;
128062306a36Sopenharmony_ci	sd.sd_CK = SEECK;
128162306a36Sopenharmony_ci	sd.sd_DO = SEEDO;
128262306a36Sopenharmony_ci	sd.sd_DI = SEEDI;
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci	have_seeprom = ahc_acquire_seeprom(ahc, &sd);
128562306a36Sopenharmony_ci	if (have_seeprom) {
128662306a36Sopenharmony_ci
128762306a36Sopenharmony_ci		if (bootverbose)
128862306a36Sopenharmony_ci			printk("%s: Reading SEEPROM...", ahc_name(ahc));
128962306a36Sopenharmony_ci
129062306a36Sopenharmony_ci		for (;;) {
129162306a36Sopenharmony_ci			u_int start_addr;
129262306a36Sopenharmony_ci
129362306a36Sopenharmony_ci			start_addr = 32 * (ahc->channel - 'A');
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci			have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc,
129662306a36Sopenharmony_ci							start_addr,
129762306a36Sopenharmony_ci							sizeof(*sc)/2);
129862306a36Sopenharmony_ci
129962306a36Sopenharmony_ci			if (have_seeprom)
130062306a36Sopenharmony_ci				have_seeprom = ahc_verify_cksum(sc);
130162306a36Sopenharmony_ci
130262306a36Sopenharmony_ci			if (have_seeprom != 0 || sd.sd_chip == C56_66) {
130362306a36Sopenharmony_ci				if (bootverbose) {
130462306a36Sopenharmony_ci					if (have_seeprom == 0)
130562306a36Sopenharmony_ci						printk ("checksum error\n");
130662306a36Sopenharmony_ci					else
130762306a36Sopenharmony_ci						printk ("done.\n");
130862306a36Sopenharmony_ci				}
130962306a36Sopenharmony_ci				break;
131062306a36Sopenharmony_ci			}
131162306a36Sopenharmony_ci			sd.sd_chip = C56_66;
131262306a36Sopenharmony_ci		}
131362306a36Sopenharmony_ci		ahc_release_seeprom(&sd);
131462306a36Sopenharmony_ci
131562306a36Sopenharmony_ci		/* Remember the SEEPROM type for later */
131662306a36Sopenharmony_ci		if (sd.sd_chip == C56_66)
131762306a36Sopenharmony_ci			ahc->flags |= AHC_LARGE_SEEPROM;
131862306a36Sopenharmony_ci	}
131962306a36Sopenharmony_ci
132062306a36Sopenharmony_ci	if (!have_seeprom) {
132162306a36Sopenharmony_ci		/*
132262306a36Sopenharmony_ci		 * Pull scratch ram settings and treat them as
132362306a36Sopenharmony_ci		 * if they are the contents of an seeprom if
132462306a36Sopenharmony_ci		 * the 'ADPT' signature is found in SCB2.
132562306a36Sopenharmony_ci		 * We manually compose the data as 16bit values
132662306a36Sopenharmony_ci		 * to avoid endian issues.
132762306a36Sopenharmony_ci		 */
132862306a36Sopenharmony_ci		ahc_outb(ahc, SCBPTR, 2);
132962306a36Sopenharmony_ci		if (ahc_inb(ahc, SCB_BASE) == 'A'
133062306a36Sopenharmony_ci		 && ahc_inb(ahc, SCB_BASE + 1) == 'D'
133162306a36Sopenharmony_ci		 && ahc_inb(ahc, SCB_BASE + 2) == 'P'
133262306a36Sopenharmony_ci		 && ahc_inb(ahc, SCB_BASE + 3) == 'T') {
133362306a36Sopenharmony_ci			uint16_t *sc_data;
133462306a36Sopenharmony_ci			int	  i;
133562306a36Sopenharmony_ci
133662306a36Sopenharmony_ci			sc_data = (uint16_t *)sc;
133762306a36Sopenharmony_ci			for (i = 0; i < 32; i++, sc_data++) {
133862306a36Sopenharmony_ci				int	j;
133962306a36Sopenharmony_ci
134062306a36Sopenharmony_ci				j = i * 2;
134162306a36Sopenharmony_ci				*sc_data = ahc_inb(ahc, SRAM_BASE + j)
134262306a36Sopenharmony_ci					 | ahc_inb(ahc, SRAM_BASE + j + 1) << 8;
134362306a36Sopenharmony_ci			}
134462306a36Sopenharmony_ci			have_seeprom = ahc_verify_cksum(sc);
134562306a36Sopenharmony_ci			if (have_seeprom)
134662306a36Sopenharmony_ci				ahc->flags |= AHC_SCB_CONFIG_USED;
134762306a36Sopenharmony_ci		}
134862306a36Sopenharmony_ci		/*
134962306a36Sopenharmony_ci		 * Clear any SCB parity errors in case this data and
135062306a36Sopenharmony_ci		 * its associated parity was not initialized by the BIOS
135162306a36Sopenharmony_ci		 */
135262306a36Sopenharmony_ci		ahc_outb(ahc, CLRINT, CLRPARERR);
135362306a36Sopenharmony_ci		ahc_outb(ahc, CLRINT, CLRBRKADRINT);
135462306a36Sopenharmony_ci	}
135562306a36Sopenharmony_ci
135662306a36Sopenharmony_ci	if (!have_seeprom) {
135762306a36Sopenharmony_ci		if (bootverbose)
135862306a36Sopenharmony_ci			printk("%s: No SEEPROM available.\n", ahc_name(ahc));
135962306a36Sopenharmony_ci		ahc->flags |= AHC_USEDEFAULTS;
136062306a36Sopenharmony_ci		kfree(ahc->seep_config);
136162306a36Sopenharmony_ci		ahc->seep_config = NULL;
136262306a36Sopenharmony_ci		sc = NULL;
136362306a36Sopenharmony_ci	} else {
136462306a36Sopenharmony_ci		ahc_parse_pci_eeprom(ahc, sc);
136562306a36Sopenharmony_ci	}
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_ci	/*
136862306a36Sopenharmony_ci	 * Cards that have the external logic necessary to talk to
136962306a36Sopenharmony_ci	 * a SEEPROM, are almost certain to have the remaining logic
137062306a36Sopenharmony_ci	 * necessary for auto-termination control.  This assumption
137162306a36Sopenharmony_ci	 * hasn't failed yet...
137262306a36Sopenharmony_ci	 */
137362306a36Sopenharmony_ci	have_autoterm = have_seeprom;
137462306a36Sopenharmony_ci
137562306a36Sopenharmony_ci	/*
137662306a36Sopenharmony_ci	 * Some low-cost chips have SEEPROM and auto-term control built
137762306a36Sopenharmony_ci	 * in, instead of using a GAL.  They can tell us directly
137862306a36Sopenharmony_ci	 * if the termination logic is enabled.
137962306a36Sopenharmony_ci	 */
138062306a36Sopenharmony_ci	if ((ahc->features & AHC_SPIOCAP) != 0) {
138162306a36Sopenharmony_ci		if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) == 0)
138262306a36Sopenharmony_ci			have_autoterm = FALSE;
138362306a36Sopenharmony_ci	}
138462306a36Sopenharmony_ci
138562306a36Sopenharmony_ci	if (have_autoterm) {
138662306a36Sopenharmony_ci		ahc->flags |= AHC_HAS_TERM_LOGIC;
138762306a36Sopenharmony_ci		ahc_acquire_seeprom(ahc, &sd);
138862306a36Sopenharmony_ci		configure_termination(ahc, &sd, sc->adapter_control, sxfrctl1);
138962306a36Sopenharmony_ci		ahc_release_seeprom(&sd);
139062306a36Sopenharmony_ci	} else if (have_seeprom) {
139162306a36Sopenharmony_ci		*sxfrctl1 &= ~STPWEN;
139262306a36Sopenharmony_ci		if ((sc->adapter_control & CFSTERM) != 0)
139362306a36Sopenharmony_ci			*sxfrctl1 |= STPWEN;
139462306a36Sopenharmony_ci		if (bootverbose)
139562306a36Sopenharmony_ci			printk("%s: Low byte termination %sabled\n",
139662306a36Sopenharmony_ci			       ahc_name(ahc),
139762306a36Sopenharmony_ci			       (*sxfrctl1 & STPWEN) ? "en" : "dis");
139862306a36Sopenharmony_ci	}
139962306a36Sopenharmony_ci}
140062306a36Sopenharmony_ci
140162306a36Sopenharmony_cistatic void
140262306a36Sopenharmony_ciahc_parse_pci_eeprom(struct ahc_softc *ahc, struct seeprom_config *sc)
140362306a36Sopenharmony_ci{
140462306a36Sopenharmony_ci	/*
140562306a36Sopenharmony_ci	 * Put the data we've collected down into SRAM
140662306a36Sopenharmony_ci	 * where ahc_init will find it.
140762306a36Sopenharmony_ci	 */
140862306a36Sopenharmony_ci	int	 i;
140962306a36Sopenharmony_ci	int	 max_targ = sc->max_targets & CFMAXTARG;
141062306a36Sopenharmony_ci	u_int	 scsi_conf;
141162306a36Sopenharmony_ci	uint16_t discenable;
141262306a36Sopenharmony_ci	uint16_t ultraenb;
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_ci	discenable = 0;
141562306a36Sopenharmony_ci	ultraenb = 0;
141662306a36Sopenharmony_ci	if ((sc->adapter_control & CFULTRAEN) != 0) {
141762306a36Sopenharmony_ci		/*
141862306a36Sopenharmony_ci		 * Determine if this adapter has a "newstyle"
141962306a36Sopenharmony_ci		 * SEEPROM format.
142062306a36Sopenharmony_ci		 */
142162306a36Sopenharmony_ci		for (i = 0; i < max_targ; i++) {
142262306a36Sopenharmony_ci			if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0) {
142362306a36Sopenharmony_ci				ahc->flags |= AHC_NEWEEPROM_FMT;
142462306a36Sopenharmony_ci				break;
142562306a36Sopenharmony_ci			}
142662306a36Sopenharmony_ci		}
142762306a36Sopenharmony_ci	}
142862306a36Sopenharmony_ci
142962306a36Sopenharmony_ci	for (i = 0; i < max_targ; i++) {
143062306a36Sopenharmony_ci		u_int     scsirate;
143162306a36Sopenharmony_ci		uint16_t target_mask;
143262306a36Sopenharmony_ci
143362306a36Sopenharmony_ci		target_mask = 0x01 << i;
143462306a36Sopenharmony_ci		if (sc->device_flags[i] & CFDISC)
143562306a36Sopenharmony_ci			discenable |= target_mask;
143662306a36Sopenharmony_ci		if ((ahc->flags & AHC_NEWEEPROM_FMT) != 0) {
143762306a36Sopenharmony_ci			if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0)
143862306a36Sopenharmony_ci				ultraenb |= target_mask;
143962306a36Sopenharmony_ci		} else if ((sc->adapter_control & CFULTRAEN) != 0) {
144062306a36Sopenharmony_ci			ultraenb |= target_mask;
144162306a36Sopenharmony_ci		}
144262306a36Sopenharmony_ci		if ((sc->device_flags[i] & CFXFER) == 0x04
144362306a36Sopenharmony_ci		 && (ultraenb & target_mask) != 0) {
144462306a36Sopenharmony_ci			/* Treat 10MHz as a non-ultra speed */
144562306a36Sopenharmony_ci			sc->device_flags[i] &= ~CFXFER;
144662306a36Sopenharmony_ci		 	ultraenb &= ~target_mask;
144762306a36Sopenharmony_ci		}
144862306a36Sopenharmony_ci		if ((ahc->features & AHC_ULTRA2) != 0) {
144962306a36Sopenharmony_ci			u_int offset;
145062306a36Sopenharmony_ci
145162306a36Sopenharmony_ci			if (sc->device_flags[i] & CFSYNCH)
145262306a36Sopenharmony_ci				offset = MAX_OFFSET_ULTRA2;
145362306a36Sopenharmony_ci			else
145462306a36Sopenharmony_ci				offset = 0;
145562306a36Sopenharmony_ci			ahc_outb(ahc, TARG_OFFSET + i, offset);
145662306a36Sopenharmony_ci
145762306a36Sopenharmony_ci			/*
145862306a36Sopenharmony_ci			 * The ultra enable bits contain the
145962306a36Sopenharmony_ci			 * high bit of the ultra2 sync rate
146062306a36Sopenharmony_ci			 * field.
146162306a36Sopenharmony_ci			 */
146262306a36Sopenharmony_ci			scsirate = (sc->device_flags[i] & CFXFER)
146362306a36Sopenharmony_ci				 | ((ultraenb & target_mask) ? 0x8 : 0x0);
146462306a36Sopenharmony_ci			if (sc->device_flags[i] & CFWIDEB)
146562306a36Sopenharmony_ci				scsirate |= WIDEXFER;
146662306a36Sopenharmony_ci		} else {
146762306a36Sopenharmony_ci			scsirate = (sc->device_flags[i] & CFXFER) << 4;
146862306a36Sopenharmony_ci			if (sc->device_flags[i] & CFSYNCH)
146962306a36Sopenharmony_ci				scsirate |= SOFS;
147062306a36Sopenharmony_ci			if (sc->device_flags[i] & CFWIDEB)
147162306a36Sopenharmony_ci				scsirate |= WIDEXFER;
147262306a36Sopenharmony_ci		}
147362306a36Sopenharmony_ci		ahc_outb(ahc, TARG_SCSIRATE + i, scsirate);
147462306a36Sopenharmony_ci	}
147562306a36Sopenharmony_ci	ahc->our_id = sc->brtime_id & CFSCSIID;
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_ci	scsi_conf = (ahc->our_id & 0x7);
147862306a36Sopenharmony_ci	if (sc->adapter_control & CFSPARITY)
147962306a36Sopenharmony_ci		scsi_conf |= ENSPCHK;
148062306a36Sopenharmony_ci	if (sc->adapter_control & CFRESETB)
148162306a36Sopenharmony_ci		scsi_conf |= RESET_SCSI;
148262306a36Sopenharmony_ci
148362306a36Sopenharmony_ci	ahc->flags |= (sc->adapter_control & CFBOOTCHAN) >> CFBOOTCHANSHIFT;
148462306a36Sopenharmony_ci
148562306a36Sopenharmony_ci	if (sc->bios_control & CFEXTEND)
148662306a36Sopenharmony_ci		ahc->flags |= AHC_EXTENDED_TRANS_A;
148762306a36Sopenharmony_ci
148862306a36Sopenharmony_ci	if (sc->bios_control & CFBIOSEN)
148962306a36Sopenharmony_ci		ahc->flags |= AHC_BIOS_ENABLED;
149062306a36Sopenharmony_ci	if (ahc->features & AHC_ULTRA
149162306a36Sopenharmony_ci	 && (ahc->flags & AHC_NEWEEPROM_FMT) == 0) {
149262306a36Sopenharmony_ci		/* Should we enable Ultra mode? */
149362306a36Sopenharmony_ci		if (!(sc->adapter_control & CFULTRAEN))
149462306a36Sopenharmony_ci			/* Treat us as a non-ultra card */
149562306a36Sopenharmony_ci			ultraenb = 0;
149662306a36Sopenharmony_ci	}
149762306a36Sopenharmony_ci
149862306a36Sopenharmony_ci	if (sc->signature == CFSIGNATURE
149962306a36Sopenharmony_ci	 || sc->signature == CFSIGNATURE2) {
150062306a36Sopenharmony_ci		uint32_t devconfig;
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci		/* Honor the STPWLEVEL settings */
150362306a36Sopenharmony_ci		devconfig = ahc_pci_read_config(ahc->dev_softc,
150462306a36Sopenharmony_ci						DEVCONFIG, /*bytes*/4);
150562306a36Sopenharmony_ci		devconfig &= ~STPWLEVEL;
150662306a36Sopenharmony_ci		if ((sc->bios_control & CFSTPWLEVEL) != 0)
150762306a36Sopenharmony_ci			devconfig |= STPWLEVEL;
150862306a36Sopenharmony_ci		ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
150962306a36Sopenharmony_ci				     devconfig, /*bytes*/4);
151062306a36Sopenharmony_ci	}
151162306a36Sopenharmony_ci	/* Set SCSICONF info */
151262306a36Sopenharmony_ci	ahc_outb(ahc, SCSICONF, scsi_conf);
151362306a36Sopenharmony_ci	ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
151462306a36Sopenharmony_ci	ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
151562306a36Sopenharmony_ci	ahc_outb(ahc, ULTRA_ENB, ultraenb & 0xff);
151662306a36Sopenharmony_ci	ahc_outb(ahc, ULTRA_ENB + 1, (ultraenb >> 8) & 0xff);
151762306a36Sopenharmony_ci}
151862306a36Sopenharmony_ci
151962306a36Sopenharmony_cistatic void
152062306a36Sopenharmony_ciconfigure_termination(struct ahc_softc *ahc,
152162306a36Sopenharmony_ci		      struct seeprom_descriptor *sd,
152262306a36Sopenharmony_ci		      u_int adapter_control,
152362306a36Sopenharmony_ci		      u_int *sxfrctl1)
152462306a36Sopenharmony_ci{
152562306a36Sopenharmony_ci	uint8_t brddat;
152662306a36Sopenharmony_ci
152762306a36Sopenharmony_ci	brddat = 0;
152862306a36Sopenharmony_ci
152962306a36Sopenharmony_ci	/*
153062306a36Sopenharmony_ci	 * Update the settings in sxfrctl1 to match the
153162306a36Sopenharmony_ci	 * termination settings
153262306a36Sopenharmony_ci	 */
153362306a36Sopenharmony_ci	*sxfrctl1 = 0;
153462306a36Sopenharmony_ci
153562306a36Sopenharmony_ci	/*
153662306a36Sopenharmony_ci	 * SEECS must be on for the GALS to latch
153762306a36Sopenharmony_ci	 * the data properly.  Be sure to leave MS
153862306a36Sopenharmony_ci	 * on or we will release the seeprom.
153962306a36Sopenharmony_ci	 */
154062306a36Sopenharmony_ci	SEEPROM_OUTB(sd, sd->sd_MS | sd->sd_CS);
154162306a36Sopenharmony_ci	if ((adapter_control & CFAUTOTERM) != 0
154262306a36Sopenharmony_ci	 || (ahc->features & AHC_NEW_TERMCTL) != 0) {
154362306a36Sopenharmony_ci		int internal50_present;
154462306a36Sopenharmony_ci		int internal68_present;
154562306a36Sopenharmony_ci		int externalcable_present;
154662306a36Sopenharmony_ci		int eeprom_present;
154762306a36Sopenharmony_ci		int enableSEC_low;
154862306a36Sopenharmony_ci		int enableSEC_high;
154962306a36Sopenharmony_ci		int enablePRI_low;
155062306a36Sopenharmony_ci		int enablePRI_high;
155162306a36Sopenharmony_ci		int sum;
155262306a36Sopenharmony_ci
155362306a36Sopenharmony_ci		enableSEC_low = 0;
155462306a36Sopenharmony_ci		enableSEC_high = 0;
155562306a36Sopenharmony_ci		enablePRI_low = 0;
155662306a36Sopenharmony_ci		enablePRI_high = 0;
155762306a36Sopenharmony_ci		if ((ahc->features & AHC_NEW_TERMCTL) != 0) {
155862306a36Sopenharmony_ci			ahc_new_term_detect(ahc, &enableSEC_low,
155962306a36Sopenharmony_ci					    &enableSEC_high,
156062306a36Sopenharmony_ci					    &enablePRI_low,
156162306a36Sopenharmony_ci					    &enablePRI_high,
156262306a36Sopenharmony_ci					    &eeprom_present);
156362306a36Sopenharmony_ci			if ((adapter_control & CFSEAUTOTERM) == 0) {
156462306a36Sopenharmony_ci				if (bootverbose)
156562306a36Sopenharmony_ci					printk("%s: Manual SE Termination\n",
156662306a36Sopenharmony_ci					       ahc_name(ahc));
156762306a36Sopenharmony_ci				enableSEC_low = (adapter_control & CFSELOWTERM);
156862306a36Sopenharmony_ci				enableSEC_high =
156962306a36Sopenharmony_ci				    (adapter_control & CFSEHIGHTERM);
157062306a36Sopenharmony_ci			}
157162306a36Sopenharmony_ci			if ((adapter_control & CFAUTOTERM) == 0) {
157262306a36Sopenharmony_ci				if (bootverbose)
157362306a36Sopenharmony_ci					printk("%s: Manual LVD Termination\n",
157462306a36Sopenharmony_ci					       ahc_name(ahc));
157562306a36Sopenharmony_ci				enablePRI_low = (adapter_control & CFSTERM);
157662306a36Sopenharmony_ci				enablePRI_high = (adapter_control & CFWSTERM);
157762306a36Sopenharmony_ci			}
157862306a36Sopenharmony_ci			/* Make the table calculations below happy */
157962306a36Sopenharmony_ci			internal50_present = 0;
158062306a36Sopenharmony_ci			internal68_present = 1;
158162306a36Sopenharmony_ci			externalcable_present = 1;
158262306a36Sopenharmony_ci		} else if ((ahc->features & AHC_SPIOCAP) != 0) {
158362306a36Sopenharmony_ci			aic785X_cable_detect(ahc, &internal50_present,
158462306a36Sopenharmony_ci					     &externalcable_present,
158562306a36Sopenharmony_ci					     &eeprom_present);
158662306a36Sopenharmony_ci			/* Can never support a wide connector. */
158762306a36Sopenharmony_ci			internal68_present = 0;
158862306a36Sopenharmony_ci		} else {
158962306a36Sopenharmony_ci			aic787X_cable_detect(ahc, &internal50_present,
159062306a36Sopenharmony_ci					     &internal68_present,
159162306a36Sopenharmony_ci					     &externalcable_present,
159262306a36Sopenharmony_ci					     &eeprom_present);
159362306a36Sopenharmony_ci		}
159462306a36Sopenharmony_ci
159562306a36Sopenharmony_ci		if ((ahc->features & AHC_WIDE) == 0)
159662306a36Sopenharmony_ci			internal68_present = 0;
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci		if (bootverbose
159962306a36Sopenharmony_ci		 && (ahc->features & AHC_ULTRA2) == 0) {
160062306a36Sopenharmony_ci			printk("%s: internal 50 cable %s present",
160162306a36Sopenharmony_ci			       ahc_name(ahc),
160262306a36Sopenharmony_ci			       internal50_present ? "is":"not");
160362306a36Sopenharmony_ci
160462306a36Sopenharmony_ci			if ((ahc->features & AHC_WIDE) != 0)
160562306a36Sopenharmony_ci				printk(", internal 68 cable %s present",
160662306a36Sopenharmony_ci				       internal68_present ? "is":"not");
160762306a36Sopenharmony_ci			printk("\n%s: external cable %s present\n",
160862306a36Sopenharmony_ci			       ahc_name(ahc),
160962306a36Sopenharmony_ci			       externalcable_present ? "is":"not");
161062306a36Sopenharmony_ci		}
161162306a36Sopenharmony_ci		if (bootverbose)
161262306a36Sopenharmony_ci			printk("%s: BIOS eeprom %s present\n",
161362306a36Sopenharmony_ci			       ahc_name(ahc), eeprom_present ? "is" : "not");
161462306a36Sopenharmony_ci
161562306a36Sopenharmony_ci		if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) {
161662306a36Sopenharmony_ci			/*
161762306a36Sopenharmony_ci			 * The 50 pin connector is a separate bus,
161862306a36Sopenharmony_ci			 * so force it to always be terminated.
161962306a36Sopenharmony_ci			 * In the future, perform current sensing
162062306a36Sopenharmony_ci			 * to determine if we are in the middle of
162162306a36Sopenharmony_ci			 * a properly terminated bus.
162262306a36Sopenharmony_ci			 */
162362306a36Sopenharmony_ci			internal50_present = 0;
162462306a36Sopenharmony_ci		}
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_ci		/*
162762306a36Sopenharmony_ci		 * Now set the termination based on what
162862306a36Sopenharmony_ci		 * we found.
162962306a36Sopenharmony_ci		 * Flash Enable = BRDDAT7
163062306a36Sopenharmony_ci		 * Secondary High Term Enable = BRDDAT6
163162306a36Sopenharmony_ci		 * Secondary Low Term Enable = BRDDAT5 (7890)
163262306a36Sopenharmony_ci		 * Primary High Term Enable = BRDDAT4 (7890)
163362306a36Sopenharmony_ci		 */
163462306a36Sopenharmony_ci		if ((ahc->features & AHC_ULTRA2) == 0
163562306a36Sopenharmony_ci		 && (internal50_present != 0)
163662306a36Sopenharmony_ci		 && (internal68_present != 0)
163762306a36Sopenharmony_ci		 && (externalcable_present != 0)) {
163862306a36Sopenharmony_ci			printk("%s: Illegal cable configuration!!. "
163962306a36Sopenharmony_ci			       "Only two connectors on the "
164062306a36Sopenharmony_ci			       "adapter may be used at a "
164162306a36Sopenharmony_ci			       "time!\n", ahc_name(ahc));
164262306a36Sopenharmony_ci
164362306a36Sopenharmony_ci			/*
164462306a36Sopenharmony_ci			 * Pretend there are no cables in the hope
164562306a36Sopenharmony_ci			 * that having all of the termination on
164662306a36Sopenharmony_ci			 * gives us a more stable bus.
164762306a36Sopenharmony_ci			 */
164862306a36Sopenharmony_ci		 	internal50_present = 0;
164962306a36Sopenharmony_ci			internal68_present = 0;
165062306a36Sopenharmony_ci			externalcable_present = 0;
165162306a36Sopenharmony_ci		}
165262306a36Sopenharmony_ci
165362306a36Sopenharmony_ci		if ((ahc->features & AHC_WIDE) != 0
165462306a36Sopenharmony_ci		 && ((externalcable_present == 0)
165562306a36Sopenharmony_ci		  || (internal68_present == 0)
165662306a36Sopenharmony_ci		  || (enableSEC_high != 0))) {
165762306a36Sopenharmony_ci			brddat |= BRDDAT6;
165862306a36Sopenharmony_ci			if (bootverbose) {
165962306a36Sopenharmony_ci				if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0)
166062306a36Sopenharmony_ci					printk("%s: 68 pin termination "
166162306a36Sopenharmony_ci					       "Enabled\n", ahc_name(ahc));
166262306a36Sopenharmony_ci				else
166362306a36Sopenharmony_ci					printk("%s: %sHigh byte termination "
166462306a36Sopenharmony_ci					       "Enabled\n", ahc_name(ahc),
166562306a36Sopenharmony_ci					       enableSEC_high ? "Secondary "
166662306a36Sopenharmony_ci							      : "");
166762306a36Sopenharmony_ci			}
166862306a36Sopenharmony_ci		}
166962306a36Sopenharmony_ci
167062306a36Sopenharmony_ci		sum = internal50_present + internal68_present
167162306a36Sopenharmony_ci		    + externalcable_present;
167262306a36Sopenharmony_ci		if (sum < 2 || (enableSEC_low != 0)) {
167362306a36Sopenharmony_ci			if ((ahc->features & AHC_ULTRA2) != 0)
167462306a36Sopenharmony_ci				brddat |= BRDDAT5;
167562306a36Sopenharmony_ci			else
167662306a36Sopenharmony_ci				*sxfrctl1 |= STPWEN;
167762306a36Sopenharmony_ci			if (bootverbose) {
167862306a36Sopenharmony_ci				if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0)
167962306a36Sopenharmony_ci					printk("%s: 50 pin termination "
168062306a36Sopenharmony_ci					       "Enabled\n", ahc_name(ahc));
168162306a36Sopenharmony_ci				else
168262306a36Sopenharmony_ci					printk("%s: %sLow byte termination "
168362306a36Sopenharmony_ci					       "Enabled\n", ahc_name(ahc),
168462306a36Sopenharmony_ci					       enableSEC_low ? "Secondary "
168562306a36Sopenharmony_ci							     : "");
168662306a36Sopenharmony_ci			}
168762306a36Sopenharmony_ci		}
168862306a36Sopenharmony_ci
168962306a36Sopenharmony_ci		if (enablePRI_low != 0) {
169062306a36Sopenharmony_ci			*sxfrctl1 |= STPWEN;
169162306a36Sopenharmony_ci			if (bootverbose)
169262306a36Sopenharmony_ci				printk("%s: Primary Low Byte termination "
169362306a36Sopenharmony_ci				       "Enabled\n", ahc_name(ahc));
169462306a36Sopenharmony_ci		}
169562306a36Sopenharmony_ci
169662306a36Sopenharmony_ci		/*
169762306a36Sopenharmony_ci		 * Setup STPWEN before setting up the rest of
169862306a36Sopenharmony_ci		 * the termination per the tech note on the U160 cards.
169962306a36Sopenharmony_ci		 */
170062306a36Sopenharmony_ci		ahc_outb(ahc, SXFRCTL1, *sxfrctl1);
170162306a36Sopenharmony_ci
170262306a36Sopenharmony_ci		if (enablePRI_high != 0) {
170362306a36Sopenharmony_ci			brddat |= BRDDAT4;
170462306a36Sopenharmony_ci			if (bootverbose)
170562306a36Sopenharmony_ci				printk("%s: Primary High Byte "
170662306a36Sopenharmony_ci				       "termination Enabled\n",
170762306a36Sopenharmony_ci				       ahc_name(ahc));
170862306a36Sopenharmony_ci		}
170962306a36Sopenharmony_ci
171062306a36Sopenharmony_ci		write_brdctl(ahc, brddat);
171162306a36Sopenharmony_ci
171262306a36Sopenharmony_ci	} else {
171362306a36Sopenharmony_ci		if ((adapter_control & CFSTERM) != 0) {
171462306a36Sopenharmony_ci			*sxfrctl1 |= STPWEN;
171562306a36Sopenharmony_ci
171662306a36Sopenharmony_ci			if (bootverbose)
171762306a36Sopenharmony_ci				printk("%s: %sLow byte termination Enabled\n",
171862306a36Sopenharmony_ci				       ahc_name(ahc),
171962306a36Sopenharmony_ci				       (ahc->features & AHC_ULTRA2) ? "Primary "
172062306a36Sopenharmony_ci								    : "");
172162306a36Sopenharmony_ci		}
172262306a36Sopenharmony_ci
172362306a36Sopenharmony_ci		if ((adapter_control & CFWSTERM) != 0
172462306a36Sopenharmony_ci		 && (ahc->features & AHC_WIDE) != 0) {
172562306a36Sopenharmony_ci			brddat |= BRDDAT6;
172662306a36Sopenharmony_ci			if (bootverbose)
172762306a36Sopenharmony_ci				printk("%s: %sHigh byte termination Enabled\n",
172862306a36Sopenharmony_ci				       ahc_name(ahc),
172962306a36Sopenharmony_ci				       (ahc->features & AHC_ULTRA2)
173062306a36Sopenharmony_ci				     ? "Secondary " : "");
173162306a36Sopenharmony_ci		}
173262306a36Sopenharmony_ci
173362306a36Sopenharmony_ci		/*
173462306a36Sopenharmony_ci		 * Setup STPWEN before setting up the rest of
173562306a36Sopenharmony_ci		 * the termination per the tech note on the U160 cards.
173662306a36Sopenharmony_ci		 */
173762306a36Sopenharmony_ci		ahc_outb(ahc, SXFRCTL1, *sxfrctl1);
173862306a36Sopenharmony_ci
173962306a36Sopenharmony_ci		if ((ahc->features & AHC_WIDE) != 0)
174062306a36Sopenharmony_ci			write_brdctl(ahc, brddat);
174162306a36Sopenharmony_ci	}
174262306a36Sopenharmony_ci	SEEPROM_OUTB(sd, sd->sd_MS); /* Clear CS */
174362306a36Sopenharmony_ci}
174462306a36Sopenharmony_ci
174562306a36Sopenharmony_cistatic void
174662306a36Sopenharmony_ciahc_new_term_detect(struct ahc_softc *ahc, int *enableSEC_low,
174762306a36Sopenharmony_ci		    int *enableSEC_high, int *enablePRI_low,
174862306a36Sopenharmony_ci		    int *enablePRI_high, int *eeprom_present)
174962306a36Sopenharmony_ci{
175062306a36Sopenharmony_ci	uint8_t brdctl;
175162306a36Sopenharmony_ci
175262306a36Sopenharmony_ci	/*
175362306a36Sopenharmony_ci	 * BRDDAT7 = Eeprom
175462306a36Sopenharmony_ci	 * BRDDAT6 = Enable Secondary High Byte termination
175562306a36Sopenharmony_ci	 * BRDDAT5 = Enable Secondary Low Byte termination
175662306a36Sopenharmony_ci	 * BRDDAT4 = Enable Primary high byte termination
175762306a36Sopenharmony_ci	 * BRDDAT3 = Enable Primary low byte termination
175862306a36Sopenharmony_ci	 */
175962306a36Sopenharmony_ci	brdctl = read_brdctl(ahc);
176062306a36Sopenharmony_ci	*eeprom_present = brdctl & BRDDAT7;
176162306a36Sopenharmony_ci	*enableSEC_high = (brdctl & BRDDAT6);
176262306a36Sopenharmony_ci	*enableSEC_low = (brdctl & BRDDAT5);
176362306a36Sopenharmony_ci	*enablePRI_high = (brdctl & BRDDAT4);
176462306a36Sopenharmony_ci	*enablePRI_low = (brdctl & BRDDAT3);
176562306a36Sopenharmony_ci}
176662306a36Sopenharmony_ci
176762306a36Sopenharmony_cistatic void
176862306a36Sopenharmony_ciaic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
176962306a36Sopenharmony_ci		     int *internal68_present, int *externalcable_present,
177062306a36Sopenharmony_ci		     int *eeprom_present)
177162306a36Sopenharmony_ci{
177262306a36Sopenharmony_ci	uint8_t brdctl;
177362306a36Sopenharmony_ci
177462306a36Sopenharmony_ci	/*
177562306a36Sopenharmony_ci	 * First read the status of our cables.
177662306a36Sopenharmony_ci	 * Set the rom bank to 0 since the
177762306a36Sopenharmony_ci	 * bank setting serves as a multiplexor
177862306a36Sopenharmony_ci	 * for the cable detection logic.
177962306a36Sopenharmony_ci	 * BRDDAT5 controls the bank switch.
178062306a36Sopenharmony_ci	 */
178162306a36Sopenharmony_ci	write_brdctl(ahc, 0);
178262306a36Sopenharmony_ci
178362306a36Sopenharmony_ci	/*
178462306a36Sopenharmony_ci	 * Now read the state of the internal
178562306a36Sopenharmony_ci	 * connectors.  BRDDAT6 is INT50 and
178662306a36Sopenharmony_ci	 * BRDDAT7 is INT68.
178762306a36Sopenharmony_ci	 */
178862306a36Sopenharmony_ci	brdctl = read_brdctl(ahc);
178962306a36Sopenharmony_ci	*internal50_present = (brdctl & BRDDAT6) ? 0 : 1;
179062306a36Sopenharmony_ci	*internal68_present = (brdctl & BRDDAT7) ? 0 : 1;
179162306a36Sopenharmony_ci
179262306a36Sopenharmony_ci	/*
179362306a36Sopenharmony_ci	 * Set the rom bank to 1 and determine
179462306a36Sopenharmony_ci	 * the other signals.
179562306a36Sopenharmony_ci	 */
179662306a36Sopenharmony_ci	write_brdctl(ahc, BRDDAT5);
179762306a36Sopenharmony_ci
179862306a36Sopenharmony_ci	/*
179962306a36Sopenharmony_ci	 * Now read the state of the external
180062306a36Sopenharmony_ci	 * connectors.  BRDDAT6 is EXT68 and
180162306a36Sopenharmony_ci	 * BRDDAT7 is EPROMPS.
180262306a36Sopenharmony_ci	 */
180362306a36Sopenharmony_ci	brdctl = read_brdctl(ahc);
180462306a36Sopenharmony_ci	*externalcable_present = (brdctl & BRDDAT6) ? 0 : 1;
180562306a36Sopenharmony_ci	*eeprom_present = (brdctl & BRDDAT7) ? 1 : 0;
180662306a36Sopenharmony_ci}
180762306a36Sopenharmony_ci
180862306a36Sopenharmony_cistatic void
180962306a36Sopenharmony_ciaic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
181062306a36Sopenharmony_ci		     int *externalcable_present, int *eeprom_present)
181162306a36Sopenharmony_ci{
181262306a36Sopenharmony_ci	uint8_t brdctl;
181362306a36Sopenharmony_ci	uint8_t spiocap;
181462306a36Sopenharmony_ci
181562306a36Sopenharmony_ci	spiocap = ahc_inb(ahc, SPIOCAP);
181662306a36Sopenharmony_ci	spiocap &= ~SOFTCMDEN;
181762306a36Sopenharmony_ci	spiocap |= EXT_BRDCTL;
181862306a36Sopenharmony_ci	ahc_outb(ahc, SPIOCAP, spiocap);
181962306a36Sopenharmony_ci	ahc_outb(ahc, BRDCTL, BRDRW|BRDCS);
182062306a36Sopenharmony_ci	ahc_flush_device_writes(ahc);
182162306a36Sopenharmony_ci	ahc_delay(500);
182262306a36Sopenharmony_ci	ahc_outb(ahc, BRDCTL, 0);
182362306a36Sopenharmony_ci	ahc_flush_device_writes(ahc);
182462306a36Sopenharmony_ci	ahc_delay(500);
182562306a36Sopenharmony_ci	brdctl = ahc_inb(ahc, BRDCTL);
182662306a36Sopenharmony_ci	*internal50_present = (brdctl & BRDDAT5) ? 0 : 1;
182762306a36Sopenharmony_ci	*externalcable_present = (brdctl & BRDDAT6) ? 0 : 1;
182862306a36Sopenharmony_ci	*eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0;
182962306a36Sopenharmony_ci}
183062306a36Sopenharmony_ci
183162306a36Sopenharmony_ciint
183262306a36Sopenharmony_ciahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd)
183362306a36Sopenharmony_ci{
183462306a36Sopenharmony_ci	int wait;
183562306a36Sopenharmony_ci
183662306a36Sopenharmony_ci	if ((ahc->features & AHC_SPIOCAP) != 0
183762306a36Sopenharmony_ci	 && (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0)
183862306a36Sopenharmony_ci		return (0);
183962306a36Sopenharmony_ci
184062306a36Sopenharmony_ci	/*
184162306a36Sopenharmony_ci	 * Request access of the memory port.  When access is
184262306a36Sopenharmony_ci	 * granted, SEERDY will go high.  We use a 1 second
184362306a36Sopenharmony_ci	 * timeout which should be near 1 second more than
184462306a36Sopenharmony_ci	 * is needed.  Reason: after the chip reset, there
184562306a36Sopenharmony_ci	 * should be no contention.
184662306a36Sopenharmony_ci	 */
184762306a36Sopenharmony_ci	SEEPROM_OUTB(sd, sd->sd_MS);
184862306a36Sopenharmony_ci	wait = 1000;  /* 1 second timeout in msec */
184962306a36Sopenharmony_ci	while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) {
185062306a36Sopenharmony_ci		ahc_delay(1000);  /* delay 1 msec */
185162306a36Sopenharmony_ci	}
185262306a36Sopenharmony_ci	if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) {
185362306a36Sopenharmony_ci		SEEPROM_OUTB(sd, 0);
185462306a36Sopenharmony_ci		return (0);
185562306a36Sopenharmony_ci	}
185662306a36Sopenharmony_ci	return(1);
185762306a36Sopenharmony_ci}
185862306a36Sopenharmony_ci
185962306a36Sopenharmony_civoid
186062306a36Sopenharmony_ciahc_release_seeprom(struct seeprom_descriptor *sd)
186162306a36Sopenharmony_ci{
186262306a36Sopenharmony_ci	/* Release access to the memory port and the serial EEPROM. */
186362306a36Sopenharmony_ci	SEEPROM_OUTB(sd, 0);
186462306a36Sopenharmony_ci}
186562306a36Sopenharmony_ci
186662306a36Sopenharmony_cistatic void
186762306a36Sopenharmony_ciwrite_brdctl(struct ahc_softc *ahc, uint8_t value)
186862306a36Sopenharmony_ci{
186962306a36Sopenharmony_ci	uint8_t brdctl;
187062306a36Sopenharmony_ci
187162306a36Sopenharmony_ci	if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
187262306a36Sopenharmony_ci		brdctl = BRDSTB;
187362306a36Sopenharmony_ci	 	if (ahc->channel == 'B')
187462306a36Sopenharmony_ci			brdctl |= BRDCS;
187562306a36Sopenharmony_ci	} else if ((ahc->features & AHC_ULTRA2) != 0) {
187662306a36Sopenharmony_ci		brdctl = 0;
187762306a36Sopenharmony_ci	} else {
187862306a36Sopenharmony_ci		brdctl = BRDSTB|BRDCS;
187962306a36Sopenharmony_ci	}
188062306a36Sopenharmony_ci	ahc_outb(ahc, BRDCTL, brdctl);
188162306a36Sopenharmony_ci	ahc_flush_device_writes(ahc);
188262306a36Sopenharmony_ci	brdctl |= value;
188362306a36Sopenharmony_ci	ahc_outb(ahc, BRDCTL, brdctl);
188462306a36Sopenharmony_ci	ahc_flush_device_writes(ahc);
188562306a36Sopenharmony_ci	if ((ahc->features & AHC_ULTRA2) != 0)
188662306a36Sopenharmony_ci		brdctl |= BRDSTB_ULTRA2;
188762306a36Sopenharmony_ci	else
188862306a36Sopenharmony_ci		brdctl &= ~BRDSTB;
188962306a36Sopenharmony_ci	ahc_outb(ahc, BRDCTL, brdctl);
189062306a36Sopenharmony_ci	ahc_flush_device_writes(ahc);
189162306a36Sopenharmony_ci	if ((ahc->features & AHC_ULTRA2) != 0)
189262306a36Sopenharmony_ci		brdctl = 0;
189362306a36Sopenharmony_ci	else
189462306a36Sopenharmony_ci		brdctl &= ~BRDCS;
189562306a36Sopenharmony_ci	ahc_outb(ahc, BRDCTL, brdctl);
189662306a36Sopenharmony_ci}
189762306a36Sopenharmony_ci
189862306a36Sopenharmony_cistatic uint8_t
189962306a36Sopenharmony_ciread_brdctl(struct ahc_softc *ahc)
190062306a36Sopenharmony_ci{
190162306a36Sopenharmony_ci	uint8_t brdctl;
190262306a36Sopenharmony_ci	uint8_t value;
190362306a36Sopenharmony_ci
190462306a36Sopenharmony_ci	if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
190562306a36Sopenharmony_ci		brdctl = BRDRW;
190662306a36Sopenharmony_ci	 	if (ahc->channel == 'B')
190762306a36Sopenharmony_ci			brdctl |= BRDCS;
190862306a36Sopenharmony_ci	} else if ((ahc->features & AHC_ULTRA2) != 0) {
190962306a36Sopenharmony_ci		brdctl = BRDRW_ULTRA2;
191062306a36Sopenharmony_ci	} else {
191162306a36Sopenharmony_ci		brdctl = BRDRW|BRDCS;
191262306a36Sopenharmony_ci	}
191362306a36Sopenharmony_ci	ahc_outb(ahc, BRDCTL, brdctl);
191462306a36Sopenharmony_ci	ahc_flush_device_writes(ahc);
191562306a36Sopenharmony_ci	value = ahc_inb(ahc, BRDCTL);
191662306a36Sopenharmony_ci	ahc_outb(ahc, BRDCTL, 0);
191762306a36Sopenharmony_ci	return (value);
191862306a36Sopenharmony_ci}
191962306a36Sopenharmony_ci
192062306a36Sopenharmony_cistatic void
192162306a36Sopenharmony_ciahc_pci_intr(struct ahc_softc *ahc)
192262306a36Sopenharmony_ci{
192362306a36Sopenharmony_ci	u_int error;
192462306a36Sopenharmony_ci	u_int status1;
192562306a36Sopenharmony_ci
192662306a36Sopenharmony_ci	error = ahc_inb(ahc, ERROR);
192762306a36Sopenharmony_ci	if ((error & PCIERRSTAT) == 0)
192862306a36Sopenharmony_ci		return;
192962306a36Sopenharmony_ci
193062306a36Sopenharmony_ci	status1 = ahc_pci_read_config(ahc->dev_softc,
193162306a36Sopenharmony_ci				      PCIR_STATUS + 1, /*bytes*/1);
193262306a36Sopenharmony_ci
193362306a36Sopenharmony_ci	printk("%s: PCI error Interrupt at seqaddr = 0x%x\n",
193462306a36Sopenharmony_ci	      ahc_name(ahc),
193562306a36Sopenharmony_ci	      ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
193662306a36Sopenharmony_ci
193762306a36Sopenharmony_ci	if (status1 & DPE) {
193862306a36Sopenharmony_ci		ahc->pci_target_perr_count++;
193962306a36Sopenharmony_ci		printk("%s: Data Parity Error Detected during address "
194062306a36Sopenharmony_ci		       "or write data phase\n", ahc_name(ahc));
194162306a36Sopenharmony_ci	}
194262306a36Sopenharmony_ci	if (status1 & SSE) {
194362306a36Sopenharmony_ci		printk("%s: Signal System Error Detected\n", ahc_name(ahc));
194462306a36Sopenharmony_ci	}
194562306a36Sopenharmony_ci	if (status1 & RMA) {
194662306a36Sopenharmony_ci		printk("%s: Received a Master Abort\n", ahc_name(ahc));
194762306a36Sopenharmony_ci	}
194862306a36Sopenharmony_ci	if (status1 & RTA) {
194962306a36Sopenharmony_ci		printk("%s: Received a Target Abort\n", ahc_name(ahc));
195062306a36Sopenharmony_ci	}
195162306a36Sopenharmony_ci	if (status1 & STA) {
195262306a36Sopenharmony_ci		printk("%s: Signaled a Target Abort\n", ahc_name(ahc));
195362306a36Sopenharmony_ci	}
195462306a36Sopenharmony_ci	if (status1 & DPR) {
195562306a36Sopenharmony_ci		printk("%s: Data Parity Error has been reported via PERR#\n",
195662306a36Sopenharmony_ci		       ahc_name(ahc));
195762306a36Sopenharmony_ci	}
195862306a36Sopenharmony_ci
195962306a36Sopenharmony_ci	/* Clear latched errors. */
196062306a36Sopenharmony_ci	ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
196162306a36Sopenharmony_ci			     status1, /*bytes*/1);
196262306a36Sopenharmony_ci
196362306a36Sopenharmony_ci	if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) {
196462306a36Sopenharmony_ci		printk("%s: Latched PCIERR interrupt with "
196562306a36Sopenharmony_ci		       "no status bits set\n", ahc_name(ahc));
196662306a36Sopenharmony_ci	} else {
196762306a36Sopenharmony_ci		ahc_outb(ahc, CLRINT, CLRPARERR);
196862306a36Sopenharmony_ci	}
196962306a36Sopenharmony_ci
197062306a36Sopenharmony_ci	if (ahc->pci_target_perr_count > AHC_PCI_TARGET_PERR_THRESH) {
197162306a36Sopenharmony_ci		printk(
197262306a36Sopenharmony_ci"%s: WARNING WARNING WARNING WARNING\n"
197362306a36Sopenharmony_ci"%s: Too many PCI parity errors observed as a target.\n"
197462306a36Sopenharmony_ci"%s: Some device on this bus is generating bad parity.\n"
197562306a36Sopenharmony_ci"%s: This is an error *observed by*, not *generated by*, this controller.\n"
197662306a36Sopenharmony_ci"%s: PCI parity error checking has been disabled.\n"
197762306a36Sopenharmony_ci"%s: WARNING WARNING WARNING WARNING\n",
197862306a36Sopenharmony_ci		       ahc_name(ahc), ahc_name(ahc), ahc_name(ahc),
197962306a36Sopenharmony_ci		       ahc_name(ahc), ahc_name(ahc), ahc_name(ahc));
198062306a36Sopenharmony_ci		ahc->seqctl |= FAILDIS;
198162306a36Sopenharmony_ci		ahc_outb(ahc, SEQCTL, ahc->seqctl);
198262306a36Sopenharmony_ci	}
198362306a36Sopenharmony_ci	ahc_unpause(ahc);
198462306a36Sopenharmony_ci}
198562306a36Sopenharmony_ci
198662306a36Sopenharmony_cistatic int
198762306a36Sopenharmony_ciahc_pci_chip_init(struct ahc_softc *ahc)
198862306a36Sopenharmony_ci{
198962306a36Sopenharmony_ci	ahc_outb(ahc, DSCOMMAND0, ahc->bus_softc.pci_softc.dscommand0);
199062306a36Sopenharmony_ci	ahc_outb(ahc, DSPCISTATUS, ahc->bus_softc.pci_softc.dspcistatus);
199162306a36Sopenharmony_ci	if ((ahc->features & AHC_DT) != 0) {
199262306a36Sopenharmony_ci		u_int sfunct;
199362306a36Sopenharmony_ci
199462306a36Sopenharmony_ci		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
199562306a36Sopenharmony_ci		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
199662306a36Sopenharmony_ci		ahc_outb(ahc, OPTIONMODE, ahc->bus_softc.pci_softc.optionmode);
199762306a36Sopenharmony_ci		ahc_outw(ahc, TARGCRCCNT, ahc->bus_softc.pci_softc.targcrccnt);
199862306a36Sopenharmony_ci		ahc_outb(ahc, SFUNCT, sfunct);
199962306a36Sopenharmony_ci		ahc_outb(ahc, CRCCONTROL1,
200062306a36Sopenharmony_ci			 ahc->bus_softc.pci_softc.crccontrol1);
200162306a36Sopenharmony_ci	}
200262306a36Sopenharmony_ci	if ((ahc->features & AHC_MULTI_FUNC) != 0)
200362306a36Sopenharmony_ci		ahc_outb(ahc, SCBBADDR, ahc->bus_softc.pci_softc.scbbaddr);
200462306a36Sopenharmony_ci
200562306a36Sopenharmony_ci	if ((ahc->features & AHC_ULTRA2) != 0)
200662306a36Sopenharmony_ci		ahc_outb(ahc, DFF_THRSH, ahc->bus_softc.pci_softc.dff_thrsh);
200762306a36Sopenharmony_ci
200862306a36Sopenharmony_ci	return (ahc_chip_init(ahc));
200962306a36Sopenharmony_ci}
201062306a36Sopenharmony_ci
201162306a36Sopenharmony_civoid __maybe_unused
201262306a36Sopenharmony_ciahc_pci_resume(struct ahc_softc *ahc)
201362306a36Sopenharmony_ci{
201462306a36Sopenharmony_ci	/*
201562306a36Sopenharmony_ci	 * We assume that the OS has restored our register
201662306a36Sopenharmony_ci	 * mappings, etc.  Just update the config space registers
201762306a36Sopenharmony_ci	 * that the OS doesn't know about and rely on our chip
201862306a36Sopenharmony_ci	 * reset handler to handle the rest.
201962306a36Sopenharmony_ci	 */
202062306a36Sopenharmony_ci	ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
202162306a36Sopenharmony_ci			     ahc->bus_softc.pci_softc.devconfig, /*bytes*/4);
202262306a36Sopenharmony_ci	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
202362306a36Sopenharmony_ci			     ahc->bus_softc.pci_softc.command, /*bytes*/1);
202462306a36Sopenharmony_ci	ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME,
202562306a36Sopenharmony_ci			     ahc->bus_softc.pci_softc.csize_lattime, /*bytes*/1);
202662306a36Sopenharmony_ci	if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) {
202762306a36Sopenharmony_ci		struct	seeprom_descriptor sd;
202862306a36Sopenharmony_ci		u_int	sxfrctl1;
202962306a36Sopenharmony_ci
203062306a36Sopenharmony_ci		sd.sd_ahc = ahc;
203162306a36Sopenharmony_ci		sd.sd_control_offset = SEECTL;
203262306a36Sopenharmony_ci		sd.sd_status_offset = SEECTL;
203362306a36Sopenharmony_ci		sd.sd_dataout_offset = SEECTL;
203462306a36Sopenharmony_ci
203562306a36Sopenharmony_ci		ahc_acquire_seeprom(ahc, &sd);
203662306a36Sopenharmony_ci		configure_termination(ahc, &sd,
203762306a36Sopenharmony_ci				      ahc->seep_config->adapter_control,
203862306a36Sopenharmony_ci				      &sxfrctl1);
203962306a36Sopenharmony_ci		ahc_release_seeprom(&sd);
204062306a36Sopenharmony_ci	}
204162306a36Sopenharmony_ci}
204262306a36Sopenharmony_ci
204362306a36Sopenharmony_cistatic int
204462306a36Sopenharmony_ciahc_aic785X_setup(struct ahc_softc *ahc)
204562306a36Sopenharmony_ci{
204662306a36Sopenharmony_ci	ahc_dev_softc_t pci;
204762306a36Sopenharmony_ci	uint8_t rev;
204862306a36Sopenharmony_ci
204962306a36Sopenharmony_ci	pci = ahc->dev_softc;
205062306a36Sopenharmony_ci	ahc->channel = 'A';
205162306a36Sopenharmony_ci	ahc->chip = AHC_AIC7850;
205262306a36Sopenharmony_ci	ahc->features = AHC_AIC7850_FE;
205362306a36Sopenharmony_ci	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
205462306a36Sopenharmony_ci	rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
205562306a36Sopenharmony_ci	if (rev >= 1)
205662306a36Sopenharmony_ci		ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
205762306a36Sopenharmony_ci	ahc->instruction_ram_size = 512;
205862306a36Sopenharmony_ci	return (0);
205962306a36Sopenharmony_ci}
206062306a36Sopenharmony_ci
206162306a36Sopenharmony_cistatic int
206262306a36Sopenharmony_ciahc_aic7860_setup(struct ahc_softc *ahc)
206362306a36Sopenharmony_ci{
206462306a36Sopenharmony_ci	ahc_dev_softc_t pci;
206562306a36Sopenharmony_ci	uint8_t rev;
206662306a36Sopenharmony_ci
206762306a36Sopenharmony_ci	pci = ahc->dev_softc;
206862306a36Sopenharmony_ci	ahc->channel = 'A';
206962306a36Sopenharmony_ci	ahc->chip = AHC_AIC7860;
207062306a36Sopenharmony_ci	ahc->features = AHC_AIC7860_FE;
207162306a36Sopenharmony_ci	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
207262306a36Sopenharmony_ci	rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
207362306a36Sopenharmony_ci	if (rev >= 1)
207462306a36Sopenharmony_ci		ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
207562306a36Sopenharmony_ci	ahc->instruction_ram_size = 512;
207662306a36Sopenharmony_ci	return (0);
207762306a36Sopenharmony_ci}
207862306a36Sopenharmony_ci
207962306a36Sopenharmony_cistatic int
208062306a36Sopenharmony_ciahc_apa1480_setup(struct ahc_softc *ahc)
208162306a36Sopenharmony_ci{
208262306a36Sopenharmony_ci	int error;
208362306a36Sopenharmony_ci
208462306a36Sopenharmony_ci	error = ahc_aic7860_setup(ahc);
208562306a36Sopenharmony_ci	if (error != 0)
208662306a36Sopenharmony_ci		return (error);
208762306a36Sopenharmony_ci	ahc->features |= AHC_REMOVABLE;
208862306a36Sopenharmony_ci	return (0);
208962306a36Sopenharmony_ci}
209062306a36Sopenharmony_ci
209162306a36Sopenharmony_cistatic int
209262306a36Sopenharmony_ciahc_aic7870_setup(struct ahc_softc *ahc)
209362306a36Sopenharmony_ci{
209462306a36Sopenharmony_ci
209562306a36Sopenharmony_ci	ahc->channel = 'A';
209662306a36Sopenharmony_ci	ahc->chip = AHC_AIC7870;
209762306a36Sopenharmony_ci	ahc->features = AHC_AIC7870_FE;
209862306a36Sopenharmony_ci	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
209962306a36Sopenharmony_ci	ahc->instruction_ram_size = 512;
210062306a36Sopenharmony_ci	return (0);
210162306a36Sopenharmony_ci}
210262306a36Sopenharmony_ci
210362306a36Sopenharmony_cistatic int
210462306a36Sopenharmony_ciahc_aic7870h_setup(struct ahc_softc *ahc)
210562306a36Sopenharmony_ci{
210662306a36Sopenharmony_ci	int error = ahc_aic7870_setup(ahc);
210762306a36Sopenharmony_ci
210862306a36Sopenharmony_ci	ahc->features |= AHC_HVD;
210962306a36Sopenharmony_ci
211062306a36Sopenharmony_ci	return error;
211162306a36Sopenharmony_ci}
211262306a36Sopenharmony_ci
211362306a36Sopenharmony_cistatic int
211462306a36Sopenharmony_ciahc_aha394X_setup(struct ahc_softc *ahc)
211562306a36Sopenharmony_ci{
211662306a36Sopenharmony_ci	int error;
211762306a36Sopenharmony_ci
211862306a36Sopenharmony_ci	error = ahc_aic7870_setup(ahc);
211962306a36Sopenharmony_ci	if (error == 0)
212062306a36Sopenharmony_ci		error = ahc_aha394XX_setup(ahc);
212162306a36Sopenharmony_ci	return (error);
212262306a36Sopenharmony_ci}
212362306a36Sopenharmony_ci
212462306a36Sopenharmony_cistatic int
212562306a36Sopenharmony_ciahc_aha394Xh_setup(struct ahc_softc *ahc)
212662306a36Sopenharmony_ci{
212762306a36Sopenharmony_ci	int error = ahc_aha394X_setup(ahc);
212862306a36Sopenharmony_ci
212962306a36Sopenharmony_ci	ahc->features |= AHC_HVD;
213062306a36Sopenharmony_ci
213162306a36Sopenharmony_ci	return error;
213262306a36Sopenharmony_ci}
213362306a36Sopenharmony_ci
213462306a36Sopenharmony_cistatic int
213562306a36Sopenharmony_ciahc_aha398X_setup(struct ahc_softc *ahc)
213662306a36Sopenharmony_ci{
213762306a36Sopenharmony_ci	int error;
213862306a36Sopenharmony_ci
213962306a36Sopenharmony_ci	error = ahc_aic7870_setup(ahc);
214062306a36Sopenharmony_ci	if (error == 0)
214162306a36Sopenharmony_ci		error = ahc_aha398XX_setup(ahc);
214262306a36Sopenharmony_ci	return (error);
214362306a36Sopenharmony_ci}
214462306a36Sopenharmony_ci
214562306a36Sopenharmony_cistatic int
214662306a36Sopenharmony_ciahc_aha494X_setup(struct ahc_softc *ahc)
214762306a36Sopenharmony_ci{
214862306a36Sopenharmony_ci	int error;
214962306a36Sopenharmony_ci
215062306a36Sopenharmony_ci	error = ahc_aic7870_setup(ahc);
215162306a36Sopenharmony_ci	if (error == 0)
215262306a36Sopenharmony_ci		error = ahc_aha494XX_setup(ahc);
215362306a36Sopenharmony_ci	return (error);
215462306a36Sopenharmony_ci}
215562306a36Sopenharmony_ci
215662306a36Sopenharmony_cistatic int
215762306a36Sopenharmony_ciahc_aha494Xh_setup(struct ahc_softc *ahc)
215862306a36Sopenharmony_ci{
215962306a36Sopenharmony_ci	int error = ahc_aha494X_setup(ahc);
216062306a36Sopenharmony_ci
216162306a36Sopenharmony_ci	ahc->features |= AHC_HVD;
216262306a36Sopenharmony_ci
216362306a36Sopenharmony_ci	return error;
216462306a36Sopenharmony_ci}
216562306a36Sopenharmony_ci
216662306a36Sopenharmony_cistatic int
216762306a36Sopenharmony_ciahc_aic7880_setup(struct ahc_softc *ahc)
216862306a36Sopenharmony_ci{
216962306a36Sopenharmony_ci	ahc_dev_softc_t pci;
217062306a36Sopenharmony_ci	uint8_t rev;
217162306a36Sopenharmony_ci
217262306a36Sopenharmony_ci	pci = ahc->dev_softc;
217362306a36Sopenharmony_ci	ahc->channel = 'A';
217462306a36Sopenharmony_ci	ahc->chip = AHC_AIC7880;
217562306a36Sopenharmony_ci	ahc->features = AHC_AIC7880_FE;
217662306a36Sopenharmony_ci	ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
217762306a36Sopenharmony_ci	rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
217862306a36Sopenharmony_ci	if (rev >= 1) {
217962306a36Sopenharmony_ci		ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
218062306a36Sopenharmony_ci	} else {
218162306a36Sopenharmony_ci		ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
218262306a36Sopenharmony_ci	}
218362306a36Sopenharmony_ci	ahc->instruction_ram_size = 512;
218462306a36Sopenharmony_ci	return (0);
218562306a36Sopenharmony_ci}
218662306a36Sopenharmony_ci
218762306a36Sopenharmony_cistatic int
218862306a36Sopenharmony_ciahc_aic7880h_setup(struct ahc_softc *ahc)
218962306a36Sopenharmony_ci{
219062306a36Sopenharmony_ci	int error = ahc_aic7880_setup(ahc);
219162306a36Sopenharmony_ci
219262306a36Sopenharmony_ci	ahc->features |= AHC_HVD;
219362306a36Sopenharmony_ci
219462306a36Sopenharmony_ci	return error;
219562306a36Sopenharmony_ci}
219662306a36Sopenharmony_ci
219762306a36Sopenharmony_ci
219862306a36Sopenharmony_cistatic int
219962306a36Sopenharmony_ciahc_aha2940Pro_setup(struct ahc_softc *ahc)
220062306a36Sopenharmony_ci{
220162306a36Sopenharmony_ci
220262306a36Sopenharmony_ci	ahc->flags |= AHC_INT50_SPEEDFLEX;
220362306a36Sopenharmony_ci	return (ahc_aic7880_setup(ahc));
220462306a36Sopenharmony_ci}
220562306a36Sopenharmony_ci
220662306a36Sopenharmony_cistatic int
220762306a36Sopenharmony_ciahc_aha394XU_setup(struct ahc_softc *ahc)
220862306a36Sopenharmony_ci{
220962306a36Sopenharmony_ci	int error;
221062306a36Sopenharmony_ci
221162306a36Sopenharmony_ci	error = ahc_aic7880_setup(ahc);
221262306a36Sopenharmony_ci	if (error == 0)
221362306a36Sopenharmony_ci		error = ahc_aha394XX_setup(ahc);
221462306a36Sopenharmony_ci	return (error);
221562306a36Sopenharmony_ci}
221662306a36Sopenharmony_ci
221762306a36Sopenharmony_cistatic int
221862306a36Sopenharmony_ciahc_aha394XUh_setup(struct ahc_softc *ahc)
221962306a36Sopenharmony_ci{
222062306a36Sopenharmony_ci	int error = ahc_aha394XU_setup(ahc);
222162306a36Sopenharmony_ci
222262306a36Sopenharmony_ci	ahc->features |= AHC_HVD;
222362306a36Sopenharmony_ci
222462306a36Sopenharmony_ci	return error;
222562306a36Sopenharmony_ci}
222662306a36Sopenharmony_ci
222762306a36Sopenharmony_cistatic int
222862306a36Sopenharmony_ciahc_aha398XU_setup(struct ahc_softc *ahc)
222962306a36Sopenharmony_ci{
223062306a36Sopenharmony_ci	int error;
223162306a36Sopenharmony_ci
223262306a36Sopenharmony_ci	error = ahc_aic7880_setup(ahc);
223362306a36Sopenharmony_ci	if (error == 0)
223462306a36Sopenharmony_ci		error = ahc_aha398XX_setup(ahc);
223562306a36Sopenharmony_ci	return (error);
223662306a36Sopenharmony_ci}
223762306a36Sopenharmony_ci
223862306a36Sopenharmony_cistatic int
223962306a36Sopenharmony_ciahc_aic7890_setup(struct ahc_softc *ahc)
224062306a36Sopenharmony_ci{
224162306a36Sopenharmony_ci	ahc_dev_softc_t pci;
224262306a36Sopenharmony_ci	uint8_t rev;
224362306a36Sopenharmony_ci
224462306a36Sopenharmony_ci	pci = ahc->dev_softc;
224562306a36Sopenharmony_ci	ahc->channel = 'A';
224662306a36Sopenharmony_ci	ahc->chip = AHC_AIC7890;
224762306a36Sopenharmony_ci	ahc->features = AHC_AIC7890_FE;
224862306a36Sopenharmony_ci	ahc->flags |= AHC_NEWEEPROM_FMT;
224962306a36Sopenharmony_ci	rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
225062306a36Sopenharmony_ci	if (rev == 0)
225162306a36Sopenharmony_ci		ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG;
225262306a36Sopenharmony_ci	ahc->instruction_ram_size = 768;
225362306a36Sopenharmony_ci	return (0);
225462306a36Sopenharmony_ci}
225562306a36Sopenharmony_ci
225662306a36Sopenharmony_cistatic int
225762306a36Sopenharmony_ciahc_aic7892_setup(struct ahc_softc *ahc)
225862306a36Sopenharmony_ci{
225962306a36Sopenharmony_ci
226062306a36Sopenharmony_ci	ahc->channel = 'A';
226162306a36Sopenharmony_ci	ahc->chip = AHC_AIC7892;
226262306a36Sopenharmony_ci	ahc->features = AHC_AIC7892_FE;
226362306a36Sopenharmony_ci	ahc->flags |= AHC_NEWEEPROM_FMT;
226462306a36Sopenharmony_ci	ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
226562306a36Sopenharmony_ci	ahc->instruction_ram_size = 1024;
226662306a36Sopenharmony_ci	return (0);
226762306a36Sopenharmony_ci}
226862306a36Sopenharmony_ci
226962306a36Sopenharmony_cistatic int
227062306a36Sopenharmony_ciahc_aic7895_setup(struct ahc_softc *ahc)
227162306a36Sopenharmony_ci{
227262306a36Sopenharmony_ci	ahc_dev_softc_t pci;
227362306a36Sopenharmony_ci	uint8_t rev;
227462306a36Sopenharmony_ci
227562306a36Sopenharmony_ci	pci = ahc->dev_softc;
227662306a36Sopenharmony_ci	ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
227762306a36Sopenharmony_ci	/*
227862306a36Sopenharmony_ci	 * The 'C' revision of the aic7895 has a few additional features.
227962306a36Sopenharmony_ci	 */
228062306a36Sopenharmony_ci	rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
228162306a36Sopenharmony_ci	if (rev >= 4) {
228262306a36Sopenharmony_ci		ahc->chip = AHC_AIC7895C;
228362306a36Sopenharmony_ci		ahc->features = AHC_AIC7895C_FE;
228462306a36Sopenharmony_ci	} else  {
228562306a36Sopenharmony_ci		u_int command;
228662306a36Sopenharmony_ci
228762306a36Sopenharmony_ci		ahc->chip = AHC_AIC7895;
228862306a36Sopenharmony_ci		ahc->features = AHC_AIC7895_FE;
228962306a36Sopenharmony_ci
229062306a36Sopenharmony_ci		/*
229162306a36Sopenharmony_ci		 * The BIOS disables the use of MWI transactions
229262306a36Sopenharmony_ci		 * since it does not have the MWI bug work around
229362306a36Sopenharmony_ci		 * we have.  Disabling MWI reduces performance, so
229462306a36Sopenharmony_ci		 * turn it on again.
229562306a36Sopenharmony_ci		 */
229662306a36Sopenharmony_ci		command = ahc_pci_read_config(pci, PCIR_COMMAND, /*bytes*/1);
229762306a36Sopenharmony_ci		command |= PCIM_CMD_MWRICEN;
229862306a36Sopenharmony_ci		ahc_pci_write_config(pci, PCIR_COMMAND, command, /*bytes*/1);
229962306a36Sopenharmony_ci		ahc->bugs |= AHC_PCI_MWI_BUG;
230062306a36Sopenharmony_ci	}
230162306a36Sopenharmony_ci	/*
230262306a36Sopenharmony_ci	 * XXX Does CACHETHEN really not work???  What about PCI retry?
230362306a36Sopenharmony_ci	 * on C level chips.  Need to test, but for now, play it safe.
230462306a36Sopenharmony_ci	 */
230562306a36Sopenharmony_ci	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_PCI_2_1_RETRY_BUG
230662306a36Sopenharmony_ci		  |  AHC_CACHETHEN_BUG;
230762306a36Sopenharmony_ci
230862306a36Sopenharmony_ci#if 0
230962306a36Sopenharmony_ci	uint32_t devconfig;
231062306a36Sopenharmony_ci
231162306a36Sopenharmony_ci	/*
231262306a36Sopenharmony_ci	 * Cachesize must also be zero due to stray DAC
231362306a36Sopenharmony_ci	 * problem when sitting behind some bridges.
231462306a36Sopenharmony_ci	 */
231562306a36Sopenharmony_ci	ahc_pci_write_config(pci, CSIZE_LATTIME, 0, /*bytes*/1);
231662306a36Sopenharmony_ci	devconfig = ahc_pci_read_config(pci, DEVCONFIG, /*bytes*/1);
231762306a36Sopenharmony_ci	devconfig |= MRDCEN;
231862306a36Sopenharmony_ci	ahc_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1);
231962306a36Sopenharmony_ci#endif
232062306a36Sopenharmony_ci	ahc->flags |= AHC_NEWEEPROM_FMT;
232162306a36Sopenharmony_ci	ahc->instruction_ram_size = 512;
232262306a36Sopenharmony_ci	return (0);
232362306a36Sopenharmony_ci}
232462306a36Sopenharmony_ci
232562306a36Sopenharmony_cistatic int
232662306a36Sopenharmony_ciahc_aic7895h_setup(struct ahc_softc *ahc)
232762306a36Sopenharmony_ci{
232862306a36Sopenharmony_ci	int error = ahc_aic7895_setup(ahc);
232962306a36Sopenharmony_ci
233062306a36Sopenharmony_ci	ahc->features |= AHC_HVD;
233162306a36Sopenharmony_ci
233262306a36Sopenharmony_ci	return error;
233362306a36Sopenharmony_ci}
233462306a36Sopenharmony_ci
233562306a36Sopenharmony_cistatic int
233662306a36Sopenharmony_ciahc_aic7896_setup(struct ahc_softc *ahc)
233762306a36Sopenharmony_ci{
233862306a36Sopenharmony_ci	ahc_dev_softc_t pci;
233962306a36Sopenharmony_ci
234062306a36Sopenharmony_ci	pci = ahc->dev_softc;
234162306a36Sopenharmony_ci	ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
234262306a36Sopenharmony_ci	ahc->chip = AHC_AIC7896;
234362306a36Sopenharmony_ci	ahc->features = AHC_AIC7896_FE;
234462306a36Sopenharmony_ci	ahc->flags |= AHC_NEWEEPROM_FMT;
234562306a36Sopenharmony_ci	ahc->bugs |= AHC_CACHETHEN_DIS_BUG;
234662306a36Sopenharmony_ci	ahc->instruction_ram_size = 768;
234762306a36Sopenharmony_ci	return (0);
234862306a36Sopenharmony_ci}
234962306a36Sopenharmony_ci
235062306a36Sopenharmony_cistatic int
235162306a36Sopenharmony_ciahc_aic7899_setup(struct ahc_softc *ahc)
235262306a36Sopenharmony_ci{
235362306a36Sopenharmony_ci	ahc_dev_softc_t pci;
235462306a36Sopenharmony_ci
235562306a36Sopenharmony_ci	pci = ahc->dev_softc;
235662306a36Sopenharmony_ci	ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
235762306a36Sopenharmony_ci	ahc->chip = AHC_AIC7899;
235862306a36Sopenharmony_ci	ahc->features = AHC_AIC7899_FE;
235962306a36Sopenharmony_ci	ahc->flags |= AHC_NEWEEPROM_FMT;
236062306a36Sopenharmony_ci	ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
236162306a36Sopenharmony_ci	ahc->instruction_ram_size = 1024;
236262306a36Sopenharmony_ci	return (0);
236362306a36Sopenharmony_ci}
236462306a36Sopenharmony_ci
236562306a36Sopenharmony_cistatic int
236662306a36Sopenharmony_ciahc_aha29160C_setup(struct ahc_softc *ahc)
236762306a36Sopenharmony_ci{
236862306a36Sopenharmony_ci	int error;
236962306a36Sopenharmony_ci
237062306a36Sopenharmony_ci	error = ahc_aic7899_setup(ahc);
237162306a36Sopenharmony_ci	if (error != 0)
237262306a36Sopenharmony_ci		return (error);
237362306a36Sopenharmony_ci	ahc->features |= AHC_REMOVABLE;
237462306a36Sopenharmony_ci	return (0);
237562306a36Sopenharmony_ci}
237662306a36Sopenharmony_ci
237762306a36Sopenharmony_cistatic int
237862306a36Sopenharmony_ciahc_raid_setup(struct ahc_softc *ahc)
237962306a36Sopenharmony_ci{
238062306a36Sopenharmony_ci	printk("RAID functionality unsupported\n");
238162306a36Sopenharmony_ci	return (ENXIO);
238262306a36Sopenharmony_ci}
238362306a36Sopenharmony_ci
238462306a36Sopenharmony_cistatic int
238562306a36Sopenharmony_ciahc_aha394XX_setup(struct ahc_softc *ahc)
238662306a36Sopenharmony_ci{
238762306a36Sopenharmony_ci	ahc_dev_softc_t pci;
238862306a36Sopenharmony_ci
238962306a36Sopenharmony_ci	pci = ahc->dev_softc;
239062306a36Sopenharmony_ci	switch (ahc_get_pci_slot(pci)) {
239162306a36Sopenharmony_ci	case AHC_394X_SLOT_CHANNEL_A:
239262306a36Sopenharmony_ci		ahc->channel = 'A';
239362306a36Sopenharmony_ci		break;
239462306a36Sopenharmony_ci	case AHC_394X_SLOT_CHANNEL_B:
239562306a36Sopenharmony_ci		ahc->channel = 'B';
239662306a36Sopenharmony_ci		break;
239762306a36Sopenharmony_ci	default:
239862306a36Sopenharmony_ci		printk("adapter at unexpected slot %d\n"
239962306a36Sopenharmony_ci		       "unable to map to a channel\n",
240062306a36Sopenharmony_ci		       ahc_get_pci_slot(pci));
240162306a36Sopenharmony_ci		ahc->channel = 'A';
240262306a36Sopenharmony_ci	}
240362306a36Sopenharmony_ci	return (0);
240462306a36Sopenharmony_ci}
240562306a36Sopenharmony_ci
240662306a36Sopenharmony_cistatic int
240762306a36Sopenharmony_ciahc_aha398XX_setup(struct ahc_softc *ahc)
240862306a36Sopenharmony_ci{
240962306a36Sopenharmony_ci	ahc_dev_softc_t pci;
241062306a36Sopenharmony_ci
241162306a36Sopenharmony_ci	pci = ahc->dev_softc;
241262306a36Sopenharmony_ci	switch (ahc_get_pci_slot(pci)) {
241362306a36Sopenharmony_ci	case AHC_398X_SLOT_CHANNEL_A:
241462306a36Sopenharmony_ci		ahc->channel = 'A';
241562306a36Sopenharmony_ci		break;
241662306a36Sopenharmony_ci	case AHC_398X_SLOT_CHANNEL_B:
241762306a36Sopenharmony_ci		ahc->channel = 'B';
241862306a36Sopenharmony_ci		break;
241962306a36Sopenharmony_ci	case AHC_398X_SLOT_CHANNEL_C:
242062306a36Sopenharmony_ci		ahc->channel = 'C';
242162306a36Sopenharmony_ci		break;
242262306a36Sopenharmony_ci	default:
242362306a36Sopenharmony_ci		printk("adapter at unexpected slot %d\n"
242462306a36Sopenharmony_ci		       "unable to map to a channel\n",
242562306a36Sopenharmony_ci		       ahc_get_pci_slot(pci));
242662306a36Sopenharmony_ci		ahc->channel = 'A';
242762306a36Sopenharmony_ci		break;
242862306a36Sopenharmony_ci	}
242962306a36Sopenharmony_ci	ahc->flags |= AHC_LARGE_SEEPROM;
243062306a36Sopenharmony_ci	return (0);
243162306a36Sopenharmony_ci}
243262306a36Sopenharmony_ci
243362306a36Sopenharmony_cistatic int
243462306a36Sopenharmony_ciahc_aha494XX_setup(struct ahc_softc *ahc)
243562306a36Sopenharmony_ci{
243662306a36Sopenharmony_ci	ahc_dev_softc_t pci;
243762306a36Sopenharmony_ci
243862306a36Sopenharmony_ci	pci = ahc->dev_softc;
243962306a36Sopenharmony_ci	switch (ahc_get_pci_slot(pci)) {
244062306a36Sopenharmony_ci	case AHC_494X_SLOT_CHANNEL_A:
244162306a36Sopenharmony_ci		ahc->channel = 'A';
244262306a36Sopenharmony_ci		break;
244362306a36Sopenharmony_ci	case AHC_494X_SLOT_CHANNEL_B:
244462306a36Sopenharmony_ci		ahc->channel = 'B';
244562306a36Sopenharmony_ci		break;
244662306a36Sopenharmony_ci	case AHC_494X_SLOT_CHANNEL_C:
244762306a36Sopenharmony_ci		ahc->channel = 'C';
244862306a36Sopenharmony_ci		break;
244962306a36Sopenharmony_ci	case AHC_494X_SLOT_CHANNEL_D:
245062306a36Sopenharmony_ci		ahc->channel = 'D';
245162306a36Sopenharmony_ci		break;
245262306a36Sopenharmony_ci	default:
245362306a36Sopenharmony_ci		printk("adapter at unexpected slot %d\n"
245462306a36Sopenharmony_ci		       "unable to map to a channel\n",
245562306a36Sopenharmony_ci		       ahc_get_pci_slot(pci));
245662306a36Sopenharmony_ci		ahc->channel = 'A';
245762306a36Sopenharmony_ci	}
245862306a36Sopenharmony_ci	ahc->flags |= AHC_LARGE_SEEPROM;
245962306a36Sopenharmony_ci	return (0);
246062306a36Sopenharmony_ci}
2461