1098ca2bdSWarner Losh /*- 2717d4247SJustin T. Gibbs * Product specific probe and attach routines for: 3717d4247SJustin T. Gibbs * 27/284X and aic7770 motherboard SCSI controllers 4717d4247SJustin T. Gibbs * 564a3876fSJustin T. Gibbs * Copyright (c) 1994-1998, 2000, 2001 Justin T. Gibbs. 6717d4247SJustin T. Gibbs * All rights reserved. 7717d4247SJustin T. Gibbs * 8717d4247SJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 9717d4247SJustin T. Gibbs * modification, are permitted provided that the following conditions 10717d4247SJustin T. Gibbs * are met: 11717d4247SJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 128f214efcSJustin T. Gibbs * notice, this list of conditions, and the following disclaimer, 138f214efcSJustin T. Gibbs * without modification. 148f214efcSJustin T. Gibbs * 2. Redistributions in binary form must reproduce at minimum a disclaimer 158f214efcSJustin T. Gibbs * substantially similar to the "NO WARRANTY" disclaimer below 168f214efcSJustin T. Gibbs * ("Disclaimer") and any redistribution must be conditioned upon 178f214efcSJustin T. Gibbs * including a substantially similar Disclaimer requirement for further 188f214efcSJustin T. Gibbs * binary redistribution. 198f214efcSJustin T. Gibbs * 3. Neither the names of the above-listed copyright holders nor the names 208f214efcSJustin T. Gibbs * of any contributors may be used to endorse or promote products derived 218f214efcSJustin T. Gibbs * from this software without specific prior written permission. 22717d4247SJustin T. Gibbs * 2364a3876fSJustin T. Gibbs * Alternatively, this software may be distributed under the terms of the 248f214efcSJustin T. Gibbs * GNU General Public License ("GPL") version 2 as published by the Free 258f214efcSJustin T. Gibbs * Software Foundation. 2664a3876fSJustin T. Gibbs * 278f214efcSJustin T. Gibbs * NO WARRANTY 288f214efcSJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 298f214efcSJustin T. Gibbs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 308f214efcSJustin T. Gibbs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 318f214efcSJustin T. Gibbs * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 328f214efcSJustin T. Gibbs * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33717d4247SJustin T. Gibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34717d4247SJustin T. Gibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 358f214efcSJustin T. Gibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 368f214efcSJustin T. Gibbs * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 378f214efcSJustin T. Gibbs * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 388f214efcSJustin T. Gibbs * POSSIBILITY OF SUCH DAMAGES. 39717d4247SJustin T. Gibbs * 40b3b25f2cSJustin T. Gibbs * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#34 $ 41717d4247SJustin T. Gibbs */ 42717d4247SJustin T. Gibbs 438f214efcSJustin T. Gibbs #ifdef __linux__ 448f214efcSJustin T. Gibbs #include "aic7xxx_osm.h" 458f214efcSJustin T. Gibbs #include "aic7xxx_inline.h" 468f214efcSJustin T. Gibbs #include "aic7xxx_93cx6.h" 478f214efcSJustin T. Gibbs #else 48b3b25f2cSJustin T. Gibbs #include <sys/cdefs.h> 49b3b25f2cSJustin T. Gibbs __FBSDID("$FreeBSD$"); 508f214efcSJustin T. Gibbs #include <dev/aic7xxx/aic7xxx_osm.h> 51717d4247SJustin T. Gibbs #include <dev/aic7xxx/aic7xxx_inline.h> 52717d4247SJustin T. Gibbs #include <dev/aic7xxx/aic7xxx_93cx6.h> 538f214efcSJustin T. Gibbs #endif 54717d4247SJustin T. Gibbs 55717d4247SJustin T. Gibbs #define ID_AIC7770 0x04907770 56717d4247SJustin T. Gibbs #define ID_AHA_274x 0x04907771 57717d4247SJustin T. Gibbs #define ID_AHA_284xB 0x04907756 /* BIOS enabled */ 58717d4247SJustin T. Gibbs #define ID_AHA_284x 0x04907757 /* BIOS disabled*/ 59b8e89ffaSScott Long #define ID_OLV_274x 0x04907782 /* Olivetti OEM */ 60b8e89ffaSScott Long #define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */ 61717d4247SJustin T. Gibbs 629bf327a7SJustin T. Gibbs static int aic7770_chip_init(struct ahc_softc *ahc); 639bf327a7SJustin T. Gibbs static int aic7770_suspend(struct ahc_softc *ahc); 649bf327a7SJustin T. Gibbs static int aic7770_resume(struct ahc_softc *ahc); 65b73b70ccSJustin T. Gibbs static int aha2840_load_seeprom(struct ahc_softc *ahc); 66717d4247SJustin T. Gibbs static ahc_device_setup_t ahc_aic7770_VL_setup; 67*a4e4cebfSWarner Losh static ahc_device_setup_t ahc_aic7770_EISA_setup; /* Really just ISA */ 68717d4247SJustin T. Gibbs static ahc_device_setup_t ahc_aic7770_setup; 69717d4247SJustin T. Gibbs 70717d4247SJustin T. Gibbs struct aic7770_identity aic7770_ident_table[] = 71717d4247SJustin T. Gibbs { 72717d4247SJustin T. Gibbs { 73717d4247SJustin T. Gibbs ID_AHA_274x, 74717d4247SJustin T. Gibbs 0xFFFFFFFF, 75717d4247SJustin T. Gibbs "Adaptec 274X SCSI adapter", 76717d4247SJustin T. Gibbs ahc_aic7770_EISA_setup 77717d4247SJustin T. Gibbs }, 78717d4247SJustin T. Gibbs { 79717d4247SJustin T. Gibbs ID_AHA_284xB, 80717d4247SJustin T. Gibbs 0xFFFFFFFE, 81717d4247SJustin T. Gibbs "Adaptec 284X SCSI adapter", 82717d4247SJustin T. Gibbs ahc_aic7770_VL_setup 83717d4247SJustin T. Gibbs }, 84b8e89ffaSScott Long { 8544744947SJustin T. Gibbs ID_AHA_284x, 8644744947SJustin T. Gibbs 0xFFFFFFFE, 8744744947SJustin T. Gibbs "Adaptec 284X SCSI adapter (BIOS Disabled)", 8844744947SJustin T. Gibbs ahc_aic7770_VL_setup 8944744947SJustin T. Gibbs }, 9044744947SJustin T. Gibbs { 91b8e89ffaSScott Long ID_OLV_274x, 92b8e89ffaSScott Long 0xFFFFFFFF, 93b8e89ffaSScott Long "Adaptec (Olivetti OEM) 274X SCSI adapter", 94b8e89ffaSScott Long ahc_aic7770_EISA_setup 95b8e89ffaSScott Long }, 96b8e89ffaSScott Long { 97b8e89ffaSScott Long ID_OLV_274xD, 98b8e89ffaSScott Long 0xFFFFFFFF, 99b8e89ffaSScott Long "Adaptec (Olivetti OEM) 274X Differential SCSI adapter", 100b8e89ffaSScott Long ahc_aic7770_EISA_setup 101b8e89ffaSScott Long }, 102717d4247SJustin T. Gibbs /* Generic chip probes for devices we don't know 'exactly' */ 103717d4247SJustin T. Gibbs { 104717d4247SJustin T. Gibbs ID_AIC7770, 105717d4247SJustin T. Gibbs 0xFFFFFFFF, 106717d4247SJustin T. Gibbs "Adaptec aic7770 SCSI adapter", 107717d4247SJustin T. Gibbs ahc_aic7770_EISA_setup 108717d4247SJustin T. Gibbs } 109717d4247SJustin T. Gibbs }; 110717d4247SJustin T. Gibbs const int ahc_num_aic7770_devs = NUM_ELEMENTS(aic7770_ident_table); 111717d4247SJustin T. Gibbs 112717d4247SJustin T. Gibbs struct aic7770_identity * 113717d4247SJustin T. Gibbs aic7770_find_device(uint32_t id) 114717d4247SJustin T. Gibbs { 115717d4247SJustin T. Gibbs struct aic7770_identity *entry; 116717d4247SJustin T. Gibbs int i; 117717d4247SJustin T. Gibbs 118717d4247SJustin T. Gibbs for (i = 0; i < ahc_num_aic7770_devs; i++) { 119717d4247SJustin T. Gibbs entry = &aic7770_ident_table[i]; 120717d4247SJustin T. Gibbs if (entry->full_id == (id & entry->id_mask)) 121717d4247SJustin T. Gibbs return (entry); 122717d4247SJustin T. Gibbs } 123717d4247SJustin T. Gibbs return (NULL); 124717d4247SJustin T. Gibbs } 125717d4247SJustin T. Gibbs 126717d4247SJustin T. Gibbs int 1278f214efcSJustin T. Gibbs aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) 128717d4247SJustin T. Gibbs { 129717d4247SJustin T. Gibbs int error; 130b73b70ccSJustin T. Gibbs int have_seeprom; 131717d4247SJustin T. Gibbs u_int hostconf; 1326fb77fefSJustin T. Gibbs u_int irq; 1336fb77fefSJustin T. Gibbs u_int intdef; 134717d4247SJustin T. Gibbs 135cd036e89SJustin T. Gibbs error = entry->setup(ahc); 136b73b70ccSJustin T. Gibbs have_seeprom = 0; 137717d4247SJustin T. Gibbs if (error != 0) 138717d4247SJustin T. Gibbs return (error); 139717d4247SJustin T. Gibbs 1408f214efcSJustin T. Gibbs error = aic7770_map_registers(ahc, io); 141717d4247SJustin T. Gibbs if (error != 0) 142717d4247SJustin T. Gibbs return (error); 143717d4247SJustin T. Gibbs 1448f214efcSJustin T. Gibbs /* 1458f214efcSJustin T. Gibbs * Before we continue probing the card, ensure that 1468f214efcSJustin T. Gibbs * its interrupts are *disabled*. We don't want 1478f214efcSJustin T. Gibbs * a misstep to hang the machine in an interrupt 1488f214efcSJustin T. Gibbs * storm. 1498f214efcSJustin T. Gibbs */ 1508f214efcSJustin T. Gibbs ahc_intr_enable(ahc, FALSE); 1518f214efcSJustin T. Gibbs 152cd036e89SJustin T. Gibbs ahc->description = entry->name; 153cd036e89SJustin T. Gibbs error = ahc_softc_init(ahc); 1549bf327a7SJustin T. Gibbs if (error != 0) 1559bf327a7SJustin T. Gibbs return (error); 1569bf327a7SJustin T. Gibbs 1579bf327a7SJustin T. Gibbs ahc->bus_chip_init = aic7770_chip_init; 1589bf327a7SJustin T. Gibbs ahc->bus_suspend = aic7770_suspend; 1599bf327a7SJustin T. Gibbs ahc->bus_resume = aic7770_resume; 160717d4247SJustin T. Gibbs 1611d528d67SJustin T. Gibbs error = ahc_reset(ahc, /*reinit*/FALSE); 162717d4247SJustin T. Gibbs if (error != 0) 163717d4247SJustin T. Gibbs return (error); 164717d4247SJustin T. Gibbs 1656fb77fefSJustin T. Gibbs /* Make sure we have a valid interrupt vector */ 1666fb77fefSJustin T. Gibbs intdef = ahc_inb(ahc, INTDEF); 1676fb77fefSJustin T. Gibbs irq = intdef & VECTOR; 1686fb77fefSJustin T. Gibbs switch (irq) { 1696fb77fefSJustin T. Gibbs case 9: 1706fb77fefSJustin T. Gibbs case 10: 1716fb77fefSJustin T. Gibbs case 11: 1726fb77fefSJustin T. Gibbs case 12: 1736fb77fefSJustin T. Gibbs case 14: 1746fb77fefSJustin T. Gibbs case 15: 1756fb77fefSJustin T. Gibbs break; 1766fb77fefSJustin T. Gibbs default: 177b3b25f2cSJustin T. Gibbs printf("aic7770_config: invalid irq setting %d\n", intdef); 1786fb77fefSJustin T. Gibbs return (ENXIO); 1796fb77fefSJustin T. Gibbs } 1806fb77fefSJustin T. Gibbs 1816fb77fefSJustin T. Gibbs if ((intdef & EDGE_TRIG) != 0) 1826fb77fefSJustin T. Gibbs ahc->flags |= AHC_EDGE_INTERRUPT; 1836fb77fefSJustin T. Gibbs 184cd036e89SJustin T. Gibbs switch (ahc->chip & (AHC_EISA|AHC_VL)) { 185717d4247SJustin T. Gibbs case AHC_EISA: 186717d4247SJustin T. Gibbs { 187717d4247SJustin T. Gibbs u_int biosctrl; 188717d4247SJustin T. Gibbs u_int scsiconf; 189717d4247SJustin T. Gibbs u_int scsiconf1; 190717d4247SJustin T. Gibbs 191717d4247SJustin T. Gibbs biosctrl = ahc_inb(ahc, HA_274_BIOSCTRL); 192717d4247SJustin T. Gibbs scsiconf = ahc_inb(ahc, SCSICONF); 193717d4247SJustin T. Gibbs scsiconf1 = ahc_inb(ahc, SCSICONF + 1); 194717d4247SJustin T. Gibbs 195717d4247SJustin T. Gibbs /* Get the primary channel information */ 196717d4247SJustin T. Gibbs if ((biosctrl & CHANNEL_B_PRIMARY) != 0) 1976fb77fefSJustin T. Gibbs ahc->flags |= 1; 198717d4247SJustin T. Gibbs 199717d4247SJustin T. Gibbs if ((biosctrl & BIOSMODE) == BIOSDISABLED) { 200717d4247SJustin T. Gibbs ahc->flags |= AHC_USEDEFAULTS; 201717d4247SJustin T. Gibbs } else { 202717d4247SJustin T. Gibbs if ((ahc->features & AHC_WIDE) != 0) { 203717d4247SJustin T. Gibbs ahc->our_id = scsiconf1 & HWSCSIID; 204717d4247SJustin T. Gibbs if (scsiconf & TERM_ENB) 205717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_A; 206717d4247SJustin T. Gibbs } else { 207717d4247SJustin T. Gibbs ahc->our_id = scsiconf & HSCSIID; 208717d4247SJustin T. Gibbs ahc->our_id_b = scsiconf1 & HSCSIID; 209717d4247SJustin T. Gibbs if (scsiconf & TERM_ENB) 210717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_A; 211717d4247SJustin T. Gibbs if (scsiconf1 & TERM_ENB) 212717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_B; 213717d4247SJustin T. Gibbs } 214717d4247SJustin T. Gibbs } 215b73b70ccSJustin T. Gibbs if ((ahc_inb(ahc, HA_274_BIOSGLOBAL) & HA_274_EXTENDED_TRANS)) 216717d4247SJustin T. Gibbs ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B; 217717d4247SJustin T. Gibbs break; 218717d4247SJustin T. Gibbs } 219717d4247SJustin T. Gibbs case AHC_VL: 220717d4247SJustin T. Gibbs { 221b73b70ccSJustin T. Gibbs have_seeprom = aha2840_load_seeprom(ahc); 222717d4247SJustin T. Gibbs break; 223717d4247SJustin T. Gibbs } 224717d4247SJustin T. Gibbs default: 225717d4247SJustin T. Gibbs break; 226717d4247SJustin T. Gibbs } 227b73b70ccSJustin T. Gibbs if (have_seeprom == 0) { 228b73b70ccSJustin T. Gibbs free(ahc->seep_config, M_DEVBUF); 229b73b70ccSJustin T. Gibbs ahc->seep_config = NULL; 230b73b70ccSJustin T. Gibbs } 231717d4247SJustin T. Gibbs 232717d4247SJustin T. Gibbs /* 233717d4247SJustin T. Gibbs * Ensure autoflush is enabled 234717d4247SJustin T. Gibbs */ 235717d4247SJustin T. Gibbs ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS); 236717d4247SJustin T. Gibbs 237717d4247SJustin T. Gibbs /* Setup the FIFO threshold and the bus off time */ 238717d4247SJustin T. Gibbs hostconf = ahc_inb(ahc, HOSTCONF); 239717d4247SJustin T. Gibbs ahc_outb(ahc, BUSSPD, hostconf & DFTHRSH); 240717d4247SJustin T. Gibbs ahc_outb(ahc, BUSTIME, (hostconf << 2) & BOFF); 241717d4247SJustin T. Gibbs 2429bf327a7SJustin T. Gibbs ahc->bus_softc.aic7770_softc.busspd = hostconf & DFTHRSH; 2439bf327a7SJustin T. Gibbs ahc->bus_softc.aic7770_softc.bustime = (hostconf << 2) & BOFF; 2449bf327a7SJustin T. Gibbs 245717d4247SJustin T. Gibbs /* 246717d4247SJustin T. Gibbs * Generic aic7xxx initialization. 247717d4247SJustin T. Gibbs */ 248717d4247SJustin T. Gibbs error = ahc_init(ahc); 249717d4247SJustin T. Gibbs if (error != 0) 250717d4247SJustin T. Gibbs return (error); 251717d4247SJustin T. Gibbs 252b73b70ccSJustin T. Gibbs error = aic7770_map_int(ahc, irq); 253b73b70ccSJustin T. Gibbs if (error != 0) 254b73b70ccSJustin T. Gibbs return (error); 255b73b70ccSJustin T. Gibbs 256032b0a17SScott Long ahc_lock(ahc); 257717d4247SJustin T. Gibbs /* 258a5847d5cSJustin T. Gibbs * Link this softc in with all other ahc instances. 259a5847d5cSJustin T. Gibbs */ 260a5847d5cSJustin T. Gibbs ahc_softc_insert(ahc); 261a5847d5cSJustin T. Gibbs 262a5847d5cSJustin T. Gibbs /* 263717d4247SJustin T. Gibbs * Enable the board's BUS drivers 264717d4247SJustin T. Gibbs */ 265717d4247SJustin T. Gibbs ahc_outb(ahc, BCTL, ENABLE); 266717d4247SJustin T. Gibbs 267032b0a17SScott Long ahc_unlock(ahc); 268b95de6daSJustin T. Gibbs 269717d4247SJustin T. Gibbs return (0); 270717d4247SJustin T. Gibbs } 271717d4247SJustin T. Gibbs 2729bf327a7SJustin T. Gibbs static int 2739bf327a7SJustin T. Gibbs aic7770_chip_init(struct ahc_softc *ahc) 2749bf327a7SJustin T. Gibbs { 2759bf327a7SJustin T. Gibbs ahc_outb(ahc, BUSSPD, ahc->bus_softc.aic7770_softc.busspd); 2769bf327a7SJustin T. Gibbs ahc_outb(ahc, BUSTIME, ahc->bus_softc.aic7770_softc.bustime); 2779bf327a7SJustin T. Gibbs ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS); 2789bf327a7SJustin T. Gibbs ahc_outb(ahc, BCTL, ENABLE); 2799bf327a7SJustin T. Gibbs return (ahc_chip_init(ahc)); 2809bf327a7SJustin T. Gibbs } 2819bf327a7SJustin T. Gibbs 2829bf327a7SJustin T. Gibbs static int 2839bf327a7SJustin T. Gibbs aic7770_suspend(struct ahc_softc *ahc) 2849bf327a7SJustin T. Gibbs { 2859bf327a7SJustin T. Gibbs return (ahc_suspend(ahc)); 2869bf327a7SJustin T. Gibbs } 2879bf327a7SJustin T. Gibbs 2889bf327a7SJustin T. Gibbs static int 2899bf327a7SJustin T. Gibbs aic7770_resume(struct ahc_softc *ahc) 2909bf327a7SJustin T. Gibbs { 2919bf327a7SJustin T. Gibbs return (ahc_resume(ahc)); 2929bf327a7SJustin T. Gibbs } 2939bf327a7SJustin T. Gibbs 294717d4247SJustin T. Gibbs /* 295717d4247SJustin T. Gibbs * Read the 284x SEEPROM. 296717d4247SJustin T. Gibbs */ 297b73b70ccSJustin T. Gibbs static int 298717d4247SJustin T. Gibbs aha2840_load_seeprom(struct ahc_softc *ahc) 299717d4247SJustin T. Gibbs { 300717d4247SJustin T. Gibbs struct seeprom_descriptor sd; 301b73b70ccSJustin T. Gibbs struct seeprom_config *sc; 302717d4247SJustin T. Gibbs int have_seeprom; 303b73b70ccSJustin T. Gibbs uint8_t scsi_conf; 304717d4247SJustin T. Gibbs 305717d4247SJustin T. Gibbs sd.sd_ahc = ahc; 306717d4247SJustin T. Gibbs sd.sd_control_offset = SEECTL_2840; 307717d4247SJustin T. Gibbs sd.sd_status_offset = STATUS_2840; 308717d4247SJustin T. Gibbs sd.sd_dataout_offset = STATUS_2840; 309717d4247SJustin T. Gibbs sd.sd_chip = C46; 310717d4247SJustin T. Gibbs sd.sd_MS = 0; 311717d4247SJustin T. Gibbs sd.sd_RDY = EEPROM_TF; 312717d4247SJustin T. Gibbs sd.sd_CS = CS_2840; 313717d4247SJustin T. Gibbs sd.sd_CK = CK_2840; 314717d4247SJustin T. Gibbs sd.sd_DO = DO_2840; 315717d4247SJustin T. Gibbs sd.sd_DI = DI_2840; 316b73b70ccSJustin T. Gibbs sc = ahc->seep_config; 317717d4247SJustin T. Gibbs 318717d4247SJustin T. Gibbs if (bootverbose) 319717d4247SJustin T. Gibbs printf("%s: Reading SEEPROM...", ahc_name(ahc)); 320655a5ce4SJustin T. Gibbs have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc, 3219bf327a7SJustin T. Gibbs /*start_addr*/0, sizeof(*sc)/2); 322717d4247SJustin T. Gibbs 323717d4247SJustin T. Gibbs if (have_seeprom) { 324717d4247SJustin T. Gibbs 325b73b70ccSJustin T. Gibbs if (ahc_verify_cksum(sc) == 0) { 326717d4247SJustin T. Gibbs if(bootverbose) 327717d4247SJustin T. Gibbs printf ("checksum error\n"); 328717d4247SJustin T. Gibbs have_seeprom = 0; 329717d4247SJustin T. Gibbs } else if (bootverbose) { 330717d4247SJustin T. Gibbs printf("done.\n"); 331717d4247SJustin T. Gibbs } 332717d4247SJustin T. Gibbs } 333717d4247SJustin T. Gibbs 334717d4247SJustin T. Gibbs if (!have_seeprom) { 335717d4247SJustin T. Gibbs if (bootverbose) 336717d4247SJustin T. Gibbs printf("%s: No SEEPROM available\n", ahc_name(ahc)); 337717d4247SJustin T. Gibbs ahc->flags |= AHC_USEDEFAULTS; 338717d4247SJustin T. Gibbs } else { 339717d4247SJustin T. Gibbs /* 340717d4247SJustin T. Gibbs * Put the data we've collected down into SRAM 341717d4247SJustin T. Gibbs * where ahc_init will find it. 342717d4247SJustin T. Gibbs */ 343717d4247SJustin T. Gibbs int i; 344b73b70ccSJustin T. Gibbs int max_targ; 345717d4247SJustin T. Gibbs uint16_t discenable; 346717d4247SJustin T. Gibbs 347b73b70ccSJustin T. Gibbs max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8; 348717d4247SJustin T. Gibbs discenable = 0; 349717d4247SJustin T. Gibbs for (i = 0; i < max_targ; i++){ 350717d4247SJustin T. Gibbs uint8_t target_settings; 351b73b70ccSJustin T. Gibbs 352b73b70ccSJustin T. Gibbs target_settings = (sc->device_flags[i] & CFXFER) << 4; 353b73b70ccSJustin T. Gibbs if (sc->device_flags[i] & CFSYNCH) 354717d4247SJustin T. Gibbs target_settings |= SOFS; 355b73b70ccSJustin T. Gibbs if (sc->device_flags[i] & CFWIDEB) 356717d4247SJustin T. Gibbs target_settings |= WIDEXFER; 357b73b70ccSJustin T. Gibbs if (sc->device_flags[i] & CFDISC) 358717d4247SJustin T. Gibbs discenable |= (0x01 << i); 359717d4247SJustin T. Gibbs ahc_outb(ahc, TARG_SCSIRATE + i, target_settings); 360717d4247SJustin T. Gibbs } 361717d4247SJustin T. Gibbs ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff)); 362717d4247SJustin T. Gibbs ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff)); 363717d4247SJustin T. Gibbs 364b73b70ccSJustin T. Gibbs ahc->our_id = sc->brtime_id & CFSCSIID; 365717d4247SJustin T. Gibbs 366717d4247SJustin T. Gibbs scsi_conf = (ahc->our_id & 0x7); 367b73b70ccSJustin T. Gibbs if (sc->adapter_control & CFSPARITY) 368717d4247SJustin T. Gibbs scsi_conf |= ENSPCHK; 369b73b70ccSJustin T. Gibbs if (sc->adapter_control & CFRESETB) 370717d4247SJustin T. Gibbs scsi_conf |= RESET_SCSI; 371717d4247SJustin T. Gibbs 372b73b70ccSJustin T. Gibbs if (sc->bios_control & CF284XEXTEND) 373717d4247SJustin T. Gibbs ahc->flags |= AHC_EXTENDED_TRANS_A; 374717d4247SJustin T. Gibbs /* Set SCSICONF info */ 375717d4247SJustin T. Gibbs ahc_outb(ahc, SCSICONF, scsi_conf); 376717d4247SJustin T. Gibbs 377b73b70ccSJustin T. Gibbs if (sc->adapter_control & CF284XSTERM) 378717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_A; 379717d4247SJustin T. Gibbs } 380b73b70ccSJustin T. Gibbs return (have_seeprom); 381717d4247SJustin T. Gibbs } 382717d4247SJustin T. Gibbs 383717d4247SJustin T. Gibbs static int 384cd036e89SJustin T. Gibbs ahc_aic7770_VL_setup(struct ahc_softc *ahc) 385717d4247SJustin T. Gibbs { 386717d4247SJustin T. Gibbs int error; 387717d4247SJustin T. Gibbs 388cd036e89SJustin T. Gibbs error = ahc_aic7770_setup(ahc); 389cd036e89SJustin T. Gibbs ahc->chip |= AHC_VL; 390717d4247SJustin T. Gibbs return (error); 391717d4247SJustin T. Gibbs } 392717d4247SJustin T. Gibbs 393717d4247SJustin T. Gibbs static int 394cd036e89SJustin T. Gibbs ahc_aic7770_EISA_setup(struct ahc_softc *ahc) 395717d4247SJustin T. Gibbs { 396717d4247SJustin T. Gibbs int error; 397717d4247SJustin T. Gibbs 398cd036e89SJustin T. Gibbs error = ahc_aic7770_setup(ahc); 399cd036e89SJustin T. Gibbs ahc->chip |= AHC_EISA; 400717d4247SJustin T. Gibbs return (error); 401717d4247SJustin T. Gibbs } 402717d4247SJustin T. Gibbs 403717d4247SJustin T. Gibbs static int 404cd036e89SJustin T. Gibbs ahc_aic7770_setup(struct ahc_softc *ahc) 405717d4247SJustin T. Gibbs { 406cd036e89SJustin T. Gibbs ahc->channel = 'A'; 407cd036e89SJustin T. Gibbs ahc->channel_b = 'B'; 408cd036e89SJustin T. Gibbs ahc->chip = AHC_AIC7770; 409cd036e89SJustin T. Gibbs ahc->features = AHC_AIC7770_FE; 410cd036e89SJustin T. Gibbs ahc->bugs |= AHC_TMODE_WIDEODD_BUG; 411cd036e89SJustin T. Gibbs ahc->flags |= AHC_PAGESCBS; 4129bf327a7SJustin T. Gibbs ahc->instruction_ram_size = 448; 413717d4247SJustin T. Gibbs return (0); 414717d4247SJustin T. Gibbs } 415