[BACK]Return to ahc_isa.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / i386 / isa

Annotation of src/sys/arch/i386/isa/ahc_isa.c, Revision 1.12.14.1

1.12.14.1! bouyer      1: /*     $NetBSD: ahc_isa.c,v 1.14 2000/09/24 12:37:04 jdolecek Exp $    */
1.8       thorpej     2:
                      3: /*
                      4:  * Product specific probe and attach routines for:
1.12.14.1! bouyer      5:  *     AHA-284X VL-bus SCSI controllers
1.8       thorpej     6:  *
1.12.14.1! bouyer      7:  * Copyright (c) 1994, 1995, 1996, 1997, 1998 Justin T. Gibbs.
1.8       thorpej     8:  * All rights reserved.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice immediately at the beginning of the file, without modification,
                     15:  *    this list of conditions, and the following disclaimer.
1.12.14.1! bouyer     16:  * 2. The name of the author may not be used to endorse or promote products
1.8       thorpej    17:  *    derived from this software without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
                     23:  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
1.12.14.1! bouyer     30:  *
        !            31:  * $FreeBSD: src/sys/dev/aic7xxx/ahc_eisa.c,v 1.15 2000/01/29 14:22:19 peter Exp $
1.8       thorpej    32:  */
1.7       thorpej    33:
                     34: /*-
                     35:  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
                     36:  * All rights reserved.
                     37:  *
                     38:  * This code is derived from software contributed to The NetBSD Foundation
                     39:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
                     40:  * NASA Ames Research Center.
                     41:  *
                     42:  * Redistribution and use in source and binary forms, with or without
                     43:  * modification, are permitted provided that the following conditions
                     44:  * are met:
                     45:  * 1. Redistributions of source code must retain the above copyright
                     46:  *    notice, this list of conditions and the following disclaimer.
                     47:  * 2. Redistributions in binary form must reproduce the above copyright
                     48:  *    notice, this list of conditions and the following disclaimer in the
                     49:  *    documentation and/or other materials provided with the distribution.
                     50:  * 3. All advertising materials mentioning features or use of this software
                     51:  *    must display the following acknowledgement:
                     52:  *     This product includes software developed by the NetBSD
                     53:  *     Foundation, Inc. and its contributors.
                     54:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     55:  *    contributors may be used to endorse or promote products derived
                     56:  *    from this software without specific prior written permission.
                     57:  *
                     58:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     59:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     60:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     61:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     62:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     63:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     64:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     65:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     66:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     67:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     68:  * POSSIBILITY OF SUCH DAMAGE.
                     69:  */
1.1       soda       70:
                     71: /*
1.8       thorpej    72:  * Copyright (c) 1995, 1996 Christopher G. Demetriou
1.1       soda       73:  * All rights reserved.
                     74:  *
                     75:  * Redistribution and use in source and binary forms, with or without
                     76:  * modification, are permitted provided that the following conditions
                     77:  * are met:
                     78:  * 1. Redistributions of source code must retain the above copyright
1.8       thorpej    79:  *    notice, this list of conditions and the following disclaimer.
1.1       soda       80:  * 2. Redistributions in binary form must reproduce the above copyright
                     81:  *    notice, this list of conditions and the following disclaimer in the
                     82:  *    documentation and/or other materials provided with the distribution.
                     83:  * 3. All advertising materials mentioning features or use of this software
                     84:  *    must display the following acknowledgement:
1.8       thorpej    85:  *      This product includes software developed by Christopher G. Demetriou
                     86:  *      for the NetBSD Project.
1.1       soda       87:  * 4. The name of the author may not be used to endorse or promote products
1.8       thorpej    88:  *    derived from this software without specific prior written permission
1.1       soda       89:  *
1.8       thorpej    90:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     91:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     92:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     93:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     94:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     95:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     96:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     97:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     98:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     99:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.1       soda      100:  */
                    101:
                    102: /*
                    103:  * This front-end driver is really sort of a hack.  The AHA-284X likes
                    104:  * to masquerade as an EISA device.  However, on VLbus machines with
                    105:  * no EISA signature in the BIOS, the EISA bus will never be scanned.
                    106:  * This is intended to catch the 284X controllers on those systems
                    107:  * by looking in "EISA i/o space" for 284X controllers.
                    108:  *
                    109:  * This relies heavily on i/o port accounting.  We also just use the
                    110:  * EISA macros for everything ... it's a real waste to redefine them.
                    111:  *
                    112:  * Note: there isn't any #ifdef for FreeBSD in this file, since the
                    113:  * FreeBSD EISA driver handles all cases of the 284X.
                    114:  *
                    115:  *     -- Jason R. Thorpe <thorpej@NetBSD.ORG>
                    116:  *        July 12, 1996
                    117:  */
                    118:
                    119: #include <sys/param.h>
                    120: #include <sys/systm.h>
                    121: #include <sys/kernel.h>
                    122: #include <sys/device.h>
                    123: #include <sys/queue.h>
                    124: #include <sys/malloc.h>
