1: /*
   2:  * Copyright (c) 1982, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)lpa.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "lpa.h"
  10: #if NLPA > 0
  11: 
  12: #include "param.h"
  13: #include "dir.h"
  14: #include "user.h"
  15: #include "buf.h"
  16: #include "proc.h"
  17: #include "ioctl.h"
  18: #include "uio.h"
  19: 
  20: #include "ubavar.h"
  21: 
  22: /*
  23:  * LPA driver for -- Asa Romberger
  24:  *
  25:  *	open
  26:  *	write microcode
  27:  *	write dedicated mode dispatch table
  28:  *	ioctl TIOCSETP to set parameters
  29:  *		struct iocb {
  30:  *			short *baddr;	buffer address
  31:  *			short rate;	- 1,000,000 / frequency in Hz
  32:  *			short wc;	15-13 = number of buffers - 1
  33:  *					12-0 = buffer size in words
  34:  *		} iocb;
  35:  *	read - 1 character indicating buffer index
  36:  *		fill or empty buffer
  37:  * minor device number = DDCCCCCC where:
  38:  *	DD	= 00 for analog input
  39:  *		= 01 for analog output
  40:  *	CCCCCC	= channel number
  41:  */
  42:  *  define NOMCODE to eliminate the microcode download check
  43:  */
  44: /* #define TRACELPA */
  45: /* #define NOMCODE */
  46: 
  47: #ifdef TRACELPA
  48: #	define TRACER(x)  printf(x)
  49: #	define TRACERN(x, d)  printf(x, d)
  50: #else
  51: #	define TRACER(x)
  52: #	define TRACERN(x, d)
  53: #endif
  54: 
  55:     /* PRIORITY AT WHICH PROGRAM SHOULD RUN */
  56:     /* THIS SHOULD EVENTUALLY  TELL UNIX THIS IS A REAL-TIME DEVICE */
  57: 
  58: #define NICE    0
  59: 
  60: #define inc(v)      (sc->v = ((sc->v + 1) % sc->sc_nbuf))
  61: 
  62: #define LPAPRI      (PZERO + 0)
  63: #define LPAUNIT(dev)    0
  64: #define LPADEVICE(dev)  (((dev) >> 6) & 03)
  65: #define LPACHANNEL(dev) ((dev) & 077)
  66: 
  67: int lpaprobe(), lpaattach(), lpaiintr(), lpaointr();
  68: u_short lpastd[] = {0170460, 0};
  69: struct  uba_device *lpadinfo[NLPA];
  70: struct uba_driver lpadriver =
  71:   {lpaprobe, 0, lpaattach, 0, lpastd, "lpa", lpadinfo, 0, 0, 0 };
  72: 
  73: struct lpa_softc {
  74:     int sc_flag;    /* flags, as defined below */
  75:     int sc_device;  /* device: 0 = analog in, 1 = analog out */
  76:     int sc_channel; /* device channel number */
  77:     struct buf sc_ubuffer;  /* user buffer header */
  78:     int sc_ubabuf;  /* uba allocation pointer for buffer */
  79:     int sc_ubufn;   /* present buffer that user is accessing */
  80:     int sc_lbufn;   /* present buffer that lpa is accessing */
  81:     int sc_lbufnx;  /* next buffer for lpa (value in ustat) */
  82:     int sc_nbuf;    /* number of buffers */
  83:     int sc_count;   /* buffer size in words */
  84:     short   sc_ustat;   /* user status word */
  85:     struct buf sc_ustatbuf; /* dummy user status word buffer for ubasetup */
  86:     int sc_ubaustat;    /* uba allocation pointer for ustat */
  87:     struct buf *sc_buffer;  /* scratch buffer header */
  88:     int sc_start;   /* 0 if lpa operation has been started */
  89: } lpa_softc[NLPA];
  90: 
  91: /* flags for sc_flag */
  92: #define OPEN    01      /* device is open */
  93: #define MCODE   02      /* microcode has been loaded */
  94: #define DMDT    04      /* dedicated mode dispatch table loaded */
  95: #define STTY    010     /* stty call and device initialized */
  96: #define SLEEP   020     /* sleeping */
  97: 
  98: /* bits for ustat */
  99: #define DONE    0100000     /* done */
 100: #define STOP    0040000     /* stop data transfer */
 101: #define NBI 0003400     /* next buffer index */
 102: #define LBI 0000003     /* last buffer index */
 103: 
 104: struct lpadevice {
 105:     short   lcim;       /* control in and maintenance */
 106:     short   lcos;       /* control and status out */
 107:     short   lrda;       /* request description array address word */
 108:     short   lms;        /* maintenance status */
 109: };
 110: 
 111: /* control in and maintenance register bits */
 112: #define READYI  0000200     /* ready in */
 113: #define IIE 0000100     /* in interrupt enable */
 114: #define RDAEXT  0000014     /* rda address extension */
 115: #define RDAEXTOFFSET    2   /* offset of RDAEXT from right side */
 116: #define GO  0000001     /* go */
 117: #define RUN 0100000     /* run */
 118: #define RESET   0040000     /* reset */
 119: #define CWRITE  0020000     /* cram write */
 120: #define EA  0004000     /* enable arbitration */
 121: #define ROMO    0002000     /* rom O */
 122: #define ROMI    0001000     /* rom I */
 123: #define SMICRO  0000400     /* step microprocessor */
 124: 
 125: /* control and status out register bits */
 126: #define READYO  0200        /* ready out */
 127: #define OIE 0100        /* out interrupt enable */
 128: #define UINDEX  0007        /* user index */
 129: #define ERROR   0100000     /* error */
 130: #define ESTAT   0060000     /* error status */
 131: #define ESCODE  0017400     /* error sub code */
 132: #define ECODE   0077400     /* error status + error sub code */
 133: #define OVERRUN 0243        /* overrun error */
 134: 
 135: /* LPA COMMAND DESCRIPTION AREA */
 136: 
 137: /* INIT COMMAND */
 138: #define INIT    0       /* mode */
 139: #define MCVERS  4       /* microcode version */
 140: #define ACLOCKA 0170404     /* LPA bus addresses */
 141: #define ACLOCKB 0170432
 142: #define AAD1    0170400
 143: #define AAD2    1       /* 0170440 - DOES NOT EXIST */
 144: #define ADA 0170420
 145: #define ADIO1   1       /* 0167770 - DOES NOT EXIST */
 146: #define ADIO2   1       /* 0167760 - DOES NOT EXIST */
 147: #define ADIO3   1       /* 0167750 - DOES NOT EXIST */
 148: #define ADIO4   1       /* 0167740 - DOES NOT EXIST */
 149: #define ADIO5   1       /* 0167730 - DOES NOT EXIST */
 150: 
 151: /* CLOCK START COMMAND */
 152: #define CLOCK   1       /* mode */
 153: #define CLOCKA  0<<4        /* clock A */
 154:     /* clock status word */
 155: #define ENACTR  1       /* enable counter */
 156: #define R1M 1<<1        /* 1 MHz rate */
 157: #define R100K   2<<1        /* 100 KHz rate */
 158: #define R10K    3<<1        /* 10 KHz rate */
 159: #define R1K 4<<1        /* 1 KHz rate */
 160: #define R100    5<<1        /* 100 Hz rate */
 161: #define REXT    6<<1        /* external rate (from st1 input) */
 162: #define R60 7<<1        /* line frequency rate */
 163: #define MFIE    0100        /* mode flag interrupt enable */
 164: #define MSI 0<<8        /* single interval mode */
 165: #define MRI 1<<8        /* repeat interval mode */
 166: #define MEET    2<<8        /* external event time mode */
 167: #define MEETZ   3<<8        /* external event time mode from zero base */
 168: #define ST1EC   020000      /* st1 enable counter */
 169: #define ST1IE   040000      /* st1 interrupt enable */
 170: 
 171: /* DATA TRANSFER START COMMAND */
 172: #define DTS 2       /* mode */
 173: #define SCHAN   1<<8        /* single channel */
 174: 
 175: lpaprobe(reg)
 176:     caddr_t reg;
 177: {
 178:     register int br, cvec;  /* value result */
 179:     register struct lpadevice *lpaaddr = (struct lpadevice *)reg;
 180: 
 181: #ifdef lint
 182:     br = 0; cvec = br; br = cvec;
 183: #endif
 184:     /* this should force an interrupt, stall, clear the lpa */
 185:     br = 0x15;
 186:     cvec = 0330;
 187: TRACER("PROBE\n");
 188:     return (sizeof (struct lpadevice));
 189: }
 190: 
 191: lpaattach(ui)
 192:     register struct upa_device *ui;
 193: {
 194: 
 195: }
 196: 
 197: lpaopen(dev, flag)
 198:     dev_t dev;
 199:     int flag;
 200: {
 201:     register int unit = LPAUNIT(dev);
 202:     register struct lpa_softc *sc = &lpa_softc[unit];
 203:     register struct uba_device *ui = lpadinfo[unit];
 204:     register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr;
 205: 
 206: TRACER("OPEN\n");
 207:     if (unit >= NLPA || sc->sc_flag & OPEN || ui == 0 ||
 208:         ui->ui_alive == 0)
 209:         return (ENXIO);
 210:     (void) splhigh();
 211:     lpaaddr->lcim = RESET;
 212:     lpaaddr->lcim = 0;
 213:     (void) spl0();
 214:     lpaaddr->lcos = 0;  /* clear the registers as a precaution */
 215:     lpaaddr->lrda = 0;
 216:     lpaaddr->lms = 0;
 217:     sc->sc_flag = OPEN;
 218:     sc->sc_device = LPADEVICE(dev);
 219:     sc->sc_channel = LPACHANNEL(dev);
 220:     sc->sc_buffer = geteblk();
 221:     sc->sc_buffer->b_error = 0;
 222:     sc->sc_buffer->b_proc = u.u_procp;
 223:     sc->sc_ubufn = -1;
 224:     /* THIS SHOULD EVENTUALLY SPECIFY "REAL-TIME" */
 225:     u.u_procp->p_nice = NICE;
 226:     return (0);
 227: }
 228: 
 229: lpaclose(dev, flag)
 230:     dev_t dev;
 231:     int flag;
 232: {
 233:     register int unit = LPAUNIT(dev);
 234:     register struct lpa_softc *sc = &lpa_softc[unit];
 235:     register struct uba_device *ui = lpadinfo[unit];
 236:     register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr;
 237: 
 238:     if (sc->sc_device && sc->sc_ubufn >= 0 && (sc->sc_flag & ERROR) == 0) {
 239:         if (sc->sc_start)
 240:             lpacmd(sc->sc_buffer, lpaaddr, sc, ui->ui_ubanum);
 241:         sc->sc_flag |= STOP;
 242:         (void) spl5();
 243:         while (sc->sc_flag & STOP) {
 244: TRACER("SLEEP\n");
 245:             sc->sc_flag |= SLEEP;
 246:             sleep((caddr_t)sc, LPAPRI);
 247:         }
 248:     }
 249:     (void) splhigh();
 250:     lpaaddr->lcim = RESET;
 251:     lpaaddr->lcim = 0;
 252:     (void) spl0();
 253:     if (sc->sc_ubabuf) {
 254:         ubarelse(ui->ui_ubanum, &sc->sc_ubabuf);
 255:         sc->sc_ubabuf = 0;
 256:         (void) splclock();
 257:         vsunlock(sc->sc_ubuffer.b_un.b_addr, sc->sc_ubuffer.b_bcount,
 258:             (sc->sc_device)? B_READ : B_WRITE);
 259:         u.u_procp->p_flag &= ~SPHYSIO;
 260:         (void) spl0();
 261:     }
 262:     if (sc->sc_ubaustat) {
 263:         ubarelse(ui->ui_ubanum, &sc->sc_ubaustat);
 264:         sc->sc_ubaustat = 0;
 265:     }
 266:     if (sc->sc_buffer) {
 267:         brelse(sc->sc_buffer);
 268:         sc->sc_buffer = 0;
 269:     }
 270:     sc->sc_flag = 0;
 271: TRACER("CLOSE\n");
 272: }
 273: 
 274: lpawrite(dev, uio)
 275:     dev_t dev;
 276:     struct uio *uio;
 277: {
 278:     register int unit = LPAUNIT(dev);
 279:     register struct lpa_softc *sc = &lpa_softc[unit];
 280:     register struct uba_device *ui = lpadinfo[unit];
 281:     register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr;
 282:     register int f;
 283: 
 284: TRACER("WRITE\n");
 285:     f = sc->sc_flag;
 286:     if ((f & OPEN) == 0)
 287:         return (ENXIO);
 288:     if ((f & MCODE) == 0)       /* first write is the microcode */
 289:         return (lpamcode(lpaaddr, sc, uio));
 290:     if ((f & DMDT) == 0)        /* second write is the dispatch table */
 291:         return (lpadmdt(lpaaddr, sc, ui->ui_ubanum, uio));
 292:     return (ENXIO);
 293: }
 294: 
 295: lpamcode(lpaaddr, sc, uio)
 296:     register struct lpadevice *lpaaddr;
 297:     register struct lpa_softc *sc;
 298:     struct uio *uio;
 299: {
 300:     short v, r;
 301:     register int mcaddr;
 302:     int error;
 303: 
 304:     mcaddr = 0;
 305:     while (uio->uio_resid) {
 306:         error = uiomove(&v, 2, UIO_WRITE, uio);
 307:         if (error)
 308:             break;
 309:         lpaaddr->lcim = 0;      /* load microcode word */
 310:         lpaaddr->lrda = mcaddr;
 311:         lpaaddr->lms = v;
 312:         lpaaddr->lcim = ROMO;
 313:         lpaaddr->lcim |= CWRITE;
 314:         lpaaddr->lcim = 0;      /* verify microcode word */
 315:         lpaaddr->lrda = mcaddr;
 316:         lpaaddr->lcim = ROMO;
 317:         if ((r = lpaaddr->lms) != v) {
 318:             /* download failure */
 319:             printf("LPA MICROCODE FAIL: exp:%o got:%o\n", v, r);
 320:             return (ENXIO);
 321:         }
 322:         mcaddr++;
 323:     }
 324:     lpaaddr->lcim = RUN | EA;   /* turn it on */
 325:     sc->sc_flag |= MCODE;
 326:     lpaaddr->lcim |= IIE;
 327:     lpaaddr->lcos |= OIE;
 328:     return (error);
 329: TRACER("MCODE\n");
 330: }
 331: 
 332: lpadmdt(lpaaddr, sc, ubanum, uio)
 333:     register struct lpadevice *lpaaddr;
 334:     register struct lpa_softc *sc;
 335:     register short ubanum;
 336:     struct uio *uio;
 337: {
 338:     register short *p;
 339:     register int n;
 340:     int error;
 341: 
 342:     p = (short *) sc->sc_buffer->b_un.b_addr;       /* INIT */
 343:     *p++ = (MCVERS << 8) | INIT;    /* mode */
 344:     *p++ = ACLOCKA;     /* LPA bus device addresses */
 345:     *p++ = ACLOCKB;
 346:     *p++ = AAD1;
 347:     *p++ = AAD2;
 348:     *p++ = ADA;
 349:     *p++ = ADIO1;
 350:     *p++ = ADIO2;
 351:     *p++ = ADIO3;
 352:     *p++ = ADIO4;
 353:     *p++ = ADIO5;
 354:     n = MIN(uio->uio_resid, 256);   /* dedicated mode dispatch table */
 355:     error = uiomove((char *)p, n, UIO_WRITE, uio);
 356:     if (error)
 357:         return (error);
 358:     n >>= 1;
 359:     p += n;
 360:     while (n++ < 128)
 361:         *p++ = 0;
 362:     lpacmd(sc->sc_buffer, lpaaddr, sc, ubanum);
 363:     sc->sc_flag |= DMDT;
 364:     return (0);
 365: TRACER("DMDT\n");
 366: }
 367: 
 368: lpaioctl(dev, cmd, data, flag)
 369:     dev_t dev;
 370:     caddr_t data;
 371: {
 372:     register int unit = LPAUNIT(dev);
 373:     register struct lpa_softc *sc = &lpa_softc[unit];
 374:     register struct uba_device *ui = lpadinfo[unit];
 375:     register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr;
 376:     register short *p;
 377:     register int i;
 378:     register int v;
 379:     struct iocb {
 380:         short *baddr;
 381:         short rate;
 382:         short wc;
 383:     } *iocb;
 384: 
 385: TRACER("IOCTL IN\n");
 386:     if (cmd != TIOCSETP || (sc->sc_flag & DMDT) == 0)
 387:         return (ENXIO);
 388:     iocb = (struct iocb *)data;
 389:     p = (short *) sc->sc_buffer->b_un.b_addr;   /* CLOCK START */
 390:     *p++ = CLOCK | CLOCKA;          /* mode */
 391:     *p++ = ENACTR | R1M | MFIE | MRI;   /* clock status */
 392:     *p = iocb->rate;            /* clock preset */
 393:     lpacmd(sc->sc_buffer, lpaaddr, sc, ui->ui_ubanum);
 394: TRACER("CLOCK STARTED\n");
 395:     p = (short *) sc->sc_buffer->b_un.b_addr;   /* DATA TRANSFER START*/
 396:     *p++ = (sc->sc_device << 7) | DTS | SCHAN;  /* mode */
 397:     sc->sc_count = iocb->wc & 017777;   /* word count per buffer */
 398:     *p++ = sc->sc_count;
 399:                             /* user status word */
 400:     sc->sc_ustatbuf.b_un.b_addr = (caddr_t) &sc->sc_ustat;
 401:     sc->sc_ustatbuf.b_flags = 0;
 402:     sc->sc_ustatbuf.b_bcount = 2;
 403:     sc->sc_ustatbuf.b_proc = u.u_procp;
 404:     sc->sc_ubaustat = ubasetup(ui->ui_ubanum, &sc->sc_ustatbuf, 0);
 405:     v = sc->sc_ubaustat;
 406:     *p++ = v;
 407:     *p = (v >> 16) & 03;        /* into low portion of word */
 408:     sc->sc_nbuf = (iocb->wc >> 13) & 07;    /* number of buffers */
 409:     *p++ |= sc->sc_nbuf++ << 8;     /* into high portion of word */
 410:                     /* buffer addresses */
 411:     if (useracc(sc->sc_ubuffer.b_un.b_addr = (caddr_t) iocb->baddr,
 412:         sc->sc_ubuffer.b_bcount = sc->sc_count * sc->sc_nbuf * 2,
 413:         (i = (sc->sc_device)? B_READ : B_WRITE) ) == NULL) {
 414: TRACER("USER BUFFER FAULT\n");
 415:         return (EFAULT);
 416:     }
 417:     sc->sc_ubuffer.b_flags = B_PHYS | B_BUSY | i;
 418:     sc->sc_ubuffer.b_proc = u.u_procp;
 419:     u.u_procp->p_flag |= SPHYSIO;
 420:     vslock(sc->sc_ubuffer.b_un.b_addr, sc->sc_ubuffer.b_bcount);
 421:     sc->sc_ubabuf = ubasetup(ui->ui_ubanum, &sc->sc_ubuffer, 0);
 422:     v = sc->sc_ubabuf;
 423:     for (i = 0; i < sc->sc_nbuf; i++) {
 424:         *p++ = v;
 425:         *p++ = (v >> 16) & 03;
 426:         v += sc->sc_count * 2;
 427:     }
 428:     for ( ; i <= 7; i++) {
 429:         *p++ = 0;
 430:         *p++ = 0;
 431:     }
 432:     *p++ = 0; *p++ = 0;     /* random channel list address */
 433:     *p++ = 0;           /* delay */
 434:     *p++ = sc->sc_channel;      /* start channel, channel inc */
 435:     *p++ = 1;           /* number of samples in a sequence */
 436:     *p++ = 0;           /* dwell */
 437:     *p++ = 0;           /* start word no., event mark word */
 438:     *p++ = 0;           /* start word mask */
 439:     *p = 0;             /* event mark mask */
 440:     sc->sc_ustat = 0;
 441:     sc->sc_start = (sc->sc_device)? sc->sc_nbuf+1 : 1;
 442:     sc->sc_lbufn = 0;
 443:     sc->sc_lbufnx = 0;
 444:     sc->sc_flag |= STTY;
 445: TRACER("IOCTL OUT\n");
 446:     return (0);
 447: }
 448: 
 449: lparead(dev, uio)
 450:     dev_t dev;
 451:     struct uio *uio;
 452: {
 453:     register int unit = LPAUNIT(dev);
 454:     register struct lpa_softc *sc = &lpa_softc[unit];
 455:     register struct uba_device *ui = lpadinfo[unit];
 456:     register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr;
 457: 
 458: TRACER("READ\n");
 459:     if ((sc->sc_flag & STTY) == 0)
 460:         return (ENXIO);
 461:     if (sc->sc_flag & ERROR)
 462:         return (ENXIO);
 463:     if (sc->sc_start)
 464:         if (--sc->sc_start == 0) {
 465:             lpacmd(sc->sc_buffer, lpaaddr, sc, ui->ui_ubanum);
 466: TRACER("START\n");
 467:         }
 468:     inc(sc_ubufn);
 469:     if (sc->sc_start == 0) {
 470:         (void) spl5();
 471:         while (sc->sc_ubufn == sc->sc_lbufn) {
 472:             if (sc->sc_flag & ERROR)
 473:                 return (ENXIO);
 474: TRACER("SLEEP\n");
 475:             sc->sc_flag |= SLEEP;
 476:             sleep(sc, LPAPRI);
 477:         }
 478:         (void) spl0();
 479:     }
 480: TRACERN("READ %d\n", sc->sc_ubufn);
 481:     return (uiomove(&sc->sc_ubufn, 1, UIO_READ, uio));
 482: }
 483: 
 484: lpacmd(bp, lpaaddr, sc, ubanum)
 485:     register struct buf *bp;
 486:     register struct lpadevice *lpaaddr;
 487:     register struct lpa_softc *sc;
 488:     register short ubanum;
 489: {
 490:     int ubareg;
 491: 
 492: TRACER("CMD\n");
 493:     ubareg = ubasetup(ubanum, bp, UBA_NEEDBDP);
 494:     lpawait(lpaaddr, sc);
 495:     lpaaddr->lrda = ubareg;
 496:     lpaaddr->lcim &= ~RDAEXT;
 497:     lpaaddr->lcim |= ((ubareg >> (16-RDAEXTOFFSET)) & RDAEXT) | GO;
 498:     lpawait(lpaaddr, sc);
 499:     ubarelse(ubanum, &ubareg);
 500: }
 501: 
 502: lpawait(lpaaddr, sc)
 503:     register struct lpadevice *lpaaddr;
 504:     register struct lpa_softc *sc;
 505: {
 506: 
 507:     (void) spl5();
 508:     while ((lpaaddr->lcim & READYI) == 0) {
 509: TRACER("SLEEP\n");
 510:         sc->sc_flag |= SLEEP;
 511:         sleep((caddr_t)sc, LPAPRI);
 512:     }
 513:     (void) spl0();
 514: }
 515: 
 516: lpaiintr(unit)
 517:     int unit;
 518: {
 519:     register struct lpa_softc *sc = &lpa_softc[unit];
 520: 
 521: TRACER("{I");
 522:     if (sc->sc_flag & SLEEP) {
 523: TRACER("<WAKEUP>");
 524:         wakeup((caddr_t)sc);
 525:         sc->sc_flag &= ~SLEEP;
 526:     }
 527: TRACER("}");
 528: }
 529: 
 530: lpaointr(unit)
 531:     int unit;
 532: {
 533:     register int c, m;
 534:     register struct lpa_softc *sc = &lpa_softc[unit];
 535:     register struct uba_device *ui = lpadinfo[unit];
 536:     register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr;
 537:     int spx;
 538: 
 539: TRACER("{O");
 540:     if (sc->sc_flag & SLEEP) {
 541: TRACER("<WAKEUP>");
 542:         wakeup(sc);
 543:         sc->sc_flag &= ~SLEEP;
 544:     }
 545:     c = lpaaddr->lcos;
 546:     m = lpaaddr->lms;
 547:     lpaaddr->lcos &= ~READYO;
 548:     if (c & ERROR) {
 549: TRACER("<ERROR>");
 550:         c = (c >> 8) & 0377;
 551:         if ((sc->sc_flag & STOP) == 0 || (c != OVERRUN)) {
 552:             printf("LPA ERROR %o %o\n", c, m&0177777);
 553:             sc->sc_flag |= ERROR;
 554:         }
 555:         sc->sc_flag &= ~STOP;
 556: TRACER("}\n");
 557:         return;
 558:     }
 559: TRACERN("<LPA %d>", sc->sc_lbufnx);
 560:     sc->sc_lbufn = sc->sc_lbufnx;
 561:     if (sc->sc_ubufn == sc->sc_lbufnx && c & ECODE) {
 562: TRACER("<STOP?>");
 563:         if (sc->sc_flag & STOP)
 564:             return;
 565:         printf("LPA OVERRUN\n");
 566:         sc->sc_flag |= ERROR;
 567:     }
 568:     inc(sc_lbufnx);
 569: TRACERN("<USTAT %o>", sc->sc_ustat);
 570:     spx = splhigh();
 571:     sc->sc_ustat &= ~NBI;
 572:     sc->sc_ustat |= sc->sc_lbufnx << 8;
 573:     sc->sc_ustat &= ~DONE;
 574:     splx(spx);
 575: TRACERN("<LPAN %d>}", sc->sc_lbufnx);
 576: }
 577: 
 578: lpareset(uban)
 579:     int uban;
 580: {
 581:     register struct uba_device *ui;
 582:     register struct lpadevice *lpaaddr;
 583:     register struct lpa_softc *sc;
 584:     register int unit;
 585: 
 586: TRACER("LPA RESET\n");
 587:     for (unit = 0; unit < NLPA; unit++) {
 588:         if ((ui = lpadinfo[unit]) == 0 ||
 589:             ui->ui_ubanum != uban || ui->ui_alive == 0)
 590:             continue;
 591:         printf(" lpa%d", unit);
 592:         lpaaddr = (struct lpadevice *)ui->ui_addr;
 593:         sc = &lpa_softc[unit];
 594:         sc->sc_flag |= ERROR;
 595:         (void) splhigh();
 596:         lpaaddr->lcim = RESET;
 597:         lpaaddr->lcim = 0;
 598:         (void) spl0();
 599:         if (sc->sc_flag & SLEEP) {
 600:             wakeup((caddr_t)sc);
 601:             sc->sc_flag &= ~SLEEP;
 602:         }
 603:     }
 604: }
 605: #endif NLPA

