[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

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