1.12.14.1! bouyer    125: #include <sys/reboot.h>
1.1       soda      126:
                    127: #include <machine/bus.h>
                    128: #include <machine/intr.h>
                    129:
1.6       bouyer    130: #include <dev/scsipi/scsi_all.h>
                    131: #include <dev/scsipi/scsipi_all.h>
                    132: #include <dev/scsipi/scsiconf.h>
1.1       soda      133:
                    134: #include <dev/isa/isavar.h>
                    135:
                    136: #include <dev/eisa/eisareg.h>
                    137: #include <dev/eisa/eisavar.h>
                    138: #include <dev/eisa/eisadevs.h>
                    139:
1.12.14.1! bouyer    140: #include <dev/microcode/aic7xxx/aic7xxx_reg.h>
1.1       soda      141: #include <dev/ic/aic7xxxvar.h>
1.12.14.1! bouyer    142: #include <dev/ic/aic77xxreg.h>
        !           143: #include <dev/ic/aic77xxvar.h>
        !           144: #include <dev/ic/smc93cx6var.h>
1.1       soda      145:
                    146: /* IO port address setting range as EISA slot number */
                    147: #define AHC_ISA_MIN_SLOT       0x1     /* from iobase = 0x1c00 */
                    148: #define AHC_ISA_MAX_SLOT       0xe     /* to   iobase = 0xec00 */
                    149:
1.12.14.1! bouyer    150: #define AHC_ISA_SLOT_OFFSET    AHC_EISA_SLOT_OFFSET
        !           151: #define AHC_ISA_IOSIZE         AHC_EISA_IOSIZE
1.1       soda      152:
                    153: /*
                    154:  * I/O port offsets
                    155:  */
                    156: #define        AHC_ISA_VID             (EISA_SLOTOFF_VID - AHC_ISA_SLOT_OFFSET)
                    157: #define        AHC_ISA_PID             (EISA_SLOTOFF_PID - AHC_ISA_SLOT_OFFSET)
                    158: #define        AHC_ISA_PRIMING         AHC_ISA_VID     /* enable vendor/product ID */
                    159:
                    160: /*
                    161:  * AHC_ISA_PRIMING register values (write)
                    162:  */
                    163: #define        AHC_ISA_PRIMING_VID(index)      (AHC_ISA_VID + (index))
                    164: #define        AHC_ISA_PRIMING_PID(index)      (AHC_ISA_PID + (index))
                    165:
1.5       thorpej   166: int    ahc_isa_idstring __P((bus_space_tag_t, bus_space_handle_t, char *));
                    167: int    ahc_isa_match __P((struct isa_attach_args *, bus_addr_t));
1.1       soda      168:
1.12      drochner  169: int    ahc_isa_probe __P((struct device *, struct cfdata *, void *));
1.1       soda      170: void   ahc_isa_attach __P((struct device *, struct device *, void *));
1.12.14.1! bouyer    171: void   aha2840_load_seeprom __P((struct ahc_softc *ahc));
1.1       soda      172:
                    173: struct cfattach ahc_isa_ca = {
1.12.14.1! bouyer    174:        sizeof(struct ahc_softc), ahc_isa_probe, ahc_isa_attach
1.1       soda      175: };
                    176:
                    177: /*
                    178:  * This keeps track of which slots are to be checked next if the
                    179:  * iobase locator is a wildcard.  A simple static variable isn't enough,
                    180:  * since it's conceivable that a system might have more than one ISA
                    181:  * bus.
                    182:  *
                    183:  * The "bus" member is the unit number of the parent ISA bus, e.g. "0"
                    184:  * for "isa0".
                    185:  */
                    186: struct ahc_isa_slot {
                    187:        LIST_ENTRY(ahc_isa_slot)        link;
                    188:        int                             bus;
                    189:        int                             slot;
                    190: };
                    191: static LIST_HEAD(, ahc_isa_slot) ahc_isa_all_slots;
                    192: static int ahc_isa_slot_initialized;
                    193:
                    194: int
