Annotation of cci/d/pits/vioc.c, revision 1.1

1.1     ! root        1: #include "vioc.h"
        !             2: #include "conf.h"
        !             3: #include "const.h"
        !             4: #include "pte.h"
        !             5: 
        !             6: #define  MAXPORT       16
        !             7: #define  MAXRLEN       50
        !             8: #define  MAXSLEN       256
        !             9: #define  NL            writec('\n')
        !            10: #define  STAR          writes(" ***");
        !            11: 
        !            12: /*             Pointers to VIOC structures in I/O space        */
        !            13: struct vblok *VP;                      /* Pointer to common buffer */
        !            14: struct cmd_inp cblok;                  /* VIOC command block (from HOST) */
        !            15: struct cmd_res *rblok;                 /* PTR to CMD respond blk (from VIOC) */
        !            16: 
        !            17: short *s_entry;
        !            18: short cmdrsp[MAXRLEN];
        !            19: 
        !            20: long viocb[NVIOC];                      /* vioc buffer's address */
        !            21: long vioctype[NVIOC];                   /* viocs type */
        !            22: long msg_on = 1;                       /* Global flag to enable messages */
        !            23: long cmd_id = 0;
        !            24: long IObase;                           /* Virtual Address of VIOC base */
        !            25: long vioc_ack, vioc_rsp;
        !            26: long log_first = 1;                    /* Logical port no. of 1st terminal */
        !            27: long log_last = 0;                     /* Logical port no. of last terminal */
        !            28: init_flg = 0;
        !            29: char port_on[MAXPORT];
        !            30: extern long savvec3, unused, clk_cnt, proc_no;
        !            31: 
        !            32: vioc() 
        !            33: {      register long ix;
        !            34:        long vnum;
        !            35: 
        !            36:        for (ix=vnum=0; ix < NVIOC ; ix++)  {
        !            37:            if (viocb[ix]) 
        !            38:               if (vioc_diag(ix,vnum)) {
        !            39:                    v_ex(ix);   /* Test this VIOC */
        !            40:               }
        !            41:        vnum++;
        !            42:           }
        !            43: }
        !            44: /*
        !            45:    VIOC test routine
        !            46:        Return code: 0-----------------Error
        !            47:                     1-----------------Good
        !            48: */
        !            49: vioc_diag(unit,vdnum)
        !            50: long unit,vdnum;               /* current vioc no */
        !            51: {      register long ix, vbase;
        !            52:        long v_reset(), v_init();
        !            53: 
        !            54:        NL; writes("\nBEGIN TESTING VIOC NO. "); writed(vdnum); NL;
        !            55:        vbase = viocb[unit];
        !            56:        cmd_id = 0;
        !            57:        writes("\nInitialize VIOC at "); writeh(vbase); NL;
        !            58:        m_vioc(vbase);                  /* Set up map for IO space */
        !            59:        writes("\n1. Internal VIOC Reset Diagnostic"); NL;
        !            60:        if (v_reset(unit,vbase)) {      /* Reset VIOC */
        !            61:                if (vioctype[ix]==VIOC_B) {
        !            62:                      writes("\n    VIOC-B currently not supported\n");
        !            63:                      return(0);
        !            64:                      }
        !            65:                else  writes("\n    Reset Passed");
        !            66:                }
        !            67:        else    { 
        !            68:                writes("\n     Reset Failed"); NL;
        !            69:                return(0);
        !            70:                }       
        !            71:        NL; writes("\n2. Initialize VIOC"); 
        !            72:        init_flg = 1;
        !            73:        if (v_init()) {         /* Initialize VIOC */
        !            74:                writes(" - initialization passed"); NL;
        !            75:                DELAY(0x400000);
        !            76:                init_flg = 0;
        !            77:                }
        !            78:        else    { 
        !            79:                writes(" - initialization failed"); NL;
        !            80:                return(0);
        !            81:                }
        !            82:        writes("\n3. Initialize ports' parameters");NL;
        !            83:        if (log_last < log_first) writes("\n\n    No ports are available\n"); 
        !            84:        else    {
        !            85:                set_port();             /* Check how many ports on line */
        !            86:                }
        !            87:        return(1);      /* good return */
        !            88: }
        !            89: /*
        !            90:   Check vioc controllers' buffer address
        !            91: */
        !            92: chk_vadr()
        !            93: {      register long curadr;           /* current examine vioc address */
        !            94:         short len, viocno, nviocs,ix;  /* address length               */
        !            95:        ix = len = 1;
        !            96:        writes("\n\nProbing for VIOC controller(s)...");
        !            97:        curadr = 0xfe0000 + IOBASE;
        !            98:         for (nviocs=viocno= 0; viocno < NVIOC; viocno++)
        !            99:           {
        !           100:           if (!badaddr(curadr,len))
        !           101:              {
        !           102:               viocb[viocno] = curadr-IOBASE;
        !           103:               writes("\nVIOC controller no. "); writed(nviocs); 
        !           104:               writes(" at address ");
        !           105:                writeh((long)curadr-IOBASE);
        !           106:               nviocs++;
        !           107:              }
        !           108:           else   /* bad address return */
        !           109:              {         
        !           110:               viocb[viocno] = 0;       /* bad address indicator */
        !           111:               /* writed(viocno); writes("               ");
        !           112:                writes("At bad address"); NL;
        !           113:                */
        !           114:              }
        !           115:           if (ix >= 4){
        !           116:                curadr -= 0x1c000;
        !           117:                ix = 1;
        !           118:                }
        !           119:           else {
        !           120:                curadr += 0x4000;       /* get to next buffer's address */
        !           121:                ix++;
        !           122:                }
        !           123:            }
        !           124:         NL; writed(nviocs); writes(" VIOC controller(s) found"); NL;
        !           125:          return(nviocs);
        !           126: }
        !           127: /*
        !           128:        Routine to Reset VIOC   
        !           129:        Poll for 10 sec. then check 
        !           130:            if (VIOC busy flag is clear) and (VIOC is ready)
        !           131:        Return code: 0---------------Fault
        !           132:                     1---------------Good
        !           133: */
        !           134: v_reset(unit,vbase)
        !           135: long unit,vbase;
        !           136: {
        !           137:        VP->v_fault = (char)0;          /* Clear fault flag */
        !           138:        VP->v_vioc = V_BSY;             /* Set VIOC busy flag */
        !           139:        VP->v_hdwre = V_RESET;          /* Reset VIOC   */
        !           140:        DELAY(0x700000);                /* Wait for reset to complete */
        !           141:        if (VP->v_fault != V_ALLOK) { 
        !           142:                writes("\n\tVIOC error after Reset !");
        !           143:                writes("\n\tVIOC I.D : ");
        !           144:                writeh(((long)VP->v_ident)&0xff);
        !           145:                writes(", Fault code : ");
        !           146:                writeh(((long)VP->v_fault)&0xff);
        !           147:                return(0);
        !           148:                }
        !           149:        vioctype[unit] = 0x0;           /* Initialize vioc type */
        !           150:        switch (VP->v_ident)   {        /* Determine VIOC type */
        !           151:            case 0x1B:  /* VIOC-X */
        !           152:                {
        !           153:                vioctype[unit] = VIOC_X;
        !           154:                writes("\n    VIOC-X  controller is at "); writeh(vbase); 
        !           155:                break;
        !           156:                }
        !           157:            case 0x1C:  /* VIOC-B */
        !           158:                {
        !           159:                vioctype[unit] = VIOC_B;
        !           160:                writes("\n    VIOC-B  controller is at "); writeh(vbase); 
        !           161:                break;
        !           162:                }
        !           163:            default:
        !           164:                {
        !           165:                writes("\n    Unrecognized VIOC ID"); writeh(VP->v_ident);
        !           166:                }
        !           167:            }                           /* end switch */
        !           168:        writes(", virtual address : "); writeh((long)VP);
        !           169:        writes("\n    Max transmit block size      "); writeh(VP->xmtsiz);
        !           170:        writes("\n    Max receive silo char number "); writeh(VP->rcvsilo);
        !           171:        VP->v_fault = (char)0x0;        /* Clear fault flag */
        !           172:        VP->v_ustat = 0x0;              /* Clear unsol status */
        !           173:        VP->v_uqual = 0x0;              /* Clear unsol qual and bsy flag */
        !           174:        return(1);
        !           175: }
        !           176: /*
        !           177:        For DEBUG. size in bytes.
        !           178: */
        !           179: dump(addr,size)
        !           180: register char *addr;
        !           181: long size;
        !           182: {      register long ix = 0;
        !           183:        for (;size;ix++) {
        !           184:                if (!(ix%4)) {
        !           185:                        NL; writeh(addr); writes(":  ");
        !           186:                        }
        !           187:                writeh((*addr++)&0xff); writes(" ");
        !           188:                writeh((*addr++)&0xff); writes(" ");
        !           189:                writeh((*addr++)&0xff); writes(" ");
        !           190:                writeh((*addr++)&0xff); writes("  ");
        !           191:                size -= 4;
        !           192:        }
        !           193: }
        !           194: 
        !           195: /*
        !           196:        dump characters version 
        !           197: */
        !           198: 
        !           199: dumpc(addr,size)
        !           200: register char *addr;
        !           201: long size;
        !           202: {
        !           203:        register long ix;
        !           204: 
        !           205:        for (;size;size-=25) {
        !           206:                
        !           207:            for (ix=25;ix;--ix) {
        !           208:                writec((*addr++)&0xff); writes(" ");
        !           209:                }
        !           210:        }
        !           211: }
        !           212: /*     
        !           213:        VIOC initialization routines : Send LIDENT cmd
        !           214:        (1) Define interrupt vectors
        !           215:        (2) Set 1st, Last logical port no.
        !           216: */
        !           217: v_init()
        !           218: {      short *flycmd(), *rsp_blk, stat_wd;
        !           219:        
        !           220:        cblok.opcode = LIDENT;          /* Set opcode */
        !           221:        cblok.byte[0] = ACK_VIOC;       /* Set ack interrupt vector */
        !           222:        cblok.byte[1] = CMD_RESP;       /* Set cmd interrupt vector */
        !           223:        cblok.byte[2] = 0x0;            /* Not used */
        !           224:        cblok.byte[3] = UNS_VEC;        /* Set unsol interrupt vector */
        !           225:        cblok.byte[5] = log_first = 1;  /* 1st port is logical no. 1 */
        !           226:        log_last = 0;                   /* Clear last port variable */
        !           227:        if (! (rsp_blk=flycmd()) ) return(0);   /* Send command to VIOC */
        !           228:        log_last = (long)(rsp_blk[6] & 0xff);   /* Last logical port no */
        !           229:        return(chk_stat(rsp_blk,"\nLIDENT"));   /* Check status and return */
        !           230: }
        !           231: /*
        !           232:        Set ports to manual mode with (DTR) and (RTS) disabled
        !           233: */
        !           234: man_init(pno)
        !           235: long pno;
        !           236: {
        !           237:        short *rsp_blk;
        !           238:        cblok.opcode = MDMCTL;                  /* Set opcode */
        !           239:        cblok.byte[0] = 0x80;                   /* DTR/RTS disabled */
        !           240:        cblok.byte[1] = (char)pno;              /* Port no. */
        !           241:        if (! (rsp_blk=flycmd()) ) return(0);   /* Send to VIOC */
        !           242:        return(chk_stat(rsp_blk,"\nMDMCTL"));   /* Check status and rtn */
        !           243: }
        !           244: /*
        !           245:        check out how many ports are on line 
        !           246: */
        !           247: set_port()
        !           248: {      long ix;
        !           249:        short  *v_reqpar();
        !           250:        char *rsp;
        !           251: 
        !           252:        for(ix=1; ix<=log_last; ix++) {         /* Initialize ports */
        !           253:                msg_on = 0;                     /* Turn off msgs */
        !           254:                port_on[ix-1] = (char)1;        /* This port is on */
        !           255:                writes("\n    Port number "); writeh(ix-1); 
        !           256:                man_init(ix);                   /* Set manual mode */
        !           257:                if ( !v_initp(ix,NDBT,NSBT,BAUD,PARY))  {
        !           258:                        port_on[ix-1] = (char)0;        /* This port is off */
        !           259:                        writes(" is not on line");      
        !           260:                        }
        !           261:                   else {
        !           262:                        if (rsp=(char *)v_reqpar(ix)) { /* Get port parameter */
        !           263:                           if ((rsp[10] == (char)NDBT) 
        !           264:                                && (rsp[11] == (char)NSBT)
        !           265:                                && (rsp[12] == (char)BAUD)
        !           266:                                && (rsp[13] == (char)PARY)) {
        !           267:                                writes(" has successfully initialized");
        !           268:                                init_buf(ix);   /* Init. input buffer */
        !           269:                                }
        !           270:                           else {
        !           271:                                 writes(" cannot be initialized");
        !           272:                                 port_on[ix-1] = (char)2; /* Turn it off */
        !           273:                                }
        !           274:                        }
        !           275:                }
        !           276:                msg_on = 1;
        !           277:        }
        !           278:        return(0);      /* don't care return code */
        !           279: }
        !           280: /*
        !           281:        Routine to send LPRARAX command to VIOC
        !           282:        Also used to probe if a port is on line.
        !           283:        return 1 if port is on line else return 0
        !           284: */
        !           285: v_initp(pno, ndbits, nsbits, baud, parity)
        !           286: long pno, ndbits, nsbits, baud, parity;
        !           287: {
        !           288:        short *flycmd(), stat_wd, *rsp_blk;
        !           289: 
        !           290:        cblok.opcode = LPARAX;          /* Set opcode */
        !           291:        cblok.byte[0] = 0x0;            /* not used */
        !           292:        cblok.byte[1] = (char)pno;      /* Port no. */
        !           293:        cblok.byte[2] = 0x0;            /* Enable port's transmitter */
        !           294:        cblok.byte[3] = 0x0;
        !           295:        cblok.byte[4] = (char)ndbits;   /* no. data bit */
        !           296:        cblok.byte[5] = (char)nsbits;   /* no. stop bit */
        !           297:        cblok.byte[6] = (char)baud;     /* Baud rate */
        !           298:        cblok.byte[7] = (char)parity;   /* Parity */
        !           299: 
        !           300:        if (! (rsp_blk=flycmd()) ) return(0);   /* Send command to VIOC */
        !           301:        return(chk_stat(rsp_blk,"\nLPARAX"));   /* Check status and rtn */
        !           302: }
        !           303: /*
        !           304:        Request port parameters 
        !           305:        return code:
        !           306:                0 ------------- command error
        !           307:                1 ------------- good
        !           308: */
        !           309: short *
        !           310: v_reqpar(pno)
        !           311: long pno;
        !           312: {      short *flycmd(), *rsp_blk, stat_wd;
        !           313: 
        !           314:        cblok.opcode = RPARALX;         /* Set opcode  */
        !           315:        cblok.byte[0] = 0;              /* unused      */
        !           316:        cblok.byte[1] = (char)pno;              /* port number */
        !           317:                                        /* Send command to VIOC */
        !           318:        if (! (rsp_blk=flycmd()) ) return(0);
        !           319:        if (chk_stat(rsp_blk,"\nRPARALX") == 0) return(0); /* error */
        !           320:        return(rsp_blk);        /* good return */
        !           321: }
        !           322: 
        !           323: /*     Routine to send AUTO loop back/local echo
        !           324:        command to VIOC;
        !           325:        return 1 if port is on line else return 0
        !           326: */
        !           327: v_autol(pno,on,op)
        !           328: long pno,on, op;
        !           329: {
        !           330:        short *flycmd(), stat_wd, *rsp_blk;
        !           331: 
        !           332:        cblok.opcode = AUTOLP;          /* Set opcode */
        !           333:        cblok.byte[0] = on | op;        /* enable/disable auto loopback/echo */
        !           334:        cblok.byte[1] = pno;            /* port no */
        !           335: 
        !           336:        /* Send command to VIOC */
        !           337:        if (! (rsp_blk=flycmd()) ) return(0);
        !           338:        return(chk_stat(rsp_blk,"\nAUTOLP"));
        !           339: }
        !           340: 
        !           341: /*     
        !           342:        Routine to send XMITIMM CMD to VIOC.
        !           343:        Used to put a char to port #pno
        !           344:        Return a 1 if command executed else return 0
        !           345: */
        !           346: pchar(pno,c)
        !           347: long pno;
        !           348: char c;
        !           349: {      register long slen, ix;
        !           350:        char str[3], *cptr;
        !           351:        register short *rsp_blk;
        !           352: 
        !           353:        str[0] = c;
        !           354:        slen = 0;
        !           355:        if (c=='\n') {
        !           356:                slen = 2;
        !           357:                str[1] = '\r';
        !           358:                str[2] = NULL;  }
        !           359:        /* Fill command buffer */
        !           360:        cblok.opcode = (short)XMITIMM;  /* XMIT immediate */
        !           361:        cblok.byte[0] = (char)pno;      /* Port no. */
        !           362:        cblok.byte[1] = (char)slen;     /* Byte count */
        !           363: 
        !           364:        cptr = (char *)&cblok.byte[2];
        !           365:        for (ix=0;ix <= slen; ix++) *cptr++ = str[ix];
        !           366:        if (! (rsp_blk=flycmd()) ) return(0);
        !           367:        return(chk_stat(rsp_blk,"\nXMITIMM"));
        !           368: }
        !           369: /*     
        !           370:        Routine to send XMITDTA CMD to VIOC.
        !           371:        Used to send a string to port #pno
        !           372:        Return a 1 if command executed else return 0
        !           373: */
        !           374: pstr(pno,c)
        !           375: long pno;
        !           376: char *c;
        !           377: {      register long *lptr, slen, phys_adr;
        !           378:        char *cptr;
        !           379:        short *rsp_blk, stat_wd , *flycmd();
        !           380: 
        !           381:        /* Count length of string */
        !           382:        slen = 0;
        !           383:        for (cptr=c; *cptr++ != NULL; slen++);
        !           384: 
        !           385:        /* Fill command buffer */
        !           386:        cblok.opcode = XMITDTA;         /* XMIT opcode */
        !           387:        cblok.byte[0] = pno;    /* Port no. */
        !           388:        cblok.byte[1] = (char)slen;     /* Byte count */
        !           389: 
        !           390:        lptr = (long *)&cblok.byte[2];
        !           391:        phys_adr = va2pa((long)c);      /* Convert VA of string to phys. addr */
        !           392:        *lptr = (long)phys_adr;         /* Set address of buffer */     
        !           393: 
        !           394:        if (! (rsp_blk=flycmd()) ) return(0);
        !           395: 
        !           396:        return(chk_stat(rsp_blk,"\nXMITDTA"));
        !           397: }
        !           398: /*
        !           399:        Routine to check returned status of CMD
        !           400:        return 0 if error else return 1
        !           401: */
        !           402: chk_stat(rsp_blk,cmd)
        !           403: short *rsp_blk;
        !           404: char *cmd;
        !           405: {      short stat_wd;
        !           406: 
        !           407:        stat_wd = *rsp_blk;                     /* Get status word */
        !           408:        if (stat_wd & (short)C_ERR) {           /* CMD Error */ 
        !           409:                if (msg_on) {                   /* Print error msg */   
        !           410:                        writes("\t"); writes(cmd); writes(" error ");
        !           411:                        stat_wd = rsp_blk[1];
        !           412:                        writeh((long)stat_wd); NL;
        !           413:                        }
        !           414:                return(0);                      /* Return bad status */
        !           415:                }
        !           416:        return(1);                              /* Return good status */
        !           417: }
        !           418: /*
        !           419:        Send a command to VIOC, wait for respond and
        !           420:        (1) return pointer to respond buffer
        !           421:        (2) Check for matched CMD ID.
        !           422:        ** Routine that called this has to check for
        !           423:        cmd completion status itself. If cmd can not
        !           424:        be send, return a NULL pointer.
        !           425: */
        !           426: short *
        !           427: flycmd()
        !           428: {      register long *r12;
        !           429:        short *sent_cmd(), *rsp_blk, stat_wd;
        !           430: 
        !           431:        rsp_blk = sent_cmd(&cblok);     /* issue command to VIOC */
        !           432:        if (!rsp_blk) {
        !           433:                /* 
        !           434:                   Should try to abort this cmd, reset VIOC
        !           435:                   to known state and continue
        !           436:                */
        !           437:                return(0);      /* ERR : CMD cannot be sent. */
        !           438:        }
        !           439:        stat_wd = (*rsp_blk) & 0xffff;
        !           440:        rsp2v(rsp_blk);                 /* Send ACK interrupt to VIOC */
        !           441:        return(rsp_blk);
        !           442: }
        !           443: /*     
        !           444:        Routine to send a command to VIOC, Command buffer should be 
        !           445:        filled by HOST before calling this routine :
        !           446:            Issue CMD INP INT to VIOC, Wait for VIOC to send ACK INT
        !           447:            If VIOC ACK with INT ERR bit set, print INT ERR code and return 0
        !           448:                else wait for CMD RESP INT from VIOC
        !           449:        Return pointer to Command Respond block.
        !           450:        return code:    0-----------------VIOC/CMD busy flag set.
        !           451:                        else--------------response buffer address.
        !           452: */
        !           453: short *
        !           454: sent_cmd(cmdblk)
        !           455: struct cmd_inp *cmdblk;
        !           456: {
        !           457:        register long cnt, *r11;
        !           458:        register short *rsp_stat;
        !           459:        short *sptr, *gt_rspadr(), ix, sec;
        !           460: 
        !           461:        if (v_busy()) return(0);        /* Test VIOC BUSY flag */
        !           462:        if (!v_rdy4cmd()) return(0);    /* Test CMD BUSY flag */
        !           463:        set_cadr((long)cmdblk);         /* Load CMD address in common buffer */
        !           464:        vioc_ack = vioc_rsp = 1;
        !           465:        VP->v_vcbsy = V_BSY;            /* Set CMD BUSY FLAG    */
        !           466:        v_int((char)V_CMDI);            /* Send CMD INPUT INTERRUPT */
        !           467:        sec = 0x0000;
        !           468:        while ((vioc_ack != 0) && (sec <= 0x100)) {
        !           469:                DELAY(0x5000);
        !           470:                if (sec == 0x100) {
        !           471:                   writes("\n\t*** Time out on CMD ACK interrupt ***\n");
        !           472:                   return(0);   /* no response */
        !           473:                }
        !           474:                sec++;
        !           475:        }
        !           476:        cmd_id = (long)(VP->v_vcid & 0xff);
        !           477:        if (cmd_id & V_ERR)
        !           478:                {
        !           479:                writes("\n\tCmd ID/ERR : ");
        !           480:                writeh((long)(cmd_id & 0x3C)); NL;
        !           481:                return(0);
        !           482:                }
        !           483:        sec = 0x0000;
        !           484:        while ((vioc_rsp != 0) && (sec <= 0x100)) {
        !           485:                DELAY(0x5000);
        !           486:                if (sec == 0x100) {
        !           487:                   writes("\n\t*** Time out on CMD RESP interrupt ***\n");
        !           488:                   return(0); /* no response ! */
        !           489:                }
        !           490:                sec++;
        !           491:        }                                                       
        !           492:        rsp_stat =  gt_rspadr();        /* Get addr of Respond buffer */
        !           493:        /* For debugging only : Read command respond buffer from VIOC */
        !           494:        sptr = rsp_stat;
        !           495:        for (ix=0; ix <MAXRLEN; ix++) cmdrsp[ix] = *sptr++;
        !           496: 
        !           497:        return(rsp_stat);
        !           498: }
        !           499: /*
        !           500:        This routine send a command respond interrupt to VIOC
        !           501: */
        !           502: rsp2v(rsp_blk)
        !           503: short *rsp_blk;
        !           504: {      register long cnt;
        !           505: 
        !           506:        if (v_busy()) panic("\n\t*** Rsp2v time out on VBSY flag ***\n");
        !           507:        *rsp_blk &= ~V_BSY;             /* Clear RESP. BUSY Flag */
        !           508:        v_int((char)V_CMDRI);           /* Send a cmd respond int. to VIOC */
        !           509: }
        !           510: /*     Routine return the address of CMD RESP. Buffer in 
        !           511:        shared area
        !           512: */
        !           513: short *
        !           514: gt_rspadr()
        !           515: {
        !           516:        return((short *)( ((char *)VP) + (VP->v_rsp & 0x7fff)));
        !           517: }
        !           518: /*
        !           519:        Routine to send an interrupt to VIOC    
        !           520:        Input : Bit 0,1 of 'qual' indicate type of interrupt
        !           521: */
        !           522: v_int(qual)
        !           523: char qual;
        !           524: {
        !           525:        char vint;
        !           526: 
        !           527:        vint = (char)((V_BSY | qual) & 0xff);
        !           528:        VP->v_vioc = vint;      /* Set busy flag, int. qualifier */
        !           529:        VP->v_hdwre = V_INTR;   /* Interrupt VIOC */
        !           530: }
        !           531: /*
        !           532:        Routine to test if VIOC is ready to accept new command
        !           533:        Return 1 if ready Else return 0
        !           534: */
        !           535: v_rdy4cmd()
        !           536: {      register long cnt;
        !           537: 
        !           538:        cnt = 0x100;
        !           539:        while (VP->v_vcbsy & V_BSY) {
        !           540:                  DELAY(0x5000);
        !           541:                  if (--cnt == 0) {
        !           542:                        writes("\n\t*** VIOC CMD BUSY flag set ***\n");
        !           543:                        return(0); }
        !           544:                }
        !           545:        return(1);
        !           546: }
        !           547: /*
        !           548:        Routine to test if VIOC busy, Return 1
        !           549:        if not busy Else return 0
        !           550: */
        !           551: v_busy()
        !           552: {      register long cnt, *r12;
        !           553: 
        !           554:        cnt = 0x100;
        !           555:        while (VP->v_vioc & V_BSY) {
        !           556:                  DELAY(0x5000);
        !           557:                  if (--cnt == 0) {
        !           558:                        writes("\n\t*** VIOC BUSY flag set ***\n");
        !           559:                        return(1);
        !           560:                        }
        !           561:                }
        !           562:        return(0);
        !           563: }
        !           564: /* 
        !           565:        Handler of VIOC CMD RESP. INT 
        !           566: */
        !           567: rsp_handlr()
        !           568: {
        !           569:        asm(".align 2");
        !           570:        asm(".globl rsp_hdlr");
        !           571: asm("rsp_hdlr:");
        !           572:        vioc_rsp = 0;                   /* Clear Vioc_rsp flag */
        !           573:        asm("rei");
        !           574: }
        !           575: /* 
        !           576:        Handler of VIOC ACK INT 
        !           577: */
        !           578: ack_handlr()
        !           579: {
        !           580:        asm(".align 2");
        !           581:        asm(".globl ack_hdlr");
        !           582: asm("ack_hdlr:");
        !           583:        vioc_ack = 0;                   /* Clear Vioc ack flag */
        !           584:        asm("rei");
        !           585: }
        !           586: /*     
        !           587:        Global variables used in Unsolicited int. handler 
        !           588: */
        !           589: long silo_no, no_char, cin, count;
        !           590: char ascii;
        !           591: 
        !           592: /*     
        !           593:        Handler of VIOC UNSOLICITED interrupt : service on ISP
        !           594:        (1) Dump silo contents
        !           595: */
        !           596: unsol_handlr()
        !           597: {
        !           598:        asm(".align 2");
        !           599:        asm(".globl unsol_hdlr");
        !           600: asm("unsol_hdlr:");
        !           601:        asm("svpctx");          /* Save context, also switch to ISP */
        !           602:        dmp_silo();
        !           603:        asm("ldpctx");          /* Restore context, switch to KSP */
        !           604:        asm("rei");
        !           605: }
        !           606: dmp_silo()
        !           607: {      register long rsp_qual, pno, error, rec_err;
        !           608:        register long ptr2silo;
        !           609:        short ix;
        !           610: 
        !           611:        rec_err = 0;
        !           612:        if(init_flg) goto nomore; 
        !           613: /*     ptr2silo = (long)*(short *)(&VP->v_usdata[0]);
        !           614:        ptr2silo &= 0x3fff;                                     */
        !           615:        rsp_qual = VP->v_uqual & 0x7;
        !           616:        switch (rsp_qual)       {
        !           617:                case 1 : {      
        !           618:                        writes("\n\t*** Received data error. ***");
        !           619:                        goto nomore; }
        !           620:                case 2 : {      
        !           621:                        writes("\n\t*** VIOC process error. ***");
        !           622:                        goto nomore; }
        !           623:                case 3 : {      
        !           624:                        error = VP->v_ustat & 0x3f;
        !           625:                        writes("\n\t*** Data set change, STATUS ");
        !           626:                        writeh(error); STAR;
        !           627:                        goto nomore; }
        !           628:                case 4 : {      
        !           629:                        writes("\n\t*** Secondary receive change ***");
        !           630:                        goto nomore; }
        !           631:                case 7 :        
        !           632:                case 6 :        
        !           633:                case 5 : {      
        !           634:                        writes("\n\t*** Undefined UNSOL INT QUAL ***");
        !           635:                        writeh(rsp_qual);
        !           636:                        goto nomore; }
        !           637:                }
        !           638:        /* Data available */
        !           639: /*             
        !           640:                s_entry = (short *) ((char *)VP) + ((char *)ptr2silo & 0xffff);
        !           641: */
        !           642:                ptr2silo = (long)*(short *)(&VP->v_usdata[0]);
        !           643:                ptr2silo &= 0x3fff;
        !           644:                ptr2silo += (long)VP;    /* VAX's Tahoe compiler sucks rock. */
        !           645:                s_entry = (short *)ptr2silo;
        !           646:                cin = (long)((*s_entry) & 0xffff);      /* Get char. count */
        !           647:                if (cin==0) goto nomore;
        !           648:                /* Print contents of 1 SILO */
        !           649:                for(no_char=1; no_char<=cin; no_char++)
        !           650:                        {
        !           651:                        ascii = (char)((s_entry[no_char] >> 8) & 0xff);
        !           652:                        if ( !(s_entry[no_char] & 0x00c0) )  {
        !           653:                                pno = s_entry[no_char] & 0x3f;
        !           654: 
        !           655:                                /* Check for port no out of bound */
        !           656:                                if (!((pno>log_last) || (pno<log_first))) {
        !           657:                                        if (!fillc(pno,ascii)) 
        !           658:                                            goto nomore; /* exit */
        !           659:                                     }
        !           660:                                else {
        !           661:                                        writes("\n\t*** Port out of bound : ");
        !           662:                                        writed(pno); STAR;
        !           663:                                        }
        !           664:                        }
        !           665:                           else {
        !           666:                                /* Data receive error : parity,frame,overrun */
        !           667:                                writes("\n\t*** data receive error ");
        !           668:                                error = (long)(s_entry[no_char] & 0xc0) >> 6;
        !           669:                                writeh(error & 0x3); STAR; NL;
        !           670:                                }
        !           671:                        }
        !           672:                *s_entry = 0;           /* Clear char. count */
        !           673: nomore:
        !           674:        if (v_busy())
        !           675:           panic("\n\t*** UNSOL hdlr : Time out on VIOC busy flag ***\n");
        !           676:        
        !           677:        VP->v_uqual = 0;                /* Reset UNSOL BUSY FLAG */
        !           678:        v_int((char)V_URESP);           /* Send ACK UNSOL interrupt to VIOC */
        !           679:        return(0);
        !           680: }
        !           681: fillc(pno,c)
        !           682: long pno;
        !           683: char c;
        !           684: {      struct vbuf *vb;
        !           685: 
        !           686:        vb = &vi_buf[pno-1];
        !           687:        if (vb->cnt >= BUFLEN) {
        !           688:                writes("\n\t*** Input overflow, port no. ");
        !           689:                writed(pno-1); STAR; NL;
        !           690: /*             dumpc(&(vb->buf[0]),100); /* dump input buffer */
        !           691:                return(0); }
        !           692:        vb->buf[vb->nxt_fill++] = c;
        !           693:        vb->cnt++;
        !           694:        if (vb->nxt_fill > BUFLEN) vb->nxt_fill = 0; 
        !           695:        return(1);
        !           696: }
        !           697: char get1c(pno)
        !           698: long pno;
        !           699: {      struct vbuf *vb;
        !           700:        char c;
        !           701: 
        !           702:        vb = &vi_buf[pno-1];
        !           703:        if (vb->cnt == 0) return((char)0xff);
        !           704:        c = vb->buf[vb->nxt_c++];
        !           705:        vb->cnt--;
        !           706:        if (vb->nxt_c > BUFLEN) vb->nxt_c = 0; 
        !           707:        return(c);
        !           708: }
        !           709: /*
        !           710:        Routine to map VIOC :
        !           711:        VIOC space is map from 1st unused virtual page on
        !           712: */
        !           713: m_vioc(vbase)
        !           714: long vbase;
        !           715: {      register long phys_pg, pte, which1;
        !           716:        long old_pte;
        !           717:        phys_pg = ((vbase+IOBASE) >> PGSHIFT) & 0x3fffff;
        !           718:                                /* 1st physical page of VIOC in IO space */
        !           719:        pte = phys_pg | PG_KW | PG_V | PG_NC;
        !           720:        for (which1=unused; which1<(unused+VIOC_LEN); which1++) {
        !           721:                fix_pte(SBR,which1,&old_pte,pte);
        !           722:                pte++;}
        !           723:        VP = (struct vblok *)(unused << PGSHIFT);
        !           724:        IObase = (long)VP;              /* Base addr of common buffer */
        !           725:        asm("mfpr $SLR,_savvec3");      /* Get number of PTE's */
        !           726:        savvec3 += VIOC_LEN;            /* Add buffer pages */
        !           727:        asm("mtpr _savvec3,$SLR");      /* Set SBR */
        !           728:        asm("mtpr _savvec3,$P0LR");     /* Set P0LR also */
        !           729:        unused = which1;                /* Next unused PTE in system map */
        !           730:        asm("mtpr $1,$TBIA");           /* Clear translation buffer */
        !           731:        asm("mtpr $1,$PADC");           /* Purge all data cache */
        !           732: }
        !           733: /*     
        !           734:        Initialize Tahoe SCB vectors to handle VIOC interrupts
        !           735: */
        !           736: init_vec()
        !           737: {      long old_vec1, old_vec2, old_vec3;
        !           738: 
        !           739:        asm("movab ack_hdlr,_savvec3");
        !           740:        set_handler(ACK_VIOC,&old_vec1,savvec3);  /* Set handler for VIOC ACK */
        !           741:        asm("movab rsp_hdlr,_savvec3");
        !           742:        set_handler(CMD_RESP,&old_vec2,savvec3);  /* Set handler for VIOC RSP */
        !           743:        asm("movab unsol_hdlr,_savvec3");
        !           744:        set_handler(UNS_VEC,&old_vec3,savvec3);  /* Set hdler for VIOC UNSOL */
        !           745: }
        !           746: /*     
        !           747:        Routine translate virtual address to physical address
        !           748: */
        !           749: va2pa(va)
        !           750: long va;
        !           751: {      register long *base, pte, pte_no, page_no, cmdadr;
        !           752: 
        !           753:        /* Translate virtual to physical address */
        !           754:        asm("mfpr $SBR,r12");
        !           755:        pte_no = (va >> PGSHIFT) & 0x3fffff; /* Virtual pgno of cmd addr */
        !           756:        pte = base[pte_no];                      /* PTE for this page no */
        !           757:        page_no = pte & 0x3fffff;
        !           758:        cmdadr = (page_no << PGSHIFT) | (va & 0x3ff);
        !           759:        return(cmdadr);
        !           760: }
        !           761: panic(msg)
        !           762: char *msg;
        !           763: {
        !           764:        writes(msg);
        !           765:        asm("halt");
        !           766: }
        !           767: /*     
        !           768:        Routine to set cmd address in common buffer. 
        !           769:        Command address has to be translated to physical
        !           770:        address. 
        !           771:        input : blkadr (virtual address)
        !           772: */
        !           773: set_cadr(blkadr)
        !           774: long blkadr;
        !           775: {      register long word1, cmdadr;
        !           776: 
        !           777:        cmdadr = va2pa(blkadr);         /* VA to physical address */
        !           778:        VP->v_vcp1 = (short)(cmdadr & 0xffff);
        !           779:        word1 = (cmdadr >> 16) & 0xffff;
        !           780:        VP->v_vcp0 = (short)word1;
        !           781: }
        !           782: /*
        !           783:        routine to initialize input buffer for port X
        !           784:        input : pno - logical port no. on VIOC
        !           785: */
        !           786: init_buf(pno)
        !           787: long pno;
        !           788: {      struct vbuf *vb;
        !           789:        register long ix;
        !           790: 
        !           791:        vb = &vi_buf[pno-1];
        !           792:        vb->cnt = vb->nxt_c = vb->nxt_fill = 0;
        !           793:        for(ix=0; ix<BUFLEN; ix++) vb->buf[ix] = 0;
        !           794: }
        !           795: /* 
        !           796:        Request current port parameters and print them to console
        !           797: */
        !           798: /*
        !           799:        Send a break command to vioc
        !           800:        return code:
        !           801:                0 ------------- command error
        !           802:                1 ------------- good return
        !           803: */
        !           804: v_break(pno,brklgth)
        !           805: long pno;
        !           806: short brklgth;
        !           807: {      short *flycmd(), *rsp_blk, stat_wd;
        !           808: 
        !           809:        cblok.opcode = SNDBRKX;         /* Set opcode  */
        !           810:        cblok.byte[0] = brklgth;        /* break length*/
        !           811:        cblok.byte[1] = pno;            /* port number */
        !           812:                                        /* Send command to VIOC */
        !           813:        if (! (rsp_blk=flycmd()) ) return(0);
        !           814:        if (chk_stat(rsp_blk,"\nSNDBRKX") == 0) return(0); /* error */
        !           815:        return(1);      /* good return */
        !           816: }
        !           817: /*
        !           818:        Send a command to flush the hung xmit command
        !           819:        return code:
        !           820:                0 ------------- command error
        !           821:                1 ------------- good return
        !           822: */
        !           823: v_flush(pno)
        !           824: long pno;
        !           825: {      short *flycmd(), *rsp_blk, stat_wd;
        !           826: 
        !           827:        cblok.opcode = FDTATOX;         /* Set opcode  */
        !           828:        cblok.byte[0] = 0;              /* not used    */
        !           829:        cblok.byte[1] = pno;            /* port number */
        !           830:                                        /* Send command to VIOC */
        !           831:        if (! (rsp_blk=flycmd()) ) return(0);
        !           832:        if (chk_stat(rsp_blk,"\nFDTATOX") == 0) return(0); /* error */
        !           833:        return(1);      /* good return */
        !           834: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.