Home | History | Annotate | Line # | Download | only in pci
ahc_pci.c revision 1.58.26.1
      1        1.1   mycroft /*
      2        1.1   mycroft  * Product specific probe and attach routines for:
      3       1.22      fvdl  *      3940, 2940, aic7895, aic7890, aic7880,
      4       1.22      fvdl  *	aic7870, aic7860 and aic7850 SCSI controllers
      5        1.1   mycroft  *
      6       1.39      fvdl  * Copyright (c) 1994-2001 Justin T. Gibbs.
      7       1.39      fvdl  * Copyright (c) 2000-2001 Adaptec Inc.
      8        1.1   mycroft  * All rights reserved.
      9        1.1   mycroft  *
     10        1.1   mycroft  * Redistribution and use in source and binary forms, with or without
     11        1.1   mycroft  * modification, are permitted provided that the following conditions
     12        1.1   mycroft  * are met:
     13        1.1   mycroft  * 1. Redistributions of source code must retain the above copyright
     14       1.22      fvdl  *    notice, this list of conditions, and the following disclaimer,
     15       1.22      fvdl  *    without modification.
     16       1.39      fvdl  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     17       1.39      fvdl  *    substantially similar to the "NO WARRANTY" disclaimer below
     18       1.39      fvdl  *    ("Disclaimer") and any redistribution must be conditioned upon
     19       1.39      fvdl  *    including a substantially similar Disclaimer requirement for further
     20       1.39      fvdl  *    binary redistribution.
     21       1.39      fvdl  * 3. Neither the names of the above-listed copyright holders nor the names
     22       1.39      fvdl  *    of any contributors may be used to endorse or promote products derived
     23       1.39      fvdl  *    from this software without specific prior written permission.
     24        1.1   mycroft  *
     25       1.22      fvdl  * Alternatively, this software may be distributed under the terms of the
     26       1.39      fvdl  * GNU General Public License ("GPL") version 2 as published by the Free
     27       1.39      fvdl  * Software Foundation.
     28       1.22      fvdl  *
     29       1.39      fvdl  * NO WARRANTY
     30       1.39      fvdl  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     31       1.39      fvdl  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     32       1.39      fvdl  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     33       1.39      fvdl  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     34       1.39      fvdl  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     35        1.1   mycroft  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     36        1.1   mycroft  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     37       1.39      fvdl  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     38       1.39      fvdl  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     39       1.39      fvdl  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     40       1.39      fvdl  * POSSIBILITY OF SUCH DAMAGES.
     41       1.39      fvdl  *
     42  1.58.26.1      yamt  * $Id: ahc_pci.c,v 1.58.26.1 2007/10/06 15:31:22 yamt Exp $
     43       1.39      fvdl  *
     44       1.39      fvdl  * //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#57 $
     45        1.3  explorer  *
     46       1.39      fvdl  * $FreeBSD: /repoman/r/ncvs/src/sys/dev/aic7xxx/aic7xxx_pci.c,v 1.22 2003/01/20 20:44:55 gibbs Exp $
     47       1.39      fvdl  */
     48       1.39      fvdl /*
     49       1.39      fvdl  * Ported from FreeBSD by Pascal Renauld, Network Storage Solutions, Inc. - April 2003
     50        1.1   mycroft  */
     51       1.42     lukem 
     52       1.42     lukem #include <sys/cdefs.h>
     53  1.58.26.1      yamt __KERNEL_RCSID(0, "$NetBSD: ahc_pci.c,v 1.58.26.1 2007/10/06 15:31:22 yamt Exp $");
     54       1.31     lukem 
     55        1.1   mycroft #include <sys/param.h>
     56        1.1   mycroft #include <sys/systm.h>
     57        1.1   mycroft #include <sys/malloc.h>
     58        1.1   mycroft #include <sys/kernel.h>
     59        1.1   mycroft #include <sys/queue.h>
     60        1.1   mycroft #include <sys/device.h>
     61       1.27  jdolecek #include <sys/reboot.h>
     62       1.21   thorpej 
     63        1.1   mycroft #include <machine/bus.h>
     64        1.1   mycroft #include <machine/intr.h>
     65        1.1   mycroft 
     66       1.22      fvdl #include <dev/pci/pcireg.h>
     67       1.22      fvdl #include <dev/pci/pcivar.h>
     68       1.22      fvdl 
     69       1.47  christos 
     70       1.47  christos /* XXXX some i386 on-board chips act weird when memory-mapped */
     71       1.47  christos #ifndef __i386__
     72       1.47  christos #define AHC_ALLOW_MEMIO
     73       1.47  christos #endif
     74       1.47  christos 
     75       1.22      fvdl #define AHC_PCI_IOADDR	PCI_MAPREG_START	/* I/O Address */
     76       1.22      fvdl #define AHC_PCI_MEMADDR	(PCI_MAPREG_START + 4)	/* Mem I/O Address */
     77       1.22      fvdl 
     78       1.39      fvdl #include <dev/ic/aic7xxx_osm.h>
     79       1.39      fvdl #include <dev/ic/aic7xxx_inline.h>
     80        1.1   mycroft 
     81       1.22      fvdl #include <dev/ic/smc93cx6var.h>
     82        1.1   mycroft 
     83       1.22      fvdl 
     84       1.53     perry static inline uint64_t
     85       1.22      fvdl ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
     86       1.22      fvdl {
     87       1.39      fvdl 	uint64_t id;
     88       1.22      fvdl 
     89       1.22      fvdl 	id = subvendor
     90       1.22      fvdl 	   | (subdevice << 16)
     91       1.39      fvdl 	   | ((uint64_t)vendor << 32)
     92       1.39      fvdl 	   | ((uint64_t)device << 48);
     93       1.22      fvdl 
     94       1.22      fvdl 	return (id);
     95       1.22      fvdl }
     96       1.22      fvdl 
     97       1.39      fvdl #define ID_ALL_MASK			0xFFFFFFFFFFFFFFFFull
     98       1.39      fvdl #define ID_DEV_VENDOR_MASK		0xFFFFFFFF00000000ull
     99       1.39      fvdl #define ID_9005_GENERIC_MASK		0xFFF0FFFF00000000ull
    100       1.39      fvdl #define ID_9005_SISL_MASK		0x000FFFFF00000000ull
    101       1.39      fvdl #define ID_9005_SISL_ID			0x0005900500000000ull
    102       1.39      fvdl #define ID_AIC7850			0x5078900400000000ull
    103       1.39      fvdl #define ID_AHA_2902_04_10_15_20_30C	0x5078900478509004ull
    104       1.39      fvdl #define ID_AIC7855			0x5578900400000000ull
    105       1.39      fvdl #define ID_AIC7859			0x3860900400000000ull
    106       1.39      fvdl #define ID_AHA_2930CU			0x3860900438699004ull
    107       1.39      fvdl #define ID_AIC7860			0x6078900400000000ull
    108       1.39      fvdl #define ID_AIC7860C			0x6078900478609004ull
    109       1.39      fvdl #define ID_AHA_1480A			0x6075900400000000ull
    110       1.39      fvdl #define ID_AHA_2940AU_0			0x6178900400000000ull
    111       1.39      fvdl #define ID_AHA_2940AU_1			0x6178900478619004ull
    112       1.39      fvdl #define ID_AHA_2940AU_CN		0x2178900478219004ull
    113       1.39      fvdl #define ID_AHA_2930C_VAR		0x6038900438689004ull
    114       1.39      fvdl 
    115       1.39      fvdl #define ID_AIC7870			0x7078900400000000ull
    116       1.39      fvdl #define ID_AHA_2940			0x7178900400000000ull
    117       1.39      fvdl #define ID_AHA_3940			0x7278900400000000ull
    118       1.39      fvdl #define ID_AHA_398X			0x7378900400000000ull
    119       1.39      fvdl #define ID_AHA_2944			0x7478900400000000ull
    120       1.39      fvdl #define ID_AHA_3944			0x7578900400000000ull
    121       1.39      fvdl #define ID_AHA_4944			0x7678900400000000ull
    122       1.39      fvdl 
    123       1.39      fvdl #define ID_AIC7880			0x8078900400000000ull
    124       1.39      fvdl #define ID_AIC7880_B			0x8078900478809004ull
    125       1.39      fvdl #define ID_AHA_2940U			0x8178900400000000ull
    126       1.39      fvdl #define ID_AHA_3940U			0x8278900400000000ull
    127       1.39      fvdl #define ID_AHA_2944U			0x8478900400000000ull
    128       1.39      fvdl #define ID_AHA_3944U			0x8578900400000000ull
    129       1.39      fvdl #define ID_AHA_398XU			0x8378900400000000ull
    130       1.39      fvdl #define ID_AHA_4944U			0x8678900400000000ull
    131       1.39      fvdl #define ID_AHA_2940UB			0x8178900478819004ull
    132       1.39      fvdl #define ID_AHA_2930U			0x8878900478889004ull
    133       1.39      fvdl #define ID_AHA_2940U_PRO		0x8778900478879004ull
    134       1.39      fvdl #define ID_AHA_2940U_CN			0x0078900478009004ull
    135       1.39      fvdl 
    136       1.39      fvdl #define ID_AIC7895			0x7895900478959004ull
    137       1.39      fvdl #define ID_AIC7895_ARO			0x7890900478939004ull
    138       1.39      fvdl #define ID_AIC7895_ARO_MASK		0xFFF0FFFFFFFFFFFFull
    139       1.39      fvdl #define ID_AHA_2940U_DUAL		0x7895900478919004ull
    140       1.39      fvdl #define ID_AHA_3940AU			0x7895900478929004ull
    141       1.39      fvdl #define ID_AHA_3944AU			0x7895900478949004ull
    142       1.39      fvdl 
    143       1.39      fvdl #define ID_AIC7890			0x001F9005000F9005ull
    144       1.39      fvdl #define ID_AIC7890_ARO			0x00139005000F9005ull
    145       1.39      fvdl #define ID_AAA_131U2			0x0013900500039005ull
    146       1.39      fvdl #define ID_AHA_2930U2			0x0011900501819005ull
    147       1.39      fvdl #define ID_AHA_2940U2B			0x00109005A1009005ull
    148       1.39      fvdl #define ID_AHA_2940U2_OEM		0x0010900521809005ull
    149       1.39      fvdl #define ID_AHA_2940U2			0x00109005A1809005ull
    150       1.39      fvdl #define ID_AHA_2950U2B			0x00109005E1009005ull
    151       1.39      fvdl 
    152       1.39      fvdl #define ID_AIC7892			0x008F9005FFFF9005ull
    153       1.39      fvdl #define ID_AIC7892_ARO			0x00839005FFFF9005ull
    154       1.43      taca #define ID_AHA_2915LP			0x0082900502109005ull
    155       1.39      fvdl #define ID_AHA_29160			0x00809005E2A09005ull
    156       1.39      fvdl #define ID_AHA_29160_CPQ		0x00809005E2A00E11ull
    157       1.39      fvdl #define ID_AHA_29160N			0x0080900562A09005ull
    158       1.39      fvdl #define ID_AHA_29160C			0x0080900562209005ull
    159       1.39      fvdl #define ID_AHA_29160B			0x00809005E2209005ull
    160       1.39      fvdl #define ID_AHA_19160B			0x0081900562A19005ull
    161       1.39      fvdl 
    162       1.39      fvdl #define ID_AIC7896			0x005F9005FFFF9005ull
    163       1.39      fvdl #define ID_AIC7896_ARO			0x00539005FFFF9005ull
    164       1.39      fvdl #define ID_AHA_3950U2B_0		0x00509005FFFF9005ull
    165       1.39      fvdl #define ID_AHA_3950U2B_1		0x00509005F5009005ull
    166       1.39      fvdl #define ID_AHA_3950U2D_0		0x00519005FFFF9005ull
    167       1.39      fvdl #define ID_AHA_3950U2D_1		0x00519005B5009005ull
    168       1.39      fvdl 
    169       1.39      fvdl #define ID_AIC7899			0x00CF9005FFFF9005ull
    170       1.39      fvdl #define ID_AIC7899_ARO			0x00C39005FFFF9005ull
    171       1.39      fvdl #define ID_AHA_3960D			0x00C09005F6209005ull
    172       1.39      fvdl #define ID_AHA_3960D_CPQ		0x00C09005F6200E11ull
    173       1.39      fvdl 
    174       1.39      fvdl #define ID_AIC7810			0x1078900400000000ull
    175       1.39      fvdl #define ID_AIC7815			0x7815900400000000ull
    176       1.39      fvdl 
    177       1.39      fvdl #define DEVID_9005_TYPE(id) ((id) & 0xF)
    178       1.39      fvdl #define		DEVID_9005_TYPE_HBA		0x0	/* Standard Card */
    179       1.39      fvdl #define		DEVID_9005_TYPE_AAA		0x3	/* RAID Card */
    180       1.39      fvdl #define		DEVID_9005_TYPE_SISL		0x5	/* Container ROMB */
    181       1.39      fvdl #define		DEVID_9005_TYPE_MB		0xF	/* On Motherboard */
    182       1.39      fvdl 
    183       1.39      fvdl #define DEVID_9005_MAXRATE(id) (((id) & 0x30) >> 4)
    184       1.39      fvdl #define		DEVID_9005_MAXRATE_U160		0x0
    185       1.39      fvdl #define		DEVID_9005_MAXRATE_ULTRA2	0x1
    186       1.39      fvdl #define		DEVID_9005_MAXRATE_ULTRA	0x2
    187       1.39      fvdl #define		DEVID_9005_MAXRATE_FAST		0x3
    188       1.39      fvdl 
    189       1.39      fvdl #define DEVID_9005_MFUNC(id) (((id) & 0x40) >> 6)
    190       1.39      fvdl 
    191       1.39      fvdl #define DEVID_9005_CLASS(id) (((id) & 0xFF00) >> 8)
    192       1.39      fvdl #define		DEVID_9005_CLASS_SPI		0x0	/* Parallel SCSI */
    193       1.39      fvdl 
    194       1.39      fvdl #define SUBID_9005_TYPE(id) ((id) & 0xF)
    195       1.39      fvdl #define		SUBID_9005_TYPE_MB		0xF	/* On Motherboard */
    196       1.39      fvdl #define		SUBID_9005_TYPE_CARD		0x0	/* Standard Card */
    197       1.39      fvdl #define		SUBID_9005_TYPE_LCCARD		0x1	/* Low Cost Card */
    198       1.39      fvdl #define		SUBID_9005_TYPE_RAID		0x3	/* Combined with Raid */
    199       1.39      fvdl 
    200       1.39      fvdl #define SUBID_9005_TYPE_KNOWN(id)			\
    201       1.39      fvdl 	  ((((id) & 0xF) == SUBID_9005_TYPE_MB)		\
    202       1.39      fvdl 	|| (((id) & 0xF) == SUBID_9005_TYPE_CARD)	\
    203       1.39      fvdl 	|| (((id) & 0xF) == SUBID_9005_TYPE_LCCARD)	\
    204       1.39      fvdl 	|| (((id) & 0xF) == SUBID_9005_TYPE_RAID))
    205       1.39      fvdl 
    206       1.39      fvdl #define SUBID_9005_MAXRATE(id) (((id) & 0x30) >> 4)
    207       1.39      fvdl #define		SUBID_9005_MAXRATE_ULTRA2	0x0
    208       1.39      fvdl #define		SUBID_9005_MAXRATE_ULTRA	0x1
    209       1.39      fvdl #define		SUBID_9005_MAXRATE_U160		0x2
    210       1.39      fvdl #define		SUBID_9005_MAXRATE_RESERVED	0x3
    211       1.39      fvdl 
    212       1.39      fvdl #define SUBID_9005_SEEPTYPE(id)						\
    213       1.39      fvdl 	((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB)			\
    214       1.39      fvdl 	 ? ((id) & 0xC0) >> 6						\
    215       1.39      fvdl 	 : ((id) & 0x300) >> 8)
    216       1.39      fvdl #define		SUBID_9005_SEEPTYPE_NONE	0x0
    217       1.39      fvdl #define		SUBID_9005_SEEPTYPE_1K		0x1
    218       1.39      fvdl #define		SUBID_9005_SEEPTYPE_2K_4K	0x2
    219       1.39      fvdl #define		SUBID_9005_SEEPTYPE_RESERVED	0x3
    220       1.39      fvdl #define SUBID_9005_AUTOTERM(id)						\
    221       1.39      fvdl 	((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB)			\
    222       1.39      fvdl 	 ? (((id) & 0x400) >> 10) == 0					\
    223       1.39      fvdl 	 : (((id) & 0x40) >> 6) == 0)
    224       1.39      fvdl 
    225       1.39      fvdl #define SUBID_9005_NUMCHAN(id)						\
    226       1.39      fvdl 	((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB)			\
    227       1.39      fvdl 	 ? ((id) & 0x300) >> 8						\
    228       1.39      fvdl 	 : ((id) & 0xC00) >> 10)
    229       1.39      fvdl 
    230       1.39      fvdl #define SUBID_9005_LEGACYCONN(id)					\
    231       1.39      fvdl 	((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB)			\
    232       1.39      fvdl 	 ? 0								\
    233       1.39      fvdl 	 : ((id) & 0x80) >> 7)
    234       1.39      fvdl 
    235       1.39      fvdl #define SUBID_9005_MFUNCENB(id)						\
    236       1.39      fvdl 	((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB)			\
    237       1.39      fvdl 	 ? ((id) & 0x800) >> 11						\
    238       1.39      fvdl 	 : ((id) & 0x1000) >> 12)
    239       1.39      fvdl /*
    240       1.39      fvdl  * Informational only. Should use chip register to be
    241       1.39      fvdl  * certain, but may be use in identification strings.
    242       1.39      fvdl  */
    243       1.39      fvdl #define SUBID_9005_CARD_SCSIWIDTH_MASK	0x2000
    244       1.39      fvdl #define SUBID_9005_CARD_PCIWIDTH_MASK	0x4000
    245       1.39      fvdl #define SUBID_9005_CARD_SEDIFF_MASK	0x8000
    246       1.39      fvdl 
    247       1.39      fvdl static ahc_device_setup_t ahc_aic785X_setup;
    248       1.22      fvdl static ahc_device_setup_t ahc_aic7860_setup;
    249       1.39      fvdl static ahc_device_setup_t ahc_apa1480_setup;
    250       1.22      fvdl static ahc_device_setup_t ahc_aic7870_setup;
    251       1.22      fvdl static ahc_device_setup_t ahc_aha394X_setup;
    252       1.39      fvdl static ahc_device_setup_t ahc_aha494X_setup;
    253       1.22      fvdl static ahc_device_setup_t ahc_aha398X_setup;
    254       1.22      fvdl static ahc_device_setup_t ahc_aic7880_setup;
    255       1.39      fvdl static ahc_device_setup_t ahc_aha2940Pro_setup;
    256       1.22      fvdl static ahc_device_setup_t ahc_aha394XU_setup;
    257       1.22      fvdl static ahc_device_setup_t ahc_aha398XU_setup;
    258       1.22      fvdl static ahc_device_setup_t ahc_aic7890_setup;
    259       1.22      fvdl static ahc_device_setup_t ahc_aic7892_setup;
    260       1.22      fvdl static ahc_device_setup_t ahc_aic7895_setup;
    261       1.22      fvdl static ahc_device_setup_t ahc_aic7896_setup;
    262       1.22      fvdl static ahc_device_setup_t ahc_aic7899_setup;
    263       1.39      fvdl static ahc_device_setup_t ahc_aha29160C_setup;
    264       1.22      fvdl static ahc_device_setup_t ahc_raid_setup;
    265       1.22      fvdl static ahc_device_setup_t ahc_aha394XX_setup;
    266       1.39      fvdl static ahc_device_setup_t ahc_aha494XX_setup;
    267       1.22      fvdl static ahc_device_setup_t ahc_aha398XX_setup;
    268       1.22      fvdl 
    269       1.51   thorpej static struct ahc_pci_identity ahc_pci_ident_table [] =
    270       1.22      fvdl {
    271       1.22      fvdl 	/* aic7850 based controllers */
    272       1.22      fvdl 	{
    273       1.39      fvdl 		ID_AHA_2902_04_10_15_20_30C,
    274       1.22      fvdl 		ID_ALL_MASK,
    275       1.39      fvdl 		"Adaptec 2902/04/10/15/20/30C SCSI adapter",
    276       1.39      fvdl 		ahc_aic785X_setup
    277       1.22      fvdl 	},
    278       1.39      fvdl 	/* aic7860 based controllers */
    279       1.22      fvdl 	{
    280       1.22      fvdl 		ID_AHA_2930CU,
    281       1.22      fvdl 		ID_ALL_MASK,
    282       1.22      fvdl 		"Adaptec 2930CU SCSI adapter",
    283       1.39      fvdl 		ahc_aic7860_setup
    284       1.39      fvdl 	},
    285       1.39      fvdl 	{
    286       1.39      fvdl 		ID_AHA_1480A & ID_DEV_VENDOR_MASK,
    287       1.39      fvdl 		ID_DEV_VENDOR_MASK,
    288       1.39      fvdl 		"Adaptec 1480A Ultra SCSI adapter",
    289       1.39      fvdl 		ahc_apa1480_setup
    290       1.22      fvdl 	},
    291       1.22      fvdl 	{
    292       1.22      fvdl 		ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK,
    293       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    294       1.22      fvdl 		"Adaptec 2940A Ultra SCSI adapter",
    295       1.22      fvdl 		ahc_aic7860_setup
    296       1.22      fvdl 	},
    297       1.22      fvdl 	{
    298       1.22      fvdl 		ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK,
    299       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    300       1.22      fvdl 		"Adaptec 2940A/CN Ultra SCSI adapter",
    301       1.22      fvdl 		ahc_aic7860_setup
    302       1.22      fvdl 	},
    303       1.22      fvdl 	{
    304       1.22      fvdl 		ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK,
    305       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    306       1.39      fvdl 		"Adaptec 2930C Ultra SCSI adapter (VAR)",
    307       1.22      fvdl 		ahc_aic7860_setup
    308       1.22      fvdl 	},
    309       1.22      fvdl 	/* aic7870 based controllers */
    310       1.22      fvdl 	{
    311       1.22      fvdl 		ID_AHA_2940,
    312       1.22      fvdl 		ID_ALL_MASK,
    313       1.22      fvdl 		"Adaptec 2940 SCSI adapter",
    314       1.22      fvdl 		ahc_aic7870_setup
    315       1.22      fvdl 	},
    316       1.22      fvdl 	{
    317       1.22      fvdl 		ID_AHA_3940,
    318       1.22      fvdl 		ID_ALL_MASK,
    319       1.22      fvdl 		"Adaptec 3940 SCSI adapter",
    320       1.22      fvdl 		ahc_aha394X_setup
    321       1.22      fvdl 	},
    322       1.22      fvdl 	{
    323       1.22      fvdl 		ID_AHA_398X,
    324       1.22      fvdl 		ID_ALL_MASK,
    325       1.22      fvdl 		"Adaptec 398X SCSI RAID adapter",
    326       1.22      fvdl 		ahc_aha398X_setup
    327       1.22      fvdl 	},
    328       1.22      fvdl 	{
    329       1.22      fvdl 		ID_AHA_2944,
    330       1.22      fvdl 		ID_ALL_MASK,
    331       1.22      fvdl 		"Adaptec 2944 SCSI adapter",
    332       1.22      fvdl 		ahc_aic7870_setup
    333       1.22      fvdl 	},
    334       1.22      fvdl 	{
    335       1.22      fvdl 		ID_AHA_3944,
    336       1.22      fvdl 		ID_ALL_MASK,
    337       1.22      fvdl 		"Adaptec 3944 SCSI adapter",
    338       1.22      fvdl 		ahc_aha394X_setup
    339       1.22      fvdl 	},
    340       1.39      fvdl 	{
    341       1.39      fvdl 		ID_AHA_4944,
    342       1.39      fvdl 		ID_ALL_MASK,
    343       1.39      fvdl 		"Adaptec 4944 SCSI adapter",
    344       1.39      fvdl 		ahc_aha494X_setup
    345       1.39      fvdl 	},
    346       1.22      fvdl 	/* aic7880 based controllers */
    347       1.22      fvdl 	{
    348       1.22      fvdl 		ID_AHA_2940U & ID_DEV_VENDOR_MASK,
    349       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    350       1.22      fvdl 		"Adaptec 2940 Ultra SCSI adapter",
    351       1.22      fvdl 		ahc_aic7880_setup
    352       1.22      fvdl 	},
    353       1.22      fvdl 	{
    354       1.22      fvdl 		ID_AHA_3940U & ID_DEV_VENDOR_MASK,
    355       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    356       1.22      fvdl 		"Adaptec 3940 Ultra SCSI adapter",
    357       1.22      fvdl 		ahc_aha394XU_setup
    358       1.22      fvdl 	},
    359       1.22      fvdl 	{
    360       1.22      fvdl 		ID_AHA_2944U & ID_DEV_VENDOR_MASK,
    361       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    362       1.22      fvdl 		"Adaptec 2944 Ultra SCSI adapter",
    363       1.22      fvdl 		ahc_aic7880_setup
    364       1.22      fvdl 	},
    365       1.22      fvdl 	{
    366       1.22      fvdl 		ID_AHA_3944U & ID_DEV_VENDOR_MASK,
    367       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    368       1.22      fvdl 		"Adaptec 3944 Ultra SCSI adapter",
    369       1.22      fvdl 		ahc_aha394XU_setup
    370       1.22      fvdl 	},
    371       1.22      fvdl 	{
    372       1.22      fvdl 		ID_AHA_398XU & ID_DEV_VENDOR_MASK,
    373       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    374       1.22      fvdl 		"Adaptec 398X Ultra SCSI RAID adapter",
    375       1.22      fvdl 		ahc_aha398XU_setup
    376       1.22      fvdl 	},
    377       1.22      fvdl 	{
    378       1.22      fvdl 		/*
    379       1.22      fvdl 		 * XXX Don't know the slot numbers
    380       1.22      fvdl 		 * so we can't identify channels
    381       1.22      fvdl 		 */
    382       1.22      fvdl 		ID_AHA_4944U & ID_DEV_VENDOR_MASK,
    383       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    384       1.22      fvdl 		"Adaptec 4944 Ultra SCSI adapter",
    385       1.22      fvdl 		ahc_aic7880_setup
    386       1.22      fvdl 	},
    387       1.22      fvdl 	{
    388       1.22      fvdl 		ID_AHA_2930U & ID_DEV_VENDOR_MASK,
    389       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    390       1.22      fvdl 		"Adaptec 2930 Ultra SCSI adapter",
    391       1.22      fvdl 		ahc_aic7880_setup
    392       1.22      fvdl 	},
    393       1.22      fvdl 	{
    394       1.22      fvdl 		ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK,
    395       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    396       1.22      fvdl 		"Adaptec 2940 Pro Ultra SCSI adapter",
    397       1.39      fvdl 		ahc_aha2940Pro_setup
    398       1.22      fvdl 	},
    399       1.22      fvdl 	{
    400       1.22      fvdl 		ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK,
    401       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    402       1.22      fvdl 		"Adaptec 2940/CN Ultra SCSI adapter",
    403       1.22      fvdl 		ahc_aic7880_setup
    404       1.22      fvdl 	},
    405       1.39      fvdl 	/* Ignore all SISL (AAC on MB) based controllers. */
    406       1.39      fvdl 	{
    407       1.39      fvdl 		ID_9005_SISL_ID,
    408       1.39      fvdl 		ID_9005_SISL_MASK,
    409       1.39      fvdl 		NULL,
    410       1.39      fvdl 		NULL
    411       1.39      fvdl 	},
    412       1.22      fvdl 	/* aic7890 based controllers */
    413       1.22      fvdl 	{
    414       1.22      fvdl 		ID_AHA_2930U2,
    415       1.22      fvdl 		ID_ALL_MASK,
    416       1.22      fvdl 		"Adaptec 2930 Ultra2 SCSI adapter",
    417       1.22      fvdl 		ahc_aic7890_setup
    418       1.22      fvdl 	},
    419       1.22      fvdl 	{
    420       1.22      fvdl 		ID_AHA_2940U2B,
    421       1.22      fvdl 		ID_ALL_MASK,
    422       1.22      fvdl 		"Adaptec 2940B Ultra2 SCSI adapter",
    423       1.22      fvdl 		ahc_aic7890_setup
    424       1.22      fvdl 	},
    425       1.22      fvdl 	{
    426       1.22      fvdl 		ID_AHA_2940U2_OEM,
    427       1.22      fvdl 		ID_ALL_MASK,
    428       1.22      fvdl 		"Adaptec 2940 Ultra2 SCSI adapter (OEM)",
    429       1.22      fvdl 		ahc_aic7890_setup
    430       1.22      fvdl 	},
    431       1.22      fvdl 	{
    432       1.22      fvdl 		ID_AHA_2940U2,
    433       1.22      fvdl 		ID_ALL_MASK,
    434       1.22      fvdl 		"Adaptec 2940 Ultra2 SCSI adapter",
    435       1.22      fvdl 		ahc_aic7890_setup
    436       1.22      fvdl 	},
    437       1.22      fvdl 	{
    438       1.22      fvdl 		ID_AHA_2950U2B,
    439       1.22      fvdl 		ID_ALL_MASK,
    440       1.22      fvdl 		"Adaptec 2950 Ultra2 SCSI adapter",
    441       1.22      fvdl 		ahc_aic7890_setup
    442       1.22      fvdl 	},
    443       1.25     soren 	{
    444       1.39      fvdl 		ID_AIC7890_ARO,
    445       1.39      fvdl 		ID_ALL_MASK,
    446       1.39      fvdl 		"Adaptec aic7890/91 Ultra2 SCSI adapter (ARO)",
    447       1.39      fvdl 		ahc_aic7890_setup
    448       1.39      fvdl 	},
    449       1.39      fvdl 	{
    450       1.25     soren 		ID_AAA_131U2,
    451       1.25     soren 		ID_ALL_MASK,
    452       1.25     soren 		"Adaptec AAA-131 Ultra2 RAID adapter",
    453       1.25     soren 		ahc_aic7890_setup
    454       1.39      fvdl 	},
    455       1.22      fvdl 	/* aic7892 based controllers */
    456       1.22      fvdl 	{
    457       1.22      fvdl 		ID_AHA_29160,
    458       1.22      fvdl 		ID_ALL_MASK,
    459       1.22      fvdl 		"Adaptec 29160 Ultra160 SCSI adapter",
    460       1.22      fvdl 		ahc_aic7892_setup
    461       1.22      fvdl 	},
    462       1.22      fvdl 	{
    463       1.22      fvdl 		ID_AHA_29160_CPQ,
    464       1.22      fvdl 		ID_ALL_MASK,
    465       1.22      fvdl 		"Adaptec (Compaq OEM) 29160 Ultra160 SCSI adapter",
    466       1.22      fvdl 		ahc_aic7892_setup
    467       1.22      fvdl 	},
    468       1.22      fvdl 	{
    469       1.22      fvdl 		ID_AHA_29160N,
    470       1.22      fvdl 		ID_ALL_MASK,
    471       1.22      fvdl 		"Adaptec 29160N Ultra160 SCSI adapter",
    472       1.22      fvdl 		ahc_aic7892_setup
    473       1.22      fvdl 	},
    474       1.22      fvdl 	{
    475       1.39      fvdl 		ID_AHA_29160C,
    476       1.39      fvdl 		ID_ALL_MASK,
    477       1.39      fvdl 		"Adaptec 29160C Ultra160 SCSI adapter",
    478       1.39      fvdl 		ahc_aha29160C_setup
    479       1.39      fvdl 	},
    480       1.39      fvdl 	{
    481       1.22      fvdl 		ID_AHA_29160B,
    482       1.22      fvdl 		ID_ALL_MASK,
    483       1.22      fvdl 		"Adaptec 29160B Ultra160 SCSI adapter",
    484       1.22      fvdl 		ahc_aic7892_setup
    485       1.22      fvdl 	},
    486       1.22      fvdl 	{
    487       1.22      fvdl 		ID_AHA_19160B,
    488       1.22      fvdl 		ID_ALL_MASK,
    489       1.22      fvdl 		"Adaptec 19160B Ultra160 SCSI adapter",
    490       1.22      fvdl 		ahc_aic7892_setup
    491       1.22      fvdl 	},
    492       1.39      fvdl 	{
    493       1.39      fvdl 		ID_AIC7892_ARO,
    494       1.39      fvdl 		ID_ALL_MASK,
    495       1.39      fvdl 		"Adaptec aic7892 Ultra160 SCSI adapter (ARO)",
    496       1.43      taca 		ahc_aic7892_setup
    497       1.43      taca 	},
    498       1.43      taca 	{
    499       1.43      taca 		ID_AHA_2915LP,
    500       1.43      taca 		ID_ALL_MASK,
    501       1.43      taca 		"Adaptec 2915LP Ultra160 SCSI adapter",
    502       1.39      fvdl 		ahc_aic7892_setup
    503       1.39      fvdl 	},
    504       1.49     perry 	/* aic7895 based controllers */
    505       1.22      fvdl 	{
    506       1.22      fvdl 		ID_AHA_2940U_DUAL,
    507       1.22      fvdl 		ID_ALL_MASK,
    508       1.22      fvdl 		"Adaptec 2940/DUAL Ultra SCSI adapter",
    509       1.22      fvdl 		ahc_aic7895_setup
    510       1.22      fvdl 	},
    511       1.22      fvdl 	{
    512       1.22      fvdl 		ID_AHA_3940AU,
    513       1.22      fvdl 		ID_ALL_MASK,
    514       1.22      fvdl 		"Adaptec 3940A Ultra SCSI adapter",
    515       1.22      fvdl 		ahc_aic7895_setup
    516       1.22      fvdl 	},
    517       1.22      fvdl 	{
    518       1.22      fvdl 		ID_AHA_3944AU,
    519       1.22      fvdl 		ID_ALL_MASK,
    520       1.22      fvdl 		"Adaptec 3944A Ultra SCSI adapter",
    521       1.22      fvdl 		ahc_aic7895_setup
    522       1.22      fvdl 	},
    523       1.39      fvdl 	{
    524       1.39      fvdl 		ID_AIC7895_ARO,
    525       1.39      fvdl 		ID_AIC7895_ARO_MASK,
    526       1.39      fvdl 		"Adaptec aic7895 Ultra SCSI adapter (ARO)",
    527       1.39      fvdl 		ahc_aic7895_setup
    528       1.39      fvdl 	},
    529       1.49     perry 	/* aic7896/97 based controllers */
    530       1.22      fvdl 	{
    531       1.22      fvdl 		ID_AHA_3950U2B_0,
    532       1.22      fvdl 		ID_ALL_MASK,
    533       1.22      fvdl 		"Adaptec 3950B Ultra2 SCSI adapter",
    534       1.22      fvdl 		ahc_aic7896_setup
    535       1.22      fvdl 	},
    536       1.22      fvdl 	{
    537       1.22      fvdl 		ID_AHA_3950U2B_1,
    538       1.22      fvdl 		ID_ALL_MASK,
    539       1.22      fvdl 		"Adaptec 3950B Ultra2 SCSI adapter",
    540       1.22      fvdl 		ahc_aic7896_setup
    541       1.22      fvdl 	},
    542       1.22      fvdl 	{
    543       1.22      fvdl 		ID_AHA_3950U2D_0,
    544       1.22      fvdl 		ID_ALL_MASK,
    545       1.22      fvdl 		"Adaptec 3950D Ultra2 SCSI adapter",
    546       1.22      fvdl 		ahc_aic7896_setup
    547       1.22      fvdl 	},
    548       1.22      fvdl 	{
    549       1.22      fvdl 		ID_AHA_3950U2D_1,
    550       1.22      fvdl 		ID_ALL_MASK,
    551       1.22      fvdl 		"Adaptec 3950D Ultra2 SCSI adapter",
    552       1.22      fvdl 		ahc_aic7896_setup
    553       1.22      fvdl 	},
    554       1.39      fvdl 	{
    555       1.39      fvdl 		ID_AIC7896_ARO,
    556       1.39      fvdl 		ID_ALL_MASK,
    557       1.39      fvdl 		"Adaptec aic7896/97 Ultra2 SCSI adapter (ARO)",
    558       1.39      fvdl 		ahc_aic7896_setup
    559       1.39      fvdl 	},
    560       1.49     perry 	/* aic7899 based controllers */
    561       1.22      fvdl 	{
    562       1.22      fvdl 		ID_AHA_3960D,
    563       1.22      fvdl 		ID_ALL_MASK,
    564       1.22      fvdl 		"Adaptec 3960D Ultra160 SCSI adapter",
    565       1.22      fvdl 		ahc_aic7899_setup
    566       1.22      fvdl 	},
    567       1.22      fvdl 	{
    568       1.22      fvdl 		ID_AHA_3960D_CPQ,
    569       1.22      fvdl 		ID_ALL_MASK,
    570       1.22      fvdl 		"Adaptec (Compaq OEM) 3960D Ultra160 SCSI adapter",
    571       1.22      fvdl 		ahc_aic7899_setup
    572       1.22      fvdl 	},
    573       1.39      fvdl 	{
    574       1.39      fvdl 		ID_AIC7899_ARO,
    575       1.39      fvdl 		ID_ALL_MASK,
    576       1.39      fvdl 		"Adaptec aic7899 Ultra160 SCSI adapter (ARO)",
    577       1.39      fvdl 		ahc_aic7899_setup
    578       1.39      fvdl 	},
    579       1.22      fvdl 	/* Generic chip probes for devices we don't know 'exactly' */
    580       1.22      fvdl 	{
    581       1.22      fvdl 		ID_AIC7850 & ID_DEV_VENDOR_MASK,
    582       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    583       1.22      fvdl 		"Adaptec aic7850 SCSI adapter",
    584       1.39      fvdl 		ahc_aic785X_setup
    585       1.22      fvdl 	},
    586       1.22      fvdl 	{
    587       1.22      fvdl 		ID_AIC7855 & ID_DEV_VENDOR_MASK,
    588       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    589       1.22      fvdl 		"Adaptec aic7855 SCSI adapter",
    590       1.39      fvdl 		ahc_aic785X_setup
    591       1.22      fvdl 	},
    592       1.22      fvdl 	{
    593       1.22      fvdl 		ID_AIC7859 & ID_DEV_VENDOR_MASK,
    594       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    595       1.22      fvdl 		"Adaptec aic7859 SCSI adapter",
    596       1.39      fvdl 		ahc_aic7860_setup
    597       1.22      fvdl 	},
    598       1.22      fvdl 	{
    599       1.22      fvdl 		ID_AIC7860 & ID_DEV_VENDOR_MASK,
    600       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    601       1.39      fvdl 		"Adaptec aic7860 Ultra SCSI adapter",
    602       1.22      fvdl 		ahc_aic7860_setup
    603       1.22      fvdl 	},
    604       1.22      fvdl 	{
    605       1.22      fvdl 		ID_AIC7870 & ID_DEV_VENDOR_MASK,
    606       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    607       1.22      fvdl 		"Adaptec aic7870 SCSI adapter",
    608       1.22      fvdl 		ahc_aic7870_setup
    609       1.22      fvdl 	},
    610       1.22      fvdl 	{
    611       1.22      fvdl 		ID_AIC7880 & ID_DEV_VENDOR_MASK,
    612       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    613       1.22      fvdl 		"Adaptec aic7880 Ultra SCSI adapter",
    614       1.22      fvdl 		ahc_aic7880_setup
    615       1.22      fvdl 	},
    616       1.22      fvdl 	{
    617       1.39      fvdl 		ID_AIC7890 & ID_9005_GENERIC_MASK,
    618       1.39      fvdl 		ID_9005_GENERIC_MASK,
    619       1.22      fvdl 		"Adaptec aic7890/91 Ultra2 SCSI adapter",
    620       1.22      fvdl 		ahc_aic7890_setup
    621       1.22      fvdl 	},
    622       1.22      fvdl 	{
    623       1.39      fvdl 		ID_AIC7892 & ID_9005_GENERIC_MASK,
    624       1.39      fvdl 		ID_9005_GENERIC_MASK,
    625       1.22      fvdl 		"Adaptec aic7892 Ultra160 SCSI adapter",
    626       1.22      fvdl 		ahc_aic7892_setup
    627       1.22      fvdl 	},
    628       1.22      fvdl 	{
    629       1.22      fvdl 		ID_AIC7895 & ID_DEV_VENDOR_MASK,
    630       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    631       1.22      fvdl 		"Adaptec aic7895 Ultra SCSI adapter",
    632       1.22      fvdl 		ahc_aic7895_setup
    633       1.22      fvdl 	},
    634       1.22      fvdl 	{
    635       1.39      fvdl 		ID_AIC7896 & ID_9005_GENERIC_MASK,
    636       1.39      fvdl 		ID_9005_GENERIC_MASK,
    637       1.22      fvdl 		"Adaptec aic7896/97 Ultra2 SCSI adapter",
    638       1.22      fvdl 		ahc_aic7896_setup
    639       1.22      fvdl 	},
    640       1.22      fvdl 	{
    641       1.39      fvdl 		ID_AIC7899 & ID_9005_GENERIC_MASK,
    642       1.39      fvdl 		ID_9005_GENERIC_MASK,
    643       1.22      fvdl 		"Adaptec aic7899 Ultra160 SCSI adapter",
    644       1.22      fvdl 		ahc_aic7899_setup
    645       1.22      fvdl 	},
    646       1.22      fvdl 	{
    647       1.22      fvdl 		ID_AIC7810 & ID_DEV_VENDOR_MASK,
    648       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    649       1.22      fvdl 		"Adaptec aic7810 RAID memory controller",
    650       1.22      fvdl 		ahc_raid_setup
    651       1.22      fvdl 	},
    652       1.22      fvdl 	{
    653       1.22      fvdl 		ID_AIC7815 & ID_DEV_VENDOR_MASK,
    654       1.22      fvdl 		ID_DEV_VENDOR_MASK,
    655       1.22      fvdl 		"Adaptec aic7815 RAID memory controller",
    656       1.22      fvdl 		ahc_raid_setup
    657       1.22      fvdl 	}
    658       1.22      fvdl };
    659       1.12       cgd 
    660       1.51   thorpej static const u_int ahc_num_pci_devs = NUM_ELEMENTS(ahc_pci_ident_table);
    661       1.49     perry 
    662       1.22      fvdl #define AHC_394X_SLOT_CHANNEL_A	4
    663       1.22      fvdl #define AHC_394X_SLOT_CHANNEL_B	5
    664       1.22      fvdl 
    665       1.22      fvdl #define AHC_398X_SLOT_CHANNEL_A	4
    666       1.22      fvdl #define AHC_398X_SLOT_CHANNEL_B	8
    667       1.22      fvdl #define AHC_398X_SLOT_CHANNEL_C	12
    668        1.1   mycroft 
    669       1.39      fvdl #define AHC_494X_SLOT_CHANNEL_A	4
    670       1.39      fvdl #define AHC_494X_SLOT_CHANNEL_B	5
    671       1.39      fvdl #define AHC_494X_SLOT_CHANNEL_C	6
    672       1.39      fvdl #define AHC_494X_SLOT_CHANNEL_D	7
    673       1.39      fvdl 
    674        1.1   mycroft #define	DEVCONFIG		0x40
    675       1.39      fvdl #define		PCIERRGENDIS	0x80000000ul
    676       1.39      fvdl #define		SCBSIZE32	0x00010000ul	/* aic789X only */
    677       1.39      fvdl #define		REXTVALID	0x00001000ul	/* ultra cards only */
    678       1.39      fvdl #define		MPORTMODE	0x00000400ul	/* aic7870+ only */
    679       1.39      fvdl #define		RAMPSM		0x00000200ul	/* aic7870+ only */
    680       1.39      fvdl #define		VOLSENSE	0x00000100ul
    681       1.39      fvdl #define		PCI64BIT	0x00000080ul	/* 64Bit PCI bus (Ultra2 Only)*/
    682       1.39      fvdl #define		SCBRAMSEL	0x00000080ul
    683       1.39      fvdl #define		MRDCEN		0x00000040ul
    684       1.39      fvdl #define		EXTSCBTIME	0x00000020ul	/* aic7870 only */
    685       1.39      fvdl #define		EXTSCBPEN	0x00000010ul	/* aic7870 only */
    686       1.39      fvdl #define		BERREN		0x00000008ul
    687       1.39      fvdl #define		DACEN		0x00000004ul
    688       1.39      fvdl #define		STPWLEVEL	0x00000002ul
    689       1.39      fvdl #define		DIFACTNEGEN	0x00000001ul	/* aic7870 only */
    690        1.1   mycroft 
    691        1.1   mycroft #define	CSIZE_LATTIME		0x0c
    692       1.39      fvdl #define		CACHESIZE	0x0000003ful	/* only 5 bits */
    693       1.39      fvdl #define		LATTIME		0x0000ff00ul
    694       1.39      fvdl 
    695       1.39      fvdl /* PCI STATUS definitions */
    696       1.39      fvdl #define	DPE	0x80
    697       1.39      fvdl #define SSE	0x40
    698       1.39      fvdl #define	RMA	0x20
    699       1.39      fvdl #define	RTA	0x10
    700       1.39      fvdl #define STA	0x08
    701       1.39      fvdl #define DPR	0x01
    702        1.1   mycroft 
    703       1.39      fvdl static int ahc_9005_subdevinfo_valid(uint16_t vendor, uint16_t device,
    704       1.39      fvdl 				     uint16_t subvendor, uint16_t subdevice);
    705       1.22      fvdl static int ahc_ext_scbram_present(struct ahc_softc *ahc);
    706       1.39      fvdl static void ahc_scbram_config(struct ahc_softc *ahc, int enable,
    707       1.39      fvdl 				  int pcheck, int fast, int large);
    708       1.22      fvdl static void ahc_probe_ext_scbram(struct ahc_softc *ahc);
    709        1.1   mycroft 
    710       1.51   thorpej static void ahc_pci_intr(struct ahc_softc *);
    711        1.1   mycroft 
    712       1.51   thorpej static const struct ahc_pci_identity *
    713       1.51   thorpej ahc_find_pci_device(pcireg_t id, pcireg_t subid, u_int func)
    714       1.22      fvdl {
    715       1.22      fvdl 	u_int64_t  full_id;
    716       1.29  jdolecek 	const struct	   ahc_pci_identity *entry;
    717       1.22      fvdl 	u_int	   i;
    718       1.22      fvdl 
    719       1.22      fvdl 	full_id = ahc_compose_id(PCI_PRODUCT(id), PCI_VENDOR(id),
    720       1.22      fvdl 				 PCI_PRODUCT(subid), PCI_VENDOR(subid));
    721       1.22      fvdl 
    722       1.39      fvdl 	/*
    723       1.39      fvdl 	 * If the second function is not hooked up, ignore it.
    724       1.39      fvdl 	 * Unfortunately, not all MB vendors implement the
    725       1.39      fvdl 	 * subdevice ID as per the Adaptec spec, so do our best
    726       1.39      fvdl 	 * to sanity check it prior to accepting the subdevice
    727       1.39      fvdl 	 * ID as valid.
    728       1.39      fvdl 	 */
    729       1.39      fvdl 	if (func > 0
    730       1.49     perry 	    && ahc_9005_subdevinfo_valid(PCI_VENDOR(id), PCI_PRODUCT(id),
    731       1.39      fvdl 					 PCI_VENDOR(subid), PCI_PRODUCT(subid))
    732       1.39      fvdl 	    && SUBID_9005_MFUNCENB(PCI_PRODUCT(subid)) == 0)
    733       1.39      fvdl 		return (NULL);
    734       1.39      fvdl 
    735       1.22      fvdl 	for (i = 0; i < ahc_num_pci_devs; i++) {
    736       1.22      fvdl 		entry = &ahc_pci_ident_table[i];
    737       1.22      fvdl 		if (entry->full_id == (full_id & entry->id_mask))
    738       1.22      fvdl 			return (entry);
    739       1.22      fvdl 	}
    740       1.22      fvdl 	return (NULL);
    741       1.22      fvdl }
    742       1.22      fvdl 
    743       1.51   thorpej static int
    744       1.58  christos ahc_pci_probe(struct device *parent, struct cfdata *match,
    745       1.57  christos     void *aux)
    746       1.22      fvdl {
    747       1.22      fvdl 	struct pci_attach_args *pa = aux;
    748       1.29  jdolecek 	const struct	   ahc_pci_identity *entry;
    749       1.22      fvdl 	pcireg_t   subid;
    750       1.22      fvdl 
    751       1.22      fvdl 	subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
    752       1.39      fvdl 	entry = ahc_find_pci_device(pa->pa_id, subid, pa->pa_function);
    753       1.41        pk 	return (entry != NULL && entry->setup != NULL) ? 1 : 0;
    754        1.1   mycroft }
    755        1.1   mycroft 
    756       1.51   thorpej static void
    757       1.58  christos ahc_pci_attach(struct device *parent, struct device *self, void *aux)
    758        1.1   mycroft {
    759        1.1   mycroft 	struct pci_attach_args *pa = aux;
    760       1.29  jdolecek 	const struct	   ahc_pci_identity *entry;
    761       1.22      fvdl 	struct		   ahc_softc *ahc = (void *)self;
    762       1.22      fvdl 	pcireg_t	   command;
    763       1.22      fvdl 	u_int		   our_id = 0;
    764       1.22      fvdl 	u_int		   sxfrctl1;
    765       1.22      fvdl 	u_int		   scsiseq;
    766       1.39      fvdl 	u_int		   sblkctl;
    767       1.39      fvdl 	uint8_t 	   dscommand0;
    768       1.39      fvdl 	uint32_t	   devconfig;
    769       1.22      fvdl 	int		   error;
    770       1.22      fvdl 	pcireg_t	   subid;
    771       1.45    simonb 	int		   ioh_valid;
    772       1.39      fvdl 	bus_space_tag_t    st, iot;
    773       1.22      fvdl 	bus_space_handle_t sh, ioh;
    774       1.22      fvdl #ifdef AHC_ALLOW_MEMIO
    775       1.45    simonb 	int		   memh_valid;
    776       1.39      fvdl 	bus_space_tag_t    memt;
    777       1.22      fvdl 	bus_space_handle_t memh;
    778       1.24   thorpej 	pcireg_t memtype;
    779       1.22      fvdl #endif
    780       1.39      fvdl 	pci_intr_handle_t  ih;
    781       1.39      fvdl 	const char        *intrstr;
    782       1.22      fvdl 	struct ahc_pci_busdata *bd;
    783  1.58.26.1      yamt 	bool               override_ultra;
    784       1.22      fvdl 
    785       1.39      fvdl 	ahc_set_name(ahc, ahc->sc_dev.dv_xname);
    786       1.39      fvdl 	ahc->parent_dmat = pa->pa_dmat;
    787       1.38   thorpej 
    788       1.22      fvdl 	command = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
    789       1.22      fvdl 	subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
    790       1.39      fvdl 	entry = ahc_find_pci_device(pa->pa_id, subid, pa->pa_function);
    791       1.22      fvdl 	if (entry == NULL)
    792       1.22      fvdl 		return;
    793       1.44  augustss 	printf(": %s\n", entry->name);
    794       1.39      fvdl 
    795       1.39      fvdl 	/* Keep information about the PCI bus */
    796       1.39      fvdl 	bd = malloc(sizeof (struct ahc_pci_busdata), M_DEVBUF, M_NOWAIT);
    797       1.39      fvdl 	if (bd == NULL) {
    798       1.46  christos 		printf("%s: unable to allocate bus-specific data\n",
    799       1.46  christos 		    ahc_name(ahc));
    800       1.39      fvdl 		return;
    801       1.39      fvdl 	}
    802       1.39      fvdl 	memset(bd, 0, sizeof(struct ahc_pci_busdata));
    803       1.39      fvdl 
    804       1.39      fvdl 	bd->pc = pa->pa_pc;
    805       1.39      fvdl 	bd->tag = pa->pa_tag;
    806       1.39      fvdl 	bd->func = pa->pa_function;
    807       1.39      fvdl 	bd->dev = pa->pa_device;
    808       1.39      fvdl 	bd->class = pa->pa_class;
    809       1.39      fvdl 
    810       1.39      fvdl 	ahc->bd = bd;
    811       1.39      fvdl 
    812       1.39      fvdl 	ahc->description = entry->name;
    813       1.39      fvdl 
    814       1.39      fvdl 	error = entry->setup(ahc);
    815       1.22      fvdl 	if (error != 0)
    816       1.22      fvdl 		return;
    817       1.22      fvdl 
    818       1.45    simonb 	ioh_valid = 0;
    819       1.22      fvdl 
    820       1.22      fvdl #ifdef AHC_ALLOW_MEMIO
    821       1.45    simonb 	memh_valid = 0;
    822       1.24   thorpej 	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, AHC_PCI_MEMADDR);
    823       1.24   thorpej 	switch (memtype) {
    824       1.24   thorpej 	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
    825       1.24   thorpej 	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
    826       1.24   thorpej 		memh_valid = (pci_mapreg_map(pa, AHC_PCI_MEMADDR,
    827       1.39      fvdl 					     memtype, 0, &memt, &memh, NULL, NULL) == 0);
    828       1.24   thorpej 		break;
    829       1.24   thorpej 	default:
    830       1.24   thorpej 		memh_valid = 0;
    831       1.24   thorpej 	}
    832       1.22      fvdl #endif
    833       1.22      fvdl 	ioh_valid = (pci_mapreg_map(pa, AHC_PCI_IOADDR,
    834       1.49     perry 				    PCI_MAPREG_TYPE_IO, 0, &iot,
    835       1.39      fvdl 				    &ioh, NULL, NULL) == 0);
    836       1.39      fvdl #if 0
    837       1.46  christos 	printf("%s: bus info: memt 0x%lx, memh 0x%lx, iot 0x%lx, ioh 0x%lx\n",
    838       1.46  christos 	    ahc_name(ahc), (u_long)memt, (u_long)memh, (u_long)iot,
    839       1.46  christos 	    (u_long)ioh);
    840       1.39      fvdl #endif
    841       1.13       cgd 
    842       1.22      fvdl 	if (ioh_valid) {
    843       1.22      fvdl 		st = iot;
    844       1.22      fvdl 		sh = ioh;
    845       1.22      fvdl #ifdef AHC_ALLOW_MEMIO
    846       1.22      fvdl 	} else if (memh_valid) {
    847       1.13       cgd 		st = memt;
    848       1.13       cgd 		sh = memh;
    849       1.22      fvdl #endif
    850       1.12       cgd 	} else {
    851       1.39      fvdl 		printf(": unable to map registers\n");
    852        1.1   mycroft 		return;
    853       1.12       cgd 	}
    854       1.39      fvdl 	ahc->tag = st;
    855       1.39      fvdl 	ahc->bsh = sh;
    856       1.39      fvdl 
    857       1.39      fvdl 	ahc->chip |= AHC_PCI;
    858       1.39      fvdl 	/*
    859       1.39      fvdl 	 * Before we continue probing the card, ensure that
    860       1.39      fvdl 	 * its interrupts are *disabled*.  We don't want
    861       1.39      fvdl 	 * a misstep to hang the machine in an interrupt
    862       1.39      fvdl 	 * storm.
    863       1.39      fvdl 	 */
    864       1.39      fvdl 	ahc_intr_enable(ahc, FALSE);
    865       1.39      fvdl 
    866       1.40      fvdl 	/*
    867       1.40      fvdl 	 * XXX somehow reading this once fails on some sparc64 systems.
    868       1.40      fvdl 	 *     This may be a problem in the sparc64 PCI code. Doing it
    869       1.40      fvdl 	 *     twice works around it.
    870       1.40      fvdl 	 */
    871       1.40      fvdl 	devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
    872       1.39      fvdl 	devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
    873       1.39      fvdl 
    874       1.39      fvdl 	/*
    875       1.39      fvdl 	 * If we need to support high memory, enable dual
    876       1.39      fvdl 	 * address cycles.  This bit must be set to enable
    877       1.39      fvdl 	 * high address bit generation even if we are on a
    878       1.39      fvdl 	 * 64bit bus (PCI64BIT set in devconfig).
    879       1.39      fvdl 	 */
    880       1.39      fvdl 	if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
    881       1.39      fvdl 
    882       1.39      fvdl 		if (1/*bootverbose*/)
    883       1.39      fvdl 			printf("%s: Enabling 39Bit Addressing\n",
    884       1.39      fvdl 			       ahc_name(ahc));
    885       1.39      fvdl 		devconfig |= DACEN;
    886       1.39      fvdl 	}
    887       1.49     perry 
    888       1.39      fvdl 	/* Ensure that pci error generation, a test feature, is disabled. */
    889       1.39      fvdl 	devconfig |= PCIERRGENDIS;
    890       1.22      fvdl 
    891       1.39      fvdl 	pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG, devconfig);
    892        1.1   mycroft 
    893       1.22      fvdl 	/* Ensure busmastering is enabled */
    894       1.39      fvdl 	command |= PCI_COMMAND_MASTER_ENABLE;;
    895       1.39      fvdl 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
    896       1.39      fvdl 
    897       1.39      fvdl 	/*
    898       1.39      fvdl 	 * Disable PCI parity error reporting.  Users typically
    899       1.39      fvdl 	 * do this to work around broken PCI chipsets that get
    900       1.39      fvdl 	 * the parity timing wrong and thus generate lots of spurious
    901       1.39      fvdl 	 * errors.
    902       1.39      fvdl 	 */
    903       1.39      fvdl 	if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0)
    904       1.39      fvdl 	  command &= ~PCI_COMMAND_PARITY_ENABLE;
    905       1.22      fvdl 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
    906        1.1   mycroft 
    907        1.1   mycroft 	/* On all PCI adapters, we allow SCB paging */
    908       1.39      fvdl 	ahc->flags |= AHC_PAGESCBS;
    909       1.39      fvdl 	error = ahc_softc_init(ahc);
    910       1.39      fvdl 	if (error != 0)
    911       1.39      fvdl 		goto error_out;
    912       1.22      fvdl 
    913       1.23      fvdl 	ahc->bus_intr = ahc_pci_intr;
    914        1.1   mycroft 
    915       1.39      fvdl 	/* Remember how the card was setup in case there is no SEEPROM */
    916       1.39      fvdl 	if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) {
    917       1.39      fvdl 		ahc_pause(ahc);
    918       1.39      fvdl 		if ((ahc->features & AHC_ULTRA2) != 0)
    919       1.39      fvdl 			our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
    920       1.39      fvdl 		else
    921       1.39      fvdl 			our_id = ahc_inb(ahc, SCSIID) & OID;
    922       1.39      fvdl 		sxfrctl1 = ahc_inb(ahc, SXFRCTL1) & STPWEN;
    923       1.39      fvdl 		scsiseq = ahc_inb(ahc, SCSISEQ);
    924       1.39      fvdl 	} else {
    925       1.39      fvdl 		sxfrctl1 = STPWEN;
    926       1.39      fvdl 		our_id = 7;
    927       1.39      fvdl 		scsiseq = 0;
    928       1.39      fvdl 	}
    929        1.1   mycroft 
    930       1.39      fvdl 	error = ahc_reset(ahc);
    931       1.39      fvdl 	if (error != 0)
    932       1.39      fvdl 		goto error_out;
    933        1.1   mycroft 
    934       1.22      fvdl 	if ((ahc->features & AHC_DT) != 0) {
    935       1.22      fvdl 		u_int sfunct;
    936       1.22      fvdl 
    937       1.22      fvdl 		/* Perform ALT-Mode Setup */
    938       1.22      fvdl 		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
    939       1.22      fvdl 		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
    940       1.39      fvdl 		ahc_outb(ahc, OPTIONMODE,
    941       1.39      fvdl 			 OPTIONMODE_DEFAULTS|AUTOACKEN|BUSFREEREV|EXPPHASEDIS);
    942       1.22      fvdl 		ahc_outb(ahc, SFUNCT, sfunct);
    943       1.22      fvdl 
    944       1.22      fvdl 		/* Normal mode setup */
    945       1.22      fvdl 		ahc_outb(ahc, CRCCONTROL1, CRCVALCHKEN|CRCENDCHKEN|CRCREQCHKEN
    946       1.39      fvdl 					  |TARGCRCENDEN);
    947       1.22      fvdl 	}
    948        1.1   mycroft 
    949       1.28  sommerfe 	if (pci_intr_map(pa, &ih)) {
    950       1.39      fvdl 		printf("%s: couldn't map interrupt\n", ahc_name(ahc));
    951        1.1   mycroft 		ahc_free(ahc);
    952        1.1   mycroft 		return;
    953        1.1   mycroft 	}
    954        1.1   mycroft 	intrstr = pci_intr_string(pa->pa_pc, ih);
    955       1.22      fvdl 	ahc->ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahc_intr, ahc);
    956       1.22      fvdl 	if (ahc->ih == NULL) {
    957       1.39      fvdl 		printf("%s: couldn't establish interrupt",
    958        1.1   mycroft 		       ahc->sc_dev.dv_xname);
    959        1.1   mycroft 		if (intrstr != NULL)
    960       1.39      fvdl 			printf(" at %s", intrstr);
    961       1.39      fvdl 		printf("\n");
    962        1.1   mycroft 		ahc_free(ahc);
    963        1.1   mycroft 		return;
    964        1.1   mycroft 	}
    965        1.1   mycroft 	if (intrstr != NULL)
    966       1.39      fvdl 		printf("%s: interrupting at %s\n", ahc_name(ahc), intrstr);
    967       1.39      fvdl 
    968       1.39      fvdl 	dscommand0 = ahc_inb(ahc, DSCOMMAND0);
    969       1.39      fvdl 	dscommand0 |= MPARCKEN|CACHETHEN;
    970       1.39      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0) {
    971       1.39      fvdl 
    972       1.39      fvdl 		/*
    973       1.39      fvdl 		 * DPARCKEN doesn't work correctly on
    974       1.39      fvdl 		 * some MBs so don't use it.
    975       1.39      fvdl 		 */
    976       1.39      fvdl 		dscommand0 &= ~DPARCKEN;
    977       1.39      fvdl 	}
    978       1.21   thorpej 
    979        1.1   mycroft 	/*
    980       1.39      fvdl 	 * Handle chips that must have cache line
    981       1.39      fvdl 	 * streaming (dis/en)abled.
    982        1.1   mycroft 	 */
    983       1.39      fvdl 	if ((ahc->bugs & AHC_CACHETHEN_DIS_BUG) != 0)
    984       1.39      fvdl 		dscommand0 |= CACHETHEN;
    985       1.39      fvdl 
    986       1.39      fvdl 	if ((ahc->bugs & AHC_CACHETHEN_BUG) != 0)
    987       1.39      fvdl 		dscommand0 &= ~CACHETHEN;
    988       1.39      fvdl 
    989       1.39      fvdl 	ahc_outb(ahc, DSCOMMAND0, dscommand0);
    990       1.39      fvdl 
    991       1.39      fvdl 	ahc->pci_cachesize =
    992       1.39      fvdl 	    pci_conf_read(pa->pa_pc, pa->pa_tag, CSIZE_LATTIME) & CACHESIZE;
    993       1.39      fvdl 	ahc->pci_cachesize *= 4;
    994       1.39      fvdl 
    995       1.39      fvdl 	if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0
    996       1.39      fvdl 	    && ahc->pci_cachesize == 4) {
    997       1.39      fvdl 		pci_conf_write(pa->pa_pc, pa->pa_tag, CSIZE_LATTIME, 0);
    998       1.39      fvdl 		ahc->pci_cachesize = 0;
    999       1.39      fvdl 	}
   1000        1.1   mycroft 
   1001       1.39      fvdl 	/*
   1002       1.39      fvdl 	 * We cannot perform ULTRA speeds without the presence
   1003       1.39      fvdl 	 * of the external precision resistor.
   1004  1.58.26.1      yamt 	 * Allow override for the SGI O2 though, which has two onboard ahc
   1005  1.58.26.1      yamt 	 * that fail here but are perfectly capable of ultra speeds.
   1006       1.39      fvdl 	 */
   1007  1.58.26.1      yamt 	override_ultra = FALSE;
   1008  1.58.26.1      yamt 	prop_dictionary_get_bool(device_properties(self), "override_ultra",
   1009  1.58.26.1      yamt 	    &override_ultra);
   1010  1.58.26.1      yamt 
   1011  1.58.26.1      yamt 	if (((ahc->features & AHC_ULTRA) != 0) && (!override_ultra)) {
   1012       1.50  christos 		uint32_t dvconfig;
   1013        1.1   mycroft 
   1014       1.50  christos 		dvconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
   1015       1.50  christos 		if ((dvconfig & REXTVALID) == 0)
   1016       1.39      fvdl 			ahc->features &= ~AHC_ULTRA;
   1017       1.39      fvdl 	}
   1018       1.39      fvdl 
   1019       1.39      fvdl 	ahc->seep_config = malloc(sizeof(*ahc->seep_config),
   1020       1.39      fvdl 				  M_DEVBUF, M_NOWAIT);
   1021       1.39      fvdl 	if (ahc->seep_config == NULL)
   1022       1.39      fvdl 		goto error_out;
   1023       1.49     perry 
   1024       1.39      fvdl 	memset(ahc->seep_config, 0, sizeof(*ahc->seep_config));
   1025        1.1   mycroft 
   1026       1.39      fvdl 	/* See if we have a SEEPROM and perform auto-term */
   1027       1.39      fvdl 	ahc_check_extport(ahc, &sxfrctl1);
   1028       1.22      fvdl 
   1029       1.39      fvdl 	/*
   1030       1.39      fvdl 	 * Take the LED out of diagnostic mode
   1031       1.39      fvdl 	 */
   1032       1.39      fvdl 	sblkctl = ahc_inb(ahc, SBLKCTL);
   1033       1.39      fvdl 	ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));
   1034       1.22      fvdl 
   1035       1.39      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0) {
   1036       1.39      fvdl 		ahc_outb(ahc, DFF_THRSH, RD_DFTHRSH_MAX|WR_DFTHRSH_MAX);
   1037       1.39      fvdl 	} else {
   1038       1.39      fvdl 		ahc_outb(ahc, DSPCISTATUS, DFTHRSH_100);
   1039       1.39      fvdl 	}
   1040        1.1   mycroft 
   1041       1.39      fvdl 	if (ahc->flags & AHC_USEDEFAULTS) {
   1042        1.1   mycroft 		/*
   1043       1.39      fvdl 		 * PCI Adapter default setup
   1044       1.39      fvdl 		 * Should only be used if the adapter does not have
   1045       1.39      fvdl 		 * a SEEPROM.
   1046        1.1   mycroft 		 */
   1047       1.39      fvdl 		/* See if someone else set us up already */
   1048       1.39      fvdl 		if ((ahc->flags & AHC_NO_BIOS_INIT) == 0
   1049       1.39      fvdl 		 && scsiseq != 0) {
   1050       1.55   thorpej 			prop_bool_t usetd;
   1051       1.54   tsutsui 
   1052       1.39      fvdl 			printf("%s: Using left over BIOS settings\n",
   1053       1.39      fvdl 				ahc_name(ahc));
   1054       1.39      fvdl 			ahc->flags &= ~AHC_USEDEFAULTS;
   1055       1.54   tsutsui 			/*
   1056       1.54   tsutsui 			 * Ignore target device settings and use default
   1057       1.54   tsutsui 			 * if BIOS initializes chip's SRAM with some
   1058       1.54   tsutsui 			 * conservative settings (async, no tagged
   1059       1.54   tsutsui 			 * queuing etc.) and machine dependent device
   1060       1.54   tsutsui 			 * property is set.
   1061       1.54   tsutsui 			 */
   1062       1.55   thorpej 			usetd = prop_dictionary_get(
   1063       1.55   thorpej 					device_properties(&ahc->sc_dev),
   1064       1.56   thorpej 					"aic7xxx-use-target-defaults");
   1065       1.55   thorpej 			if (usetd != NULL) {
   1066       1.55   thorpej 				KASSERT(prop_object_type(usetd) ==
   1067       1.55   thorpej 					PROP_TYPE_BOOL);
   1068       1.55   thorpej 				if (prop_bool_true(usetd))
   1069       1.55   thorpej 					ahc->flags |= AHC_USETARGETDEFAULTS;
   1070       1.55   thorpej 			}
   1071       1.39      fvdl 			ahc->flags |= AHC_BIOS_ENABLED;
   1072       1.22      fvdl 		} else {
   1073        1.1   mycroft 			/*
   1074       1.39      fvdl 			 * Assume only one connector and always turn
   1075       1.39      fvdl 			 * on termination.
   1076        1.1   mycroft 			 */
   1077       1.39      fvdl  			our_id = 0x07;
   1078       1.39      fvdl 			sxfrctl1 = STPWEN;
   1079       1.39      fvdl 		}
   1080       1.39      fvdl 		ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI);
   1081       1.22      fvdl 
   1082       1.39      fvdl 		ahc->our_id = our_id;
   1083       1.22      fvdl 	}
   1084       1.22      fvdl 
   1085       1.22      fvdl 	/*
   1086       1.22      fvdl 	 * Take a look to see if we have external SRAM.
   1087       1.22      fvdl 	 * We currently do not attempt to use SRAM that is
   1088       1.22      fvdl 	 * shared among multiple controllers.
   1089       1.22      fvdl 	 */
   1090       1.22      fvdl 	ahc_probe_ext_scbram(ahc);
   1091       1.22      fvdl 
   1092       1.22      fvdl 	/*
   1093       1.22      fvdl 	 * Record our termination setting for the
   1094       1.22      fvdl 	 * generic initialization routine.
   1095       1.22      fvdl 	 */
   1096       1.22      fvdl 	if ((sxfrctl1 & STPWEN) != 0)
   1097       1.22      fvdl 		ahc->flags |= AHC_TERM_ENB_A;
   1098        1.1   mycroft 
   1099       1.39      fvdl 	if (ahc_init(ahc))
   1100       1.39      fvdl 		goto error_out;
   1101        1.1   mycroft 
   1102        1.1   mycroft 	ahc_attach(ahc);
   1103       1.39      fvdl 
   1104       1.39      fvdl 	return;
   1105       1.39      fvdl 
   1106       1.39      fvdl  error_out:
   1107       1.39      fvdl 	ahc_free(ahc);
   1108       1.39      fvdl 	return;
   1109       1.22      fvdl }
   1110       1.22      fvdl 
   1111       1.51   thorpej CFATTACH_DECL(ahc_pci, sizeof(struct ahc_softc),
   1112       1.51   thorpej     ahc_pci_probe, ahc_pci_attach, NULL, NULL);
   1113       1.51   thorpej 
   1114       1.39      fvdl static int
   1115       1.39      fvdl ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor,
   1116       1.39      fvdl 			  uint16_t subdevice, uint16_t subvendor)
   1117       1.39      fvdl {
   1118       1.39      fvdl 	int result;
   1119       1.39      fvdl 
   1120       1.39      fvdl 	/* Default to invalid. */
   1121       1.39      fvdl 	result = 0;
   1122       1.39      fvdl 	if (vendor == 0x9005
   1123       1.39      fvdl 	 && subvendor == 0x9005
   1124       1.39      fvdl          && subdevice != device
   1125       1.39      fvdl          && SUBID_9005_TYPE_KNOWN(subdevice) != 0) {
   1126       1.39      fvdl 
   1127       1.39      fvdl 		switch (SUBID_9005_TYPE(subdevice)) {
   1128       1.39      fvdl 		case SUBID_9005_TYPE_MB:
   1129       1.39      fvdl 			break;
   1130       1.39      fvdl 		case SUBID_9005_TYPE_CARD:
   1131       1.39      fvdl 		case SUBID_9005_TYPE_LCCARD:
   1132       1.39      fvdl 			/*
   1133       1.39      fvdl 			 * Currently only trust Adaptec cards to
   1134       1.39      fvdl 			 * get the sub device info correct.
   1135       1.39      fvdl 			 */
   1136       1.39      fvdl 			if (DEVID_9005_TYPE(device) == DEVID_9005_TYPE_HBA)
   1137       1.39      fvdl 				result = 1;
   1138       1.39      fvdl 			break;
   1139       1.39      fvdl 		case SUBID_9005_TYPE_RAID:
   1140       1.39      fvdl 			break;
   1141       1.39      fvdl 		default:
   1142       1.39      fvdl 			break;
   1143       1.39      fvdl 		}
   1144       1.39      fvdl 	}
   1145       1.39      fvdl 	return (result);
   1146       1.39      fvdl }
   1147       1.39      fvdl 
   1148       1.39      fvdl 
   1149       1.22      fvdl /*
   1150       1.39      fvdl  * Test for the presense of external sram in an
   1151       1.22      fvdl  * "unshared" configuration.
   1152       1.22      fvdl  */
   1153       1.22      fvdl static int
   1154       1.22      fvdl ahc_ext_scbram_present(struct ahc_softc *ahc)
   1155       1.22      fvdl {
   1156       1.39      fvdl 	u_int chip;
   1157       1.22      fvdl 	int ramps;
   1158       1.22      fvdl 	int single_user;
   1159       1.39      fvdl 	uint32_t devconfig;
   1160       1.22      fvdl 
   1161       1.39      fvdl 	chip = ahc->chip & AHC_CHIPID_MASK;
   1162       1.39      fvdl 	devconfig = pci_conf_read(ahc->bd->pc, ahc->bd->tag, DEVCONFIG);
   1163       1.22      fvdl 	single_user = (devconfig & MPORTMODE) != 0;
   1164       1.22      fvdl 
   1165       1.22      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0)
   1166       1.22      fvdl 		ramps = (ahc_inb(ahc, DSCOMMAND0) & RAMPS) != 0;
   1167       1.39      fvdl 	else if (chip == AHC_AIC7895 || chip == AHC_AIC7895C)
   1168       1.39      fvdl 		/*
   1169       1.39      fvdl 		 * External SCBRAM arbitration is flakey
   1170       1.39      fvdl 		 * on these chips.  Unfortunately this means
   1171       1.39      fvdl 		 * we don't use the extra SCB ram space on the
   1172       1.39      fvdl 		 * 3940AUW.
   1173       1.39      fvdl 		 */
   1174       1.39      fvdl 		ramps = 0;
   1175       1.39      fvdl 	else if (chip >= AHC_AIC7870)
   1176       1.22      fvdl 		ramps = (devconfig & RAMPSM) != 0;
   1177       1.22      fvdl 	else
   1178       1.22      fvdl 		ramps = 0;
   1179       1.22      fvdl 
   1180       1.22      fvdl 	if (ramps && single_user)
   1181       1.22      fvdl 		return (1);
   1182       1.22      fvdl 	return (0);
   1183       1.22      fvdl }
   1184       1.22      fvdl 
   1185       1.22      fvdl /*
   1186       1.22      fvdl  * Enable external scbram.
   1187       1.22      fvdl  */
   1188       1.22      fvdl static void
   1189       1.39      fvdl ahc_scbram_config(struct ahc_softc *ahc, int enable, int pcheck,
   1190       1.39      fvdl 		  int fast, int large)
   1191       1.22      fvdl {
   1192       1.39      fvdl 	uint32_t devconfig;
   1193       1.22      fvdl 
   1194       1.22      fvdl 	if (ahc->features & AHC_MULTI_FUNC) {
   1195       1.22      fvdl 		/*
   1196       1.22      fvdl 		 * Set the SCB Base addr (highest address bit)
   1197       1.22      fvdl 		 * depending on which channel we are.
   1198       1.22      fvdl 		 */
   1199       1.39      fvdl 		ahc_outb(ahc, SCBBADDR, ahc->bd->func);
   1200       1.22      fvdl 	}
   1201       1.22      fvdl 
   1202       1.39      fvdl 	ahc->flags &= ~AHC_LSCBS_ENABLED;
   1203       1.39      fvdl 	if (large)
   1204       1.39      fvdl 		ahc->flags |= AHC_LSCBS_ENABLED;
   1205       1.39      fvdl 	devconfig = pci_conf_read(ahc->bd->pc, ahc->bd->tag, DEVCONFIG);
   1206       1.22      fvdl 	if ((ahc->features & AHC_ULTRA2) != 0) {
   1207       1.22      fvdl 		u_int dscommand0;
   1208       1.22      fvdl 
   1209       1.22      fvdl 		dscommand0 = ahc_inb(ahc, DSCOMMAND0);
   1210       1.22      fvdl 		if (enable)
   1211       1.22      fvdl 			dscommand0 &= ~INTSCBRAMSEL;
   1212       1.22      fvdl 		else
   1213       1.22      fvdl 			dscommand0 |= INTSCBRAMSEL;
   1214       1.39      fvdl 		if (large)
   1215       1.39      fvdl 			dscommand0 &= ~USCBSIZE32;
   1216       1.39      fvdl 		else
   1217       1.39      fvdl 			dscommand0 |= USCBSIZE32;
   1218       1.22      fvdl 		ahc_outb(ahc, DSCOMMAND0, dscommand0);
   1219       1.22      fvdl 	} else {
   1220       1.22      fvdl 		if (fast)
   1221       1.22      fvdl 			devconfig &= ~EXTSCBTIME;
   1222       1.22      fvdl 		else
   1223       1.22      fvdl 			devconfig |= EXTSCBTIME;
   1224       1.22      fvdl 		if (enable)
   1225       1.22      fvdl 			devconfig &= ~SCBRAMSEL;
   1226       1.22      fvdl 		else
   1227       1.22      fvdl 			devconfig |= SCBRAMSEL;
   1228       1.39      fvdl 		if (large)
   1229       1.39      fvdl 			devconfig &= ~SCBSIZE32;
   1230       1.39      fvdl 		else
   1231       1.39      fvdl 			devconfig |= SCBSIZE32;
   1232       1.22      fvdl 	}
   1233       1.22      fvdl 	if (pcheck)
   1234       1.22      fvdl 		devconfig |= EXTSCBPEN;
   1235       1.22      fvdl 	else
   1236       1.22      fvdl 		devconfig &= ~EXTSCBPEN;
   1237       1.22      fvdl 
   1238       1.39      fvdl 	pci_conf_write(ahc->bd->pc, ahc->bd->tag, DEVCONFIG, devconfig);
   1239       1.22      fvdl }
   1240       1.22      fvdl 
   1241       1.22      fvdl /*
   1242       1.22      fvdl  * Take a look to see if we have external SRAM.
   1243       1.22      fvdl  * We currently do not attempt to use SRAM that is
   1244       1.22      fvdl  * shared among multiple controllers.
   1245       1.22      fvdl  */
   1246       1.22      fvdl static void
   1247       1.22      fvdl ahc_probe_ext_scbram(struct ahc_softc *ahc)
   1248       1.22      fvdl {
   1249       1.22      fvdl 	int num_scbs;
   1250       1.22      fvdl 	int test_num_scbs;
   1251       1.22      fvdl 	int enable;
   1252       1.22      fvdl 	int pcheck;
   1253       1.22      fvdl 	int fast;
   1254       1.39      fvdl 	int large;
   1255       1.22      fvdl 
   1256       1.39      fvdl 	enable = FALSE;
   1257       1.39      fvdl 	pcheck = FALSE;
   1258       1.39      fvdl 	fast = FALSE;
   1259       1.39      fvdl 	large = FALSE;
   1260       1.39      fvdl 	num_scbs = 0;
   1261       1.49     perry 
   1262       1.22      fvdl 	if (ahc_ext_scbram_present(ahc) == 0)
   1263       1.39      fvdl 		goto done;
   1264       1.22      fvdl 
   1265       1.22      fvdl 	/*
   1266       1.22      fvdl 	 * Probe for the best parameters to use.
   1267       1.22      fvdl 	 */
   1268       1.39      fvdl 	ahc_scbram_config(ahc, /*enable*/TRUE, pcheck, fast, large);
   1269       1.22      fvdl 	num_scbs = ahc_probe_scbs(ahc);
   1270       1.22      fvdl 	if (num_scbs == 0) {
   1271       1.22      fvdl 		/* The SRAM wasn't really present. */
   1272       1.22      fvdl 		goto done;
   1273       1.22      fvdl 	}
   1274       1.22      fvdl 	enable = TRUE;
   1275       1.22      fvdl 
   1276       1.22      fvdl 	/*
   1277       1.22      fvdl 	 * Clear any outstanding parity error
   1278       1.22      fvdl 	 * and ensure that parity error reporting
   1279       1.22      fvdl 	 * is enabled.
   1280       1.22      fvdl 	 */
   1281       1.22      fvdl 	ahc_outb(ahc, SEQCTL, 0);
   1282       1.22      fvdl 	ahc_outb(ahc, CLRINT, CLRPARERR);
   1283       1.22      fvdl 	ahc_outb(ahc, CLRINT, CLRBRKADRINT);
   1284       1.22      fvdl 
   1285       1.22      fvdl 	/* Now see if we can do parity */
   1286       1.39      fvdl 	ahc_scbram_config(ahc, enable, /*pcheck*/TRUE, fast, large);
   1287       1.22      fvdl 	num_scbs = ahc_probe_scbs(ahc);
   1288       1.22      fvdl 	if ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0
   1289       1.22      fvdl 	 || (ahc_inb(ahc, ERROR) & MPARERR) == 0)
   1290       1.22      fvdl 		pcheck = TRUE;
   1291       1.22      fvdl 
   1292       1.22      fvdl 	/* Clear any resulting parity error */
   1293       1.22      fvdl 	ahc_outb(ahc, CLRINT, CLRPARERR);
   1294       1.22      fvdl 	ahc_outb(ahc, CLRINT, CLRBRKADRINT);
   1295       1.22      fvdl 
   1296       1.22      fvdl 	/* Now see if we can do fast timing */
   1297       1.39      fvdl 	ahc_scbram_config(ahc, enable, pcheck, /*fast*/TRUE, large);
   1298       1.22      fvdl 	test_num_scbs = ahc_probe_scbs(ahc);
   1299       1.22      fvdl 	if (test_num_scbs == num_scbs
   1300       1.22      fvdl 	 && ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0
   1301       1.22      fvdl 	  || (ahc_inb(ahc, ERROR) & MPARERR) == 0))
   1302       1.22      fvdl 		fast = TRUE;
   1303       1.22      fvdl 
   1304       1.39      fvdl 	/*
   1305       1.39      fvdl 	 * See if we can use large SCBs and still maintain
   1306       1.39      fvdl 	 * the same overall count of SCBs.
   1307       1.39      fvdl 	 */
   1308       1.39      fvdl 	if ((ahc->features & AHC_LARGE_SCBS) != 0) {
   1309       1.39      fvdl 		ahc_scbram_config(ahc, enable, pcheck, fast, /*large*/TRUE);
   1310       1.39      fvdl 		test_num_scbs = ahc_probe_scbs(ahc);
   1311       1.39      fvdl 		if (test_num_scbs >= num_scbs) {
   1312       1.39      fvdl 			large = TRUE;
   1313       1.39      fvdl 			num_scbs = test_num_scbs;
   1314       1.39      fvdl 	 		if (num_scbs >= 64) {
   1315       1.39      fvdl 				/*
   1316       1.39      fvdl 				 * We have enough space to move the
   1317       1.39      fvdl 				 * "busy targets table" into SCB space
   1318       1.39      fvdl 				 * and make it qualify all the way to the
   1319       1.39      fvdl 				 * lun level.
   1320       1.39      fvdl 				 */
   1321       1.39      fvdl 				ahc->flags |= AHC_SCB_BTT;
   1322       1.39      fvdl 			}
   1323       1.39      fvdl 		}
   1324       1.39      fvdl 	}
   1325       1.22      fvdl done:
   1326       1.22      fvdl 	/*
   1327       1.22      fvdl 	 * Disable parity error reporting until we
   1328       1.22      fvdl 	 * can load instruction ram.
   1329       1.22      fvdl 	 */
   1330       1.22      fvdl 	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);
   1331       1.22      fvdl 	/* Clear any latched parity error */
   1332       1.22      fvdl 	ahc_outb(ahc, CLRINT, CLRPARERR);
   1333       1.22      fvdl 	ahc_outb(ahc, CLRINT, CLRBRKADRINT);
   1334       1.39      fvdl 	if (1/*bootverbose*/ && enable) {
   1335       1.39      fvdl 		printf("%s: External SRAM, %s access%s, %dbytes/SCB\n",
   1336       1.49     perry 		       ahc_name(ahc), fast ? "fast" : "slow",
   1337       1.39      fvdl 		       pcheck ? ", parity checking enabled" : "",
   1338       1.39      fvdl 		       large ? 64 : 32);
   1339       1.22      fvdl 	}
   1340       1.39      fvdl 	ahc_scbram_config(ahc, enable, pcheck, fast, large);
   1341       1.22      fvdl }
   1342       1.22      fvdl 
   1343       1.39      fvdl #if 0
   1344       1.39      fvdl /*
   1345       1.39      fvdl  * Perform some simple tests that should catch situations where
   1346       1.39      fvdl  * our registers are invalidly mapped.
   1347       1.39      fvdl  */
   1348       1.51   thorpej static int
   1349       1.39      fvdl ahc_pci_test_register_access(struct ahc_softc *ahc)
   1350       1.39      fvdl {
   1351       1.39      fvdl 	int	 error;
   1352       1.39      fvdl 	u_int	 status1;
   1353       1.39      fvdl 	uint32_t cmd;
   1354       1.39      fvdl 	uint8_t	 hcntrl;
   1355       1.39      fvdl 
   1356       1.39      fvdl 	error = EIO;
   1357       1.39      fvdl 
   1358       1.39      fvdl 	/*
   1359       1.39      fvdl 	 * Enable PCI error interrupt status, but suppress NMIs
   1360       1.39      fvdl 	 * generated by SERR raised due to target aborts.
   1361       1.39      fvdl 	 */
   1362       1.39      fvdl 	cmd = pci_conf_read(ahc->bd->pc, ahc->bd->tag, PCIR_COMMAND);
   1363       1.39      fvdl 	pci_conf_write(ahc->bd->pc, ahc->bd->tag, PCIR_COMMAND,
   1364       1.39      fvdl 		       cmd & ~PCIM_CMD_SERRESPEN);
   1365       1.39      fvdl 
   1366       1.39      fvdl 	/*
   1367       1.39      fvdl 	 * First a simple test to see if any
   1368       1.39      fvdl 	 * registers can be read.  Reading
   1369       1.39      fvdl 	 * HCNTRL has no side effects and has
   1370       1.39      fvdl 	 * at least one bit that is guaranteed to
   1371       1.39      fvdl 	 * be zero so it is a good register to
   1372       1.39      fvdl 	 * use for this test.
   1373       1.39      fvdl 	 */
   1374       1.39      fvdl 	hcntrl = ahc_inb(ahc, HCNTRL);
   1375       1.39      fvdl 	if (hcntrl == 0xFF)
   1376       1.39      fvdl 		goto fail;
   1377       1.39      fvdl 
   1378       1.39      fvdl 	/*
   1379       1.39      fvdl 	 * Next create a situation where write combining
   1380       1.39      fvdl 	 * or read prefetching could be initiated by the
   1381       1.39      fvdl 	 * CPU or host bridge.  Our device does not support
   1382       1.39      fvdl 	 * either, so look for data corruption and/or flagged
   1383       1.39      fvdl 	 * PCI errors.
   1384       1.39      fvdl 	 */
   1385       1.39      fvdl 	ahc_outb(ahc, HCNTRL, hcntrl|PAUSE);
   1386       1.39      fvdl 	while (ahc_is_paused(ahc) == 0)
   1387       1.39      fvdl 		;
   1388       1.39      fvdl 	ahc_outb(ahc, SEQCTL, PERRORDIS);
   1389       1.39      fvdl 	ahc_outb(ahc, SCBPTR, 0);
   1390       1.39      fvdl 	ahc_outl(ahc, SCB_BASE, 0x5aa555aa);
   1391       1.39      fvdl 	if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa)
   1392       1.39      fvdl 		goto fail;
   1393       1.39      fvdl 
   1394       1.39      fvdl 	status1 = pci_conf_read(ahc->bd->pc, ahc->bd->tag,
   1395       1.39      fvdl 				PCI_COMMAND_STATUS_REG + 1);
   1396       1.39      fvdl 	if ((status1 & STA) != 0)
   1397       1.39      fvdl 		goto fail;
   1398       1.39      fvdl 
   1399       1.39      fvdl 	error = 0;
   1400       1.39      fvdl 
   1401       1.39      fvdl fail:
   1402       1.39      fvdl 	/* Silently clear any latched errors. */
   1403       1.46  christos 	status1 = pci_conf_read(ahc->bd->pc, ahc->bd->tag,
   1404       1.46  christos 	    PCI_COMMAND_STATUS_REG + 1);
   1405       1.39      fvdl 	ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
   1406       1.39      fvdl 			     status1, /*bytes*/1);
   1407       1.39      fvdl 	ahc_outb(ahc, CLRINT, CLRPARERR);
   1408       1.39      fvdl 	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);
   1409       1.39      fvdl 	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
   1410       1.39      fvdl 	return (error);
   1411       1.39      fvdl }
   1412       1.39      fvdl #endif
   1413       1.22      fvdl 
   1414       1.51   thorpej static void
   1415       1.22      fvdl ahc_pci_intr(struct ahc_softc *ahc)
   1416       1.22      fvdl {
   1417       1.39      fvdl 	u_int error;
   1418       1.39      fvdl 	u_int status1;
   1419       1.22      fvdl 
   1420       1.39      fvdl 	error = ahc_inb(ahc, ERROR);
   1421       1.39      fvdl 	if ((error & PCIERRSTAT) == 0)
   1422       1.39      fvdl 		return;
   1423       1.23      fvdl 
   1424       1.46  christos 	status1 = pci_conf_read(ahc->bd->pc, ahc->bd->tag,
   1425       1.46  christos 	    PCI_COMMAND_STATUS_REG);
   1426       1.39      fvdl 
   1427       1.39      fvdl 	printf("%s: PCI error Interrupt at seqaddr = 0x%x\n",
   1428       1.39      fvdl 	      ahc_name(ahc),
   1429       1.39      fvdl 	      ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
   1430       1.22      fvdl 
   1431       1.22      fvdl 	if (status1 & DPE) {
   1432       1.22      fvdl 		printf("%s: Data Parity Error Detected during address "
   1433       1.22      fvdl 		       "or write data phase\n", ahc_name(ahc));
   1434       1.22      fvdl 	}
   1435       1.22      fvdl 	if (status1 & SSE) {
   1436       1.22      fvdl 		printf("%s: Signal System Error Detected\n", ahc_name(ahc));
   1437       1.22      fvdl 	}
   1438       1.22      fvdl 	if (status1 & RMA) {
   1439       1.22      fvdl 		printf("%s: Received a Master Abort\n", ahc_name(ahc));
   1440       1.22      fvdl 	}
   1441       1.22      fvdl 	if (status1 & RTA) {
   1442       1.22      fvdl 		printf("%s: Received a Target Abort\n", ahc_name(ahc));
   1443       1.22      fvdl 	}
   1444       1.22      fvdl 	if (status1 & STA) {
   1445       1.22      fvdl 		printf("%s: Signaled a Target Abort\n", ahc_name(ahc));
   1446       1.22      fvdl 	}
   1447       1.22      fvdl 	if (status1 & DPR) {
   1448       1.22      fvdl 		printf("%s: Data Parity Error has been reported via PERR#\n",
   1449       1.22      fvdl 		       ahc_name(ahc));
   1450       1.22      fvdl 	}
   1451       1.39      fvdl 
   1452       1.39      fvdl 	/* Clear latched errors. */
   1453       1.46  christos 	pci_conf_write(ahc->bd->pc, ahc->bd->tag,  PCI_COMMAND_STATUS_REG,
   1454       1.46  christos 	    status1);
   1455       1.39      fvdl 
   1456       1.22      fvdl 	if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) {
   1457       1.22      fvdl 		printf("%s: Latched PCIERR interrupt with "
   1458       1.49     perry 		       "no status bits set\n", ahc_name(ahc));
   1459       1.39      fvdl 	} else {
   1460       1.22      fvdl 		ahc_outb(ahc, CLRINT, CLRPARERR);
   1461       1.22      fvdl 	}
   1462       1.23      fvdl 
   1463       1.39      fvdl 	ahc_unpause(ahc);
   1464       1.22      fvdl }
   1465       1.22      fvdl 
   1466       1.22      fvdl static int
   1467       1.39      fvdl ahc_aic785X_setup(struct ahc_softc *ahc)
   1468       1.22      fvdl {
   1469       1.39      fvdl 	uint8_t rev;
   1470       1.39      fvdl 
   1471       1.39      fvdl 	ahc->channel = 'A';
   1472       1.39      fvdl 	ahc->chip = AHC_AIC7850;
   1473       1.39      fvdl 	ahc->features = AHC_AIC7850_FE;
   1474       1.39      fvdl 	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
   1475       1.39      fvdl 	rev = PCI_REVISION(ahc->bd->class);
   1476       1.39      fvdl 	if (rev >= 1)
   1477       1.39      fvdl 		ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
   1478       1.22      fvdl 	return (0);
   1479       1.22      fvdl }
   1480       1.22      fvdl 
   1481       1.22      fvdl static int
   1482       1.39      fvdl ahc_aic7860_setup(struct ahc_softc *ahc)
   1483       1.22      fvdl {
   1484       1.39      fvdl 	uint8_t rev;
   1485       1.39      fvdl 
   1486       1.39      fvdl 	ahc->channel = 'A';
   1487       1.39      fvdl 	ahc->chip = AHC_AIC7860;
   1488       1.39      fvdl 	ahc->features = AHC_AIC7860_FE;
   1489       1.39      fvdl 	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
   1490       1.39      fvdl 	rev = PCI_REVISION(ahc->bd->class);
   1491       1.39      fvdl 	if (rev >= 1)
   1492       1.39      fvdl 		ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
   1493       1.22      fvdl 	return (0);
   1494       1.22      fvdl }
   1495       1.22      fvdl 
   1496       1.22      fvdl static int
   1497       1.39      fvdl ahc_apa1480_setup(struct ahc_softc *ahc)
   1498       1.22      fvdl {
   1499       1.39      fvdl 	int error;
   1500       1.39      fvdl 
   1501       1.39      fvdl 	error = ahc_aic7860_setup(ahc);
   1502       1.39      fvdl 	if (error != 0)
   1503       1.39      fvdl 		return (error);
   1504       1.39      fvdl 	ahc->features |= AHC_REMOVABLE;
   1505       1.22      fvdl 	return (0);
   1506       1.22      fvdl }
   1507       1.22      fvdl 
   1508       1.22      fvdl static int
   1509       1.39      fvdl ahc_aic7870_setup(struct ahc_softc *ahc)
   1510       1.22      fvdl {
   1511       1.39      fvdl 
   1512       1.39      fvdl 	ahc->channel = 'A';
   1513       1.39      fvdl 	ahc->chip = AHC_AIC7870;
   1514       1.39      fvdl 	ahc->features = AHC_AIC7870_FE;
   1515       1.39      fvdl 	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
   1516       1.22      fvdl 	return (0);
   1517       1.22      fvdl }
   1518       1.22      fvdl 
   1519       1.22      fvdl static int
   1520       1.39      fvdl ahc_aha394X_setup(struct ahc_softc *ahc)
   1521       1.22      fvdl {
   1522       1.39      fvdl 	int error;
   1523       1.39      fvdl 
   1524       1.39      fvdl 	error = ahc_aic7870_setup(ahc);
   1525       1.39      fvdl 	if (error == 0)
   1526       1.39      fvdl 		error = ahc_aha394XX_setup(ahc);
   1527       1.39      fvdl 	return (error);
   1528       1.22      fvdl }
   1529       1.22      fvdl 
   1530       1.22      fvdl static int
   1531       1.39      fvdl ahc_aha398X_setup(struct ahc_softc *ahc)
   1532       1.22      fvdl {
   1533       1.22      fvdl 	int error;
   1534       1.22      fvdl 
   1535       1.39      fvdl 	error = ahc_aic7870_setup(ahc);
   1536       1.22      fvdl 	if (error == 0)
   1537       1.39      fvdl 		error = ahc_aha398XX_setup(ahc);
   1538       1.22      fvdl 	return (error);
   1539       1.22      fvdl }
   1540       1.22      fvdl 
   1541       1.22      fvdl static int
   1542       1.39      fvdl ahc_aha494X_setup(struct ahc_softc *ahc)
   1543       1.22      fvdl {
   1544       1.22      fvdl 	int error;
   1545       1.22      fvdl 
   1546       1.39      fvdl 	error = ahc_aic7870_setup(ahc);
   1547       1.22      fvdl 	if (error == 0)
   1548       1.39      fvdl 		error = ahc_aha494XX_setup(ahc);
   1549       1.22      fvdl 	return (error);
   1550       1.22      fvdl }
   1551       1.22      fvdl 
   1552       1.22      fvdl static int
   1553       1.39      fvdl ahc_aic7880_setup(struct ahc_softc *ahc)
   1554       1.22      fvdl {
   1555       1.39      fvdl 	uint8_t rev;
   1556       1.39      fvdl 
   1557       1.39      fvdl 	ahc->channel = 'A';
   1558       1.39      fvdl 	ahc->chip = AHC_AIC7880;
   1559       1.39      fvdl 	ahc->features = AHC_AIC7880_FE;
   1560       1.39      fvdl 	ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
   1561       1.39      fvdl 	rev = PCI_REVISION(ahc->bd->class);
   1562       1.39      fvdl 	if (rev >= 1) {
   1563       1.39      fvdl 		ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
   1564       1.39      fvdl 	} else {
   1565       1.39      fvdl 		ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
   1566       1.39      fvdl 	}
   1567       1.22      fvdl 	return (0);
   1568       1.22      fvdl }
   1569       1.22      fvdl 
   1570       1.22      fvdl static int
   1571       1.39      fvdl ahc_aha2940Pro_setup(struct ahc_softc *ahc)
   1572       1.22      fvdl {
   1573       1.22      fvdl 
   1574       1.39      fvdl 	ahc->flags |= AHC_INT50_SPEEDFLEX;
   1575       1.39      fvdl 	return (ahc_aic7880_setup(ahc));
   1576       1.22      fvdl }
   1577       1.22      fvdl 
   1578       1.22      fvdl static int
   1579       1.39      fvdl ahc_aha394XU_setup(struct ahc_softc *ahc)
   1580       1.22      fvdl {
   1581       1.22      fvdl 	int error;
   1582       1.22      fvdl 
   1583       1.39      fvdl 	error = ahc_aic7880_setup(ahc);
   1584       1.22      fvdl 	if (error == 0)
   1585       1.39      fvdl 		error = ahc_aha394XX_setup(ahc);
   1586       1.22      fvdl 	return (error);
   1587       1.22      fvdl }
   1588       1.22      fvdl 
   1589       1.22      fvdl static int
   1590       1.39      fvdl ahc_aha398XU_setup(struct ahc_softc *ahc)
   1591       1.22      fvdl {
   1592       1.22      fvdl 	int error;
   1593       1.22      fvdl 
   1594       1.39      fvdl 	error = ahc_aic7880_setup(ahc);
   1595       1.22      fvdl 	if (error == 0)
   1596       1.39      fvdl 		error = ahc_aha398XX_setup(ahc);
   1597       1.22      fvdl 	return (error);
   1598       1.22      fvdl }
   1599       1.22      fvdl 
   1600       1.22      fvdl static int
   1601       1.39      fvdl ahc_aic7890_setup(struct ahc_softc *ahc)
   1602       1.22      fvdl {
   1603       1.39      fvdl 	uint8_t rev;
   1604       1.39      fvdl 
   1605       1.39      fvdl 	ahc->channel = 'A';
   1606       1.39      fvdl 	ahc->chip = AHC_AIC7890;
   1607       1.39      fvdl 	ahc->features = AHC_AIC7890_FE;
   1608       1.39      fvdl 	ahc->flags |= AHC_NEWEEPROM_FMT;
   1609       1.39      fvdl 	rev = PCI_REVISION(ahc->bd->class);
   1610       1.39      fvdl 	if (rev == 0)
   1611       1.39      fvdl 		ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG;
   1612       1.22      fvdl 	return (0);
   1613       1.22      fvdl }
   1614       1.22      fvdl 
   1615       1.22      fvdl static int
   1616       1.39      fvdl ahc_aic7892_setup(struct ahc_softc *ahc)
   1617       1.22      fvdl {
   1618       1.39      fvdl 
   1619       1.39      fvdl 	ahc->channel = 'A';
   1620       1.39      fvdl 	ahc->chip = AHC_AIC7892;
   1621       1.39      fvdl 	ahc->features = AHC_AIC7892_FE;
   1622       1.39      fvdl 	ahc->flags |= AHC_NEWEEPROM_FMT;
   1623       1.39      fvdl 	ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
   1624       1.22      fvdl 	return (0);
   1625       1.22      fvdl }
   1626       1.22      fvdl 
   1627       1.22      fvdl static int
   1628       1.39      fvdl ahc_aic7895_setup(struct ahc_softc *ahc)
   1629       1.22      fvdl {
   1630       1.39      fvdl 	uint8_t rev;
   1631       1.39      fvdl 
   1632       1.39      fvdl 	ahc->channel = (ahc->bd->func == 1) ? 'B' : 'A';
   1633       1.39      fvdl 	/*
   1634       1.39      fvdl 	 * The 'C' revision of the aic7895 has a few additional features.
   1635       1.39      fvdl 	 */
   1636       1.39      fvdl 	rev = PCI_REVISION(ahc->bd->class);
   1637       1.39      fvdl 	if (rev >= 4) {
   1638       1.39      fvdl 		ahc->chip = AHC_AIC7895C;
   1639       1.39      fvdl 		ahc->features = AHC_AIC7895C_FE;
   1640       1.39      fvdl 	} else  {
   1641       1.39      fvdl 		u_int command;
   1642       1.39      fvdl 
   1643       1.39      fvdl 		ahc->chip = AHC_AIC7895;
   1644       1.39      fvdl 		ahc->features = AHC_AIC7895_FE;
   1645       1.39      fvdl 
   1646       1.39      fvdl 		/*
   1647       1.39      fvdl 		 * The BIOS disables the use of MWI transactions
   1648       1.39      fvdl 		 * since it does not have the MWI bug work around
   1649       1.39      fvdl 		 * we have.  Disabling MWI reduces performance, so
   1650       1.39      fvdl 		 * turn it on again.
   1651       1.39      fvdl 		 */
   1652       1.46  christos 		command = pci_conf_read(ahc->bd->pc, ahc->bd->tag,
   1653       1.46  christos 		    PCI_COMMAND_STATUS_REG);
   1654       1.39      fvdl 		command |=  PCI_COMMAND_INVALIDATE_ENABLE;
   1655       1.46  christos 		pci_conf_write(ahc->bd->pc, ahc->bd->tag,
   1656       1.46  christos 		    PCI_COMMAND_STATUS_REG, command);
   1657       1.39      fvdl 		ahc->bugs |= AHC_PCI_MWI_BUG;
   1658       1.39      fvdl 	}
   1659       1.39      fvdl 	/*
   1660       1.39      fvdl 	 * XXX Does CACHETHEN really not work???  What about PCI retry?
   1661       1.39      fvdl 	 * on C level chips.  Need to test, but for now, play it safe.
   1662       1.39      fvdl 	 */
   1663       1.39      fvdl 	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_PCI_2_1_RETRY_BUG
   1664       1.39      fvdl 		  |  AHC_CACHETHEN_BUG;
   1665       1.39      fvdl 
   1666       1.39      fvdl #if 0
   1667       1.39      fvdl 	uint32_t devconfig;
   1668       1.39      fvdl 
   1669       1.39      fvdl 	/*
   1670       1.39      fvdl 	 * Cachesize must also be zero due to stray DAC
   1671       1.39      fvdl 	 * problem when sitting behind some bridges.
   1672       1.39      fvdl 	 */
   1673       1.39      fvdl 	pci_conf_write(ahc->bd->pc, ahc->bd->tag, CSIZE_LATTIME, 0);
   1674       1.39      fvdl 	devconfig = pci_conf_read(ahc->bd->pc, ahc->bd->tag, DEVCONFIG);
   1675       1.39      fvdl 	devconfig |= MRDCEN;
   1676       1.39      fvdl 	pci_conf_write(ahc->bd->pc, ahc->bd->tag, DEVCONFIG, devconfig);
   1677       1.39      fvdl #endif
   1678       1.39      fvdl 	ahc->flags |= AHC_NEWEEPROM_FMT;
   1679       1.39      fvdl 	return (0);
   1680       1.39      fvdl }
   1681       1.22      fvdl 
   1682       1.39      fvdl static int
   1683       1.39      fvdl ahc_aic7896_setup(struct ahc_softc *ahc)
   1684       1.39      fvdl {
   1685       1.39      fvdl 	ahc->channel = (ahc->bd->func == 1) ? 'B' : 'A';
   1686       1.39      fvdl 	ahc->chip = AHC_AIC7896;
   1687       1.39      fvdl 	ahc->features = AHC_AIC7896_FE;
   1688       1.39      fvdl 	ahc->flags |= AHC_NEWEEPROM_FMT;
   1689       1.39      fvdl 	ahc->bugs |= AHC_CACHETHEN_DIS_BUG;
   1690       1.22      fvdl 	return (0);
   1691       1.22      fvdl }
   1692       1.22      fvdl 
   1693       1.22      fvdl static int
   1694       1.39      fvdl ahc_aic7899_setup(struct ahc_softc *ahc)
   1695       1.22      fvdl {
   1696       1.39      fvdl 	ahc->channel = (ahc->bd->func == 1) ? 'B' : 'A';
   1697       1.39      fvdl 	ahc->chip = AHC_AIC7899;
   1698       1.39      fvdl 	ahc->features = AHC_AIC7899_FE;
   1699       1.39      fvdl 	ahc->flags |= AHC_NEWEEPROM_FMT;
   1700       1.39      fvdl 	ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
   1701       1.22      fvdl 	return (0);
   1702       1.22      fvdl }
   1703       1.22      fvdl 
   1704       1.22      fvdl static int
   1705       1.39      fvdl ahc_aha29160C_setup(struct ahc_softc *ahc)
   1706       1.22      fvdl {
   1707       1.39      fvdl 	int error;
   1708       1.39      fvdl 
   1709       1.39      fvdl 	error = ahc_aic7899_setup(ahc);
   1710       1.39      fvdl 	if (error != 0)
   1711       1.39      fvdl 		return (error);
   1712       1.39      fvdl 	ahc->features |= AHC_REMOVABLE;
   1713       1.22      fvdl 	return (0);
   1714       1.22      fvdl }
   1715       1.22      fvdl 
   1716       1.22      fvdl static int
   1717       1.39      fvdl ahc_raid_setup(struct ahc_softc *ahc)
   1718       1.22      fvdl {
   1719       1.57  christos 	printf("%s: RAID functionality unsupported\n", ahc->sc_dev.dv_xname);
   1720       1.22      fvdl 	return (ENXIO);
   1721       1.22      fvdl }
   1722       1.22      fvdl 
   1723       1.22      fvdl static int
   1724       1.39      fvdl ahc_aha394XX_setup(struct ahc_softc *ahc)
   1725       1.22      fvdl {
   1726       1.39      fvdl 
   1727       1.39      fvdl 	switch (ahc->bd->dev) {
   1728       1.22      fvdl 	case AHC_394X_SLOT_CHANNEL_A:
   1729       1.39      fvdl 		ahc->channel = 'A';
   1730       1.22      fvdl 		break;
   1731       1.22      fvdl 	case AHC_394X_SLOT_CHANNEL_B:
   1732       1.39      fvdl 		ahc->channel = 'B';
   1733       1.22      fvdl 		break;
   1734       1.22      fvdl 	default:
   1735       1.22      fvdl 		printf("adapter at unexpected slot %d\n"
   1736       1.22      fvdl 		       "unable to map to a channel\n",
   1737       1.39      fvdl 		       ahc->bd->dev);
   1738       1.39      fvdl 		ahc->channel = 'A';
   1739       1.22      fvdl 	}
   1740       1.22      fvdl 	return (0);
   1741       1.22      fvdl }
   1742       1.22      fvdl 
   1743       1.22      fvdl static int
   1744       1.39      fvdl ahc_aha398XX_setup(struct ahc_softc *ahc)
   1745       1.22      fvdl {
   1746       1.39      fvdl 
   1747       1.39      fvdl 	switch (ahc->bd->dev) {
   1748       1.22      fvdl 	case AHC_398X_SLOT_CHANNEL_A:
   1749       1.39      fvdl 		ahc->channel = 'A';
   1750       1.22      fvdl 		break;
   1751       1.22      fvdl 	case AHC_398X_SLOT_CHANNEL_B:
   1752       1.39      fvdl 		ahc->channel = 'B';
   1753       1.22      fvdl 		break;
   1754       1.22      fvdl 	case AHC_398X_SLOT_CHANNEL_C:
   1755       1.39      fvdl 		ahc->channel = 'C';
   1756       1.39      fvdl 		break;
   1757       1.39      fvdl 	default:
   1758       1.39      fvdl 		printf("adapter at unexpected slot %d\n"
   1759       1.39      fvdl 		       "unable to map to a channel\n",
   1760       1.39      fvdl 		       ahc->bd->dev);
   1761       1.39      fvdl 		ahc->channel = 'A';
   1762       1.39      fvdl 		break;
   1763       1.39      fvdl 	}
   1764       1.39      fvdl 	ahc->flags |= AHC_LARGE_SEEPROM;
   1765       1.39      fvdl 	return (0);
   1766       1.39      fvdl }
   1767       1.39      fvdl 
   1768       1.39      fvdl static int
   1769       1.39      fvdl ahc_aha494XX_setup(struct ahc_softc *ahc)
   1770       1.39      fvdl {
   1771       1.39      fvdl 
   1772       1.39      fvdl 	switch (ahc->bd->dev) {
   1773       1.39      fvdl 	case AHC_494X_SLOT_CHANNEL_A:
   1774       1.39      fvdl 		ahc->channel = 'A';
   1775       1.39      fvdl 		break;
   1776       1.39      fvdl 	case AHC_494X_SLOT_CHANNEL_B:
   1777       1.39      fvdl 		ahc->channel = 'B';
   1778       1.39      fvdl 		break;
   1779       1.39      fvdl 	case AHC_494X_SLOT_CHANNEL_C:
   1780       1.39      fvdl 		ahc->channel = 'C';
   1781       1.39      fvdl 		break;
   1782       1.39      fvdl 	case AHC_494X_SLOT_CHANNEL_D:
   1783       1.39      fvdl 		ahc->channel = 'D';
   1784       1.22      fvdl 		break;
   1785       1.22      fvdl 	default:
   1786       1.22      fvdl 		printf("adapter at unexpected slot %d\n"
   1787       1.22      fvdl 		       "unable to map to a channel\n",
   1788       1.39      fvdl 		       ahc->bd->dev);
   1789       1.39      fvdl 		ahc->channel = 'A';
   1790       1.22      fvdl 	}
   1791       1.39      fvdl 	ahc->flags |= AHC_LARGE_SEEPROM;
   1792       1.22      fvdl 	return (0);
   1793        1.1   mycroft }
   1794