1.5       thorpej   195: ahc_isa_idstring(iot, ioh, idstring)
                    196:        bus_space_tag_t iot;
                    197:        bus_space_handle_t ioh;
1.1       soda      198:        char *idstring;
                    199: {
                    200:        u_int8_t vid[EISA_NVIDREGS], pid[EISA_NPIDREGS];
                    201:        int i;
                    202:
                    203:        /* Get the vendor ID bytes */
                    204:        for (i = 0; i < EISA_NVIDREGS; i++) {
1.5       thorpej   205:                bus_space_write_1(iot, ioh, AHC_ISA_PRIMING,
1.1       soda      206:                    AHC_ISA_PRIMING_VID(i));
1.5       thorpej   207:                vid[i] = bus_space_read_1(iot, ioh, AHC_ISA_VID + i);
1.1       soda      208:        }
                    209:
                    210:        /* Check for device existence */
                    211:        if (EISA_VENDID_NODEV(vid)) {
                    212: #if 0
1.4       christos  213:                printf("ahc_isa_idstring: no device at 0x%lx\n",
1.1       soda      214:                    ioh); /* XXX knows about ioh guts */
1.4       christos  215:                printf("\t(0x%x, 0x%x)\n", vid[0], vid[1]);
1.1       soda      216: #endif
                    217:                return (0);
                    218:        }
                    219:
                    220:        /* And check that the firmware didn't biff something badly */
                    221:        if (EISA_VENDID_IDDELAY(vid)) {
1.4       christos  222:                printf("ahc_isa_idstring: BIOS biffed it at 0x%lx\n",
1.1       soda      223:                    ioh);       /* XXX knows about ioh guts */
                    224:                return (0);
                    225:        }
                    226:
                    227:        /* Get the product ID bytes */
                    228:        for (i = 0; i < EISA_NPIDREGS; i++) {
1.5       thorpej   229:                bus_space_write_1(iot, ioh, AHC_ISA_PRIMING,
1.1       soda      230:                    AHC_ISA_PRIMING_PID(i));
1.5       thorpej   231:                pid[i] = bus_space_read_1(iot, ioh, AHC_ISA_PID + i);
1.1       soda      232:        }
                    233:
                    234:        /* Create the ID string from the vendor and product IDs */
                    235:        idstring[0] = EISA_VENDID_0(vid);
                    236:        idstring[1] = EISA_VENDID_1(vid);
                    237:        idstring[2] = EISA_VENDID_2(vid);
                    238:        idstring[3] = EISA_PRODID_0(pid);
                    239:        idstring[4] = EISA_PRODID_1(pid);
                    240:        idstring[5] = EISA_PRODID_2(pid);
                    241:        idstring[6] = EISA_PRODID_3(pid);
                    242:        idstring[7] = '\0';             /* sanity */
                    243:
                    244:        return (1);
                    245: }
                    246:
                    247: int
                    248: ahc_isa_match(ia, iobase)
                    249:        struct isa_attach_args *ia;
