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