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

Annotation of sys/arch/hppa/dev/pdc.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: pdc.c,v 1.30 2007/07/15 19:25:49 kettenis Exp $       */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 1998-2003 Michael Shalayeff
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  *
        !            16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            18:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            19:  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
        !            20:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            21:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            22:  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            24:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
        !            25:  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
        !            26:  * THE POSSIBILITY OF SUCH DAMAGE.
        !            27:  */
        !            28:
        !            29: #include "com.h"
        !            30:
        !            31: #include <sys/param.h>
        !            32: #include <sys/systm.h>
        !            33: #include <sys/device.h>
        !            34: #include <sys/tty.h>
        !            35: #include <sys/user.h>
        !            36: #include <sys/timeout.h>
        !            37:
        !            38: #include <dev/cons.h>
        !            39:
        !            40: #include <machine/conf.h>
        !            41: #include <machine/pdc.h>
        !            42: #include <machine/iomod.h>
        !            43: #include <machine/autoconf.h>
        !            44:
        !            45: typedef
        !            46: struct pdc_softc {
        !            47:        struct device sc_dv;
        !            48:        struct tty *sc_tty;
        !            49:        struct timeout sc_to;
        !            50: } pdcsoftc_t;
        !            51:
        !            52: pdcio_t pdc;
        !            53: int pdcret[32] PDC_ALIGNMENT;
        !            54: char pdc_consbuf[IODC_MINIOSIZ] PDC_ALIGNMENT;
        !            55: iodcio_t pdc_cniodc, pdc_kbdiodc;
        !            56: pz_device_t *pz_kbd, *pz_cons;
        !            57:
        !            58: int pdcngetc(dev_t);
        !            59: void pdcnputc(dev_t, char *);
        !            60:
        !            61: struct consdev pdccons = { NULL, NULL, pdccngetc, pdccnputc,
        !            62:      nullcnpollc, NULL, makedev(22, 0), CN_NORMAL };
        !            63:
        !            64: int pdcmatch(struct device *, void *, void *);
        !            65: void pdcattach(struct device *, struct device *, void *);
        !            66:
        !            67: struct cfattach pdc_ca = {
        !            68:        sizeof(pdcsoftc_t), pdcmatch, pdcattach
        !            69: };
        !            70:
        !            71: struct cfdriver pdc_cd = {
        !            72:        NULL, "pdc", DV_DULL
        !            73: };
        !            74:
        !            75: void pdcstart(struct tty *tp);
        !            76: void pdctimeout(void *v);
        !            77: int pdcparam(struct tty *tp, struct termios *);
        !            78: int pdccnlookc(dev_t dev, int *cp);
        !            79:
        !            80: #if NCOM_GSC > 0
        !            81: /* serial console speed table */
        !            82: static int pdc_speeds[] = {
        !            83:        B50,
        !            84:        B75,
        !            85:        B110,
        !            86:        B150,
        !            87:        B300,
        !            88:        B600,
        !            89:        B1200,
        !            90:        B2400,
        !            91:        B4800,
        !            92:        B7200,
        !            93:        B9600,
        !            94:        B19200,
        !            95:        B38400,
        !            96:        B57600,
        !            97:        B115200,
        !            98:        B230400,
        !            99: };
        !           100: #endif
        !           101:
        !           102: void
        !           103: pdc_init()
        !           104: {
        !           105:        static int kbd_iodc[IODC_MAXSIZE/sizeof(int)];
        !           106:        static int cn_iodc[IODC_MAXSIZE/sizeof(int)];
        !           107:        int err;
        !           108:
        !           109:        /* XXX locore've done it XXX pdc = (pdcio_t)PAGE0->mem_pdc; */
        !           110:        pz_kbd = &PAGE0->mem_kbd;
        !           111:        pz_cons = &PAGE0->mem_cons;
        !           112:
        !           113:        /* XXX should we reset the console/kbd here?
        !           114:           well, /boot did that for us anyway */
        !           115:        if ((err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_READ,
        !           116:              pdcret, pz_cons->pz_hpa, IODC_IO, cn_iodc, IODC_MAXSIZE)) < 0 ||
        !           117:            (err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_READ,
        !           118:              pdcret, pz_kbd->pz_hpa, IODC_IO, kbd_iodc, IODC_MAXSIZE)) < 0) {
        !           119: #ifdef DEBUG
        !           120:                printf("pdc_init: failed reading IODC (%d)\n", err);
        !           121: #endif
        !           122:        }
        !           123:
        !           124:        pdc_cniodc = (iodcio_t)cn_iodc;
        !           125:        pdc_kbdiodc = (iodcio_t)kbd_iodc;
        !           126:
        !           127:        /* Start out with pdc as the console. */
        !           128:        cn_tab = &pdccons;
        !           129:
        !           130:        /* Figure out console settings. */
        !           131: #if NCOM_GSC > 0
        !           132:        if (PAGE0->mem_cons.pz_class == PCL_DUPLEX) {
        !           133:                struct pz_device *pzd = &PAGE0->mem_cons;
        !           134:                extern int comdefaultrate;
        !           135: #ifdef DEBUG
        !           136:                printf("console: class %d flags %b ",
        !           137:                    pzd->pz_class, pzd->pz_flags, PZF_BITS);
        !           138:                printf("bc %d/%d/%d/%d/%d/%d ",
        !           139:                    pzd->pz_bc[0], pzd->pz_bc[1], pzd->pz_bc[2],
        !           140:                    pzd->pz_bc[3], pzd->pz_bc[4], pzd->pz_bc[5]);
        !           141:                printf("mod %x layers %x/%x/%x/%x/%x/%x hpa %x\n", pzd->pz_mod,
        !           142:                    pzd->pz_layers[0], pzd->pz_layers[1], pzd->pz_layers[2],
        !           143:                    pzd->pz_layers[3], pzd->pz_layers[4], pzd->pz_layers[5],
        !           144:                    pzd->pz_hpa);
        !           145:
        !           146: #endif
        !           147:
        !           148:                /* compute correct baud rate */
        !           149:                if (PZL_SPEED(pzd->pz_layers[0]) <
        !           150:                    sizeof(pdc_speeds) / sizeof(int))
        !           151:                        comdefaultrate =
        !           152:                            pdc_speeds[PZL_SPEED(pzd->pz_layers[0])];
        !           153:                else
        !           154:                        comdefaultrate = B9600; /* XXX */
        !           155:        }
        !           156: #endif
        !           157: }
        !           158:
        !           159: int
        !           160: pdcmatch(parent, cfdata, aux)
        !           161:        struct device *parent;
        !           162:        void *cfdata;
        !           163:        void *aux;
        !           164: {
        !           165:        struct cfdata *cf = cfdata;
        !           166:        struct confargs *ca = aux;
        !           167:
        !           168:        /* there could be only one */
        !           169:        if (cf->cf_unit > 0 && !strcmp(ca->ca_name, "pdc"))
        !           170:                return 0;
        !           171:
        !           172:        return 1;
        !           173: }
        !           174:
        !           175: void
        !           176: pdcattach(parent, self, aux)
        !           177:        struct device *parent;
        !           178:        struct device *self;
        !           179:        void *aux;
        !           180: {
        !           181:        struct pdc_softc *sc = (struct pdc_softc *)self;
        !           182:
        !           183:        if (!pdc)
        !           184:                pdc_init();
        !           185:
        !           186:        printf("\n");
        !           187:
        !           188:        timeout_set(&sc->sc_to, pdctimeout, sc);
        !           189: }
        !           190:
        !           191: int
        !           192: pdcopen(dev, flag, mode, p)
        !           193:        dev_t dev;
        !           194:        int flag, mode;
        !           195:        struct proc *p;
        !           196: {
        !           197:        int unit = minor(dev);
        !           198:        struct pdc_softc *sc;
        !           199:        struct tty *tp;
        !           200:        int s;
        !           201:        int error = 0, setuptimeout = 0;
        !           202:
        !           203:        if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
        !           204:                return ENXIO;
        !           205:
        !           206:        s = spltty();
        !           207:
        !           208:        if (sc->sc_tty)
        !           209:                tp = sc->sc_tty;
        !           210:        else {
        !           211:                tp = sc->sc_tty = ttymalloc();
        !           212:        }
        !           213:
        !           214:        tp->t_oproc = pdcstart;
        !           215:        tp->t_param = pdcparam;
        !           216:        tp->t_dev = dev;
        !           217:        if ((tp->t_state & TS_ISOPEN) == 0) {
        !           218:                ttychars(tp);
        !           219:                tp->t_iflag = TTYDEF_IFLAG;
        !           220:                tp->t_oflag = TTYDEF_OFLAG;
        !           221:                tp->t_cflag = TTYDEF_CFLAG|CLOCAL;
        !           222:                tp->t_lflag = TTYDEF_LFLAG;
        !           223:                tp->t_ispeed = tp->t_ospeed = B9600;
        !           224:                ttsetwater(tp);
        !           225:
        !           226:                setuptimeout = 1;
        !           227:        } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) {
        !           228:                splx(s);
        !           229:                return (EBUSY);
        !           230:        }
        !           231:        tp->t_state |= TS_CARR_ON;
        !           232:        splx(s);
        !           233:
        !           234:        error = (*linesw[tp->t_line].l_open)(dev, tp);
        !           235:        if (error == 0 && setuptimeout)
        !           236:                pdctimeout(sc);
        !           237:
        !           238:        return error;
        !           239: }
        !           240:
        !           241: int
        !           242: pdcclose(dev, flag, mode, p)
        !           243:        dev_t dev;
        !           244:        int flag, mode;
        !           245:        struct proc *p;
        !           246: {
        !           247:        int unit = minor(dev);
        !           248:        struct tty *tp;
        !           249:        struct pdc_softc *sc;
        !           250:
        !           251:        if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
        !           252:                return ENXIO;
        !           253:
        !           254:        tp = sc->sc_tty;
        !           255:        timeout_del(&sc->sc_to);
        !           256:        (*linesw[tp->t_line].l_close)(tp, flag);
        !           257:        ttyclose(tp);
        !           258:        return 0;
        !           259: }
        !           260:
        !           261: int
        !           262: pdcread(dev, uio, flag)
        !           263:        dev_t dev;
        !           264:        struct uio *uio;
        !           265:        int flag;
        !           266: {
        !           267:        int unit = minor(dev);
        !           268:        struct tty *tp;
        !           269:        struct pdc_softc *sc;
        !           270:
        !           271:        if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
        !           272:                return ENXIO;
        !           273:
        !           274:        tp = sc->sc_tty;
        !           275:        return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
        !           276: }
        !           277:
        !           278: int
        !           279: pdcwrite(dev, uio, flag)
        !           280:        dev_t dev;
        !           281:        struct uio *uio;
        !           282:        int flag;
        !           283: {
        !           284:        int unit = minor(dev);
        !           285:        struct tty *tp;
        !           286:        struct pdc_softc *sc;
        !           287:
        !           288:        if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
        !           289:                return ENXIO;
        !           290:
        !           291:        tp = sc->sc_tty;
        !           292:        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
        !           293: }
        !           294:
        !           295: int
        !           296: pdcioctl(dev, cmd, data, flag, p)
        !           297:        dev_t dev;
        !           298:        u_long cmd;
        !           299:        caddr_t data;
        !           300:        int flag;
        !           301:        struct proc *p;
        !           302: {
        !           303:        int unit = minor(dev);
        !           304:        int error;
        !           305:        struct tty *tp;
        !           306:        struct pdc_softc *sc;
        !           307:
        !           308:        if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
        !           309:                return ENXIO;
        !           310:
        !           311:        tp = sc->sc_tty;
        !           312:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
        !           313:        if (error >= 0)
        !           314:                return error;
        !           315:        error = ttioctl(tp, cmd, data, flag, p);
        !           316:        if (error >= 0)
        !           317:                return error;
        !           318:
        !           319:        return ENOTTY;
        !           320: }
        !           321:
        !           322: int
        !           323: pdcparam(tp, t)
        !           324:        struct tty *tp;
        !           325:        struct termios *t;
        !           326: {
        !           327:
        !           328:        return 0;
        !           329: }
        !           330:
        !           331: void
        !           332: pdcstart(tp)
        !           333:        struct tty *tp;
        !           334: {
        !           335:        int s;
        !           336:
        !           337:        s = spltty();
        !           338:        if (tp->t_state & (TS_TTSTOP | TS_BUSY)) {
        !           339:                splx(s);
        !           340:                return;
        !           341:        }
        !           342:        if (tp->t_outq.c_cc <= tp->t_lowat) {
        !           343:                if (tp->t_state & TS_ASLEEP) {
        !           344:                        tp->t_state &= ~TS_ASLEEP;
        !           345:                        wakeup((caddr_t)&tp->t_outq);
        !           346:                }
        !           347:                selwakeup(&tp->t_wsel);
        !           348:        }
        !           349:        tp->t_state |= TS_BUSY;
        !           350:        while (tp->t_outq.c_cc != 0)
        !           351:                pdccnputc(tp->t_dev, getc(&tp->t_outq));
        !           352:        tp->t_state &= ~TS_BUSY;
        !           353:        splx(s);
        !           354: }
        !           355:
        !           356: int
        !           357: pdcstop(tp, flag)
        !           358:        struct tty *tp;
        !           359:        int flag;
        !           360: {
        !           361:        int s;
        !           362:
        !           363:        s = spltty();
        !           364:        if (tp->t_state & TS_BUSY)
        !           365:                if ((tp->t_state & TS_TTSTOP) == 0)
        !           366:                        tp->t_state |= TS_FLUSH;
        !           367:        splx(s);
        !           368:        return 0;
        !           369: }
        !           370:
        !           371: void
        !           372: pdctimeout(v)
        !           373:        void *v;
        !           374: {
        !           375:        struct pdc_softc *sc = v;
        !           376:        struct tty *tp = sc->sc_tty;
        !           377:        int c;
        !           378:
        !           379:        while (pdccnlookc(tp->t_dev, &c)) {
        !           380:                if (tp->t_state & TS_ISOPEN)
        !           381:                        (*linesw[tp->t_line].l_rint)(c, tp);
        !           382:        }
        !           383:        timeout_add(&sc->sc_to, 1);
        !           384: }
        !           385:
        !           386: struct tty *
        !           387: pdctty(dev)
        !           388:        dev_t dev;
        !           389: {
        !           390:        int unit = minor(dev);
        !           391:        struct pdc_softc *sc;
        !           392:
        !           393:        if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
        !           394:                return NULL;
        !           395:
        !           396:        return sc->sc_tty;
        !           397: }
        !           398:
        !           399: int
        !           400: pdccnlookc(dev, cp)
        !           401:        dev_t dev;
        !           402:        int *cp;
        !           403: {
        !           404:        int err, l;
        !           405:        int s = splhigh();
        !           406:
        !           407:        err = pdc_call(pdc_kbdiodc, 0, pz_kbd->pz_hpa, IODC_IO_CONSIN,
        !           408:            pz_kbd->pz_spa, pz_kbd->pz_layers, pdcret, 0, pdc_consbuf, 1, 0);
        !           409:
        !           410:        l = pdcret[0];
        !           411:        *cp = pdc_consbuf[0];
        !           412:        splx(s);
        !           413: #ifdef DEBUG
        !           414:        if (err < 0)
        !           415:                printf("pdccnlookc: input error: %d\n", err);
        !           416: #endif
        !           417:
        !           418:        return l;
        !           419: }
        !           420:
        !           421: int
        !           422: pdccngetc(dev)
        !           423:        dev_t dev;
        !           424: {
        !           425:        int c;
        !           426:
        !           427:        if (!pdc)
        !           428:                return 0;
        !           429:
        !           430:        while(!pdccnlookc(dev, &c))
        !           431:                ;
        !           432:
        !           433:        return (c);
        !           434: }
        !           435:
        !           436: void
        !           437: pdccnputc(dev, c)
        !           438:        dev_t dev;
        !           439:        int c;
        !           440: {
        !           441:        register int err;
        !           442:        int s = splhigh();
        !           443:
        !           444:        *pdc_consbuf = c;
        !           445:        err = pdc_call(pdc_cniodc, 0, pz_cons->pz_hpa, IODC_IO_CONSOUT,
        !           446:            pz_cons->pz_spa, pz_cons->pz_layers, pdcret, 0, pdc_consbuf, 1, 0);
        !           447:        splx(s);
        !           448:
        !           449:        if (err < 0) {
        !           450: #ifdef DEBUG
        !           451:                printf("pdccnputc: output error: %d\n", err);
        !           452: #endif
        !           453:        }
        !           454: }

CVSweb