1.5       thorpej   250:        bus_addr_t iobase;
1.1       soda      251: {
1.5       thorpej   252:        bus_space_tag_t iot = ia->ia_iot;
                    253:        bus_space_handle_t ioh;
1.1       soda      254:        int irq;
                    255:        char idstring[EISA_IDSTRINGLEN];
                    256:
                    257:        /*
                    258:         * Get a mapping for the while slot-specific address
                    259:         * space.  If we can't, assume nothing's there, but
                    260:         * warn about it.
                    261:         */
1.5       thorpej   262:        if (bus_space_map(iot, iobase, AHC_ISA_IOSIZE, 0, &ioh)) {
1.1       soda      263: #if 0
                    264:                /*
                    265:                 * Don't print anything out here, since this could
                    266:                 * be common on machines configured to look for
                    267:                 * ahc_eisa and ahc_isa.
                    268:                 */
1.4       christos  269:                printf("ahc_isa_match: can't map I/O space for 0x%x\n",
1.1       soda      270:                    iobase);
                    271: #endif
                    272:                return (0);
                    273:        }
                    274:
1.5       thorpej   275:        if (!ahc_isa_idstring(iot, ioh, idstring))
1.1       soda      276:                irq = -1;       /* cannot get the ID string */
                    277:        else if (strcmp(idstring, "ADP7756") &&
                    278:            strcmp(idstring, "ADP7757"))
                    279:                irq = -1;       /* unknown ID strings */
                    280:        else
1.12.14.1! bouyer    281:                irq = ahc_aic77xx_irq(iot, ioh);
1.1       soda      282:
1.5       thorpej   283:        bus_space_unmap(iot, ioh, AHC_ISA_IOSIZE);
1.1       soda      284:
                    285:        if (irq < 0)
                    286:                return (0);
                    287:
                    288:        if (ia->ia_irq != IRQUNK &&
                    289:            ia->ia_irq != irq) {
1.4       christos  290:                printf("ahc_isa_match: irq mismatch (kernel %d, card %d)\n",
1.1       soda      291:                    ia->ia_irq, irq);
                    292:                return (0);
                    293:        }
                    294:
                    295:        /* We have a match */
                    296:        ia->ia_iobase = iobase;
                    297:        ia->ia_irq = irq;
                    298:        ia->ia_iosize = AHC_ISA_IOSIZE;
                    299:        ia->ia_msize = 0;
                    300:        return (1);
                    301: }
                    302:
                    303: /*
                    304:  * Check the slots looking for a board we recognise
                    305:  * If we find one, note it's address (slot) and call
                    306:  * the actual probe routine to check it out.
                    307:  */
                    308: int
                    309: ahc_isa_probe(parent, match, aux)
                    310:         struct device *parent;
1.12      drochner  311:         struct cfdata *match;
                    312:        void *aux;
