|
|
1.1 ! root 1: /* mx2.c 4.7 81/09/11 */ ! 2: ! 3: #include "../h/param.h" ! 4: #include "../h/systm.h" ! 5: #include "../h/dir.h" ! 6: #include "../h/user.h" ! 7: #include "../h/proc.h" ! 8: #include "../h/tty.h" ! 9: #include "../h/inode.h" ! 10: #include "../h/mx.h" ! 11: #include "../h/file.h" ! 12: #include "../h/conf.h" ! 13: #include "../h/buf.h" ! 14: /* ! 15: * multiplexor driver ! 16: */ ! 17: struct chan chans[NCHANS]; ! 18: struct group *groups[NGROUPS]; ! 19: int mpxline; ! 20: ! 21: short cmask[16] ={ ! 22: 01, 02, 04, ! 23: 010, 020, 040, ! 24: 0100, 0200, 0400, ! 25: 01000, 02000, 04000, ! 26: 010000, 020000, 040000, 0100000 ! 27: }; ! 28: ! 29: #define IOMOVE iomove ! 30: struct chan *xcp(),*addch(),*nextcp(); ! 31: ! 32: #define HIQ 100 ! 33: #define LOQ 20 ! 34: #define FP ((struct file *)cp) ! 35: ! 36: char mcdebugs[NDEBUGS]; ! 37: ! 38: struct group * ! 39: getmpx(dev) ! 40: dev_t dev; ! 41: { ! 42: register d; ! 43: ! 44: d = minor(dev); ! 45: if (d >= NGROUPS) { ! 46: u.u_error = ENXIO; ! 47: return(NULL); ! 48: } ! 49: return(groups[d]); ! 50: } ! 51: ! 52: ! 53: /*ARGSUSED*/ ! 54: mxopen(dev, flag) ! 55: { ! 56: register struct group *gp; ! 57: register struct file *fp; ! 58: register struct chan *cp; ! 59: int msg; ! 60: ! 61: if ((gp=getmpx(dev)) == NULL) { ! 62: return; ! 63: } ! 64: if (!(gp->g_state&INUSE)) { ! 65: u.u_error = ENXIO; ! 66: return; ! 67: } ! 68: fp = u.u_ofile[u.u_r.r_val1]; ! 69: if (fp->f_inode != gp->g_inode) { ! 70: u.u_error = ENXIO; ! 71: return; ! 72: } ! 73: if ((cp=addch(gp->g_inode,0)) == NULL) { ! 74: u.u_error = ENXIO; ! 75: return; ! 76: } ! 77: ! 78: cp->c_flags = XGRP; ! 79: cp->c_ottyp = cp->c_ttyp = (struct tty *)cp; ! 80: cp->c_line = cp->c_oline = mpxline; ! 81: ! 82: fp->f_flag |= FMPY; ! 83: fp->f_flag |= FREAD+FWRITE; ! 84: fp->f_un.f_chan = cp; ! 85: ! 86: if (gp->g_inode == mpxip) { ! 87: plock(mpxip); ! 88: mpxname(cp); ! 89: msg = M_OPEN; ! 90: } else ! 91: msg = M_WATCH; ! 92: ! 93: scontrol(cp, msg+(cp->c_index<<8), u.u_uid); ! 94: sleep((caddr_t)cp,TTIPRI); ! 95: if (cp->c_flags&NMBUF) ! 96: prele(mpxip); ! 97: if (cp->c_flags & WCLOSE) { ! 98: chdrain(cp); ! 99: chfree(cp); ! 100: u.u_error = ENXIO; ! 101: return; ! 102: } ! 103: cp->c_fy = fp; ! 104: cp->c_pgrp = u.u_procp->p_pgrp; ! 105: } ! 106: ! 107: ! 108: char mxnmbuf[NMSIZE]; ! 109: int nmsize; ! 110: ! 111: mpxname(cp) ! 112: register struct chan *cp; ! 113: { ! 114: register char *np; ! 115: register c; ! 116: ! 117: np = mxnmbuf; ! 118: u.u_dirp = (caddr_t)u.u_arg[0]; ! 119: ! 120: while (np < &mxnmbuf[NMSIZE]) { ! 121: c = uchar(); ! 122: if (c <= 0) ! 123: break; ! 124: *np++ = c; ! 125: } ! 126: *np++ = '\0'; ! 127: nmsize = np - mxnmbuf; ! 128: ! 129: cp->c_flags |= NMBUF; ! 130: } ! 131: ! 132: ! 133: mxclose(dev, flag, fp) ! 134: dev_t dev; ! 135: register struct file *fp; ! 136: { ! 137: register struct chan *cp = fp->f_un.f_chan; ! 138: register struct group *gp; ! 139: register struct inode *ip; ! 140: int i, fmp; ! 141: ! 142: fmp = flag&FMP; ! 143: if ((gp=getmpx(dev)) == NULL) ! 144: return; ! 145: ! 146: ip = gp->g_inode; ! 147: if (ip==NULL || (ip->i_mode&IFMT)!=IFMPC) { ! 148: return; ! 149: } ! 150: ! 151: /* ! 152: * close a channel ! 153: */ ! 154: if (cp!=NULL && fmp && fmp!=FMP) { ! 155: for(fp=file; fp< fileNFILE; fp++) ! 156: if(fp->f_count && fp->f_flag&FMP && fp->f_un.f_chan==cp){ ! 157: return; ! 158: } ! 159: chdrain(cp); ! 160: if ((cp->c_flags&WCLOSE)==0) { ! 161: scontrol(cp, M_CLOSE, 0); ! 162: cp->c_flags |= WCLOSE; ! 163: } else { ! 164: chfree(cp); ! 165: } ! 166: goto out; ! 167: } ! 168: ! 169: ! 170: for(fp=file; fp < fileNFILE; fp++) { ! 171: if (fp->f_count && (fp->f_flag&FMP)==FMP && fp->f_inode==ip) ! 172: return; ! 173: } ! 174: ! 175: if (ip == mpxip) { ! 176: mpxip = NULL; ! 177: prele(ip); ! 178: } ! 179: ! 180: for(i=0;i<NINDEX;i++) ! 181: (void) detach(gp->g_chans[i]); ! 182: ! 183: out: ! 184: plock(ip); ! 185: if (ip->i_count == 1) { ! 186: groups[minor(dev)] = NULL; ! 187: zero((caddr_t)gp, sizeof (struct group)); ! 188: ip->i_mode = IFREG + 0666; ! 189: ip->i_un.i_rdev = 0; ! 190: ip->i_flag |= IUPD|ICHG; ! 191: iput(ip); ! 192: return; ! 193: } ! 194: prele(ip); ! 195: } ! 196: ! 197: zero(s, cc) ! 198: register char *s; ! 199: register cc; ! 200: { ! 201: while (cc--) ! 202: *s++ = 0; ! 203: } ! 204: ! 205: char m_eot[] ={ M_EOT, 0, 0, 0}; ! 206: ! 207: /* ! 208: * Mxread + mxwrite are entered from cdevsw ! 209: * for all read/write calls. Operations on ! 210: * an mpx file are handled here. ! 211: * Calls are made through linesw to handle actual ! 212: * data movement. ! 213: */ ! 214: mxread(dev) ! 215: { ! 216: register struct group *gp; ! 217: register struct chan *cp; ! 218: register esc; ! 219: struct rh h; ! 220: caddr_t base; ! 221: unsigned count; ! 222: int s, xfr, more, fmp; ! 223: ! 224: if ((gp=getmpx(dev))==NULL || (FP=getf(u.u_arg[0]))==NULL) { ! 225: u.u_error = ENXIO; ! 226: return; ! 227: } ! 228: ! 229: fmp = FP->f_flag & FMP; ! 230: if (fmp != FMP) { ! 231: if (u.u_count == 0) ! 232: return; ! 233: msread(fmp, FP->f_un.f_chan); ! 234: return; ! 235: } ! 236: ! 237: if ((int)u.u_base & 1) { ! 238: u.u_error = ENXIO; ! 239: return; ! 240: } ! 241: ! 242: s = spl6(); ! 243: if (u.u_count == 0) ! 244: { ! 245: if (gp->g_datq == 0) ! 246: u.u_error = ENXIO; ! 247: splx(s); ! 248: return; ! 249: } ! 250: while (gp->g_datq == 0) { ! 251: sleep((caddr_t)&gp->g_datq, TTIPRI); ! 252: } ! 253: splx(s); ! 254: ! 255: while (gp->g_datq && u.u_count >= CNTLSIZ + 2) { ! 256: esc = 0; ! 257: cp = nextcp(gp); ! 258: if (cp==NULL) { ! 259: continue; ! 260: } ! 261: h.index = cpx(cp); ! 262: if (count = cp->c_ctlx.c_cc) { ! 263: count += CNTLSIZ; ! 264: if (cp->c_flags&NMBUF) ! 265: count += nmsize; ! 266: if (count > u.u_count) { ! 267: (void) sdata(cp); ! 268: return; ! 269: } ! 270: esc++; ! 271: } ! 272: base = u.u_base; ! 273: count = u.u_count; ! 274: u.u_base += sizeof h; ! 275: u.u_count -= sizeof h; ! 276: xfr = u.u_count; ! 277: if (esc) { ! 278: more = mcread(cp); ! 279: } else { ! 280: more = (*linesw[cp->c_line].l_read)(cp->c_ttyp); ! 281: } ! 282: if (more > 0) ! 283: (void) sdata(cp); ! 284: if (more < 0) ! 285: scontrol(cp, M_CLOSE, 0); ! 286: (void) spl0(); ! 287: if (xfr == u.u_count) { ! 288: esc++; ! 289: IOMOVE((caddr_t)m_eot, sizeof m_eot, B_READ); ! 290: } ! 291: xfr -= u.u_count; ! 292: if (esc) { ! 293: h.count = 0; ! 294: h.ccount = xfr; ! 295: } else { ! 296: h.count = xfr; ! 297: h.ccount = 0; ! 298: mxrstrt(cp, &cp->cx.datq, BLOCK|ALT); ! 299: } ! 300: if (u.u_count && (xfr&1)) { ! 301: u.u_base++; ! 302: u.u_count--; ! 303: } ! 304: (void) copyout((caddr_t)&h, base, sizeof h); ! 305: ! 306: } ! 307: } ! 308: ! 309: ! 310: mxwrite(dev) ! 311: { ! 312: register struct chan *cp; ! 313: struct wh h; ! 314: struct group *gp; ! 315: int ucount, esc, fmp, burpcount; ! 316: caddr_t ubase, hbase; ! 317: ! 318: if ((gp=getmpx(dev))==NULL || (FP=getf(u.u_arg[0]))==NULL) { ! 319: return; ! 320: } ! 321: fmp = FP->f_flag & FMP; ! 322: if (fmp != FMP) { ! 323: mswrite(fmp, FP->f_un.f_chan); ! 324: return; ! 325: } ! 326: ! 327: burpcount = 0; ! 328: while (u.u_count >= sizeof h) { ! 329: hbase = u.u_base; ! 330: IOMOVE((caddr_t)&h, sizeof h, B_WRITE); ! 331: if (u.u_error) ! 332: return; ! 333: esc = 0; ! 334: if (h.count==0) { ! 335: esc++; ! 336: h.count = h.ccount; ! 337: } ! 338: cp = xcp(gp, h.index); ! 339: if (cp==NULL || cp->c_flags&ISGRP) { ! 340: u.u_error = ENXIO; ! 341: return; ! 342: } ! 343: ucount = u.u_count; ! 344: ubase = u.u_base; ! 345: u.u_count = h.count; ! 346: u.u_base = h.data; ! 347: ! 348: if (esc==0) { ! 349: struct tty *tp; ! 350: caddr_t waddr; ! 351: int line; ! 352: ! 353: if (cp->c_flags&PORT) { ! 354: line = cp->c_line; ! 355: tp = cp->c_ttyp; ! 356: } else { ! 357: line = cp->c_oline; ! 358: tp = cp->c_ottyp; ! 359: } ! 360: loop: ! 361: waddr = (caddr_t)(*linesw[line].l_write)(tp); ! 362: if (u.u_count) { ! 363: if (gp->g_state&ENAMSG) { ! 364: burpcount++; ! 365: cp->c_flags |= BLKMSG; ! 366: /* ! 367: scontrol(cp, M_BLK, u.u_count); ! 368: */ ! 369: h.ccount = -1; ! 370: h.count = u.u_count; ! 371: h.data = u.u_base; ! 372: (void) copyout((caddr_t)&h, hbase, sizeof h); ! 373: } else { ! 374: if(waddr == 0) { ! 375: u.u_error = ENXIO; ! 376: return; ! 377: } ! 378: sleep(waddr, TTOPRI); ! 379: goto loop; ! 380: } ! 381: } ! 382: } else { ! 383: mxwcontrol(cp); ! 384: } ! 385: u.u_count = ucount; ! 386: u.u_base = ubase; ! 387: } ! 388: u.u_count = burpcount; ! 389: } ! 390: ! 391: ! 392: ! 393: /* ! 394: * Mcread and mcwrite move data on an mpx file. ! 395: * Transfer addr and length is controlled by mxread/mxwrite. ! 396: * Kernel-to-Kernel and other special transfers are not ! 397: * yet in. ! 398: */ ! 399: mcread(cp) ! 400: register struct chan *cp; ! 401: { ! 402: register struct clist *q; ! 403: register char *np; ! 404: ! 405: ! 406: q = (cp->c_ctlx.c_cc) ? &cp->c_ctlx : &cp->cx.datq; ! 407: (void) mxmove(q, B_READ); ! 408: ! 409: if (cp->c_flags&NMBUF && q == &cp->c_ctlx) { ! 410: np = mxnmbuf; ! 411: while (nmsize--) ! 412: (void) passc(*np++); ! 413: cp->c_flags &= ~NMBUF; ! 414: prele(mpxip); ! 415: } ! 416: if (cp->c_flags&PORT) ! 417: return(cp->c_ctlx.c_cc + cp->c_ttyp->t_rawq.c_cc); else ! 418: return(cp->c_ctlx.c_cc + cp->cx.datq.c_cc); ! 419: ! 420: } ! 421: ! 422: ! 423: caddr_t ! 424: mcwrite(cp) ! 425: register struct chan *cp; ! 426: { ! 427: register struct clist *q; ! 428: int s; ! 429: ! 430: q = &cp->cy.datq; ! 431: while (u.u_count) { ! 432: s = spl6(); ! 433: if (q->c_cc > HIQ || (cp->c_flags&EOTMARK)) { ! 434: cp->c_flags |= SIGBLK; ! 435: splx(s); ! 436: break; ! 437: } ! 438: splx(s); ! 439: (void) mxmove(q, B_WRITE); ! 440: } ! 441: wakeup((caddr_t)q); ! 442: return((caddr_t)q); ! 443: } ! 444: ! 445: ! 446: /* ! 447: * Msread and mswrite move bytes ! 448: * between user and non-multiplexed channel. ! 449: */ ! 450: msread(fmp, cp) ! 451: register struct chan *cp; ! 452: { ! 453: register struct clist *q; ! 454: int s; ! 455: ! 456: q = (fmp&FMPX) ? &cp->cx.datq : &cp->cy.datq; ! 457: s = spl6(); ! 458: while (q->c_cc == 0) { ! 459: if (cp->c_flags&WCLOSE) { ! 460: u.u_error = ENXIO; ! 461: goto out; ! 462: } ! 463: if (cp->c_flags & EOTMARK) { ! 464: cp->c_flags &= ~EOTMARK; ! 465: if(msgenab(cp)) ! 466: scontrol(cp, M_UBLK, 0); ! 467: else { ! 468: wakeup((caddr_t)cp); ! 469: wakeup((caddr_t)q); ! 470: } ! 471: goto out; ! 472: } ! 473: sleep((caddr_t)q,TTIPRI); ! 474: } ! 475: if (cp->c_flags&WCLOSE) { ! 476: u.u_error = ENXIO; ! 477: goto out; ! 478: } ! 479: splx(s); ! 480: while (mxmove(q, B_READ) > 0) ! 481: ; ! 482: mxrstrt(cp, q, SIGBLK); ! 483: return; ! 484: out: ! 485: splx(s); ! 486: } ! 487: ! 488: ! 489: mswrite(fmp, cp) ! 490: register struct chan *cp; ! 491: { ! 492: register struct clist *q; ! 493: register int cc; ! 494: ! 495: q = (fmp&FMPX) ? &cp->cy.datq : &cp->cx.datq; ! 496: while (u.u_count) { ! 497: (void) spl6(); ! 498: if (cp->c_flags&WCLOSE) { ! 499: gsignal(cp->c_pgrp, SIGPIPE); ! 500: (void) spl0(); ! 501: return; ! 502: } ! 503: if (q->c_cc>= HIQ || cp->c_flags&FBLOCK) { ! 504: if (cp->c_flags&WCLOSE) { ! 505: gsignal(cp->c_pgrp, SIGPIPE); ! 506: (void) spl0(); ! 507: return; ! 508: } ! 509: (void) sdata(cp); ! 510: cp->c_flags |= BLOCK; ! 511: sleep((caddr_t)q+1,TTOPRI); ! 512: (void) spl0(); ! 513: continue; ! 514: } ! 515: (void) spl0(); ! 516: cc = mxmove(q, B_WRITE); ! 517: if (cc < 0) ! 518: break; ! 519: } ! 520: if (fmp&FMPX) { ! 521: if (cp->c_flags&YGRP) (void) sdata(cp); ! 522: else wakeup((caddr_t)q); ! 523: } else { ! 524: if (cp->c_flags&XGRP) (void) sdata(cp); ! 525: else wakeup((caddr_t)q); ! 526: } ! 527: } ! 528: ! 529: ! 530: /* ! 531: * move chars between clist and user space. ! 532: */ ! 533: ! 534: mxmove(q, dir) ! 535: register struct clist *q; ! 536: register dir; ! 537: { ! 538: register cc; ! 539: char cbuf[HIQ]; ! 540: ! 541: cc = MIN(u.u_count, sizeof cbuf); ! 542: if (dir == B_READ) ! 543: cc = q_to_b(q, cbuf, cc); ! 544: if (cc <= 0) ! 545: return(cc); ! 546: IOMOVE((caddr_t)cbuf, (unsigned)cc, dir); ! 547: if (dir == B_WRITE) ! 548: cc = b_to_q(cbuf, cc, q); ! 549: return(cc); ! 550: } ! 551: ! 552: ! 553: ! 554: mxrstrt(cp, q, b) ! 555: register struct chan *cp; ! 556: register struct clist *q; ! 557: register b; ! 558: { ! 559: int s; ! 560: ! 561: s = spl6(); ! 562: if (cp->c_flags&b && q->c_cc<LOQ) { ! 563: cp->c_flags &= ~b; ! 564: if (b&ALT) ! 565: wakeup((caddr_t)q+1); else ! 566: if (b&(BLKMSG)) ! 567: scontrol(cp, M_UBLK, 0); else ! 568: wakeup((caddr_t)q); ! 569: } ! 570: if (cp->c_flags&WFLUSH) ! 571: wakeup((caddr_t)q+2); ! 572: splx(s); ! 573: } ! 574: ! 575: ! 576: ! 577: /* ! 578: * called from driver start or xint routines ! 579: * to wakeup output sleeper. ! 580: */ ! 581: mcstart(cp, q) ! 582: register struct chan *cp; ! 583: register caddr_t q; ! 584: { ! 585: ! 586: if (cp->c_flags&(BLKMSG)) { ! 587: cp->c_flags &= ~BLKMSG; ! 588: scontrol(cp, M_UBLK, 0); ! 589: } else ! 590: wakeup((caddr_t)q); ! 591: } ! 592: ! 593: ! 594: mxwcontrol(cp) ! 595: register struct chan *cp; ! 596: { ! 597: short cmd; ! 598: struct sgttyb vec; ! 599: int s; ! 600: ! 601: IOMOVE((caddr_t)&cmd, sizeof cmd, B_WRITE); ! 602: if (u.u_error) ! 603: return; ! 604: switch(cmd) { ! 605: /* ! 606: * not ready to queue this up yet. ! 607: */ ! 608: case M_EOT: ! 609: s = spl6(); ! 610: while (cp->c_flags & EOTMARK) ! 611: if(msgenab(cp)){ ! 612: scontrol(cp, M_BLK, 0); ! 613: goto out; ! 614: } else ! 615: sleep((caddr_t)cp, TTOPRI); ! 616: cp->c_flags |= EOTMARK; ! 617: out: ! 618: wakeup((caddr_t)&cp->cy.datq); ! 619: splx(s); ! 620: break; ! 621: case M_IOCTL: ! 622: break; ! 623: case M_IOANS: ! 624: if (cp->c_flags&SIOCTL) { ! 625: IOMOVE((caddr_t)&vec, sizeof vec, B_WRITE); ! 626: (void) b_to_q((caddr_t)&vec, sizeof vec, &cp->c_ctly); ! 627: cp->c_flags &= ~SIOCTL; ! 628: wakeup((caddr_t)cp); ! 629: } ! 630: break; ! 631: case M_BLK: ! 632: cp->c_flags |= FBLOCK; ! 633: break; ! 634: case M_UBLK: ! 635: cp->c_flags &= ~FBLOCK; ! 636: chwake(cp); ! 637: break; ! 638: default: ! 639: u.u_error = ENXIO; ! 640: } ! 641: } ! 642: ! 643: ! 644: ! 645: /*ARGSUSED*/ ! 646: mxioctl(dev, cmd, addr, flag) ! 647: caddr_t addr; ! 648: { ! 649: struct group *gp; ! 650: int fmp; ! 651: struct file *fp; ! 652: struct { ! 653: short c_ctl; ! 654: short c_cmd; ! 655: struct sgttyb c_vec; ! 656: } ctlbuf; ! 657: ! 658: if ((gp=getmpx(dev))==NULL || (fp=getf(u.u_arg[0]))==NULL) { ! 659: return; ! 660: } ! 661: ! 662: fmp = fp->f_flag & FMP; ! 663: if (fmp == FMP) { ! 664: switch(cmd) { ! 665: ! 666: case MXLSTN: ! 667: if (mpxip == NULL) { ! 668: mpxip = gp->g_inode; ! 669: } else { ! 670: u.u_error = ENXIO; ! 671: return; ! 672: } ! 673: break; ! 674: ! 675: case MXNBLK: ! 676: gp->g_state |= ENAMSG; ! 677: break; ! 678: ! 679: default: ! 680: u.u_error = ENXIO; ! 681: return; ! 682: } ! 683: } else { ! 684: ctlbuf.c_ctl = M_IOCTL; ! 685: ctlbuf.c_cmd = cmd; ! 686: (void) copyin(addr, (caddr_t)&ctlbuf.c_vec, sizeof (struct sgttyb)); ! 687: sioctl(fp->f_un.f_chan, (char *)&ctlbuf, sizeof ctlbuf); ! 688: (void) copyout((caddr_t)&ctlbuf, addr, sizeof (struct sgttyb)); ! 689: } ! 690: } ! 691: ! 692: ! 693: chdrain(cp) ! 694: register struct chan *cp; ! 695: { ! 696: register struct tty *tp; ! 697: int wflag; ! 698: ! 699: chwake(cp); ! 700: ! 701: wflag = (cp->c_flags&WCLOSE)==0; ! 702: tp = cp->c_ttyp; ! 703: if (tp == NULL) /* prob not required */ ! 704: return; ! 705: if (cp->c_flags&PORT && tp->t_chan == cp) { ! 706: cp->c_ttyp = NULL; ! 707: tp->t_chan = NULL; ! 708: return; ! 709: } ! 710: if (wflag) ! 711: wflush(cp,&cp->cx.datq); else ! 712: flush(&cp->cx.datq); ! 713: if (!(cp->c_flags&YGRP)) { ! 714: flush(&cp->cy.datq); ! 715: } ! 716: } ! 717: ! 718: chwake(cp) ! 719: register struct chan *cp; ! 720: { ! 721: register char *p; ! 722: ! 723: wakeup((caddr_t)cp); ! 724: flush(&cp->c_ctlx); ! 725: p = (char *)&cp->cx.datq; ! 726: wakeup((caddr_t)p); wakeup((caddr_t)++p); wakeup((caddr_t)++p); ! 727: p = (char *)&cp->cy.datq; ! 728: wakeup((caddr_t)p); wakeup((caddr_t)++p); wakeup((caddr_t)++p); ! 729: } ! 730: ! 731: ! 732: chfree(cp) ! 733: register struct chan *cp; ! 734: { ! 735: register struct group *gp; ! 736: register i; ! 737: ! 738: gp = cp->c_group; ! 739: if (gp==NULL) ! 740: return; ! 741: i = cp->c_index; ! 742: if (cp == gp->g_chans[i]) { ! 743: gp->g_chans[i] = NULL; ! 744: } ! 745: cp->c_group = NULL; ! 746: wakeup((caddr_t)gp); ! 747: } ! 748: ! 749: ! 750: flush(q) ! 751: register struct clist *q; ! 752: { ! 753: ! 754: while(q->c_cc) ! 755: (void) getc(q); ! 756: } ! 757: ! 758: ! 759: wflush(cp,q) ! 760: register struct chan *cp; ! 761: register struct clist *q; ! 762: { ! 763: register s; ! 764: ! 765: s = spl6(); ! 766: if(q->c_cc && (cp->c_flags&WCLOSE) == 0) { ! 767: cp->c_flags |= WFLUSH; ! 768: (void) sdata(cp); ! 769: (void) tsleep((caddr_t)q+2, TTOPRI, 30); ! 770: } ! 771: flush(q); ! 772: cp->c_flags &= ~WFLUSH; ! 773: splx(s); ! 774: } ! 775: ! 776: ! 777: scontrol(cp,event,value) ! 778: register struct chan *cp; ! 779: short event,value; ! 780: { ! 781: register struct clist *q; ! 782: int s; ! 783: ! 784: q = &cp->c_ctlx; ! 785: s = spl6(); ! 786: if (sdata(cp) == NULL) ! 787: return; ! 788: (void) putw(event,q); ! 789: (void) putw(value,q); ! 790: splx(s); ! 791: } ! 792: ! 793: ! 794: ! 795: sioctl(cp, vec, cc) ! 796: register struct chan *cp; ! 797: char *vec; ! 798: { ! 799: register s; ! 800: register struct clist *q; ! 801: ! 802: s = spl6(); ! 803: q = &cp->cx.datq; ! 804: while (q->c_cc) { ! 805: cp->c_flags |= BLOCK; ! 806: if (sdata(cp)==NULL) { ! 807: u.u_error = ENXIO; ! 808: return; ! 809: } ! 810: sleep((caddr_t)q+1, TTOPRI); ! 811: } ! 812: (void) b_to_q(vec, cc, &cp->c_ctlx); ! 813: cp->c_flags |= SIOCTL; ! 814: while (cp->c_flags&SIOCTL) { ! 815: if (cp->c_ctlx.c_cc) ! 816: if (sdata(cp)==NULL) { ! 817: u.u_error = ENXIO; ! 818: return; ! 819: } ! 820: sleep((caddr_t)cp, TTOPRI); ! 821: } ! 822: (void) q_to_b(&cp->c_ctly, vec, cp->c_ctly.c_cc); ! 823: splx(s); ! 824: } ! 825: ! 826: sdata(cp) ! 827: struct chan *cp; ! 828: { ! 829: register struct group *gp = (struct group *)cp; ! 830: register struct group *ngp; ! 831: register int s; ! 832: ! 833: ngp = gp->g_group; ! 834: if (ngp==NULL || (ngp->g_state&ISGRP)==0) ! 835: return(NULL); ! 836: ! 837: s = spl6(); ! 838: do { ! 839: ngp->g_datq |= cmask[gp->g_index]; ! 840: wakeup((caddr_t)&ngp->g_datq); ! 841: gp = ngp; ! 842: } while(ngp=ngp->g_group); ! 843: splx(s); ! 844: return((int)gp); ! 845: } ! 846: ! 847: ! 848: ! 849: struct chan * ! 850: xcp(gp, x) ! 851: register struct group *gp; ! 852: register short x; ! 853: { ! 854: register int i; ! 855: ! 856: while (gp->g_group) gp=gp->g_group; ! 857: for (i=0;i<NLEVELS;i++) { ! 858: if ((x&017) >= NINDEX) ! 859: break; ! 860: if (gp==NULL || (gp->g_state&ISGRP)==0) ! 861: return((struct chan *)NULL); ! 862: gp = (struct group *)gp->g_chans[x&017]; ! 863: x >>= 4; ! 864: } ! 865: return((struct chan *)gp); ! 866: } ! 867: ! 868: cpx(cp) ! 869: register struct chan *cp; ! 870: { ! 871: register x; ! 872: register struct group *gp; ! 873: ! 874: x = (-1<<4) + cp->c_index; ! 875: gp = cp->c_group; ! 876: while (gp->g_group) { ! 877: x <<= 4; ! 878: x |= gp->g_index; ! 879: gp = gp->g_group; ! 880: } ! 881: return(x); ! 882: } ! 883: ! 884: ! 885: struct chan * ! 886: nextcp(gp) ! 887: register struct group *gp; ! 888: { ! 889: register struct group *lgp, *ngp; ! 890: ! 891: do { ! 892: while ((gp->g_datq & cmask[gp->g_rot]) == 0) { ! 893: gp->g_rot = (gp->g_rot+1)%NINDEX; ! 894: } ! 895: lgp = gp; ! 896: gp = (struct group *)gp->g_chans[gp->g_rot]; ! 897: } while (gp!=NULL && gp->g_state&ISGRP); ! 898: ! 899: lgp->g_datq &= ~cmask[lgp->g_rot]; ! 900: lgp->g_rot = (lgp->g_rot+1)%NINDEX; ! 901: ! 902: while (ngp=lgp->g_group) { ! 903: ngp->g_datq &= ~cmask[lgp->g_index]; ! 904: if (ngp->g_datq) ! 905: break; ! 906: lgp = ngp; ! 907: } ! 908: return((struct chan *)gp); ! 909: } ! 910: ! 911: ! 912: ! 913: msgenab(cp) ! 914: register struct chan *cp; ! 915: { ! 916: register struct group *gp; ! 917: ! 918: for(gp=cp->c_group;gp;gp=gp->g_group) ! 919: if(gp->g_state & ENAMSG)return(1); ! 920: return(0); ! 921: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.