[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

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