--- cci/sys/vba/vcc.c 2019/07/28 12:24:19 1.1 +++ cci/sys/vba/vcc.c 2019/07/28 12:30:09 1.1.1.2 @@ -11,7 +11,6 @@ #include "../h/time.h" #include "../h/kernel.h" #include "../vba/vioc.h" -#include "../sna/snadebug.h" #ifdef VXPERF #include "../vba/scope.h" #endif VXPERF @@ -20,10 +19,9 @@ #define RSPquals 1 #define UNSquals 2 -long reinit = 0; -extern struct vcx vcx[] ; -extern struct tty vx_tty[]; -struct vcmds v_cmds[NVIOCX] ; +extern struct vcx vcx[]; +extern struct tty vx_tty[]; +struct vcmds v_cmds[NVIOCX]; extern char vxtype[]; extern char vxbbno; @@ -35,27 +33,21 @@ extern vbrall(); vbrall() {}; #endif -extern struct vxcmd *vobtain(); - -#ifdef VX_DEBUG -#include "../vba/vxdebug.h" -#endif - /* * Write a command out to the VIOC */ vcmd(n, cmdad) -register int n ; -register caddr_t cmdad ; /* command address */ +register int n; +register caddr_t cmdad; /* command address */ { - - register struct vcmds *cp ; + register struct vcmds *cp; register struct vcx *xp; - int s ; + int s; - s = spl8() ; - cp = &v_cmds[n] ; + s = spl8(); + cp = &v_cmds[n]; xp = &vcx[n]; + if (xp->v_state&V_RESETTING && cmdad != NULL) { /* * When the vioc is resetting, don't process @@ -69,26 +61,24 @@ register caddr_t cmdad ; /* command add } } if (cmdad != (caddr_t) 0) { -#ifdef VX_DEBUG - if ((*((short *)cmdad) == FDTATOX) && (vxdebug & VXVCC)) - printf("vcmd: FDTATOX queued to VIOC%d\n",n); -#endif - cp->cmdbuf[cp->v_fill] = cmdad ; - if( ++cp->v_fill >= VC_CMDBUFL ) cp->v_fill = 0 ; - if(cp->v_fill == cp->v_empty) { - vpanic("vc: CMD Q OVFLO") ; + cp->cmdbuf[cp->v_fill] = cmdad; + if (++cp->v_fill >= VC_CMDBUFL) + cp->v_fill = 0; + if (cp->v_fill == cp->v_empty) { + vpanic("vc: CMD Q OVFLO"); vxstreset(n); splx(s); return(0); } cp->v_cmdsem++; } - if(cp->v_cmdsem && cp->v_curcnt < vcx[n].v_maxcmd) { + if (cp->v_cmdsem && cp->v_curcnt < vcx[n].v_maxcmd) { cp->v_cmdsem--; cp->v_curcnt++; - vinthandl(n, ((V_BSY | CMDquals) << 8) | V_INTR ) ; + vinthandl(n, ((V_BSY | CMDquals) << 8) | V_INTR); } - splx(s) ; + splx(s); + return(1); } /* @@ -97,56 +87,44 @@ register caddr_t cmdad ; /* command add * current commands being executed. */ vackint(n) -register n ; /* VIOC number */ +register int n; /* VIOC number */ { - - register struct vblok *vp ; - register struct vcmds *cp ; - register s; + register struct vblok *vp; + register struct vcmds *cp; + register int s; #ifdef VXPERF scope_out(5); #endif VXPERF - if (vxtype[n]) { /* Its a BOP */ - vbrall(n); /* Int. from BOP, port 0 */ + + if (vxtype[n]) { /* It is a BOP */ + vbrall(n); /* Int. from BOP, port 0 */ return; } + s = spl8(); - vp = VBAS(n) ; - cp = &v_cmds[n] ; - if( vp->v_vcid & V_ERR ) { + vp = VBAS(n); + cp = &v_cmds[n]; + if (vp->v_vcid&V_ERR) { register char *resp; register i; - printf ("INTR ERR type = %x VIOC = %x, v_dcd: %lx\n", - vp->v_vcid & 07, n, vp->v_dcd & 0xff); - /* resp = (char *)vp + (vp->v_rspoff & 0x7FFF); */ - resp = (char *)(&vcx[n])->v_mricmd; - for(i=0; i<16; i++) + printf("INTR ERR type = %x VIOC = %x\n", vp->v_vcid&07, n); + resp = (char *)vp + (vp->v_rspoff&0x7FFF); + for (i = 0; i < 16; i++) printf("%x ", resp[i]&0xff); - vpanic( "\nvcc: vackint") ; - splx(s); + vpanic("\nvcc: vackint"); vxstreset(n); - return ; - } else - if((vp->v_hdwre&017) == CMDquals) { -#ifdef VX_DEBUG - if (vxintr4 & VXERR4) { /* causes VIOC INTR ERR 4 */ - register struct vxcmd *cp1; - register struct vxcmd *cp0 = (struct vxcmd *) - ((long)cp->cmdbuf[cp->v_empty] - 4); - if ((cp0->cmd == XMITDTA) || (cp0->cmd == XMITIMM)) { - cp1 = vobtain(&vcx[n]); - *cp1 = *cp0; - vxintr4 &= ~VXERR4; - vcmd(n,&cp1->cmd); - } - } -#endif - cp->v_curcmd[vp->v_vcid & VCMDLEN-1] = cp->cmdbuf[cp->v_empty] ; - if( ++cp->v_empty >= VC_CMDBUFL ) cp->v_empty = 0 ; + splx(s); + return; } - if( ++cp->v_itrempt >= VC_IQLEN ) cp->v_itrempt = 0 ; - vintempt(n) ; + if ((vp->v_hdwre&017) == CMDquals) { + cp->v_curcmd[vp->v_vcid&VCMDLEN-1] = cp->cmdbuf[cp->v_empty]; + if (++cp->v_empty >= VC_CMDBUFL) + cp->v_empty = 0; + } + if (++cp->v_itrempt >= VC_IQLEN) + cp->v_itrempt = 0; + vintempt(n); splx(s); vcmd(n, 0); /* queue next cmd, if any */ } @@ -157,92 +135,96 @@ register n ; /* VIOC number */ * the appropriate device driver . */ vcmdrsp(n) -register n ; +register int n; { - - register struct vblok *vp ; - register struct vcmds *cp ; - register caddr_t cmd ; - register char *resp ; - register k ; - register int s ; + register struct vblok *vp; + register struct vcmds *cp; + register caddr_t cmd; + register char *resp; + register int k, s; #ifdef VXPERF scope_out(6); #endif VXPERF + if (vxtype[n]) { /* Its a BOP */ - printf("vcmdrsp: stray interrupt from BOP at VIOC%d...\n",n); + printf("vcmdrsp: stray interrupt from BOP at VIOC%d...\n", n); return; } s = spl8(); - vp = VBAS(n) ; - cp = &v_cmds[n] ; + vp = VBAS(n); + + cp = &v_cmds[n]; resp = (char *)vp; - resp += vp->v_rspoff & 0x7FFF; + resp += vp->v_rspoff&0x7FFF; if ( #if VX_TESTING - (vx_test&VX_CMDRESP_DEBUG) == 0 && + (vx_test&VX_CMDRESP_DEBUG) == 0 && #endif - (k=resp[1]) & V_UNBSY ) { + (k=resp[1])&V_UNBSY) { k &= VCMDLEN-1; cmd = cp->v_curcmd[k]; cp->v_curcmd[k] = (caddr_t)0; cp->v_curcnt--; k = *((short *)&resp[4]); /* cmd operation code */ - if((k & 0xFF00) == LIDENT) { /* want hiport number */ - for(k=0; kv_state == V_RESETTING) return; + vxxint(n, cmd); } else { - vpanic( "vc, cmdresp debug") ; - splx(s); + vpanic("vc, cmdresp debug"); vxstreset(n); + splx(s); return; } - vinthandl(n, ( (V_BSY | RSPquals) << 8 ) | V_INTR ) ; + vinthandl(n, ((V_BSY | RSPquals) << 8) | V_INTR); splx(s); } - /* * Unsolicited interrupt. */ vunsol(n) -register(n) ; +register int n; { - - register struct vblok *vp ; - register s; + register struct vblok *vp; + register int s; #ifdef VXPERF scope_out(1); #endif VXPERF + if (vxtype[n]) { /* Its a BOP */ - printf("vunsol: stray interrupt from BOP at VIOC%d...\n",n); + printf("vunsol: stray interrupt from BOP at VIOC%d...\n", n); return; } s = spl8(); - vp = VBAS(n) ; + vp = VBAS(n); + if (vp == 0) { + printf("vunsol: stray interrupt from VIOC%d...\n", n); + splx(s); + return; + } + if ( #if VX_TESTING (vx_test&VX_UNSOL_INT_DEBUG) == 0 && #endif - vp->v_uqual & V_UNBSY) { + vp->v_uqual&V_UNBSY) { if (vxrint(n)) - vinthandl(n, ( (V_BSY | UNSquals) << 8 ) | V_INTR ) ; + vinthandl(n, ((V_BSY | UNSquals) << 8) | V_INTR); splx(s); } else { - vpanic("vc: UNSOL INT ERR") ; - splx(s); + vpanic("vc: UNSOL INT ERR"); vxstreset(n); + splx(s); } } @@ -250,99 +232,119 @@ register(n) ; * Enqueue an interrupt */ vinthandl(n, item) -register int n ; -register item ; +register int n, item; { + register struct vcmds *cp; + register int empflag = 0; - register struct vcmds *cp ; - register int empflag = 0 ; - - cp = &v_cmds[n] ; - if( cp->v_itrfill == cp->v_itrempt ) empflag++ ; - cp->v_itrqueu[cp->v_itrfill] = item ; - if( ++cp->v_itrfill >= VC_IQLEN ) cp->v_itrfill = 0 ; - if(cp->v_itrfill == cp->v_itrempt) { - vpanic( "vc: INT Q OVFLO" ) ; + cp = &v_cmds[n]; + if (cp->v_itrfill == cp->v_itrempt) + empflag++; + cp->v_itrqueu[cp->v_itrfill] = item; + if (++cp->v_itrfill >= VC_IQLEN) + cp->v_itrfill = 0; + if (cp->v_itrfill == cp->v_itrempt) { + vpanic("vc: INT Q OVFLO"); vxstreset(n); - } - else if( empflag ) vintempt(n) ; + } else if (empflag) + vintempt(n); } vintempt(n) -register int n ; +register int n; { - register struct vcmds *cp ; - register struct vblok *vp ; - register short item ; - register short *intr ; - - vp = VBAS(n) ; - if(vp->v_vioc & V_BSY) return ; - cp = &v_cmds[n] ; - if(cp->v_itrempt == cp->v_itrfill) return ; - item = cp->v_itrqueu[cp->v_itrempt] ; - intr = (short *)&vp->v_vioc ; - switch( (item >> 8) & 03 ) { + register struct vcmds *cp; + register struct vblok *vp; + register short item, *intr; + vp = VBAS(n); + if (vp->v_vioc&V_BSY) + return; + cp = &v_cmds[n]; + if (cp->v_itrempt == cp->v_itrfill) + return; + item = cp->v_itrqueu[cp->v_itrempt]; + intr = (short *)&vp->v_vioc; + switch ((item >> 8)&03) { case CMDquals: /* command */ { int phys; - if(cp->v_empty == cp->v_fill || vp->v_vcbsy&V_BSY) + if (cp->v_empty == cp->v_fill || vp->v_vcbsy&V_BSY) break; - (&vcx[n])->v_mricmd = (caddr_t)cp->cmdbuf[cp->v_empty]; - phys = vtoph(0, cp->cmdbuf[cp->v_empty]) ; /* should be a sys address */ + phys = vtoph(0, cp->cmdbuf[cp->v_empty]); /* should be a sys address */ vp->v_vcp[0] = ((short *)&phys)[0]; vp->v_vcp[1] = ((short *)&phys)[1]; - vp->v_vcbsy = V_BSY ; - *intr = item ; + vp->v_vcbsy = V_BSY; + *intr = item; } #ifdef VXPERF scope_out(4); #endif VXPERF - break ; + break; case RSPquals: /* command response */ - *intr = item ; + *intr = item; #ifdef VXPERF scope_out(7); #endif VXPERF - break ; + break; case UNSquals: /* unsolicited interrupt */ - vp->v_uqual = 0 ; - *intr = item ; + vp->v_uqual = 0; + *intr = item; #ifdef VXPERF scope_out(2); #endif VXPERF - break ; + break; } } +struct viocdump viocdump; /* contents of VIOC memory prior to reset */ /* start a reset on a vioc after error (hopefully) */ vxstreset(n) - register n; +register int n; { register struct vcx *xp; - register struct vblok *vp ; + register struct vblok *vp; register struct vxcmd *cp; + register short *src, *dst, *end; register int j; extern int vxinreset(); - int s ; + int s; - s = spl8() ; + s = spl8(); vp = VBAS(n); xp = &vcx[n]; #if VX_TESTING vx_test = 0; #endif - if (xp->v_state&V_RESETTING) + if (xp->v_state&V_RESETTING) { /* * Avoid infinite recursion. */ + splx(s); return; + } + + /* + * Dump the VIOC memory -- important we do it as shorts. + */ + src = (short *)vp; + dst = (short *)viocdump.vxcore; + end = (short *)((char *)viocdump.vxcore + sizeof(viocdump.vxcore)); + while (dst < end) + *dst++ = *src++; + + /* + * Note the time so we may correlate console messages + * with the vioc dump. + */ + viocdump.vxtime = time.tv_sec; + viocdump.vxn = n; + viocdump.vxmagic = VIOCDMAGIC; /* * Zero out the vioc structures, mark the vioc as being @@ -358,19 +360,18 @@ vxstreset(n) * be passed to the VIOC. */ xp->v_state |= V_RESETTING; - for(j=0; jvx_lst[j]; /* index a buffer */ cp->c_fwd = &xp->vx_lst[j+1]; /* point to next buf */ } xp->vx_avail = &xp->vx_lst[0]; /* set idx to 1st free buf */ cp->c_fwd = (struct vxcmd *)0; /* mark last buf in free list */ - printf("resetting VIOC %x .. ", n); + printf("resetting VIOC %x at %x .. ", n, viocdump.vxtime); - vp->v_fault = 0 ; - vp->v_vioc = V_BSY ; - vp->v_hdwre = V_RESET ; /* reset interrupt */ + vp->v_fault = 0; + vp->v_vioc = V_BSY; + vp->v_hdwre = V_RESET; /* reset interrupt */ timeout(vxinreset, (caddr_t)n, hz*5); splx(s); @@ -382,10 +383,9 @@ vxinreset(vioc) caddr_t vioc; { register struct vcx *xp; - register struct vblok *vp ; + register struct vblok *vp; register int n = (int)vioc; int s = spl8(); -printf("vxinreset "); vp = VBAS(n); xp = &vcx[n]; @@ -409,9 +409,6 @@ printf("vxinreset "); /* * Restore modem control, parameters and restart output. - * Since the vioc can handle no more then 24 commands at a time - * and we could generate as many as 48 commands, we must do this in - * phases, issuing no more then 16 commands at a time. */ /* finish the reset on the vioc after an error (hopefully) */ vxfnreset(n, cp) @@ -419,117 +416,90 @@ register int n; register struct vxcmd *cp; { register struct vcx *xp; - register struct vblok *vp ; - register struct tty *tp; + register struct vblok *vp; + register struct tty *tp, *tp0; register int i; register int on; - extern int vxrestart(); int s = spl8(); -printf("vxfnreset "); vp = VBAS(n); xp = &vcx[n]; xp->v_loport = cp->par[5]; /* save low port number */ - xp->v_hiport = cp->par[7];/* VIOC knows high port numbr */ - vrelease(xp,cp); /* done with this control block */ - xp->v_nbr = n; /* assign VIOC-X board number */ + xp->v_hiport = cp->par[7]; /* VIOC knows high port numbr */ + vrelease(xp, cp); /* done with this control block */ + xp->v_nbr = n; /* assign VIOC-X board number */ xp->v_state &= ~V_RESETTING; - vp->v_vcid = 0; /* + * Wakeup up anyone waiting for the reset (LIDENT) to complete. + */ + wakeup((caddr_t)&xp->v_state); + + /* * Restore modem information and control. */ - for(i=xp->v_loport; i<=xp->v_hiport; i++) { - tp = &vx_tty[i+n*16]; - if (tp->t_state&(TS_ISOPEN|TS_WOPEN)) { - tp->t_state &= ~TS_CARR_ON; - vcmodem(tp->t_dev, VMOD_ON); - if (tp->t_state&TS_CARR_ON) { - wakeup((caddr_t)&tp->t_canq) ; - } - else { - if(tp->t_state & TS_ISOPEN) { - ttyflush(tp, FREAD|FWRITE); - if(tp->t_state&TS_FLUSH) - wakeup((caddr_t)&tp->t_state) ; - if((tp->t_flags&NOHANG)==0) { - gsignal(tp->t_pgrp, SIGHUP) ; - gsignal(tp->t_pgrp, SIGCONT); - } - } - } - } + tp0 = &vx_tty[n<<4]; + for (i = xp->v_loport; i <= xp->v_hiport; i++) { + tp = tp0 + i; + if ((tp->t_state&(TS_ISOPEN|TS_WOPEN)) == 0) + /* + * Nobody cares about this line. + */ + continue; + /* + * Reset modem signals and set parameters + */ + tp->t_state &= ~TS_CARR_ON; + vcmodem(tp->t_dev, VMOD_ON); + vxcparam(tp->t_dev, 0); + /* * If carrier has changed while we were resetting, * take appropriate action. */ -/* - on = vp->v_dcd & 1<t_state&TS_CARR_ON) == 0) { - tp->t_state |= TS_CARR_ON ; - wakeup((caddr_t)&tp->t_canq) ; + on = vp->v_dcd&1<t_state&TS_CARR_ON) == 0) { + /* + * Carrier has come on. + */ + tp->t_state |= TS_CARR_ON; + wakeup((caddr_t)&tp->t_canq); } else if (!on && tp->t_state&TS_CARR_ON) { - tp->t_state &= ~TS_CARR_ON ; - if(tp->t_state & TS_ISOPEN) { + /* + * Carrier has gone off. + */ + tp->t_state &= ~TS_CARR_ON; + if (tp->t_state&TS_ISOPEN) { ttyflush(tp, FREAD|FWRITE); - if(tp->t_state&TS_FLUSH) - wakeup((caddr_t)&tp->t_state) ; - if((tp->t_flags&NOHANG)==0) { - gsignal(tp->t_pgrp, SIGHUP) ; + if (tp->t_state&TS_FLUSH) + wakeup((caddr_t)&tp->t_state); + if ((tp->t_flags&NOHANG)==0) { + gsignal(tp->t_pgrp, SIGHUP); gsignal(tp->t_pgrp, SIGCONT); } } } -*/ - } - xp->v_state |= V_RESETTING; - - timeout(vxrestart, (caddr_t)n, hz); - splx(s); -} - -/* - * Restore a particular aspect of the VIOC. - */ -vxrestart(vioc) -caddr_t vioc; -{ - register struct tty *tp, *tp0; - register struct vcx *xp; - register int i, cnt; - register int n = (int)vioc; - int s = spl8(); - - cnt = n>>8; -printf("vxrestart %d ",cnt); - n &= 0xff; - - tp0 = &vx_tty[n*16]; - xp = &vcx[n]; - - xp->v_state &= ~V_RESETTING; - - for(i=xp->v_loport; i<=xp->v_hiport; i++) { - tp = tp0 + i; - if (cnt != 0) { - tp->t_state &= ~(TS_BUSY|TS_TIMEOUT); - if(tp->t_state&(TS_ISOPEN|TS_WOPEN)) /* restart pending output */ - vxstart(tp); - } else { - if (tp->t_state&(TS_WOPEN|TS_ISOPEN)) - vxcparam(tp->t_dev, 0); + /* + * If anyone is awaiting a transmission interrupt, + * wake them up. + */ + if (tp->t_state&TS_ASLEEP) { + tp->t_state &= ~TS_ASLEEP; + wakeup((caddr_t)&tp->t_outq); } - } - if (cnt == 0) { - xp->v_state |= V_RESETTING; - timeout(vxrestart, (caddr_t)(n + 1*256), hz); - } else - printf("done\n"); + /* + * Restart pending output. + */ + tp->t_state &= ~(TS_BUSY|TS_TIMEOUT); + if (tp->t_state&(TS_ISOPEN|TS_WOPEN)) + vxstart(tp); + } + printf("done\n"); splx(s); } @@ -551,4 +521,3 @@ register int n; return(0); /* completes asynchronously */ } #endif -