[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

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