Annotation of cci/d/ioex/tape.c, revision 1.1

1.1     ! root        1: 
        !             2: /*
        !             3:  * Cypher tape driver
        !             4:  *
        !             5:  */
        !             6: 
        !             7: #include "pte.h"
        !             8: #include "cy.h"
        !             9: #include "cyconf.h"
        !            10: 
        !            11: struct scp *SCP;       /* Pointer System configuration block */
        !            12: struct scb scblk;      /* System conf. block */
        !            13: struct ccb ccblk;      /* Channel control block */
        !            14: struct tpb tpb;                /* Tape parameter block */
        !            15: struct tpb tpb1;       /* Tape parameter block (spare) */
        !            16: long cmd_done;         /* 1 : cmd completed without error */
        !            17:                        /* 2 : cmd error */
        !            18: 
        !            19: long CYattn;           /* Virtual address of Cypher I/O attention address */
        !            20: long tm_bsiz = 0;
        !            21: extern long unused, Multi, Berr;
        !            22: 
        !            23: tape()
        !            24: {      register long r12;
        !            25:        long oldvec;
        !            26: 
        !            27:        m_cy();                 /* Map Tape master space */
        !            28: 
        !            29:        /* Set handler for tape master interrupt */
        !            30:        asm("movab cyhdlr,r12");
        !            31:        set_handler(CYVEC,&oldvec,r12);
        !            32: 
        !            33:        cy_reset();             /* Reset Tape master */
        !            34:        return(cy_setup());   /* Set up structures and initailize Tape master */
        !            35: }
        !            36: 
        !            37: 
        !            38: long tm_cnt;
        !            39: 
        !            40: /*     Routine to sent a command to Tape master
        !            41:        return -1 if error
        !            42:        return return count of TPB if sucessful
        !            43: */
        !            44: sent_tm()
        !            45: {      register long cntr, rtn_cnt;
        !            46: 
        !            47:        tm_cnt = 0;
        !            48:        ccblk.gate = (char)GATE_CLOSED;         /* Close gate */
        !            49:        cy_attn();                              /* Execute command */
        !            50:        cntr = RETRY;
        !            51:        cmd_done = 0;
        !            52:        if (Multi) return;
        !            53:        while (!cmd_done) {             /* Wait for completion interrupt */
        !            54:                DELAY(0x5000);
        !            55:                if (--cntr == 0) {
        !            56:                        writes("sent_tm no interrupt respond\n");
        !            57:                        return(-1);     /* Time out */
        !            58:                        }
        !            59:                }
        !            60:        if (cmd_done == 2) return(-1);  /* Command has error */ 
        !            61:        return(tm_cnt);
        !            62: }
        !            63: 
        !            64: /*     Tape master completion interrupt handler
        !            65: */
        !            66: tm_hdlr()
        !            67: {
        !            68:        if (chk_cstat())
        !            69:                cmd_done = 2;   /* completion error */
        !            70:           else cmd_done = 1;   /* completion without error */
        !            71:        tm_cnt = gt_bcnt();     /* Get return count from TPB */
        !            72:        clr_tint();             /* Clear tape master interrupt */
        !            73: }
        !            74: 
        !            75: 
        !            76: /*     Routine to ACK on tape master completion interrupt
        !            77:        Sent out a NOOP command without interrupt on completion
        !            78: */
        !            79: clr_tint()
        !            80: {
        !            81:        while (g_open()==0)     /* Gate close */
        !            82:                { tm_init();
        !            83:                error("Received interrupt but gate closed.\n");
        !            84:                }
        !            85:        ccblk.gate = GATE_CLOSED;       
        !            86:        ccblk.ccw = 0x9;                /* Clear tape master interrupt */
        !            87:        set_g3(&tpb,NOOP,0,0,0);        /* No Interrupt on completion please */
        !            88:        cy_attn();
        !            89:        DELAY(0x1500);                  /* wait for completion */
        !            90:        while (g_open()==0)     /* Gate close */
        !            91:                { tm_init();
        !            92:                error("Cannot clear interrupt\n");
        !            93:                return(0);
        !            94:                }
        !            95:        ccblk.ccw = 0x11;
        !            96:        return(1);
        !            97: }
        !            98: 
        !            99: 
        !           100: /*     Check status of command previously issued
        !           101:        If all are OK return 0
        !           102:                else return Status byte.
        !           103: */
        !           104: chk_cstat()
        !           105: {
        !           106:        register long *r12, cstat;
        !           107: 
        !           108:        r12 = (long *)&tpb.status[1];
        !           109:        uncache(r12);
        !           110:        /* Cmd status without retry bit */
        !           111:        cstat = (long)tpb.status[1];
        !           112:        if ((cstat & 0xc0) != 0xc0)
        !           113:                { writes("Cy hard error ");
        !           114:                  writeh(cstat & 0xff); writec('\n');
        !           115:                  return(cstat); } 
        !           116:        return(0);
        !           117: }
        !           118: 
        !           119: /*     Check status of drive after received command
        !           120:        completion interrupt. If all are OK return 0
        !           121:        else return Status byte.
        !           122: */
        !           123: chk_dstat()
        !           124: {      register long *r12, tstat;
        !           125: 
        !           126:        r12 = (long *)&tpb.status[0];
        !           127:        uncache(r12);
        !           128:        tstat = tpb.status[0];
        !           129:        if ( (tstat & 0x48) != 0x48)
        !           130:                { writes("drive error ");
        !           131:                  writeh(tstat & 0xff);
        !           132:                  return(tstat); }
        !           133:        return(0);
        !           134: }
        !           135: 
        !           136: /*     Routine to get return_count field of TPB after
        !           137:        receive command completion interrupt
        !           138: */
        !           139: gt_bcnt()
        !           140: {      register long *r12, tmp1, tmp2;
        !           141: 
        !           142:        r12 = (long *)&tpb.count;
        !           143:        uncache(r12);
        !           144:        tmp1 = (long)((tpb.count & (short)0xff)<<8);
        !           145:        tmp2 = (long)((tpb.count & (short)0xff00)>>8);
        !           146:        return(tmp1|tmp2);
        !           147: }
        !           148: 
        !           149: 
        !           150: /*     Routine to issue a GO command to tape master
        !           151:        also known as Channel attention interrupt
        !           152: */
        !           153: cy_attn()
        !           154: {      register long r12;
        !           155: 
        !           156:        r12 = CYattn;           /* R12 = Cypher attention address */
        !           157:        asm("movob $0xff,(r12)");
        !           158: }
        !           159: 
        !           160: /*     Routine to reset Tape master controller 
        !           161: */
        !           162: cy_reset()
        !           163: {      register long r12;
        !           164: 
        !           165:        r12 = CYattn + 1;               /* R12 = Cypher attention address */
        !           166:        asm("movob $0xff,(r12)");
        !           167:        DELAY(100);
        !           168:        if (!Berr) { writes("\nTape controller is at "); writeh(TBASE); }
        !           169: }
        !           170: 
        !           171: 
        !           172: /*     Map channel attention address of Tape master 
        !           173: */
        !           174: m_cy()
        !           175: {      register long r12;
        !           176:        long phys_pg, pte, old_pte, which1;
        !           177: 
        !           178:        /* physical page of Tape master in IO space */
        !           179:        phys_pg = ((TBASE+IOBASE) >> PGSHIFT) & 0x3fffff;
        !           180:        pte = phys_pg | PG_KW | PG_V | PG_NC;
        !           181:        fix_pte(SBR,unused,&old_pte,pte);
        !           182:        CYattn = (unused << PGSHIFT);   /* Virtual address of CY attn address */
        !           183:        asm("mfpr $SLR,r12");
        !           184:        r12++;
        !           185:        asm("mtpr r12,$SLR");
        !           186:        unused++;               /* Next unused PTE in system map */
        !           187: }
        !           188: 
        !           189: /*     Set up all structures for Tape master
        !           190:        and initialize Tape master
        !           191: */
        !           192: cy_setup()
        !           193: {
        !           194:        register long cntr;
        !           195: 
        !           196:        SCP = (struct scp *)SCP_ADR;    /* absolute - for setup */
        !           197: 
        !           198:        /* Initialize the system configuration pointer  */
        !           199:        SCP->sysbus = 1;                        /* system width = 16 bits. */
        !           200:        set_pointer(&scblk.sysblk,(char *)SCP->pt_scb);
        !           201: 
        !           202:        /* Initialize the system configuration block. */
        !           203:        scblk.sysblk = 0x3;             /* fixed value */
        !           204:        scblk.nu2 = 0;                  /* not used */
        !           205:        set_pointer(&ccblk.ccw,(char *)scblk.pt_ccb);
        !           206: 
        !           207:        /* Initialize the channel control block. */
        !           208:        ccblk.ccw = 0x11;               /* normal interrupts */
        !           209:        set_pointer(&tpb,(char *)ccblk.pt_tpb);
        !           210: 
        !           211:        ccblk.gate = GATE_CLOSED;       
        !           212:        cy_attn();              /* 1st attention : initilization Cypher */
        !           213:        cntr = RETRY;
        !           214:        while (ccblk.gate == GATE_CLOSED) {
        !           215:                DELAY(0x400);                   /* wait for completion */
        !           216:                if (--cntr == 0) {
        !           217:                        writes("Init : Cypher time out\n");
        !           218:                        return(0); }    /* Time out */
        !           219:                }
        !           220:        return(1);
        !           221: }
        !           222: 
        !           223: 
        !           224:  /*
        !           225:  *  Set a TAPEMASTER 20_bit pointer (first parameter), into the
        !           226:  *  4 bytes array pointed by the second parameter.
        !           227:  */
        !           228: set_pointer(pointer,dest)
        !           229: long pointer;
        !           230: char *dest;
        !           231: {
        !           232:        *dest++ = pointer & 0xff;               /* low byte - offset */
        !           233:        *dest++ = (pointer >> 8) & 0xff;        /* high byte - offset */
        !           234:        *dest++ = 0; 
        !           235:        *dest   = (pointer & 0xf0000) >> 12;    /* base */
        !           236: }
        !           237: 
        !           238: 
        !           239: 
        !           240: g_open()
        !           241: {      register long *r12, cntr;
        !           242: 
        !           243:        r12 = (long *)&ccblk.gate;
        !           244:        cntr = RETRY;
        !           245:        while (ccblk.gate!=0) {
        !           246:                uncache(r12);
        !           247:                DELAY(0x500);                   /* wait for completion */
        !           248:                if (--cntr == 0) {
        !           249:                        writes("g_open time out\n");
        !           250:                        return(0);
        !           251:                        }
        !           252:                }
        !           253:        return(1);
        !           254: }
        !           255: 
        !           256: error(msg)
        !           257: char *msg;
        !           258: {
        !           259:        writes(msg);
        !           260: }
        !           261: 
        !           262: 
        !           263: 
        !           264: /*     Set Tape Parameter Block
        !           265:        Input :
        !           266:              cmd    = Opcode
        !           267:              bufsiz = Block size 
        !           268:              bufadr = System buffer address
        !           269:              int    = interrupt on completion or not
        !           270: */
        !           271: 
        !           272: set_g3(tpblk,cmd,bufsiz,bufadr,intr)
        !           273: struct tpb *tpblk;
        !           274: long cmd, bufsiz, intr;
        !           275: char *bufadr;
        !           276: {      char *cptr;
        !           277: 
        !           278:        tpblk->cmd = cmd;                       /* Command */
        !           279:        tpblk->control[1] = 0x80 | CW_100ips;   /* 16_bit system bus */
        !           280:        tpblk->control[0] = (0|(intr << 5));    /* Bank=0,Drive=0,interrupt */
        !           281:        tpblk->count = 0;                       /* Return count = 0 */
        !           282: 
        !           283:        cptr = (char *)&tpblk->size;    /* Set buffer size */
        !           284:        *cptr++ = (char)(bufsiz & 0xff);
        !           285:        *cptr = (char)((bufsiz & 0xff00)>>8);   
        !           286:        tpblk->rec_over = 0;
        !           287: 
        !           288:        /* Set system buffer address */
        !           289:        set_pointer((long)(bufadr),(char *)tpblk->pt_data);
        !           290:        tpblk->status[0] = tpblk->status[1] = 0;
        !           291: }
        !           292: 
        !           293: 
        !           294: 
        !           295: 
        !           296: /*     *************************************
        !           297:        Routine to Read/Write Cypher tape 
        !           298:        return 0 if cannot complete operation
        !           299:        *************************************
        !           300: */
        !           301: long tape_op(cmd,buf_adr,buf_siz)
        !           302: long cmd, buf_siz;
        !           303: char *buf_adr;
        !           304: {      char *cptr;
        !           305:        register long cnt, stat, tmp1, tmp2;
        !           306: 
        !           307:        switch (cmd) {
        !           308:                case READ_TA : { writec('.'); break; }
        !           309:                case WRIT_TA : { writec(','); break; }
        !           310:                case REWD_TA : { writec('*'); break; }
        !           311:                }
        !           312:        set_g3(&tpb,cmd,buf_siz,buf_adr,1);     /* Set up command block */
        !           313:        while (g_open()==0) {           /* Gate closed !! */
        !           314:                tm_init();              /* Init controller */
        !           315:                writes("\ntape_op : Can not open gate !!\n");
        !           316:                return(0);
        !           317:                } 
        !           318:        return(sent_tm());
        !           319: }
        !           320: 
        !           321: /*     Rewind tapemaster
        !           322: */
        !           323: tm_rew()
        !           324: {      char tstat;
        !           325: 
        !           326:        if (tape_op(REWD_TA,0,0) == -1)  return(0);
        !           327:        tstat = tpb.status[0];
        !           328:        if ( (tstat & 0x20) != 0x20) return(0);
        !           329:        return(1);
        !           330: }
        !           331: 
        !           332: 
        !           333: /*     Routine to initialize tape master 
        !           334: */
        !           335: tm_init()
        !           336: {      register long cntr;
        !           337: 
        !           338:        cy_reset();
        !           339:        if (!g_open()) return(0);
        !           340:        ccblk.gate = GATE_CLOSED;       
        !           341:        cy_attn();              /* 1st attention : initilization Cypher */
        !           342:        cntr = RETRY;
        !           343:        while (ccblk.gate == GATE_CLOSED) {
        !           344:                DELAY(2000);                    /* wait for completion */
        !           345:                if (--cntr == 0) {
        !           346:                        writes("Init : Cypher time out\n");
        !           347:                        return(0); }    /* Time out */
        !           348:                }
        !           349:        return(1);
        !           350: }
        !           351: 
        !           352: cyhandler()
        !           353: {      long dummy;
        !           354: 
        !           355:        asm(".align 2");
        !           356: asm("cyhdlr:");
        !           357:        asm("svpctx");
        !           358:        tm_hdlr();
        !           359:        asm("ldpctx");
        !           360:        asm("rei");
        !           361:        dummy = 0;
        !           362: }
        !           363: 

unix.superglobalmegacorp.com

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