Annotation of cci/d/ioex/tape.c, revision 1.1.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.