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

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

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

CVSweb