1139749Simp/*- 265942Sgibbs * Product specific probe and attach routines for: 365942Sgibbs * 3940, 2940, aic7895, aic7890, aic7880, 465942Sgibbs * aic7870, aic7860 and aic7850 SCSI controllers 565942Sgibbs * 695378Sgibbs * Copyright (c) 1994-2001 Justin T. Gibbs. 795378Sgibbs * Copyright (c) 2000-2001 Adaptec Inc. 865942Sgibbs * All rights reserved. 965942Sgibbs * 1065942Sgibbs * Redistribution and use in source and binary forms, with or without 1165942Sgibbs * modification, are permitted provided that the following conditions 1265942Sgibbs * are met: 1365942Sgibbs * 1. Redistributions of source code must retain the above copyright 1465942Sgibbs * notice, this list of conditions, and the following disclaimer, 1595378Sgibbs * without modification. 1695378Sgibbs * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1795378Sgibbs * substantially similar to the "NO WARRANTY" disclaimer below 1895378Sgibbs * ("Disclaimer") and any redistribution must be conditioned upon 1995378Sgibbs * including a substantially similar Disclaimer requirement for further 2095378Sgibbs * binary redistribution. 2195378Sgibbs * 3. Neither the names of the above-listed copyright holders nor the names 2295378Sgibbs * of any contributors may be used to endorse or promote products derived 2395378Sgibbs * from this software without specific prior written permission. 2465942Sgibbs * 2565942Sgibbs * Alternatively, this software may be distributed under the terms of the 2695378Sgibbs * GNU General Public License ("GPL") version 2 as published by the Free 2795378Sgibbs * Software Foundation. 2865942Sgibbs * 2995378Sgibbs * NO WARRANTY 3095378Sgibbs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3195378Sgibbs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3295378Sgibbs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3395378Sgibbs * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3495378Sgibbs * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3565942Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3665942Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3795378Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3895378Sgibbs * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 3995378Sgibbs * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4095378Sgibbs * POSSIBILITY OF SUCH DAMAGES. 4165942Sgibbs * 42123579Sgibbs * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#78 $ 4365942Sgibbs */ 4465942Sgibbs 4595378Sgibbs#ifdef __linux__ 4695378Sgibbs#include "aic7xxx_osm.h" 4795378Sgibbs#include "aic7xxx_inline.h" 4895378Sgibbs#include "aic7xxx_93cx6.h" 4995378Sgibbs#else 50123579Sgibbs#include <sys/cdefs.h> 51123579Sgibbs__FBSDID("$FreeBSD$"); 5295378Sgibbs#include <dev/aic7xxx/aic7xxx_osm.h> 5365942Sgibbs#include <dev/aic7xxx/aic7xxx_inline.h> 5465942Sgibbs#include <dev/aic7xxx/aic7xxx_93cx6.h> 5595378Sgibbs#endif 5665942Sgibbs 5765942Sgibbsstatic __inline uint64_t 5865942Sgibbsahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) 5965942Sgibbs{ 6065942Sgibbs uint64_t id; 6165942Sgibbs 6265942Sgibbs id = subvendor 6365942Sgibbs | (subdevice << 16) 6465942Sgibbs | ((uint64_t)vendor << 32) 6565942Sgibbs | ((uint64_t)device << 48); 6665942Sgibbs 6765942Sgibbs return (id); 6865942Sgibbs} 6965942Sgibbs 7074094Sgibbs#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull 7174094Sgibbs#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull 7274094Sgibbs#define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull 7374094Sgibbs#define ID_9005_SISL_MASK 0x000FFFFF00000000ull 7474094Sgibbs#define ID_9005_SISL_ID 0x0005900500000000ull 7574094Sgibbs#define ID_AIC7850 0x5078900400000000ull 76115338Sgibbs#define ID_AHA_2902_04_10_15_20C_30C 0x5078900478509004ull 7774094Sgibbs#define ID_AIC7855 0x5578900400000000ull 7874094Sgibbs#define ID_AIC7859 0x3860900400000000ull 7974094Sgibbs#define ID_AHA_2930CU 0x3860900438699004ull 8074094Sgibbs#define ID_AIC7860 0x6078900400000000ull 8174094Sgibbs#define ID_AIC7860C 0x6078900478609004ull 8274094Sgibbs#define ID_AHA_1480A 0x6075900400000000ull 8374094Sgibbs#define ID_AHA_2940AU_0 0x6178900400000000ull 8474094Sgibbs#define ID_AHA_2940AU_1 0x6178900478619004ull 8574094Sgibbs#define ID_AHA_2940AU_CN 0x2178900478219004ull 8674094Sgibbs#define ID_AHA_2930C_VAR 0x6038900438689004ull 8765942Sgibbs 8874094Sgibbs#define ID_AIC7870 0x7078900400000000ull 8974094Sgibbs#define ID_AHA_2940 0x7178900400000000ull 9074094Sgibbs#define ID_AHA_3940 0x7278900400000000ull 9174094Sgibbs#define ID_AHA_398X 0x7378900400000000ull 9274094Sgibbs#define ID_AHA_2944 0x7478900400000000ull 9374094Sgibbs#define ID_AHA_3944 0x7578900400000000ull 9474094Sgibbs#define ID_AHA_4944 0x7678900400000000ull 9565942Sgibbs 9674094Sgibbs#define ID_AIC7880 0x8078900400000000ull 9774094Sgibbs#define ID_AIC7880_B 0x8078900478809004ull 9874094Sgibbs#define ID_AHA_2940U 0x8178900400000000ull 9974094Sgibbs#define ID_AHA_3940U 0x8278900400000000ull 10074094Sgibbs#define ID_AHA_2944U 0x8478900400000000ull 10174094Sgibbs#define ID_AHA_3944U 0x8578900400000000ull 10274094Sgibbs#define ID_AHA_398XU 0x8378900400000000ull 10374094Sgibbs#define ID_AHA_4944U 0x8678900400000000ull 10474094Sgibbs#define ID_AHA_2940UB 0x8178900478819004ull 10574094Sgibbs#define ID_AHA_2930U 0x8878900478889004ull 10674094Sgibbs#define ID_AHA_2940U_PRO 0x8778900478879004ull 10774094Sgibbs#define ID_AHA_2940U_CN 0x0078900478009004ull 10865942Sgibbs 10974094Sgibbs#define ID_AIC7895 0x7895900478959004ull 11074094Sgibbs#define ID_AIC7895_ARO 0x7890900478939004ull 11174094Sgibbs#define ID_AIC7895_ARO_MASK 0xFFF0FFFFFFFFFFFFull 11274094Sgibbs#define ID_AHA_2940U_DUAL 0x7895900478919004ull 11374094Sgibbs#define ID_AHA_3940AU 0x7895900478929004ull 11474094Sgibbs#define ID_AHA_3944AU 0x7895900478949004ull 11565942Sgibbs 11674094Sgibbs#define ID_AIC7890 0x001F9005000F9005ull 11774094Sgibbs#define ID_AIC7890_ARO 0x00139005000F9005ull 11874094Sgibbs#define ID_AAA_131U2 0x0013900500039005ull 11974094Sgibbs#define ID_AHA_2930U2 0x0011900501819005ull 12074094Sgibbs#define ID_AHA_2940U2B 0x00109005A1009005ull 12174094Sgibbs#define ID_AHA_2940U2_OEM 0x0010900521809005ull 12274094Sgibbs#define ID_AHA_2940U2 0x00109005A1809005ull 12374094Sgibbs#define ID_AHA_2950U2B 0x00109005E1009005ull 12465942Sgibbs 12574094Sgibbs#define ID_AIC7892 0x008F9005FFFF9005ull 12674094Sgibbs#define ID_AIC7892_ARO 0x00839005FFFF9005ull 12774094Sgibbs#define ID_AHA_29160 0x00809005E2A09005ull 12874094Sgibbs#define ID_AHA_29160_CPQ 0x00809005E2A00E11ull 12974094Sgibbs#define ID_AHA_29160N 0x0080900562A09005ull 13074094Sgibbs#define ID_AHA_29160C 0x0080900562209005ull 13174094Sgibbs#define ID_AHA_29160B 0x00809005E2209005ull 13274094Sgibbs#define ID_AHA_19160B 0x0081900562A19005ull 133123579Sgibbs#define ID_AHA_2915_30LP 0x0082900502109005ull 13465942Sgibbs 13574094Sgibbs#define ID_AIC7896 0x005F9005FFFF9005ull 13674094Sgibbs#define ID_AIC7896_ARO 0x00539005FFFF9005ull 13774094Sgibbs#define ID_AHA_3950U2B_0 0x00509005FFFF9005ull 13874094Sgibbs#define ID_AHA_3950U2B_1 0x00509005F5009005ull 13974094Sgibbs#define ID_AHA_3950U2D_0 0x00519005FFFF9005ull 14074094Sgibbs#define ID_AHA_3950U2D_1 0x00519005B5009005ull 14165942Sgibbs 14274094Sgibbs#define ID_AIC7899 0x00CF9005FFFF9005ull 14374094Sgibbs#define ID_AIC7899_ARO 0x00C39005FFFF9005ull 14474094Sgibbs#define ID_AHA_3960D 0x00C09005F6209005ull 14574094Sgibbs#define ID_AHA_3960D_CPQ 0x00C09005F6200E11ull 14665942Sgibbs 14774094Sgibbs#define ID_AIC7810 0x1078900400000000ull 14874094Sgibbs#define ID_AIC7815 0x7815900400000000ull 14965942Sgibbs 15072325Sgibbs#define DEVID_9005_TYPE(id) ((id) & 0xF) 15172325Sgibbs#define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */ 15272325Sgibbs#define DEVID_9005_TYPE_AAA 0x3 /* RAID Card */ 15395378Sgibbs#define DEVID_9005_TYPE_SISL 0x5 /* Container ROMB */ 15472325Sgibbs#define DEVID_9005_TYPE_MB 0xF /* On Motherboard */ 15572325Sgibbs 15672325Sgibbs#define DEVID_9005_MAXRATE(id) (((id) & 0x30) >> 4) 15772325Sgibbs#define DEVID_9005_MAXRATE_U160 0x0 15872325Sgibbs#define DEVID_9005_MAXRATE_ULTRA2 0x1 15972325Sgibbs#define DEVID_9005_MAXRATE_ULTRA 0x2 16072325Sgibbs#define DEVID_9005_MAXRATE_FAST 0x3 16172325Sgibbs 16272325Sgibbs#define DEVID_9005_MFUNC(id) (((id) & 0x40) >> 6) 16372325Sgibbs 16472325Sgibbs#define DEVID_9005_CLASS(id) (((id) & 0xFF00) >> 8) 16572325Sgibbs#define DEVID_9005_CLASS_SPI 0x0 /* Parallel SCSI */ 16672325Sgibbs 16770693Sgibbs#define SUBID_9005_TYPE(id) ((id) & 0xF) 16870693Sgibbs#define SUBID_9005_TYPE_MB 0xF /* On Motherboard */ 16970693Sgibbs#define SUBID_9005_TYPE_CARD 0x0 /* Standard Card */ 17070693Sgibbs#define SUBID_9005_TYPE_LCCARD 0x1 /* Low Cost Card */ 17170693Sgibbs#define SUBID_9005_TYPE_RAID 0x3 /* Combined with Raid */ 17270204Sgibbs 17372811Sgibbs#define SUBID_9005_TYPE_KNOWN(id) \ 17472811Sgibbs ((((id) & 0xF) == SUBID_9005_TYPE_MB) \ 17572811Sgibbs || (((id) & 0xF) == SUBID_9005_TYPE_CARD) \ 17672811Sgibbs || (((id) & 0xF) == SUBID_9005_TYPE_LCCARD) \ 17772811Sgibbs || (((id) & 0xF) == SUBID_9005_TYPE_RAID)) 17872811Sgibbs 17970693Sgibbs#define SUBID_9005_MAXRATE(id) (((id) & 0x30) >> 4) 18070693Sgibbs#define SUBID_9005_MAXRATE_ULTRA2 0x0 18170693Sgibbs#define SUBID_9005_MAXRATE_ULTRA 0x1 18270693Sgibbs#define SUBID_9005_MAXRATE_U160 0x2 18370693Sgibbs#define SUBID_9005_MAXRATE_RESERVED 0x3 18470693Sgibbs 18570693Sgibbs#define SUBID_9005_SEEPTYPE(id) \ 18670693Sgibbs ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \ 18770693Sgibbs ? ((id) & 0xC0) >> 6 \ 18870693Sgibbs : ((id) & 0x300) >> 8) 18970693Sgibbs#define SUBID_9005_SEEPTYPE_NONE 0x0 19070693Sgibbs#define SUBID_9005_SEEPTYPE_1K 0x1 19170693Sgibbs#define SUBID_9005_SEEPTYPE_2K_4K 0x2 19270693Sgibbs#define SUBID_9005_SEEPTYPE_RESERVED 0x3 19370693Sgibbs#define SUBID_9005_AUTOTERM(id) \ 19470693Sgibbs ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \ 19570693Sgibbs ? (((id) & 0x400) >> 10) == 0 \ 19670693Sgibbs : (((id) & 0x40) >> 6) == 0) 19770693Sgibbs 19870693Sgibbs#define SUBID_9005_NUMCHAN(id) \ 19970693Sgibbs ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \ 20070693Sgibbs ? ((id) & 0x300) >> 8 \ 20170693Sgibbs : ((id) & 0xC00) >> 10) 20270693Sgibbs 20370693Sgibbs#define SUBID_9005_LEGACYCONN(id) \ 20470693Sgibbs ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \ 20570693Sgibbs ? 0 \ 20670693Sgibbs : ((id) & 0x80) >> 7) 20770693Sgibbs 20870693Sgibbs#define SUBID_9005_MFUNCENB(id) \ 20970693Sgibbs ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \ 21070693Sgibbs ? ((id) & 0x800) >> 11 \ 21170693Sgibbs : ((id) & 0x1000) >> 12) 21270693Sgibbs/* 21370693Sgibbs * Informational only. Should use chip register to be 21495378Sgibbs * certain, but may be use in identification strings. 21570693Sgibbs */ 21670693Sgibbs#define SUBID_9005_CARD_SCSIWIDTH_MASK 0x2000 21770693Sgibbs#define SUBID_9005_CARD_PCIWIDTH_MASK 0x4000 21870693Sgibbs#define SUBID_9005_CARD_SEDIFF_MASK 0x8000 21970693Sgibbs 22074094Sgibbsstatic ahc_device_setup_t ahc_aic785X_setup; 22165942Sgibbsstatic ahc_device_setup_t ahc_aic7860_setup; 22271390Sgibbsstatic ahc_device_setup_t ahc_apa1480_setup; 22365942Sgibbsstatic ahc_device_setup_t ahc_aic7870_setup; 22465942Sgibbsstatic ahc_device_setup_t ahc_aha394X_setup; 22565942Sgibbsstatic ahc_device_setup_t ahc_aha494X_setup; 22665942Sgibbsstatic ahc_device_setup_t ahc_aha398X_setup; 22765942Sgibbsstatic ahc_device_setup_t ahc_aic7880_setup; 22871390Sgibbsstatic ahc_device_setup_t ahc_aha2940Pro_setup; 22965942Sgibbsstatic ahc_device_setup_t ahc_aha394XU_setup; 23065942Sgibbsstatic ahc_device_setup_t ahc_aha398XU_setup; 23165942Sgibbsstatic ahc_device_setup_t ahc_aic7890_setup; 23265942Sgibbsstatic ahc_device_setup_t ahc_aic7892_setup; 23365942Sgibbsstatic ahc_device_setup_t ahc_aic7895_setup; 23465942Sgibbsstatic ahc_device_setup_t ahc_aic7896_setup; 23565942Sgibbsstatic ahc_device_setup_t ahc_aic7899_setup; 23671390Sgibbsstatic ahc_device_setup_t ahc_aha29160C_setup; 23765942Sgibbsstatic ahc_device_setup_t ahc_raid_setup; 23865942Sgibbsstatic ahc_device_setup_t ahc_aha394XX_setup; 23965942Sgibbsstatic ahc_device_setup_t ahc_aha494XX_setup; 24065942Sgibbsstatic ahc_device_setup_t ahc_aha398XX_setup; 24165942Sgibbs 24265942Sgibbsstruct ahc_pci_identity ahc_pci_ident_table [] = 24365942Sgibbs{ 24465942Sgibbs /* aic7850 based controllers */ 24565942Sgibbs { 246115338Sgibbs ID_AHA_2902_04_10_15_20C_30C, 24765942Sgibbs ID_ALL_MASK, 248115338Sgibbs "Adaptec 2902/04/10/15/20C/30C SCSI adapter", 24974094Sgibbs ahc_aic785X_setup 25065942Sgibbs }, 25165942Sgibbs /* aic7860 based controllers */ 25265942Sgibbs { 25365942Sgibbs ID_AHA_2930CU, 25465942Sgibbs ID_ALL_MASK, 25565942Sgibbs "Adaptec 2930CU SCSI adapter", 25665942Sgibbs ahc_aic7860_setup 25765942Sgibbs }, 25865942Sgibbs { 25965942Sgibbs ID_AHA_1480A & ID_DEV_VENDOR_MASK, 26065942Sgibbs ID_DEV_VENDOR_MASK, 26165942Sgibbs "Adaptec 1480A Ultra SCSI adapter", 26271390Sgibbs ahc_apa1480_setup 26365942Sgibbs }, 26465942Sgibbs { 26565942Sgibbs ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK, 26665942Sgibbs ID_DEV_VENDOR_MASK, 26765942Sgibbs "Adaptec 2940A Ultra SCSI adapter", 26865942Sgibbs ahc_aic7860_setup 26965942Sgibbs }, 27065942Sgibbs { 27165942Sgibbs ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK, 27265942Sgibbs ID_DEV_VENDOR_MASK, 27365942Sgibbs "Adaptec 2940A/CN Ultra SCSI adapter", 27465942Sgibbs ahc_aic7860_setup 27565942Sgibbs }, 27665942Sgibbs { 27765942Sgibbs ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK, 27865942Sgibbs ID_DEV_VENDOR_MASK, 27976634Sgibbs "Adaptec 2930C Ultra SCSI adapter (VAR)", 28065942Sgibbs ahc_aic7860_setup 28165942Sgibbs }, 28265942Sgibbs /* aic7870 based controllers */ 28365942Sgibbs { 28465942Sgibbs ID_AHA_2940, 28565942Sgibbs ID_ALL_MASK, 28665942Sgibbs "Adaptec 2940 SCSI adapter", 28765942Sgibbs ahc_aic7870_setup 28865942Sgibbs }, 28965942Sgibbs { 29065942Sgibbs ID_AHA_3940, 29165942Sgibbs ID_ALL_MASK, 29265942Sgibbs "Adaptec 3940 SCSI adapter", 29365942Sgibbs ahc_aha394X_setup 29465942Sgibbs }, 29565942Sgibbs { 29665942Sgibbs ID_AHA_398X, 29765942Sgibbs ID_ALL_MASK, 29865942Sgibbs "Adaptec 398X SCSI RAID adapter", 29965942Sgibbs ahc_aha398X_setup 30065942Sgibbs }, 30165942Sgibbs { 30265942Sgibbs ID_AHA_2944, 30365942Sgibbs ID_ALL_MASK, 30465942Sgibbs "Adaptec 2944 SCSI adapter", 30565942Sgibbs ahc_aic7870_setup 30665942Sgibbs }, 30765942Sgibbs { 30865942Sgibbs ID_AHA_3944, 30965942Sgibbs ID_ALL_MASK, 31065942Sgibbs "Adaptec 3944 SCSI adapter", 31165942Sgibbs ahc_aha394X_setup 31265942Sgibbs }, 31365942Sgibbs { 31465942Sgibbs ID_AHA_4944, 31565942Sgibbs ID_ALL_MASK, 31665942Sgibbs "Adaptec 4944 SCSI adapter", 31765942Sgibbs ahc_aha494X_setup 31865942Sgibbs }, 31965942Sgibbs /* aic7880 based controllers */ 32065942Sgibbs { 32165942Sgibbs ID_AHA_2940U & ID_DEV_VENDOR_MASK, 32265942Sgibbs ID_DEV_VENDOR_MASK, 32365942Sgibbs "Adaptec 2940 Ultra SCSI adapter", 32465942Sgibbs ahc_aic7880_setup 32565942Sgibbs }, 32665942Sgibbs { 32765942Sgibbs ID_AHA_3940U & ID_DEV_VENDOR_MASK, 32865942Sgibbs ID_DEV_VENDOR_MASK, 32965942Sgibbs "Adaptec 3940 Ultra SCSI adapter", 33065942Sgibbs ahc_aha394XU_setup 33165942Sgibbs }, 33265942Sgibbs { 33365942Sgibbs ID_AHA_2944U & ID_DEV_VENDOR_MASK, 33465942Sgibbs ID_DEV_VENDOR_MASK, 33565942Sgibbs "Adaptec 2944 Ultra SCSI adapter", 33665942Sgibbs ahc_aic7880_setup 33765942Sgibbs }, 33865942Sgibbs { 33965942Sgibbs ID_AHA_3944U & ID_DEV_VENDOR_MASK, 34065942Sgibbs ID_DEV_VENDOR_MASK, 34165942Sgibbs "Adaptec 3944 Ultra SCSI adapter", 34265942Sgibbs ahc_aha394XU_setup 34365942Sgibbs }, 34465942Sgibbs { 34565942Sgibbs ID_AHA_398XU & ID_DEV_VENDOR_MASK, 34665942Sgibbs ID_DEV_VENDOR_MASK, 34765942Sgibbs "Adaptec 398X Ultra SCSI RAID adapter", 34865942Sgibbs ahc_aha398XU_setup 34965942Sgibbs }, 35065942Sgibbs { 35165942Sgibbs /* 35265942Sgibbs * XXX Don't know the slot numbers 35365942Sgibbs * so we can't identify channels 35465942Sgibbs */ 35565942Sgibbs ID_AHA_4944U & ID_DEV_VENDOR_MASK, 35665942Sgibbs ID_DEV_VENDOR_MASK, 35765942Sgibbs "Adaptec 4944 Ultra SCSI adapter", 35865942Sgibbs ahc_aic7880_setup 35965942Sgibbs }, 36065942Sgibbs { 36165942Sgibbs ID_AHA_2930U & ID_DEV_VENDOR_MASK, 36265942Sgibbs ID_DEV_VENDOR_MASK, 36365942Sgibbs "Adaptec 2930 Ultra SCSI adapter", 36465942Sgibbs ahc_aic7880_setup 36565942Sgibbs }, 36665942Sgibbs { 36765942Sgibbs ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK, 36865942Sgibbs ID_DEV_VENDOR_MASK, 36965942Sgibbs "Adaptec 2940 Pro Ultra SCSI adapter", 37071390Sgibbs ahc_aha2940Pro_setup 37165942Sgibbs }, 37265942Sgibbs { 37365942Sgibbs ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK, 37465942Sgibbs ID_DEV_VENDOR_MASK, 37565942Sgibbs "Adaptec 2940/CN Ultra SCSI adapter", 37665942Sgibbs ahc_aic7880_setup 37765942Sgibbs }, 37872811Sgibbs /* Ignore all SISL (AAC on MB) based controllers. */ 37972811Sgibbs { 38072811Sgibbs ID_9005_SISL_ID, 38172811Sgibbs ID_9005_SISL_MASK, 38272811Sgibbs NULL, 38372811Sgibbs NULL 38472811Sgibbs }, 38565942Sgibbs /* aic7890 based controllers */ 38665942Sgibbs { 38765942Sgibbs ID_AHA_2930U2, 38865942Sgibbs ID_ALL_MASK, 38965942Sgibbs "Adaptec 2930 Ultra2 SCSI adapter", 39065942Sgibbs ahc_aic7890_setup 39165942Sgibbs }, 39265942Sgibbs { 39365942Sgibbs ID_AHA_2940U2B, 39465942Sgibbs ID_ALL_MASK, 39565942Sgibbs "Adaptec 2940B Ultra2 SCSI adapter", 39665942Sgibbs ahc_aic7890_setup 39765942Sgibbs }, 39865942Sgibbs { 39965942Sgibbs ID_AHA_2940U2_OEM, 40065942Sgibbs ID_ALL_MASK, 40165942Sgibbs "Adaptec 2940 Ultra2 SCSI adapter (OEM)", 40265942Sgibbs ahc_aic7890_setup 40365942Sgibbs }, 40465942Sgibbs { 40565942Sgibbs ID_AHA_2940U2, 40665942Sgibbs ID_ALL_MASK, 40765942Sgibbs "Adaptec 2940 Ultra2 SCSI adapter", 40865942Sgibbs ahc_aic7890_setup 40965942Sgibbs }, 41065942Sgibbs { 41165942Sgibbs ID_AHA_2950U2B, 41265942Sgibbs ID_ALL_MASK, 41365942Sgibbs "Adaptec 2950 Ultra2 SCSI adapter", 41465942Sgibbs ahc_aic7890_setup 41565942Sgibbs }, 41665942Sgibbs { 41772811Sgibbs ID_AIC7890_ARO, 41872811Sgibbs ID_ALL_MASK, 41972811Sgibbs "Adaptec aic7890/91 Ultra2 SCSI adapter (ARO)", 42072811Sgibbs ahc_aic7890_setup 42172811Sgibbs }, 42272811Sgibbs { 42365942Sgibbs ID_AAA_131U2, 42465942Sgibbs ID_ALL_MASK, 42565942Sgibbs "Adaptec AAA-131 Ultra2 RAID adapter", 42665942Sgibbs ahc_aic7890_setup 42765942Sgibbs }, 42865942Sgibbs /* aic7892 based controllers */ 42965942Sgibbs { 43065942Sgibbs ID_AHA_29160, 43165942Sgibbs ID_ALL_MASK, 43265942Sgibbs "Adaptec 29160 Ultra160 SCSI adapter", 43365942Sgibbs ahc_aic7892_setup 43465942Sgibbs }, 43565942Sgibbs { 43665942Sgibbs ID_AHA_29160_CPQ, 43765942Sgibbs ID_ALL_MASK, 43865942Sgibbs "Adaptec (Compaq OEM) 29160 Ultra160 SCSI adapter", 43965942Sgibbs ahc_aic7892_setup 44065942Sgibbs }, 44165942Sgibbs { 44265942Sgibbs ID_AHA_29160N, 44365942Sgibbs ID_ALL_MASK, 44465942Sgibbs "Adaptec 29160N Ultra160 SCSI adapter", 44565942Sgibbs ahc_aic7892_setup 44665942Sgibbs }, 44765942Sgibbs { 44870204Sgibbs ID_AHA_29160C, 44970204Sgibbs ID_ALL_MASK, 45070204Sgibbs "Adaptec 29160C Ultra160 SCSI adapter", 45171390Sgibbs ahc_aha29160C_setup 45270204Sgibbs }, 45370204Sgibbs { 45465942Sgibbs ID_AHA_29160B, 45565942Sgibbs ID_ALL_MASK, 45665942Sgibbs "Adaptec 29160B Ultra160 SCSI adapter", 45765942Sgibbs ahc_aic7892_setup 45865942Sgibbs }, 45965942Sgibbs { 46065942Sgibbs ID_AHA_19160B, 46165942Sgibbs ID_ALL_MASK, 46265942Sgibbs "Adaptec 19160B Ultra160 SCSI adapter", 46365942Sgibbs ahc_aic7892_setup 46465942Sgibbs }, 46572811Sgibbs { 46672811Sgibbs ID_AIC7892_ARO, 46772811Sgibbs ID_ALL_MASK, 46876634Sgibbs "Adaptec aic7892 Ultra160 SCSI adapter (ARO)", 46972811Sgibbs ahc_aic7892_setup 47072811Sgibbs }, 471123579Sgibbs { 472123579Sgibbs ID_AHA_2915_30LP, 473123579Sgibbs ID_ALL_MASK, 474123579Sgibbs "Adaptec 2915/30LP Ultra160 SCSI adapter", 475123579Sgibbs ahc_aic7892_setup 476123579Sgibbs }, 47765942Sgibbs /* aic7895 based controllers */ 47865942Sgibbs { 47965942Sgibbs ID_AHA_2940U_DUAL, 48065942Sgibbs ID_ALL_MASK, 48165942Sgibbs "Adaptec 2940/DUAL Ultra SCSI adapter", 48265942Sgibbs ahc_aic7895_setup 48365942Sgibbs }, 48465942Sgibbs { 48565942Sgibbs ID_AHA_3940AU, 48665942Sgibbs ID_ALL_MASK, 48765942Sgibbs "Adaptec 3940A Ultra SCSI adapter", 48865942Sgibbs ahc_aic7895_setup 48965942Sgibbs }, 49065942Sgibbs { 49165942Sgibbs ID_AHA_3944AU, 49265942Sgibbs ID_ALL_MASK, 49365942Sgibbs "Adaptec 3944A Ultra SCSI adapter", 49465942Sgibbs ahc_aic7895_setup 49565942Sgibbs }, 49672811Sgibbs { 49772811Sgibbs ID_AIC7895_ARO, 49872811Sgibbs ID_AIC7895_ARO_MASK, 49972811Sgibbs "Adaptec aic7895 Ultra SCSI adapter (ARO)", 50072811Sgibbs ahc_aic7895_setup 50172811Sgibbs }, 50265942Sgibbs /* aic7896/97 based controllers */ 50365942Sgibbs { 50465942Sgibbs ID_AHA_3950U2B_0, 50565942Sgibbs ID_ALL_MASK, 50665942Sgibbs "Adaptec 3950B Ultra2 SCSI adapter", 50765942Sgibbs ahc_aic7896_setup 50865942Sgibbs }, 50965942Sgibbs { 51065942Sgibbs ID_AHA_3950U2B_1, 51165942Sgibbs ID_ALL_MASK, 51265942Sgibbs "Adaptec 3950B Ultra2 SCSI adapter", 51365942Sgibbs ahc_aic7896_setup 51465942Sgibbs }, 51565942Sgibbs { 51665942Sgibbs ID_AHA_3950U2D_0, 51765942Sgibbs ID_ALL_MASK, 51865942Sgibbs "Adaptec 3950D Ultra2 SCSI adapter", 51965942Sgibbs ahc_aic7896_setup 52065942Sgibbs }, 52165942Sgibbs { 52265942Sgibbs ID_AHA_3950U2D_1, 52365942Sgibbs ID_ALL_MASK, 52465942Sgibbs "Adaptec 3950D Ultra2 SCSI adapter", 52565942Sgibbs ahc_aic7896_setup 52665942Sgibbs }, 52772811Sgibbs { 52872811Sgibbs ID_AIC7896_ARO, 52972811Sgibbs ID_ALL_MASK, 53072811Sgibbs "Adaptec aic7896/97 Ultra2 SCSI adapter (ARO)", 53172811Sgibbs ahc_aic7896_setup 53272811Sgibbs }, 53365942Sgibbs /* aic7899 based controllers */ 53465942Sgibbs { 53565942Sgibbs ID_AHA_3960D, 53665942Sgibbs ID_ALL_MASK, 53765942Sgibbs "Adaptec 3960D Ultra160 SCSI adapter", 53865942Sgibbs ahc_aic7899_setup 53965942Sgibbs }, 54065942Sgibbs { 54165942Sgibbs ID_AHA_3960D_CPQ, 54265942Sgibbs ID_ALL_MASK, 54365942Sgibbs "Adaptec (Compaq OEM) 3960D Ultra160 SCSI adapter", 54465942Sgibbs ahc_aic7899_setup 54565942Sgibbs }, 54672811Sgibbs { 54772811Sgibbs ID_AIC7899_ARO, 54872811Sgibbs ID_ALL_MASK, 54972811Sgibbs "Adaptec aic7899 Ultra160 SCSI adapter (ARO)", 55072811Sgibbs ahc_aic7899_setup 55172811Sgibbs }, 55265942Sgibbs /* Generic chip probes for devices we don't know 'exactly' */ 55365942Sgibbs { 55465942Sgibbs ID_AIC7850 & ID_DEV_VENDOR_MASK, 55565942Sgibbs ID_DEV_VENDOR_MASK, 55665942Sgibbs "Adaptec aic7850 SCSI adapter", 55774094Sgibbs ahc_aic785X_setup 55865942Sgibbs }, 55965942Sgibbs { 56065942Sgibbs ID_AIC7855 & ID_DEV_VENDOR_MASK, 56165942Sgibbs ID_DEV_VENDOR_MASK, 56265942Sgibbs "Adaptec aic7855 SCSI adapter", 56374094Sgibbs ahc_aic785X_setup 56465942Sgibbs }, 56565942Sgibbs { 56665942Sgibbs ID_AIC7859 & ID_DEV_VENDOR_MASK, 56765942Sgibbs ID_DEV_VENDOR_MASK, 56876634Sgibbs "Adaptec aic7859 SCSI adapter", 56965942Sgibbs ahc_aic7860_setup 57065942Sgibbs }, 57165942Sgibbs { 57265942Sgibbs ID_AIC7860 & ID_DEV_VENDOR_MASK, 57365942Sgibbs ID_DEV_VENDOR_MASK, 57476634Sgibbs "Adaptec aic7860 Ultra SCSI adapter", 57565942Sgibbs ahc_aic7860_setup 57665942Sgibbs }, 57765942Sgibbs { 57865942Sgibbs ID_AIC7870 & ID_DEV_VENDOR_MASK, 57965942Sgibbs ID_DEV_VENDOR_MASK, 58065942Sgibbs "Adaptec aic7870 SCSI adapter", 58165942Sgibbs ahc_aic7870_setup 58265942Sgibbs }, 58365942Sgibbs { 58465942Sgibbs ID_AIC7880 & ID_DEV_VENDOR_MASK, 58565942Sgibbs ID_DEV_VENDOR_MASK, 58665942Sgibbs "Adaptec aic7880 Ultra SCSI adapter", 58765942Sgibbs ahc_aic7880_setup 58865942Sgibbs }, 58965942Sgibbs { 59072325Sgibbs ID_AIC7890 & ID_9005_GENERIC_MASK, 59172325Sgibbs ID_9005_GENERIC_MASK, 59265942Sgibbs "Adaptec aic7890/91 Ultra2 SCSI adapter", 59365942Sgibbs ahc_aic7890_setup 59465942Sgibbs }, 59565942Sgibbs { 59672325Sgibbs ID_AIC7892 & ID_9005_GENERIC_MASK, 59772325Sgibbs ID_9005_GENERIC_MASK, 59865942Sgibbs "Adaptec aic7892 Ultra160 SCSI adapter", 59965942Sgibbs ahc_aic7892_setup 60065942Sgibbs }, 60165942Sgibbs { 60265942Sgibbs ID_AIC7895 & ID_DEV_VENDOR_MASK, 60365942Sgibbs ID_DEV_VENDOR_MASK, 60465942Sgibbs "Adaptec aic7895 Ultra SCSI adapter", 60565942Sgibbs ahc_aic7895_setup 60665942Sgibbs }, 60765942Sgibbs { 60872325Sgibbs ID_AIC7896 & ID_9005_GENERIC_MASK, 60972325Sgibbs ID_9005_GENERIC_MASK, 61065942Sgibbs "Adaptec aic7896/97 Ultra2 SCSI adapter", 61165942Sgibbs ahc_aic7896_setup 61265942Sgibbs }, 61365942Sgibbs { 61472325Sgibbs ID_AIC7899 & ID_9005_GENERIC_MASK, 61572325Sgibbs ID_9005_GENERIC_MASK, 61665942Sgibbs "Adaptec aic7899 Ultra160 SCSI adapter", 61765942Sgibbs ahc_aic7899_setup 61865942Sgibbs }, 61965942Sgibbs { 62065942Sgibbs ID_AIC7810 & ID_DEV_VENDOR_MASK, 62165942Sgibbs ID_DEV_VENDOR_MASK, 62265942Sgibbs "Adaptec aic7810 RAID memory controller", 62365942Sgibbs ahc_raid_setup 62465942Sgibbs }, 62565942Sgibbs { 62665942Sgibbs ID_AIC7815 & ID_DEV_VENDOR_MASK, 62765942Sgibbs ID_DEV_VENDOR_MASK, 62865942Sgibbs "Adaptec aic7815 RAID memory controller", 62965942Sgibbs ahc_raid_setup 63065942Sgibbs } 63165942Sgibbs}; 63265942Sgibbs 63370204Sgibbsconst u_int ahc_num_pci_devs = NUM_ELEMENTS(ahc_pci_ident_table); 63465942Sgibbs 63565942Sgibbs#define AHC_394X_SLOT_CHANNEL_A 4 63665942Sgibbs#define AHC_394X_SLOT_CHANNEL_B 5 63765942Sgibbs 63865942Sgibbs#define AHC_398X_SLOT_CHANNEL_A 4 63965942Sgibbs#define AHC_398X_SLOT_CHANNEL_B 8 64065942Sgibbs#define AHC_398X_SLOT_CHANNEL_C 12 64165942Sgibbs 64265942Sgibbs#define AHC_494X_SLOT_CHANNEL_A 4 64365942Sgibbs#define AHC_494X_SLOT_CHANNEL_B 5 64465942Sgibbs#define AHC_494X_SLOT_CHANNEL_C 6 64565942Sgibbs#define AHC_494X_SLOT_CHANNEL_D 7 64665942Sgibbs 64765942Sgibbs#define DEVCONFIG 0x40 648109590Sgibbs#define PCIERRGENDIS 0x80000000ul 64965942Sgibbs#define SCBSIZE32 0x00010000ul /* aic789X only */ 65074094Sgibbs#define REXTVALID 0x00001000ul /* ultra cards only */ 65179874Sgibbs#define MPORTMODE 0x00000400ul /* aic7870+ only */ 65279874Sgibbs#define RAMPSM 0x00000200ul /* aic7870+ only */ 65365942Sgibbs#define VOLSENSE 0x00000100ul 65479874Sgibbs#define PCI64BIT 0x00000080ul /* 64Bit PCI bus (Ultra2 Only)*/ 65565942Sgibbs#define SCBRAMSEL 0x00000080ul 65665942Sgibbs#define MRDCEN 0x00000040ul 65765942Sgibbs#define EXTSCBTIME 0x00000020ul /* aic7870 only */ 65865942Sgibbs#define EXTSCBPEN 0x00000010ul /* aic7870 only */ 65965942Sgibbs#define BERREN 0x00000008ul 66065942Sgibbs#define DACEN 0x00000004ul 66165942Sgibbs#define STPWLEVEL 0x00000002ul 66265942Sgibbs#define DIFACTNEGEN 0x00000001ul /* aic7870 only */ 66365942Sgibbs 66465942Sgibbs#define CSIZE_LATTIME 0x0c 66565942Sgibbs#define CACHESIZE 0x0000003ful /* only 5 bits */ 66665942Sgibbs#define LATTIME 0x0000ff00ul 66765942Sgibbs 668107419Sscottl/* PCI STATUS definitions */ 669107419Sscottl#define DPE 0x80 670107419Sscottl#define SSE 0x40 671107419Sscottl#define RMA 0x20 672107419Sscottl#define RTA 0x10 673107419Sscottl#define STA 0x08 674107419Sscottl#define DPR 0x01 675107419Sscottl 676253646Suqsstatic int ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor, 677253646Suqs uint16_t subdevice, uint16_t subvendor); 67865942Sgibbsstatic int ahc_ext_scbram_present(struct ahc_softc *ahc); 67965942Sgibbsstatic void ahc_scbram_config(struct ahc_softc *ahc, int enable, 68065942Sgibbs int pcheck, int fast, int large); 68165942Sgibbsstatic void ahc_probe_ext_scbram(struct ahc_softc *ahc); 68265942Sgibbsstatic void check_extport(struct ahc_softc *ahc, u_int *sxfrctl1); 683102676Sgibbsstatic void ahc_parse_pci_eeprom(struct ahc_softc *ahc, 684102676Sgibbs struct seeprom_config *sc); 68565942Sgibbsstatic void configure_termination(struct ahc_softc *ahc, 68665942Sgibbs struct seeprom_descriptor *sd, 68765942Sgibbs u_int adapter_control, 68865942Sgibbs u_int *sxfrctl1); 68965942Sgibbs 69065942Sgibbsstatic void ahc_new_term_detect(struct ahc_softc *ahc, 69165942Sgibbs int *enableSEC_low, 69265942Sgibbs int *enableSEC_high, 69365942Sgibbs int *enablePRI_low, 69465942Sgibbs int *enablePRI_high, 69565942Sgibbs int *eeprom_present); 69665942Sgibbsstatic void aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present, 69765942Sgibbs int *internal68_present, 69865942Sgibbs int *externalcable_present, 69965942Sgibbs int *eeprom_present); 70065942Sgibbsstatic void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present, 70165942Sgibbs int *externalcable_present, 70265942Sgibbs int *eeprom_present); 703114621Sgibbsstatic void write_brdctl(struct ahc_softc *ahc, uint8_t value); 70465942Sgibbsstatic uint8_t read_brdctl(struct ahc_softc *ahc); 705114621Sgibbsstatic void ahc_pci_intr(struct ahc_softc *ahc); 706114621Sgibbsstatic int ahc_pci_chip_init(struct ahc_softc *ahc); 707114621Sgibbsstatic int ahc_pci_suspend(struct ahc_softc *ahc); 708114621Sgibbsstatic int ahc_pci_resume(struct ahc_softc *ahc); 70965942Sgibbs 71095378Sgibbsstatic int 71195378Sgibbsahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor, 71295378Sgibbs uint16_t subdevice, uint16_t subvendor) 71395378Sgibbs{ 71495378Sgibbs int result; 71595378Sgibbs 71695378Sgibbs /* Default to invalid. */ 71795378Sgibbs result = 0; 71895378Sgibbs if (vendor == 0x9005 71995378Sgibbs && subvendor == 0x9005 72095378Sgibbs && subdevice != device 72195378Sgibbs && SUBID_9005_TYPE_KNOWN(subdevice) != 0) { 72295378Sgibbs 72395378Sgibbs switch (SUBID_9005_TYPE(subdevice)) { 72495378Sgibbs case SUBID_9005_TYPE_MB: 72595378Sgibbs break; 72695378Sgibbs case SUBID_9005_TYPE_CARD: 72795378Sgibbs case SUBID_9005_TYPE_LCCARD: 72895378Sgibbs /* 72995378Sgibbs * Currently only trust Adaptec cards to 73095378Sgibbs * get the sub device info correct. 73195378Sgibbs */ 73295378Sgibbs if (DEVID_9005_TYPE(device) == DEVID_9005_TYPE_HBA) 73395378Sgibbs result = 1; 73495378Sgibbs break; 73595378Sgibbs case SUBID_9005_TYPE_RAID: 73695378Sgibbs break; 73795378Sgibbs default: 73895378Sgibbs break; 73995378Sgibbs } 74095378Sgibbs } 74195378Sgibbs return (result); 74295378Sgibbs} 74395378Sgibbs 74465942Sgibbsstruct ahc_pci_identity * 745123579Sgibbsahc_find_pci_device(aic_dev_softc_t pci) 74665942Sgibbs{ 74765942Sgibbs uint64_t full_id; 74865942Sgibbs uint16_t device; 74965942Sgibbs uint16_t vendor; 75065942Sgibbs uint16_t subdevice; 75165942Sgibbs uint16_t subvendor; 75265942Sgibbs struct ahc_pci_identity *entry; 75365942Sgibbs u_int i; 75465942Sgibbs 755123579Sgibbs vendor = aic_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2); 756123579Sgibbs device = aic_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2); 757123579Sgibbs subvendor = aic_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2); 758123579Sgibbs subdevice = aic_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2); 759114621Sgibbs full_id = ahc_compose_id(device, vendor, subdevice, subvendor); 76065942Sgibbs 76179874Sgibbs /* 76279874Sgibbs * If the second function is not hooked up, ignore it. 76379874Sgibbs * Unfortunately, not all MB vendors implement the 76479874Sgibbs * subdevice ID as per the Adaptec spec, so do our best 76579874Sgibbs * to sanity check it prior to accepting the subdevice 76679874Sgibbs * ID as valid. 76779874Sgibbs */ 768123579Sgibbs if (aic_get_pci_function(pci) > 0 769253646Suqs && ahc_9005_subdevinfo_valid(device, vendor, subdevice, subvendor) 77070693Sgibbs && SUBID_9005_MFUNCENB(subdevice) == 0) 77170204Sgibbs return (NULL); 77270204Sgibbs 77365942Sgibbs for (i = 0; i < ahc_num_pci_devs; i++) { 77465942Sgibbs entry = &ahc_pci_ident_table[i]; 77572811Sgibbs if (entry->full_id == (full_id & entry->id_mask)) { 77672811Sgibbs /* Honor exclusion entries. */ 77772811Sgibbs if (entry->name == NULL) 77872811Sgibbs return (NULL); 77965942Sgibbs return (entry); 78072811Sgibbs } 78165942Sgibbs } 78265942Sgibbs return (NULL); 78365942Sgibbs} 78465942Sgibbs 78565942Sgibbsint 78665942Sgibbsahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) 78765942Sgibbs{ 788102676Sgibbs u_int command; 789102676Sgibbs u_int our_id; 790102676Sgibbs u_int sxfrctl1; 791102676Sgibbs u_int scsiseq; 792102676Sgibbs u_int dscommand0; 793109590Sgibbs uint32_t devconfig; 794102676Sgibbs int error; 795102676Sgibbs uint8_t sblkctl; 79665942Sgibbs 797102676Sgibbs our_id = 0; 79879874Sgibbs error = entry->setup(ahc); 79965942Sgibbs if (error != 0) 80065942Sgibbs return (error); 80179874Sgibbs ahc->chip |= AHC_PCI; 80279874Sgibbs ahc->description = entry->name; 80365942Sgibbs 804123579Sgibbs aic_power_state_change(ahc, AIC_POWER_STATE_D0); 80595378Sgibbs 80665942Sgibbs error = ahc_pci_map_registers(ahc); 80765942Sgibbs if (error != 0) 80865942Sgibbs return (error); 80965942Sgibbs 81095378Sgibbs /* 81195378Sgibbs * Before we continue probing the card, ensure that 81295378Sgibbs * its interrupts are *disabled*. We don't want 81395378Sgibbs * a misstep to hang the machine in an interrupt 81495378Sgibbs * storm. 81595378Sgibbs */ 81695378Sgibbs ahc_intr_enable(ahc, FALSE); 81770204Sgibbs 818123579Sgibbs devconfig = aic_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4); 819109590Sgibbs 82079874Sgibbs /* 82179874Sgibbs * If we need to support high memory, enable dual 82279874Sgibbs * address cycles. This bit must be set to enable 82379874Sgibbs * high address bit generation even if we are on a 82479874Sgibbs * 64bit bus (PCI64BIT set in devconfig). 82579874Sgibbs */ 82679874Sgibbs if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { 82779874Sgibbs 82879874Sgibbs if (bootverbose) 82979874Sgibbs printf("%s: Enabling 39Bit Addressing\n", 83079874Sgibbs ahc_name(ahc)); 83179874Sgibbs devconfig |= DACEN; 83279874Sgibbs } 83379874Sgibbs 834109590Sgibbs /* Ensure that pci error generation, a test feature, is disabled. */ 835109590Sgibbs devconfig |= PCIERRGENDIS; 836109590Sgibbs 837123579Sgibbs aic_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4); 838109590Sgibbs 83965942Sgibbs /* Ensure busmastering is enabled */ 840123579Sgibbs command = aic_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2); 84165942Sgibbs command |= PCIM_CMD_BUSMASTEREN; 842109590Sgibbs 843123579Sgibbs aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/2); 84465942Sgibbs 84565942Sgibbs /* On all PCI adapters, we allow SCB paging */ 84679874Sgibbs ahc->flags |= AHC_PAGESCBS; 84765942Sgibbs 84879874Sgibbs error = ahc_softc_init(ahc); 84965942Sgibbs if (error != 0) 85065942Sgibbs return (error); 85165942Sgibbs 852114621Sgibbs /* 853114621Sgibbs * Disable PCI parity error checking. Users typically 854114621Sgibbs * do this to work around broken PCI chipsets that get 855114621Sgibbs * the parity timing wrong and thus generate lots of spurious 856114621Sgibbs * errors. The chip only allows us to disable *all* parity 857114621Sgibbs * error reporting when doing this, so CIO bus, scb ram, and 858114621Sgibbs * scratch ram parity errors will be ignored too. 859114621Sgibbs */ 860115332Sgibbs if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0) 861115332Sgibbs ahc->seqctl |= FAILDIS; 862114621Sgibbs 86374972Sgibbs ahc->bus_intr = ahc_pci_intr; 864114621Sgibbs ahc->bus_chip_init = ahc_pci_chip_init; 865114621Sgibbs ahc->bus_suspend = ahc_pci_suspend; 866114621Sgibbs ahc->bus_resume = ahc_pci_resume; 86774972Sgibbs 868299375Spfg /* Remember how the card was setup in case there is no SEEPROM */ 86970204Sgibbs if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) { 87074094Sgibbs ahc_pause(ahc); 87170204Sgibbs if ((ahc->features & AHC_ULTRA2) != 0) 87270204Sgibbs our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID; 87370204Sgibbs else 87470204Sgibbs our_id = ahc_inb(ahc, SCSIID) & OID; 87570204Sgibbs sxfrctl1 = ahc_inb(ahc, SXFRCTL1) & STPWEN; 87670204Sgibbs scsiseq = ahc_inb(ahc, SCSISEQ); 87770204Sgibbs } else { 87870204Sgibbs sxfrctl1 = STPWEN; 87970204Sgibbs our_id = 7; 88070204Sgibbs scsiseq = 0; 88170204Sgibbs } 88265942Sgibbs 883115917Sgibbs error = ahc_reset(ahc, /*reinit*/FALSE); 88465942Sgibbs if (error != 0) 88565942Sgibbs return (ENXIO); 88665942Sgibbs 88765942Sgibbs if ((ahc->features & AHC_DT) != 0) { 88865942Sgibbs u_int sfunct; 88965942Sgibbs 89065942Sgibbs /* Perform ALT-Mode Setup */ 89165942Sgibbs sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE; 89265942Sgibbs ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE); 89376634Sgibbs ahc_outb(ahc, OPTIONMODE, 89476634Sgibbs OPTIONMODE_DEFAULTS|AUTOACKEN|BUSFREEREV|EXPPHASEDIS); 89565942Sgibbs ahc_outb(ahc, SFUNCT, sfunct); 89665942Sgibbs 89765942Sgibbs /* Normal mode setup */ 89865942Sgibbs ahc_outb(ahc, CRCCONTROL1, CRCVALCHKEN|CRCENDCHKEN|CRCREQCHKEN 89970204Sgibbs |TARGCRCENDEN); 90065942Sgibbs } 90165942Sgibbs 90265942Sgibbs dscommand0 = ahc_inb(ahc, DSCOMMAND0); 90366647Sgibbs dscommand0 |= MPARCKEN|CACHETHEN; 90465942Sgibbs if ((ahc->features & AHC_ULTRA2) != 0) { 90565942Sgibbs 90665942Sgibbs /* 90765942Sgibbs * DPARCKEN doesn't work correctly on 90865942Sgibbs * some MBs so don't use it. 90965942Sgibbs */ 91065942Sgibbs dscommand0 &= ~DPARCKEN; 91165942Sgibbs } 91265942Sgibbs 91365942Sgibbs /* 91465942Sgibbs * Handle chips that must have cache line 91565942Sgibbs * streaming (dis/en)abled. 91665942Sgibbs */ 91765942Sgibbs if ((ahc->bugs & AHC_CACHETHEN_DIS_BUG) != 0) 91865942Sgibbs dscommand0 |= CACHETHEN; 91965942Sgibbs 92065942Sgibbs if ((ahc->bugs & AHC_CACHETHEN_BUG) != 0) 92165942Sgibbs dscommand0 &= ~CACHETHEN; 92265942Sgibbs 92365942Sgibbs ahc_outb(ahc, DSCOMMAND0, dscommand0); 92465942Sgibbs 92565942Sgibbs ahc->pci_cachesize = 926123579Sgibbs aic_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, 92765942Sgibbs /*bytes*/1) & CACHESIZE; 92865942Sgibbs ahc->pci_cachesize *= 4; 92965942Sgibbs 93081170Sgibbs if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0 93181170Sgibbs && ahc->pci_cachesize == 4) { 93281170Sgibbs 933123579Sgibbs aic_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, 93481170Sgibbs 0, /*bytes*/1); 93581170Sgibbs ahc->pci_cachesize = 0; 93681170Sgibbs } 93781170Sgibbs 93876634Sgibbs /* 939299375Spfg * We cannot perform ULTRA speeds without the presence 94076634Sgibbs * of the external precision resistor. 94176634Sgibbs */ 94276634Sgibbs if ((ahc->features & AHC_ULTRA) != 0) { 94376634Sgibbs uint32_t devconfig; 94476634Sgibbs 945123579Sgibbs devconfig = aic_pci_read_config(ahc->dev_softc, 94676634Sgibbs DEVCONFIG, /*bytes*/4); 94776634Sgibbs if ((devconfig & REXTVALID) == 0) 94876634Sgibbs ahc->features &= ~AHC_ULTRA; 94976634Sgibbs } 95076634Sgibbs 95165942Sgibbs /* See if we have a SEEPROM and perform auto-term */ 95265942Sgibbs check_extport(ahc, &sxfrctl1); 95365942Sgibbs 95465942Sgibbs /* 95565942Sgibbs * Take the LED out of diagnostic mode 95665942Sgibbs */ 95765942Sgibbs sblkctl = ahc_inb(ahc, SBLKCTL); 95865942Sgibbs ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON))); 95965942Sgibbs 96065942Sgibbs if ((ahc->features & AHC_ULTRA2) != 0) { 96168087Sgibbs ahc_outb(ahc, DFF_THRSH, RD_DFTHRSH_MAX|WR_DFTHRSH_MAX); 96265942Sgibbs } else { 96365942Sgibbs ahc_outb(ahc, DSPCISTATUS, DFTHRSH_100); 96465942Sgibbs } 96565942Sgibbs 96665942Sgibbs if (ahc->flags & AHC_USEDEFAULTS) { 96765942Sgibbs /* 96865942Sgibbs * PCI Adapter default setup 96965942Sgibbs * Should only be used if the adapter does not have 97065942Sgibbs * a SEEPROM. 97165942Sgibbs */ 97265942Sgibbs /* See if someone else set us up already */ 973109590Sgibbs if ((ahc->flags & AHC_NO_BIOS_INIT) == 0 974109590Sgibbs && scsiseq != 0) { 97565942Sgibbs printf("%s: Using left over BIOS settings\n", 97665942Sgibbs ahc_name(ahc)); 97765942Sgibbs ahc->flags &= ~AHC_USEDEFAULTS; 97872325Sgibbs ahc->flags |= AHC_BIOS_ENABLED; 97965942Sgibbs } else { 98065942Sgibbs /* 98165942Sgibbs * Assume only one connector and always turn 98265942Sgibbs * on termination. 98365942Sgibbs */ 98465942Sgibbs our_id = 0x07; 98565942Sgibbs sxfrctl1 = STPWEN; 98665942Sgibbs } 98765942Sgibbs ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI); 98865942Sgibbs 98965942Sgibbs ahc->our_id = our_id; 99065942Sgibbs } 99165942Sgibbs 99265942Sgibbs /* 99365942Sgibbs * Take a look to see if we have external SRAM. 99465942Sgibbs * We currently do not attempt to use SRAM that is 99565942Sgibbs * shared among multiple controllers. 99665942Sgibbs */ 99765942Sgibbs ahc_probe_ext_scbram(ahc); 99865942Sgibbs 99965942Sgibbs /* 100065942Sgibbs * Record our termination setting for the 100165942Sgibbs * generic initialization routine. 100265942Sgibbs */ 100365942Sgibbs if ((sxfrctl1 & STPWEN) != 0) 100465942Sgibbs ahc->flags |= AHC_TERM_ENB_A; 100565942Sgibbs 1006114621Sgibbs /* 1007114621Sgibbs * Save chip register configuration data for chip resets 1008114621Sgibbs * that occur during runtime and resume events. 1009114621Sgibbs */ 1010114621Sgibbs ahc->bus_softc.pci_softc.devconfig = 1011123579Sgibbs aic_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4); 1012114621Sgibbs ahc->bus_softc.pci_softc.command = 1013123579Sgibbs aic_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1); 1014114621Sgibbs ahc->bus_softc.pci_softc.csize_lattime = 1015123579Sgibbs aic_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1); 1016114621Sgibbs ahc->bus_softc.pci_softc.dscommand0 = ahc_inb(ahc, DSCOMMAND0); 1017114621Sgibbs ahc->bus_softc.pci_softc.dspcistatus = ahc_inb(ahc, DSPCISTATUS); 1018114621Sgibbs if ((ahc->features & AHC_DT) != 0) { 1019114621Sgibbs u_int sfunct; 1020114621Sgibbs 1021114621Sgibbs sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE; 1022114621Sgibbs ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE); 1023114621Sgibbs ahc->bus_softc.pci_softc.optionmode = ahc_inb(ahc, OPTIONMODE); 1024114621Sgibbs ahc->bus_softc.pci_softc.targcrccnt = ahc_inw(ahc, TARGCRCCNT); 1025114621Sgibbs ahc_outb(ahc, SFUNCT, sfunct); 1026114621Sgibbs ahc->bus_softc.pci_softc.crccontrol1 = 1027114621Sgibbs ahc_inb(ahc, CRCCONTROL1); 1028114621Sgibbs } 1029114621Sgibbs if ((ahc->features & AHC_MULTI_FUNC) != 0) 1030114621Sgibbs ahc->bus_softc.pci_softc.scbbaddr = ahc_inb(ahc, SCBBADDR); 1031114621Sgibbs 1032114621Sgibbs if ((ahc->features & AHC_ULTRA2) != 0) 1033114621Sgibbs ahc->bus_softc.pci_softc.dff_thrsh = ahc_inb(ahc, DFF_THRSH); 1034114621Sgibbs 103565942Sgibbs /* Core initialization */ 103665942Sgibbs error = ahc_init(ahc); 103765942Sgibbs if (error != 0) 103865942Sgibbs return (error); 103965942Sgibbs 104065942Sgibbs /* 104174972Sgibbs * Allow interrupts now that we are completely setup. 104274972Sgibbs */ 104376634Sgibbs error = ahc_pci_map_int(ahc); 104476634Sgibbs if (error != 0) 104576634Sgibbs return (error); 104676634Sgibbs 1047168807Sscottl ahc_lock(ahc); 1048102676Sgibbs /* 1049102676Sgibbs * Link this softc in with all other ahc instances. 1050102676Sgibbs */ 1051102676Sgibbs ahc_softc_insert(ahc); 1052168807Sscottl ahc_unlock(ahc); 105365942Sgibbs return (0); 105465942Sgibbs} 105565942Sgibbs 105665942Sgibbs/* 1057299375Spfg * Test for the presence of external sram in an 105865942Sgibbs * "unshared" configuration. 105965942Sgibbs */ 106065942Sgibbsstatic int 106165942Sgibbsahc_ext_scbram_present(struct ahc_softc *ahc) 106265942Sgibbs{ 106368087Sgibbs u_int chip; 106465942Sgibbs int ramps; 106565942Sgibbs int single_user; 106665942Sgibbs uint32_t devconfig; 106765942Sgibbs 106868087Sgibbs chip = ahc->chip & AHC_CHIPID_MASK; 1069123579Sgibbs devconfig = aic_pci_read_config(ahc->dev_softc, 107065942Sgibbs DEVCONFIG, /*bytes*/4); 107165942Sgibbs single_user = (devconfig & MPORTMODE) != 0; 107265942Sgibbs 107365942Sgibbs if ((ahc->features & AHC_ULTRA2) != 0) 107465942Sgibbs ramps = (ahc_inb(ahc, DSCOMMAND0) & RAMPS) != 0; 107595378Sgibbs else if (chip == AHC_AIC7895 || chip == AHC_AIC7895C) 107695378Sgibbs /* 107795378Sgibbs * External SCBRAM arbitration is flakey 107895378Sgibbs * on these chips. Unfortunately this means 107995378Sgibbs * we don't use the extra SCB ram space on the 108095378Sgibbs * 3940AUW. 108195378Sgibbs */ 108295378Sgibbs ramps = 0; 108368087Sgibbs else if (chip >= AHC_AIC7870) 108465942Sgibbs ramps = (devconfig & RAMPSM) != 0; 108565942Sgibbs else 108665942Sgibbs ramps = 0; 108765942Sgibbs 108865942Sgibbs if (ramps && single_user) 108965942Sgibbs return (1); 109065942Sgibbs return (0); 109165942Sgibbs} 109265942Sgibbs 109365942Sgibbs/* 109465942Sgibbs * Enable external scbram. 109565942Sgibbs */ 109665942Sgibbsstatic void 109765942Sgibbsahc_scbram_config(struct ahc_softc *ahc, int enable, int pcheck, 109865942Sgibbs int fast, int large) 109965942Sgibbs{ 110065942Sgibbs uint32_t devconfig; 110165942Sgibbs 110265942Sgibbs if (ahc->features & AHC_MULTI_FUNC) { 110365942Sgibbs /* 110465942Sgibbs * Set the SCB Base addr (highest address bit) 110565942Sgibbs * depending on which channel we are. 110665942Sgibbs */ 1107123579Sgibbs ahc_outb(ahc, SCBBADDR, aic_get_pci_function(ahc->dev_softc)); 110865942Sgibbs } 110965942Sgibbs 1110102676Sgibbs ahc->flags &= ~AHC_LSCBS_ENABLED; 1111102676Sgibbs if (large) 1112102676Sgibbs ahc->flags |= AHC_LSCBS_ENABLED; 1113123579Sgibbs devconfig = aic_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4); 111465942Sgibbs if ((ahc->features & AHC_ULTRA2) != 0) { 111565942Sgibbs u_int dscommand0; 111665942Sgibbs 111765942Sgibbs dscommand0 = ahc_inb(ahc, DSCOMMAND0); 111865942Sgibbs if (enable) 111965942Sgibbs dscommand0 &= ~INTSCBRAMSEL; 112065942Sgibbs else 112165942Sgibbs dscommand0 |= INTSCBRAMSEL; 112265942Sgibbs if (large) 112365942Sgibbs dscommand0 &= ~USCBSIZE32; 112465942Sgibbs else 112565942Sgibbs dscommand0 |= USCBSIZE32; 112665942Sgibbs ahc_outb(ahc, DSCOMMAND0, dscommand0); 112765942Sgibbs } else { 112865942Sgibbs if (fast) 112965942Sgibbs devconfig &= ~EXTSCBTIME; 113065942Sgibbs else 113165942Sgibbs devconfig |= EXTSCBTIME; 113265942Sgibbs if (enable) 113365942Sgibbs devconfig &= ~SCBRAMSEL; 113465942Sgibbs else 113565942Sgibbs devconfig |= SCBRAMSEL; 113665942Sgibbs if (large) 113765942Sgibbs devconfig &= ~SCBSIZE32; 113865942Sgibbs else 113965942Sgibbs devconfig |= SCBSIZE32; 114065942Sgibbs } 114165942Sgibbs if (pcheck) 114265942Sgibbs devconfig |= EXTSCBPEN; 114365942Sgibbs else 114465942Sgibbs devconfig &= ~EXTSCBPEN; 114565942Sgibbs 1146123579Sgibbs aic_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4); 114765942Sgibbs} 114865942Sgibbs 114965942Sgibbs/* 115065942Sgibbs * Take a look to see if we have external SRAM. 115165942Sgibbs * We currently do not attempt to use SRAM that is 115265942Sgibbs * shared among multiple controllers. 115365942Sgibbs */ 115465942Sgibbsstatic void 115565942Sgibbsahc_probe_ext_scbram(struct ahc_softc *ahc) 115665942Sgibbs{ 115765942Sgibbs int num_scbs; 115865942Sgibbs int test_num_scbs; 115965942Sgibbs int enable; 116065942Sgibbs int pcheck; 116165942Sgibbs int fast; 116265942Sgibbs int large; 116365942Sgibbs 116465942Sgibbs enable = FALSE; 116565942Sgibbs pcheck = FALSE; 116665942Sgibbs fast = FALSE; 116765942Sgibbs large = FALSE; 116865942Sgibbs num_scbs = 0; 116965942Sgibbs 117065942Sgibbs if (ahc_ext_scbram_present(ahc) == 0) 117165942Sgibbs goto done; 117265942Sgibbs 117365942Sgibbs /* 117465942Sgibbs * Probe for the best parameters to use. 117565942Sgibbs */ 117665942Sgibbs ahc_scbram_config(ahc, /*enable*/TRUE, pcheck, fast, large); 117765942Sgibbs num_scbs = ahc_probe_scbs(ahc); 117865942Sgibbs if (num_scbs == 0) { 117965942Sgibbs /* The SRAM wasn't really present. */ 118065942Sgibbs goto done; 118165942Sgibbs } 118265942Sgibbs enable = TRUE; 118365942Sgibbs 118465942Sgibbs /* 118565942Sgibbs * Clear any outstanding parity error 118665942Sgibbs * and ensure that parity error reporting 118765942Sgibbs * is enabled. 118865942Sgibbs */ 118965942Sgibbs ahc_outb(ahc, SEQCTL, 0); 119065942Sgibbs ahc_outb(ahc, CLRINT, CLRPARERR); 119165942Sgibbs ahc_outb(ahc, CLRINT, CLRBRKADRINT); 119265942Sgibbs 119365942Sgibbs /* Now see if we can do parity */ 119465942Sgibbs ahc_scbram_config(ahc, enable, /*pcheck*/TRUE, fast, large); 119565942Sgibbs num_scbs = ahc_probe_scbs(ahc); 119665942Sgibbs if ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0 119765942Sgibbs || (ahc_inb(ahc, ERROR) & MPARERR) == 0) 119865942Sgibbs pcheck = TRUE; 119965942Sgibbs 120065942Sgibbs /* Clear any resulting parity error */ 120165942Sgibbs ahc_outb(ahc, CLRINT, CLRPARERR); 120265942Sgibbs ahc_outb(ahc, CLRINT, CLRBRKADRINT); 120365942Sgibbs 120465942Sgibbs /* Now see if we can do fast timing */ 120565942Sgibbs ahc_scbram_config(ahc, enable, pcheck, /*fast*/TRUE, large); 120665942Sgibbs test_num_scbs = ahc_probe_scbs(ahc); 120765942Sgibbs if (test_num_scbs == num_scbs 120865942Sgibbs && ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0 120965942Sgibbs || (ahc_inb(ahc, ERROR) & MPARERR) == 0)) 121065942Sgibbs fast = TRUE; 121165942Sgibbs 121265942Sgibbs /* 121365942Sgibbs * See if we can use large SCBs and still maintain 121465942Sgibbs * the same overall count of SCBs. 121565942Sgibbs */ 121665942Sgibbs if ((ahc->features & AHC_LARGE_SCBS) != 0) { 121765942Sgibbs ahc_scbram_config(ahc, enable, pcheck, fast, /*large*/TRUE); 121865942Sgibbs test_num_scbs = ahc_probe_scbs(ahc); 121965942Sgibbs if (test_num_scbs >= num_scbs) { 122065942Sgibbs large = TRUE; 122165942Sgibbs num_scbs = test_num_scbs; 122265942Sgibbs if (num_scbs >= 64) { 122365942Sgibbs /* 122465942Sgibbs * We have enough space to move the 122565942Sgibbs * "busy targets table" into SCB space 122665942Sgibbs * and make it qualify all the way to the 122765942Sgibbs * lun level. 122865942Sgibbs */ 122965942Sgibbs ahc->flags |= AHC_SCB_BTT; 123065942Sgibbs } 123165942Sgibbs } 123265942Sgibbs } 123365942Sgibbsdone: 123465942Sgibbs /* 123565942Sgibbs * Disable parity error reporting until we 123665942Sgibbs * can load instruction ram. 123765942Sgibbs */ 123865942Sgibbs ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS); 123965942Sgibbs /* Clear any latched parity error */ 124065942Sgibbs ahc_outb(ahc, CLRINT, CLRPARERR); 124165942Sgibbs ahc_outb(ahc, CLRINT, CLRBRKADRINT); 124265942Sgibbs if (bootverbose && enable) { 124365942Sgibbs printf("%s: External SRAM, %s access%s, %dbytes/SCB\n", 124465942Sgibbs ahc_name(ahc), fast ? "fast" : "slow", 124565942Sgibbs pcheck ? ", parity checking enabled" : "", 124665942Sgibbs large ? 64 : 32); 124765942Sgibbs } 124865942Sgibbs ahc_scbram_config(ahc, enable, pcheck, fast, large); 124965942Sgibbs} 125065942Sgibbs 125165942Sgibbs/* 1252107419Sscottl * Perform some simple tests that should catch situations where 1253107419Sscottl * our registers are invalidly mapped. 1254107419Sscottl */ 1255107419Sscottlint 1256107419Sscottlahc_pci_test_register_access(struct ahc_softc *ahc) 1257107419Sscottl{ 1258109590Sgibbs int error; 1259109590Sgibbs u_int status1; 1260109590Sgibbs uint32_t cmd; 1261109590Sgibbs uint8_t hcntrl; 1262107419Sscottl 1263107623Sscottl error = EIO; 1264107623Sscottl 1265109590Sgibbs /* 1266109590Sgibbs * Enable PCI error interrupt status, but suppress NMIs 1267109590Sgibbs * generated by SERR raised due to target aborts. 1268109590Sgibbs */ 1269123579Sgibbs cmd = aic_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2); 1270123579Sgibbs aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND, 1271109590Sgibbs cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2); 1272107623Sscottl 1273107419Sscottl /* 1274107419Sscottl * First a simple test to see if any 1275107419Sscottl * registers can be read. Reading 1276107419Sscottl * HCNTRL has no side effects and has 1277107419Sscottl * at least one bit that is guaranteed to 1278107419Sscottl * be zero so it is a good register to 1279107419Sscottl * use for this test. 1280107419Sscottl */ 1281109590Sgibbs hcntrl = ahc_inb(ahc, HCNTRL); 1282123579Sgibbs 1283109590Sgibbs if (hcntrl == 0xFF) 1284107623Sscottl goto fail; 1285107419Sscottl 1286123579Sgibbs if ((hcntrl & CHIPRST) != 0) { 1287123579Sgibbs /* 1288123579Sgibbs * The chip has not been initialized since 1289123579Sgibbs * PCI/EISA/VLB bus reset. Don't trust 1290123579Sgibbs * "left over BIOS data". 1291123579Sgibbs */ 1292123579Sgibbs ahc->flags |= AHC_NO_BIOS_INIT; 1293123579Sgibbs } 1294123579Sgibbs 1295107419Sscottl /* 1296107419Sscottl * Next create a situation where write combining 1297107419Sscottl * or read prefetching could be initiated by the 1298107419Sscottl * CPU or host bridge. Our device does not support 1299107419Sscottl * either, so look for data corruption and/or flagged 1300120445Sscottl * PCI errors. First pause without causing another 1301120445Sscottl * chip reset. 1302107419Sscottl */ 1303120445Sscottl hcntrl &= ~CHIPRST; 1304109590Sgibbs ahc_outb(ahc, HCNTRL, hcntrl|PAUSE); 1305109590Sgibbs while (ahc_is_paused(ahc) == 0) 1306109590Sgibbs ; 1307115919Sgibbs 1308115919Sgibbs /* Clear any PCI errors that occurred before our driver attached. */ 1309123579Sgibbs status1 = aic_pci_read_config(ahc->dev_softc, 1310115919Sgibbs PCIR_STATUS + 1, /*bytes*/1); 1311123579Sgibbs aic_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, 1312115919Sgibbs status1, /*bytes*/1); 1313115919Sgibbs ahc_outb(ahc, CLRINT, CLRPARERR); 1314115919Sgibbs 1315109590Sgibbs ahc_outb(ahc, SEQCTL, PERRORDIS); 1316109590Sgibbs ahc_outb(ahc, SCBPTR, 0); 1317109590Sgibbs ahc_outl(ahc, SCB_BASE, 0x5aa555aa); 1318109590Sgibbs if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa) 1319107623Sscottl goto fail; 1320107419Sscottl 1321123579Sgibbs status1 = aic_pci_read_config(ahc->dev_softc, 1322107419Sscottl PCIR_STATUS + 1, /*bytes*/1); 1323107623Sscottl if ((status1 & STA) != 0) 1324107623Sscottl goto fail; 1325107419Sscottl 1326107623Sscottl error = 0; 1327107419Sscottl 1328107623Sscottlfail: 1329107623Sscottl /* Silently clear any latched errors. */ 1330123579Sgibbs status1 = aic_pci_read_config(ahc->dev_softc, 1331107623Sscottl PCIR_STATUS + 1, /*bytes*/1); 1332123579Sgibbs aic_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, 1333107623Sscottl status1, /*bytes*/1); 1334107623Sscottl ahc_outb(ahc, CLRINT, CLRPARERR); 1335109590Sgibbs ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS); 1336123579Sgibbs aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2); 1337107623Sscottl return (error); 1338107419Sscottl} 1339107419Sscottl 1340107419Sscottl/* 134165942Sgibbs * Check the external port logic for a serial eeprom 134265942Sgibbs * and termination/cable detection contrls. 134365942Sgibbs */ 134465942Sgibbsstatic void 134565942Sgibbscheck_extport(struct ahc_softc *ahc, u_int *sxfrctl1) 134665942Sgibbs{ 134765942Sgibbs struct seeprom_descriptor sd; 1348102676Sgibbs struct seeprom_config *sc; 134965942Sgibbs int have_seeprom; 135065942Sgibbs int have_autoterm; 135165942Sgibbs 135265942Sgibbs sd.sd_ahc = ahc; 135365942Sgibbs sd.sd_control_offset = SEECTL; 135465942Sgibbs sd.sd_status_offset = SEECTL; 135565942Sgibbs sd.sd_dataout_offset = SEECTL; 1356102676Sgibbs sc = ahc->seep_config; 135765942Sgibbs 135865942Sgibbs /* 135965942Sgibbs * For some multi-channel devices, the c46 is simply too 136065942Sgibbs * small to work. For the other controller types, we can 136165942Sgibbs * get our information from either SEEPROM type. Set the 136265942Sgibbs * type to start our probe with accordingly. 136365942Sgibbs */ 136465942Sgibbs if (ahc->flags & AHC_LARGE_SEEPROM) 136565942Sgibbs sd.sd_chip = C56_66; 136665942Sgibbs else 136765942Sgibbs sd.sd_chip = C46; 136865942Sgibbs 136965942Sgibbs sd.sd_MS = SEEMS; 137065942Sgibbs sd.sd_RDY = SEERDY; 137165942Sgibbs sd.sd_CS = SEECS; 137265942Sgibbs sd.sd_CK = SEECK; 137365942Sgibbs sd.sd_DO = SEEDO; 137465942Sgibbs sd.sd_DI = SEEDI; 137565942Sgibbs 137695378Sgibbs have_seeprom = ahc_acquire_seeprom(ahc, &sd); 137765942Sgibbs if (have_seeprom) { 137865942Sgibbs 137965942Sgibbs if (bootverbose) 138065942Sgibbs printf("%s: Reading SEEPROM...", ahc_name(ahc)); 138165942Sgibbs 138265942Sgibbs for (;;) { 138365942Sgibbs u_int start_addr; 138465942Sgibbs 138565942Sgibbs start_addr = 32 * (ahc->channel - 'A'); 138665942Sgibbs 1387102676Sgibbs have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc, 138895378Sgibbs start_addr, 1389102676Sgibbs sizeof(*sc)/2); 139065942Sgibbs 139165942Sgibbs if (have_seeprom) 1392102676Sgibbs have_seeprom = ahc_verify_cksum(sc); 139365942Sgibbs 139465942Sgibbs if (have_seeprom != 0 || sd.sd_chip == C56_66) { 139565942Sgibbs if (bootverbose) { 139665942Sgibbs if (have_seeprom == 0) 139765942Sgibbs printf ("checksum error\n"); 139865942Sgibbs else 139965942Sgibbs printf ("done.\n"); 140065942Sgibbs } 140165942Sgibbs break; 140265942Sgibbs } 140365942Sgibbs sd.sd_chip = C56_66; 140465942Sgibbs } 140595378Sgibbs ahc_release_seeprom(&sd); 1406123579Sgibbs 1407123579Sgibbs /* Remember the SEEPROM type for later */ 1408123579Sgibbs if (sd.sd_chip == C56_66) 1409123579Sgibbs ahc->flags |= AHC_LARGE_SEEPROM; 141065942Sgibbs } 141165942Sgibbs 141265942Sgibbs if (!have_seeprom) { 141365942Sgibbs /* 141465942Sgibbs * Pull scratch ram settings and treat them as 141565942Sgibbs * if they are the contents of an seeprom if 141665942Sgibbs * the 'ADPT' signature is found in SCB2. 141774094Sgibbs * We manually compose the data as 16bit values 141874094Sgibbs * to avoid endian issues. 141965942Sgibbs */ 142065942Sgibbs ahc_outb(ahc, SCBPTR, 2); 142165942Sgibbs if (ahc_inb(ahc, SCB_BASE) == 'A' 142265942Sgibbs && ahc_inb(ahc, SCB_BASE + 1) == 'D' 142365942Sgibbs && ahc_inb(ahc, SCB_BASE + 2) == 'P' 142465942Sgibbs && ahc_inb(ahc, SCB_BASE + 3) == 'T') { 142574094Sgibbs uint16_t *sc_data; 142665942Sgibbs int i; 142765942Sgibbs 1428102676Sgibbs sc_data = (uint16_t *)sc; 1429102676Sgibbs for (i = 0; i < 32; i++, sc_data++) { 1430102676Sgibbs int j; 143174094Sgibbs 143274094Sgibbs j = i * 2; 1433102676Sgibbs *sc_data = ahc_inb(ahc, SRAM_BASE + j) 1434102676Sgibbs | ahc_inb(ahc, SRAM_BASE + j + 1) << 8; 143574094Sgibbs } 1436102676Sgibbs have_seeprom = ahc_verify_cksum(sc); 1437102676Sgibbs if (have_seeprom) 1438102676Sgibbs ahc->flags |= AHC_SCB_CONFIG_USED; 143965942Sgibbs } 144095378Sgibbs /* 144195378Sgibbs * Clear any SCB parity errors in case this data and 144295378Sgibbs * its associated parity was not initialized by the BIOS 144395378Sgibbs */ 144495378Sgibbs ahc_outb(ahc, CLRINT, CLRPARERR); 144595378Sgibbs ahc_outb(ahc, CLRINT, CLRBRKADRINT); 144665942Sgibbs } 144765942Sgibbs 144865942Sgibbs if (!have_seeprom) { 144965942Sgibbs if (bootverbose) 145065942Sgibbs printf("%s: No SEEPROM available.\n", ahc_name(ahc)); 145165942Sgibbs ahc->flags |= AHC_USEDEFAULTS; 1452102676Sgibbs free(ahc->seep_config, M_DEVBUF); 1453102676Sgibbs ahc->seep_config = NULL; 1454102676Sgibbs sc = NULL; 145565942Sgibbs } else { 1456102676Sgibbs ahc_parse_pci_eeprom(ahc, sc); 145765942Sgibbs } 145865942Sgibbs 145965942Sgibbs /* 146065942Sgibbs * Cards that have the external logic necessary to talk to 146165942Sgibbs * a SEEPROM, are almost certain to have the remaining logic 146265942Sgibbs * necessary for auto-termination control. This assumption 146365942Sgibbs * hasn't failed yet... 146465942Sgibbs */ 146565942Sgibbs have_autoterm = have_seeprom; 146665942Sgibbs 146765942Sgibbs /* 146865942Sgibbs * Some low-cost chips have SEEPROM and auto-term control built 146965942Sgibbs * in, instead of using a GAL. They can tell us directly 147065942Sgibbs * if the termination logic is enabled. 147165942Sgibbs */ 147265942Sgibbs if ((ahc->features & AHC_SPIOCAP) != 0) { 1473102676Sgibbs if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) == 0) 147465942Sgibbs have_autoterm = FALSE; 147565942Sgibbs } 147665942Sgibbs 147774094Sgibbs if (have_autoterm) { 1478114621Sgibbs ahc->flags |= AHC_HAS_TERM_LOGIC; 147995378Sgibbs ahc_acquire_seeprom(ahc, &sd); 1480102676Sgibbs configure_termination(ahc, &sd, sc->adapter_control, sxfrctl1); 148195378Sgibbs ahc_release_seeprom(&sd); 1482102676Sgibbs } else if (have_seeprom) { 1483102676Sgibbs *sxfrctl1 &= ~STPWEN; 1484102676Sgibbs if ((sc->adapter_control & CFSTERM) != 0) 1485102676Sgibbs *sxfrctl1 |= STPWEN; 1486102676Sgibbs if (bootverbose) 1487102676Sgibbs printf("%s: Low byte termination %sabled\n", 1488102676Sgibbs ahc_name(ahc), 1489102676Sgibbs (*sxfrctl1 & STPWEN) ? "en" : "dis"); 149074094Sgibbs } 149165942Sgibbs} 149265942Sgibbs 149365942Sgibbsstatic void 1494102676Sgibbsahc_parse_pci_eeprom(struct ahc_softc *ahc, struct seeprom_config *sc) 1495102676Sgibbs{ 1496102676Sgibbs /* 1497102676Sgibbs * Put the data we've collected down into SRAM 1498102676Sgibbs * where ahc_init will find it. 1499102676Sgibbs */ 1500102676Sgibbs int i; 1501102676Sgibbs int max_targ = sc->max_targets & CFMAXTARG; 1502102676Sgibbs u_int scsi_conf; 1503102676Sgibbs uint16_t discenable; 1504102676Sgibbs uint16_t ultraenb; 1505102676Sgibbs 1506102676Sgibbs discenable = 0; 1507102676Sgibbs ultraenb = 0; 1508102676Sgibbs if ((sc->adapter_control & CFULTRAEN) != 0) { 1509102676Sgibbs /* 1510102676Sgibbs * Determine if this adapter has a "newstyle" 1511102676Sgibbs * SEEPROM format. 1512102676Sgibbs */ 1513102676Sgibbs for (i = 0; i < max_targ; i++) { 1514102676Sgibbs if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0) { 1515102676Sgibbs ahc->flags |= AHC_NEWEEPROM_FMT; 1516102676Sgibbs break; 1517102676Sgibbs } 1518102676Sgibbs } 1519102676Sgibbs } 1520102676Sgibbs 1521102676Sgibbs for (i = 0; i < max_targ; i++) { 1522102676Sgibbs u_int scsirate; 1523102676Sgibbs uint16_t target_mask; 1524102676Sgibbs 1525102676Sgibbs target_mask = 0x01 << i; 1526102676Sgibbs if (sc->device_flags[i] & CFDISC) 1527102676Sgibbs discenable |= target_mask; 1528102676Sgibbs if ((ahc->flags & AHC_NEWEEPROM_FMT) != 0) { 1529102676Sgibbs if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0) 1530102676Sgibbs ultraenb |= target_mask; 1531102676Sgibbs } else if ((sc->adapter_control & CFULTRAEN) != 0) { 1532102676Sgibbs ultraenb |= target_mask; 1533102676Sgibbs } 1534102676Sgibbs if ((sc->device_flags[i] & CFXFER) == 0x04 1535102676Sgibbs && (ultraenb & target_mask) != 0) { 1536102676Sgibbs /* Treat 10MHz as a non-ultra speed */ 1537102676Sgibbs sc->device_flags[i] &= ~CFXFER; 1538102676Sgibbs ultraenb &= ~target_mask; 1539102676Sgibbs } 1540102676Sgibbs if ((ahc->features & AHC_ULTRA2) != 0) { 1541102676Sgibbs u_int offset; 1542102676Sgibbs 1543102676Sgibbs if (sc->device_flags[i] & CFSYNCH) 1544102676Sgibbs offset = MAX_OFFSET_ULTRA2; 1545102676Sgibbs else 1546102676Sgibbs offset = 0; 1547102676Sgibbs ahc_outb(ahc, TARG_OFFSET + i, offset); 1548102676Sgibbs 1549102676Sgibbs /* 1550102676Sgibbs * The ultra enable bits contain the 1551102676Sgibbs * high bit of the ultra2 sync rate 1552102676Sgibbs * field. 1553102676Sgibbs */ 1554102676Sgibbs scsirate = (sc->device_flags[i] & CFXFER) 1555102676Sgibbs | ((ultraenb & target_mask) ? 0x8 : 0x0); 1556102676Sgibbs if (sc->device_flags[i] & CFWIDEB) 1557102676Sgibbs scsirate |= WIDEXFER; 1558102676Sgibbs } else { 1559102676Sgibbs scsirate = (sc->device_flags[i] & CFXFER) << 4; 1560102676Sgibbs if (sc->device_flags[i] & CFSYNCH) 1561102676Sgibbs scsirate |= SOFS; 1562102676Sgibbs if (sc->device_flags[i] & CFWIDEB) 1563102676Sgibbs scsirate |= WIDEXFER; 1564102676Sgibbs } 1565102676Sgibbs ahc_outb(ahc, TARG_SCSIRATE + i, scsirate); 1566102676Sgibbs } 1567102676Sgibbs ahc->our_id = sc->brtime_id & CFSCSIID; 1568102676Sgibbs 1569102676Sgibbs scsi_conf = (ahc->our_id & 0x7); 1570102676Sgibbs if (sc->adapter_control & CFSPARITY) 1571102676Sgibbs scsi_conf |= ENSPCHK; 1572102676Sgibbs if (sc->adapter_control & CFRESETB) 1573102676Sgibbs scsi_conf |= RESET_SCSI; 1574102676Sgibbs 1575102676Sgibbs ahc->flags |= (sc->adapter_control & CFBOOTCHAN) >> CFBOOTCHANSHIFT; 1576102676Sgibbs 1577102676Sgibbs if (sc->bios_control & CFEXTEND) 1578102676Sgibbs ahc->flags |= AHC_EXTENDED_TRANS_A; 1579102676Sgibbs 1580102676Sgibbs if (sc->bios_control & CFBIOSEN) 1581102676Sgibbs ahc->flags |= AHC_BIOS_ENABLED; 1582102676Sgibbs if (ahc->features & AHC_ULTRA 1583102676Sgibbs && (ahc->flags & AHC_NEWEEPROM_FMT) == 0) { 1584102676Sgibbs /* Should we enable Ultra mode? */ 1585102676Sgibbs if (!(sc->adapter_control & CFULTRAEN)) 1586102676Sgibbs /* Treat us as a non-ultra card */ 1587102676Sgibbs ultraenb = 0; 1588102676Sgibbs } 1589102676Sgibbs 1590102676Sgibbs if (sc->signature == CFSIGNATURE 1591102676Sgibbs || sc->signature == CFSIGNATURE2) { 1592102676Sgibbs uint32_t devconfig; 1593102676Sgibbs 1594102676Sgibbs /* Honor the STPWLEVEL settings */ 1595123579Sgibbs devconfig = aic_pci_read_config(ahc->dev_softc, 1596102676Sgibbs DEVCONFIG, /*bytes*/4); 1597102676Sgibbs devconfig &= ~STPWLEVEL; 1598102676Sgibbs if ((sc->bios_control & CFSTPWLEVEL) != 0) 1599102676Sgibbs devconfig |= STPWLEVEL; 1600123579Sgibbs aic_pci_write_config(ahc->dev_softc, DEVCONFIG, 1601102676Sgibbs devconfig, /*bytes*/4); 1602102676Sgibbs } 1603102676Sgibbs /* Set SCSICONF info */ 1604102676Sgibbs ahc_outb(ahc, SCSICONF, scsi_conf); 1605102676Sgibbs ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff)); 1606102676Sgibbs ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff)); 1607102676Sgibbs ahc_outb(ahc, ULTRA_ENB, ultraenb & 0xff); 1608102676Sgibbs ahc_outb(ahc, ULTRA_ENB + 1, (ultraenb >> 8) & 0xff); 1609102676Sgibbs} 1610102676Sgibbs 1611102676Sgibbsstatic void 161265942Sgibbsconfigure_termination(struct ahc_softc *ahc, 161365942Sgibbs struct seeprom_descriptor *sd, 161465942Sgibbs u_int adapter_control, 161565942Sgibbs u_int *sxfrctl1) 161665942Sgibbs{ 161765942Sgibbs uint8_t brddat; 161865942Sgibbs 161965942Sgibbs brddat = 0; 162065942Sgibbs 162165942Sgibbs /* 162265942Sgibbs * Update the settings in sxfrctl1 to match the 162365942Sgibbs * termination settings 162465942Sgibbs */ 162565942Sgibbs *sxfrctl1 = 0; 162665942Sgibbs 162765942Sgibbs /* 162865942Sgibbs * SEECS must be on for the GALS to latch 162965942Sgibbs * the data properly. Be sure to leave MS 163065942Sgibbs * on or we will release the seeprom. 163165942Sgibbs */ 163265942Sgibbs SEEPROM_OUTB(sd, sd->sd_MS | sd->sd_CS); 163365942Sgibbs if ((adapter_control & CFAUTOTERM) != 0 163465942Sgibbs || (ahc->features & AHC_NEW_TERMCTL) != 0) { 163565942Sgibbs int internal50_present; 163665942Sgibbs int internal68_present; 163765942Sgibbs int externalcable_present; 163865942Sgibbs int eeprom_present; 163965942Sgibbs int enableSEC_low; 164065942Sgibbs int enableSEC_high; 164165942Sgibbs int enablePRI_low; 164265942Sgibbs int enablePRI_high; 164371390Sgibbs int sum; 164465942Sgibbs 164565942Sgibbs enableSEC_low = 0; 164665942Sgibbs enableSEC_high = 0; 164765942Sgibbs enablePRI_low = 0; 164865942Sgibbs enablePRI_high = 0; 164965942Sgibbs if ((ahc->features & AHC_NEW_TERMCTL) != 0) { 165065942Sgibbs ahc_new_term_detect(ahc, &enableSEC_low, 1651102676Sgibbs &enableSEC_high, 1652102676Sgibbs &enablePRI_low, 1653102676Sgibbs &enablePRI_high, 1654102676Sgibbs &eeprom_present); 165565942Sgibbs if ((adapter_control & CFSEAUTOTERM) == 0) { 165665942Sgibbs if (bootverbose) 165765942Sgibbs printf("%s: Manual SE Termination\n", 165865942Sgibbs ahc_name(ahc)); 165965942Sgibbs enableSEC_low = (adapter_control & CFSELOWTERM); 166065942Sgibbs enableSEC_high = 166165942Sgibbs (adapter_control & CFSEHIGHTERM); 166265942Sgibbs } 166365942Sgibbs if ((adapter_control & CFAUTOTERM) == 0) { 166465942Sgibbs if (bootverbose) 166565942Sgibbs printf("%s: Manual LVD Termination\n", 166665942Sgibbs ahc_name(ahc)); 166765942Sgibbs enablePRI_low = (adapter_control & CFSTERM); 166865942Sgibbs enablePRI_high = (adapter_control & CFWSTERM); 166965942Sgibbs } 167065942Sgibbs /* Make the table calculations below happy */ 167165942Sgibbs internal50_present = 0; 167265942Sgibbs internal68_present = 1; 167365942Sgibbs externalcable_present = 1; 167465942Sgibbs } else if ((ahc->features & AHC_SPIOCAP) != 0) { 167565942Sgibbs aic785X_cable_detect(ahc, &internal50_present, 167665942Sgibbs &externalcable_present, 167765942Sgibbs &eeprom_present); 1678102676Sgibbs /* Can never support a wide connector. */ 1679102676Sgibbs internal68_present = 0; 168065942Sgibbs } else { 168165942Sgibbs aic787X_cable_detect(ahc, &internal50_present, 168265942Sgibbs &internal68_present, 168365942Sgibbs &externalcable_present, 168465942Sgibbs &eeprom_present); 168565942Sgibbs } 168665942Sgibbs 168765942Sgibbs if ((ahc->features & AHC_WIDE) == 0) 168865942Sgibbs internal68_present = 0; 168965942Sgibbs 169071390Sgibbs if (bootverbose 169171390Sgibbs && (ahc->features & AHC_ULTRA2) == 0) { 169271390Sgibbs printf("%s: internal 50 cable %s present", 169371390Sgibbs ahc_name(ahc), 169471390Sgibbs internal50_present ? "is":"not"); 169571390Sgibbs 169671390Sgibbs if ((ahc->features & AHC_WIDE) != 0) 169771390Sgibbs printf(", internal 68 cable %s present", 169865942Sgibbs internal68_present ? "is":"not"); 169971390Sgibbs printf("\n%s: external cable %s present\n", 170071390Sgibbs ahc_name(ahc), 170171390Sgibbs externalcable_present ? "is":"not"); 170271390Sgibbs } 170371390Sgibbs if (bootverbose) 170465942Sgibbs printf("%s: BIOS eeprom %s present\n", 170565942Sgibbs ahc_name(ahc), eeprom_present ? "is" : "not"); 170665942Sgibbs 170765942Sgibbs if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) { 170865942Sgibbs /* 170965942Sgibbs * The 50 pin connector is a separate bus, 171065942Sgibbs * so force it to always be terminated. 171165942Sgibbs * In the future, perform current sensing 171265942Sgibbs * to determine if we are in the middle of 171365942Sgibbs * a properly terminated bus. 171465942Sgibbs */ 171565942Sgibbs internal50_present = 0; 171665942Sgibbs } 171765942Sgibbs 171865942Sgibbs /* 171965942Sgibbs * Now set the termination based on what 172065942Sgibbs * we found. 172165942Sgibbs * Flash Enable = BRDDAT7 172265942Sgibbs * Secondary High Term Enable = BRDDAT6 172365942Sgibbs * Secondary Low Term Enable = BRDDAT5 (7890) 172465942Sgibbs * Primary High Term Enable = BRDDAT4 (7890) 172565942Sgibbs */ 172665942Sgibbs if ((ahc->features & AHC_ULTRA2) == 0 172771390Sgibbs && (internal50_present != 0) 172871390Sgibbs && (internal68_present != 0) 172971390Sgibbs && (externalcable_present != 0)) { 173065942Sgibbs printf("%s: Illegal cable configuration!!. " 173165942Sgibbs "Only two connectors on the " 173265942Sgibbs "adapter may be used at a " 173365942Sgibbs "time!\n", ahc_name(ahc)); 173495378Sgibbs 173595378Sgibbs /* 173695378Sgibbs * Pretend there are no cables in the hope 173795378Sgibbs * that having all of the termination on 173895378Sgibbs * gives us a more stable bus. 173995378Sgibbs */ 174095378Sgibbs internal50_present = 0; 174195378Sgibbs internal68_present = 0; 174295378Sgibbs externalcable_present = 0; 174365942Sgibbs } 174465942Sgibbs 174565942Sgibbs if ((ahc->features & AHC_WIDE) != 0 174665942Sgibbs && ((externalcable_present == 0) 174765942Sgibbs || (internal68_present == 0) 174865942Sgibbs || (enableSEC_high != 0))) { 174965942Sgibbs brddat |= BRDDAT6; 175065942Sgibbs if (bootverbose) { 175165942Sgibbs if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) 175265942Sgibbs printf("%s: 68 pin termination " 175365942Sgibbs "Enabled\n", ahc_name(ahc)); 175465942Sgibbs else 175565942Sgibbs printf("%s: %sHigh byte termination " 175665942Sgibbs "Enabled\n", ahc_name(ahc), 175765942Sgibbs enableSEC_high ? "Secondary " 175865942Sgibbs : ""); 175965942Sgibbs } 176065942Sgibbs } 176165942Sgibbs 176271390Sgibbs sum = internal50_present + internal68_present 176371390Sgibbs + externalcable_present; 176471390Sgibbs if (sum < 2 || (enableSEC_low != 0)) { 176565942Sgibbs if ((ahc->features & AHC_ULTRA2) != 0) 176665942Sgibbs brddat |= BRDDAT5; 176765942Sgibbs else 176865942Sgibbs *sxfrctl1 |= STPWEN; 176965942Sgibbs if (bootverbose) { 177065942Sgibbs if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) 177165942Sgibbs printf("%s: 50 pin termination " 177265942Sgibbs "Enabled\n", ahc_name(ahc)); 177365942Sgibbs else 177465942Sgibbs printf("%s: %sLow byte termination " 177565942Sgibbs "Enabled\n", ahc_name(ahc), 177665942Sgibbs enableSEC_low ? "Secondary " 177765942Sgibbs : ""); 177865942Sgibbs } 177965942Sgibbs } 178065942Sgibbs 178165942Sgibbs if (enablePRI_low != 0) { 178265942Sgibbs *sxfrctl1 |= STPWEN; 178365942Sgibbs if (bootverbose) 178465942Sgibbs printf("%s: Primary Low Byte termination " 178565942Sgibbs "Enabled\n", ahc_name(ahc)); 178665942Sgibbs } 178765942Sgibbs 178865942Sgibbs /* 178965942Sgibbs * Setup STPWEN before setting up the rest of 179065942Sgibbs * the termination per the tech note on the U160 cards. 179165942Sgibbs */ 179265942Sgibbs ahc_outb(ahc, SXFRCTL1, *sxfrctl1); 179365942Sgibbs 179465942Sgibbs if (enablePRI_high != 0) { 179565942Sgibbs brddat |= BRDDAT4; 179665942Sgibbs if (bootverbose) 179765942Sgibbs printf("%s: Primary High Byte " 179865942Sgibbs "termination Enabled\n", 179965942Sgibbs ahc_name(ahc)); 180065942Sgibbs } 180165942Sgibbs 180265942Sgibbs write_brdctl(ahc, brddat); 180365942Sgibbs 180465942Sgibbs } else { 180565942Sgibbs if ((adapter_control & CFSTERM) != 0) { 180665942Sgibbs *sxfrctl1 |= STPWEN; 180765942Sgibbs 180865942Sgibbs if (bootverbose) 180965942Sgibbs printf("%s: %sLow byte termination Enabled\n", 181065942Sgibbs ahc_name(ahc), 181165942Sgibbs (ahc->features & AHC_ULTRA2) ? "Primary " 181265942Sgibbs : ""); 181365942Sgibbs } 181465942Sgibbs 181571390Sgibbs if ((adapter_control & CFWSTERM) != 0 181671390Sgibbs && (ahc->features & AHC_WIDE) != 0) { 181765942Sgibbs brddat |= BRDDAT6; 181865942Sgibbs if (bootverbose) 181965942Sgibbs printf("%s: %sHigh byte termination Enabled\n", 182065942Sgibbs ahc_name(ahc), 182165942Sgibbs (ahc->features & AHC_ULTRA2) 182265942Sgibbs ? "Secondary " : ""); 182365942Sgibbs } 182465942Sgibbs 182565942Sgibbs /* 182665942Sgibbs * Setup STPWEN before setting up the rest of 182765942Sgibbs * the termination per the tech note on the U160 cards. 182865942Sgibbs */ 182965942Sgibbs ahc_outb(ahc, SXFRCTL1, *sxfrctl1); 183065942Sgibbs 183171390Sgibbs if ((ahc->features & AHC_WIDE) != 0) 183271390Sgibbs write_brdctl(ahc, brddat); 183365942Sgibbs } 183465942Sgibbs SEEPROM_OUTB(sd, sd->sd_MS); /* Clear CS */ 183565942Sgibbs} 183665942Sgibbs 183765942Sgibbsstatic void 183865942Sgibbsahc_new_term_detect(struct ahc_softc *ahc, int *enableSEC_low, 183965942Sgibbs int *enableSEC_high, int *enablePRI_low, 184065942Sgibbs int *enablePRI_high, int *eeprom_present) 184165942Sgibbs{ 184265942Sgibbs uint8_t brdctl; 184365942Sgibbs 184465942Sgibbs /* 184565942Sgibbs * BRDDAT7 = Eeprom 184665942Sgibbs * BRDDAT6 = Enable Secondary High Byte termination 184765942Sgibbs * BRDDAT5 = Enable Secondary Low Byte termination 184865942Sgibbs * BRDDAT4 = Enable Primary high byte termination 184965942Sgibbs * BRDDAT3 = Enable Primary low byte termination 185065942Sgibbs */ 185165942Sgibbs brdctl = read_brdctl(ahc); 185265942Sgibbs *eeprom_present = brdctl & BRDDAT7; 185365942Sgibbs *enableSEC_high = (brdctl & BRDDAT6); 185465942Sgibbs *enableSEC_low = (brdctl & BRDDAT5); 185565942Sgibbs *enablePRI_high = (brdctl & BRDDAT4); 185665942Sgibbs *enablePRI_low = (brdctl & BRDDAT3); 185765942Sgibbs} 185865942Sgibbs 185965942Sgibbsstatic void 186065942Sgibbsaic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present, 186165942Sgibbs int *internal68_present, int *externalcable_present, 186265942Sgibbs int *eeprom_present) 186365942Sgibbs{ 186465942Sgibbs uint8_t brdctl; 186565942Sgibbs 186665942Sgibbs /* 186765942Sgibbs * First read the status of our cables. 186865942Sgibbs * Set the rom bank to 0 since the 186965942Sgibbs * bank setting serves as a multiplexor 187065942Sgibbs * for the cable detection logic. 187165942Sgibbs * BRDDAT5 controls the bank switch. 187265942Sgibbs */ 187365942Sgibbs write_brdctl(ahc, 0); 187465942Sgibbs 187565942Sgibbs /* 187665942Sgibbs * Now read the state of the internal 187765942Sgibbs * connectors. BRDDAT6 is INT50 and 187865942Sgibbs * BRDDAT7 is INT68. 187965942Sgibbs */ 188065942Sgibbs brdctl = read_brdctl(ahc); 188171390Sgibbs *internal50_present = (brdctl & BRDDAT6) ? 0 : 1; 188271390Sgibbs *internal68_present = (brdctl & BRDDAT7) ? 0 : 1; 188365942Sgibbs 188465942Sgibbs /* 188565942Sgibbs * Set the rom bank to 1 and determine 188665942Sgibbs * the other signals. 188765942Sgibbs */ 188865942Sgibbs write_brdctl(ahc, BRDDAT5); 188965942Sgibbs 189065942Sgibbs /* 189165942Sgibbs * Now read the state of the external 189265942Sgibbs * connectors. BRDDAT6 is EXT68 and 189365942Sgibbs * BRDDAT7 is EPROMPS. 189465942Sgibbs */ 189565942Sgibbs brdctl = read_brdctl(ahc); 189671390Sgibbs *externalcable_present = (brdctl & BRDDAT6) ? 0 : 1; 189771390Sgibbs *eeprom_present = (brdctl & BRDDAT7) ? 1 : 0; 189865942Sgibbs} 189965942Sgibbs 190065942Sgibbsstatic void 190165942Sgibbsaic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present, 190265942Sgibbs int *externalcable_present, int *eeprom_present) 190365942Sgibbs{ 190465942Sgibbs uint8_t brdctl; 1905102676Sgibbs uint8_t spiocap; 190665942Sgibbs 1907102676Sgibbs spiocap = ahc_inb(ahc, SPIOCAP); 1908102676Sgibbs spiocap &= ~SOFTCMDEN; 1909102676Sgibbs spiocap |= EXT_BRDCTL; 1910102676Sgibbs ahc_outb(ahc, SPIOCAP, spiocap); 191165942Sgibbs ahc_outb(ahc, BRDCTL, BRDRW|BRDCS); 1912114621Sgibbs ahc_flush_device_writes(ahc); 1913123579Sgibbs aic_delay(500); 191465942Sgibbs ahc_outb(ahc, BRDCTL, 0); 1915114621Sgibbs ahc_flush_device_writes(ahc); 1916123579Sgibbs aic_delay(500); 191765942Sgibbs brdctl = ahc_inb(ahc, BRDCTL); 191871390Sgibbs *internal50_present = (brdctl & BRDDAT5) ? 0 : 1; 191971390Sgibbs *externalcable_present = (brdctl & BRDDAT6) ? 0 : 1; 192071390Sgibbs *eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0; 192165942Sgibbs} 192265942Sgibbs 192395378Sgibbsint 192495378Sgibbsahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd) 192565942Sgibbs{ 192665942Sgibbs int wait; 192765942Sgibbs 192865942Sgibbs if ((ahc->features & AHC_SPIOCAP) != 0 192965942Sgibbs && (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0) 193065942Sgibbs return (0); 193165942Sgibbs 193265942Sgibbs /* 193365942Sgibbs * Request access of the memory port. When access is 193465942Sgibbs * granted, SEERDY will go high. We use a 1 second 193565942Sgibbs * timeout which should be near 1 second more than 193665942Sgibbs * is needed. Reason: after the chip reset, there 193765942Sgibbs * should be no contention. 193865942Sgibbs */ 193965942Sgibbs SEEPROM_OUTB(sd, sd->sd_MS); 194065942Sgibbs wait = 1000; /* 1 second timeout in msec */ 194165942Sgibbs while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) { 1942123579Sgibbs aic_delay(1000); /* delay 1 msec */ 194365942Sgibbs } 194465942Sgibbs if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) { 194565942Sgibbs SEEPROM_OUTB(sd, 0); 194665942Sgibbs return (0); 194765942Sgibbs } 194865942Sgibbs return(1); 194965942Sgibbs} 195065942Sgibbs 195195378Sgibbsvoid 195295378Sgibbsahc_release_seeprom(struct seeprom_descriptor *sd) 195365942Sgibbs{ 195465942Sgibbs /* Release access to the memory port and the serial EEPROM. */ 195565942Sgibbs SEEPROM_OUTB(sd, 0); 195665942Sgibbs} 195765942Sgibbs 195865942Sgibbsstatic void 195965942Sgibbswrite_brdctl(struct ahc_softc *ahc, uint8_t value) 196065942Sgibbs{ 196165942Sgibbs uint8_t brdctl; 196265942Sgibbs 196365942Sgibbs if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { 196465942Sgibbs brdctl = BRDSTB; 196565942Sgibbs if (ahc->channel == 'B') 196665942Sgibbs brdctl |= BRDCS; 196765942Sgibbs } else if ((ahc->features & AHC_ULTRA2) != 0) { 196865942Sgibbs brdctl = 0; 196965942Sgibbs } else { 197065942Sgibbs brdctl = BRDSTB|BRDCS; 197165942Sgibbs } 197265942Sgibbs ahc_outb(ahc, BRDCTL, brdctl); 197371390Sgibbs ahc_flush_device_writes(ahc); 197465942Sgibbs brdctl |= value; 197565942Sgibbs ahc_outb(ahc, BRDCTL, brdctl); 197671390Sgibbs ahc_flush_device_writes(ahc); 197765942Sgibbs if ((ahc->features & AHC_ULTRA2) != 0) 197865942Sgibbs brdctl |= BRDSTB_ULTRA2; 197965942Sgibbs else 198065942Sgibbs brdctl &= ~BRDSTB; 198165942Sgibbs ahc_outb(ahc, BRDCTL, brdctl); 198271390Sgibbs ahc_flush_device_writes(ahc); 198365942Sgibbs if ((ahc->features & AHC_ULTRA2) != 0) 198465942Sgibbs brdctl = 0; 198565942Sgibbs else 198665942Sgibbs brdctl &= ~BRDCS; 198765942Sgibbs ahc_outb(ahc, BRDCTL, brdctl); 198865942Sgibbs} 198965942Sgibbs 199065942Sgibbsstatic uint8_t 1991115328Sgibbsread_brdctl(struct ahc_softc *ahc) 199265942Sgibbs{ 199365942Sgibbs uint8_t brdctl; 199465942Sgibbs uint8_t value; 199565942Sgibbs 199665942Sgibbs if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { 199765942Sgibbs brdctl = BRDRW; 199865942Sgibbs if (ahc->channel == 'B') 199965942Sgibbs brdctl |= BRDCS; 200065942Sgibbs } else if ((ahc->features & AHC_ULTRA2) != 0) { 200165942Sgibbs brdctl = BRDRW_ULTRA2; 200265942Sgibbs } else { 200365942Sgibbs brdctl = BRDRW|BRDCS; 200465942Sgibbs } 200565942Sgibbs ahc_outb(ahc, BRDCTL, brdctl); 200671390Sgibbs ahc_flush_device_writes(ahc); 200765942Sgibbs value = ahc_inb(ahc, BRDCTL); 200865942Sgibbs ahc_outb(ahc, BRDCTL, 0); 200965942Sgibbs return (value); 201065942Sgibbs} 201165942Sgibbs 2012114621Sgibbsstatic void 201365942Sgibbsahc_pci_intr(struct ahc_softc *ahc) 201465942Sgibbs{ 201566269Sgibbs u_int error; 201666269Sgibbs u_int status1; 201765942Sgibbs 201866269Sgibbs error = ahc_inb(ahc, ERROR); 201966269Sgibbs if ((error & PCIERRSTAT) == 0) 202066269Sgibbs return; 202166269Sgibbs 2022123579Sgibbs status1 = aic_pci_read_config(ahc->dev_softc, 202365942Sgibbs PCIR_STATUS + 1, /*bytes*/1); 202465942Sgibbs 2025150453Sgibbs if ((status1 & ~DPE) != 0 2026150453Sgibbs || (ahc->flags & AHC_DISABLE_PCI_PERR) == 0) { 2027150453Sgibbs printf("%s: PCI error Interrupt at seqaddr = 0x%x\n", 2028150453Sgibbs ahc_name(ahc), 2029150453Sgibbs ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); 2030150453Sgibbs } 203166269Sgibbs 2032150453Sgibbs if (status1 & DPE 2033150453Sgibbs && (ahc->flags & AHC_DISABLE_PCI_PERR) == 0) { 2034114621Sgibbs ahc->pci_target_perr_count++; 203565942Sgibbs printf("%s: Data Parity Error Detected during address " 203665942Sgibbs "or write data phase\n", ahc_name(ahc)); 203765942Sgibbs } 203865942Sgibbs if (status1 & SSE) { 203966647Sgibbs printf("%s: Signal System Error Detected\n", ahc_name(ahc)); 204065942Sgibbs } 204165942Sgibbs if (status1 & RMA) { 204266647Sgibbs printf("%s: Received a Master Abort\n", ahc_name(ahc)); 204365942Sgibbs } 204465942Sgibbs if (status1 & RTA) { 204565942Sgibbs printf("%s: Received a Target Abort\n", ahc_name(ahc)); 204665942Sgibbs } 204765942Sgibbs if (status1 & STA) { 204865942Sgibbs printf("%s: Signaled a Target Abort\n", ahc_name(ahc)); 204965942Sgibbs } 205065942Sgibbs if (status1 & DPR) { 205165942Sgibbs printf("%s: Data Parity Error has been reported via PERR#\n", 205265942Sgibbs ahc_name(ahc)); 205365942Sgibbs } 205479874Sgibbs 205579874Sgibbs /* Clear latched errors. */ 2056123579Sgibbs aic_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, 205779874Sgibbs status1, /*bytes*/1); 205879874Sgibbs 205965942Sgibbs if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) { 206065942Sgibbs printf("%s: Latched PCIERR interrupt with " 206165942Sgibbs "no status bits set\n", ahc_name(ahc)); 206279874Sgibbs } else { 206365942Sgibbs ahc_outb(ahc, CLRINT, CLRPARERR); 206465942Sgibbs } 206566269Sgibbs 2066150453Sgibbs if (ahc->pci_target_perr_count > AHC_PCI_TARGET_PERR_THRESH 2067150453Sgibbs && (ahc->flags & AHC_DISABLE_PCI_PERR) == 0) { 2068114621Sgibbs printf( 2069114621Sgibbs"%s: WARNING WARNING WARNING WARNING\n" 2070114621Sgibbs"%s: Too many PCI parity errors observed as a target.\n" 2071150453Sgibbs"%s: Some device on this PCI bus is generating bad parity.\n" 2072150453Sgibbs"%s: This is an error *observed by*, not *generated by*, %s.\n" 2073114621Sgibbs"%s: PCI parity error checking has been disabled.\n" 2074114621Sgibbs"%s: WARNING WARNING WARNING WARNING\n", 2075114621Sgibbs ahc_name(ahc), ahc_name(ahc), ahc_name(ahc), 2076150453Sgibbs ahc_name(ahc), ahc_name(ahc), ahc_name(ahc), 2077150453Sgibbs ahc_name(ahc)); 2078115332Sgibbs ahc->seqctl |= FAILDIS; 2079150453Sgibbs ahc->flags |= AHC_DISABLE_PCI_PERR; 2080115332Sgibbs ahc_outb(ahc, SEQCTL, ahc->seqctl); 2081114621Sgibbs } 208274094Sgibbs ahc_unpause(ahc); 208365942Sgibbs} 208465942Sgibbs 208565942Sgibbsstatic int 2086114621Sgibbsahc_pci_chip_init(struct ahc_softc *ahc) 2087114621Sgibbs{ 2088114621Sgibbs ahc_outb(ahc, DSCOMMAND0, ahc->bus_softc.pci_softc.dscommand0); 2089114621Sgibbs ahc_outb(ahc, DSPCISTATUS, ahc->bus_softc.pci_softc.dspcistatus); 2090114621Sgibbs if ((ahc->features & AHC_DT) != 0) { 2091114621Sgibbs u_int sfunct; 2092114621Sgibbs 2093114621Sgibbs sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE; 2094114621Sgibbs ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE); 2095114621Sgibbs ahc_outb(ahc, OPTIONMODE, ahc->bus_softc.pci_softc.optionmode); 2096114621Sgibbs ahc_outw(ahc, TARGCRCCNT, ahc->bus_softc.pci_softc.targcrccnt); 2097114621Sgibbs ahc_outb(ahc, SFUNCT, sfunct); 2098114621Sgibbs ahc_outb(ahc, CRCCONTROL1, 2099114621Sgibbs ahc->bus_softc.pci_softc.crccontrol1); 2100114621Sgibbs } 2101114621Sgibbs if ((ahc->features & AHC_MULTI_FUNC) != 0) 2102114621Sgibbs ahc_outb(ahc, SCBBADDR, ahc->bus_softc.pci_softc.scbbaddr); 2103114621Sgibbs 2104114621Sgibbs if ((ahc->features & AHC_ULTRA2) != 0) 2105114621Sgibbs ahc_outb(ahc, DFF_THRSH, ahc->bus_softc.pci_softc.dff_thrsh); 2106114621Sgibbs 2107114621Sgibbs return (ahc_chip_init(ahc)); 2108114621Sgibbs} 2109114621Sgibbs 2110114621Sgibbsstatic int 2111114621Sgibbsahc_pci_suspend(struct ahc_softc *ahc) 2112114621Sgibbs{ 2113114621Sgibbs return (ahc_suspend(ahc)); 2114114621Sgibbs} 2115114621Sgibbs 2116114621Sgibbsstatic int 2117114621Sgibbsahc_pci_resume(struct ahc_softc *ahc) 2118114621Sgibbs{ 2119114621Sgibbs 2120123579Sgibbs aic_power_state_change(ahc, AIC_POWER_STATE_D0); 2121114621Sgibbs 2122114621Sgibbs /* 2123114621Sgibbs * We assume that the OS has restored our register 2124114621Sgibbs * mappings, etc. Just update the config space registers 2125114621Sgibbs * that the OS doesn't know about and rely on our chip 2126114621Sgibbs * reset handler to handle the rest. 2127114621Sgibbs */ 2128134157Sgibbs aic_pci_write_config(ahc->dev_softc, DEVCONFIG, 2129134157Sgibbs ahc->bus_softc.pci_softc.devconfig, /*bytes*/4); 2130134157Sgibbs aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND, 2131134157Sgibbs ahc->bus_softc.pci_softc.command, /*bytes*/1); 2132134157Sgibbs aic_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, 2133134157Sgibbs ahc->bus_softc.pci_softc.csize_lattime, 2134134157Sgibbs /*bytes*/1); 2135114621Sgibbs if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) { 2136114621Sgibbs struct seeprom_descriptor sd; 2137114621Sgibbs u_int sxfrctl1; 2138114621Sgibbs 2139114621Sgibbs sd.sd_ahc = ahc; 2140114621Sgibbs sd.sd_control_offset = SEECTL; 2141114621Sgibbs sd.sd_status_offset = SEECTL; 2142114621Sgibbs sd.sd_dataout_offset = SEECTL; 2143114621Sgibbs 2144114621Sgibbs ahc_acquire_seeprom(ahc, &sd); 2145114621Sgibbs configure_termination(ahc, &sd, 2146114621Sgibbs ahc->seep_config->adapter_control, 2147114621Sgibbs &sxfrctl1); 2148114621Sgibbs ahc_release_seeprom(&sd); 2149114621Sgibbs } 2150114621Sgibbs return (ahc_resume(ahc)); 2151114621Sgibbs} 2152114621Sgibbs 2153114621Sgibbsstatic int 215479874Sgibbsahc_aic785X_setup(struct ahc_softc *ahc) 215565942Sgibbs{ 2156123579Sgibbs aic_dev_softc_t pci; 215774094Sgibbs uint8_t rev; 215874094Sgibbs 215979874Sgibbs pci = ahc->dev_softc; 216079874Sgibbs ahc->channel = 'A'; 216179874Sgibbs ahc->chip = AHC_AIC7850; 216279874Sgibbs ahc->features = AHC_AIC7850_FE; 216379874Sgibbs ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; 2164123579Sgibbs rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1); 216574094Sgibbs if (rev >= 1) 216679874Sgibbs ahc->bugs |= AHC_PCI_2_1_RETRY_BUG; 2167114621Sgibbs ahc->instruction_ram_size = 512; 216865942Sgibbs return (0); 216965942Sgibbs} 217065942Sgibbs 217165942Sgibbsstatic int 217279874Sgibbsahc_aic7860_setup(struct ahc_softc *ahc) 217365942Sgibbs{ 2174123579Sgibbs aic_dev_softc_t pci; 217565942Sgibbs uint8_t rev; 217665942Sgibbs 217779874Sgibbs pci = ahc->dev_softc; 217879874Sgibbs ahc->channel = 'A'; 217979874Sgibbs ahc->chip = AHC_AIC7860; 218079874Sgibbs ahc->features = AHC_AIC7860_FE; 218179874Sgibbs ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; 2182123579Sgibbs rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1); 218365942Sgibbs if (rev >= 1) 218479874Sgibbs ahc->bugs |= AHC_PCI_2_1_RETRY_BUG; 2185114621Sgibbs ahc->instruction_ram_size = 512; 218665942Sgibbs return (0); 218765942Sgibbs} 218865942Sgibbs 218965942Sgibbsstatic int 219079874Sgibbsahc_apa1480_setup(struct ahc_softc *ahc) 219171390Sgibbs{ 219271390Sgibbs int error; 219371390Sgibbs 219479874Sgibbs error = ahc_aic7860_setup(ahc); 219571390Sgibbs if (error != 0) 219671390Sgibbs return (error); 219779874Sgibbs ahc->features |= AHC_REMOVABLE; 219871390Sgibbs return (0); 219971390Sgibbs} 220071390Sgibbs 220171390Sgibbsstatic int 220279874Sgibbsahc_aic7870_setup(struct ahc_softc *ahc) 220365942Sgibbs{ 220479874Sgibbs 220579874Sgibbs ahc->channel = 'A'; 220679874Sgibbs ahc->chip = AHC_AIC7870; 220779874Sgibbs ahc->features = AHC_AIC7870_FE; 220879874Sgibbs ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; 2209114621Sgibbs ahc->instruction_ram_size = 512; 221065942Sgibbs return (0); 221165942Sgibbs} 221265942Sgibbs 221365942Sgibbsstatic int 221479874Sgibbsahc_aha394X_setup(struct ahc_softc *ahc) 221565942Sgibbs{ 221665942Sgibbs int error; 221765942Sgibbs 221879874Sgibbs error = ahc_aic7870_setup(ahc); 221965942Sgibbs if (error == 0) 222079874Sgibbs error = ahc_aha394XX_setup(ahc); 222165942Sgibbs return (error); 222265942Sgibbs} 222365942Sgibbs 222465942Sgibbsstatic int 222579874Sgibbsahc_aha398X_setup(struct ahc_softc *ahc) 222665942Sgibbs{ 222765942Sgibbs int error; 222865942Sgibbs 222979874Sgibbs error = ahc_aic7870_setup(ahc); 223065942Sgibbs if (error == 0) 223179874Sgibbs error = ahc_aha398XX_setup(ahc); 223265942Sgibbs return (error); 223365942Sgibbs} 223465942Sgibbs 223565942Sgibbsstatic int 223679874Sgibbsahc_aha494X_setup(struct ahc_softc *ahc) 223765942Sgibbs{ 223865942Sgibbs int error; 223965942Sgibbs 224079874Sgibbs error = ahc_aic7870_setup(ahc); 224165942Sgibbs if (error == 0) 224279874Sgibbs error = ahc_aha494XX_setup(ahc); 224365942Sgibbs return (error); 224465942Sgibbs} 224565942Sgibbs 224665942Sgibbsstatic int 224779874Sgibbsahc_aic7880_setup(struct ahc_softc *ahc) 224865942Sgibbs{ 2249123579Sgibbs aic_dev_softc_t pci; 225065942Sgibbs uint8_t rev; 225165942Sgibbs 225279874Sgibbs pci = ahc->dev_softc; 225379874Sgibbs ahc->channel = 'A'; 225479874Sgibbs ahc->chip = AHC_AIC7880; 225579874Sgibbs ahc->features = AHC_AIC7880_FE; 225679874Sgibbs ahc->bugs |= AHC_TMODE_WIDEODD_BUG; 2257123579Sgibbs rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1); 225865942Sgibbs if (rev >= 1) { 225979874Sgibbs ahc->bugs |= AHC_PCI_2_1_RETRY_BUG; 226065942Sgibbs } else { 226179874Sgibbs ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG; 226265942Sgibbs } 2263114621Sgibbs ahc->instruction_ram_size = 512; 226465942Sgibbs return (0); 226565942Sgibbs} 226665942Sgibbs 226765942Sgibbsstatic int 226879874Sgibbsahc_aha2940Pro_setup(struct ahc_softc *ahc) 226965942Sgibbs{ 227065942Sgibbs 227179874Sgibbs ahc->flags |= AHC_INT50_SPEEDFLEX; 2272102676Sgibbs return (ahc_aic7880_setup(ahc)); 227365942Sgibbs} 227465942Sgibbs 227565942Sgibbsstatic int 227679874Sgibbsahc_aha394XU_setup(struct ahc_softc *ahc) 227765942Sgibbs{ 227865942Sgibbs int error; 227965942Sgibbs 228079874Sgibbs error = ahc_aic7880_setup(ahc); 228165942Sgibbs if (error == 0) 228279874Sgibbs error = ahc_aha394XX_setup(ahc); 228365942Sgibbs return (error); 228465942Sgibbs} 228565942Sgibbs 228665942Sgibbsstatic int 228779874Sgibbsahc_aha398XU_setup(struct ahc_softc *ahc) 228865942Sgibbs{ 228965942Sgibbs int error; 229065942Sgibbs 229179874Sgibbs error = ahc_aic7880_setup(ahc); 229265942Sgibbs if (error == 0) 229379874Sgibbs error = ahc_aha398XX_setup(ahc); 229465942Sgibbs return (error); 229565942Sgibbs} 229665942Sgibbs 229765942Sgibbsstatic int 229879874Sgibbsahc_aic7890_setup(struct ahc_softc *ahc) 229965942Sgibbs{ 2300123579Sgibbs aic_dev_softc_t pci; 230165942Sgibbs uint8_t rev; 230265942Sgibbs 230379874Sgibbs pci = ahc->dev_softc; 230479874Sgibbs ahc->channel = 'A'; 230579874Sgibbs ahc->chip = AHC_AIC7890; 230679874Sgibbs ahc->features = AHC_AIC7890_FE; 230779874Sgibbs ahc->flags |= AHC_NEWEEPROM_FMT; 2308123579Sgibbs rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1); 230965942Sgibbs if (rev == 0) 231079874Sgibbs ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG; 2311114621Sgibbs ahc->instruction_ram_size = 768; 231265942Sgibbs return (0); 231365942Sgibbs} 231465942Sgibbs 231565942Sgibbsstatic int 231679874Sgibbsahc_aic7892_setup(struct ahc_softc *ahc) 231765942Sgibbs{ 231879874Sgibbs 231979874Sgibbs ahc->channel = 'A'; 232079874Sgibbs ahc->chip = AHC_AIC7892; 232179874Sgibbs ahc->features = AHC_AIC7892_FE; 232279874Sgibbs ahc->flags |= AHC_NEWEEPROM_FMT; 232379874Sgibbs ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG; 2324114621Sgibbs ahc->instruction_ram_size = 1024; 232565942Sgibbs return (0); 232665942Sgibbs} 232765942Sgibbs 232865942Sgibbsstatic int 232979874Sgibbsahc_aic7895_setup(struct ahc_softc *ahc) 233065942Sgibbs{ 2331123579Sgibbs aic_dev_softc_t pci; 233265942Sgibbs uint8_t rev; 233365942Sgibbs 233479874Sgibbs pci = ahc->dev_softc; 2335123579Sgibbs ahc->channel = aic_get_pci_function(pci) == 1 ? 'B' : 'A'; 233665942Sgibbs /* 233765942Sgibbs * The 'C' revision of the aic7895 has a few additional features. 233865942Sgibbs */ 2339123579Sgibbs rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1); 234065942Sgibbs if (rev >= 4) { 234179874Sgibbs ahc->chip = AHC_AIC7895C; 234279874Sgibbs ahc->features = AHC_AIC7895C_FE; 234365942Sgibbs } else { 234465942Sgibbs u_int command; 234565942Sgibbs 234679874Sgibbs ahc->chip = AHC_AIC7895; 234779874Sgibbs ahc->features = AHC_AIC7895_FE; 234865942Sgibbs 234965942Sgibbs /* 235065942Sgibbs * The BIOS disables the use of MWI transactions 235165942Sgibbs * since it does not have the MWI bug work around 235265942Sgibbs * we have. Disabling MWI reduces performance, so 235365942Sgibbs * turn it on again. 235465942Sgibbs */ 2355123579Sgibbs command = aic_pci_read_config(pci, PCIR_COMMAND, /*bytes*/1); 235665942Sgibbs command |= PCIM_CMD_MWRICEN; 2357123579Sgibbs aic_pci_write_config(pci, PCIR_COMMAND, command, /*bytes*/1); 235879874Sgibbs ahc->bugs |= AHC_PCI_MWI_BUG; 235965942Sgibbs } 236065942Sgibbs /* 236165942Sgibbs * XXX Does CACHETHEN really not work??? What about PCI retry? 236265942Sgibbs * on C level chips. Need to test, but for now, play it safe. 236365942Sgibbs */ 236479874Sgibbs ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_PCI_2_1_RETRY_BUG 236579874Sgibbs | AHC_CACHETHEN_BUG; 236665942Sgibbs 236765942Sgibbs#if 0 236865942Sgibbs uint32_t devconfig; 236965942Sgibbs 237065942Sgibbs /* 237165942Sgibbs * Cachesize must also be zero due to stray DAC 237265942Sgibbs * problem when sitting behind some bridges. 237365942Sgibbs */ 2374123579Sgibbs aic_pci_write_config(pci, CSIZE_LATTIME, 0, /*bytes*/1); 2375123579Sgibbs devconfig = aic_pci_read_config(pci, DEVCONFIG, /*bytes*/1); 237665942Sgibbs devconfig |= MRDCEN; 2377123579Sgibbs aic_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1); 237865942Sgibbs#endif 237979874Sgibbs ahc->flags |= AHC_NEWEEPROM_FMT; 2380114621Sgibbs ahc->instruction_ram_size = 512; 238165942Sgibbs return (0); 238265942Sgibbs} 238365942Sgibbs 238465942Sgibbsstatic int 238579874Sgibbsahc_aic7896_setup(struct ahc_softc *ahc) 238665942Sgibbs{ 2387123579Sgibbs aic_dev_softc_t pci; 238879874Sgibbs 238979874Sgibbs pci = ahc->dev_softc; 2390123579Sgibbs ahc->channel = aic_get_pci_function(pci) == 1 ? 'B' : 'A'; 239179874Sgibbs ahc->chip = AHC_AIC7896; 239279874Sgibbs ahc->features = AHC_AIC7896_FE; 239379874Sgibbs ahc->flags |= AHC_NEWEEPROM_FMT; 239479874Sgibbs ahc->bugs |= AHC_CACHETHEN_DIS_BUG; 2395114621Sgibbs ahc->instruction_ram_size = 768; 239665942Sgibbs return (0); 239765942Sgibbs} 239865942Sgibbs 239965942Sgibbsstatic int 240079874Sgibbsahc_aic7899_setup(struct ahc_softc *ahc) 240165942Sgibbs{ 2402123579Sgibbs aic_dev_softc_t pci; 240379874Sgibbs 240479874Sgibbs pci = ahc->dev_softc; 2405123579Sgibbs ahc->channel = aic_get_pci_function(pci) == 1 ? 'B' : 'A'; 240679874Sgibbs ahc->chip = AHC_AIC7899; 240779874Sgibbs ahc->features = AHC_AIC7899_FE; 240879874Sgibbs ahc->flags |= AHC_NEWEEPROM_FMT; 240979874Sgibbs ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG; 2410114621Sgibbs ahc->instruction_ram_size = 1024; 241165942Sgibbs return (0); 241265942Sgibbs} 241365942Sgibbs 241465942Sgibbsstatic int 241579874Sgibbsahc_aha29160C_setup(struct ahc_softc *ahc) 241671390Sgibbs{ 241771390Sgibbs int error; 241871390Sgibbs 241979874Sgibbs error = ahc_aic7899_setup(ahc); 242071390Sgibbs if (error != 0) 242171390Sgibbs return (error); 242279874Sgibbs ahc->features |= AHC_REMOVABLE; 242371390Sgibbs return (0); 242471390Sgibbs} 242571390Sgibbs 242671390Sgibbsstatic int 242779874Sgibbsahc_raid_setup(struct ahc_softc *ahc) 242865942Sgibbs{ 242965942Sgibbs printf("RAID functionality unsupported\n"); 243065942Sgibbs return (ENXIO); 243165942Sgibbs} 243265942Sgibbs 243365942Sgibbsstatic int 243479874Sgibbsahc_aha394XX_setup(struct ahc_softc *ahc) 243565942Sgibbs{ 2436123579Sgibbs aic_dev_softc_t pci; 243779874Sgibbs 243879874Sgibbs pci = ahc->dev_softc; 2439123579Sgibbs switch (aic_get_pci_slot(pci)) { 244065942Sgibbs case AHC_394X_SLOT_CHANNEL_A: 244179874Sgibbs ahc->channel = 'A'; 244265942Sgibbs break; 244365942Sgibbs case AHC_394X_SLOT_CHANNEL_B: 244479874Sgibbs ahc->channel = 'B'; 244565942Sgibbs break; 244665942Sgibbs default: 244765942Sgibbs printf("adapter at unexpected slot %d\n" 244865942Sgibbs "unable to map to a channel\n", 2449123579Sgibbs aic_get_pci_slot(pci)); 245079874Sgibbs ahc->channel = 'A'; 245165942Sgibbs } 245265942Sgibbs return (0); 245365942Sgibbs} 245465942Sgibbs 245565942Sgibbsstatic int 245679874Sgibbsahc_aha398XX_setup(struct ahc_softc *ahc) 245765942Sgibbs{ 2458123579Sgibbs aic_dev_softc_t pci; 245979874Sgibbs 246079874Sgibbs pci = ahc->dev_softc; 2461123579Sgibbs switch (aic_get_pci_slot(pci)) { 246265942Sgibbs case AHC_398X_SLOT_CHANNEL_A: 246379874Sgibbs ahc->channel = 'A'; 246465942Sgibbs break; 246565942Sgibbs case AHC_398X_SLOT_CHANNEL_B: 246679874Sgibbs ahc->channel = 'B'; 246765942Sgibbs break; 246865942Sgibbs case AHC_398X_SLOT_CHANNEL_C: 246979874Sgibbs ahc->channel = 'C'; 247065942Sgibbs break; 247165942Sgibbs default: 247265942Sgibbs printf("adapter at unexpected slot %d\n" 247365942Sgibbs "unable to map to a channel\n", 2474123579Sgibbs aic_get_pci_slot(pci)); 247579874Sgibbs ahc->channel = 'A'; 247665942Sgibbs break; 247765942Sgibbs } 247879874Sgibbs ahc->flags |= AHC_LARGE_SEEPROM; 247965942Sgibbs return (0); 248065942Sgibbs} 248165942Sgibbs 248265942Sgibbsstatic int 248379874Sgibbsahc_aha494XX_setup(struct ahc_softc *ahc) 248465942Sgibbs{ 2485123579Sgibbs aic_dev_softc_t pci; 248679874Sgibbs 248779874Sgibbs pci = ahc->dev_softc; 2488123579Sgibbs switch (aic_get_pci_slot(pci)) { 248965942Sgibbs case AHC_494X_SLOT_CHANNEL_A: 249079874Sgibbs ahc->channel = 'A'; 249165942Sgibbs break; 249265942Sgibbs case AHC_494X_SLOT_CHANNEL_B: 249379874Sgibbs ahc->channel = 'B'; 249465942Sgibbs break; 249565942Sgibbs case AHC_494X_SLOT_CHANNEL_C: 249679874Sgibbs ahc->channel = 'C'; 249765942Sgibbs break; 249865942Sgibbs case AHC_494X_SLOT_CHANNEL_D: 249979874Sgibbs ahc->channel = 'D'; 250065942Sgibbs break; 250165942Sgibbs default: 250265942Sgibbs printf("adapter at unexpected slot %d\n" 250365942Sgibbs "unable to map to a channel\n", 2504123579Sgibbs aic_get_pci_slot(pci)); 250579874Sgibbs ahc->channel = 'A'; 250665942Sgibbs } 250779874Sgibbs ahc->flags |= AHC_LARGE_SEEPROM; 250865942Sgibbs return (0); 250965942Sgibbs} 2510