[BACK]Return to dl.c CVS log [TXT][DIR] Up to [local] / sys / arch / vax / qbus

Annotation of sys/arch/vax/qbus/dl.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: dl.c,v 1.5 2003/10/03 16:44:50 miod Exp $     */
        !             2: /*     $NetBSD: dl.c,v 1.11 2000/01/24 02:40:29 matt 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 FOUNDATION OR CONTRIBUTORS
        !            31:  * BE 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:  * Copyright (c) 1997  Ben Harris.  All rights reserved.
        !            42:  * Copyright (c) 1996  Ken C. Wellsch.  All rights reserved.
        !            43:  * Copyright (c) 1982, 1986, 1990, 1992, 1993
        !            44:  *     The Regents of the University of California.  All rights reserved.
        !            45:  *
        !            46:  * This code is derived from software contributed to Berkeley by
        !            47:  * Ralph Campbell and Rick Macklem.
        !            48:  *
        !            49:  * Redistribution and use in source and binary forms, with or without
        !            50:  * modification, are permitted provided that the following conditions
        !            51:  * are met:
        !            52:  * 1. Redistributions of source code must retain the above copyright
        !            53:  *    notice, this list of conditions and the following disclaimer.
        !            54:  * 2. Redistributions in binary form must reproduce the above copyright
        !            55:  *    notice, this list of conditions and the following disclaimer in the
        !            56:  *    documentation and/or other materials provided with the distribution.
        !            57:  * 3. Neither the name of the University nor the names of its contributors
        !            58:  *    may be used to endorse or promote products derived from this software
        !            59:  *    without specific prior written permission.
        !            60:  *
        !            61:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            62:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            63:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            64:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            65:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            66:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            67:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            68:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            69:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            70:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            71:  * SUCH DAMAGE.
        !            72:  */
        !            73:
        !            74: /*
        !            75:  * dl.c -- Device driver for the DL11 and DLV11 serial cards.
        !            76:  *
        !            77:  * OS-interface code derived from the dz and dca (hp300) drivers.
        !            78:  */
        !            79:
        !            80: #include <sys/param.h>
        !            81: #include <sys/systm.h>
        !            82: #include <sys/ioctl.h>
        !            83: #include <sys/tty.h>
        !            84: #include <sys/proc.h>
        !            85: #include <sys/buf.h>
        !            86: #include <sys/conf.h>
        !            87: #include <sys/file.h>
        !            88: #include <sys/uio.h>
        !            89: #include <sys/kernel.h>
        !            90: #include <sys/syslog.h>
        !            91: #include <sys/device.h>
        !            92:
        !            93: #include <machine/bus.h>
        !            94: #include <machine/scb.h>
        !            95:
        !            96: #include <arch/vax/qbus/ubavar.h>
        !            97: #include <arch/vax/qbus/dlreg.h>
        !            98:
        !            99: struct dl_softc {
        !           100:        struct device   sc_dev;
        !           101:        bus_space_tag_t sc_iot;
        !           102:        bus_space_handle_t sc_ioh;
        !           103:        struct tty      *sc_tty;
        !           104: };
        !           105:
        !           106: static int     dl_match(struct device *, struct cfdata *, void *);
        !           107: static void    dl_attach(struct device *, struct device *, void *);
        !           108: static void    dlrint(void *);
        !           109: static void    dlxint(void *);
        !           110: static void    dlstart(struct tty *);
        !           111: static int     dlparam(struct tty *, struct termios *);
        !           112: static void    dlbrk(struct dl_softc *, int);
        !           113: struct tty *   dltty(dev_t);
        !           114:        int     dlopen(dev_t, int, int, struct proc *);
        !           115:        int     dlclose(dev_t, int, int, struct proc *);
        !           116:        int     dlread(dev_t, struct uio *, int);
        !           117:        int     dlwrite(dev_t, struct uio *, int);
        !           118:        int     dlioctl(dev_t, int, caddr_t, int, struct proc *);
        !           119:        void    dlstop(struct tty *, int);
        !           120:
        !           121: struct cfattach dl_ca = {
        !           122:        sizeof(struct dl_softc), (cfmatch_t)dl_match, dl_attach
        !           123: };
        !           124:
        !           125: struct cfdriver dl_cd = {
        !           126:        NULL, "dl", DV_TTY
        !           127: };
        !           128:
        !           129: #define        DL_READ_WORD(reg) \
        !           130:        bus_space_read_2(sc->sc_iot, sc->sc_ioh, reg)
        !           131: #define        DL_WRITE_WORD(reg, val) \
        !           132:        bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg, val)
        !           133: #define        DL_WRITE_BYTE(reg, val) \
        !           134:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, reg, val)
        !           135:
        !           136: /* Autoconfig handles: setup the controller to interrupt, */
        !           137: /* then complete the housecleaning for full operation */
        !           138:
        !           139: static int
        !           140: dl_match (parent, cf, aux)
        !           141:        struct device * parent;
        !           142:        struct cfdata *cf;
        !           143:        void *aux;
        !           144: {
        !           145:        struct uba_attach_args *ua = aux;
        !           146:
        !           147: #ifdef DL_DEBUG
        !           148:        printf("Probing for dl at %lo ... ", (long)ua->ua_iaddr);
        !           149: #endif
        !           150:
        !           151:        bus_space_write_2(ua->ua_iot, ua->ua_ioh, DL_UBA_XCSR, DL_XCSR_TXIE);
        !           152:        if (bus_space_read_2(ua->ua_iot, ua->ua_ioh, DL_UBA_XCSR) !=
        !           153:            (DL_XCSR_TXIE | DL_XCSR_TX_READY)) {
        !           154: #ifdef DL_DEBUG
        !           155:                printf("failed (step 1; XCSR = %.4b)\n",
        !           156:                    bus_space_read_2(ua->ua_iot, ua->ua_ioh, DL_UBA_XCSR),
        !           157:                    DL_XCSR_BITS);
        !           158: #endif
        !           159:                return 0;
        !           160:        }
        !           161:
        !           162:        /*
        !           163:         * We have to force an interrupt so the uba driver can work
        !           164:         * out where we are.  Unfortunately, the only way to make a
        !           165:         * DL11 interrupt is to get it to send or receive a
        !           166:         * character.  We'll send a NUL and hope it doesn't hurt
        !           167:         * anything.
        !           168:         */
        !           169:
        !           170:        bus_space_write_1(ua->ua_iot, ua->ua_ioh, DL_UBA_XBUFL, '\0');
        !           171: #if 0 /* This test seems to fail 2/3 of the time :-( */
        !           172:        if (dladdr->dl_xcsr != (DL_XCSR_TXIE)) {
        !           173: #ifdef DL_DEBUG
        !           174:                printf("failed (step 2; XCSR = %.4b)\n", dladdr->dl_xcsr,
        !           175:                       DL_XCSR_BITS);
        !           176: #endif
        !           177:                return 0;
        !           178:        }
        !           179: #endif
        !           180:        DELAY(100000); /* delay 1/10 s for character to transmit */
        !           181:        if (bus_space_read_2(ua->ua_iot, ua->ua_ioh, DL_UBA_XCSR) !=
        !           182:            (DL_XCSR_TXIE | DL_XCSR_TX_READY)) {
        !           183: #ifdef DL_DEBUG
        !           184:                printf("failed (step 3; XCSR = %.4b)\n",
        !           185:                    bus_space_read_2(ua->ua_iot, ua->ua_ioh, DL_UBA_XCSR),
        !           186:                    DL_XCSR_BITS);
        !           187: #endif
        !           188:                return 0;
        !           189:        }
        !           190:
        !           191:
        !           192:         /* What else do I need to do? */
        !           193:
        !           194:        return 1;
        !           195:
        !           196: }
        !           197:
        !           198: static void
        !           199: dl_attach (parent, self, aux)
        !           200:        struct device *parent, *self;
        !           201:        void *aux;
        !           202: {
        !           203:        struct dl_softc *sc = (void *)self;
        !           204:        register struct uba_attach_args *ua = aux;
        !           205:
        !           206:        sc->sc_iot = ua->ua_iot;
        !           207:        sc->sc_ioh = ua->ua_ioh;
        !           208:
        !           209:        /* Tidy up the device */
        !           210:
        !           211:        DL_WRITE_WORD(DL_UBA_RCSR, DL_RCSR_RXIE);
        !           212:        DL_WRITE_WORD(DL_UBA_XCSR, DL_XCSR_TXIE);
        !           213:
        !           214:        /* Initialize our softc structure. Should be done in open? */
        !           215:
        !           216:        sc->sc_tty = ttymalloc();
        !           217:
        !           218:        /* Now register the TX & RX interrupt handlers */
        !           219:        uba_intr_establish(ua->ua_icookie, ua->ua_cvec    , dlxint, sc);
        !           220:        uba_intr_establish(ua->ua_icookie, ua->ua_cvec - 4, dlrint, sc);
        !           221:
        !           222:        printf("\n");
        !           223: }
        !           224:
        !           225: /* Receiver Interrupt Handler */
        !           226:
        !           227: static void
        !           228: dlrint(arg)
        !           229:        void *arg;
        !           230: {
        !           231:        struct  dl_softc *sc = arg;
        !           232:        register struct tty *tp;
        !           233:        register int cc;
        !           234:        register unsigned c;
        !           235:
        !           236:        if (DL_READ_WORD(DL_UBA_RCSR) & DL_RCSR_RX_DONE) {
        !           237:                c = DL_READ_WORD(DL_UBA_RBUF);
        !           238:                cc = c & 0xFF;
        !           239:                tp = sc->sc_tty;
        !           240:
        !           241:                if (!(tp->t_state & TS_ISOPEN)) {
        !           242:                        wakeup((caddr_t)&tp->t_rawq);
        !           243:                        return;
        !           244:                }
        !           245:
        !           246:                if (c & DL_RBUF_OVERRUN_ERR)
        !           247:                        /*
        !           248:                         * XXX: This should really be logged somwhere
        !           249:                         * else where we can afford the time.
        !           250:                         */
        !           251:                        log(LOG_WARNING, "%s: rx overrun\n",
        !           252:                            sc->sc_dev.dv_xname);
        !           253:                if (c & DL_RBUF_FRAMING_ERR)
        !           254:                        cc |= TTY_FE;
        !           255:                if (c & DL_RBUF_PARITY_ERR)
        !           256:                        cc |= TTY_PE;
        !           257:
        !           258:                (*linesw[tp->t_line].l_rint)(cc, tp);
        !           259:        } else
        !           260:                log(LOG_WARNING, "%s: stray rx interrupt\n",
        !           261:                    sc->sc_dev.dv_xname);
        !           262:        return;
        !           263: }
        !           264:
        !           265: /* Transmitter Interrupt Handler */
        !           266:
        !           267: static void
        !           268: dlxint(arg)
        !           269:        void *arg;
        !           270: {
        !           271:        struct dl_softc *sc = arg;
        !           272:        register struct tty *tp;
        !           273:
        !           274:        tp = sc->sc_tty;
        !           275:        tp->t_state &= ~(TS_BUSY | TS_FLUSH);
        !           276:        if (tp->t_line)
        !           277:                (*linesw[tp->t_line].l_start)(tp);
        !           278:        else
        !           279:                dlstart(tp);
        !           280:
        !           281:        return;
        !           282: }
        !           283:
        !           284: int
        !           285: dlopen(dev, flag, mode, p)
        !           286:        dev_t dev;
        !           287:        int flag, mode;
        !           288:        struct proc *p;
        !           289: {
        !           290:        register struct tty *tp;
        !           291:        register int unit;
        !           292:        struct dl_softc *sc;
        !           293:
        !           294:        unit = minor(dev);
        !           295:
        !           296:        if (unit >= dl_cd.cd_ndevs || dl_cd.cd_devs[unit] == NULL)
        !           297:                return ENXIO;
        !           298:        sc = dl_cd.cd_devs[unit];
        !           299:
        !           300:        tp = sc->sc_tty;
        !           301:        if (tp == NULL)
        !           302:                return ENODEV;
        !           303:        tp->t_oproc = dlstart;
        !           304:        tp->t_param = dlparam;
        !           305:        tp->t_dev = dev;
        !           306:
        !           307:        if (!(tp->t_state & TS_ISOPEN)) {
        !           308:                ttychars(tp);
        !           309:                tp->t_iflag = TTYDEF_IFLAG;
        !           310:                tp->t_oflag = TTYDEF_OFLAG;
        !           311:                /* No modem control, so set CLOCAL. */
        !           312:                tp->t_cflag = TTYDEF_CFLAG | CLOCAL;
        !           313:                tp->t_lflag = TTYDEF_LFLAG;
        !           314:                tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
        !           315:
        !           316:                dlparam(tp, &tp->t_termios);
        !           317:                ttsetwater(tp);
        !           318:
        !           319:        } else if ((tp->t_state & TS_XCLUDE) && p->p_ucred->cr_uid != 0)
        !           320:                return EBUSY;
        !           321:
        !           322:        return ((*linesw[tp->t_line].l_open)(dev, tp));
        !           323: }
        !           324:
        !           325: /*ARGSUSED*/
        !           326: int
        !           327: dlclose(dev, flag, mode, p)
        !           328:        dev_t dev;
        !           329:        int flag, mode;
        !           330:        struct proc *p;
        !           331: {
        !           332:        struct dl_softc *sc;
        !           333:        register struct tty *tp;
        !           334:        register int unit;
        !           335:
        !           336:        unit = minor(dev);
        !           337:        sc = dl_cd.cd_devs[unit];
        !           338:        tp = sc->sc_tty;
        !           339:
        !           340:        (*linesw[tp->t_line].l_close)(tp, flag);
        !           341:
        !           342:        /* Make sure a BREAK state is not left enabled. */
        !           343:        dlbrk(sc, 0);
        !           344:
        !           345:        return (ttyclose(tp));
        !           346: }
        !           347:
        !           348: int
        !           349: dlread(dev, uio, flag)
        !           350:        dev_t dev;
        !           351:        struct uio *uio;
        !           352:        int flag;
        !           353: {
        !           354:        register struct tty *tp;
        !           355:        struct dl_softc *sc;
        !           356:        register int unit;
        !           357:
        !           358:        unit = minor(dev);
        !           359:        sc = dl_cd.cd_devs[unit];
        !           360:        tp = sc->sc_tty;
        !           361:        return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
        !           362: }
        !           363:
        !           364: int
        !           365: dlwrite(dev, uio, flag)
        !           366:        dev_t dev;
        !           367:        struct uio *uio;
        !           368:        int flag;
        !           369: {
        !           370:        register struct tty *tp;
        !           371:        struct dl_softc *sc;
        !           372:        register int unit;
        !           373:
        !           374:        unit = minor(dev);
        !           375:        sc = dl_cd.cd_devs[unit];
        !           376:        tp = sc->sc_tty;
        !           377:        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
        !           378: }
        !           379:
        !           380: int
        !           381: dlioctl(dev, cmd, data, flag, p)
        !           382:        dev_t dev;
        !           383:         int cmd;
        !           384:         caddr_t data;
        !           385:         int flag;
        !           386:         struct proc *p;
        !           387: {
        !           388:        struct dl_softc *sc;
        !           389:         register struct tty *tp;
        !           390:         register int unit;
        !           391:         int error;
        !           392:
        !           393:        unit = minor(dev);
        !           394:        sc = dl_cd.cd_devs[unit];
        !           395:        tp = sc->sc_tty;
        !           396:
        !           397:         error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
        !           398:         if (error >= 0)
        !           399:                 return (error);
        !           400:         error = ttioctl(tp, cmd, data, flag, p);
        !           401:         if (error >= 0)
        !           402:                 return (error);
        !           403:
        !           404:        switch (cmd) {
        !           405:
        !           406:         case TIOCSBRK:
        !           407:                 dlbrk(sc, 1);
        !           408:                 break;
        !           409:
        !           410:         case TIOCCBRK:
        !           411:                 dlbrk(sc, 0);
        !           412:                 break;
        !           413:
        !           414:         case TIOCMGET:
        !           415:                /* No modem control, assume they're all low. */
        !           416:                 *(int *)data = 0;
        !           417:                 break;
        !           418:
        !           419:         default:
        !           420:                 return (ENOTTY);
        !           421:         }
        !           422:         return (0);
        !           423: }
        !           424:
        !           425: struct tty *
        !           426: dltty(dev)
        !           427:        dev_t dev;
        !           428: {
        !           429:        register struct dl_softc* sc;
        !           430:
        !           431:        sc = dl_cd.cd_devs[minor(dev)];
        !           432:        return sc->sc_tty;
        !           433: }
        !           434:
        !           435: void
        !           436: dlstop(tp, flag)
        !           437:        register struct tty *tp;
        !           438:        int flag;
        !           439: {
        !           440:        register struct dl_softc *sc;
        !           441:        int unit, s;
        !           442:
        !           443:        unit = minor(tp->t_dev);
        !           444:        sc = dl_cd.cd_devs[unit];
        !           445:
        !           446:        s = spltty();
        !           447:
        !           448:        if (tp->t_state & TS_BUSY)
        !           449:                 if (!(tp->t_state & TS_TTSTOP))
        !           450:                         tp->t_state |= TS_FLUSH;
        !           451:         splx(s);
        !           452: }
        !           453:
        !           454: static void
        !           455: dlstart(tp)
        !           456:        register struct tty *tp;
        !           457: {
        !           458:        register struct dl_softc *sc;
        !           459:        register int unit;
        !           460:        int s;
        !           461:
        !           462:        unit = minor(tp->t_dev);
        !           463:        sc = dl_cd.cd_devs[unit];
        !           464:
        !           465:        s = spltty();
        !           466:         if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
        !           467:                 goto out;
        !           468:         if (tp->t_outq.c_cc <= tp->t_lowat) {
        !           469:                 if (tp->t_state & TS_ASLEEP) {
        !           470:                         tp->t_state &= ~TS_ASLEEP;
        !           471:                         wakeup((caddr_t)&tp->t_outq);
        !           472:                 }
        !           473:                 selwakeup(&tp->t_wsel);
        !           474:         }
        !           475:         if (tp->t_outq.c_cc == 0)
        !           476:                 goto out;
        !           477:
        !           478:
        !           479:        if (DL_READ_WORD(DL_UBA_XCSR) & DL_XCSR_TX_READY) {
        !           480:                tp->t_state |= TS_BUSY;
        !           481:                DL_WRITE_BYTE(DL_UBA_XBUFL, getc(&tp->t_outq));
        !           482:        }
        !           483: out:
        !           484:        splx(s);
        !           485:        return;
        !           486: }
        !           487:
        !           488: /*ARGSUSED*/
        !           489: static int
        !           490: dlparam(tp, t)
        !           491:         register struct tty *tp;
        !           492:         register struct termios *t;
        !           493: {
        !           494:        /*
        !           495:         * All this kind of stuff (speed, character format, whatever)
        !           496:         * is set by jumpers on the card.  Changing it is thus rather
        !           497:         * tricky for a mere device driver.
        !           498:         */
        !           499:        return 0;
        !           500: }
        !           501:
        !           502: static void
        !           503: dlbrk(sc, state)
        !           504:        register struct dl_softc *sc;
        !           505:        int state;
        !           506: {
        !           507:        int s = spltty();
        !           508:
        !           509:        if (state) {
        !           510:                DL_WRITE_WORD(DL_UBA_XCSR, DL_READ_WORD(DL_UBA_XCSR) |
        !           511:                    DL_XCSR_TX_BREAK);
        !           512:        } else {
        !           513:                DL_WRITE_WORD(DL_UBA_XCSR, DL_READ_WORD(DL_UBA_XCSR) &
        !           514:                    ~DL_XCSR_TX_BREAK);
        !           515:        }
        !           516:        splx(s);
        !           517: }

CVSweb