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 * 5*718cf2ccSPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 6*718cf2ccSPedro F. Giffuni * 764a3876fSJustin T. Gibbs * Copyright (c) 1994-1998, 2000, 2001 Justin T. Gibbs. 8717d4247SJustin T. Gibbs * All rights reserved. 9717d4247SJustin T. Gibbs * 10717d4247SJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 11717d4247SJustin T. Gibbs * modification, are permitted provided that the following conditions 12717d4247SJustin T. Gibbs * are met: 13717d4247SJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 148f214efcSJustin T. Gibbs * notice, this list of conditions, and the following disclaimer, 158f214efcSJustin T. Gibbs * without modification. 168f214efcSJustin T. Gibbs * 2. Redistributions in binary form must reproduce at minimum a disclaimer 178f214efcSJustin T. Gibbs * substantially similar to the "NO WARRANTY" disclaimer below 188f214efcSJustin T. Gibbs * ("Disclaimer") and any redistribution must be conditioned upon 198f214efcSJustin T. Gibbs * including a substantially similar Disclaimer requirement for further 208f214efcSJustin T. Gibbs * binary redistribution. 218f214efcSJustin T. Gibbs * 3. Neither the names of the above-listed copyright holders nor the names 228f214efcSJustin T. Gibbs * of any contributors may be used to endorse or promote products derived 238f214efcSJustin T. Gibbs * from this software without specific prior written permission. 24717d4247SJustin T. Gibbs * 2564a3876fSJustin T. Gibbs * Alternatively, this software may be distributed under the terms of the 268f214efcSJustin T. Gibbs * GNU General Public License ("GPL") version 2 as published by the Free 278f214efcSJustin T. Gibbs * Software Foundation. 2864a3876fSJustin T. Gibbs * 298f214efcSJustin T. Gibbs * NO WARRANTY 308f214efcSJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 318f214efcSJustin T. Gibbs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 328f214efcSJustin T. Gibbs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 338f214efcSJustin T. Gibbs * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 348f214efcSJustin T. Gibbs * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35717d4247SJustin T. Gibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36717d4247SJustin T. Gibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 378f214efcSJustin T. Gibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 388f214efcSJustin T. Gibbs * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 398f214efcSJustin T. Gibbs * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 408f214efcSJustin T. Gibbs * POSSIBILITY OF SUCH DAMAGES. 41717d4247SJustin T. Gibbs * 42b3b25f2cSJustin T. Gibbs * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#34 $ 43717d4247SJustin T. Gibbs */ 44717d4247SJustin T. Gibbs 458f214efcSJustin T. Gibbs #include <dev/aic7xxx/aic7xxx_osm.h> 46717d4247SJustin T. Gibbs #include <dev/aic7xxx/aic7xxx_inline.h> 47717d4247SJustin T. Gibbs #include <dev/aic7xxx/aic7xxx_93cx6.h> 48717d4247SJustin T. Gibbs 49717d4247SJustin T. Gibbs #define ID_AIC7770 0x04907770 50717d4247SJustin T. Gibbs #define ID_AHA_274x 0x04907771 51717d4247SJustin T. Gibbs #define ID_AHA_284xB 0x04907756 /* BIOS enabled */ 52717d4247SJustin T. Gibbs #define ID_AHA_284x 0x04907757 /* BIOS disabled*/ 53b8e89ffaSScott Long #define ID_OLV_274x 0x04907782 /* Olivetti OEM */ 54b8e89ffaSScott Long #define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */ 55717d4247SJustin T. Gibbs 569bf327a7SJustin T. Gibbs static int aic7770_chip_init(struct ahc_softc *ahc); 579bf327a7SJustin T. Gibbs static int aic7770_suspend(struct ahc_softc *ahc); 589bf327a7SJustin T. Gibbs static int aic7770_resume(struct ahc_softc *ahc); 59b73b70ccSJustin T. Gibbs static int aha2840_load_seeprom(struct ahc_softc *ahc); 60717d4247SJustin T. Gibbs static ahc_device_setup_t ahc_aic7770_VL_setup; 61a4e4cebfSWarner Losh static ahc_device_setup_t ahc_aic7770_EISA_setup; /* Really just ISA */ 62717d4247SJustin T. Gibbs static ahc_device_setup_t ahc_aic7770_setup; 63717d4247SJustin T. Gibbs 64717d4247SJustin T. Gibbs struct aic7770_identity aic7770_ident_table[] = 65717d4247SJustin T. Gibbs { 66717d4247SJustin T. Gibbs { 67717d4247SJustin T. Gibbs ID_AHA_274x, 68717d4247SJustin T. Gibbs 0xFFFFFFFF, 69717d4247SJustin T. Gibbs "Adaptec 274X SCSI adapter", 70717d4247SJustin T. Gibbs ahc_aic7770_EISA_setup 71717d4247SJustin T. Gibbs }, 72717d4247SJustin T. Gibbs { 73717d4247SJustin T. Gibbs ID_AHA_284xB, 74717d4247SJustin T. Gibbs 0xFFFFFFFE, 75717d4247SJustin T. Gibbs "Adaptec 284X SCSI adapter", 76717d4247SJustin T. Gibbs ahc_aic7770_VL_setup 77717d4247SJustin T. Gibbs }, 78b8e89ffaSScott Long { 7944744947SJustin T. Gibbs ID_AHA_284x, 8044744947SJustin T. Gibbs 0xFFFFFFFE, 8144744947SJustin T. Gibbs "Adaptec 284X SCSI adapter (BIOS Disabled)", 8244744947SJustin T. Gibbs ahc_aic7770_VL_setup 8344744947SJustin T. Gibbs }, 8444744947SJustin T. Gibbs { 85b8e89ffaSScott Long ID_OLV_274x, 86b8e89ffaSScott Long 0xFFFFFFFF, 87b8e89ffaSScott Long "Adaptec (Olivetti OEM) 274X SCSI adapter", 88b8e89ffaSScott Long ahc_aic7770_EISA_setup 89b8e89ffaSScott Long }, 90b8e89ffaSScott Long { 91b8e89ffaSScott Long ID_OLV_274xD, 92b8e89ffaSScott Long 0xFFFFFFFF, 93b8e89ffaSScott Long "Adaptec (Olivetti OEM) 274X Differential SCSI adapter", 94b8e89ffaSScott Long ahc_aic7770_EISA_setup 95b8e89ffaSScott Long }, 96717d4247SJustin T. Gibbs /* Generic chip probes for devices we don't know 'exactly' */ 97717d4247SJustin T. Gibbs { 98717d4247SJustin T. Gibbs ID_AIC7770, 99717d4247SJustin T. Gibbs 0xFFFFFFFF, 100717d4247SJustin T. Gibbs "Adaptec aic7770 SCSI adapter", 101717d4247SJustin T. Gibbs ahc_aic7770_EISA_setup 102717d4247SJustin T. Gibbs } 103717d4247SJustin T. Gibbs }; 104717d4247SJustin T. Gibbs const int ahc_num_aic7770_devs = NUM_ELEMENTS(aic7770_ident_table); 105717d4247SJustin T. Gibbs 106717d4247SJustin T. Gibbs struct aic7770_identity * 107717d4247SJustin T. Gibbs aic7770_find_device(uint32_t id) 108717d4247SJustin T. Gibbs { 109717d4247SJustin T. Gibbs struct aic7770_identity *entry; 110717d4247SJustin T. Gibbs int i; 111717d4247SJustin T. Gibbs 112717d4247SJustin T. Gibbs for (i = 0; i < ahc_num_aic7770_devs; i++) { 113717d4247SJustin T. Gibbs entry = &aic7770_ident_table[i]; 114717d4247SJustin T. Gibbs if (entry->full_id == (id & entry->id_mask)) 115717d4247SJustin T. Gibbs return (entry); 116717d4247SJustin T. Gibbs } 117717d4247SJustin T. Gibbs return (NULL); 118717d4247SJustin T. Gibbs } 119717d4247SJustin T. Gibbs 120717d4247SJustin T. Gibbs int 1218f214efcSJustin T. Gibbs aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) 122717d4247SJustin T. Gibbs { 123717d4247SJustin T. Gibbs int error; 124b73b70ccSJustin T. Gibbs int have_seeprom; 125717d4247SJustin T. Gibbs u_int hostconf; 1266fb77fefSJustin T. Gibbs u_int irq; 1276fb77fefSJustin T. Gibbs u_int intdef; 128717d4247SJustin T. Gibbs 129cd036e89SJustin T. Gibbs error = entry->setup(ahc); 130b73b70ccSJustin T. Gibbs have_seeprom = 0; 131717d4247SJustin T. Gibbs if (error != 0) 132717d4247SJustin T. Gibbs return (error); 133717d4247SJustin T. Gibbs 1348f214efcSJustin T. Gibbs error = aic7770_map_registers(ahc, io); 135717d4247SJustin T. Gibbs if (error != 0) 136717d4247SJustin T. Gibbs return (error); 137717d4247SJustin T. Gibbs 1388f214efcSJustin T. Gibbs /* 1398f214efcSJustin T. Gibbs * Before we continue probing the card, ensure that 1408f214efcSJustin T. Gibbs * its interrupts are *disabled*. We don't want 1418f214efcSJustin T. Gibbs * a misstep to hang the machine in an interrupt 1428f214efcSJustin T. Gibbs * storm. 1438f214efcSJustin T. Gibbs */ 1448f214efcSJustin T. Gibbs ahc_intr_enable(ahc, FALSE); 1458f214efcSJustin T. Gibbs 146cd036e89SJustin T. Gibbs ahc->description = entry->name; 147cd036e89SJustin T. Gibbs error = ahc_softc_init(ahc); 1489bf327a7SJustin T. Gibbs if (error != 0) 1499bf327a7SJustin T. Gibbs return (error); 1509bf327a7SJustin T. Gibbs 1519bf327a7SJustin T. Gibbs ahc->bus_chip_init = aic7770_chip_init; 1529bf327a7SJustin T. Gibbs ahc->bus_suspend = aic7770_suspend; 1539bf327a7SJustin T. Gibbs ahc->bus_resume = aic7770_resume; 154717d4247SJustin T. Gibbs 1551d528d67SJustin T. Gibbs error = ahc_reset(ahc, /*reinit*/FALSE); 156717d4247SJustin T. Gibbs if (error != 0) 157717d4247SJustin T. Gibbs return (error); 158717d4247SJustin T. Gibbs 1596fb77fefSJustin T. Gibbs /* Make sure we have a valid interrupt vector */ 1606fb77fefSJustin T. Gibbs intdef = ahc_inb(ahc, INTDEF); 1616fb77fefSJustin T. Gibbs irq = intdef & VECTOR; 1626fb77fefSJustin T. Gibbs switch (irq) { 1636fb77fefSJustin T. Gibbs case 9: 1646fb77fefSJustin T. Gibbs case 10: 1656fb77fefSJustin T. Gibbs case 11: 1666fb77fefSJustin T. Gibbs case 12: 1676fb77fefSJustin T. Gibbs case 14: 1686fb77fefSJustin T. Gibbs case 15: 1696fb77fefSJustin T. Gibbs break; 1706fb77fefSJustin T. Gibbs default: 171b3b25f2cSJustin T. Gibbs printf("aic7770_config: invalid irq setting %d\n", intdef); 1726fb77fefSJustin T. Gibbs return (ENXIO); 1736fb77fefSJustin T. Gibbs } 1746fb77fefSJustin T. Gibbs 1756fb77fefSJustin T. Gibbs if ((intdef & EDGE_TRIG) != 0) 1766fb77fefSJustin T. Gibbs ahc->flags |= AHC_EDGE_INTERRUPT; 1776fb77fefSJustin T. Gibbs 178cd036e89SJustin T. Gibbs switch (ahc->chip & (AHC_EISA|AHC_VL)) { 179717d4247SJustin T. Gibbs case AHC_EISA: 180717d4247SJustin T. Gibbs { 181717d4247SJustin T. Gibbs u_int biosctrl; 182717d4247SJustin T. Gibbs u_int scsiconf; 183717d4247SJustin T. Gibbs u_int scsiconf1; 184717d4247SJustin T. Gibbs 185717d4247SJustin T. Gibbs biosctrl = ahc_inb(ahc, HA_274_BIOSCTRL); 186717d4247SJustin T. Gibbs scsiconf = ahc_inb(ahc, SCSICONF); 187717d4247SJustin T. Gibbs scsiconf1 = ahc_inb(ahc, SCSICONF + 1); 188717d4247SJustin T. Gibbs 189717d4247SJustin T. Gibbs /* Get the primary channel information */ 190717d4247SJustin T. Gibbs if ((biosctrl & CHANNEL_B_PRIMARY) != 0) 1916fb77fefSJustin T. Gibbs ahc->flags |= 1; 192717d4247SJustin T. Gibbs 193717d4247SJustin T. Gibbs if ((biosctrl & BIOSMODE) == BIOSDISABLED) { 194717d4247SJustin T. Gibbs ahc->flags |= AHC_USEDEFAULTS; 195717d4247SJustin T. Gibbs } else { 196717d4247SJustin T. Gibbs if ((ahc->features & AHC_WIDE) != 0) { 197717d4247SJustin T. Gibbs ahc->our_id = scsiconf1 & HWSCSIID; 198717d4247SJustin T. Gibbs if (scsiconf & TERM_ENB) 199717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_A; 200717d4247SJustin T. Gibbs } else { 201717d4247SJustin T. Gibbs ahc->our_id = scsiconf & HSCSIID; 202717d4247SJustin T. Gibbs ahc->our_id_b = scsiconf1 & HSCSIID; 203717d4247SJustin T. Gibbs if (scsiconf & TERM_ENB) 204717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_A; 205717d4247SJustin T. Gibbs if (scsiconf1 & TERM_ENB) 206717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_B; 207717d4247SJustin T. Gibbs } 208717d4247SJustin T. Gibbs } 209b73b70ccSJustin T. Gibbs if ((ahc_inb(ahc, HA_274_BIOSGLOBAL) & HA_274_EXTENDED_TRANS)) 210717d4247SJustin T. Gibbs ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B; 211717d4247SJustin T. Gibbs break; 212717d4247SJustin T. Gibbs } 213717d4247SJustin T. Gibbs case AHC_VL: 214717d4247SJustin T. Gibbs { 215b73b70ccSJustin T. Gibbs have_seeprom = aha2840_load_seeprom(ahc); 216717d4247SJustin T. Gibbs break; 217717d4247SJustin T. Gibbs } 218717d4247SJustin T. Gibbs default: 219717d4247SJustin T. Gibbs break; 220717d4247SJustin T. Gibbs } 221b73b70ccSJustin T. Gibbs if (have_seeprom == 0) { 222b73b70ccSJustin T. Gibbs free(ahc->seep_config, M_DEVBUF); 223b73b70ccSJustin T. Gibbs ahc->seep_config = NULL; 224b73b70ccSJustin T. Gibbs } 225717d4247SJustin T. Gibbs 226717d4247SJustin T. Gibbs /* 227717d4247SJustin T. Gibbs * Ensure autoflush is enabled 228717d4247SJustin T. Gibbs */ 229717d4247SJustin T. Gibbs ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS); 230717d4247SJustin T. Gibbs 231717d4247SJustin T. Gibbs /* Setup the FIFO threshold and the bus off time */ 232717d4247SJustin T. Gibbs hostconf = ahc_inb(ahc, HOSTCONF); 233717d4247SJustin T. Gibbs ahc_outb(ahc, BUSSPD, hostconf & DFTHRSH); 234717d4247SJustin T. Gibbs ahc_outb(ahc, BUSTIME, (hostconf << 2) & BOFF); 235717d4247SJustin T. Gibbs 2369bf327a7SJustin T. Gibbs ahc->bus_softc.aic7770_softc.busspd = hostconf & DFTHRSH; 2379bf327a7SJustin T. Gibbs ahc->bus_softc.aic7770_softc.bustime = (hostconf << 2) & BOFF; 2389bf327a7SJustin T. Gibbs 239717d4247SJustin T. Gibbs /* 240717d4247SJustin T. Gibbs * Generic aic7xxx initialization. 241717d4247SJustin T. Gibbs */ 242717d4247SJustin T. Gibbs error = ahc_init(ahc); 243717d4247SJustin T. Gibbs if (error != 0) 244717d4247SJustin T. Gibbs return (error); 245717d4247SJustin T. Gibbs 246b73b70ccSJustin T. Gibbs error = aic7770_map_int(ahc, irq); 247b73b70ccSJustin T. Gibbs if (error != 0) 248b73b70ccSJustin T. Gibbs return (error); 249b73b70ccSJustin T. Gibbs 250032b0a17SScott Long ahc_lock(ahc); 251717d4247SJustin T. Gibbs /* 252a5847d5cSJustin T. Gibbs * Link this softc in with all other ahc instances. 253a5847d5cSJustin T. Gibbs */ 254a5847d5cSJustin T. Gibbs ahc_softc_insert(ahc); 255a5847d5cSJustin T. Gibbs 256a5847d5cSJustin T. Gibbs /* 257717d4247SJustin T. Gibbs * Enable the board's BUS drivers 258717d4247SJustin T. Gibbs */ 259717d4247SJustin T. Gibbs ahc_outb(ahc, BCTL, ENABLE); 260717d4247SJustin T. Gibbs 261032b0a17SScott Long ahc_unlock(ahc); 262b95de6daSJustin T. Gibbs 263717d4247SJustin T. Gibbs return (0); 264717d4247SJustin T. Gibbs } 265717d4247SJustin T. Gibbs 2669bf327a7SJustin T. Gibbs static int 2679bf327a7SJustin T. Gibbs aic7770_chip_init(struct ahc_softc *ahc) 2689bf327a7SJustin T. Gibbs { 2699bf327a7SJustin T. Gibbs ahc_outb(ahc, BUSSPD, ahc->bus_softc.aic7770_softc.busspd); 2709bf327a7SJustin T. Gibbs ahc_outb(ahc, BUSTIME, ahc->bus_softc.aic7770_softc.bustime); 2719bf327a7SJustin T. Gibbs ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS); 2729bf327a7SJustin T. Gibbs ahc_outb(ahc, BCTL, ENABLE); 2739bf327a7SJustin T. Gibbs return (ahc_chip_init(ahc)); 2749bf327a7SJustin T. Gibbs } 2759bf327a7SJustin T. Gibbs 2769bf327a7SJustin T. Gibbs static int 2779bf327a7SJustin T. Gibbs aic7770_suspend(struct ahc_softc *ahc) 2789bf327a7SJustin T. Gibbs { 2799bf327a7SJustin T. Gibbs return (ahc_suspend(ahc)); 2809bf327a7SJustin T. Gibbs } 2819bf327a7SJustin T. Gibbs 2829bf327a7SJustin T. Gibbs static int 2839bf327a7SJustin T. Gibbs aic7770_resume(struct ahc_softc *ahc) 2849bf327a7SJustin T. Gibbs { 2859bf327a7SJustin T. Gibbs return (ahc_resume(ahc)); 2869bf327a7SJustin T. Gibbs } 2879bf327a7SJustin T. Gibbs 288717d4247SJustin T. Gibbs /* 289717d4247SJustin T. Gibbs * Read the 284x SEEPROM. 290717d4247SJustin T. Gibbs */ 291b73b70ccSJustin T. Gibbs static int 292717d4247SJustin T. Gibbs aha2840_load_seeprom(struct ahc_softc *ahc) 293717d4247SJustin T. Gibbs { 294717d4247SJustin T. Gibbs struct seeprom_descriptor sd; 295b73b70ccSJustin T. Gibbs struct seeprom_config *sc; 296717d4247SJustin T. Gibbs int have_seeprom; 297b73b70ccSJustin T. Gibbs uint8_t scsi_conf; 298717d4247SJustin T. Gibbs 299717d4247SJustin T. Gibbs sd.sd_ahc = ahc; 300717d4247SJustin T. Gibbs sd.sd_control_offset = SEECTL_2840; 301717d4247SJustin T. Gibbs sd.sd_status_offset = STATUS_2840; 302717d4247SJustin T. Gibbs sd.sd_dataout_offset = STATUS_2840; 303717d4247SJustin T. Gibbs sd.sd_chip = C46; 304717d4247SJustin T. Gibbs sd.sd_MS = 0; 305717d4247SJustin T. Gibbs sd.sd_RDY = EEPROM_TF; 306717d4247SJustin T. Gibbs sd.sd_CS = CS_2840; 307717d4247SJustin T. Gibbs sd.sd_CK = CK_2840; 308717d4247SJustin T. Gibbs sd.sd_DO = DO_2840; 309717d4247SJustin T. Gibbs sd.sd_DI = DI_2840; 310b73b70ccSJustin T. Gibbs sc = ahc->seep_config; 311717d4247SJustin T. Gibbs 312717d4247SJustin T. Gibbs if (bootverbose) 313717d4247SJustin T. Gibbs printf("%s: Reading SEEPROM...", ahc_name(ahc)); 314655a5ce4SJustin T. Gibbs have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc, 3159bf327a7SJustin T. Gibbs /*start_addr*/0, sizeof(*sc)/2); 316717d4247SJustin T. Gibbs 317717d4247SJustin T. Gibbs if (have_seeprom) { 318b73b70ccSJustin T. Gibbs if (ahc_verify_cksum(sc) == 0) { 319717d4247SJustin T. Gibbs if(bootverbose) 320717d4247SJustin T. Gibbs printf ("checksum error\n"); 321717d4247SJustin T. Gibbs have_seeprom = 0; 322717d4247SJustin T. Gibbs } else if (bootverbose) { 323717d4247SJustin T. Gibbs printf("done.\n"); 324717d4247SJustin T. Gibbs } 325717d4247SJustin T. Gibbs } 326717d4247SJustin T. Gibbs 327717d4247SJustin T. Gibbs if (!have_seeprom) { 328717d4247SJustin T. Gibbs if (bootverbose) 329717d4247SJustin T. Gibbs printf("%s: No SEEPROM available\n", ahc_name(ahc)); 330717d4247SJustin T. Gibbs ahc->flags |= AHC_USEDEFAULTS; 331717d4247SJustin T. Gibbs } else { 332717d4247SJustin T. Gibbs /* 333717d4247SJustin T. Gibbs * Put the data we've collected down into SRAM 334717d4247SJustin T. Gibbs * where ahc_init will find it. 335717d4247SJustin T. Gibbs */ 336717d4247SJustin T. Gibbs int i; 337b73b70ccSJustin T. Gibbs int max_targ; 338717d4247SJustin T. Gibbs uint16_t discenable; 339717d4247SJustin T. Gibbs 340b73b70ccSJustin T. Gibbs max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8; 341717d4247SJustin T. Gibbs discenable = 0; 342717d4247SJustin T. Gibbs for (i = 0; i < max_targ; i++){ 343717d4247SJustin T. Gibbs uint8_t target_settings; 344b73b70ccSJustin T. Gibbs 345b73b70ccSJustin T. Gibbs target_settings = (sc->device_flags[i] & CFXFER) << 4; 346b73b70ccSJustin T. Gibbs if (sc->device_flags[i] & CFSYNCH) 347717d4247SJustin T. Gibbs target_settings |= SOFS; 348b73b70ccSJustin T. Gibbs if (sc->device_flags[i] & CFWIDEB) 349717d4247SJustin T. Gibbs target_settings |= WIDEXFER; 350b73b70ccSJustin T. Gibbs if (sc->device_flags[i] & CFDISC) 351717d4247SJustin T. Gibbs discenable |= (0x01 << i); 352717d4247SJustin T. Gibbs ahc_outb(ahc, TARG_SCSIRATE + i, target_settings); 353717d4247SJustin T. Gibbs } 354717d4247SJustin T. Gibbs ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff)); 355717d4247SJustin T. Gibbs ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff)); 356717d4247SJustin T. Gibbs 357b73b70ccSJustin T. Gibbs ahc->our_id = sc->brtime_id & CFSCSIID; 358717d4247SJustin T. Gibbs 359717d4247SJustin T. Gibbs scsi_conf = (ahc->our_id & 0x7); 360b73b70ccSJustin T. Gibbs if (sc->adapter_control & CFSPARITY) 361717d4247SJustin T. Gibbs scsi_conf |= ENSPCHK; 362b73b70ccSJustin T. Gibbs if (sc->adapter_control & CFRESETB) 363717d4247SJustin T. Gibbs scsi_conf |= RESET_SCSI; 364717d4247SJustin T. Gibbs 365b73b70ccSJustin T. Gibbs if (sc->bios_control & CF284XEXTEND) 366717d4247SJustin T. Gibbs ahc->flags |= AHC_EXTENDED_TRANS_A; 367717d4247SJustin T. Gibbs /* Set SCSICONF info */ 368717d4247SJustin T. Gibbs ahc_outb(ahc, SCSICONF, scsi_conf); 369717d4247SJustin T. Gibbs 370b73b70ccSJustin T. Gibbs if (sc->adapter_control & CF284XSTERM) 371717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_A; 372717d4247SJustin T. Gibbs } 373b73b70ccSJustin T. Gibbs return (have_seeprom); 374717d4247SJustin T. Gibbs } 375717d4247SJustin T. Gibbs 376717d4247SJustin T. Gibbs static int 377cd036e89SJustin T. Gibbs ahc_aic7770_VL_setup(struct ahc_softc *ahc) 378717d4247SJustin T. Gibbs { 379717d4247SJustin T. Gibbs int error; 380717d4247SJustin T. Gibbs 381cd036e89SJustin T. Gibbs error = ahc_aic7770_setup(ahc); 382cd036e89SJustin T. Gibbs ahc->chip |= AHC_VL; 383717d4247SJustin T. Gibbs return (error); 384717d4247SJustin T. Gibbs } 385717d4247SJustin T. Gibbs 386717d4247SJustin T. Gibbs static int 387cd036e89SJustin T. Gibbs ahc_aic7770_EISA_setup(struct ahc_softc *ahc) 388717d4247SJustin T. Gibbs { 389717d4247SJustin T. Gibbs int error; 390717d4247SJustin T. Gibbs 391cd036e89SJustin T. Gibbs error = ahc_aic7770_setup(ahc); 392cd036e89SJustin T. Gibbs ahc->chip |= AHC_EISA; 393717d4247SJustin T. Gibbs return (error); 394717d4247SJustin T. Gibbs } 395717d4247SJustin T. Gibbs 396717d4247SJustin T. Gibbs static int 397cd036e89SJustin T. Gibbs ahc_aic7770_setup(struct ahc_softc *ahc) 398717d4247SJustin T. Gibbs { 399cd036e89SJustin T. Gibbs ahc->channel = 'A'; 400cd036e89SJustin T. Gibbs ahc->channel_b = 'B'; 401cd036e89SJustin T. Gibbs ahc->chip = AHC_AIC7770; 402cd036e89SJustin T. Gibbs ahc->features = AHC_AIC7770_FE; 403cd036e89SJustin T. Gibbs ahc->bugs |= AHC_TMODE_WIDEODD_BUG; 404cd036e89SJustin T. Gibbs ahc->flags |= AHC_PAGESCBS; 4059bf327a7SJustin T. Gibbs ahc->instruction_ram_size = 448; 406717d4247SJustin T. Gibbs return (0); 407717d4247SJustin T. Gibbs } 408