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