Defined functions

lpaattach defined in line 191; used 2 times
lpaclose defined in line 229; never used
lpacmd defined in line 484; used 4 times
lpadmdt defined in line 332; used 1 times
lpaiintr defined in line 516; used 1 times
  • in line 67
lpaioctl defined in line 368; never used
lpamcode defined in line 295; used 1 times
lpaointr defined in line 530; used 1 times
  • in line 67
lpaopen defined in line 197; never used
lpaprobe defined in line 175; used 2 times
lparead defined in line 449; never used
lpareset defined in line 578; never used
lpawait defined in line 502; used 2 times
lpawrite defined in line 274; never used

Defined variables

lpa_softc defined in line 89; used 8 times
lpadinfo defined in line 69; used 8 times
lpadriver defined in line 70; never used
lpastd defined in line 68; used 1 times
  • in line 71

Defined struct's

iocb defined in line 379; used 2 times
  • in line 388(2)
lpa_softc defined in line 73; used 24 times
lpadevice defined in line 104; used 42 times

Defined macros

AAD1 defined in line 142; used 1 times
AAD2 defined in line 143; used 1 times
ACLOCKA defined in line 140; used 1 times
ACLOCKB defined in line 141; used 1 times
ADA defined in line 144; used 1 times
ADIO1 defined in line 145; used 1 times
ADIO2 defined in line 146; used 1 times
ADIO3 defined in line 147; used 1 times
ADIO4 defined in line 148; used 1 times
ADIO5 defined in line 149; used 1 times
CLOCK defined in line 152; used 1 times
CLOCKA defined in line 153; used 1 times
CWRITE defined in line 119; used 1 times
DMDT defined in line 94; used 3 times
DONE defined in line 99; used 1 times
DTS defined in line 172; used 1 times
EA defined in line 120; used 1 times
ECODE defined in line 132; used 1 times
ENACTR defined in line 155; used 1 times
ERROR defined in line 129; used 7 times
ESCODE defined in line 131; never used
ESTAT defined in line 130; never used
GO defined in line 116; used 1 times
IIE defined in line 113; used 1 times
INIT defined in line 138; used 1 times
LBI defined in line 102; never used
LPACHANNEL defined in line 65; used 1 times
LPADEVICE defined in line 64; used 1 times
LPAPRI defined in line 62; used 3 times
LPAUNIT defined in line 63; used 5 times
MCODE defined in line 93; used 2 times
MCVERS defined in line 139; used 1 times
MEET defined in line 166; never used
MEETZ defined in line 167; never used
MFIE defined in line 163; used 1 times
MRI defined in line 165; used 1 times
MSI defined in line 164; never used
NBI defined in line 101; used 1 times
NICE defined in line 58; used 1 times
OIE defined in line 127; used 1 times
OPEN defined in line 92; used 3 times
OVERRUN defined in line 133; used 1 times
R100 defined in line 160; never used
R100K defined in line 157; never used
R10K defined in line 158; never used
R1K defined in line 159; never used
R1M defined in line 156; used 1 times
R60 defined in line 162; never used
RDAEXT defined in line 114; used 2 times
RDAEXTOFFSET defined in line 115; used 1 times
READYI defined in line 112; used 1 times
READYO defined in line 126; used 1 times
RESET defined in line 118; used 3 times
REXT defined in line 161; never used
ROMI defined in line 122; never used
ROMO defined in line 121; used 2 times
RUN defined in line 117; used 1 times
SCHAN defined in line 173; used 1 times
SLEEP defined in line 96; used 9 times
SMICRO defined in line 123; never used
ST1EC defined in line 168; never used
ST1IE defined in line 169; never used
STOP defined in line 100; used 5 times
STTY defined in line 95; used 2 times
TRACER defined in line 51; used 25 times
TRACERN defined in line 52; used 4 times
UINDEX defined in line 128; never used
inc defined in line 60; used 2 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2951
Valid CSS Valid XHTML 1.0 Strict