[BACK]Return to adwlib.c CVS log [TXT][DIR] Up to [local] / sys / dev / ic

Annotation of sys/dev/ic/adwlib.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: adwlib.c,v 1.20 2004/06/24 09:07:39 itojun Exp $ */
        !             2: /* $NetBSD: adwlib.c,v 1.20 2000/07/04 04:17:03 itojun Exp $        */
        !             3:
        !             4: /*
        !             5:  * Low level routines for the Advanced Systems Inc. SCSI controllers chips
        !             6:  *
        !             7:  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
        !             8:  * All rights reserved.
        !             9:  *
        !            10:  * Author: Baldassare Dante Profeta <dante@mclink.it>
        !            11:  *
        !            12:  * Redistribution and use in source and binary forms, with or without
        !            13:  * modification, are permitted provided that the following conditions
        !            14:  * are met:
        !            15:  * 1. Redistributions of source code must retain the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer.
        !            17:  * 2. Redistributions in binary form must reproduce the above copyright
        !            18:  *    notice, this list of conditions and the following disclaimer in the
        !            19:  *    documentation and/or other materials provided with the distribution.
        !            20:  * 3. All advertising materials mentioning features or use of this software
        !            21:  *    must display the following acknowledgement:
        !            22:  *        This product includes software developed by the NetBSD
        !            23:  *        Foundation, Inc. and its contributors.
        !            24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            25:  *    contributors may be used to endorse or promote products derived
        !            26:  *    from this software without specific prior written permission.
        !            27:  *
        !            28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            38:  * POSSIBILITY OF SUCH DAMAGE.
        !            39:  */
        !            40: /*
        !            41:  * Ported from:
        !            42:  */
        !            43: /*
        !            44:  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
        !            45:  *
        !            46:  * Copyright (c) 1995-2000 Advanced System Products, Inc.
        !            47:  * All Rights Reserved.
        !            48:  *
        !            49:  * Redistribution and use in source and binary forms, with or without
        !            50:  * modification, are permitted provided that redistributions of source
        !            51:  * code retain the above copyright notice and this comment without
        !            52:  * modification.
        !            53:  */
        !            54:
        !            55: #include <sys/types.h>
        !            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:
        !            63: #include <machine/bus.h>
        !            64: #include <machine/intr.h>
        !            65:
        !            66: #include <scsi/scsi_all.h>
        !            67: #include <scsi/scsiconf.h>
        !            68:
        !            69: #include <dev/pci/pcidevs.h>
        !            70:
        !            71: #include <dev/ic/adwlib.h>
        !            72: #include <dev/microcode/adw/adwmcode.h>
        !            73: #include <dev/ic/adw.h>
        !            74:
        !            75:
        !            76: int AdwRamSelfTest(bus_space_tag_t, bus_space_handle_t, u_int8_t);
        !            77: int AdwLoadMCode(bus_space_tag_t, bus_space_handle_t, u_int16_t *,
        !            78:                                                                u_int8_t);
        !            79: int AdwASC3550Cabling(bus_space_tag_t, bus_space_handle_t, ADW_DVC_CFG *);
        !            80: int AdwASC38C0800Cabling(bus_space_tag_t, bus_space_handle_t,
        !            81:                                                                ADW_DVC_CFG *);
        !            82: int AdwASC38C1600Cabling(bus_space_tag_t, bus_space_handle_t,
        !            83:                                                                ADW_DVC_CFG *);
        !            84:
        !            85: u_int16_t AdwGetEEPROMConfig(bus_space_tag_t, bus_space_handle_t,
        !            86:                                                        ADW_EEPROM *);
        !            87: void AdwSetEEPROMConfig(bus_space_tag_t, bus_space_handle_t,
        !            88:                                                         ADW_EEPROM *);
        !            89: u_int16_t AdwReadEEPWord(bus_space_tag_t, bus_space_handle_t, int);
        !            90: void AdwWaitEEPCmd(bus_space_tag_t, bus_space_handle_t);
        !            91:
        !            92: void AdwInquiryHandling(ADW_SOFTC *, ADW_SCSI_REQ_Q *);
        !            93:
        !            94: void AdwSleepMilliSecond(u_int32_t);
        !            95: void AdwDelayMicroSecond(u_int32_t);
        !            96:
        !            97:
        !            98: /*
        !            99:  * EEPROM Configuration.
        !           100:  *
        !           101:  * All drivers should use this structure to set the default EEPROM
        !           102:  * configuration. The BIOS now uses this structure when it is built.
        !           103:  * Additional structure information can be found in adwlib.h where
        !           104:  * the structure is defined.
        !           105:  */
        !           106: const static ADW_EEPROM adw_3550_Default_EEPROM = {
        !           107:        ADW_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
        !           108:        0x0000,                 /* 01 cfg_msw */
        !           109:        0xFFFF,                 /* 02 disc_enable */
        !           110:        0xFFFF,                 /* 03 wdtr_able */
        !           111:        { 0xFFFF },             /* 04 sdtr_able */
        !           112:        0xFFFF,                 /* 05 start_motor */
        !           113:        0xFFFF,                 /* 06 tagqng_able */
        !           114:        0xFFFF,                 /* 07 bios_scan */
        !           115:        0,                      /* 08 scam_tolerant */
        !           116:        7,                      /* 09 adapter_scsi_id */
        !           117:        0,                      /*    bios_boot_delay */
        !           118:        3,                      /* 10 scsi_reset_delay */
        !           119:        0,                      /*    bios_id_lun */
        !           120:        0,                      /* 11 termination */
        !           121:        0,                      /*    reserved1 */
        !           122:        0xFFE7,                 /* 12 bios_ctrl */
        !           123:        { 0xFFFF },             /* 13 ultra_able */
        !           124:        { 0 },                  /* 14 reserved2 */
        !           125:        ADW_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
        !           126:        ADW_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
        !           127:        0,                      /* 16 dvc_cntl */
        !           128:        { 0 },                  /* 17 bug_fix */
        !           129:        { 0,0,0 },              /* 18-20 serial_number[3] */
        !           130:        0,                      /* 21 check_sum */
        !           131:        {                       /* 22-29 oem_name[16] */
        !           132:          0,0,0,0,0,0,0,0,
        !           133:          0,0,0,0,0,0,0,0
        !           134:        },
        !           135:        0,                      /* 30 dvc_err_code */
        !           136:        0,                      /* 31 adw_err_code */
        !           137:        0,                      /* 32 adw_err_addr */
        !           138:        0,                      /* 33 saved_dvc_err_code */
        !           139:        0,                      /* 34 saved_adw_err_code */
        !           140:        0                       /* 35 saved_adw_err_addr */
        !           141: };
        !           142:
        !           143: const static ADW_EEPROM adw_38C0800_Default_EEPROM = {
        !           144:        ADW_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
        !           145:        0x0000,                 /* 01 cfg_msw */
        !           146:        0xFFFF,                 /* 02 disc_enable */
        !           147:        0xFFFF,                 /* 03 wdtr_able */
        !           148:        { 0x4444 },             /* 04 sdtr_speed1 */
        !           149:        0xFFFF,                 /* 05 start_motor */
        !           150:        0xFFFF,                 /* 06 tagqng_able */
        !           151:        0xFFFF,                 /* 07 bios_scan */
        !           152:        0,                      /* 08 scam_tolerant */
        !           153:        7,                      /* 09 adapter_scsi_id */
        !           154:        0,                      /*    bios_boot_delay */
        !           155:        3,                      /* 10 scsi_reset_delay */
        !           156:        0,                      /*    bios_id_lun */
        !           157:        0,                      /* 11 termination_se */
        !           158:        0,                      /*    termination_lvd */
        !           159:        0xFFE7,                 /* 12 bios_ctrl */
        !           160:        { 0x4444 },             /* 13 sdtr_speed2 */
        !           161:        { 0x4444 },             /* 14 sdtr_speed3 */
        !           162:        ADW_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
        !           163:        ADW_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
        !           164:        0,                      /* 16 dvc_cntl */
        !           165:        { 0x4444 },             /* 17 sdtr_speed4 */
        !           166:        { 0,0,0 },              /* 18-20 serial_number[3] */
        !           167:        0,                      /* 21 check_sum */
        !           168:        {                       /* 22-29 oem_name[16] */
        !           169:          0,0,0,0,0,0,0,0,
        !           170:          0,0,0,0,0,0,0,0
        !           171:        },
        !           172:        0,                      /* 30 dvc_err_code */
        !           173:        0,                      /* 31 adw_err_code */
        !           174:        0,                      /* 32 adw_err_addr */
        !           175:        0,                      /* 33 saved_dvc_err_code */
        !           176:        0,                      /* 34 saved_adw_err_code */
        !           177:        0,                      /* 35 saved_adw_err_addr */
        !           178:        {                       /* 36-55 reserved1[16] */
        !           179:          0,0,0,0,0,0,0,0,0,0,
        !           180:          0,0,0,0,0,0,0,0,0,0
        !           181:        },
        !           182:        0,                      /* 56 cisptr_lsw */
        !           183:        0,                      /* 57 cisprt_msw */
        !           184:        PCI_VENDOR_ADVSYS,      /* 58 subsysvid */
        !           185:        PCI_PRODUCT_ADVSYS_U2W, /* 59 subsysid */
        !           186:        { 0,0,0,0 }             /* 60-63 reserved2[4] */
        !           187: };
        !           188:
        !           189: const static ADW_EEPROM adw_38C1600_Default_EEPROM = {
        !           190:        ADW_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
        !           191:        0x0000,                 /* 01 cfg_msw */
        !           192:        0xFFFF,                 /* 02 disc_enable */
        !           193:        0xFFFF,                 /* 03 wdtr_able */
        !           194:        { 0x5555 },             /* 04 sdtr_speed1 */
        !           195:        0xFFFF,                 /* 05 start_motor */
        !           196:        0xFFFF,                 /* 06 tagqng_able */
        !           197:        0xFFFF,                 /* 07 bios_scan */
        !           198:        0,                      /* 08 scam_tolerant */
        !           199:        7,                      /* 09 adapter_scsi_id */
        !           200:        0,                      /*    bios_boot_delay */
        !           201:        3,                      /* 10 scsi_reset_delay */
        !           202:        0,                      /*    bios_id_lun */
        !           203:        0,                      /* 11 termination_se */
        !           204:        0,                      /*    termination_lvd */
        !           205:        0xFFE7,                 /* 12 bios_ctrl */
        !           206:        { 0x5555 },             /* 13 sdtr_speed2 */
        !           207:        { 0x5555 },             /* 14 sdtr_speed3 */
        !           208:        ADW_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
        !           209:        ADW_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
        !           210:        0,                      /* 16 dvc_cntl */
        !           211:        { 0x5555 },             /* 17 sdtr_speed4 */
        !           212:        { 0,0,0 },              /* 18-20 serial_number[3] */
        !           213:        0,                      /* 21 check_sum */
        !           214:        {                       /* 22-29 oem_name[16] */
        !           215:          0,0,0,0,0,0,0,0,
        !           216:          0,0,0,0,0,0,0,0
        !           217:        },
        !           218:        0,                      /* 30 dvc_err_code */
        !           219:        0,                      /* 31 adw_err_code */
        !           220:        0,                      /* 32 adw_err_addr */
        !           221:        0,                      /* 33 saved_dvc_err_code */
        !           222:        0,                      /* 34 saved_adw_err_code */
        !           223:        0,                      /* 35 saved_adw_err_addr */
        !           224:        {                       /* 36-55 reserved1[16] */
        !           225:          0,0,0,0,0,0,0,0,0,0,
        !           226:          0,0,0,0,0,0,0,0,0,0
        !           227:        },
        !           228:        0,                      /* 56 cisptr_lsw */
        !           229:        0,                      /* 57 cisprt_msw */
        !           230:        PCI_VENDOR_ADVSYS,      /* 58 subsysvid */
        !           231:        PCI_PRODUCT_ADVSYS_U3W, /* 59 subsysid */
        !           232:        { 0,0,0,0 }             /* 60-63 reserved2[4] */
        !           233: };
        !           234:
        !           235:
        !           236: /*
        !           237:  * Read the board's EEPROM configuration. Set fields in ADW_SOFTC and
        !           238:  * ADW_DVC_CFG based on the EEPROM settings. The chip is stopped while
        !           239:  * all of this is done.
        !           240:  *
        !           241:  * For a non-fatal error return a warning code. If there are no warnings
        !           242:  * then 0 is returned.
        !           243:  *
        !           244:  * Note: Chip is stopped on entry.
        !           245:  */
        !           246: int
        !           247: AdwInitFromEEPROM(sc)
        !           248: ADW_SOFTC      *sc;
        !           249: {
        !           250:        bus_space_tag_t iot = sc->sc_iot;
        !           251:        bus_space_handle_t ioh = sc->sc_ioh;
        !           252:        ADW_EEPROM              eep_config;
        !           253:        u_int16_t               warn_code;
        !           254:        u_int16_t               sdtr_speed = 0;
        !           255:        u_int8_t                tid, termination;
        !           256:        int                     i, j;
        !           257:
        !           258:
        !           259:        warn_code = 0;
        !           260:
        !           261:        /*
        !           262:         * Read the board's EEPROM configuration.
        !           263:         *
        !           264:         * Set default values if a bad checksum is found.
        !           265:         *
        !           266:         * XXX - Don't handle big-endian access to EEPROM yet.
        !           267:         */
        !           268:        if (AdwGetEEPROMConfig(iot, ioh, &eep_config) != eep_config.check_sum) {
        !           269:                warn_code |= ADW_WARN_EEPROM_CHKSUM;
        !           270:
        !           271:                /*
        !           272:                 * Set EEPROM default values.
        !           273:                 */
        !           274:                switch(sc->chip_type) {
        !           275:                case ADW_CHIP_ASC3550:
        !           276:                        eep_config = adw_3550_Default_EEPROM;
        !           277:                        break;
        !           278:                case ADW_CHIP_ASC38C0800:
        !           279:                        eep_config = adw_38C0800_Default_EEPROM;
        !           280:                        break;
        !           281:                case ADW_CHIP_ASC38C1600:
        !           282:                        eep_config = adw_38C1600_Default_EEPROM;
        !           283:
        !           284: // XXX   TODO!!!       if (ASC_PCI_ID2FUNC(sc->cfg.pci_slot_info) != 0) {
        !           285:                        if (sc->cfg.pci_slot_info != 0) {
        !           286:                                u_int8_t lsw_msb;
        !           287:
        !           288:                                lsw_msb = eep_config.cfg_lsw >> 8;
        !           289:                                /*
        !           290:                                 * Set Function 1 EEPROM Word 0 MSB
        !           291:                                 *
        !           292:                                 * Clear the BIOS_ENABLE (bit 14) and
        !           293:                                 * INTAB (bit 11) EEPROM bits.
        !           294:                                 *
        !           295:                                 * Disable Bit 14 (BIOS_ENABLE) to fix
        !           296:                                 * SPARC Ultra 60 and old Mac system booting
        !           297:                                 * problem. The Expansion ROM must
        !           298:                                 * be disabled in Function 1 for these systems.
        !           299:                                 */
        !           300:                                lsw_msb &= ~(((ADW_EEPROM_BIOS_ENABLE |
        !           301:                                                ADW_EEPROM_INTAB) >> 8) & 0xFF);
        !           302:                                /*
        !           303:                                 * Set the INTAB (bit 11) if the GPIO 0 input
        !           304:                                 * indicates the Function 1 interrupt line is
        !           305:                                 * wired to INTA.
        !           306:                                 *
        !           307:                                 * Set/Clear Bit 11 (INTAB) from
        !           308:                                 * the GPIO bit 0 input:
        !           309:                                 *   1 - Function 1 intr line wired to INT A.
        !           310:                                 *   0 - Function 1 intr line wired to INT B.
        !           311:                                 *
        !           312:                                 * Note: Adapter boards always have Function 0
        !           313:                                 * wired to INTA.
        !           314:                                 * Put all 5 GPIO bits in input mode and then
        !           315:                                 * read their input values.
        !           316:                                 */
        !           317:                                ADW_WRITE_BYTE_REGISTER(iot, ioh,
        !           318:                                                        IOPB_GPIO_CNTL, 0);
        !           319:                                if (ADW_READ_BYTE_REGISTER(iot, ioh,
        !           320:                                                IOPB_GPIO_DATA) & 0x01) {
        !           321:                                        /*
        !           322:                                         * Function 1 interrupt wired to INTA;
        !           323:                                         * Set EEPROM bit.
        !           324:                                         */
        !           325:                                        lsw_msb |= (ADW_EEPROM_INTAB >> 8)
        !           326:                                                         & 0xFF;
        !           327:                                 }
        !           328:                                 eep_config.cfg_lsw &= 0x00FF;
        !           329:                                 eep_config.cfg_lsw |= lsw_msb << 8;
        !           330:                        }
        !           331:                        break;
        !           332:                }
        !           333:
        !           334:                /*
        !           335:                 * Assume the 6 byte board serial number that was read
        !           336:                 * from EEPROM is correct even if the EEPROM checksum
        !           337:                 * failed.
        !           338:                 */
        !           339:                for (i=2, j=1; i>=0; i--, j++) {
        !           340:                eep_config.serial_number[i] =
        !           341:                        AdwReadEEPWord(iot, ioh, ADW_EEP_DVC_CFG_END - j);
        !           342:                }
        !           343:
        !           344:                AdwSetEEPROMConfig(iot, ioh, &eep_config);
        !           345:        }
        !           346:        /*
        !           347:         * Set sc and sc->cfg variables from the EEPROM configuration
        !           348:         * that was read.
        !           349:         *
        !           350:         * This is the mapping of EEPROM fields to Adw Library fields.
        !           351:         */
        !           352:        sc->wdtr_able = eep_config.wdtr_able;
        !           353:        if (sc->chip_type == ADW_CHIP_ASC3550) {
        !           354:                sc->sdtr_able = eep_config.sdtr1.sdtr_able;
        !           355:                sc->ultra_able = eep_config.sdtr2.ultra_able;
        !           356:        } else {
        !           357:                sc->sdtr_speed1 = eep_config.sdtr1.sdtr_speed1;
        !           358:                sc->sdtr_speed2 = eep_config.sdtr2.sdtr_speed2;
        !           359:                sc->sdtr_speed3 = eep_config.sdtr3.sdtr_speed3;
        !           360:                sc->sdtr_speed4 = eep_config.sdtr4.sdtr_speed4;
        !           361:        }
        !           362:        sc->ppr_able = 0;
        !           363:        sc->tagqng_able = eep_config.tagqng_able;
        !           364:        sc->cfg.disc_enable = eep_config.disc_enable;
        !           365:        sc->max_host_qng = eep_config.max_host_qng;
        !           366:        sc->max_dvc_qng = eep_config.max_dvc_qng;
        !           367:        sc->chip_scsi_id = (eep_config.adapter_scsi_id & ADW_MAX_TID);
        !           368:        sc->start_motor = eep_config.start_motor;
        !           369:        sc->scsi_reset_wait = eep_config.scsi_reset_delay;
        !           370:        sc->bios_ctrl = eep_config.bios_ctrl;
        !           371:        sc->no_scam = eep_config.scam_tolerant;
        !           372:        sc->cfg.serial1 = eep_config.serial_number[0];
        !           373:        sc->cfg.serial2 = eep_config.serial_number[1];
        !           374:        sc->cfg.serial3 = eep_config.serial_number[2];
        !           375:
        !           376:        if (sc->chip_type == ADW_CHIP_ASC38C0800 ||
        !           377:            sc->chip_type == ADW_CHIP_ASC38C1600) {
        !           378:                sc->sdtr_able = 0;
        !           379:                for (tid = 0; tid <= ADW_MAX_TID; tid++) {
        !           380:                        if (tid == 0) {
        !           381:                                sdtr_speed = sc->sdtr_speed1;
        !           382:                        } else if (tid == 4) {
        !           383:                                sdtr_speed = sc->sdtr_speed2;
        !           384:                        } else if (tid == 8) {
        !           385:                                sdtr_speed = sc->sdtr_speed3;
        !           386:                        } else if (tid == 12) {
        !           387:                                sdtr_speed = sc->sdtr_speed4;
        !           388:                        }
        !           389:                        if (sdtr_speed & ADW_MAX_TID) {
        !           390:                                sc->sdtr_able |= (1 << tid);
        !           391:                        }
        !           392:                        sdtr_speed >>= 4;
        !           393:                }
        !           394:        }
        !           395:
        !           396:        /*
        !           397:         * Set the host maximum queuing (max. 253, min. 16) and the per device
        !           398:         * maximum queuing (max. 63, min. 4).
        !           399:         */
        !           400:        if (eep_config.max_host_qng > ADW_DEF_MAX_HOST_QNG) {
        !           401:                eep_config.max_host_qng = ADW_DEF_MAX_HOST_QNG;
        !           402:        } else if (eep_config.max_host_qng < ADW_DEF_MIN_HOST_QNG)
        !           403:        {
        !           404:                /* If the value is zero, assume it is uninitialized. */
        !           405:                if (eep_config.max_host_qng == 0) {
        !           406:                        eep_config.max_host_qng = ADW_DEF_MAX_HOST_QNG;
        !           407:                } else {
        !           408:                        eep_config.max_host_qng = ADW_DEF_MIN_HOST_QNG;
        !           409:                }
        !           410:        }
        !           411:
        !           412:        if (eep_config.max_dvc_qng > ADW_DEF_MAX_DVC_QNG) {
        !           413:                eep_config.max_dvc_qng = ADW_DEF_MAX_DVC_QNG;
        !           414:        } else if (eep_config.max_dvc_qng < ADW_DEF_MIN_DVC_QNG) {
        !           415:                /* If the value is zero, assume it is uninitialized. */
        !           416:                if (eep_config.max_dvc_qng == 0) {
        !           417:                        eep_config.max_dvc_qng = ADW_DEF_MAX_DVC_QNG;
        !           418:                } else {
        !           419:                        eep_config.max_dvc_qng = ADW_DEF_MIN_DVC_QNG;
        !           420:                }
        !           421:        }
        !           422:
        !           423:        /*
        !           424:         * If 'max_dvc_qng' is greater than 'max_host_qng', then
        !           425:         * set 'max_dvc_qng' to 'max_host_qng'.
        !           426:         */
        !           427:        if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
        !           428:                eep_config.max_dvc_qng = eep_config.max_host_qng;
        !           429:        }
        !           430:
        !           431:        /*
        !           432:         * Set ADW_SOFTC 'max_host_qng' and 'max_dvc_qng'
        !           433:         * values based on possibly adjusted EEPROM values.
        !           434:         */
        !           435:        sc->max_host_qng = eep_config.max_host_qng;
        !           436:        sc->max_dvc_qng = eep_config.max_dvc_qng;
        !           437:
        !           438:
        !           439:        /*
        !           440:         * If the EEPROM 'termination' field is set to automatic (0), then set
        !           441:         * the ADW_SOFTC.cfg 'termination' field to automatic also.
        !           442:         *
        !           443:         * If the termination is specified with a non-zero 'termination'
        !           444:         * value check that a legal value is set and set the ADW_SOFTC.cfg
        !           445:         * 'termination' field appropriately.
        !           446:         */
        !           447:
        !           448:        switch(sc->chip_type) {
        !           449:        case ADW_CHIP_ASC3550:
        !           450:                sc->cfg.termination = 0;        /* auto termination */
        !           451:                switch(eep_config.termination_se) {
        !           452:                case 3:
        !           453:                        /* Enable manual control with low on / high on. */
        !           454:                        sc->cfg.termination |= ADW_TERM_CTL_L;
        !           455:                case 2:
        !           456:                        /* Enable manual control with low off / high on. */
        !           457:                        sc->cfg.termination |= ADW_TERM_CTL_H;
        !           458:                case 1:
        !           459:                        /* Enable manual control with low off / high off. */
        !           460:                        sc->cfg.termination |= ADW_TERM_CTL_SEL;
        !           461:                case 0:
        !           462:                        break;
        !           463:                default:
        !           464:                        warn_code |= ADW_WARN_EEPROM_TERMINATION;
        !           465:                }
        !           466:                break;
        !           467:
        !           468:        case ADW_CHIP_ASC38C0800:
        !           469:        case ADW_CHIP_ASC38C1600:
        !           470:                switch(eep_config.termination_se) {
        !           471:                case 0:
        !           472:                        /* auto termination for SE */
        !           473:                        termination = 0;
        !           474:                        break;
        !           475:                case 1:
        !           476:                        /* Enable manual control with low off / high off. */
        !           477:                        termination = 0;
        !           478:                        break;
        !           479:                case 2:
        !           480:                        /* Enable manual control with low off / high on. */
        !           481:                        termination = ADW_TERM_SE_HI;
        !           482:                        break;
        !           483:                case 3:
        !           484:                        /* Enable manual control with low on / high on. */
        !           485:                        termination = ADW_TERM_SE;
        !           486:                        break;
        !           487:                default:
        !           488:                        /*
        !           489:                         * The EEPROM 'termination_se' field contains a
        !           490:                         * bad value. Use automatic termination instead.
        !           491:                         */
        !           492:                        termination = 0;
        !           493:                        warn_code |= ADW_WARN_EEPROM_TERMINATION;
        !           494:                }
        !           495:
        !           496:                switch(eep_config.termination_lvd) {
        !           497:                case 0:
        !           498:                        /* auto termination for LVD */
        !           499:                        sc->cfg.termination = termination;
        !           500:                        break;
        !           501:                case 1:
        !           502:                        /* Enable manual control with low off / high off. */
        !           503:                        sc->cfg.termination = termination;
        !           504:                        break;
        !           505:                case 2:
        !           506:                        /* Enable manual control with low off / high on. */
        !           507:                        sc->cfg.termination = termination | ADW_TERM_LVD_HI;
        !           508:                        break;
        !           509:                case 3:
        !           510:                        /* Enable manual control with low on / high on. */
        !           511:                        sc->cfg.termination = termination | ADW_TERM_LVD;
        !           512:                        break;
        !           513:                default:
        !           514:                        /*
        !           515:                         * The EEPROM 'termination_lvd' field contains a
        !           516:                         * bad value. Use automatic termination instead.
        !           517:                         */
        !           518:                        sc->cfg.termination = termination;
        !           519:                        warn_code |= ADW_WARN_EEPROM_TERMINATION;
        !           520:                }
        !           521:                break;
        !           522:        }
        !           523:
        !           524:        return warn_code;
        !           525: }
        !           526:
        !           527:
        !           528: /*
        !           529:  * Initialize the ASC-3550/ASC-38C0800/ASC-38C1600.
        !           530:  *
        !           531:  * On failure return the error code.
        !           532:  */
        !           533: int
        !           534: AdwInitDriver(sc)
        !           535: ADW_SOFTC      *sc;
        !           536: {
        !           537:        bus_space_tag_t iot = sc->sc_iot;
        !           538:        bus_space_handle_t ioh = sc->sc_ioh;
        !           539:        u_int16_t       error_code;
        !           540:        int             word;
        !           541:        int             i;
        !           542:        u_int16_t       bios_mem[ADW_MC_BIOSLEN/2];     /* BIOS RISC Memory
        !           543:                                                                0x40-0x8F. */
        !           544:        u_int16_t       wdtr_able = 0, sdtr_able, ppr_able, tagqng_able;
        !           545:        u_int8_t        max_cmd[ADW_MAX_TID + 1];
        !           546:        u_int8_t        tid;
        !           547:
        !           548:
        !           549:        error_code = 0;
        !           550:
        !           551:        /*
        !           552:         * Save the RISC memory BIOS region before writing the microcode.
        !           553:         * The BIOS may already be loaded and using its RISC LRAM region
        !           554:         * so its region must be saved and restored.
        !           555:         *
        !           556:         * Note: This code makes the assumption, which is currently true,
        !           557:         * that a chip reset does not clear RISC LRAM.
        !           558:         */
        !           559:        for (i = 0; i < ADW_MC_BIOSLEN/2; i++) {
        !           560:                ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_BIOSMEM+(2*i), bios_mem[i]);
        !           561:        }
        !           562:
        !           563:        /*
        !           564:         * Save current per TID negotiated values.
        !           565:         */
        !           566:        switch (sc->chip_type) {
        !           567:        case ADW_CHIP_ASC3550:
        !           568:                if (bios_mem[(ADW_MC_BIOS_SIGNATURE-ADW_MC_BIOSMEM)/2]==0x55AA){
        !           569:
        !           570:                        u_int16_t  bios_version, major, minor;
        !           571:
        !           572:                        bios_version = bios_mem[(ADW_MC_BIOS_VERSION -
        !           573:                                        ADW_MC_BIOSMEM) / 2];
        !           574:                        major = (bios_version  >> 12) & 0xF;
        !           575:                        minor = (bios_version  >> 8) & 0xF;
        !           576:                        if (major < 3 || (major == 3 && minor == 1)) {
        !           577:                            /*
        !           578:                             * BIOS 3.1 and earlier location of
        !           579:                             * 'wdtr_able' variable.
        !           580:                             */
        !           581:                            ADW_READ_WORD_LRAM(iot, ioh, 0x120, wdtr_able);
        !           582:                        } else {
        !           583:                            ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE,
        !           584:                                            wdtr_able);
        !           585:                        }
        !           586:                }
        !           587:                break;
        !           588:
        !           589:        case ADW_CHIP_ASC38C1600:
        !           590:                ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_PPR_ABLE, ppr_able);
        !           591:                /* FALLTHROUGH */
        !           592:        case ADW_CHIP_ASC38C0800:
        !           593:                ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, wdtr_able);
        !           594:                break;
        !           595:        }
        !           596:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, sdtr_able);
        !           597:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE, tagqng_able);
        !           598:        for (tid = 0; tid <= ADW_MAX_TID; tid++) {
        !           599:                ADW_READ_BYTE_LRAM(iot, ioh, ADW_MC_NUMBER_OF_MAX_CMD + tid,
        !           600:                        max_cmd[tid]);
        !           601:        }
        !           602:
        !           603:        /*
        !           604:         * Perform a RAM Built-In Self Test
        !           605:         */
        !           606:        if((error_code = AdwRamSelfTest(iot, ioh, sc->chip_type))) {
        !           607:                return error_code;
        !           608:        }
        !           609:
        !           610:        /*
        !           611:         * Load the Microcode
        !           612:         */
        !           613:        ;
        !           614:        if((error_code = AdwLoadMCode(iot, ioh, bios_mem, sc->chip_type))) {
        !           615:                return error_code;
        !           616:        }
        !           617:
        !           618:        /*
        !           619:         * Read microcode version and date.
        !           620:         */
        !           621:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_VERSION_DATE, sc->cfg.mcode_date);
        !           622:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_VERSION_NUM, sc->cfg.mcode_version);
        !           623:
        !           624:        /*
        !           625:         * If the PCI Configuration Command Register "Parity Error Response
        !           626:         * Control" Bit was clear (0), then set the microcode variable
        !           627:         * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
        !           628:         * to ignore DMA parity errors.
        !           629:         */
        !           630:        if (sc->cfg.control_flag & CONTROL_FLAG_IGNORE_PERR) {
        !           631:                ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_CONTROL_FLAG, word);
        !           632:                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_CONTROL_FLAG,
        !           633:                                        word | CONTROL_FLAG_IGNORE_PERR);
        !           634:        }
        !           635:
        !           636:        switch (sc->chip_type) {
        !           637:        case ADW_CHIP_ASC3550:
        !           638:                /*
        !           639:                 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a
        !           640:                 * FIFO threshold of 128 bytes.
        !           641:                 * This register is only accessible to the host.
        !           642:                 */
        !           643:                ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_DMA_CFG0,
        !           644:                                START_CTL_EMFU | READ_CMD_MRM);
        !           645:                break;
        !           646:
        !           647:        case ADW_CHIP_ASC38C0800:
        !           648:                /*
        !           649:                 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
        !           650:                 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
        !           651:                 * cable detection and then we are able to read C_DET[3:0].
        !           652:                 *
        !           653:                 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
        !           654:                 * Microcode Default Value' section below.
        !           655:                 */
        !           656:                ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1,
        !           657:                                ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1)
        !           658:                                | ADW_DIS_TERM_DRV);
        !           659:
        !           660:                /*
        !           661:                 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and
        !           662:                 * START_CTL_TH [3:2] bits for the default FIFO threshold.
        !           663:                 *
        !           664:                 * Note: ASC-38C0800 FIFO threshold has been changed to
        !           665:                 * 256 bytes.
        !           666:                 *
        !           667:                 * For DMA Errata #4 set the BC_THRESH_ENB bit.
        !           668:                 */
        !           669:                ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_DMA_CFG0,
        !           670:                                                BC_THRESH_ENB | FIFO_THRESH_80B
        !           671:                                                | START_CTL_TH | READ_CMD_MRM);
        !           672:                break;
        !           673:
        !           674:        case ADW_CHIP_ASC38C1600:
        !           675:                /*
        !           676:                 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
        !           677:                 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
        !           678:                 * cable detection and then we are able to read C_DET[3:0].
        !           679:                 *
        !           680:                 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
        !           681:                 * Microcode Default Value' section below.
        !           682:                 */
        !           683:                ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1,
        !           684:                                ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1)
        !           685:                                | ADW_DIS_TERM_DRV);
        !           686:
        !           687:                /*
        !           688:                 * If the BIOS control flag AIPP (Asynchronous Information
        !           689:                 * Phase Protection) disable bit is not set, then set the
        !           690:                 * firmware 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to
        !           691:                 * enable AIPP checking and encoding.
        !           692:                 */
        !           693:                if ((sc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
        !           694:                        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_CONTROL_FLAG, word);
        !           695:                        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_CONTROL_FLAG,
        !           696:                                        word | CONTROL_FLAG_ENABLE_AIPP);
        !           697:                }
        !           698:
        !           699:                /*
        !           700:                 * For ASC-38C1600 use DMA_CFG0 default values:
        !           701:                 * FIFO_THRESH_80B [6:4], and START_CTL_TH [3:2].
        !           702:                 */
        !           703:                ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_DMA_CFG0,
        !           704:                                FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
        !           705:                break;
        !           706:        }
        !           707:
        !           708:        /*
        !           709:         * Microcode operating variables for WDTR, SDTR, and command tag
        !           710:         * queuing will be set in AdwInquiryHandling() based on what a
        !           711:         * device reports it is capable of in Inquiry byte 7.
        !           712:         *
        !           713:         * If SCSI Bus Resets have been disabled, then directly set
        !           714:         * SDTR and WDTR from the EEPROM configuration. This will allow
        !           715:         * the BIOS and warm boot to work without a SCSI bus hang on
        !           716:         * the Inquiry caused by host and target mismatched DTR values.
        !           717:         * Without the SCSI Bus Reset, before an Inquiry a device can't
        !           718:         * be assumed to be in Asynchronous, Narrow mode.
        !           719:         */
        !           720:        if ((sc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
        !           721:                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, sc->wdtr_able);
        !           722:                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, sc->sdtr_able);
        !           723:        }
        !           724:
        !           725:        /*
        !           726:         * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
        !           727:         * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
        !           728:         * bitmask. These values determine the maximum SDTR speed negotiated
        !           729:         * with a device.
        !           730:         *
        !           731:         * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
        !           732:         * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
        !           733:         * without determining here whether the device supports SDTR.
        !           734:         */
        !           735:        switch (sc->chip_type) {
        !           736:        case ADW_CHIP_ASC3550:
        !           737:                word = 0;
        !           738:                for (tid = 0; tid <= ADW_MAX_TID; tid++) {
        !           739:                        if (ADW_TID_TO_TIDMASK(tid) & sc->ultra_able) {
        !           740:                                /* Set Ultra speed for TID 'tid'. */
        !           741:                                word |= (0x3 << (4 * (tid % 4)));
        !           742:                        } else {
        !           743:                                /* Set Fast speed for TID 'tid'. */
        !           744:                                word |= (0x2 << (4 * (tid % 4)));
        !           745:                        }
        !           746:                        /* Check if done with sdtr_speed1. */
        !           747:                        if (tid == 3) {
        !           748:                                ADW_WRITE_WORD_LRAM(iot, ioh,
        !           749:                                                ADW_MC_SDTR_SPEED1, word);
        !           750:                                word = 0;
        !           751:                        /* Check if done with sdtr_speed2. */
        !           752:                        } else if (tid == 7) {
        !           753:                                ADW_WRITE_WORD_LRAM(iot, ioh,
        !           754:                                                ADW_MC_SDTR_SPEED2, word);
        !           755:                                word = 0;
        !           756:                        /* Check if done with sdtr_speed3. */
        !           757:                        } else if (tid == 11) {
        !           758:                                ADW_WRITE_WORD_LRAM(iot, ioh,
        !           759:                                                ADW_MC_SDTR_SPEED3, word);
        !           760:                                word = 0;
        !           761:                        /* Check if done with sdtr_speed4. */
        !           762:                        } else if (tid == 15) {
        !           763:                                ADW_WRITE_WORD_LRAM(iot, ioh,
        !           764:                                                ADW_MC_SDTR_SPEED4, word);
        !           765:                                /* End of loop. */
        !           766:                        }
        !           767:                }
        !           768:
        !           769:                /*
        !           770:                 * Set microcode operating variable for the
        !           771:                 * disconnect per TID bitmask.
        !           772:                 */
        !           773:                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DISC_ENABLE,
        !           774:                                                        sc->cfg.disc_enable);
        !           775:                break;
        !           776:
        !           777:        case ADW_CHIP_ASC38C0800:
        !           778:                /* FALLTHROUGH */
        !           779:        case ADW_CHIP_ASC38C1600:
        !           780:                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DISC_ENABLE,
        !           781:                                                        sc->cfg.disc_enable);
        !           782:                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_SPEED1,
        !           783:                                                        sc->sdtr_speed1);
        !           784:                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_SPEED2,
        !           785:                                                        sc->sdtr_speed2);
        !           786:                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_SPEED3,
        !           787:                                                        sc->sdtr_speed3);
        !           788:                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_SPEED4,
        !           789:                                                        sc->sdtr_speed4);
        !           790:                break;
        !           791:        }
        !           792:
        !           793:
        !           794:        /*
        !           795:         * Set SCSI_CFG0 Microcode Default Value.
        !           796:         *
        !           797:         * The microcode will set the SCSI_CFG0 register using this value
        !           798:         * after it is started below.
        !           799:         */
        !           800:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_SCSI_CFG0,
        !           801:                ADW_PARITY_EN | ADW_QUEUE_128 | ADW_SEL_TMO_LONG |
        !           802:                ADW_OUR_ID_EN | sc->chip_scsi_id);
        !           803:
        !           804:
        !           805:        switch(sc->chip_type) {
        !           806:        case ADW_CHIP_ASC3550:
        !           807:                error_code = AdwASC3550Cabling(iot, ioh, &sc->cfg);
        !           808:                break;
        !           809:
        !           810:        case ADW_CHIP_ASC38C0800:
        !           811:                error_code = AdwASC38C0800Cabling(iot, ioh, &sc->cfg);
        !           812:                break;
        !           813:
        !           814:        case ADW_CHIP_ASC38C1600:
        !           815:                error_code = AdwASC38C1600Cabling(iot, ioh, &sc->cfg);
        !           816:                break;
        !           817:        }
        !           818:        if(error_code) {
        !           819:                return error_code;
        !           820:        }
        !           821:
        !           822:        /*
        !           823:         * Set SEL_MASK Microcode Default Value
        !           824:         *
        !           825:         * The microcode will set the SEL_MASK register using this value
        !           826:         * after it is started below.
        !           827:         */
        !           828:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_SEL_MASK,
        !           829:                ADW_TID_TO_TIDMASK(sc->chip_scsi_id));
        !           830:
        !           831:        /*
        !           832:         * Create and Initialize Host->RISC Carrier lists
        !           833:         */
        !           834:        sc->carr_freelist = AdwInitCarriers(sc->sc_dmamap_carrier,
        !           835:                                                sc->sc_control->carriers);
        !           836:
        !           837:        /*
        !           838:         * Set-up the Host->RISC Initiator Command Queue (ICQ).
        !           839:         */
        !           840:
        !           841:        if ((sc->icq_sp = sc->carr_freelist) == NULL) {
        !           842:                return ADW_IERR_NO_CARRIER;
        !           843:        }
        !           844:        sc->carr_freelist = ADW_CARRIER_VADDR(sc,
        !           845:                        ADW_GET_CARRP(sc->icq_sp->next_ba));
        !           846:
        !           847:        /*
        !           848:         * The first command issued will be placed in the stopper carrier.
        !           849:         */
        !           850:        sc->icq_sp->next_ba = ADW_CQ_STOPPER;
        !           851:
        !           852:        /*
        !           853:         * Set RISC ICQ physical address start value.
        !           854:         */
        !           855:        ADW_WRITE_DWORD_LRAM(iot, ioh, ADW_MC_ICQ, sc->icq_sp->carr_ba);
        !           856:
        !           857:        /*
        !           858:         * Initialize the COMMA register to the same value otherwise
        !           859:         * the RISC will prematurely detect a command is available.
        !           860:         */
        !           861:        if(sc->chip_type == ADW_CHIP_ASC38C1600) {
        !           862:                ADW_WRITE_DWORD_REGISTER(iot, ioh, IOPDW_COMMA,
        !           863:                                                        sc->icq_sp->carr_ba);
        !           864:        }
        !           865:
        !           866:        /*
        !           867:         * Set-up the RISC->Host Initiator Response Queue (IRQ).
        !           868:         */
        !           869:        if ((sc->irq_sp = sc->carr_freelist) == NULL) {
        !           870:                return ADW_IERR_NO_CARRIER;
        !           871:        }
        !           872:        sc->carr_freelist = ADW_CARRIER_VADDR(sc,
        !           873:                        ADW_GET_CARRP(sc->irq_sp->next_ba));
        !           874:
        !           875:        /*
        !           876:         * The first command completed by the RISC will be placed in
        !           877:         * the stopper.
        !           878:         *
        !           879:         * Note: Set 'next_ba' to ADW_CQ_STOPPER. When the request is
        !           880:         * completed the RISC will set the ADW_RQ_DONE bit.
        !           881:         */
        !           882:        sc->irq_sp->next_ba = ADW_CQ_STOPPER;
        !           883:
        !           884:        /*
        !           885:         * Set RISC IRQ physical address start value.
        !           886:         */
        !           887:        ADW_WRITE_DWORD_LRAM(iot, ioh, ADW_MC_IRQ, sc->irq_sp->carr_ba);
        !           888:        sc->carr_pending_cnt = 0;
        !           889:
        !           890:        ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_INTR_ENABLES,
        !           891:                (ADW_INTR_ENABLE_HOST_INTR | ADW_INTR_ENABLE_GLOBAL_INTR));
        !           892:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_CODE_BEGIN_ADDR, word);
        !           893:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_PC, word);
        !           894:
        !           895:        /* finally, finally, gentlemen, start your engine */
        !           896:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RISC_CSR, ADW_RISC_CSR_RUN);
        !           897:
        !           898:        /*
        !           899:         * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
        !           900:         * Resets should be performed. The RISC has to be running
        !           901:         * to issue a SCSI Bus Reset.
        !           902:         */
        !           903:        if (sc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
        !           904:        {
        !           905:                /*
        !           906:                 * If the BIOS Signature is present in memory, restore the
        !           907:                 * BIOS Handshake Configuration Table and do not perform
        !           908:                 * a SCSI Bus Reset.
        !           909:                 */
        !           910:                if (bios_mem[(ADW_MC_BIOS_SIGNATURE - ADW_MC_BIOSMEM)/2] ==
        !           911:                                0x55AA) {
        !           912:                        /*
        !           913:                         * Restore per TID negotiated values.
        !           914:                         */
        !           915:                        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE,
        !           916:                                        wdtr_able);
        !           917:                        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE,
        !           918:                                        sdtr_able);
        !           919:                        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE,
        !           920:                                        tagqng_able);
        !           921:                        for (tid = 0; tid <= ADW_MAX_TID; tid++) {
        !           922:                                ADW_WRITE_BYTE_LRAM(iot, ioh,
        !           923:                                                ADW_MC_NUMBER_OF_MAX_CMD + tid,
        !           924:                                                max_cmd[tid]);
        !           925:                        }
        !           926:                } else {
        !           927:                        if (AdwResetCCB(sc) != ADW_TRUE) {
        !           928:                                error_code = ADW_WARN_BUSRESET_ERROR;
        !           929:                        }
        !           930:                }
        !           931:        }
        !           932:
        !           933:        return error_code;
        !           934: }
        !           935:
        !           936:
        !           937: int
        !           938: AdwRamSelfTest(iot, ioh, chip_type)
        !           939:        bus_space_tag_t iot;
        !           940:        bus_space_handle_t ioh;
        !           941:        u_int8_t chip_type;
        !           942: {
        !           943:        int             i;
        !           944:        u_int8_t        byte;
        !           945:
        !           946:
        !           947:        if ((chip_type == ADW_CHIP_ASC38C0800) ||
        !           948:            (chip_type == ADW_CHIP_ASC38C1600)) {
        !           949:                /*
        !           950:                 * RAM BIST (RAM Built-In Self Test)
        !           951:                 *
        !           952:                 * Address : I/O base + offset 0x38h register (byte).
        !           953:                 * Function: Bit 7-6(RW) : RAM mode
        !           954:                 *                          Normal Mode   : 0x00
        !           955:                 *                          Pre-test Mode : 0x40
        !           956:                 *                          RAM Test Mode : 0x80
        !           957:                 *           Bit 5       : unused
        !           958:                 *           Bit 4(RO)   : Done bit
        !           959:                 *           Bit 3-0(RO) : Status
        !           960:                 *                          Host Error    : 0x08
        !           961:                 *                          Int_RAM Error : 0x04
        !           962:                 *                          RISC Error    : 0x02
        !           963:                 *                          SCSI Error    : 0x01
        !           964:                 *                          No Error      : 0x00
        !           965:                 *
        !           966:                 * Note: RAM BIST code should be put right here, before loading
        !           967:                 * the microcode and after saving the RISC memory BIOS region.
        !           968:                 */
        !           969:
        !           970:                /*
        !           971:                 * LRAM Pre-test
        !           972:                 *
        !           973:                 * Write PRE_TEST_MODE (0x40) to register and wait for
        !           974:                 * 10 milliseconds.
        !           975:                 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05),
        !           976:                 * return an error. Reset to NORMAL_MODE (0x00) and do again.
        !           977:                 * If cannot reset to NORMAL_MODE, return an error too.
        !           978:                 */
        !           979:                for (i = 0; i < 2; i++) {
        !           980:                        ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST,
        !           981:                                        PRE_TEST_MODE);
        !           982:                         /* Wait for 10ms before reading back. */
        !           983:                        AdwSleepMilliSecond(10);
        !           984:                        byte = ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST);
        !           985:                        if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) !=
        !           986:                                        PRE_TEST_VALUE) {
        !           987:                                return ADW_IERR_BIST_PRE_TEST;
        !           988:                        }
        !           989:
        !           990:                        ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST,
        !           991:                                                                NORMAL_MODE);
        !           992:                        /* Wait for 10ms before reading back. */
        !           993:                        AdwSleepMilliSecond(10);
        !           994:                        if (ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST)
        !           995:                            != NORMAL_VALUE) {
        !           996:                                return ADW_IERR_BIST_PRE_TEST;
        !           997:                        }
        !           998:                }
        !           999:
        !          1000:                /*
        !          1001:                 * LRAM Test - It takes about 1.5 ms to run through the test.
        !          1002:                 *
        !          1003:                 * Write RAM_TEST_MODE (0x80) to register and wait for
        !          1004:                 * 10 milliseconds.
        !          1005:                 * If Done bit not set or Status not 0, save register byte,
        !          1006:                 * set the err_code, and return an error.
        !          1007:                 */
        !          1008:                ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST, RAM_TEST_MODE);
        !          1009:                /* Wait for 10ms before checking status. */
        !          1010:                AdwSleepMilliSecond(10);
        !          1011:
        !          1012:                byte = ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST);
        !          1013:                if ((byte & RAM_TEST_DONE)==0 || (byte & RAM_TEST_STATUS)!=0) {
        !          1014:                        /* Get here if Done bit not set or Status not 0. */
        !          1015:                        return ADW_IERR_BIST_RAM_TEST;
        !          1016:                }
        !          1017:
        !          1018:                /* We need to reset back to normal mode after LRAM test passes*/
        !          1019:                ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST, NORMAL_MODE);
        !          1020:        }
        !          1021:
        !          1022:        return 0;
        !          1023: }
        !          1024:
        !          1025:
        !          1026: int
        !          1027: AdwLoadMCode(iot, ioh, bios_mem, chip_type)
        !          1028:        bus_space_tag_t iot;
        !          1029:        bus_space_handle_t ioh;
        !          1030:        u_int16_t *bios_mem;
        !          1031:        u_int8_t chip_type;
        !          1032: {
        !          1033:        u_int8_t        *mcode_data;
        !          1034:        u_int32_t        mcode_chksum;
        !          1035:        u_int16_t        mcode_size;
        !          1036:        u_int32_t       sum;
        !          1037:        u_int16_t       code_sum;
        !          1038:        int             begin_addr;
        !          1039:        int             end_addr;
        !          1040:        int             word;
        !          1041:        int             adw_memsize;
        !          1042:        int             adw_mcode_expanded_size;
        !          1043:        int             i, j;
        !          1044:
        !          1045:
        !          1046:        switch(chip_type) {
        !          1047:        case ADW_CHIP_ASC3550:
        !          1048:                mcode_data = (u_int8_t *)adw_asc3550_mcode_data.mcode_data;
        !          1049:                mcode_chksum = (u_int32_t)adw_asc3550_mcode_data.mcode_chksum;
        !          1050:                mcode_size = (u_int16_t)adw_asc3550_mcode_data.mcode_size;
        !          1051:                adw_memsize = ADW_3550_MEMSIZE;
        !          1052:                break;
        !          1053:
        !          1054:        case ADW_CHIP_ASC38C0800:
        !          1055:                mcode_data = (u_int8_t *)adw_asc38C0800_mcode_data.mcode_data;
        !          1056:                mcode_chksum =(u_int32_t)adw_asc38C0800_mcode_data.mcode_chksum;
        !          1057:                mcode_size = (u_int16_t)adw_asc38C0800_mcode_data.mcode_size;
        !          1058:                adw_memsize = ADW_38C0800_MEMSIZE;
        !          1059:                break;
        !          1060:
        !          1061:        case ADW_CHIP_ASC38C1600:
        !          1062:                mcode_data = (u_int8_t *)adw_asc38C1600_mcode_data.mcode_data;
        !          1063:                mcode_chksum =(u_int32_t)adw_asc38C1600_mcode_data.mcode_chksum;
        !          1064:                mcode_size = (u_int16_t)adw_asc38C1600_mcode_data.mcode_size;
        !          1065:                adw_memsize = ADW_38C1600_MEMSIZE;
        !          1066:                break;
        !          1067:        }
        !          1068:
        !          1069:        /*
        !          1070:         * Write the microcode image to RISC memory starting at address 0.
        !          1071:         */
        !          1072:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, 0);
        !          1073:
        !          1074:        /* Assume the following compressed format of the microcode buffer:
        !          1075:         *
        !          1076:         *  254 word (508 byte) table indexed by byte code followed
        !          1077:         *  by the following byte codes:
        !          1078:         *
        !          1079:         *    1-Byte Code:
        !          1080:         *      00: Emit word 0 in table.
        !          1081:         *      01: Emit word 1 in table.
        !          1082:         *      .
        !          1083:         *      FD: Emit word 253 in table.
        !          1084:         *
        !          1085:         *    Multi-Byte Code:
        !          1086:         *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
        !          1087:         *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
        !          1088:         */
        !          1089:        word = 0;
        !          1090:        for (i = 253 * 2; i < mcode_size; i++) {
        !          1091:                if (mcode_data[i] == 0xff) {
        !          1092:                        for (j = 0; j < mcode_data[i + 1]; j++) {
        !          1093:                                ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh,
        !          1094:                                  (((u_int16_t)mcode_data[i + 3] << 8) |
        !          1095:                                  mcode_data[i + 2]));
        !          1096:                                word++;
        !          1097:                        }
        !          1098:                        i += 3;
        !          1099:                } else if (mcode_data[i] == 0xfe) {
        !          1100:                        ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh,
        !          1101:                            (((u_int16_t)mcode_data[i + 2] << 8) |
        !          1102:                            mcode_data[i + 1]));
        !          1103:                        i += 2;
        !          1104:                        word++;
        !          1105:                } else {
        !          1106:                        ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, (((u_int16_t)
        !          1107:                         mcode_data[(mcode_data[i] * 2) + 1] <<8) |
        !          1108:                         mcode_data[mcode_data[i] * 2]));
        !          1109:                        word++;
        !          1110:                }
        !          1111:        }
        !          1112:
        !          1113:        /*
        !          1114:         * Set 'word' for later use to clear the rest of memory and save
        !          1115:         * the expanded mcode size.
        !          1116:         */
        !          1117:        word *= 2;
        !          1118:        adw_mcode_expanded_size = word;
        !          1119:
        !          1120:        /*
        !          1121:         * Clear the rest of the Internal RAM.
        !          1122:         */
        !          1123:        for (; word < adw_memsize; word += 2) {
        !          1124:                ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, 0);
        !          1125:        }
        !          1126:
        !          1127:        /*
        !          1128:         * Verify the microcode checksum.
        !          1129:         */
        !          1130:        sum = 0;
        !          1131:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, 0);
        !          1132:
        !          1133:        for (word = 0; word < adw_mcode_expanded_size; word += 2) {
        !          1134:                sum += ADW_READ_WORD_AUTO_INC_LRAM(iot, ioh);
        !          1135:        }
        !          1136:
        !          1137:        if (sum != mcode_chksum) {
        !          1138:                return ADW_IERR_MCODE_CHKSUM;
        !          1139:        }
        !          1140:
        !          1141:        /*
        !          1142:         * Restore the RISC memory BIOS region.
        !          1143:         */
        !          1144:        for (i = 0; i < ADW_MC_BIOSLEN/2; i++) {
        !          1145:                if(chip_type == ADW_CHIP_ASC3550) {
        !          1146:                        ADW_WRITE_BYTE_LRAM(iot, ioh, ADW_MC_BIOSMEM + (2 * i),
        !          1147:                                                                bios_mem[i]);
        !          1148:                } else {
        !          1149:                        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_BIOSMEM + (2 * i),
        !          1150:                                                                bios_mem[i]);
        !          1151:                }
        !          1152:        }
        !          1153:
        !          1154:        /*
        !          1155:         * Calculate and write the microcode code checksum to the microcode
        !          1156:         * code checksum location ADW_MC_CODE_CHK_SUM (0x2C).
        !          1157:         */
        !          1158:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_CODE_BEGIN_ADDR, begin_addr);
        !          1159:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_CODE_END_ADDR, end_addr);
        !          1160:        code_sum = 0;
        !          1161:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, begin_addr);
        !          1162:        for (word = begin_addr; word < end_addr; word += 2) {
        !          1163:                code_sum += ADW_READ_WORD_AUTO_INC_LRAM(iot, ioh);
        !          1164:        }
        !          1165:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_CODE_CHK_SUM, code_sum);
        !          1166:
        !          1167:        /*
        !          1168:         * Set the chip type.
        !          1169:         */
        !          1170:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_CHIP_TYPE, chip_type);
        !          1171:
        !          1172:        return 0;
        !          1173: }
        !          1174:
        !          1175:
        !          1176: int
        !          1177: AdwASC3550Cabling(iot, ioh, cfg)
        !          1178:        bus_space_tag_t iot;
        !          1179:        bus_space_handle_t ioh;
        !          1180:        ADW_DVC_CFG *cfg;
        !          1181: {
        !          1182:        u_int16_t       scsi_cfg1;
        !          1183:
        !          1184:
        !          1185:        /*
        !          1186:         * Determine SCSI_CFG1 Microcode Default Value.
        !          1187:         *
        !          1188:         * The microcode will set the SCSI_CFG1 register using this value
        !          1189:         * after it is started below.
        !          1190:         */
        !          1191:
        !          1192:        /* Read current SCSI_CFG1 Register value. */
        !          1193:        scsi_cfg1 = ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1);
        !          1194:
        !          1195:        /*
        !          1196:         * If all three connectors are in use in ASC3550, return an error.
        !          1197:         */
        !          1198:        if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
        !          1199:             (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
        !          1200:                return ADW_IERR_ILLEGAL_CONNECTION;
        !          1201:        }
        !          1202:
        !          1203:        /*
        !          1204:         * If the cable is reversed all of the SCSI_CTRL register signals
        !          1205:         * will be set. Check for and return an error if this condition is
        !          1206:         * found.
        !          1207:         */
        !          1208:        if ((ADW_READ_WORD_REGISTER(iot,ioh, IOPW_SCSI_CTRL) & 0x3F07)==0x3F07){
        !          1209:                return ADW_IERR_REVERSED_CABLE;
        !          1210:        }
        !          1211:
        !          1212:        /*
        !          1213:         * If this is a differential board and a single-ended device
        !          1214:         * is attached to one of the connectors, return an error.
        !          1215:         */
        !          1216:        if ((scsi_cfg1 & ADW_DIFF_MODE) &&
        !          1217:            (scsi_cfg1 & ADW_DIFF_SENSE) == 0) {
        !          1218:                return ADW_IERR_SINGLE_END_DEVICE;
        !          1219:        }
        !          1220:
        !          1221:        /*
        !          1222:         * If automatic termination control is enabled, then set the
        !          1223:         * termination value based on a table listed in a_condor.h.
        !          1224:         *
        !          1225:         * If manual termination was specified with an EEPROM setting
        !          1226:         * then 'termination' was set-up in AdwInitFromEEPROM() and
        !          1227:         * is ready to be 'ored' into SCSI_CFG1.
        !          1228:         */
        !          1229:        if (cfg->termination == 0) {
        !          1230:                /*
        !          1231:                 * The software always controls termination by setting
        !          1232:                 * TERM_CTL_SEL.
        !          1233:                 * If TERM_CTL_SEL were set to 0, the hardware would set
        !          1234:                 * termination.
        !          1235:                 */
        !          1236:                cfg->termination |= ADW_TERM_CTL_SEL;
        !          1237:
        !          1238:                switch(scsi_cfg1 & ADW_CABLE_DETECT) {
        !          1239:                        /* TERM_CTL_H: on, TERM_CTL_L: on */
        !          1240:                        case 0x3: case 0x7: case 0xB:
        !          1241:                        case 0xD: case 0xE: case 0xF:
        !          1242:                                cfg->termination |=
        !          1243:                                (ADW_TERM_CTL_H | ADW_TERM_CTL_L);
        !          1244:                                break;
        !          1245:
        !          1246:                        /* TERM_CTL_H: on, TERM_CTL_L: off */
        !          1247:                        case 0x1: case 0x5: case 0x9:
        !          1248:                        case 0xA: case 0xC:
        !          1249:                                cfg->termination |= ADW_TERM_CTL_H;
        !          1250:                                break;
        !          1251:
        !          1252:                        /* TERM_CTL_H: off, TERM_CTL_L: off */
        !          1253:                        case 0x2: case 0x6:
        !          1254:                                break;
        !          1255:                }
        !          1256:        }
        !          1257:
        !          1258:        /*
        !          1259:         * Clear any set TERM_CTL_H and TERM_CTL_L bits.
        !          1260:         */
        !          1261:        scsi_cfg1 &= ~ADW_TERM_CTL;
        !          1262:
        !          1263:        /*
        !          1264:         * Invert the TERM_CTL_H and TERM_CTL_L bits and then
        !          1265:         * set 'scsi_cfg1'. The TERM_POL bit does not need to be
        !          1266:         * referenced, because the hardware internally inverts
        !          1267:         * the Termination High and Low bits if TERM_POL is set.
        !          1268:         */
        !          1269:        scsi_cfg1 |= (ADW_TERM_CTL_SEL | (~cfg->termination & ADW_TERM_CTL));
        !          1270:
        !          1271:        /*
        !          1272:         * Set SCSI_CFG1 Microcode Default Value
        !          1273:         *
        !          1274:         * Set filter value and possibly modified termination control
        !          1275:         * bits in the Microcode SCSI_CFG1 Register Value.
        !          1276:         *
        !          1277:         * The microcode will set the SCSI_CFG1 register using this value
        !          1278:         * after it is started below.
        !          1279:         */
        !          1280:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_SCSI_CFG1,
        !          1281:                                                ADW_FLTR_DISABLE | scsi_cfg1);
        !          1282:
        !          1283:        /*
        !          1284:         * Set MEM_CFG Microcode Default Value
        !          1285:         *
        !          1286:         * The microcode will set the MEM_CFG register using this value
        !          1287:         * after it is started below.
        !          1288:         *
        !          1289:         * MEM_CFG may be accessed as a word or byte, but only bits 0-7
        !          1290:         * are defined.
        !          1291:         *
        !          1292:         * ASC-3550 has 8KB internal memory.
        !          1293:         */
        !          1294:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_MEM_CFG,
        !          1295:                                                ADW_BIOS_EN | ADW_RAM_SZ_8KB);
        !          1296:
        !          1297:        return 0;
        !          1298: }
        !          1299:
        !          1300:
        !          1301: int
        !          1302: AdwASC38C0800Cabling(iot, ioh, cfg)
        !          1303:        bus_space_tag_t iot;
        !          1304:        bus_space_handle_t ioh;
        !          1305:        ADW_DVC_CFG *cfg;
        !          1306: {
        !          1307:        u_int16_t       scsi_cfg1;
        !          1308:
        !          1309:
        !          1310:        /*
        !          1311:         * Determine SCSI_CFG1 Microcode Default Value.
        !          1312:         *
        !          1313:         * The microcode will set the SCSI_CFG1 register using this value
        !          1314:         * after it is started below.
        !          1315:         */
        !          1316:
        !          1317:        /* Read current SCSI_CFG1 Register value. */
        !          1318:        scsi_cfg1 = ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1);
        !          1319:
        !          1320:        /*
        !          1321:         * If the cable is reversed all of the SCSI_CTRL register signals
        !          1322:         * will be set. Check for and return an error if this condition is
        !          1323:         * found.
        !          1324:         */
        !          1325:        if ((ADW_READ_WORD_REGISTER(iot,ioh, IOPW_SCSI_CTRL) & 0x3F07)==0x3F07){
        !          1326:                return ADW_IERR_REVERSED_CABLE;
        !          1327:        }
        !          1328:
        !          1329:        /*
        !          1330:         * All kind of combinations of devices attached to one of four
        !          1331:         * connectors are acceptable except HVD device attached.
        !          1332:         * For example, LVD device can be attached to SE connector while
        !          1333:         * SE device attached to LVD connector.
        !          1334:         * If LVD device attached to SE connector, it only runs up to
        !          1335:         * Ultra speed.
        !          1336:         *
        !          1337:         * If an HVD device is attached to one of LVD connectors, return
        !          1338:         * an error.
        !          1339:         * However, there is no way to detect HVD device attached to
        !          1340:         * SE connectors.
        !          1341:         */
        !          1342:        if (scsi_cfg1 & ADW_HVD) {
        !          1343:                return ADW_IERR_HVD_DEVICE;
        !          1344:        }
        !          1345:
        !          1346:        /*
        !          1347:         * If either SE or LVD automatic termination control is enabled, then
        !          1348:         * set the termination value based on a table listed in a_condor.h.
        !          1349:         *
        !          1350:         * If manual termination was specified with an EEPROM setting then
        !          1351:         * 'termination' was set-up in AdwInitFromEEPROM() and is ready
        !          1352:         * to be 'ored' into SCSI_CFG1.
        !          1353:         */
        !          1354:        if ((cfg->termination & ADW_TERM_SE) == 0) {
        !          1355:                /* SE automatic termination control is enabled. */
        !          1356:                switch(scsi_cfg1 & ADW_C_DET_SE) {
        !          1357:                        /* TERM_SE_HI: on, TERM_SE_LO: on */
        !          1358:                        case 0x1: case 0x2: case 0x3:
        !          1359:                                cfg->termination |= ADW_TERM_SE;
        !          1360:                                break;
        !          1361:
        !          1362:                        /* TERM_SE_HI: on, TERM_SE_LO: off */
        !          1363:                        case 0x0:
        !          1364:                                cfg->termination |= ADW_TERM_SE_HI;
        !          1365:                                break;
        !          1366:                }
        !          1367:        }
        !          1368:
        !          1369:        if ((cfg->termination & ADW_TERM_LVD) == 0) {
        !          1370:                /* LVD automatic termination control is enabled. */
        !          1371:                switch(scsi_cfg1 & ADW_C_DET_LVD) {
        !          1372:                        /* TERM_LVD_HI: on, TERM_LVD_LO: on */
        !          1373:                        case 0x4: case 0x8: case 0xC:
        !          1374:                                cfg->termination |= ADW_TERM_LVD;
        !          1375:                                break;
        !          1376:
        !          1377:                        /* TERM_LVD_HI: off, TERM_LVD_LO: off */
        !          1378:                        case 0x0:
        !          1379:                                break;
        !          1380:                }
        !          1381:        }
        !          1382:
        !          1383:        /*
        !          1384:         * Clear any set TERM_SE and TERM_LVD bits.
        !          1385:         */
        !          1386:        scsi_cfg1 &= (~ADW_TERM_SE & ~ADW_TERM_LVD);
        !          1387:
        !          1388:        /*
        !          1389:         * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
        !          1390:         */
        !          1391:        scsi_cfg1 |= (~cfg->termination & 0xF0);
        !          1392:
        !          1393:        /*
        !          1394:         * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and
        !          1395:         * HVD/LVD/SE bits and set possibly modified termination control bits
        !          1396:         * in the Microcode SCSI_CFG1 Register Value.
        !          1397:         */
        !          1398:        scsi_cfg1 &= (~ADW_BIG_ENDIAN & ~ADW_DIS_TERM_DRV &
        !          1399:                                        ~ADW_TERM_POL & ~ADW_HVD_LVD_SE);
        !          1400:
        !          1401:        /*
        !          1402:         * Set SCSI_CFG1 Microcode Default Value
        !          1403:         *
        !          1404:         * Set possibly modified termination control and reset DIS_TERM_DRV
        !          1405:         * bits in the Microcode SCSI_CFG1 Register Value.
        !          1406:         *
        !          1407:         * The microcode will set the SCSI_CFG1 register using this value
        !          1408:         * after it is started below.
        !          1409:         */
        !          1410:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
        !          1411:
        !          1412:        /*
        !          1413:         * Set MEM_CFG Microcode Default Value
        !          1414:         *
        !          1415:         * The microcode will set the MEM_CFG register using this value
        !          1416:         * after it is started below.
        !          1417:         *
        !          1418:         * MEM_CFG may be accessed as a word or byte, but only bits 0-7
        !          1419:         * are defined.
        !          1420:         *
        !          1421:         * ASC-38C0800 has 16KB internal memory.
        !          1422:         */
        !          1423:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_MEM_CFG,
        !          1424:                                                ADW_BIOS_EN | ADW_RAM_SZ_16KB);
        !          1425:
        !          1426:        return 0;
        !          1427: }
        !          1428:
        !          1429:
        !          1430: int
        !          1431: AdwASC38C1600Cabling(iot, ioh, cfg)
        !          1432:        bus_space_tag_t iot;
        !          1433:        bus_space_handle_t ioh;
        !          1434:        ADW_DVC_CFG *cfg;
        !          1435: {
        !          1436:        u_int16_t       scsi_cfg1;
        !          1437:
        !          1438:
        !          1439:        /*
        !          1440:         * Determine SCSI_CFG1 Microcode Default Value.
        !          1441:         *
        !          1442:         * The microcode will set the SCSI_CFG1 register using this value
        !          1443:         * after it is started below.
        !          1444:         * Each ASC-38C1600 function has only two cable detect bits.
        !          1445:         * The bus mode override bits are in IOPB_SOFT_OVER_WR.
        !          1446:         */
        !          1447:
        !          1448:        /* Read current SCSI_CFG1 Register value. */
        !          1449:        scsi_cfg1 = ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1);
        !          1450:
        !          1451:        /*
        !          1452:         * If the cable is reversed all of the SCSI_CTRL register signals
        !          1453:         * will be set. Check for and return an error if this condition is
        !          1454:         * found.
        !          1455:         */
        !          1456:        if ((ADW_READ_WORD_REGISTER(iot,ioh, IOPW_SCSI_CTRL) & 0x3F07)==0x3F07){
        !          1457:                return ADW_IERR_REVERSED_CABLE;
        !          1458:        }
        !          1459:
        !          1460:        /*
        !          1461:         * Each ASC-38C1600 function has two connectors. Only an HVD device
        !          1462:         * cannot be connected to either connector. An LVD device or SE device
        !          1463:         * may be connected to either connector. If an SE device is connected,
        !          1464:         * then at most Ultra speed (20 MHz) can be used on both connectors.
        !          1465:         *
        !          1466:         * If an HVD device is attached, return an error.
        !          1467:         */
        !          1468:        if (scsi_cfg1 & ADW_HVD) {
        !          1469:                return ADW_IERR_HVD_DEVICE;
        !          1470:        }
        !          1471:
        !          1472:        /*
        !          1473:         * Each function in the ASC-38C1600 uses only the SE cable detect and
        !          1474:         * termination because there are two connectors for each function.
        !          1475:         * Each function may use either LVD or SE mode.
        !          1476:         * Corresponding the SE automatic termination control EEPROM bits are
        !          1477:         * used for each function.
        !          1478:         * Each function has its own EEPROM. If SE automatic control is enabled
        !          1479:         * for the function, then set the termination value based on a table
        !          1480:         * listed in adwlib.h.
        !          1481:         *
        !          1482:         * If manual termination is specified in the EEPROM for the function,
        !          1483:         * then 'termination' was set-up in AdwInitFromEEPROM() and is
        !          1484:         * ready to be 'ored' into SCSI_CFG1.
        !          1485:         */
        !          1486:        if ((cfg->termination & ADW_TERM_SE) == 0) {
        !          1487:                /* SE automatic termination control is enabled. */
        !          1488:                switch(scsi_cfg1 & ADW_C_DET_SE) {
        !          1489:                        /* TERM_SE_HI: on, TERM_SE_LO: on */
        !          1490:                        case 0x1: case 0x2: case 0x3:
        !          1491:                                cfg->termination |= ADW_TERM_SE;
        !          1492:                                break;
        !          1493:
        !          1494:                        case 0x0:
        !          1495:        /* !!!!TODO!!!! */
        !          1496: //                             if (ASC_PCI_ID2FUNC(cfg->pci_slot_info) == 0) {
        !          1497:                                /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
        !          1498: //                             }
        !          1499: //                             else
        !          1500: //                             {
        !          1501:                                /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
        !          1502:                                        cfg->termination |= ADW_TERM_SE_HI;
        !          1503: //                             }
        !          1504:                                break;
        !          1505:                        }
        !          1506:        }
        !          1507:
        !          1508:        /*
        !          1509:         * Clear any set TERM_SE bits.
        !          1510:         */
        !          1511:        scsi_cfg1 &= ~ADW_TERM_SE;
        !          1512:
        !          1513:        /*
        !          1514:         * Invert the TERM_SE bits and then set 'scsi_cfg1'.
        !          1515:         */
        !          1516:        scsi_cfg1 |= (~cfg->termination & ADW_TERM_SE);
        !          1517:
        !          1518:        /*
        !          1519:         * Clear Big Endian and Terminator Polarity bits and set possibly
        !          1520:         * modified termination control bits in the Microcode SCSI_CFG1
        !          1521:         * Register Value.
        !          1522:         */
        !          1523:        scsi_cfg1 &= (~ADW_BIG_ENDIAN & ~ADW_DIS_TERM_DRV & ~ADW_TERM_POL);
        !          1524:
        !          1525:        /*
        !          1526:         * Set SCSI_CFG1 Microcode Default Value
        !          1527:         *
        !          1528:         * Set possibly modified termination control bits in the Microcode
        !          1529:         * SCSI_CFG1 Register Value.
        !          1530:         *
        !          1531:         * The microcode will set the SCSI_CFG1 register using this value
        !          1532:         * after it is started below.
        !          1533:         */
        !          1534:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
        !          1535:
        !          1536:        /*
        !          1537:         * Set MEM_CFG Microcode Default Value
        !          1538:         *
        !          1539:         * The microcode will set the MEM_CFG register using this value
        !          1540:         * after it is started below.
        !          1541:         *
        !          1542:         * MEM_CFG may be accessed as a word or byte, but only bits 0-7
        !          1543:         * are defined.
        !          1544:         *
        !          1545:         * ASC-38C1600 has 32KB internal memory.
        !          1546:         */
        !          1547:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_MEM_CFG,
        !          1548:                                                ADW_BIOS_EN | ADW_RAM_SZ_32KB);
        !          1549:
        !          1550:        return 0;
        !          1551: }
        !          1552:
        !          1553:
        !          1554: /*
        !          1555:  * Read EEPROM configuration into the specified buffer.
        !          1556:  *
        !          1557:  * Return a checksum based on the EEPROM configuration read.
        !          1558:  */
        !          1559: u_int16_t
        !          1560: AdwGetEEPROMConfig(iot, ioh, cfg_buf)
        !          1561:        bus_space_tag_t         iot;
        !          1562:        bus_space_handle_t      ioh;
        !          1563:        ADW_EEPROM              *cfg_buf;
        !          1564: {
        !          1565:        u_int16_t              wval, chksum;
        !          1566:        u_int16_t              *wbuf;
        !          1567:        int                 eep_addr;
        !          1568:
        !          1569:
        !          1570:        wbuf = (u_int16_t *) cfg_buf;
        !          1571:        chksum = 0;
        !          1572:
        !          1573:        for (eep_addr = ADW_EEP_DVC_CFG_BEGIN;
        !          1574:                eep_addr < ADW_EEP_DVC_CFG_END;
        !          1575:                eep_addr++, wbuf++) {
        !          1576:                wval = AdwReadEEPWord(iot, ioh, eep_addr);
        !          1577:                chksum += wval;
        !          1578:                *wbuf = wval;
        !          1579:        }
        !          1580:
        !          1581:        *wbuf = AdwReadEEPWord(iot, ioh, eep_addr);
        !          1582:        wbuf++;
        !          1583:        for (eep_addr = ADW_EEP_DVC_CTL_BEGIN;
        !          1584:                        eep_addr < ADW_EEP_MAX_WORD_ADDR;
        !          1585:                        eep_addr++, wbuf++) {
        !          1586:                *wbuf = AdwReadEEPWord(iot, ioh, eep_addr);
        !          1587:        }
        !          1588:
        !          1589:        return chksum;
        !          1590: }
        !          1591:
        !          1592:
        !          1593: /*
        !          1594:  * Read the EEPROM from specified location
        !          1595:  */
        !          1596: u_int16_t
        !          1597: AdwReadEEPWord(iot, ioh, eep_word_addr)
        !          1598:        bus_space_tag_t         iot;
        !          1599:        bus_space_handle_t      ioh;
        !          1600:        int                     eep_word_addr;
        !          1601: {
        !          1602:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD,
        !          1603:                ADW_EEP_CMD_READ | eep_word_addr);
        !          1604:        AdwWaitEEPCmd(iot, ioh);
        !          1605:
        !          1606:        return ADW_READ_WORD_REGISTER(iot, ioh, IOPW_EE_DATA);
        !          1607: }
        !          1608:
        !          1609:
        !          1610: /*
        !          1611:  * Wait for EEPROM command to complete
        !          1612:  */
        !          1613: void
        !          1614: AdwWaitEEPCmd(iot, ioh)
        !          1615:        bus_space_tag_t         iot;
        !          1616:        bus_space_handle_t      ioh;
        !          1617: {
        !          1618:        int eep_delay_ms;
        !          1619:
        !          1620:
        !          1621:        for (eep_delay_ms = 0; eep_delay_ms < ADW_EEP_DELAY_MS; eep_delay_ms++){
        !          1622:                if (ADW_READ_WORD_REGISTER(iot, ioh, IOPW_EE_CMD) &
        !          1623:                                ADW_EEP_CMD_DONE) {
        !          1624:                        break;
        !          1625:                }
        !          1626:                AdwSleepMilliSecond(1);
        !          1627:        }
        !          1628:
        !          1629:        ADW_READ_WORD_REGISTER(iot, ioh, IOPW_EE_CMD);
        !          1630: }
        !          1631:
        !          1632:
        !          1633: /*
        !          1634:  * Write the EEPROM from 'cfg_buf'.
        !          1635:  */
        !          1636: void
        !          1637: AdwSetEEPROMConfig(iot, ioh, cfg_buf)
        !          1638:        bus_space_tag_t         iot;
        !          1639:        bus_space_handle_t      ioh;
        !          1640:        ADW_EEPROM              *cfg_buf;
        !          1641: {
        !          1642:        u_int16_t *wbuf;
        !          1643:        u_int16_t addr, chksum;
        !          1644:
        !          1645:
        !          1646:        wbuf = (u_int16_t *) cfg_buf;
        !          1647:        chksum = 0;
        !          1648:
        !          1649:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, ADW_EEP_CMD_WRITE_ABLE);
        !          1650:        AdwWaitEEPCmd(iot, ioh);
        !          1651:
        !          1652:        /*
        !          1653:         * Write EEPROM from word 0 to word 20
        !          1654:         */
        !          1655:        for (addr = ADW_EEP_DVC_CFG_BEGIN;
        !          1656:             addr < ADW_EEP_DVC_CFG_END; addr++, wbuf++) {
        !          1657:                chksum += *wbuf;
        !          1658:                ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, *wbuf);
        !          1659:                ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD,
        !          1660:                                ADW_EEP_CMD_WRITE | addr);
        !          1661:                AdwWaitEEPCmd(iot, ioh);
        !          1662:                AdwSleepMilliSecond(ADW_EEP_DELAY_MS);
        !          1663:        }
        !          1664:
        !          1665:        /*
        !          1666:         * Write EEPROM checksum at word 21
        !          1667:         */
        !          1668:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, chksum);
        !          1669:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD,
        !          1670:                        ADW_EEP_CMD_WRITE | addr);
        !          1671:        AdwWaitEEPCmd(iot, ioh);
        !          1672:        wbuf++;        /* skip over check_sum */
        !          1673:
        !          1674:        /*
        !          1675:         * Write EEPROM OEM name at words 22 to 29
        !          1676:         */
        !          1677:        for (addr = ADW_EEP_DVC_CTL_BEGIN;
        !          1678:             addr < ADW_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
        !          1679:                ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, *wbuf);
        !          1680:                ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD,
        !          1681:                                ADW_EEP_CMD_WRITE | addr);
        !          1682:                AdwWaitEEPCmd(iot, ioh);
        !          1683:        }
        !          1684:
        !          1685:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD,
        !          1686:                        ADW_EEP_CMD_WRITE_DISABLE);
        !          1687:        AdwWaitEEPCmd(iot, ioh);
        !          1688:
        !          1689:        return;
        !          1690: }
        !          1691:
        !          1692:
        !          1693: /*
        !          1694:  * AdwExeScsiQueue() - Send a request to the RISC microcode program.
        !          1695:  *
        !          1696:  *   Allocate a carrier structure, point the carrier to the ADW_SCSI_REQ_Q,
        !          1697:  *   add the carrier to the ICQ (Initiator Command Queue), and tickle the
        !          1698:  *   RISC to notify it a new command is ready to be executed.
        !          1699:  *
        !          1700:  * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
        !          1701:  * set to SCSI_MAX_RETRY.
        !          1702:  *
        !          1703:  * Return:
        !          1704:  *      ADW_SUCCESS(1) - The request was successfully queued.
        !          1705:  *      ADW_BUSY(0) -    Resource unavailable; Retry again after pending
        !          1706:  *                       request completes.
        !          1707:  *      ADW_ERROR(-1) -  Invalid ADW_SCSI_REQ_Q request structure
        !          1708:  *                       host IC error.
        !          1709:  */
        !          1710: int
        !          1711: AdwExeScsiQueue(sc, scsiq)
        !          1712: ADW_SOFTC      *sc;
        !          1713: ADW_SCSI_REQ_Q *scsiq;
        !          1714: {
        !          1715:        bus_space_tag_t iot = sc->sc_iot;
        !          1716:        bus_space_handle_t ioh = sc->sc_ioh;
        !          1717:        ADW_CCB         *ccb;
        !          1718:        long            req_size;
        !          1719:        u_int32_t       req_paddr;
        !          1720:        ADW_CARRIER     *new_carrp;
        !          1721:
        !          1722:        /*
        !          1723:         * The ADW_SCSI_REQ_Q 'target_id' field should never exceed ADW_MAX_TID.
        !          1724:         */
        !          1725:        if (scsiq->target_id > ADW_MAX_TID) {
        !          1726:                scsiq->host_status = QHSTA_M_INVALID_DEVICE;
        !          1727:                scsiq->done_status = QD_WITH_ERROR;
        !          1728:                return ADW_ERROR;
        !          1729:        }
        !          1730:
        !          1731:        /*
        !          1732:         * Beginning of CRITICAL SECTION: ASSUME splbio() in effect
        !          1733:         */
        !          1734:
        !          1735:        ccb = adw_ccb_phys_kv(sc, scsiq->ccb_ptr);
        !          1736:
        !          1737:        /*
        !          1738:         * Allocate a carrier and initialize fields.
        !          1739:         */
        !          1740:        if ((new_carrp = sc->carr_freelist) == NULL) {
        !          1741:                return ADW_BUSY;
        !          1742:        }
        !          1743:        sc->carr_freelist = ADW_CARRIER_VADDR(sc,
        !          1744:                        ADW_GET_CARRP(new_carrp->next_ba));
        !          1745:        sc->carr_pending_cnt++;
        !          1746:
        !          1747:        /*
        !          1748:         * Set the carrier to be a stopper by setting 'next_ba'
        !          1749:         * to the stopper value. The current stopper will be changed
        !          1750:         * below to point to the new stopper.
        !          1751:         */
        !          1752:        new_carrp->next_ba = ADW_CQ_STOPPER;
        !          1753:
        !          1754:        req_size = sizeof(ADW_SCSI_REQ_Q);
        !          1755:        req_paddr = sc->sc_dmamap_control->dm_segs[0].ds_addr +
        !          1756:                ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsiq);
        !          1757:
        !          1758:        /* Save physical address of ADW_SCSI_REQ_Q and Carrier. */
        !          1759:        scsiq->scsiq_rptr = req_paddr;
        !          1760:
        !          1761:        /*
        !          1762:         * Every ADW_SCSI_REQ_Q.carr_ba is byte swapped to little-endian
        !          1763:         * order during initialization.
        !          1764:         */
        !          1765:        scsiq->carr_ba = sc->icq_sp->carr_ba;
        !          1766:        scsiq->carr_va = sc->icq_sp->carr_ba;
        !          1767:
        !          1768:        /*
        !          1769:         * Use the current stopper to send the ADW_SCSI_REQ_Q command to
        !          1770:         * the microcode. The newly allocated stopper will become the new
        !          1771:         * stopper.
        !          1772:         */
        !          1773:        sc->icq_sp->areq_ba = req_paddr;
        !          1774:
        !          1775:        /*
        !          1776:         * Set the 'next_ba' pointer for the old stopper to be the
        !          1777:         * physical address of the new stopper. The RISC can only
        !          1778:         * follow physical addresses.
        !          1779:         */
        !          1780:        sc->icq_sp->next_ba = new_carrp->carr_ba;
        !          1781:
        !          1782: #if ADW_DEBUG
        !          1783:        printf("icq 0x%x, 0x%x, 0x%x, 0x%x\n",
        !          1784:                        sc->icq_sp->carr_id,
        !          1785:                        sc->icq_sp->carr_ba,
        !          1786:                        sc->icq_sp->areq_ba,
        !          1787:                        sc->icq_sp->next_ba);
        !          1788: #endif
        !          1789:        /*
        !          1790:         * Set the host adapter stopper pointer to point to the new carrier.
        !          1791:         */
        !          1792:        sc->icq_sp = new_carrp;
        !          1793:
        !          1794:        if (sc->chip_type == ADW_CHIP_ASC3550 ||
        !          1795:            sc->chip_type == ADW_CHIP_ASC38C0800) {
        !          1796:                /*
        !          1797:                 * Tickle the RISC to tell it to read its Command Queue Head
        !          1798:                 * pointer.
        !          1799:                 */
        !          1800:                ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADW_TICKLE_A);
        !          1801:                if (sc->chip_type == ADW_CHIP_ASC3550) {
        !          1802:                        /*
        !          1803:                         * Clear the tickle value. In the ASC-3550 the RISC flag
        !          1804:                         * command 'clr_tickle_a' does not work unless the host
        !          1805:                         * value is cleared.
        !          1806:                         */
        !          1807:                        ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE,
        !          1808:                                        ADW_TICKLE_NOP);
        !          1809:                }
        !          1810:        } else if (sc->chip_type == ADW_CHIP_ASC38C1600) {
        !          1811:                /*
        !          1812:                 * Notify the RISC a carrier is ready by writing the physical
        !          1813:                 * address of the new carrier stopper to the COMMA register.
        !          1814:                 */
        !          1815:                ADW_WRITE_DWORD_REGISTER(iot, ioh, IOPDW_COMMA,
        !          1816:                                new_carrp->carr_ba);
        !          1817:        }
        !          1818:
        !          1819:        /*
        !          1820:         * End of CRITICAL SECTION: Must be protected within splbio/splx pair
        !          1821:         */
        !          1822:
        !          1823:        return ADW_SUCCESS;
        !          1824: }
        !          1825:
        !          1826:
        !          1827: void
        !          1828: AdwResetChip(iot, ioh)
        !          1829:        bus_space_tag_t iot;
        !          1830:        bus_space_handle_t ioh;
        !          1831: {
        !          1832:
        !          1833:        /*
        !          1834:         * Reset Chip.
        !          1835:         */
        !          1836:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG,
        !          1837:                        ADW_CTRL_REG_CMD_RESET);
        !          1838:        AdwSleepMilliSecond(100);
        !          1839:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG,
        !          1840:                        ADW_CTRL_REG_CMD_WR_IO_REG);
        !          1841: }
        !          1842:
        !          1843:
        !          1844: /*
        !          1845:  * Reset SCSI Bus and purge all outstanding requests.
        !          1846:  *
        !          1847:  * Return Value:
        !          1848:  *      ADW_TRUE(1) -   All requests are purged and SCSI Bus is reset.
        !          1849:  *      ADW_FALSE(0) -  Microcode command failed.
        !          1850:  *      ADW_ERROR(-1) - Microcode command timed-out. Microcode or IC
        !          1851:  *                      may be hung which requires driver recovery.
        !          1852:  */
        !          1853: int
        !          1854: AdwResetCCB(sc)
        !          1855: ADW_SOFTC      *sc;
        !          1856: {
        !          1857:        int         status;
        !          1858:
        !          1859:        /*
        !          1860:         * Send the SCSI Bus Reset idle start idle command which asserts
        !          1861:         * the SCSI Bus Reset signal.
        !          1862:         */
        !          1863:        status = AdwSendIdleCmd(sc, (u_int16_t) IDLE_CMD_SCSI_RESET_START, 0L);
        !          1864:        if (status != ADW_TRUE) {
        !          1865:                return status;
        !          1866:        }
        !          1867:
        !          1868:        /*
        !          1869:         * Delay for the specified SCSI Bus Reset hold time.
        !          1870:         *
        !          1871:         * The hold time delay is done on the host because the RISC has no
        !          1872:         * microsecond accurate timer.
        !          1873:         */
        !          1874:        AdwDelayMicroSecond((u_int16_t) ADW_SCSI_RESET_HOLD_TIME_US);
        !          1875:
        !          1876:        /*
        !          1877:         * Send the SCSI Bus Reset end idle command which de-asserts
        !          1878:         * the SCSI Bus Reset signal and purges any pending requests.
        !          1879:         */
        !          1880:        status = AdwSendIdleCmd(sc, (u_int16_t) IDLE_CMD_SCSI_RESET_END, 0L);
        !          1881:        if (status != ADW_TRUE) {
        !          1882:                return status;
        !          1883:        }
        !          1884:
        !          1885:        AdwSleepMilliSecond((u_int32_t) sc->scsi_reset_wait * 1000);
        !          1886:
        !          1887:        return status;
        !          1888: }
        !          1889:
        !          1890:
        !          1891: /*
        !          1892:  * Reset chip and SCSI Bus.
        !          1893:  *
        !          1894:  * Return Value:
        !          1895:  *      ADW_TRUE(1) -   Chip re-initialization and SCSI Bus Reset successful.
        !          1896:  *      ADW_FALSE(0) -  Chip re-initialization and SCSI Bus Reset failure.
        !          1897:  */
        !          1898: int
        !          1899: AdwResetSCSIBus(sc)
        !          1900: ADW_SOFTC      *sc;
        !          1901: {
        !          1902:        bus_space_tag_t iot = sc->sc_iot;
        !          1903:        bus_space_handle_t ioh = sc->sc_ioh;
        !          1904:        int             status;
        !          1905:        u_int16_t       wdtr_able, sdtr_able, ppr_able, tagqng_able;
        !          1906:        u_int8_t        tid, max_cmd[ADW_MAX_TID + 1];
        !          1907:        u_int16_t       bios_sig;
        !          1908:
        !          1909:
        !          1910:        /*
        !          1911:         * Save current per TID negotiated values.
        !          1912:         */
        !          1913:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, wdtr_able);
        !          1914:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, sdtr_able);
        !          1915:        if (sc->chip_type == ADW_CHIP_ASC38C1600) {
        !          1916:                ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_PPR_ABLE, ppr_able);
        !          1917:        }
        !          1918:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE, tagqng_able);
        !          1919:        for (tid = 0; tid <= ADW_MAX_TID; tid++) {
        !          1920:                ADW_READ_BYTE_LRAM(iot, ioh, ADW_MC_NUMBER_OF_MAX_CMD + tid,
        !          1921:                        max_cmd[tid]);
        !          1922:        }
        !          1923:
        !          1924:        /*
        !          1925:         * Force the AdwInitAscDriver() function to perform a SCSI Bus Reset
        !          1926:         * by clearing the BIOS signature word.
        !          1927:         * The initialization functions assumes a SCSI Bus Reset is not
        !          1928:         * needed if the BIOS signature word is present.
        !          1929:         */
        !          1930:        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_BIOS_SIGNATURE, bios_sig);
        !          1931:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_BIOS_SIGNATURE, 0);
        !          1932:
        !          1933:        /*
        !          1934:         * Stop chip and reset it.
        !          1935:         */
        !          1936:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RISC_CSR, ADW_RISC_CSR_STOP);
        !          1937:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG,
        !          1938:                        ADW_CTRL_REG_CMD_RESET);
        !          1939:        AdwSleepMilliSecond(100);
        !          1940:        ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG,
        !          1941:                        ADW_CTRL_REG_CMD_WR_IO_REG);
        !          1942:
        !          1943:        /*
        !          1944:         * Reset Adw Library error code, if any, and try
        !          1945:         * re-initializing the chip.
        !          1946:         * Then translate initialization return value to status value.
        !          1947:         */
        !          1948:        status = (AdwInitDriver(sc) == 0)? ADW_TRUE : ADW_FALSE;
        !          1949:
        !          1950:        /*
        !          1951:         * Restore the BIOS signature word.
        !          1952:         */
        !          1953:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_BIOS_SIGNATURE, bios_sig);
        !          1954:
        !          1955:        /*
        !          1956:         * Restore per TID negotiated values.
        !          1957:         */
        !          1958:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, wdtr_able);
        !          1959:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, sdtr_able);
        !          1960:        if (sc->chip_type == ADW_CHIP_ASC38C1600) {
        !          1961:                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_PPR_ABLE, ppr_able);
        !          1962:        }
        !          1963:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE, tagqng_able);
        !          1964:        for (tid = 0; tid <= ADW_MAX_TID; tid++) {
        !          1965:                ADW_WRITE_BYTE_LRAM(iot, ioh, ADW_MC_NUMBER_OF_MAX_CMD + tid,
        !          1966:                        max_cmd[tid]);
        !          1967:        }
        !          1968:
        !          1969:        return status;
        !          1970: }
        !          1971:
        !          1972:
        !          1973: /*
        !          1974:  * Adw Library Interrupt Service Routine
        !          1975:  *
        !          1976:  *  This function is called by a driver's interrupt service routine.
        !          1977:  *  The function disables and re-enables interrupts.
        !          1978:  *
        !          1979:  *  Note: AdwISR() can be called when interrupts are disabled or even
        !          1980:  *  when there is no hardware interrupt condition present. It will
        !          1981:  *  always check for completed idle commands and microcode requests.
        !          1982:  *  This is an important feature that shouldn't be changed because it
        !          1983:  *  allows commands to be completed from polling mode loops.
        !          1984:  *
        !          1985:  * Return:
        !          1986:  *   ADW_TRUE(1) - interrupt was pending
        !          1987:  *   ADW_FALSE(0) - no interrupt was pending
        !          1988:  */
        !          1989: int
        !          1990: AdwISR(sc)
        !          1991: ADW_SOFTC      *sc;
        !          1992: {
        !          1993:        bus_space_tag_t iot = sc->sc_iot;
        !          1994:        bus_space_handle_t ioh = sc->sc_ioh;
        !          1995:        u_int8_t        int_stat;
        !          1996:        u_int16_t       target_bit;
        !          1997:        ADW_CARRIER     *free_carrp/*, *ccb_carr*/;
        !          1998:        u_int32_t       irq_next_pa;
        !          1999:        ADW_SCSI_REQ_Q  *scsiq;
        !          2000:        ADW_CCB         *ccb;
        !          2001:        int             s;
        !          2002:
        !          2003:
        !          2004:        s = splbio();
        !          2005:
        !          2006:        /* Reading the register clears the interrupt. */
        !          2007:        int_stat = ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_INTR_STATUS_REG);
        !          2008:
        !          2009:        if ((int_stat & (ADW_INTR_STATUS_INTRA | ADW_INTR_STATUS_INTRB |
        !          2010:             ADW_INTR_STATUS_INTRC)) == 0) {
        !          2011:                splx(s);
        !          2012:                return ADW_FALSE;
        !          2013:        }
        !          2014:
        !          2015:        /*
        !          2016:         * Notify the driver of an asynchronous microcode condition by
        !          2017:         * calling the ADW_SOFTC.async_callback function. The function
        !          2018:         * is passed the microcode ADW_MC_INTRB_CODE byte value.
        !          2019:         */
        !          2020:        if (int_stat & ADW_INTR_STATUS_INTRB) {
        !          2021:                u_int8_t intrb_code;
        !          2022:
        !          2023:                ADW_READ_BYTE_LRAM(iot, ioh, ADW_MC_INTRB_CODE, intrb_code);
        !          2024:
        !          2025:                if (sc->chip_type == ADW_CHIP_ASC3550 ||
        !          2026:                    sc->chip_type == ADW_CHIP_ASC38C0800) {
        !          2027:                        if (intrb_code == ADW_ASYNC_CARRIER_READY_FAILURE &&
        !          2028:                                sc->carr_pending_cnt != 0) {
        !          2029:                                ADW_WRITE_BYTE_REGISTER(iot, ioh,
        !          2030:                                        IOPB_TICKLE, ADW_TICKLE_A);
        !          2031:                                if (sc->chip_type == ADW_CHIP_ASC3550) {
        !          2032:                                        ADW_WRITE_BYTE_REGISTER(iot, ioh,
        !          2033:                                                IOPB_TICKLE, ADW_TICKLE_NOP);
        !          2034:                                }
        !          2035:                        }
        !          2036:                }
        !          2037:
        !          2038:                if (sc->async_callback != 0) {
        !          2039:                    (*(ADW_ASYNC_CALLBACK)sc->async_callback)(sc, intrb_code);
        !          2040:                }
        !          2041:        }
        !          2042:
        !          2043:        /*
        !          2044:         * Check if the IRQ stopper carrier contains a completed request.
        !          2045:         */
        !          2046:        while (((irq_next_pa = sc->irq_sp->next_ba) & ADW_RQ_DONE) != 0)
        !          2047:        {
        !          2048: #if ADW_DEBUG
        !          2049:                printf("irq 0x%x, 0x%x, 0x%x, 0x%x\n",
        !          2050:                                sc->irq_sp->carr_id,
        !          2051:                                sc->irq_sp->carr_ba,
        !          2052:                                sc->irq_sp->areq_ba,
        !          2053:                                sc->irq_sp->next_ba);
        !          2054: #endif
        !          2055:                /*
        !          2056:                 * Get a pointer to the newly completed ADW_SCSI_REQ_Q
        !          2057:                 * structure.
        !          2058:                 * The RISC will have set 'areq_ba' to a virtual address.
        !          2059:                 *
        !          2060:                 * The firmware will have copied the ADW_SCSI_REQ_Q.ccb_ptr
        !          2061:                 * field to the carrier ADW_CARRIER.areq_ba field.
        !          2062:                 * The conversion below complements the conversion of
        !          2063:                 * ADW_SCSI_REQ_Q.ccb_ptr' in AdwExeScsiQueue().
        !          2064:                 */
        !          2065:                ccb = adw_ccb_phys_kv(sc, sc->irq_sp->areq_ba);
        !          2066:                scsiq = &ccb->scsiq;
        !          2067:                scsiq->ccb_ptr = sc->irq_sp->areq_ba;
        !          2068:
        !          2069:                /*
        !          2070:                 * Request finished with good status and the queue was not
        !          2071:                 * DMAed to host memory by the firmware. Set all status fields
        !          2072:                 * to indicate good status.
        !          2073:                 */
        !          2074:                if ((irq_next_pa & ADW_RQ_GOOD) != 0) {
        !          2075:                        scsiq->done_status = QD_NO_ERROR;
        !          2076:                        scsiq->host_status = scsiq->scsi_status = 0;
        !          2077:                        scsiq->data_cnt = 0L;
        !          2078:                }
        !          2079:
        !          2080:                /*
        !          2081:                 * Advance the stopper pointer to the next carrier
        !          2082:                 * ignoring the lower four bits. Free the previous
        !          2083:                 * stopper carrier.
        !          2084:                 */
        !          2085:                free_carrp = sc->irq_sp;
        !          2086:                sc->irq_sp = ADW_CARRIER_VADDR(sc, ADW_GET_CARRP(irq_next_pa));
        !          2087:
        !          2088:                free_carrp->next_ba = (sc->carr_freelist == NULL) ? NULL
        !          2089:                                        : sc->carr_freelist->carr_ba;
        !          2090:                sc->carr_freelist = free_carrp;
        !          2091:                sc->carr_pending_cnt--;
        !          2092:
        !          2093:                target_bit = ADW_TID_TO_TIDMASK(scsiq->target_id);
        !          2094:
        !          2095:                /*
        !          2096:                 * Clear request microcode control flag.
        !          2097:                 */
        !          2098:                scsiq->cntl = 0;
        !          2099:
        !          2100:                /*
        !          2101:                 * Check Condition handling
        !          2102:                 */
        !          2103:                /*
        !          2104:                 * If the command that completed was a SCSI INQUIRY and
        !          2105:                 * LUN 0 was sent the command, then process the INQUIRY
        !          2106:                 * command information for the device.
        !          2107:                 */
        !          2108:                if (scsiq->done_status == QD_NO_ERROR &&
        !          2109:                    scsiq->cdb[0] == INQUIRY &&
        !          2110:                    scsiq->target_lun == 0) {
        !          2111:                        AdwInquiryHandling(sc, scsiq);
        !          2112:                }
        !          2113:
        !          2114:                /*
        !          2115:                 * Notify the driver of the completed request by passing
        !          2116:                 * the ADW_SCSI_REQ_Q pointer to its callback function.
        !          2117:                 */
        !          2118:                (*(ADW_ISR_CALLBACK)sc->isr_callback)(sc, scsiq);
        !          2119:                /*
        !          2120:                 * Note: After the driver callback function is called, 'scsiq'
        !          2121:                 * can no longer be referenced.
        !          2122:                 *
        !          2123:                 * Fall through and continue processing other completed
        !          2124:                 * requests...
        !          2125:                 */
        !          2126:        }
        !          2127:
        !          2128:        splx(s);
        !          2129:
        !          2130:        return ADW_TRUE;
        !          2131: }
        !          2132:
        !          2133:
        !          2134: /*
        !          2135:  * Send an idle command to the chip and wait for completion.
        !          2136:  *
        !          2137:  * Command completion is polled for once per microsecond.
        !          2138:  *
        !          2139:  * The function can be called from anywhere including an interrupt handler.
        !          2140:  * But the function is not re-entrant, so it uses the splbio/splx()
        !          2141:  * functions to prevent reentrancy.
        !          2142:  *
        !          2143:  * Return Values:
        !          2144:  *   ADW_TRUE - command completed successfully
        !          2145:  *   ADW_FALSE - command failed
        !          2146:  *   ADW_ERROR - command timed out
        !          2147:  */
        !          2148: int
        !          2149: AdwSendIdleCmd(sc, idle_cmd, idle_cmd_parameter)
        !          2150: ADW_SOFTC      *sc;
        !          2151: u_int16_t       idle_cmd;
        !          2152: u_int32_t       idle_cmd_parameter;
        !          2153: {
        !          2154:        bus_space_tag_t iot = sc->sc_iot;
        !          2155:        bus_space_handle_t ioh = sc->sc_ioh;
        !          2156:        u_int16_t       result;
        !          2157:        u_int32_t       i, j, s;
        !          2158:
        !          2159:        s = splbio();
        !          2160:
        !          2161:        /*
        !          2162:         * Clear the idle command status which is set by the microcode
        !          2163:         * to a non-zero value to indicate when the command is completed.
        !          2164:         */
        !          2165:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_IDLE_CMD_STATUS, (u_int16_t) 0);
        !          2166:
        !          2167:        /*
        !          2168:         * Write the idle command value after the idle command parameter
        !          2169:         * has been written to avoid a race condition. If the order is not
        !          2170:         * followed, the microcode may process the idle command before the
        !          2171:         * parameters have been written to LRAM.
        !          2172:         */
        !          2173:        ADW_WRITE_DWORD_LRAM(iot, ioh, ADW_MC_IDLE_CMD_PARAMETER,
        !          2174:                        idle_cmd_parameter);
        !          2175:        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_IDLE_CMD, idle_cmd);
        !          2176:
        !          2177:        /*
        !          2178:         * Tickle the RISC to tell it to process the idle command.
        !          2179:         */
        !          2180:        ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADW_TICKLE_B);
        !          2181:        if (sc->chip_type == ADW_CHIP_ASC3550) {
        !          2182:                /*
        !          2183:                 * Clear the tickle value. In the ASC-3550 the RISC flag
        !          2184:                 * command 'clr_tickle_b' does not work unless the host
        !          2185:                 * value is cleared.
        !          2186:                 */
        !          2187:                ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADW_TICKLE_NOP);
        !          2188:        }
        !          2189:
        !          2190:        /* Wait for up to 100 millisecond for the idle command to timeout. */
        !          2191:        for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
        !          2192:                /* Poll once each microsecond for command completion. */
        !          2193:                for (j = 0; j < SCSI_US_PER_MSEC; j++) {
        !          2194:                        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_IDLE_CMD_STATUS,
        !          2195:                                                                        result);
        !          2196:                        if (result != 0) {
        !          2197:                                splx(s);
        !          2198:                                return result;
        !          2199:                        }
        !          2200:                        AdwDelayMicroSecond(1);
        !          2201:                }
        !          2202:        }
        !          2203:
        !          2204:        splx(s);
        !          2205:        return ADW_ERROR;
        !          2206: }
        !          2207:
        !          2208:
        !          2209: /*
        !          2210:  * Inquiry Information Byte 7 Handling
        !          2211:  *
        !          2212:  * Handle SCSI Inquiry Command information for a device by setting
        !          2213:  * microcode operating variables that affect WDTR, SDTR, and Tag
        !          2214:  * Queuing.
        !          2215:  */
        !          2216: void
        !          2217: AdwInquiryHandling(sc, scsiq)
        !          2218: ADW_SOFTC      *sc;
        !          2219: ADW_SCSI_REQ_Q *scsiq;
        !          2220: {
        !          2221: #ifndef FAILSAFE
        !          2222:        bus_space_tag_t iot = sc->sc_iot;
        !          2223:        bus_space_handle_t ioh = sc->sc_ioh;
        !          2224:        u_int8_t                tid;
        !          2225:        ADW_SCSI_INQUIRY        *inq;
        !          2226:        u_int16_t               tidmask;
        !          2227:        u_int16_t               cfg_word;
        !          2228:
        !          2229:
        !          2230:        /*
        !          2231:         * AdwInquiryHandling() requires up to INQUIRY information Byte 7
        !          2232:         * to be available.
        !          2233:         *
        !          2234:         * If less than 8 bytes of INQUIRY information were requested or less
        !          2235:         * than 8 bytes were transferred, then return. cdb[4] is the request
        !          2236:         * length and the ADW_SCSI_REQ_Q 'data_cnt' field is set by the
        !          2237:         * microcode to the transfer residual count.
        !          2238:         */
        !          2239:
        !          2240:        if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8) {
        !          2241:                return;
        !          2242:        }
        !          2243:
        !          2244:        tid = scsiq->target_id;
        !          2245:
        !          2246:         inq = (ADW_SCSI_INQUIRY *) scsiq->vdata_addr;
        !          2247:
        !          2248:        /*
        !          2249:         * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
        !          2250:         */
        !          2251:        if ((inq->rsp_data_fmt < 2) /*SCSI-1 | CCS*/ &&
        !          2252:            (inq->ansi_apr_ver < 2)) {
        !          2253:                return;
        !          2254:        } else {
        !          2255:                /*
        !          2256:                 * INQUIRY Byte 7 Handling
        !          2257:                 *
        !          2258:                 * Use a device's INQUIRY byte 7 to determine whether it
        !          2259:                 * supports WDTR, SDTR, and Tag Queuing. If the feature
        !          2260:                 * is enabled in the EEPROM and the device supports the
        !          2261:                 * feature, then enable it in the microcode.
        !          2262:                 */
        !          2263:
        !          2264:                tidmask = ADW_TID_TO_TIDMASK(tid);
        !          2265:
        !          2266:                /*
        !          2267:                 * Wide Transfers
        !          2268:                 *
        !          2269:                 * If the EEPROM enabled WDTR for the device and the device
        !          2270:                 * supports wide bus (16 bit) transfers, then turn on the
        !          2271:                 * device's 'wdtr_able' bit and write the new value to the
        !          2272:                 * microcode.
        !          2273:                 */
        !          2274: #ifdef SCSI_ADW_WDTR_DISABLE
        !          2275:        if(!(tidmask & SCSI_ADW_WDTR_DISABLE))
        !          2276: #endif /* SCSI_ADW_WDTR_DISABLE */
        !          2277:                if ((sc->wdtr_able & tidmask) && inq->WBus16) {
        !          2278:                        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE,
        !          2279:                                        cfg_word);
        !          2280:                        if ((cfg_word & tidmask) == 0) {
        !          2281:                                cfg_word |= tidmask;
        !          2282:                                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE,
        !          2283:                                                cfg_word);
        !          2284:
        !          2285:                                /*
        !          2286:                                 * Clear the microcode "SDTR negotiation" and
        !          2287:                                 * "WDTR negotiation" done indicators for the
        !          2288:                                 * target to cause it to negotiate with the new
        !          2289:                                 * setting set above.
        !          2290:                                 * WDTR when accepted causes the target to enter
        !          2291:                                 * asynchronous mode, so SDTR must be negotiated
        !          2292:                                 */
        !          2293:                                ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_DONE,
        !          2294:                                                cfg_word);
        !          2295:                                cfg_word &= ~tidmask;
        !          2296:                                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_DONE,
        !          2297:                                                cfg_word);
        !          2298:                                ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_DONE,
        !          2299:                                                cfg_word);
        !          2300:                                cfg_word &= ~tidmask;
        !          2301:                                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_WDTR_DONE,
        !          2302:                                                cfg_word);
        !          2303:                        }
        !          2304:                }
        !          2305:
        !          2306:                /*
        !          2307:                 * Synchronous Transfers
        !          2308:                 *
        !          2309:                 * If the EEPROM enabled SDTR for the device and the device
        !          2310:                 * supports synchronous transfers, then turn on the device's
        !          2311:                 * 'sdtr_able' bit. Write the new value to the microcode.
        !          2312:                 */
        !          2313: #ifdef SCSI_ADW_SDTR_DISABLE
        !          2314:        if(!(tidmask & SCSI_ADW_SDTR_DISABLE))
        !          2315: #endif /* SCSI_ADW_SDTR_DISABLE */
        !          2316:                if ((sc->sdtr_able & tidmask) && inq->Sync) {
        !          2317:                        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE,cfg_word);
        !          2318:                        if ((cfg_word & tidmask) == 0) {
        !          2319:                                cfg_word |= tidmask;
        !          2320:                                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE,
        !          2321:                                                cfg_word);
        !          2322:
        !          2323:                                /*
        !          2324:                                 * Clear the microcode "SDTR negotiation"
        !          2325:                                 * done indicator for the target to cause it
        !          2326:                                 * to negotiate with the new setting set above.
        !          2327:                                 */
        !          2328:                                ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_DONE,
        !          2329:                                                cfg_word);
        !          2330:                                cfg_word &= ~tidmask;
        !          2331:                                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_DONE,
        !          2332:                                                cfg_word);
        !          2333:                        }
        !          2334:                }
        !          2335:                /*
        !          2336:                 * If the Inquiry data included enough space for the SPI-3
        !          2337:                 * Clocking field, then check if DT mode is supported.
        !          2338:                 */
        !          2339:                if (sc->chip_type == ADW_CHIP_ASC38C1600 &&
        !          2340:                   (scsiq->cdb[4] >= 57 ||
        !          2341:                   (scsiq->cdb[4] - scsiq->data_cnt) >= 57)) {
        !          2342:                        /*
        !          2343:                         * PPR (Parallel Protocol Request) Capable
        !          2344:                         *
        !          2345:                         * If the device supports DT mode, then it must be
        !          2346:                         * PPR capable.
        !          2347:                         * The PPR message will be used in place of the SDTR
        !          2348:                         * and WDTR messages to negotiate synchronous speed
        !          2349:                         * and offset, transfer width, and protocol options.
        !          2350:                         */
        !          2351:                          if((inq->Clocking) & INQ_CLOCKING_DT_ONLY){
        !          2352:                                ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_PPR_ABLE,
        !          2353:                                                sc->ppr_able);
        !          2354:                                sc->ppr_able |= tidmask;
        !          2355:                                ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_PPR_ABLE,
        !          2356:                                                sc->ppr_able);
        !          2357:                        }
        !          2358:                }
        !          2359:
        !          2360:                /*
        !          2361:                 * If the EEPROM enabled Tag Queuing for the device and the
        !          2362:                 * device supports Tag Queueing, then turn on the device's
        !          2363:                 * 'tagqng_enable' bit in the microcode and set the microcode
        !          2364:                 * maximum command count to the ADW_SOFTC 'max_dvc_qng'
        !          2365:                 * value.
        !          2366:                 *
        !          2367:                 * Tag Queuing is disabled for the BIOS which runs in polled
        !          2368:                 * mode and would see no benefit from Tag Queuing. Also by
        !          2369:                 * disabling Tag Queuing in the BIOS devices with Tag Queuing
        !          2370:                 * bugs will at least work with the BIOS.
        !          2371:                 */
        !          2372: #ifdef SCSI_ADW_TAGQ_DISABLE
        !          2373:        if(!(tidmask & SCSI_ADW_TAGQ_DISABLE))
        !          2374: #endif /* SCSI_ADW_TAGQ_DISABLE */
        !          2375:                if ((sc->tagqng_able & tidmask) && inq->CmdQue) {
        !          2376:                        ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE,
        !          2377:                                        cfg_word);
        !          2378:                        cfg_word |= tidmask;
        !          2379:                        ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE,
        !          2380:                                        cfg_word);
        !          2381:
        !          2382:                        ADW_WRITE_BYTE_LRAM(iot, ioh,
        !          2383:                                        ADW_MC_NUMBER_OF_MAX_CMD + tid,
        !          2384:                                        sc->max_dvc_qng);
        !          2385:                }
        !          2386:        }
        !          2387: #endif /* FAILSAFE */
        !          2388: }
        !          2389:
        !          2390:
        !          2391: void
        !          2392: AdwSleepMilliSecond(n)
        !          2393: u_int32_t      n;
        !          2394: {
        !          2395:
        !          2396:        DELAY(n * 1000);
        !          2397: }
        !          2398:
        !          2399:
        !          2400: void
        !          2401: AdwDelayMicroSecond(n)
        !          2402: u_int32_t      n;
        !          2403: {
        !          2404:
        !          2405:        DELAY(n);
        !          2406: }
        !          2407:

CVSweb