1717d4247SJustin T. Gibbs /* 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 * 408f214efcSJustin T. Gibbs * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#16 $ 41717d4247SJustin T. Gibbs * 42717d4247SJustin T. Gibbs * $FreeBSD$ 43717d4247SJustin T. Gibbs */ 44717d4247SJustin T. Gibbs 458f214efcSJustin T. Gibbs #ifdef __linux__ 468f214efcSJustin T. Gibbs #include "aic7xxx_osm.h" 478f214efcSJustin T. Gibbs #include "aic7xxx_inline.h" 488f214efcSJustin T. Gibbs #include "aic7xxx_93cx6.h" 498f214efcSJustin T. Gibbs #else 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*/ 59717d4247SJustin T. Gibbs 60717d4247SJustin T. Gibbs static void aha2840_load_seeprom(struct ahc_softc *ahc); 61717d4247SJustin T. Gibbs static ahc_device_setup_t ahc_aic7770_VL_setup; 62717d4247SJustin T. Gibbs static ahc_device_setup_t ahc_aic7770_EISA_setup;; 63717d4247SJustin T. Gibbs static ahc_device_setup_t ahc_aic7770_setup; 64717d4247SJustin T. Gibbs 65717d4247SJustin T. Gibbs 66717d4247SJustin T. Gibbs struct aic7770_identity aic7770_ident_table [] = 67717d4247SJustin T. Gibbs { 68717d4247SJustin T. Gibbs { 69717d4247SJustin T. Gibbs ID_AHA_274x, 70717d4247SJustin T. Gibbs 0xFFFFFFFF, 71717d4247SJustin T. Gibbs "Adaptec 274X SCSI adapter", 72717d4247SJustin T. Gibbs ahc_aic7770_EISA_setup 73717d4247SJustin T. Gibbs }, 74717d4247SJustin T. Gibbs { 75717d4247SJustin T. Gibbs ID_AHA_284xB, 76717d4247SJustin T. Gibbs 0xFFFFFFFE, 77717d4247SJustin T. Gibbs "Adaptec 284X SCSI adapter", 78717d4247SJustin T. Gibbs ahc_aic7770_VL_setup 79717d4247SJustin T. Gibbs }, 80717d4247SJustin T. Gibbs /* Generic chip probes for devices we don't know 'exactly' */ 81717d4247SJustin T. Gibbs { 82717d4247SJustin T. Gibbs ID_AIC7770, 83717d4247SJustin T. Gibbs 0xFFFFFFFF, 84717d4247SJustin T. Gibbs "Adaptec aic7770 SCSI adapter", 85717d4247SJustin T. Gibbs ahc_aic7770_EISA_setup 86717d4247SJustin T. Gibbs } 87717d4247SJustin T. Gibbs }; 88717d4247SJustin T. Gibbs const int ahc_num_aic7770_devs = NUM_ELEMENTS(aic7770_ident_table); 89717d4247SJustin T. Gibbs 90717d4247SJustin T. Gibbs struct aic7770_identity * 91717d4247SJustin T. Gibbs aic7770_find_device(uint32_t id) 92717d4247SJustin T. Gibbs { 93717d4247SJustin T. Gibbs struct aic7770_identity *entry; 94717d4247SJustin T. Gibbs int i; 95717d4247SJustin T. Gibbs 96717d4247SJustin T. Gibbs for (i = 0; i < ahc_num_aic7770_devs; i++) { 97717d4247SJustin T. Gibbs entry = &aic7770_ident_table[i]; 98717d4247SJustin T. Gibbs if (entry->full_id == (id & entry->id_mask)) 99717d4247SJustin T. Gibbs return (entry); 100717d4247SJustin T. Gibbs } 101717d4247SJustin T. Gibbs return (NULL); 102717d4247SJustin T. Gibbs } 103717d4247SJustin T. Gibbs 104717d4247SJustin T. Gibbs int 1058f214efcSJustin T. Gibbs aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io) 106717d4247SJustin T. Gibbs { 107717d4247SJustin T. Gibbs int error; 108717d4247SJustin T. Gibbs u_int hostconf; 1096fb77fefSJustin T. Gibbs u_int irq; 1106fb77fefSJustin T. Gibbs u_int intdef; 111717d4247SJustin T. Gibbs 112cd036e89SJustin T. Gibbs error = entry->setup(ahc); 113717d4247SJustin T. Gibbs if (error != 0) 114717d4247SJustin T. Gibbs return (error); 115717d4247SJustin T. Gibbs 1168f214efcSJustin T. Gibbs error = aic7770_map_registers(ahc, io); 117717d4247SJustin T. Gibbs if (error != 0) 118717d4247SJustin T. Gibbs return (error); 119717d4247SJustin T. Gibbs 1208f214efcSJustin T. Gibbs /* 1218f214efcSJustin T. Gibbs * Before we continue probing the card, ensure that 1228f214efcSJustin T. Gibbs * its interrupts are *disabled*. We don't want 1238f214efcSJustin T. Gibbs * a misstep to hang the machine in an interrupt 1248f214efcSJustin T. Gibbs * storm. 1258f214efcSJustin T. Gibbs */ 1268f214efcSJustin T. Gibbs ahc_intr_enable(ahc, FALSE); 1278f214efcSJustin T. Gibbs 128cd036e89SJustin T. Gibbs ahc->description = entry->name; 129cd036e89SJustin T. Gibbs error = ahc_softc_init(ahc); 130717d4247SJustin T. Gibbs 1316fb77fefSJustin T. Gibbs error = ahc_reset(ahc); 132717d4247SJustin T. Gibbs if (error != 0) 133717d4247SJustin T. Gibbs return (error); 134717d4247SJustin T. Gibbs 1356fb77fefSJustin T. Gibbs /* Make sure we have a valid interrupt vector */ 1366fb77fefSJustin T. Gibbs intdef = ahc_inb(ahc, INTDEF); 1376fb77fefSJustin T. Gibbs irq = intdef & VECTOR; 1386fb77fefSJustin T. Gibbs switch (irq) { 1396fb77fefSJustin T. Gibbs case 9: 1406fb77fefSJustin T. Gibbs case 10: 1416fb77fefSJustin T. Gibbs case 11: 1426fb77fefSJustin T. Gibbs case 12: 1436fb77fefSJustin T. Gibbs case 14: 1446fb77fefSJustin T. Gibbs case 15: 1456fb77fefSJustin T. Gibbs break; 1466fb77fefSJustin T. Gibbs default: 1476fb77fefSJustin T. Gibbs printf("aic7770_config: illegal irq setting %d\n", intdef); 1486fb77fefSJustin T. Gibbs return (ENXIO); 1496fb77fefSJustin T. Gibbs } 1506fb77fefSJustin T. Gibbs 1516fb77fefSJustin T. Gibbs if ((intdef & EDGE_TRIG) != 0) 1526fb77fefSJustin T. Gibbs ahc->flags |= AHC_EDGE_INTERRUPT; 1536fb77fefSJustin T. Gibbs 154cd036e89SJustin T. Gibbs switch (ahc->chip & (AHC_EISA|AHC_VL)) { 155717d4247SJustin T. Gibbs case AHC_EISA: 156717d4247SJustin T. Gibbs { 157717d4247SJustin T. Gibbs u_int biosctrl; 158717d4247SJustin T. Gibbs u_int scsiconf; 159717d4247SJustin T. Gibbs u_int scsiconf1; 160717d4247SJustin T. Gibbs 161717d4247SJustin T. Gibbs biosctrl = ahc_inb(ahc, HA_274_BIOSCTRL); 162717d4247SJustin T. Gibbs scsiconf = ahc_inb(ahc, SCSICONF); 163717d4247SJustin T. Gibbs scsiconf1 = ahc_inb(ahc, SCSICONF + 1); 164717d4247SJustin T. Gibbs 165717d4247SJustin T. Gibbs /* Get the primary channel information */ 166717d4247SJustin T. Gibbs if ((biosctrl & CHANNEL_B_PRIMARY) != 0) 1676fb77fefSJustin T. Gibbs ahc->flags |= 1; 168717d4247SJustin T. Gibbs 169717d4247SJustin T. Gibbs if ((biosctrl & BIOSMODE) == BIOSDISABLED) { 170717d4247SJustin T. Gibbs ahc->flags |= AHC_USEDEFAULTS; 171717d4247SJustin T. Gibbs } else { 172717d4247SJustin T. Gibbs if ((ahc->features & AHC_WIDE) != 0) { 173717d4247SJustin T. Gibbs ahc->our_id = scsiconf1 & HWSCSIID; 174717d4247SJustin T. Gibbs if (scsiconf & TERM_ENB) 175717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_A; 176717d4247SJustin T. Gibbs } else { 177717d4247SJustin T. Gibbs ahc->our_id = scsiconf & HSCSIID; 178717d4247SJustin T. Gibbs ahc->our_id_b = scsiconf1 & HSCSIID; 179717d4247SJustin T. Gibbs if (scsiconf & TERM_ENB) 180717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_A; 181717d4247SJustin T. Gibbs if (scsiconf1 & TERM_ENB) 182717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_B; 183717d4247SJustin T. Gibbs } 184717d4247SJustin T. Gibbs } 185717d4247SJustin T. Gibbs /* 186717d4247SJustin T. Gibbs * We have no way to tell, so assume extended 187717d4247SJustin T. Gibbs * translation is enabled. 188717d4247SJustin T. Gibbs */ 189717d4247SJustin T. Gibbs ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B; 190717d4247SJustin T. Gibbs break; 191717d4247SJustin T. Gibbs } 192717d4247SJustin T. Gibbs case AHC_VL: 193717d4247SJustin T. Gibbs { 194717d4247SJustin T. Gibbs aha2840_load_seeprom(ahc); 195717d4247SJustin T. Gibbs break; 196717d4247SJustin T. Gibbs } 197717d4247SJustin T. Gibbs default: 198717d4247SJustin T. Gibbs break; 199717d4247SJustin T. Gibbs } 200717d4247SJustin T. Gibbs 201717d4247SJustin T. Gibbs /* 202717d4247SJustin T. Gibbs * Ensure autoflush is enabled 203717d4247SJustin T. Gibbs */ 204717d4247SJustin T. Gibbs ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS); 205717d4247SJustin T. Gibbs 206717d4247SJustin T. Gibbs /* Setup the FIFO threshold and the bus off time */ 207717d4247SJustin T. Gibbs hostconf = ahc_inb(ahc, HOSTCONF); 208717d4247SJustin T. Gibbs ahc_outb(ahc, BUSSPD, hostconf & DFTHRSH); 209717d4247SJustin T. Gibbs ahc_outb(ahc, BUSTIME, (hostconf << 2) & BOFF); 210717d4247SJustin T. Gibbs 211717d4247SJustin T. Gibbs /* 212717d4247SJustin T. Gibbs * Generic aic7xxx initialization. 213717d4247SJustin T. Gibbs */ 214717d4247SJustin T. Gibbs error = ahc_init(ahc); 215717d4247SJustin T. Gibbs if (error != 0) 216717d4247SJustin T. Gibbs return (error); 217717d4247SJustin T. Gibbs 218717d4247SJustin T. Gibbs /* 219a5847d5cSJustin T. Gibbs * Link this softc in with all other ahc instances. 220a5847d5cSJustin T. Gibbs */ 221a5847d5cSJustin T. Gibbs ahc_softc_insert(ahc); 222a5847d5cSJustin T. Gibbs 22358fb7d8eSJustin T. Gibbs error = aic7770_map_int(ahc, irq); 22458fb7d8eSJustin T. Gibbs if (error != 0) 22558fb7d8eSJustin T. Gibbs return (error); 22658fb7d8eSJustin T. Gibbs 227a5847d5cSJustin T. Gibbs /* 228717d4247SJustin T. Gibbs * Enable the board's BUS drivers 229717d4247SJustin T. Gibbs */ 230717d4247SJustin T. Gibbs ahc_outb(ahc, BCTL, ENABLE); 231717d4247SJustin T. Gibbs 232b95de6daSJustin T. Gibbs /* 233b95de6daSJustin T. Gibbs * Allow interrupts. 234b95de6daSJustin T. Gibbs */ 235b95de6daSJustin T. Gibbs ahc_intr_enable(ahc, TRUE); 236b95de6daSJustin T. Gibbs 237717d4247SJustin T. Gibbs return (0); 238717d4247SJustin T. Gibbs } 239717d4247SJustin T. Gibbs 240717d4247SJustin T. Gibbs /* 241717d4247SJustin T. Gibbs * Read the 284x SEEPROM. 242717d4247SJustin T. Gibbs */ 243717d4247SJustin T. Gibbs static void 244717d4247SJustin T. Gibbs aha2840_load_seeprom(struct ahc_softc *ahc) 245717d4247SJustin T. Gibbs { 246717d4247SJustin T. Gibbs struct seeprom_descriptor sd; 247717d4247SJustin T. Gibbs struct seeprom_config sc; 248717d4247SJustin T. Gibbs uint8_t scsi_conf; 249717d4247SJustin T. Gibbs int have_seeprom; 250717d4247SJustin T. Gibbs 251717d4247SJustin T. Gibbs sd.sd_ahc = ahc; 252717d4247SJustin T. Gibbs sd.sd_control_offset = SEECTL_2840; 253717d4247SJustin T. Gibbs sd.sd_status_offset = STATUS_2840; 254717d4247SJustin T. Gibbs sd.sd_dataout_offset = STATUS_2840; 255717d4247SJustin T. Gibbs sd.sd_chip = C46; 256717d4247SJustin T. Gibbs sd.sd_MS = 0; 257717d4247SJustin T. Gibbs sd.sd_RDY = EEPROM_TF; 258717d4247SJustin T. Gibbs sd.sd_CS = CS_2840; 259717d4247SJustin T. Gibbs sd.sd_CK = CK_2840; 260717d4247SJustin T. Gibbs sd.sd_DO = DO_2840; 261717d4247SJustin T. Gibbs sd.sd_DI = DI_2840; 262717d4247SJustin T. Gibbs 263717d4247SJustin T. Gibbs if (bootverbose) 264717d4247SJustin T. Gibbs printf("%s: Reading SEEPROM...", ahc_name(ahc)); 2658f214efcSJustin T. Gibbs have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)&sc, 2668f214efcSJustin T. Gibbs /*start_addr*/0, sizeof(sc)/2); 267717d4247SJustin T. Gibbs 268717d4247SJustin T. Gibbs if (have_seeprom) { 269717d4247SJustin T. Gibbs 2708f214efcSJustin T. Gibbs if (ahc_verify_cksum(&sc) == 0) { 271717d4247SJustin T. Gibbs if(bootverbose) 272717d4247SJustin T. Gibbs printf ("checksum error\n"); 273717d4247SJustin T. Gibbs have_seeprom = 0; 274717d4247SJustin T. Gibbs } else if (bootverbose) { 275717d4247SJustin T. Gibbs printf("done.\n"); 276717d4247SJustin T. Gibbs } 277717d4247SJustin T. Gibbs } 278717d4247SJustin T. Gibbs 279717d4247SJustin T. Gibbs if (!have_seeprom) { 280717d4247SJustin T. Gibbs if (bootverbose) 281717d4247SJustin T. Gibbs printf("%s: No SEEPROM available\n", ahc_name(ahc)); 282717d4247SJustin T. Gibbs ahc->flags |= AHC_USEDEFAULTS; 283717d4247SJustin T. Gibbs } else { 284717d4247SJustin T. Gibbs /* 285717d4247SJustin T. Gibbs * Put the data we've collected down into SRAM 286717d4247SJustin T. Gibbs * where ahc_init will find it. 287717d4247SJustin T. Gibbs */ 288717d4247SJustin T. Gibbs int i; 289717d4247SJustin T. Gibbs int max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8; 290717d4247SJustin T. Gibbs uint16_t discenable; 291717d4247SJustin T. Gibbs 292717d4247SJustin T. Gibbs discenable = 0; 293717d4247SJustin T. Gibbs for (i = 0; i < max_targ; i++){ 294717d4247SJustin T. Gibbs uint8_t target_settings; 295717d4247SJustin T. Gibbs target_settings = (sc.device_flags[i] & CFXFER) << 4; 296717d4247SJustin T. Gibbs if (sc.device_flags[i] & CFSYNCH) 297717d4247SJustin T. Gibbs target_settings |= SOFS; 298717d4247SJustin T. Gibbs if (sc.device_flags[i] & CFWIDEB) 299717d4247SJustin T. Gibbs target_settings |= WIDEXFER; 300717d4247SJustin T. Gibbs if (sc.device_flags[i] & CFDISC) 301717d4247SJustin T. Gibbs discenable |= (0x01 << i); 302717d4247SJustin T. Gibbs ahc_outb(ahc, TARG_SCSIRATE + i, target_settings); 303717d4247SJustin T. Gibbs } 304717d4247SJustin T. Gibbs ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff)); 305717d4247SJustin T. Gibbs ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff)); 306717d4247SJustin T. Gibbs 307717d4247SJustin T. Gibbs ahc->our_id = sc.brtime_id & CFSCSIID; 308717d4247SJustin T. Gibbs 309717d4247SJustin T. Gibbs scsi_conf = (ahc->our_id & 0x7); 310717d4247SJustin T. Gibbs if (sc.adapter_control & CFSPARITY) 311717d4247SJustin T. Gibbs scsi_conf |= ENSPCHK; 312717d4247SJustin T. Gibbs if (sc.adapter_control & CFRESETB) 313717d4247SJustin T. Gibbs scsi_conf |= RESET_SCSI; 314717d4247SJustin T. Gibbs 315717d4247SJustin T. Gibbs if (sc.bios_control & CF284XEXTEND) 316717d4247SJustin T. Gibbs ahc->flags |= AHC_EXTENDED_TRANS_A; 317717d4247SJustin T. Gibbs /* Set SCSICONF info */ 318717d4247SJustin T. Gibbs ahc_outb(ahc, SCSICONF, scsi_conf); 319717d4247SJustin T. Gibbs 320717d4247SJustin T. Gibbs if (sc.adapter_control & CF284XSTERM) 321717d4247SJustin T. Gibbs ahc->flags |= AHC_TERM_ENB_A; 322717d4247SJustin T. Gibbs } 323717d4247SJustin T. Gibbs } 324717d4247SJustin T. Gibbs 325717d4247SJustin T. Gibbs static int 326cd036e89SJustin T. Gibbs ahc_aic7770_VL_setup(struct ahc_softc *ahc) 327717d4247SJustin T. Gibbs { 328717d4247SJustin T. Gibbs int error; 329717d4247SJustin T. Gibbs 330cd036e89SJustin T. Gibbs error = ahc_aic7770_setup(ahc); 331cd036e89SJustin T. Gibbs ahc->chip |= AHC_VL; 332717d4247SJustin T. Gibbs return (error); 333717d4247SJustin T. Gibbs } 334717d4247SJustin T. Gibbs 335717d4247SJustin T. Gibbs static int 336cd036e89SJustin T. Gibbs ahc_aic7770_EISA_setup(struct ahc_softc *ahc) 337717d4247SJustin T. Gibbs { 338717d4247SJustin T. Gibbs int error; 339717d4247SJustin T. Gibbs 340cd036e89SJustin T. Gibbs error = ahc_aic7770_setup(ahc); 341cd036e89SJustin T. Gibbs ahc->chip |= AHC_EISA; 342717d4247SJustin T. Gibbs return (error); 343717d4247SJustin T. Gibbs } 344717d4247SJustin T. Gibbs 345717d4247SJustin T. Gibbs static int 346cd036e89SJustin T. Gibbs ahc_aic7770_setup(struct ahc_softc *ahc) 347717d4247SJustin T. Gibbs { 348cd036e89SJustin T. Gibbs ahc->channel = 'A'; 349cd036e89SJustin T. Gibbs ahc->channel_b = 'B'; 350cd036e89SJustin T. Gibbs ahc->chip = AHC_AIC7770; 351cd036e89SJustin T. Gibbs ahc->features = AHC_AIC7770_FE; 352cd036e89SJustin T. Gibbs ahc->bugs |= AHC_TMODE_WIDEODD_BUG; 353cd036e89SJustin T. Gibbs ahc->flags |= AHC_PAGESCBS; 354717d4247SJustin T. Gibbs return (0); 355717d4247SJustin T. Gibbs } 356