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