11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Product specific probe and attach routines for: 31da177e4SLinus Torvalds * 27/284X and aic7770 motherboard SCSI controllers 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Copyright (c) 1994-1998, 2000, 2001 Justin T. Gibbs. 61da177e4SLinus Torvalds * All rights reserved. 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * Redistribution and use in source and binary forms, with or without 91da177e4SLinus Torvalds * modification, are permitted provided that the following conditions 101da177e4SLinus Torvalds * are met: 111da177e4SLinus Torvalds * 1. Redistributions of source code must retain the above copyright 121da177e4SLinus Torvalds * notice, this list of conditions, and the following disclaimer, 131da177e4SLinus Torvalds * without modification. 141da177e4SLinus Torvalds * 2. Redistributions in binary form must reproduce at minimum a disclaimer 151da177e4SLinus Torvalds * substantially similar to the "NO WARRANTY" disclaimer below 161da177e4SLinus Torvalds * ("Disclaimer") and any redistribution must be conditioned upon 171da177e4SLinus Torvalds * including a substantially similar Disclaimer requirement for further 181da177e4SLinus Torvalds * binary redistribution. 191da177e4SLinus Torvalds * 3. Neither the names of the above-listed copyright holders nor the names 201da177e4SLinus Torvalds * of any contributors may be used to endorse or promote products derived 211da177e4SLinus Torvalds * from this software without specific prior written permission. 221da177e4SLinus Torvalds * 231da177e4SLinus Torvalds * Alternatively, this software may be distributed under the terms of the 241da177e4SLinus Torvalds * GNU General Public License ("GPL") version 2 as published by the Free 251da177e4SLinus Torvalds * Software Foundation. 261da177e4SLinus Torvalds * 271da177e4SLinus Torvalds * NO WARRANTY 281da177e4SLinus Torvalds * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 291da177e4SLinus Torvalds * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 301da177e4SLinus Torvalds * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 311da177e4SLinus Torvalds * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 321da177e4SLinus Torvalds * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 331da177e4SLinus Torvalds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 341da177e4SLinus Torvalds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 351da177e4SLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 361da177e4SLinus Torvalds * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 371da177e4SLinus Torvalds * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 381da177e4SLinus Torvalds * POSSIBILITY OF SUCH DAMAGES. 391da177e4SLinus Torvalds * 401da177e4SLinus Torvalds * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#32 $ 411da177e4SLinus Torvalds * 421da177e4SLinus Torvalds * $FreeBSD$ 431da177e4SLinus Torvalds */ 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds #ifdef __linux__ 461da177e4SLinus Torvalds #include "aic7xxx_osm.h" 471da177e4SLinus Torvalds #include "aic7xxx_inline.h" 481da177e4SLinus Torvalds #include "aic7xxx_93cx6.h" 491da177e4SLinus Torvalds #else 501da177e4SLinus Torvalds #include <dev/aic7xxx/aic7xxx_osm.h> 511da177e4SLinus Torvalds #include <dev/aic7xxx/aic7xxx_inline.h> 521da177e4SLinus Torvalds #include <dev/aic7xxx/aic7xxx_93cx6.h> 531da177e4SLinus Torvalds #endif 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds #define ID_AIC7770 0x04907770 561da177e4SLinus Torvalds #define ID_AHA_274x 0x04907771 571da177e4SLinus Torvalds #define ID_AHA_284xB 0x04907756 /* BIOS enabled */ 581da177e4SLinus Torvalds #define ID_AHA_284x 0x04907757 /* BIOS disabled*/ 591da177e4SLinus Torvalds #define ID_OLV_274x 0x04907782 /* Olivetti OEM */ 601da177e4SLinus Torvalds #define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */ 611da177e4SLinus Torvalds 621da177e4SLinus Torvalds static int aic7770_chip_init(struct ahc_softc *ahc); 631da177e4SLinus Torvalds static int aic7770_suspend(struct ahc_softc *ahc); 641da177e4SLinus Torvalds static int aic7770_resume(struct ahc_softc *ahc); 651da177e4SLinus Torvalds static int aha2840_load_seeprom(struct ahc_softc *ahc); 661da177e4SLinus Torvalds static ahc_device_setup_t ahc_aic7770_VL_setup; 671da177e4SLinus Torvalds static ahc_device_setup_t ahc_aic7770_EISA_setup; 681da177e4SLinus Torvalds static ahc_device_setup_t ahc_aic7770_setup; 691da177e4SLinus Torvalds 701da177e4SLinus Torvalds struct aic7770_identity aic7770_ident_table[] = 711da177e4SLinus Torvalds { 721da177e4SLinus Torvalds { 731da177e4SLinus Torvalds ID_AHA_274x, 741da177e4SLinus Torvalds 0xFFFFFFFF, 751da177e4SLinus Torvalds "Adaptec 274X SCSI adapter", 761da177e4SLinus Torvalds ahc_aic7770_EISA_setup 771da177e4SLinus Torvalds }, 781da177e4SLinus Torvalds { 791da177e4SLinus Torvalds ID_AHA_284xB, 801da177e4SLinus Torvalds 0xFFFFFFFE, 811da177e4SLinus Torvalds "Adaptec 284X SCSI adapter", 821da177e4SLinus Torvalds ahc_aic7770_VL_setup 831da177e4SLinus Torvalds }, 841da177e4SLinus Torvalds { 851da177e4SLinus Torvalds ID_AHA_284x, 861da177e4SLinus Torvalds 0xFFFFFFFE, 871da177e4SLinus Torvalds "Adaptec 284X SCSI adapter (BIOS Disabled)", 881da177e4SLinus Torvalds ahc_aic7770_VL_setup 891da177e4SLinus Torvalds }, 901da177e4SLinus Torvalds { 911da177e4SLinus Torvalds ID_OLV_274x, 921da177e4SLinus Torvalds 0xFFFFFFFF, 931da177e4SLinus Torvalds "Adaptec (Olivetti OEM) 274X SCSI adapter", 941da177e4SLinus Torvalds ahc_aic7770_EISA_setup 951da177e4SLinus Torvalds }, 961da177e4SLinus Torvalds { 971da177e4SLinus Torvalds ID_OLV_274xD, 981da177e4SLinus Torvalds 0xFFFFFFFF, 991da177e4SLinus Torvalds "Adaptec (Olivetti OEM) 274X Differential SCSI adapter", 1001da177e4SLinus Torvalds ahc_aic7770_EISA_setup 1011da177e4SLinus Torvalds }, 1021da177e4SLinus Torvalds /* Generic chip probes for devices we don't know 'exactly' */ 1031da177e4SLinus Torvalds { 1041da177e4SLinus Torvalds ID_AIC7770, 1051da177e4SLinus Torvalds 0xFFFFFFFF, 1061da177e4SLinus Torvalds "Adaptec aic7770 SCSI adapter", 1071da177e4SLinus Torvalds ahc_aic7770_EISA_setup 1081da177e4SLinus Torvalds } 1091da177e4SLinus Torvalds }; 1101da177e4SLinus Torvalds const int ahc_num_aic7770_devs = NUM_ELEMENTS(aic7770_ident_table); 1111da177e4SLinus Torvalds 1121da177e4SLinus Torvalds struct aic7770_identity * 1131da177e4SLinus Torvalds aic7770_find_device(uint32_t id) 1141da177e4SLinus Torvalds { 1151da177e4SLinus Torvalds struct aic7770_identity *entry; 1161da177e4SLinus Torvalds int i; 1171da177e4SLinus Torvalds 1181da177e4SLinus Torvalds for (i = 0; i < ahc_num_aic7770_devs; i++) { 1191da177e4SLinus Torvalds entry = &aic7770_ident_table[i]; 1201da177e4SLinus Torvalds if (entry->full_id == (id & entry->id_mask)) 1211da177e4SLinus Torvalds return (entry); 1221da177e4SLinus Torvalds } 1231da177e4SLinus Torvalds return (NULL); 1241da177e4SLinus Torvalds } 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds int 1271da177e4SLinus Torvalds aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) 1281da177e4SLinus Torvalds { 1291da177e4SLinus Torvalds u_long l; 1301da177e4SLinus Torvalds int error; 1311da177e4SLinus Torvalds int have_seeprom; 1321da177e4SLinus Torvalds u_int hostconf; 1331da177e4SLinus Torvalds u_int irq; 1341da177e4SLinus Torvalds u_int intdef; 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds error = entry->setup(ahc); 1371da177e4SLinus Torvalds have_seeprom = 0; 1381da177e4SLinus Torvalds if (error != 0) 1391da177e4SLinus Torvalds return (error); 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds error = aic7770_map_registers(ahc, io); 1421da177e4SLinus Torvalds if (error != 0) 1431da177e4SLinus Torvalds return (error); 1441da177e4SLinus Torvalds 1451da177e4SLinus Torvalds /* 1461da177e4SLinus Torvalds * Before we continue probing the card, ensure that 1471da177e4SLinus Torvalds * its interrupts are *disabled*. We don't want 1481da177e4SLinus Torvalds * a misstep to hang the machine in an interrupt 1491da177e4SLinus Torvalds * storm. 1501da177e4SLinus Torvalds */ 1511da177e4SLinus Torvalds ahc_intr_enable(ahc, FALSE); 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds ahc->description = entry->name; 1541da177e4SLinus Torvalds error = ahc_softc_init(ahc); 1551da177e4SLinus Torvalds if (error != 0) 1561da177e4SLinus Torvalds return (error); 1571da177e4SLinus Torvalds 1581da177e4SLinus Torvalds ahc->bus_chip_init = aic7770_chip_init; 1591da177e4SLinus Torvalds ahc->bus_suspend = aic7770_suspend; 1601da177e4SLinus Torvalds ahc->bus_resume = aic7770_resume; 1611da177e4SLinus Torvalds 1621da177e4SLinus Torvalds error = ahc_reset(ahc, /*reinit*/FALSE); 1631da177e4SLinus Torvalds if (error != 0) 1641da177e4SLinus Torvalds return (error); 1651da177e4SLinus Torvalds 1661da177e4SLinus Torvalds /* Make sure we have a valid interrupt vector */ 1671da177e4SLinus Torvalds intdef = ahc_inb(ahc, INTDEF); 1681da177e4SLinus Torvalds irq = intdef & VECTOR; 1691da177e4SLinus Torvalds switch (irq) { 1701da177e4SLinus Torvalds case 9: 1711da177e4SLinus Torvalds case 10: 1721da177e4SLinus Torvalds case 11: 1731da177e4SLinus Torvalds case 12: 1741da177e4SLinus Torvalds case 14: 1751da177e4SLinus Torvalds case 15: 1761da177e4SLinus Torvalds break; 1771da177e4SLinus Torvalds default: 1781da177e4SLinus Torvalds printf("aic7770_config: invalid irq setting %d\n", intdef); 1791da177e4SLinus Torvalds return (ENXIO); 1801da177e4SLinus Torvalds } 1811da177e4SLinus Torvalds 1821da177e4SLinus Torvalds if ((intdef & EDGE_TRIG) != 0) 1831da177e4SLinus Torvalds ahc->flags |= AHC_EDGE_INTERRUPT; 1841da177e4SLinus Torvalds 1851da177e4SLinus Torvalds switch (ahc->chip & (AHC_EISA|AHC_VL)) { 1861da177e4SLinus Torvalds case AHC_EISA: 1871da177e4SLinus Torvalds { 1881da177e4SLinus Torvalds u_int biosctrl; 1891da177e4SLinus Torvalds u_int scsiconf; 1901da177e4SLinus Torvalds u_int scsiconf1; 1911da177e4SLinus Torvalds 1921da177e4SLinus Torvalds biosctrl = ahc_inb(ahc, HA_274_BIOSCTRL); 1931da177e4SLinus Torvalds scsiconf = ahc_inb(ahc, SCSICONF); 1941da177e4SLinus Torvalds scsiconf1 = ahc_inb(ahc, SCSICONF + 1); 1951da177e4SLinus Torvalds 1961da177e4SLinus Torvalds /* Get the primary channel information */ 1971da177e4SLinus Torvalds if ((biosctrl & CHANNEL_B_PRIMARY) != 0) 1981da177e4SLinus Torvalds ahc->flags |= 1; 1991da177e4SLinus Torvalds 2001da177e4SLinus Torvalds if ((biosctrl & BIOSMODE) == BIOSDISABLED) { 2011da177e4SLinus Torvalds ahc->flags |= AHC_USEDEFAULTS; 2021da177e4SLinus Torvalds } else { 2031da177e4SLinus Torvalds if ((ahc->features & AHC_WIDE) != 0) { 2041da177e4SLinus Torvalds ahc->our_id = scsiconf1 & HWSCSIID; 2051da177e4SLinus Torvalds if (scsiconf & TERM_ENB) 2061da177e4SLinus Torvalds ahc->flags |= AHC_TERM_ENB_A; 2071da177e4SLinus Torvalds } else { 2081da177e4SLinus Torvalds ahc->our_id = scsiconf & HSCSIID; 2091da177e4SLinus Torvalds ahc->our_id_b = scsiconf1 & HSCSIID; 2101da177e4SLinus Torvalds if (scsiconf & TERM_ENB) 2111da177e4SLinus Torvalds ahc->flags |= AHC_TERM_ENB_A; 2121da177e4SLinus Torvalds if (scsiconf1 & TERM_ENB) 2131da177e4SLinus Torvalds ahc->flags |= AHC_TERM_ENB_B; 2141da177e4SLinus Torvalds } 2151da177e4SLinus Torvalds } 2161da177e4SLinus Torvalds if ((ahc_inb(ahc, HA_274_BIOSGLOBAL) & HA_274_EXTENDED_TRANS)) 2171da177e4SLinus Torvalds ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B; 2181da177e4SLinus Torvalds break; 2191da177e4SLinus Torvalds } 2201da177e4SLinus Torvalds case AHC_VL: 2211da177e4SLinus Torvalds { 2221da177e4SLinus Torvalds have_seeprom = aha2840_load_seeprom(ahc); 2231da177e4SLinus Torvalds break; 2241da177e4SLinus Torvalds } 2251da177e4SLinus Torvalds default: 2261da177e4SLinus Torvalds break; 2271da177e4SLinus Torvalds } 2281da177e4SLinus Torvalds if (have_seeprom == 0) { 2291da177e4SLinus Torvalds free(ahc->seep_config, M_DEVBUF); 2301da177e4SLinus Torvalds ahc->seep_config = NULL; 2311da177e4SLinus Torvalds } 2321da177e4SLinus Torvalds 2331da177e4SLinus Torvalds /* 2341da177e4SLinus Torvalds * Ensure autoflush is enabled 2351da177e4SLinus Torvalds */ 2361da177e4SLinus Torvalds ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS); 2371da177e4SLinus Torvalds 2381da177e4SLinus Torvalds /* Setup the FIFO threshold and the bus off time */ 2391da177e4SLinus Torvalds hostconf = ahc_inb(ahc, HOSTCONF); 2401da177e4SLinus Torvalds ahc_outb(ahc, BUSSPD, hostconf & DFTHRSH); 2411da177e4SLinus Torvalds ahc_outb(ahc, BUSTIME, (hostconf << 2) & BOFF); 2421da177e4SLinus Torvalds 2431da177e4SLinus Torvalds ahc->bus_softc.aic7770_softc.busspd = hostconf & DFTHRSH; 2441da177e4SLinus Torvalds ahc->bus_softc.aic7770_softc.bustime = (hostconf << 2) & BOFF; 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds /* 2471da177e4SLinus Torvalds * Generic aic7xxx initialization. 2481da177e4SLinus Torvalds */ 2491da177e4SLinus Torvalds error = ahc_init(ahc); 2501da177e4SLinus Torvalds if (error != 0) 2511da177e4SLinus Torvalds return (error); 2521da177e4SLinus Torvalds 2531da177e4SLinus Torvalds error = aic7770_map_int(ahc, irq); 2541da177e4SLinus Torvalds if (error != 0) 2551da177e4SLinus Torvalds return (error); 2561da177e4SLinus Torvalds 2572a40342eSChristoph Hellwig ahc->init_level++; 2581da177e4SLinus Torvalds 2591da177e4SLinus Torvalds /* 2601da177e4SLinus Torvalds * Enable the board's BUS drivers 2611da177e4SLinus Torvalds */ 2621da177e4SLinus Torvalds ahc_outb(ahc, BCTL, ENABLE); 2631da177e4SLinus Torvalds return (0); 2641da177e4SLinus Torvalds } 2651da177e4SLinus Torvalds 2661da177e4SLinus Torvalds static int 2671da177e4SLinus Torvalds aic7770_chip_init(struct ahc_softc *ahc) 2681da177e4SLinus Torvalds { 2691da177e4SLinus Torvalds ahc_outb(ahc, BUSSPD, ahc->bus_softc.aic7770_softc.busspd); 2701da177e4SLinus Torvalds ahc_outb(ahc, BUSTIME, ahc->bus_softc.aic7770_softc.bustime); 2711da177e4SLinus Torvalds ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS); 2721da177e4SLinus Torvalds ahc_outb(ahc, BCTL, ENABLE); 2731da177e4SLinus Torvalds return (ahc_chip_init(ahc)); 2741da177e4SLinus Torvalds } 2751da177e4SLinus Torvalds 2761da177e4SLinus Torvalds static int 2771da177e4SLinus Torvalds aic7770_suspend(struct ahc_softc *ahc) 2781da177e4SLinus Torvalds { 2791da177e4SLinus Torvalds return (ahc_suspend(ahc)); 2801da177e4SLinus Torvalds } 2811da177e4SLinus Torvalds 2821da177e4SLinus Torvalds static int 2831da177e4SLinus Torvalds aic7770_resume(struct ahc_softc *ahc) 2841da177e4SLinus Torvalds { 2851da177e4SLinus Torvalds return (ahc_resume(ahc)); 2861da177e4SLinus Torvalds } 2871da177e4SLinus Torvalds 2881da177e4SLinus Torvalds /* 2891da177e4SLinus Torvalds * Read the 284x SEEPROM. 2901da177e4SLinus Torvalds */ 2911da177e4SLinus Torvalds static int 2921da177e4SLinus Torvalds aha2840_load_seeprom(struct ahc_softc *ahc) 2931da177e4SLinus Torvalds { 2941da177e4SLinus Torvalds struct seeprom_descriptor sd; 2951da177e4SLinus Torvalds struct seeprom_config *sc; 2961da177e4SLinus Torvalds int have_seeprom; 2971da177e4SLinus Torvalds uint8_t scsi_conf; 2981da177e4SLinus Torvalds 2991da177e4SLinus Torvalds sd.sd_ahc = ahc; 3001da177e4SLinus Torvalds sd.sd_control_offset = SEECTL_2840; 3011da177e4SLinus Torvalds sd.sd_status_offset = STATUS_2840; 3021da177e4SLinus Torvalds sd.sd_dataout_offset = STATUS_2840; 3031da177e4SLinus Torvalds sd.sd_chip = C46; 3041da177e4SLinus Torvalds sd.sd_MS = 0; 3051da177e4SLinus Torvalds sd.sd_RDY = EEPROM_TF; 3061da177e4SLinus Torvalds sd.sd_CS = CS_2840; 3071da177e4SLinus Torvalds sd.sd_CK = CK_2840; 3081da177e4SLinus Torvalds sd.sd_DO = DO_2840; 3091da177e4SLinus Torvalds sd.sd_DI = DI_2840; 3101da177e4SLinus Torvalds sc = ahc->seep_config; 3111da177e4SLinus Torvalds 3121da177e4SLinus Torvalds if (bootverbose) 3131da177e4SLinus Torvalds printf("%s: Reading SEEPROM...", ahc_name(ahc)); 3141da177e4SLinus Torvalds have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc, 3151da177e4SLinus Torvalds /*start_addr*/0, sizeof(*sc)/2); 3161da177e4SLinus Torvalds 3171da177e4SLinus Torvalds if (have_seeprom) { 3181da177e4SLinus Torvalds 3191da177e4SLinus Torvalds if (ahc_verify_cksum(sc) == 0) { 3201da177e4SLinus Torvalds if(bootverbose) 3211da177e4SLinus Torvalds printf ("checksum error\n"); 3221da177e4SLinus Torvalds have_seeprom = 0; 3231da177e4SLinus Torvalds } else if (bootverbose) { 3241da177e4SLinus Torvalds printf("done.\n"); 3251da177e4SLinus Torvalds } 3261da177e4SLinus Torvalds } 3271da177e4SLinus Torvalds 3281da177e4SLinus Torvalds if (!have_seeprom) { 3291da177e4SLinus Torvalds if (bootverbose) 3301da177e4SLinus Torvalds printf("%s: No SEEPROM available\n", ahc_name(ahc)); 3311da177e4SLinus Torvalds ahc->flags |= AHC_USEDEFAULTS; 3321da177e4SLinus Torvalds } else { 3331da177e4SLinus Torvalds /* 3341da177e4SLinus Torvalds * Put the data we've collected down into SRAM 3351da177e4SLinus Torvalds * where ahc_init will find it. 3361da177e4SLinus Torvalds */ 3371da177e4SLinus Torvalds int i; 3381da177e4SLinus Torvalds int max_targ; 3391da177e4SLinus Torvalds uint16_t discenable; 3401da177e4SLinus Torvalds 3411da177e4SLinus Torvalds max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8; 3421da177e4SLinus Torvalds discenable = 0; 3431da177e4SLinus Torvalds for (i = 0; i < max_targ; i++){ 3441da177e4SLinus Torvalds uint8_t target_settings; 3451da177e4SLinus Torvalds 3461da177e4SLinus Torvalds target_settings = (sc->device_flags[i] & CFXFER) << 4; 3471da177e4SLinus Torvalds if (sc->device_flags[i] & CFSYNCH) 3481da177e4SLinus Torvalds target_settings |= SOFS; 3491da177e4SLinus Torvalds if (sc->device_flags[i] & CFWIDEB) 3501da177e4SLinus Torvalds target_settings |= WIDEXFER; 3511da177e4SLinus Torvalds if (sc->device_flags[i] & CFDISC) 3521da177e4SLinus Torvalds discenable |= (0x01 << i); 3531da177e4SLinus Torvalds ahc_outb(ahc, TARG_SCSIRATE + i, target_settings); 3541da177e4SLinus Torvalds } 3551da177e4SLinus Torvalds ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff)); 3561da177e4SLinus Torvalds ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff)); 3571da177e4SLinus Torvalds 3581da177e4SLinus Torvalds ahc->our_id = sc->brtime_id & CFSCSIID; 3591da177e4SLinus Torvalds 3601da177e4SLinus Torvalds scsi_conf = (ahc->our_id & 0x7); 3611da177e4SLinus Torvalds if (sc->adapter_control & CFSPARITY) 3621da177e4SLinus Torvalds scsi_conf |= ENSPCHK; 3631da177e4SLinus Torvalds if (sc->adapter_control & CFRESETB) 3641da177e4SLinus Torvalds scsi_conf |= RESET_SCSI; 3651da177e4SLinus Torvalds 3661da177e4SLinus Torvalds if (sc->bios_control & CF284XEXTEND) 3671da177e4SLinus Torvalds ahc->flags |= AHC_EXTENDED_TRANS_A; 3681da177e4SLinus Torvalds /* Set SCSICONF info */ 3691da177e4SLinus Torvalds ahc_outb(ahc, SCSICONF, scsi_conf); 3701da177e4SLinus Torvalds 3711da177e4SLinus Torvalds if (sc->adapter_control & CF284XSTERM) 3721da177e4SLinus Torvalds ahc->flags |= AHC_TERM_ENB_A; 3731da177e4SLinus Torvalds } 3741da177e4SLinus Torvalds return (have_seeprom); 3751da177e4SLinus Torvalds } 3761da177e4SLinus Torvalds 3771da177e4SLinus Torvalds static int 3781da177e4SLinus Torvalds ahc_aic7770_VL_setup(struct ahc_softc *ahc) 3791da177e4SLinus Torvalds { 3801da177e4SLinus Torvalds int error; 3811da177e4SLinus Torvalds 3821da177e4SLinus Torvalds error = ahc_aic7770_setup(ahc); 3831da177e4SLinus Torvalds ahc->chip |= AHC_VL; 3841da177e4SLinus Torvalds return (error); 3851da177e4SLinus Torvalds } 3861da177e4SLinus Torvalds 3871da177e4SLinus Torvalds static int 3881da177e4SLinus Torvalds ahc_aic7770_EISA_setup(struct ahc_softc *ahc) 3891da177e4SLinus Torvalds { 3901da177e4SLinus Torvalds int error; 3911da177e4SLinus Torvalds 3921da177e4SLinus Torvalds error = ahc_aic7770_setup(ahc); 3931da177e4SLinus Torvalds ahc->chip |= AHC_EISA; 3941da177e4SLinus Torvalds return (error); 3951da177e4SLinus Torvalds } 3961da177e4SLinus Torvalds 3971da177e4SLinus Torvalds static int 3981da177e4SLinus Torvalds ahc_aic7770_setup(struct ahc_softc *ahc) 3991da177e4SLinus Torvalds { 4001da177e4SLinus Torvalds ahc->channel = 'A'; 4011da177e4SLinus Torvalds ahc->channel_b = 'B'; 4021da177e4SLinus Torvalds ahc->chip = AHC_AIC7770; 4031da177e4SLinus Torvalds ahc->features = AHC_AIC7770_FE; 4041da177e4SLinus Torvalds ahc->bugs |= AHC_TMODE_WIDEODD_BUG; 4051da177e4SLinus Torvalds ahc->flags |= AHC_PAGESCBS; 4061da177e4SLinus Torvalds ahc->instruction_ram_size = 448; 4071da177e4SLinus Torvalds return (0); 4081da177e4SLinus Torvalds } 409