|
|
1.1 ! root 1: /* ! 2: * stream driver for DK via KMC-11/KDI board ! 3: */ ! 4: #include "kdi.h" ! 5: #include "kmc.h" ! 6: #if NKDI && NKMC ! 7: ! 8: #include "../h/param.h" ! 9: #include "../h/systm.h" ! 10: #include "../h/stream.h" ! 11: #include "../h/ioctl.h" ! 12: #include "../h/pte.h" ! 13: #include "../h/map.h" ! 14: #include "../h/buf.h" ! 15: #include "../h/ubavar.h" ! 16: #include "../h/conf.h" ! 17: #include "../h/ttyld.h" ! 18: #include "../h/dkstat.h" ! 19: #include "../h/dkmod.h" ! 20: ! 21: #define NKMB 10 /* size of cmd/status buffers */ ! 22: #define KDIPRI 28 ! 23: ! 24: /* channel states */ ! 25: #define CLOSED 0 ! 26: #define RCLOSE 1 /* remote gone, local still around */ ! 27: #define LCLOSE 2 /* closed locally, not acked yet */ ! 28: #define OPEN 3 /* in use */ ! 29: ! 30: /* ! 31: * format of UB addresses sent to KMC ! 32: */ ! 33: struct kmaddr { ! 34: u_short hi; ! 35: u_short lo; ! 36: }; ! 37: ! 38: /* ! 39: * KMC init packet ! 40: */ ! 41: struct kinit { ! 42: struct kmaddr cmdaddr; /* UB addr of cmd buf */ ! 43: struct kmaddr stataddr; /* UB addr of statbuf */ ! 44: struct kmaddr bufaddr; /* UB addr of KMC workspace */ ! 45: struct kmaddr csraddr; /* for DR11C - unused */ ! 46: }; ! 47: ! 48: /* ! 49: * command/status packets ! 50: */ ! 51: struct kin { /* KMC command buffer */ ! 52: u_char type; /* command type */ ! 53: u_char serno; /* probably seq number */ ! 54: u_char chan; /* channel number */ ! 55: u_char fill2; /* probably seq number */ ! 56: u_short len; /* byte count */ ! 57: char ctl; /* possible control byte */ ! 58: char mode; /* command variant */ ! 59: struct kmaddr addr; /* UB location of buffer */ ! 60: }; ! 61: ! 62: /* ! 63: * Big structure with stuff that needs to be accessible on the unibus ! 64: */ ! 65: struct kmcdk { ! 66: struct kinit kinit; /* the init packet */ ! 67: struct kin cmd[NKMB]; /* KMC command buffer */ ! 68: struct kin stat[NKMB]; /* KMC status buffer */ ! 69: char kmcbuf[16*1024]; /* temp space for KMC */ ! 70: } k; ! 71: ! 72: struct kdi { ! 73: struct queue *dkrq; ! 74: struct block *ibp; ! 75: struct block *obp; ! 76: u_short rsize; /* # bytes in last read */ ! 77: char chan; ! 78: char ostate; ! 79: } kdi[NKDI]; ! 80: ! 81: ! 82: #define KMBUSY 01 ! 83: #define KMSTOP 02 ! 84: #define KMBIG 04 /* rcvd lots last time, use big buffer */ ! 85: ! 86: /* ! 87: * device structure ! 88: */ ! 89: struct device { ! 90: char sts; ! 91: char x1; ! 92: union { ! 93: struct { ! 94: u_short lo; ! 95: u_char hi; ! 96: } a; ! 97: struct { ! 98: u_char x2; ! 99: u_char x3; ! 100: u_char ch; ! 101: u_char ct; ! 102: u_char sh; ! 103: u_char st; ! 104: } q; ! 105: } u; ! 106: }; ! 107: ! 108: /* ! 109: * KMC commands ! 110: */ ! 111: #define KC_INIT 1 ! 112: #define KC_SEND 2 ! 113: #define KC_RCVB 3 ! 114: #define KC_CLOSE 4 ! 115: #define KC_XINIT 5 ! 116: #define KC_CMD 6 ! 117: #define KC_FLAG 7 ! 118: #define KC_SOI 8 ! 119: ! 120: /* ! 121: * subcommands of KC_CMD or KC_SEND ! 122: */ ! 123: #define OFLUSH 02 /* flush output */ ! 124: #define OSPND 04 /* suspend output */ ! 125: #define ORSME 010 /* resume output */ ! 126: #define OBOTM 0200 /* send BOTM trailer, not BOT */ ! 127: ! 128: /* ! 129: * KMC reports ! 130: */ ! 131: #define KS_SEND 024 ! 132: #define KS_RDB 025 ! 133: #define KS_EOI 026 ! 134: #define KS_CNTL 027 ! 135: #define KS_ERR 030 ! 136: ! 137: /* ! 138: * KC_RCV modes ! 139: */ ! 140: #define CBLOCK 0040 /* return on block boundary */ ! 141: #define CTIME 0100 /* return when time expires */ ! 142: ! 143: /* ! 144: * KS_RDB mode ! 145: */ ! 146: #define SFULL 0001 /* buffer full */ ! 147: #define SCNTL 0002 /* cntl char recv */ ! 148: #define SABORT 0010 /* rcv aborted */ ! 149: #define SBLOCK 0040 /* block boundary */ ! 150: #define STIME 0100 /* time limit expired */ ! 151: ! 152: /* ! 153: * URP control characters ! 154: */ ! 155: #define D_DELAY 0100 ! 156: #define D_BREAK 0110 ! 157: ! 158: /* ! 159: * KMC errors ! 160: */ ! 161: #define E_NOQB 4 /* internal buffer runout */ ! 162: #define E_UMETA 7 /* unknown control character */ ! 163: ! 164: /* ! 165: * tracing ! 166: */ ! 167: #define DEBUG ! 168: #ifdef DEBUG ! 169: struct kin ktrbuf[256]; ! 170: struct kin *ktrp = ktrbuf; ! 171: #define TRACE(x) *ktrp++ = x; if (ktrp >= &ktrbuf[256]) ktrp = ktrbuf; ! 172: #else ! 173: #define TRACE(x) ; ! 174: #endif ! 175: ! 176: int nodev(), kdiopen(), kdiclose(), kdiput(), kdiisrv(); ! 177: struct qinit kdirinit = { nodev, kdiisrv, kdiopen, kdiclose, 0, 0 }; ! 178: struct qinit kdiwinit = { kdiput, NULL, kdiopen, kdiclose, 512, 128 }; ! 179: struct streamtab kdiinfo = { &kdirinit, &kdiwinit }; ! 180: ! 181: extern u_char blkdata[]; /* stream IO blocks */ ! 182: extern long blkubad; /* unibus address of IO blocks */ ! 183: long kdiubad; /* unibus address of device data */ ! 184: struct kmaddr kmcaddr(); ! 185: int kdiopened; ! 186: int kmcbad; ! 187: char kdistate[NKDI]; ! 188: struct dkmodule *kdmodp; ! 189: extern struct dkmodule dkmod[]; ! 190: extern struct uba_device *kmcdinfo[NKMC]; ! 191: extern struct uba_driver kmcdriver; ! 192: extern (*kdirint)(); ! 193: extern (*kdixint)(); ! 194: struct dkstat dkstat; ! 195: ! 196: /* ! 197: * open channel ! 198: */ ! 199: kdiopen(q, dev) ! 200: register struct queue *q; ! 201: register dev_t dev; ! 202: { ! 203: register struct kdi *kp; ! 204: register struct block *bp; ! 205: register mindev = minor(dev); ! 206: ! 207: if (mindev <= 0 || mindev >= NKDI || kmcbad) ! 208: return(0); ! 209: if (!kdiopened) { ! 210: if (mindev > 1) ! 211: return(0); ! 212: for (kp = &kdi[0]; kp < &kdi[NKDI]; kp++) ! 213: kp->chan = kp - &kdi[0]; ! 214: if (kdiinit() == 0) ! 215: return(0); ! 216: for (kdmodp = dkmod; ;kdmodp++) { ! 217: if (kdmodp->dev==(dev_t)0 || kdmodp->dev==major(dev)) { ! 218: kdmodp->dev = major(dev); ! 219: kdmodp->dkstate = kdistate; ! 220: kdmodp->nchan = NKDI; ! 221: break; ! 222: } ! 223: } ! 224: kdiopened++; ! 225: } ! 226: kp = &kdi[mindev]; ! 227: if (kdmodp->dkstate[mindev] != CLOSED) { ! 228: if (mindev&01 && mindev>1) /* outgoing channels cannot reopen */ ! 229: return(0); ! 230: if (kdmodp->dkstate[mindev] != OPEN) ! 231: return(0); /* closing channels cannot reopen */ ! 232: return(1); ! 233: } ! 234: kp->dkrq = q; ! 235: q->ptr = (caddr_t)kp; ! 236: WR(q)->flag |= QDELIM|QBIGB; ! 237: q->flag |= QDELIM; ! 238: WR(q)->ptr = (caddr_t)kp; ! 239: kdmodp->dkstate[mindev] = OPEN; ! 240: kp->ostate = 0; ! 241: kcmd(KC_INIT, kp->chan, 0, 0, 0, (caddr_t)0); ! 242: if ((bp = allocb(64)) == NULL) { ! 243: kdmodp->dkstate[mindev] = 0; ! 244: return(0); ! 245: } ! 246: kp->ibp = bp; ! 247: kcmd(KC_RCVB, mindev, bp->lim-bp->wptr, 50, ! 248: CBLOCK|CTIME, (caddr_t)bp->wptr); ! 249: return(1); ! 250: } ! 251: ! 252: kdiclose(q) ! 253: register struct queue *q; ! 254: { ! 255: register struct kdi *kp = (struct kdi *)q->ptr; ! 256: register s, i; ! 257: register struct block *bp; ! 258: ! 259: if (kdmodp->dkstate[kp->chan]==RCLOSE || kdmodp->listnrq==NULL) ! 260: kdmodp->dkstate[kp->chan] = CLOSED; ! 261: else if (kdmodp->dkstate[kp->chan] == OPEN) { ! 262: kdmodp->dkstate[kp->chan] = LCLOSE; ! 263: for (i=0; i<30 && (WR(q)->count || kp->obp); i++) ! 264: tsleep((caddr_t)kp, KDIPRI, 1); ! 265: } ! 266: kp->dkrq = NULL; ! 267: if (kdmodp->listnrq) ! 268: putctl1(RD(kdmodp->listnrq), M_CLOSE, kp->chan); ! 269: s = spl6(); ! 270: if (kp->obp) { ! 271: freeb(kp->obp); ! 272: kp->obp = NULL; ! 273: } ! 274: splx(s); ! 275: kcmd(KC_CLOSE, kp->chan, 0, 0, 0, (caddr_t)NULL); ! 276: } ! 277: ! 278: kdiput(q, bp) ! 279: register struct queue *q; ! 280: register struct block *bp; ! 281: { ! 282: register struct kdi *kdp = (struct kdi *)q->ptr; ! 283: register union stmsg *sp; ! 284: register s; ! 285: ! 286: switch(bp->type) { ! 287: ! 288: case M_DATA: ! 289: case M_DELIM: ! 290: case M_DELAY: ! 291: case M_BREAK: ! 292: if (kdmodp->dkstate[kdp->chan] < LCLOSE) { ! 293: freeb(bp); ! 294: return; ! 295: } ! 296: putq(q, bp); ! 297: if ((kdp->ostate&KMBUSY)==0) ! 298: kmstart(kdp); ! 299: return; ! 300: ! 301: case M_CLOSE: ! 302: s = *bp->rptr; ! 303: if (s < NKDI) { ! 304: flushq(q, 1); ! 305: if (kdmodp->dkstate[s] == OPEN) { ! 306: kdmodp->dkstate[s] = RCLOSE; ! 307: putctl(kdi[s].dkrq->next, M_HANGUP); ! 308: } else if (kdmodp->dkstate[s] == LCLOSE) ! 309: kdmodp->dkstate[s] = CLOSED; ! 310: kcmd(KC_CLOSE, s, 0, 0, 0, (caddr_t)NULL); ! 311: } ! 312: freeb(bp); ! 313: return; ! 314: ! 315: case M_IOCTL: ! 316: sp = (union stmsg *)bp->rptr; ! 317: bp->type = M_IOCACK; ! 318: switch (sp->ioc0.com) { ! 319: ! 320: case TIOCSETP: ! 321: case TIOCSETN: ! 322: if (sp->ioc1.sb.sg_ispeed == 0) ! 323: putctl1(q, M_CLOSE, kdp->chan); ! 324: case KIOCISURP: ! 325: bp->wptr = bp->rptr; ! 326: break; ! 327: ! 328: case TIOCGETP: ! 329: sp->ioc1.sb.sg_ispeed = ! 330: sp->ioc1.sb.sg_ospeed = B9600; ! 331: break; ! 332: ! 333: case KIOCINIT: ! 334: kcmd(KC_XINIT, kdp->chan, 0, 0, 0, (caddr_t)NULL); ! 335: bp->rptr = bp->wptr; ! 336: break; ! 337: ! 338: case KIOCSHUT: ! 339: if (kdp->chan > 1) { ! 340: bp->type = M_IOCNAK; ! 341: break; ! 342: } ! 343: kdireset(); ! 344: bp->rptr = bp->wptr; ! 345: break; ! 346: ! 347: case DIOCSTREAM: ! 348: RD(q)->flag &= ~QDELIM; ! 349: bp->rptr = bp->wptr; ! 350: break; ! 351: ! 352: case DIOCRECORD: ! 353: RD(q)->flag |= QDELIM; ! 354: bp->rptr = bp->wptr; ! 355: break; ! 356: ! 357: default: ! 358: bp->wptr = bp->rptr; ! 359: bp->type = M_IOCNAK; ! 360: break; ! 361: } ! 362: qreply(q, bp); ! 363: return; ! 364: ! 365: case M_STOP: ! 366: s = OSPND; ! 367: kdp->ostate |= KMSTOP; ! 368: goto dontcmd; ! 369: ! 370: case M_FLUSH: ! 371: flushq(q, 0); ! 372: s = spl6(); ! 373: if (kdp->obp) { ! 374: freeb(kdp->obp); ! 375: kdp->obp = 0; ! 376: } ! 377: kdp->ostate &= ~(KMSTOP|KMBUSY); ! 378: splx(s); ! 379: s = OFLUSH|ORSME; ! 380: goto docmd; ! 381: ! 382: case M_START: ! 383: case M_HANGUP: ! 384: s = ORSME; ! 385: kdp->ostate &= ~KMSTOP; ! 386: goto dontcmd; ! 387: docmd: ! 388: kcmd(KC_CMD, kdp->chan, 0, s, 0, (caddr_t)NULL); ! 389: dontcmd: ! 390: kmstart(kdp); ! 391: break; ! 392: ! 393: default: /* not handled; just toss */ ! 394: break; ! 395: } ! 396: freeb(bp); ! 397: } ! 398: ! 399: kdiisrv(q) ! 400: register struct queue *q; ! 401: { ! 402: register struct kdi *kp = (struct kdi *)q->ptr; ! 403: ! 404: if ((q->next->flag&QFULL)==0 && kp->ibp==NULL) { ! 405: register struct block *bp = allocb(kp->ostate&KMBIG? 1024:64); ! 406: if (bp == NULL) ! 407: panic("kdi: can't alloc"); ! 408: kp->ibp = bp; ! 409: kcmd(KC_RCVB, kp->chan, bp->lim - bp->wptr, ! 410: 50, CBLOCK|CTIME, (caddr_t)bp->wptr); ! 411: } ! 412: } ! 413: ! 414: kmstart(kdp) ! 415: register struct kdi *kdp; ! 416: { ! 417: register s = spl5(); ! 418: register struct block *bp; ! 419: register struct queue *qp; ! 420: register c; ! 421: register struct block *xbp; ! 422: ! 423: if (kdp->ostate&(KMBUSY|KMSTOP)) { ! 424: splx(s); ! 425: return; ! 426: } ! 427: if ((qp = kdp->dkrq)==NULL || (qp = WR(qp))==NULL) { ! 428: splx(s); ! 429: return; ! 430: } ! 431: if (bp = getq(qp)) switch (bp->type) { ! 432: ! 433: case M_DELIM: ! 434: kcmd(KC_SEND, kdp->chan, 0, ! 435: D_DELAY, 0, (caddr_t)bp->rptr); ! 436: kdp->ostate |= KMBUSY; ! 437: kdp->obp = bp; ! 438: break; ! 439: ! 440: case M_DATA: ! 441: c = OBOTM; ! 442: if (xbp = qp->first) { ! 443: if (xbp->type==M_DELIM) { ! 444: if (xbp = getq(qp)) ! 445: freeb(xbp); ! 446: c = 0; ! 447: } ! 448: } else { /* wait for delim or data */ ! 449: putbq(qp, bp); ! 450: splx(s); ! 451: return; ! 452: } ! 453: kcmd(KC_SEND, kdp->chan, bp->wptr-bp->rptr, ! 454: 0, c, (caddr_t)bp->rptr); ! 455: kdp->ostate |= KMBUSY; ! 456: dkstat.output += bp->wptr - bp->rptr; ! 457: kdp->obp = bp; ! 458: break; ! 459: ! 460: case M_DELAY: ! 461: c = D_DELAY; ! 462: while (*bp->rptr>0) { ! 463: c++; ! 464: *bp->rptr >>= 1; ! 465: } ! 466: kcmd(KC_SEND, kdp->chan, 1, c, 0, (caddr_t)bp->rptr); ! 467: kdp->ostate |= KMBUSY; ! 468: kdp->obp = bp; ! 469: break; ! 470: ! 471: case M_BREAK: ! 472: kcmd(KC_SEND, kdp->chan, 0, D_BREAK, 0, (caddr_t)bp->rptr); ! 473: kdp->ostate |= KMBUSY; ! 474: kdp->obp = bp; ! 475: break; ! 476: ! 477: default: ! 478: printf("mesg %o in kdi\n", bp->type); ! 479: freeb(bp); ! 480: break; ! 481: } ! 482: splx(s); ! 483: } ! 484: ! 485: kcmd(type, chan, len, ctl, mode, addr) ! 486: caddr_t addr; ! 487: { ! 488: register i; ! 489: register struct device *dp = (struct device *)kmcdinfo[0]->ui_addr; ! 490: register struct kin *kp; ! 491: register s = spl5(); ! 492: static struct kmaddr nulladr = {0, 0}; ! 493: static serno; ! 494: ! 495: i = dp->u.q.ch; ! 496: if (i >= NKMB) ! 497: panic("cmd hd %d in kcmd\n", i); ! 498: kp = &k.cmd[i]; ! 499: kp->type = type; ! 500: kp->serno = ++serno; ! 501: kp->chan = chan; ! 502: kp->len = len; ! 503: kp->ctl = ctl; ! 504: kp->mode = mode; ! 505: if (addr) ! 506: kp->addr = kmcaddr(addr, (caddr_t)blkdata, blkubad); ! 507: else ! 508: kp->addr = nulladr; ! 509: i++; ! 510: if (i >= NKMB) ! 511: i = 0; ! 512: dp->u.q.ch = i; ! 513: TRACE(*kp); ! 514: splx(s); ! 515: } ! 516: ! 517: /* ! 518: * Interrupt routine-- unload status buffer: ! 519: * release write blocks, collect input ! 520: */ ! 521: kdiintr() ! 522: { ! 523: register struct device *dp = (struct device *)(kmcdinfo[0]->ui_addr); ! 524: register struct kin *sp; ! 525: register struct kdi *kp; ! 526: register struct block *bp; ! 527: register c; ! 528: ! 529: for ( ; (c = dp->u.q.st) != dp->u.q.sh; dp->u.q.st = c) { ! 530: if (c >= NKMB) ! 531: panic("kdi stat buf is %d\n", c); ! 532: sp = &k.stat[c]; ! 533: TRACE(*sp); ! 534: c++; ! 535: if (c >= NKMB) ! 536: c = 0; ! 537: if (sp->chan >= NKDI) { ! 538: printf("kdi stat chan is 0%o\n", sp->chan); ! 539: printf("type: %o len: 0%o mode: 0%o\n"); ! 540: continue; ! 541: } ! 542: kp = &kdi[sp->chan]; ! 543: switch (sp->type) { ! 544: ! 545: case KS_SEND: ! 546: if (kp->obp) { ! 547: freeb(kp->obp); ! 548: kp->obp = NULL; ! 549: } ! 550: kp->ostate &= ~KMBUSY; ! 551: if (kp->dkrq && WR(kp->dkrq)->first) ! 552: kmstart(kp); ! 553: break; ! 554: ! 555: case KS_RDB: ! 556: bp = kp->ibp; ! 557: kp->ibp = NULL; ! 558: if (kp->dkrq==NULL || kdmodp->dkstate[kp->chan]!=OPEN) { ! 559: if (bp) ! 560: freeb(bp); ! 561: break; ! 562: } ! 563: if (sp->mode & SABORT) { ! 564: printf("kdi rcv abort chan %d mode %o bp %x\n", ! 565: kp->chan, sp->mode, bp); ! 566: if (bp) ! 567: kp->ibp = bp; ! 568: kp->rsize = 0; ! 569: kp->ostate &= ~KMBIG; ! 570: break; ! 571: } ! 572: if (bp == NULL) { ! 573: printf("kdi intr: no ibp\n"); ! 574: break;; ! 575: } ! 576: /* special hacks */ ! 577: if (sp->mode&020 ! 578: || sp->mode==0100 && bp->wptr+sp->len == bp->lim) { ! 579: printf("I"); ! 580: freeb(bp); ! 581: } else { ! 582: bp->wptr = bp->lim - sp->len; ! 583: kp->rsize += bp->wptr - bp->rptr; ! 584: dkstat.input += bp->wptr - bp->rptr; ! 585: (*kp->dkrq->next->qinfo->putp) ! 586: (kp->dkrq->next, bp); ! 587: kp->ibp = NULL; ! 588: if(sp->mode&(SBLOCK|STIME)) { ! 589: putctl(kp->dkrq->next, M_DELIM); ! 590: kp->ostate &= ~KMBIG; ! 591: if (kp->rsize >= 512) ! 592: kp->ostate |= KMBIG; ! 593: kp->rsize = 0; ! 594: } ! 595: if (sp->mode&SCNTL) { ! 596: switch (sp->ctl) { ! 597: ! 598: case D_BREAK: ! 599: putctl(kp->dkrq->next, M_BREAK); ! 600: break; ! 601: ! 602: } ! 603: } ! 604: } ! 605: if ((kp->dkrq->next->flag&QFULL) == 0) { ! 606: bp = allocb(kp->ostate&KMBIG? 1024:64); ! 607: if (bp == NULL) ! 608: panic("kdi: can't alloc"); ! 609: kp->ibp = bp; ! 610: kcmd(KC_RCVB, kp->chan, bp->lim - bp->wptr, ! 611: 50, CBLOCK|CTIME, (caddr_t)bp->wptr); ! 612: } ! 613: break; ! 614: ! 615: case KS_EOI: ! 616: printf("kdi chan %d rcv EOI %x\n", sp->chan, sp->len); ! 617: break; ! 618: ! 619: case KS_CNTL: ! 620: /* ! 621: printf("kdi chan %d rcv ctl %x\n", sp->chan, sp->len); ! 622: */ ! 623: break; ! 624: ! 625: case KS_ERR: ! 626: printf("kdi chan %d error %d\n", sp->chan, sp->len); ! 627: if (sp->len==E_NOQB || sp->len==E_UMETA) { ! 628: printf("ignored\n"); ! 629: break; ! 630: } ! 631: kdireset(); ! 632: break; ! 633: ! 634: } ! 635: } ! 636: } ! 637: ! 638: kdiinit() ! 639: { ! 640: register struct device *kp = (struct device *)kmcdinfo[0]->ui_addr; ! 641: register i; ! 642: struct kmaddr ka; ! 643: static time_t kditime; ! 644: extern time_t time; ! 645: ! 646: /* close all open channels? */ ! 647: if (kditime+30 > time) ! 648: return(0); ! 649: kp->sts = 0; /* initialize KMC */ ! 650: if (kdiubad == 0) { ! 651: kdiubad = uballoc(kmcdinfo[0]->ui_ubanum, ! 652: (caddr_t)&k, sizeof(k), 0); ! 653: if (kdiubad == 0) ! 654: panic("UB AD 0 in kdiinit"); ! 655: } ! 656: k.kinit.cmdaddr = kmcaddr((caddr_t)k.cmd, (caddr_t)&k, kdiubad); ! 657: k.kinit.stataddr = kmcaddr((caddr_t)k.stat, (caddr_t)&k, kdiubad); ! 658: k.kinit.bufaddr = kmcaddr((caddr_t)k.kmcbuf, (caddr_t)&k, kdiubad); ! 659: ka = kmcaddr((caddr_t)&k.kinit, (caddr_t)&k, kdiubad); ! 660: kp->u.a.lo = ka.lo; ! 661: kp->u.a.hi = ka.hi; ! 662: kditime = time; ! 663: kp->sts = 1; /* start handshake */ ! 664: for (i = 0; i<100000; i++) { ! 665: if (kp->sts == 2) { ! 666: kdirint = kdiintr; ! 667: kdixint = kdiintr; ! 668: return(1); /* KMC is running OK */ ! 669: } ! 670: if (kp->sts == 3) { ! 671: printf("KMC entered state 3\n"); ! 672: return(0); ! 673: } ! 674: } ! 675: printf("KMC did not come ready\n"); ! 676: return(0); ! 677: } ! 678: ! 679: struct kmaddr ! 680: kmcaddr(memaddr, membase, ubbase) ! 681: caddr_t memaddr, membase, ubbase; ! 682: { ! 683: register struct kmaddr r; ! 684: register long a; ! 685: ! 686: a = (long)memaddr - (long)membase + ((long)ubbase & 0x03ffff); ! 687: r.hi = a >> 16; ! 688: r.lo = (u_short)a; ! 689: return(r); ! 690: } ! 691: ! 692: /* ! 693: * kmc reload ! 694: */ ! 695: kdireload() ! 696: { ! 697: kdiopened = 0; ! 698: kdmodp = 0; ! 699: kmcbad = 0; ! 700: } ! 701: ! 702: /* ! 703: * zap all open channels ! 704: */ ! 705: kdireset() ! 706: { ! 707: register struct kdi *kp; ! 708: ! 709: if (kdmodp==0) ! 710: return; ! 711: for (kp = kdi; kp < &kdi[NKDI]; kp++) { ! 712: register state = kdmodp->dkstate[kp->chan]; ! 713: if ((state==OPEN || state==LCLOSE) && kp->dkrq) { ! 714: flushq(WR(kp->dkrq), 1); ! 715: kdmodp->dkstate[kp->chan] = state==OPEN? RCLOSE: CLOSED; ! 716: putctl(kp->dkrq->next, M_HANGUP); ! 717: } ! 718: } ! 719: kmcbad = 1; ! 720: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.