|
|
1.1 ! root 1: #include "vx.h" ! 2: #if NVX > 0 ! 3: /* ! 4: * VIOC-X driver ! 5: */ ! 6: ! 7: #include "../h/param.h" ! 8: #include "../h/ioctl.h" ! 9: #include "../h/tty.h" ! 10: #include "../h/dir.h" ! 11: #include "../h/user.h" ! 12: #include "../h/map.h" ! 13: #include "../machine/pte.h" ! 14: #include "../h/buf.h" ! 15: #include "../vba/vbavar.h" ! 16: #include "../h/conf.h" ! 17: #include "../h/file.h" ! 18: #include "../h/uio.h" ! 19: #include "../vba/vioc.h" ! 20: #ifdef VXPERF ! 21: #include "../vba/scope.h" ! 22: #endif VXPERF ! 23: #include "vbsc.h" ! 24: #if NVBSC > 0 ! 25: #include "../bsc/bscio.h" ! 26: #include "../bsc/bsc.h" ! 27: char bscport[NVXPORTS]; ! 28: long bscno = 0; ! 29: #endif ! 30: ! 31: #ifdef BSC_DEBUG ! 32: #include "../bsc/bscdebug.h" ! 33: #endif ! 34: ! 35: #ifdef VX_DEBUG ! 36: long vxintr4 = 0; ! 37: long vxdebug = 0; ! 38: #include "../vba/vxdebug.h" ! 39: #endif ! 40: ! 41: #define RSPquals 1 ! 42: ! 43: struct vcx vcx[NVIOCX] ; ! 44: struct tty vx_tty[NVXPORTS]; ! 45: extern struct vcmds v_cmds[]; ! 46: extern long reinit; ! 47: ! 48: int vxstart() ; ! 49: int ttrstrt() ; ! 50: caddr_t vtoph(); ! 51: struct vxcmd *vobtain() ; ! 52: struct vxcmd *nextcmd() ; ! 53: ! 54: /* ! 55: * Driver information for auto-configuration stuff. ! 56: * (not tested and probably should be changed) ! 57: */ ! 58: int vxprobe(), vxattach(), vxrint(); ! 59: struct vba_device *vxinfo[NVIOCX]; ! 60: long vxstd[] = { 0 }; ! 61: struct vba_driver vxdriver = ! 62: { vxprobe, 0, vxattach, 0, vxstd, "VIOC ", vxinfo }; ! 63: ! 64: char vxtype[NVIOCX]; /* 0: viox-x/vioc-b; 1: vioc-bop */ ! 65: char vxbbno = -1; ! 66: char vxbopno[NVIOCX]; /* BOP board no. if indicated by vxtype[] */ ! 67: short vbtbl = -1; ! 68: extern vbrall(); ! 69: ! 70: ! 71: vxprobe(reg) ! 72: caddr_t reg; ! 73: { ! 74: register int br, cvec; ! 75: register struct vblok *vp = (struct vblok *)reg; ! 76: ! 77: #ifdef lint ! 78: br = 0; cvec = br; br = cvec; ! 79: #endif ! 80: ! 81: if(badaddr(vp, 1)) ! 82: return(0); ! 83: vp->v_fault = 0 ; ! 84: vp->v_vioc = V_BSY ; ! 85: vp->v_hdwre = V_RESET ; /* reset interrupt */ ! 86: ! 87: DELAY(4000000); ! 88: return ( vp->v_fault == VREADY); ! 89: } ! 90: ! 91: vxattach(ui) ! 92: register struct vba_device *ui; ! 93: { ! 94: VIOCBAS[ui->ui_unit] = ui->ui_addr; ! 95: vxinit(ui->ui_unit,1); ! 96: } ! 97: ! 98: /* ! 99: * Open a VX line. ! 100: */ ! 101: vxopen(dev, flag) ! 102: { ! 103: register struct tty *tp; /* pointer to tty struct for port */ ! 104: register struct vcx *xp; /* pointer to VIOC-X info/cmd buffer */ ! 105: register d; /* minor device number */ ! 106: register long jj; ! 107: ! 108: ! 109: d = minor(dev); /* get minor device number */ ! 110: if (d >= NVXPORTS) /* validate minor device number */ ! 111: return ENXIO; /* set errno to indicate bad port # */ ! 112: tp = &vx_tty[d]; /* index the tty structure for port */ ! 113: ! 114: xp = &vcx[d>>4]; /* index VIOC-X info/cmd area */ ! 115: d &= 017; ! 116: ! 117: /* If we did not find a board with the correct port number on ! 118: it, or the entry for the VIOC-X had no ports on it, inform the ! 119: caller that the port does not exist. */ ! 120: if(!( xp->v_loport <= d && d <= xp->v_hiport ) /* home? */ ! 121: || (xp->v_hiport - xp->v_loport)==0) ! 122: return ENXIO; /* bad minor device number */ ! 123: tp->t_addr = (caddr_t)xp; /* store address of VIOC-X info */ ! 124: tp->t_oproc = vxstart; /* store address of startup routine */ ! 125: tp->t_dev = dev; /* store major/minor device numbers */ ! 126: d = spl8(); ! 127: tp->t_state |= TS_WOPEN; /* mark device as waiting for open */ ! 128: if ((tp->t_state&TS_ISOPEN) == 0) /* is device already open? */ ! 129: { /* no, open it */ ! 130: ttychars(tp); /* set default control chars */ ! 131: if (tp->t_ispeed == 0) /* if no default speeds set them */ ! 132: { ! 133: tp->t_ispeed = SSPEED; /* default input baud */ ! 134: tp->t_ospeed = SSPEED; /* default output baud */ ! 135: tp->t_flags |= (ODDP|EVENP|ECHO); /* default modes */ ! 136: } ! 137: vxparam(dev); /* set parameters for this port */ ! 138: } ! 139: splx(d); ! 140: /* ? if already open for exclusive use open fails unless caller is ! 141: root. */ ! 142: if (tp->t_state&TS_XCLUDE && u.u_uid!=0) ! 143: return EBUSY; /* device is busy, sorry */ ! 144: ! 145: /* wait for data carrier detect to go high */ ! 146: d = spl8(); ! 147: if( !vcmodem(dev,VMOD_ON) ) ! 148: while( (tp->t_state&TS_CARR_ON) == 0 ) ! 149: sleep(&tp->t_canq,TTIPRI); ! 150: jj= (*linesw[tp->t_line].l_open)(dev,tp); /*let tty.c finish the open */ ! 151: splx(d); /* 1/2/85 : assures open complete */ ! 152: return (jj); ! 153: } ! 154: ! 155: /* ! 156: * Close a VX line. ! 157: */ ! 158: vxclose(dev, flag) ! 159: dev_t dev; ! 160: int flag; ! 161: { ! 162: register struct tty *tp; ! 163: register d; ! 164: ! 165: d = minor(dev) & 0377; ! 166: tp = &vx_tty[d]; ! 167: d = spl8(); ! 168: (*linesw[tp->t_line].l_close)(tp); ! 169: if ((tp->t_state&TS_ISOPEN) && (tp->t_state&TS_HUPCLS)) ! 170: if( !vcmodem(dev,VMOD_OFF) ) ! 171: tp->t_state &= ~TS_CARR_ON; ! 172: /* wait for the last response */ ! 173: while(tp->t_state & TS_FLUSH) ! 174: sleep( (caddr_t)&tp->t_state, TTOPRI ) ; ! 175: ttyclose(tp); /* let tty.c finish the close */ ! 176: splx(d); ! 177: } ! 178: ! 179: /* ! 180: * Read from a VX line. ! 181: */ ! 182: vxread(dev, uio) ! 183: dev_t dev; ! 184: struct uio *uio; ! 185: { ! 186: register struct tty *tp = &vx_tty[minor(dev) & 0377]; ! 187: return (*linesw[tp->t_line].l_read)(tp, uio); ! 188: } ! 189: ! 190: /* ! 191: * write on a VX line ! 192: */ ! 193: vxwrite(dev, uio) ! 194: dev_t dev; ! 195: struct uio *uio; ! 196: { ! 197: register struct tty *tp = &vx_tty[minor(dev) & 0377]; ! 198: return (*linesw[tp->t_line].l_write)(tp, uio); ! 199: } ! 200: ! 201: /* ! 202: * VIOCX unsolicited interrupt. ! 203: */ ! 204: vxrint(n) ! 205: register n; /* mux number */ ! 206: { ! 207: register struct tty *tp; ! 208: register struct vcx *xp; ! 209: register short *sp; ! 210: register struct vblok *kp; ! 211: register int i, c; ! 212: short *savsilo; ! 213: struct silo { ! 214: char data; ! 215: char port; ! 216: }; ! 217: ! 218: kp = VBAS(n); ! 219: xp = &vcx[n]; ! 220: #if VX_TESTING ! 221: c = kp->v_uqual&037; ! 222: if (vx_test&VX_PROC_ERR_DEBUG) ! 223: c = 2; ! 224: else if (vx_test&VX_UQUAL_ERR_DEBUG) ! 225: c = 5; ! 226: switch (c) { ! 227: #else ! 228: switch(kp->v_uqual&037) { ! 229: #endif ! 230: case 0: ! 231: break; ! 232: case 2: ! 233: printf(" ERR NBR %x\n",kp->v_ustat); ! 234: vpanic("vc: VC PROC ERR"); ! 235: vxstreset(n); ! 236: return(0); ! 237: case 3: ! 238: vcmintr(n); ! 239: return(1); ! 240: case 4: ! 241: return(1); ! 242: default: ! 243: printf(" ERR NBR %x\n",kp->v_uqual); ! 244: vpanic("vc: VC UQUAL ERR"); ! 245: vxstreset(n); ! 246: return(0); ! 247: } ! 248: if(xp->v_vers == V_NEW) { ! 249: register short *aa ; ! 250: aa = (short *)kp->v_usdata; ! 251: sp = (short *)(*aa + (char *)kp) ; ! 252: } else { ! 253: c = kp->v_usdata[0] << 6; ! 254: sp = (short *)((char *)kp + SILOBAS + c); ! 255: } ! 256: nextsilo: ! 257: i = *(savsilo = sp); ! 258: if (i == 0) return(1); ! 259: if(xp->v_vers == V_NEW) ! 260: if( i > xp->v_silosiz ) { ! 261: printf("vx: %d exceeds silo size\n",i) ; ! 262: i = xp->v_silosiz; ! 263: } ! 264: for(sp++;i > 0;i--,sp++) { ! 265: c = ((struct silo *)sp)->port & 017; ! 266: tp = &vx_tty[c+n*16]; ! 267: if(xp->v_loport > c || c > xp->v_hiport) ! 268: continue; /* port out of bounds */ ! 269: if( (tp->t_state & TS_ISOPEN) == 0) { ! 270: wakeup((caddr_t)&tp->t_rawq); ! 271: continue; ! 272: } ! 273: c = ((struct silo *)sp)->data; ! 274: switch(((struct silo *)sp)->port&(PERROR|FERROR)) { ! 275: case PERROR: ! 276: case PERROR|FERROR: ! 277: if( (tp->t_flags&(EVENP|ODDP)) == EVENP ! 278: || (tp->t_flags & (EVENP|ODDP)) == ODDP ) ! 279: continue; ! 280: if(!(((struct silo *)sp)->port&FERROR)) ! 281: break; ! 282: case FERROR: ! 283: if(tp->t_flags & RAW) c = 0; ! 284: else c = tp->t_intrc; ! 285: } ! 286: (*linesw[tp->t_line].l_rint)(c, tp); ! 287: } ! 288: *savsilo = 0; ! 289: return(1); ! 290: } ! 291: ! 292: /* ! 293: * stty/gtty for VX ! 294: */ ! 295: vxioctl(dev, cmd, data, flag) ! 296: int dev; /* major, minor device numbers */ ! 297: int cmd; /* command */ ! 298: caddr_t data; ! 299: int flag; ! 300: { ! 301: register struct tty *tp; ! 302: register error; ! 303: ! 304: tp = &vx_tty[minor(dev) & 0377]; ! 305: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); ! 306: if (error == 0) ! 307: return error; ! 308: if((error = ttioctl(tp, cmd, data, flag)) >= 0) ! 309: { ! 310: if (cmd==TIOCSETP||cmd==TIOCSETN) ! 311: vxparam(dev); ! 312: return error; ! 313: } else ! 314: return ENOTTY; ! 315: } ! 316: ! 317: ! 318: vxparam(dev) ! 319: dev_t dev; ! 320: { ! 321: vxcparam(dev, 1); ! 322: } ! 323: ! 324: /* ! 325: * Set parameters from open or stty into the VX hardware ! 326: * registers. ! 327: */ ! 328: vxcparam(dev, wait) ! 329: dev_t dev; /* major, minor device numbers */ ! 330: int wait; /* nonzero if we should wait for finish */ ! 331: { ! 332: register struct tty *tp; ! 333: register struct vcx *xp; ! 334: register struct vxcmd *cp; ! 335: register s; ! 336: ! 337: tp = &vx_tty[minor(dev)]; /* pointer to tty structure for port */ ! 338: xp = (struct vcx *)tp->t_addr; /* pointer to VIOCX info/cmd buffer */ ! 339: cp = vobtain(xp); ! 340: s = spl8(); ! 341: cp->cmd = LPARAX; /* set command to "load parameters" */ ! 342: cp->par[1] = minor(dev)&017; /* port number */ ! 343: ! 344: cp->par[2] = (tp->t_flags&RAW)? 0 : tp->t_startc; /* XON char */ ! 345: cp->par[3] = (tp->t_flags&RAW)? 0 : tp->t_stopc; /* XOFF char */ ! 346: ! 347: if(tp->t_flags&(RAW|LITOUT) || ! 348: (tp->t_flags&(EVENP|ODDP)) == (EVENP|ODDP)) { ! 349: cp->par[4] = 0xc0; /* 8 bits of data */ ! 350: cp->par[7] = 0; /* no parity */ ! 351: } else { ! 352: cp->par[4] = 0x40; /* 7 bits of data */ ! 353: if((tp->t_flags&(EVENP|ODDP)) == ODDP) ! 354: cp->par[7] = 1; /* odd parity */ ! 355: else if((tp->t_flags&(EVENP|ODDP)) == EVENP) ! 356: cp->par[7] = 3; /* even parity */ ! 357: else ! 358: cp->par[7] = 0; /* no parity */ ! 359: } ! 360: cp->par[5] = (tp->t_stopbits == 0) ? 4 : tp->t_stopbits; ! 361: cp->par[6] = tp->t_ospeed; ! 362: ! 363: if (vcmd(xp->v_nbr, &cp->cmd) && wait) ! 364: sleep(cp,TTIPRI); ! 365: splx(s); ! 366: } ! 367: ! 368: /* ! 369: * VIOCX command response interrupt. ! 370: * For transmission, restart output to any active port. ! 371: * For all other commands, just clean up. ! 372: */ ! 373: vxxint(n,cp) ! 374: register int n; /* VIOC number */ ! 375: register struct vxcmd *cp; /* command structure */ ! 376: { ! 377: register struct vxmit *vp, *pvp; ! 378: register struct tty *tp; ! 379: register struct vcx *xp; ! 380: register struct tty *hp; ! 381: register long port; ! 382: ! 383: xp = &vcx[n]; ! 384: cp = (struct vxcmd *)( (long *)cp - 1); ! 385: #if NVBSC > 0 ! 386: switch(cp->cmd) { ! 387: case MDMCTL1: case HUNTMD1: case LPARAX1: ! 388: vrelease(xp, cp); ! 389: wakeup(cp); ! 390: return; ! 391: } ! 392: #endif ! 393: switch(cp->cmd&0xff00) { ! 394: case LIDENT: /* initialization complete */ ! 395: if (xp->v_state & V_RESETTING) { ! 396: vxfnreset(n,cp); ! 397: vinthandl(n,((V_BSY | RSPquals) << 8) | V_INTR); ! 398: } ! 399: cp->cmd++; ! 400: return; ! 401: case XMITDTA: case XMITIMM: ! 402: break; ! 403: case LPARAX: ! 404: wakeup(cp); ! 405: default: /* MDMCTL or FDTATOX */ ! 406: vrelease(xp, cp); ! 407: if (xp->v_state & V_RESETTING) { ! 408: vinthandl(n,((V_BSY | RSPquals) << 8) | V_INTR); ! 409: } ! 410: return; ! 411: } ! 412: for(vp = (struct vxmit *)(cp->par + (cp->cmd & 07)*sizvxmit); ! 413: vp >= (struct vxmit *)cp->par; ! 414: vp = (struct vxmit *) ((char *)vp - sizvxmit) ) ! 415: { ! 416: tp = &vx_tty[(vp->line & 017)+n*16]; ! 417: ! 418: #if NVBSC > 0 ! 419: /* ======= BSC code ================ ! 420: */ ! 421: port = vp->line; ! 422: if (tp->t_line == LDISP) { ! 423: vrelease(xp, cp) ; ! 424: /* Call bsctxd with logical bscport no; 0,1..4,5 */ ! 425: /* v_xmtcnt was set to BISYNC ctlr no in vxinit() */ ! 426: bsctxd((xp->v_xmtcnt*NBSC)+port); ! 427: return ; ! 428: } ! 429: if (bscport[(n<<4)+port] == BISYNC) { ! 430: printf("\nvxxint: int. after line closed. (cmd:%lx)", ! 431: cp->cmd&0xff); ! 432: vrelease(xp, cp) ; ! 433: return ; ! 434: } ! 435: /* ================================== ! 436: */ ! 437: #endif ! 438: pvp = vp; ! 439: tp->t_state &= ~TS_BUSY; ! 440: if(tp->t_state & TS_FLUSH) { ! 441: tp->t_state &= ~TS_FLUSH; ! 442: wakeup( (caddr_t)&tp->t_state ) ; ! 443: } ! 444: else ! 445: ndflush(&tp->t_outq, vp->bcount+1); ! 446: } ! 447: xp->v_xmtcnt--; ! 448: vrelease(xp,cp); ! 449: if(xp->v_vers == V_NEW) { ! 450: vp = pvp; ! 451: xp->v_actport[(vp->line & 017) - xp->v_loport] |= 1 ; ! 452: if(vxstart(tp) && (cp = nextcmd(xp)) != NULL) ! 453: { ! 454: xp->v_xmtcnt++; ! 455: vcmd(n, &cp->cmd); ! 456: return ; ! 457: } ! 458: xp->v_actport[(vp->line & 017) - xp->v_loport] = 0 ; ! 459: return ; ! 460: } ! 461: xp->v_actflg = 1; ! 462: hp = &vx_tty[xp->v_hiport+n*16]; ! 463: for(tp = &vx_tty[xp->v_loport+n*16];tp <= hp;tp++) ! 464: if(vxstart(tp) && (cp = nextcmd(xp)) != NULL) ! 465: { ! 466: xp->v_xmtcnt++; ! 467: vcmd(n, &cp->cmd); ! 468: } ! 469: if( (cp = nextcmd(xp)) != NULL ) /* command to send ? */ ! 470: { ! 471: xp->v_xmtcnt++; ! 472: vcmd(n,&cp->cmd); ! 473: } ! 474: xp->v_actflg = 0; ! 475: } ! 476: ! 477: /* ! 478: * Force out partial XMIT command after timeout ! 479: */ ! 480: vxforce(xp) ! 481: register struct vcx *xp; ! 482: { ! 483: register struct vxcmd *cp; ! 484: register int s; ! 485: ! 486: s = spl8(); ! 487: if((cp = nextcmd(xp)) != NULL) { ! 488: xp->v_xmtcnt++; ! 489: vcmd(xp->v_nbr, &cp->cmd); ! 490: } ! 491: splx(s); ! 492: } ! 493: ! 494: /* ! 495: * Start (restart) transmission on the given VX line. ! 496: */ ! 497: vxstart(tp) ! 498: register struct tty *tp; ! 499: { ! 500: register short nch; ! 501: register struct vcx *xp; ! 502: register char *outb; ! 503: register full = 0; ! 504: int k, s, port; ! 505: ! 506: s = spl8(); ! 507: port = minor(tp->t_dev) & 017; ! 508: xp = (struct vcx *)tp->t_addr; ! 509: if (!(tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) { ! 510: if (tp->t_outq.c_cc<=TTLOWAT(tp)) { ! 511: if (tp->t_state&TS_ASLEEP) { ! 512: tp->t_state &= ~TS_ASLEEP; ! 513: wakeup((caddr_t)&tp->t_outq); ! 514: } ! 515: if (tp->t_wsel) { ! 516: selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); ! 517: tp->t_wsel = 0; ! 518: tp->t_state &= ~TS_WCOLL; ! 519: } ! 520: } ! 521: if(tp->t_outq.c_cc == 0) { ! 522: splx(s); ! 523: return(0); ! 524: } ! 525: #ifdef VXPERF ! 526: scope_out(3); ! 527: #endif VXPERF ! 528: if(!(tp->t_flags&(RAW|LITOUT))) ! 529: full = 0200; ! 530: if((nch = ndqb(&tp->t_outq, full)) == 0) { ! 531: if(full) { ! 532: nch = getc(&tp->t_outq); ! 533: timeout(ttrstrt, (caddr_t)tp, (nch&0177) +6); ! 534: tp->t_state |= TS_TIMEOUT; ! 535: full = 0; ! 536: } ! 537: } else { ! 538: outb = (char *)tp->t_outq.c_cf; ! 539: tp->t_state |= TS_BUSY; ! 540: if(xp->v_vers == V_NEW) ! 541: k = xp->v_actport[port - xp->v_loport] ; ! 542: else ! 543: k = xp->v_actflg ; ! 544: ! 545: full = vsetq(xp, port, outb, nch); ! 546: ! 547: if( (k&1) == 0 ) { /* not called from vxxint */ ! 548: if(full || xp->v_xmtcnt == 0) { ! 549: outb = (char *)(&nextcmd(xp)->cmd); ! 550: xp->v_xmtcnt++; ! 551: vcmd(xp->v_nbr, outb ); ! 552: } else ! 553: timeout(vxforce,xp,3); ! 554: } ! 555: } ! 556: } ! 557: splx(s); ! 558: return(full); /* indicate if max commands or not */ ! 559: } ! 560: ! 561: /* ! 562: * Stop output on a line. ! 563: */ ! 564: vxstop(tp) ! 565: register struct tty *tp; ! 566: { ! 567: register s; ! 568: ! 569: s = spl8(); ! 570: if (tp->t_state & TS_BUSY) { ! 571: if ((tp->t_state&TS_TTSTOP)==0) { ! 572: tp->t_state |= TS_FLUSH; ! 573: } ! 574: } ! 575: splx(s); ! 576: } ! 577: ! 578: /* ! 579: * VIOCX Initialization. Makes free lists of command buffers. ! 580: * Resets all viocx's. Issues a LIDENT command to each ! 581: * viocx which establishes interrupt vectors and logical ! 582: * port numbers ! 583: */ ! 584: vxinit(i,wait) ! 585: register int i; ! 586: long wait; ! 587: { ! 588: register struct vcx *xp; /* ptr to VIOC-X info/cmd buffer */ ! 589: register struct vblok *kp; /* pointer to VIOC-X control block */ ! 590: register struct vxcmd *cp; /* pointer to a command buffer */ ! 591: register char *resp; /* pointer to response buffer */ ! 592: register int j,ix; ! 593: register struct vcmds *cpp; ! 594: char type; ! 595: register struct bsc *bp; /* bsc change */ ! 596: extern struct bsc bsc[]; ! 597: ! 598: if (vbtbl) { ! 599: for(j=0;j<NVIOCX;j++) vxbopno[j] = (char)-1; ! 600: vbtbl = 0; ! 601: } ! 602: ! 603: kp = VBAS(i); /* get base adr of cntl blok for VIOC */ ! 604: ! 605: xp = &vcx[i]; /* index info/command buffers */ ! 606: cpp = &v_cmds[i]; ! 607: type = kp->v_ident; ! 608: vxtype[i] = 0; /* Type is Viox-x */ ! 609: switch(type) { ! 610: case VIOCX: ! 611: { ! 612: xp->v_vers = V_OLD ; ! 613: /* set DCD for printer ports */ ! 614: for(j = 0;j < 16;j++) ! 615: if (kp->v_portyp[j] == 4 ) ! 616: kp->v_dcd |= 1 << j ; ! 617: } ! 618: break ; ! 619: case NWVIOCX: ! 620: { ! 621: xp->v_vers = V_NEW ; ! 622: xp->v_silosiz = kp->v_maxsilo ; ! 623: /* set DCD for printer ports */ ! 624: for(j = 0;j < 16;j++) ! 625: if (kp->v_portyp[j] == 4 ) ! 626: kp->v_dcd |= 1 << j ; ! 627: } ! 628: break ; ! 629: case PVIOCX: ! 630: xp->v_vers = V_OLD ; ! 631: break ; ! 632: case NPVIOCX: ! 633: xp->v_vers = V_NEW ; ! 634: xp->v_silosiz = kp->v_maxsilo ; ! 635: break ; ! 636: #ifdef VIOCB ! 637: case VIOCB: /* old f/w, Bisync board */ ! 638: if (wait) /* Just boot up */ ! 639: if (bscno >= MXVIOC_B) { ! 640: printf("\nvxinit: exceed max no of VIOC-B:%ld", ! 641: MXVIOC_B); ! 642: break; ! 643: } ! 644: printf("(kp:%lx)(xp:%lx): %lx---%x OLD VIOC-B, ", ! 645: (long)kp, (long)xp,(int)kp->v_ident, ! 646: (int)kp->v_fault); ! 647: xp->v_vers = V_OLD ; ! 648: /* save device specific info */ ! 649: /*for(bp = &bsc[0]; bp <= &bsc[NBSC-1]; bp++) ! 650: bp->b_devregs = (caddr_t)xp ; ! 651: */ ! 652: ! 653: if (wait) /* Use v_xmtcnt to */ ! 654: xp->v_xmtcnt = (char)bscno; /* save VIOC-B ctlrno */ ! 655: else bscno = (long)xp->v_xmtcnt & 0x7f; ! 656: ! 657: bp = &bsc[0+(bscno*4)]; ! 658: for(ix=0;ix<4;ix++,bp++) ! 659: bp->b_devregs = (caddr_t)xp ; ! 660: bscno++; ! 661: bscport[(i*16)+0] = BISYNC; ! 662: bscport[(i*16)+1] = BISYNC; ! 663: bscport[(i*16)+2] = BISYNC; ! 664: bscport[(i*16)+3] = BISYNC; ! 665: printf(",BSC no %d initialized.\n",bscno-1); ! 666: break ; ! 667: #endif ! 668: ! 669: #ifdef NWVIOCB ! 670: case NWVIOCB: /* new f/w, Bisync board */ ! 671: if (wait) /* Just boot up */ ! 672: if (bscno >= MXVIOC_B) { ! 673: printf("\nvxinit: exceed max no of VIOC-B:%ld", ! 674: MXVIOC_B); ! 675: break; ! 676: } ! 677: printf("(kp:%lx)(xp:%lx): %lx---%x 16K VIOC-B", ! 678: (long)kp, (long)xp,(int)kp->v_ident, ! 679: (int)kp->v_fault); ! 680: xp->v_vers = V_NEW ; ! 681: xp->v_silosiz = kp->v_maxsilo ; ! 682: /* save device specific info */ ! 683: ! 684: if (wait) /* Use v_xmtcnt to */ ! 685: xp->v_xmtcnt = (char)bscno; /* save VIOC-B ctlrno */ ! 686: else bscno = (long)xp->v_xmtcnt & 0x7f; ! 687: ! 688: bp = &bsc[bscno*4]; ! 689: for(ix=0;ix<4;ix++,bp++) ! 690: bp->b_devregs = (caddr_t)xp ; ! 691: bscno++; ! 692: bscport[(i*16)+0] = BISYNC; ! 693: bscport[(i*16)+1] = BISYNC; ! 694: bscport[(i*16)+2] = BISYNC; ! 695: bscport[(i*16)+3] = BISYNC; ! 696: printf(",BSC no %d initialized.\n",bscno-1); ! 697: if(CBSIZE > kp->v_maxxmt) ! 698: printf("vxinit: Warning CBSIZE > maxxmt\n") ; ! 699: break ; ! 700: #endif ! 701: case VBOPID: /* VIOC-BOP */ ! 702: vxbbno++; ! 703: vxtype[i] = 1; ! 704: vxbopno[i] = vxbbno; ! 705: printf("VIOC-BOP no. %d at %lx\n",vxbopno[i],VIOCBAS[i]); ! 706: default: ! 707: return ; /* Not a viocx type */ ! 708: } ! 709: xp->v_nbr = -1; /* no number for it yet */ ! 710: xp->v_maxcmd = xp->v_vers == V_NEW ? 24 : 4; ! 711: ! 712: for(j=0; j<NVCXBUFS; j++) /* init all cmd buffers */ ! 713: { ! 714: cp = &xp->vx_lst[j]; /* index a buffer */ ! 715: cp->c_fwd = &xp->vx_lst[j+1]; /* point to next buf */ ! 716: } ! 717: xp->vx_avail = &xp->vx_lst[0]; /* set idx to 1st free buf */ ! 718: cp->c_fwd = (struct vxcmd *)0; /* mark last buf in free list */ ! 719: ! 720: cp = vobtain(xp); /* grap the control block */ ! 721: cp->cmd = LIDENT; /* set command type */ ! 722: cp->par[0] = i * 4 + VCVECT; /* ack vector */ ! 723: cp->par[1] = cp->par[0] + 1; /* cmd resp vector */ ! 724: cp->par[3] = cp->par[0] + 2; /* unsol intr vector */ ! 725: cp->par[4] = 15; /* max ports, no longer used */ ! 726: cp->par[5] = 0; /* set 1st port number */ ! 727: vcmd(i, &cp->cmd); /* initialize the VIOC-X */ ! 728: ! 729: if (!wait) return; ! 730: while(cp->cmd == LIDENT); /* wait for command completion */ ! 731: ! 732: /* calculate address of response buffer */ ! 733: resp = (char *)kp; ! 734: resp += kp->v_rspoff & 0x3FFF; ! 735: ! 736: if(resp[0] != 0 && (resp[0]&0177) != 3) /* did init work? */ ! 737: { ! 738: vrelease(xp,cp); /* init failed */ ! 739: return; /* try next VIOC-X */ ! 740: } ! 741: ! 742: xp->v_loport = cp->par[5]; /* save low port number */ ! 743: xp->v_hiport = cp->par[7];/* VIOC knows high port numbr */ ! 744: vrelease(xp,cp); /* done with this control block */ ! 745: xp->v_nbr = i; /* assign VIOC-X board number */ ! 746: } ! 747: ! 748: /* ! 749: * Obtain a command buffer ! 750: */ ! 751: struct vxcmd * ! 752: vobtain(xp) ! 753: register struct vcx *xp; ! 754: { ! 755: ! 756: register struct vxcmd *p; ! 757: register s; ! 758: ! 759: s = spl8(); ! 760: p = xp->vx_avail; ! 761: if(p == (struct vxcmd *)0) { ! 762: #ifdef VX_DEBUG ! 763: if (vxintr4 & VXNOBUF) vxintr4 &= ~VXNOBUF; ! 764: #endif ! 765: vpanic("vx: no buffs"); ! 766: vxstreset(xp - vcx); ! 767: splx(s); ! 768: return(vobtain(xp)); ! 769: } ! 770: xp->vx_avail = (xp->vx_avail)->c_fwd; ! 771: splx(s); ! 772: return( (struct vxcmd *)p); ! 773: } ! 774: ! 775: /* ! 776: * Release a command buffer ! 777: */ ! 778: vrelease(xp,cp) ! 779: register struct vcx *xp; ! 780: register struct vxcmd *cp; ! 781: { ! 782: ! 783: register s; ! 784: ! 785: #ifdef VX_DEBUG ! 786: if (vxintr4 & VXNOBUF) return; ! 787: #endif ! 788: s = spl8(); ! 789: cp->c_fwd = xp->vx_avail; ! 790: xp->vx_avail = cp; ! 791: splx(s); ! 792: } ! 793: ! 794: /* ! 795: * vxcmd - ! 796: * ! 797: */ ! 798: struct vxcmd * ! 799: nextcmd(xp) ! 800: register struct vcx *xp; ! 801: { ! 802: register struct vxcmd *cp; ! 803: register int s; ! 804: ! 805: s = spl8(); ! 806: cp = xp->vx_build; ! 807: xp->vx_build = (struct vxcmd *)0; ! 808: splx(s); ! 809: return(cp); ! 810: } ! 811: ! 812: /* ! 813: * assemble transmits into a multiple command. ! 814: * up to 8 transmits to 8 lines can be assembled together ! 815: */ ! 816: vsetq(xp ,d ,addr, cnt) ! 817: register struct vcx *xp; ! 818: caddr_t addr; ! 819: { ! 820: ! 821: register struct vxcmd *cp; ! 822: register struct vxmit *mp; ! 823: register char *p; ! 824: register i; ! 825: ! 826: cp = xp->vx_build; ! 827: if(cp == (struct vxcmd *)0) { ! 828: cp = vobtain(xp); ! 829: xp->vx_build = cp; ! 830: cp->cmd = XMITDTA; ! 831: } else { ! 832: if((cp->cmd & 07) == 07) { ! 833: vpanic("vx: vsetq overflow"); ! 834: vxstreset(xp->v_nbr); ! 835: return(0); ! 836: } ! 837: cp->cmd++; ! 838: } ! 839: ! 840: mp = (struct vxmit *)(cp->par + (cp->cmd & 07)*sizvxmit); ! 841: mp->bcount = cnt-1; ! 842: ! 843: mp->line = d; ! 844: if((xp->v_vers == V_NEW) && (cnt <= 6)) { ! 845: cp->cmd = XMITIMM ; ! 846: p = addr; ! 847: /* bcopy(addr, &(char *)mp->ostream, cnt) ; */ ! 848: } else { ! 849: addr = vtoph(0, (caddr_t)addr) ; /* should be a sys address */ ! 850: p = (char *)&addr; ! 851: cnt = sizeof addr; ! 852: /* mp->ostream = addr ; */ ! 853: } ! 854: for(i=0; i<cnt; i++) ! 855: mp->ostream[i] = *p++; ! 856: if(xp->v_vers == V_NEW) ! 857: return(1) ; ! 858: else ! 859: return((cp->cmd&07) == 7) ; /* Indicate if full */ ! 860: } ! 861: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.