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

Annotation of sys/dev/eisa/eisa.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: eisa.c,v 1.12 2007/06/25 14:13:40 tom Exp $   */
        !             2: /*     $NetBSD: eisa.c,v 1.15 1996/10/21 22:31:01 thorpej Exp $        */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1995, 1996 Christopher G. Demetriou
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  * 3. All advertising materials mentioning features or use of this software
        !            17:  *    must display the following acknowledgement:
        !            18:  *      This product includes software developed by Christopher G. Demetriou
        !            19:  *      for the NetBSD Project.
        !            20:  * 4. The name of the author may not be used to endorse or promote products
        !            21:  *    derived from this software without specific prior written permission
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            33:  */
        !            34:
        !            35: /*
        !            36:  * EISA Bus device
        !            37:  *
        !            38:  * Makes sure an EISA bus is present, and finds and attaches devices
        !            39:  * living on it.
        !            40:  */
        !            41:
        !            42: #include <sys/param.h>
        !            43: #include <sys/systm.h>
        !            44: #include <sys/device.h>
        !            45:
        !            46: #include <machine/bus.h>
        !            47:
        !            48: #include <dev/eisa/eisareg.h>
        !            49: #include <dev/eisa/eisavar.h>
        !            50: #include <dev/eisa/eisadevs.h>
        !            51:
        !            52: int    eisamatch(struct device *, void *, void *);
        !            53: void   eisaattach(struct device *, struct device *, void *);
        !            54:
        !            55: struct cfattach eisa_ca = {
        !            56:        sizeof(struct device), eisamatch, eisaattach
        !            57: };
        !            58:
        !            59: struct cfdriver eisa_cd = {
        !            60:        NULL, "eisa", DV_DULL
        !            61: };
        !            62:
        !            63: int    eisasubmatch(struct device *, void *, void *);
        !            64: int    eisaprint(void *, const char *);
        !            65: void   eisa_devinfo(const char *, char *, size_t);
        !            66:
        !            67: int
        !            68: eisamatch(parent, match, aux)
        !            69:        struct device *parent;
        !            70:        void *match, *aux;
        !            71: {
        !            72:        struct cfdata *cf = match;
        !            73:        struct eisabus_attach_args *eba = aux;
        !            74:
        !            75:        if (strcmp(eba->eba_busname, cf->cf_driver->cd_name))
        !            76:                return (0);
        !            77:
        !            78:        /* XXX check other indicators */
        !            79:
        !            80:        return (1);
        !            81: }
        !            82:
        !            83: int
        !            84: eisaprint(aux, pnp)
        !            85:        void *aux;
        !            86:        const char *pnp;
        !            87: {
        !            88:        register struct eisa_attach_args *ea = aux;
        !            89:        char devinfo[256];
        !            90:
        !            91:        if (pnp) {
        !            92:                eisa_devinfo(ea->ea_idstring, devinfo, sizeof devinfo);
        !            93:                printf("%s at %s", devinfo, pnp);
        !            94:        }
        !            95:        printf(" slot %d", ea->ea_slot);
        !            96:        return (UNCONF);
        !            97: }
        !            98:
        !            99: int
        !           100: eisasubmatch(parent, match, aux)
        !           101:        struct device *parent;
        !           102:        void *match, *aux;
        !           103: {
        !           104:        struct cfdata *cf = match;
        !           105:        struct eisa_attach_args *ea = aux;
        !           106:
        !           107:        if (cf->eisacf_slot != EISA_UNKNOWN_SLOT &&
        !           108:            cf->eisacf_slot != ea->ea_slot)
        !           109:                return 0;
        !           110:        return ((*cf->cf_attach->ca_match)(parent, match, aux));
        !           111: }
        !           112:
        !           113: void
        !           114: eisaattach(parent, self, aux)
        !           115:        struct device *parent, *self;
        !           116:        void *aux;
        !           117: {
        !           118:        struct eisabus_attach_args *eba = aux;
        !           119:        bus_space_tag_t iot, memt;
        !           120:        eisa_chipset_tag_t ec;
        !           121:        int slot, maxnslots;
        !           122:
        !           123:        eisa_attach_hook(parent, self, eba);
        !           124:        printf("\n");
        !           125:
        !           126:        iot = eba->eba_iot;
        !           127:        memt = eba->eba_memt;
        !           128:        ec = eba->eba_ec;
        !           129:
        !           130:        /*
        !           131:         * Search for and attach subdevices.
        !           132:         *
        !           133:         * Slot 0 is the "motherboard" slot, and the code attaching
        !           134:         * the EISA bus should have already attached an ISA bus there.
        !           135:         */
        !           136:        maxnslots = eisa_maxslots(ec);
        !           137:        for (slot = 1; slot < maxnslots; slot++) {
        !           138:                struct eisa_attach_args ea;
        !           139:                u_int slotaddr;
        !           140:                bus_space_handle_t slotioh;
        !           141:                int i;
        !           142:
        !           143:                ea.ea_dmat = eba->eba_dmat;
        !           144:                ea.ea_iot = iot;
        !           145:                ea.ea_memt = memt;
        !           146:                ea.ea_ec = ec;
        !           147:                ea.ea_slot = slot;
        !           148:                slotaddr = EISA_SLOT_ADDR(slot);
        !           149:
        !           150:                /*
        !           151:                 * Get a mapping for the whole slot-specific address
        !           152:                 * space.  If we can't, assume nothing's there but warn
        !           153:                 * about it.
        !           154:                 */
        !           155:                if (bus_space_map(iot, slotaddr, EISA_SLOT_SIZE, 0, &slotioh)) {
        !           156:                        printf("%s: can't map I/O space for slot %d\n",
        !           157:                            self->dv_xname, slot);
        !           158:                        continue;
        !           159:                }
        !           160:
        !           161:                /* Get the vendor ID bytes */
        !           162:                for (i = 0; i < EISA_NVIDREGS; i++) {
        !           163: #ifdef EISA_SLOTOFF_PRIMING
        !           164:                        bus_space_write_1(iot, slotioh,
        !           165:                            EISA_SLOTOFF_PRIMING, EISA_PRIMING_VID(i));
        !           166: #endif
        !           167:                        ea.ea_vid[i] = bus_space_read_1(iot, slotioh,
        !           168:                            EISA_SLOTOFF_VID + i);
        !           169:                }
        !           170:
        !           171:                /* Check for device existence */
        !           172:                if (EISA_VENDID_NODEV(ea.ea_vid)) {
        !           173: #if 0
        !           174:                        printf("no device at %s slot %d\n", self->dv_xname,
        !           175:                            slot);
        !           176:                        printf("\t(0x%x, 0x%x)\n", ea.ea_vid[0],
        !           177:                            ea.ea_vid[1]);
        !           178: #endif
        !           179:                        bus_space_unmap(iot, slotioh, EISA_SLOT_SIZE);
        !           180:                        continue;
        !           181:                }
        !           182:
        !           183:                /* And check that the firmware didn't biff something badly */
        !           184:                if (EISA_VENDID_IDDELAY(ea.ea_vid)) {
        !           185:                        printf("%s slot %d not configured by BIOS?\n",
        !           186:                            self->dv_xname, slot);
        !           187:                        bus_space_unmap(iot, slotioh, EISA_SLOT_SIZE);
        !           188:                        continue;
        !           189:                }
        !           190:
        !           191:                /* Get the product ID bytes */
        !           192:                for (i = 0; i < EISA_NPIDREGS; i++) {
        !           193: #ifdef EISA_SLOTOFF_PRIMING
        !           194:                        bus_space_write_1(iot, slotioh,
        !           195:                            EISA_SLOTOFF_PRIMING, EISA_PRIMING_PID(i));
        !           196: #endif
        !           197:                        ea.ea_pid[i] = bus_space_read_1(iot, slotioh,
        !           198:                            EISA_SLOTOFF_PID + i);
        !           199:                }
        !           200:
        !           201:                /* Create the ID string from the vendor and product IDs */
        !           202:                ea.ea_idstring[0] = EISA_VENDID_0(ea.ea_vid);
        !           203:                ea.ea_idstring[1] = EISA_VENDID_1(ea.ea_vid);
        !           204:                ea.ea_idstring[2] = EISA_VENDID_2(ea.ea_vid);
        !           205:                ea.ea_idstring[3] = EISA_PRODID_0(ea.ea_pid);
        !           206:                ea.ea_idstring[4] = EISA_PRODID_1(ea.ea_pid);
        !           207:                ea.ea_idstring[5] = EISA_PRODID_2(ea.ea_pid);
        !           208:                ea.ea_idstring[6] = EISA_PRODID_3(ea.ea_pid);
        !           209:                ea.ea_idstring[7] = '\0';               /* sanity */
        !           210:
        !           211:                /* We no longer need the I/O handle; free it. */
        !           212:                bus_space_unmap(iot, slotioh, EISA_SLOT_SIZE);
        !           213:
        !           214:                /* Attach matching device. */
        !           215:                config_found_sm(self, &ea, eisaprint, eisasubmatch);
        !           216:        }
        !           217: }
        !           218:
        !           219: #ifdef EISAVERBOSE
        !           220: /*
        !           221:  * Descriptions of known vendors and devices ("products").
        !           222:  */
        !           223: struct eisa_knowndev {
        !           224:        int     flags;
        !           225:        char    id[8];
        !           226:        const char *name;
        !           227: };
        !           228: #define EISA_KNOWNDEV_NOPROD   0x01            /* match on vendor only */
        !           229:
        !           230: #include <dev/eisa/eisadevs_data.h>
        !           231: #endif /* EISAVERBOSE */
        !           232:
        !           233: void
        !           234: eisa_devinfo(const char *id, char *cp, size_t cp_len)
        !           235: {
        !           236:        const char *name;
        !           237:        int onlyvendor;
        !           238: #ifdef EISAVERBOSE
        !           239:        const struct eisa_knowndev *edp;
        !           240:        int match;
        !           241:        const char *unmatched = "unknown ";
        !           242: #else
        !           243:        const char *unmatched = "";
        !           244: #endif
        !           245:
        !           246:        onlyvendor = 0;
        !           247:        name = NULL;
        !           248:
        !           249: #ifdef EISAVERBOSE
        !           250:        /* find the device in the table, if possible. */
        !           251:        edp = eisa_knowndevs;
        !           252:        while (edp->name != NULL) {
        !           253:                /* check this entry for a match */
        !           254:                if ((edp->flags & EISA_KNOWNDEV_NOPROD) != 0)
        !           255:                        match = !strncmp(edp->id, id, 3);
        !           256:                else
        !           257:                        match = !strcmp(edp->id, id);
        !           258:                if (match) {
        !           259:                        name = edp->name;
        !           260:                        onlyvendor = (edp->flags & EISA_KNOWNDEV_NOPROD) != 0;
        !           261:                        break;
        !           262:                }
        !           263:                edp++;
        !           264:        }
        !           265: #endif
        !           266:
        !           267:        if (name == NULL)
        !           268:                snprintf(cp, cp_len, "%sdevice %s", unmatched, id);
        !           269:        else if (onlyvendor)                    /* never if not EISAVERBOSE */
        !           270:                snprintf(cp, cp_len, "unknown %s device %s", name, id);
        !           271:        else
        !           272:                snprintf(cp, cp_len, "%s", name);
        !           273: }

CVSweb