cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

aic79xx_pci.c (27447B)


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