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