1.1       soda      313: {
                    314:        struct isa_attach_args *ia = aux;
                    315:        struct ahc_isa_slot *as;
                    316:
                    317:        if (ahc_isa_slot_initialized == 0) {
                    318:                LIST_INIT(&ahc_isa_all_slots);
                    319:                ahc_isa_slot_initialized = 1;
                    320:        }
                    321:
                    322:        if (ia->ia_iobase != IOBASEUNK)
                    323:                return (ahc_isa_match(ia, ia->ia_iobase));
                    324:
                    325:        /*
                    326:         * Find this bus's state.  If we don't yet have a slot
                    327:         * marker, allocate and initialize one.
                    328:         */
                    329:        for (as = ahc_isa_all_slots.lh_first; as != NULL;
                    330:            as = as->link.le_next)
                    331:                if (as->bus == parent->dv_unit)
                    332:                        goto found_slot_marker;
                    333:
                    334:        /*
                    335:         * Don't have one, so make one.
                    336:         */
                    337:        as = (struct ahc_isa_slot *)
                    338:            malloc(sizeof(struct ahc_isa_slot), M_DEVBUF, M_NOWAIT);
                    339:        if (as == NULL)
                    340:                panic("ahc_isa_probe: can't allocate slot marker");
                    341:
                    342:        as->bus = parent->dv_unit;
                    343:        as->slot = AHC_ISA_MIN_SLOT;
                    344:        LIST_INSERT_HEAD(&ahc_isa_all_slots, as, link);
                    345:
                    346:  found_slot_marker:
                    347:
                    348:        for (; as->slot <= AHC_ISA_MAX_SLOT; as->slot++) {
                    349:                if (ahc_isa_match(ia, EISA_SLOT_ADDR(as->slot) +
                    350:                    AHC_ISA_SLOT_OFFSET)) {
                    351:                        as->slot++; /* next slot to search */
                    352:                        return (1);
                    353:                }
                    354:        }
                    355:
                    356:        /* No matching cards were found. */
                    357:        return (0);
                    358: }
                    359:
                    360: void
                    361: ahc_isa_attach(parent, self, aux)
                    362:        struct device *parent, *self;
                    363:        void *aux;
                    364: {
1.12.14.1! bouyer    365:        struct ahc_softc *ahc = (void *)self;
1.1       soda      366:        struct isa_attach_args *ia = aux;
1.5       thorpej   367:        bus_space_tag_t iot = ia->ia_iot;
                    368:        bus_space_handle_t ioh;
1.12.14.1! bouyer    369:        int irq, intrtype;
        !           370:        const char *intrtypestr;
1.1       soda      371:        char idstring[EISA_IDSTRINGLEN];
                    372:
1.9       thorpej   373:        if (bus_space_map(iot, ia->ia_iobase, ia->ia_iosize, 0, &ioh)) {
                    374:                printf(": can't map i/o space\n");
                    375:                return;
                    376:        }
                    377:        if (!ahc_isa_idstring(iot, ioh, idstring)) {
                    378:                printf(": can't read ID string\n");
1.12.14.1! bouyer    379:                goto free_io;
1.9       thorpej   380:        }
1.12.14.1! bouyer    381:        if ((irq = ahc_aic77xx_irq(iot, ioh)) < 0) {
        !           382:                printf(": ahc_aic77xx_irq failed\n");
        !           383:                goto free_io;
1.9       thorpej   384:        }
1.1       soda      385:
                    386:        if (strcmp(idstring, "ADP7756") == 0) {
1.12.14.1! bouyer    387:                printf(": %s\n", EISA_PRODUCT_ADP7756);
1.1       soda      388:        } else if (strcmp(idstring, "ADP7757") == 0) {
1.12.14.1! bouyer    389:                printf(": %s\n", EISA_PRODUCT_ADP7757);
1.1       soda      390:        } else {
1.9       thorpej   391:                printf(": unknown device type %s\n", idstring);
1.12.14.1! bouyer    392:                goto free_io;
1.1       soda      393:        }
                    394:
1.12.14.1! bouyer    395:        if (ahc_alloc(ahc, ioh, iot, ia->ia_dmat,
        !           396:            AHC_AIC7770|AHC_VL, AHC_AIC7770_FE, AHC_FNONE))
        !           397:                goto free_io;
1.11      leo       398:
                    399:        /*
                    400:         * Tell the bus-dma interface that we can do 32bit dma
1.12.14.1! bouyer    401:         * NOTE: this variable is first referenced in ahc_init().
1.11      leo       402:         */
                    403:        ahc->sc_dmaflags = ISABUS_DMA_32BIT;
1.1       soda      404:
1.12.14.1! bouyer    405:        ahc->channel = 'A';
        !           406:        ahc->channel_b = 'B';
        !           407:        if (ahc_reset(ahc) != 0)
        !           408:                goto free_ahc;
        !           409:
        !           410:        /*
        !           411:         * The IRQMS bit enables level sensitive interrupts. Only allow
        !           412:         * IRQ sharing if it's set.
        !           413:         * NOTE: ahc->pause is initialized in ahc_alloc().
        !           414:         */
        !           415:        if (ahc->pause & IRQMS) {
        !           416:                intrtype = IST_LEVEL;
        !           417:                intrtypestr = "level sensitive";
        !           418:        } else {
        !           419:                intrtype = IST_EDGE;
        !           420:                intrtypestr = "edge triggered";
        !           421:        }
        !           422:        ahc->ih = isa_intr_establish(ia->ia_ic, irq,
        !           423:            intrtype, IPL_BIO, ahc_intr, ahc);
        !           424:        if (ahc->ih == NULL) {
        !           425:                printf("%s: couldn't establish %s interrupt\n",
        !           426:                       ahc->sc_dev.dv_xname, intrtypestr);
        !           427:                goto free_ahc;
        !           428:        }
        !           429:
1.1       soda      430:        /*
                    431:         * Tell the user what type of interrupts we're using.
                    432:         * usefull for debugging irq problems
                    433:         */
1.12.14.1! bouyer    434:        if (bootverbose) {
        !           435:                printf("%s: Using %s interrupts\n",
        !           436:                       ahc->sc_dev.dv_xname, intrtypestr);
        !           437:        }
1.1       soda      438:
                    439:        /*
                    440:         * Now that we know we own the resources we need, do the
                    441:         * card initialization.
                    442:         */
1.12.14.1! bouyer    443:        aha2840_load_seeprom(ahc);
1.1       soda      444:
1.12.14.1! bouyer    445:        /* Attach sub-devices */
        !           446:        if (ahc_aic77xx_attach(ahc) == 0)
        !           447:                return; /* succeed */
        !           448:
        !           449:        /* failed */
        !           450:        isa_intr_disestablish(ia->ia_ic, ahc->ih);
        !           451: free_ahc:
        !           452:        ahc_free(ahc);
        !           453: free_io:
        !           454:        bus_space_unmap(iot, ioh, ia->ia_iosize);
        !           455: }
