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

Annotation of sys/arch/hp300/dev/dio.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: dio.c,v 1.12 2005/01/15 23:37:45 miod Exp $   */
        !             2: /*     $NetBSD: dio.c,v 1.7 1997/05/05 21:00:32 thorpej Exp $  */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * This code is derived from software contributed to The NetBSD Foundation
        !             9:  * by Jason R. Thorpe.
        !            10:  *
        !            11:  * Redistribution and use in source and binary forms, with or without
        !            12:  * modification, are permitted provided that the following conditions
        !            13:  * are met:
        !            14:  * 1. Redistributions of source code must retain the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer.
        !            16:  * 2. Redistributions in binary form must reproduce the above copyright
        !            17:  *    notice, this list of conditions and the following disclaimer in the
        !            18:  *    documentation and/or other materials provided with the distribution.
        !            19:  * 3. All advertising materials mentioning features or use of this software
        !            20:  *    must display the following acknowledgement:
        !            21:  *        This product includes software developed by the NetBSD
        !            22:  *        Foundation, Inc. and its contributors.
        !            23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            24:  *    contributors may be used to endorse or promote products derived
        !            25:  *    from this software without specific prior written permission.
        !            26:  *
        !            27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
        !            31:  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            37:  * POSSIBILITY OF SUCH DAMAGE.
        !            38:  */
        !            39:
        !            40: /*
        !            41:  * Autoconfiguration and mapping support for the DIO bus.
        !            42:  */
        !            43:
        !            44: #include <sys/param.h>
        !            45: #include <sys/systm.h>
        !            46: #include <sys/device.h>
        !            47: #include <sys/kernel.h>
        !            48: #include <sys/device.h>
        !            49:
        !            50: #include <machine/autoconf.h>
        !            51: #include <machine/cpu.h>
        !            52: #include <machine/hp300spu.h>
        !            53:
        !            54: #include <hp300/dev/dmavar.h>
        !            55:
        !            56: #include <hp300/dev/dioreg.h>
        !            57: #include <hp300/dev/diovar.h>
        !            58:
        !            59: #include <hp300/dev/diodevs.h>
        !            60: #include <hp300/dev/diodevs_data.h>
        !            61:
        !            62: extern caddr_t internalhpib;
        !            63:
        !            64: int    dio_scodesize(struct dio_attach_args *);
        !            65: char   *dio_devinfo(struct dio_attach_args *, char *, size_t);
        !            66:
        !            67: int    diomatch(struct device *, void *, void *);
        !            68: void   dioattach(struct device *, struct device *, void *);
        !            69: int    dioprint(void *, const char *);
        !            70: int    diosubmatch(struct device *, void *, void *);
        !            71:
        !            72: struct cfattach dio_ca = {
        !            73:        sizeof(struct device), diomatch, dioattach
        !            74: };
        !            75:
        !            76: struct cfdriver dio_cd = {
        !            77:        NULL, "dio", DV_DULL
        !            78: };
        !            79:
        !            80: int
        !            81: diomatch(parent, match, aux)
        !            82:        struct device *parent;
        !            83:        void *match, *aux;
        !            84: {
        !            85:        static int dio_matched = 0;
        !            86:
        !            87:        /* Allow only one instance. */
        !            88:        if (dio_matched)
        !            89:                return (0);
        !            90:
        !            91:        dio_matched = 1;
        !            92:        return (1);
        !            93: }
        !            94:
        !            95: void
        !            96: dioattach(parent, self, aux)
        !            97:        struct device *parent, *self;
        !            98:        void *aux;
        !            99: {
        !           100:        struct dio_attach_args da;
        !           101:        caddr_t pa, va;
        !           102:        int scode, scmax, didmap, scodesize;
        !           103:
        !           104:        scmax = DIO_SCMAX(machineid);
        !           105:        printf(": ");
        !           106:        dmainit();
        !           107:
        !           108:        for (scode = 0; scode < scmax; ) {
        !           109:                if (DIO_INHOLE(scode)) {
        !           110:                        scode++;
        !           111:                        continue;
        !           112:                }
        !           113:
        !           114:                didmap = 0;
        !           115:
        !           116:                /*
        !           117:                 * Temporarily map the space corresponding to
        !           118:                 * the current select code unless:
        !           119:                 *      - this is the internal hpib select code,
        !           120:                 *      - this is the console select code.
        !           121:                 */
        !           122:                pa = dio_scodetopa(scode);
        !           123:                if (scode == conscode)
        !           124:                        va = conaddr;
        !           125:                else if ((scode == 7) && internalhpib)
        !           126:                        va = internalhpib = (caddr_t)IIOV(pa);
        !           127:                else {
        !           128:                        va = iomap(pa, NBPG);
        !           129:                        if (va == NULL) {
        !           130:                                printf("%s: can't map scode %d\n",
        !           131:                                    self->dv_xname, scode);
        !           132:                                scode++;
        !           133:                                continue;
        !           134:                        }
        !           135:                        didmap = 1;
        !           136:                }
        !           137:
        !           138:                /* Check for hardware. */
        !           139:                if (badaddr(va)) {
        !           140:                        if (didmap)
        !           141:                                iounmap(va, NBPG);
        !           142:                        scode++;
        !           143:                        continue;
        !           144:                }
        !           145:
        !           146:                /* Fill out attach args. */
        !           147:                bzero(&da, sizeof(da));
        !           148:                da.da_scode = scode;
        !           149:                if (scode == 7 && internalhpib)
        !           150:                        da.da_id = DIO_DEVICE_ID_IHPIB;
        !           151:                else {
        !           152:                        da.da_id = DIO_ID(va);
        !           153:                        /*
        !           154:                         * If we probe an unknown device, we do not necessarily
        !           155:                         * know how many scodes it will span.
        !           156:                         * Extra scodes will usually report an id of zero,
        !           157:                         * which would match ihpib!
        !           158:                         * Check for this, warn the user, and skip that scode.
        !           159:                         */
        !           160:                        if (da.da_id == 0) {
        !           161:                                if (didmap)
        !           162:                                        iounmap(va, NBPG);
        !           163:                                printf("%s: warning: select code %d is likely "
        !           164:                                    "a span of a previous unsupported device\n",
        !           165:                                    self->dv_xname, scode);
        !           166:                                scode++;
        !           167:                                continue;
        !           168:                        }
        !           169:                }
        !           170:
        !           171:                if (DIO_ISFRAMEBUFFER(da.da_id))
        !           172:                        da.da_secid = DIO_SECID(va);
        !           173:
        !           174:                da.da_size = DIO_SIZE(scode, va);
        !           175:                scodesize = dio_scodesize(&da);
        !           176:                if (DIO_ISDIO(scode))
        !           177:                        da.da_size *= scodesize;
        !           178:
        !           179:                /* No longer need the device to be mapped. */
        !           180:                if (didmap)
        !           181:                        iounmap(va, NBPG);
        !           182:
        !           183:                /* Attach matching device. */
        !           184:                config_found_sm(self, &da, dioprint, diosubmatch);
        !           185:                scode += scodesize;
        !           186:        }
        !           187: }
        !           188:
        !           189: int
        !           190: diosubmatch(parent, match, aux)
        !           191:        struct device *parent;
        !           192:        void *match, *aux;
        !           193: {
        !           194:        struct cfdata *cf = match;
        !           195:        struct dio_attach_args *da = aux;
        !           196:
        !           197:        if (cf->diocf_scode != DIO_UNKNOWN_SCODE &&
        !           198:            cf->diocf_scode != da->da_scode)
        !           199:                return (0);
        !           200:
        !           201:        return ((*cf->cf_attach->ca_match)(parent, cf, aux));
        !           202: }
        !           203:
        !           204: int
        !           205: dioprint(aux, pnp)
        !           206:        void *aux;
        !           207:        const char *pnp;
        !           208: {
        !           209:        struct dio_attach_args *da = aux;
        !           210:        char buf[128];
        !           211:
        !           212:        if (pnp)
        !           213:                printf("%s at %s", dio_devinfo(da, buf, sizeof(buf)), pnp);
        !           214:        printf(" scode %d", da->da_scode);
        !           215:        return (UNCONF);
        !           216: }
        !           217:
        !           218: /*
        !           219:  * Convert a select code to a system physical address.
        !           220:  */
        !           221: void *
        !           222: dio_scodetopa(scode)
        !           223:        int scode;
        !           224: {
        !           225:        u_long rval;
        !           226:
        !           227:        if (scode == 7 && internalhpib)
        !           228:                rval = DIO_IHPIBADDR;
        !           229:        else if (DIO_ISDIO(scode))
        !           230:                rval = DIO_BASE + (scode * DIO_DEVSIZE);
        !           231:        else if (DIO_ISDIOII(scode))
        !           232:                rval = DIOII_BASE + ((scode - DIOII_SCBASE) * DIOII_DEVSIZE);
        !           233:        else
        !           234:                rval = 0;
        !           235:
        !           236:        return ((void *)rval);
        !           237: }
        !           238:
        !           239: /*
        !           240:  * Return the select code size for this device, defaulting to 1
        !           241:  * if we don't know what kind of device we have.
        !           242:  */
        !           243: int
        !           244: dio_scodesize(da)
        !           245:        struct dio_attach_args *da;
        !           246: {
        !           247:        int i;
        !           248:
        !           249:        /*
        !           250:         * Deal with lame internal HP-IB controllers which don't have
        !           251:         * consistent/reliable device ids.
        !           252:         */
        !           253:        if (da->da_scode == 7 && internalhpib)
        !           254:                return (1);
        !           255:
        !           256:        /*
        !           257:         * Find the dio_devdata matching the primary id.
        !           258:         * If we're a framebuffer, we also check the secondary id.
        !           259:         */
        !           260:        for (i = 0; i < DIO_NDEVICES; i++) {
        !           261:                if (da->da_id == dio_devdatas[i].dd_id) {
        !           262:                        if (DIO_ISFRAMEBUFFER(da->da_id)) {
        !           263:                                if (da->da_secid == dio_devdatas[i].dd_secid) {
        !           264:                                        goto foundit;
        !           265:                                }
        !           266:                        } else {
        !           267:                        foundit:
        !           268:                                return (dio_devdatas[i].dd_nscode);
        !           269:                        }
        !           270:                }
        !           271:        }
        !           272:
        !           273:        /*
        !           274:         * Device is unknown.  Print a warning and assume a default.
        !           275:         */
        !           276:        printf("WARNING: select code size unknown for id = 0x%x secid = 0x%x\n",
        !           277:            da->da_id, da->da_secid);
        !           278:        return (1);
        !           279: }
        !           280:
        !           281: /*
        !           282:  * Return a reasonable description of a DIO device.
        !           283:  */
        !           284: char *
        !           285: dio_devinfo(da, buf, buflen)
        !           286:        struct dio_attach_args *da;
        !           287:        char *buf;
        !           288:        size_t buflen;
        !           289: {
        !           290: #ifdef DIOVERBOSE
        !           291:        int i;
        !           292: #endif
        !           293:
        !           294:        bzero(buf, buflen);
        !           295:
        !           296:        /*
        !           297:         * Deal with lame internal HP-IB controllers which don't have
        !           298:         * consistent/reliable device ids.
        !           299:         */
        !           300:        if (da->da_scode == 7 && internalhpib) {
        !           301:                snprintf(buf, buflen, DIO_DEVICE_DESC_IHPIB);
        !           302:                return (buf);
        !           303:        }
        !           304:
        !           305: #ifdef DIOVERBOSE
        !           306:        /*
        !           307:         * Find the description matching our primary id.
        !           308:         * If we're a framebuffer, we also check the secondary id.
        !           309:         */
        !           310:        for (i = 0; i < DIO_NDEVICES; i++) {
        !           311:                if (da->da_id == dio_devdescs[i].dd_id) {
        !           312:                        if (DIO_ISFRAMEBUFFER(da->da_id)) {
        !           313:                                if (da->da_secid == dio_devdescs[i].dd_secid) {
        !           314:                                        goto foundit;
        !           315:                                }
        !           316:                        } else {
        !           317:                        foundit:
        !           318:                                snprintf(buf, buflen, "%s",
        !           319:                                    dio_devdescs[i].dd_desc);
        !           320:                                return (buf);
        !           321:                        }
        !           322:                }
        !           323:        }
        !           324: #endif /* DIOVERBOSE */
        !           325:
        !           326:        /*
        !           327:         * Device is unknown.  Construct something reasonable.
        !           328:         */
        !           329:        snprintf(buf, buflen, "device id = 0x%x secid = 0x%x",
        !           330:            da->da_id, da->da_secid);
        !           331:        return (buf);
        !           332: }
        !           333:
        !           334: /*
        !           335:  * Establish an interrupt handler for a DIO device.
        !           336:  */
        !           337: void
        !           338: dio_intr_establish(struct isr *isr, const char *name)
        !           339: {
        !           340:        intr_establish(isr, name);
        !           341:
        !           342:        if (isr->isr_priority == IPL_BIO)
        !           343:                dmacomputeipl();
        !           344: }
        !           345:
        !           346: /*
        !           347:  * Remove an interrupt handler for a DIO device.
        !           348:  */
        !           349: void
        !           350: dio_intr_disestablish(struct isr *isr)
        !           351: {
        !           352:        intr_disestablish(isr);
        !           353:
        !           354:        if (isr->isr_priority == IPL_BIO)
        !           355:                dmacomputeipl();
        !           356: }

CVSweb