1.1       soda      456:
1.12.14.1! bouyer    457: /*
        !           458:  * Read the 284x SEEPROM.
        !           459:  */
        !           460: void
        !           461: aha2840_load_seeprom(struct ahc_softc *ahc)
        !           462: {
        !           463:        struct    seeprom_descriptor sd;
        !           464:        struct    seeprom_config sc;
        !           465:        u_int16_t checksum = 0;
        !           466:        u_int8_t  scsi_conf;
        !           467:        int       have_seeprom;
        !           468:
        !           469:        sd.sd_tag = ahc->tag;
        !           470:        sd.sd_bsh = ahc->bsh;
        !           471:        sd.sd_control_offset = SEECTL_2840;
        !           472:        sd.sd_status_offset = STATUS_2840;
        !           473:        sd.sd_dataout_offset = STATUS_2840;
        !           474:        sd.sd_chip = C46;
        !           475:        sd.sd_MS = 0;
        !           476:        sd.sd_RDY = EEPROM_TF;
        !           477:        sd.sd_CS = CS_2840;
        !           478:        sd.sd_CK = CK_2840;
        !           479:        sd.sd_DO = DO_2840;
        !           480:        sd.sd_DI = DI_2840;
        !           481:
        !           482:        if (bootverbose)
        !           483:                printf("%s: Reading SEEPROM...", ahc_name(ahc));
        !           484:        have_seeprom = read_seeprom(&sd,
        !           485:                                    (u_int16_t *)&sc,
        !           486:                                    /*start_addr*/0,
        !           487:                                    sizeof(sc)/2);
        !           488:
        !           489:        if (have_seeprom) {
        !           490:                /* Check checksum */
        !           491:                int i;
        !           492:                int maxaddr = (sizeof(sc)/2) - 1;
        !           493:                u_int16_t *scarray = (u_int16_t *)&sc;
        !           494:
        !           495:                for (i = 0; i < maxaddr; i++)
        !           496:                        checksum = checksum + scarray[i];
        !           497:                if (checksum != sc.checksum) {
        !           498:                        if(bootverbose)
        !           499:                                printf ("checksum error\n");
        !           500:                        have_seeprom = 0;
        !           501:                } else if (bootverbose) {
        !           502:                        printf("done.\n");
1.1       soda      503:                }
                    504:        }
                    505:
1.12.14.1! bouyer    506:        if (!have_seeprom) {
        !           507:                if (bootverbose)
        !           508:                        printf("%s: No SEEPROM available\n", ahc_name(ahc));
        !           509:                ahc->flags |= AHC_USEDEFAULTS;
        !           510:        } else {
        !           511:                /*
        !           512:                 * Put the data we've collected down into SRAM
        !           513:                 * where ahc_init will find it.
        !           514:                 */
        !           515:                int i;
        !           516:                int max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8;
        !           517:                u_int16_t discenable;
        !           518:
        !           519:                discenable = 0;
        !           520:                for (i = 0; i < max_targ; i++){
        !           521:                        u_int8_t target_settings;
        !           522:                        target_settings = (sc.device_flags[i] & CFXFER) << 4;
        !           523:                        if (sc.device_flags[i] & CFSYNCH)
        !           524:                                target_settings |= SOFS;
        !           525:                        if (sc.device_flags[i] & CFWIDEB)
        !           526:                                target_settings |= WIDEXFER;
        !           527:                        if (sc.device_flags[i] & CFDISC)
        !           528:                                discenable |= (0x01 << i);
        !           529:                        ahc_outb(ahc, TARG_SCSIRATE + i, target_settings);
        !           530:                }
        !           531:                ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
        !           532:                ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
1.1       soda      533:
1.12.14.1! bouyer    534:                ahc->our_id = sc.brtime_id & CFSCSIID;
1.1       soda      535:
1.12.14.1! bouyer    536:                scsi_conf = (ahc->our_id & 0x7);
        !           537:                if (sc.adapter_control & CFSPARITY)
        !           538:                        scsi_conf |= ENSPCHK;
        !           539:                if (sc.adapter_control & CFRESETB)
        !           540:                        scsi_conf |= RESET_SCSI;
        !           541:
        !           542:                if (sc.bios_control & CF284XEXTEND)
        !           543:                        ahc->flags |= AHC_EXTENDED_TRANS_A;
        !           544:                /* Set SCSICONF info */
        !           545:                ahc_outb(ahc, SCSICONF, scsi_conf);
1.1       soda      546:
1.12.14.1! bouyer    547:                if (sc.adapter_control & CF284XSTERM)
        !           548:                        ahc->flags |= AHC_TERM_ENB_A;
1.1       soda      549:        }
                    550: }

CVSweb <webmaster@jp.NetBSD.org>