Annotation of cci/sys/stand/cy.c, revision 1.1

1.1     ! root        1: /*     cy.c    Tahoe version   Mar 1983.       */
        !             2: 
        !             3: /*
        !             4:  * Cypher tape driver. Stand alone version.
        !             5:  *
        !             6:  */
        !             7: #include "../h/param.h"
        !             8: #include "../h/inode.h"
        !             9: #include "../h/fs.h"
        !            10: #include "../machine/pte.h"
        !            11: #include "../machine/mtpr.h"
        !            12: #include "../stand/saio.h"
        !            13: #include "../stand/cyvar.h"
        !            14: 
        !            15: long   cystd[] = { 0xf4000, 0 };
        !            16: 
        !            17: struct scp     /* SYSTEM CONFIGURATION POINTER */
        !            18: {
        !            19:   char sysbus ;        /* width of system buss 0=8;1=16 */
        !            20:   char nu1 ;
        !            21:   char pt_scb[4] ;     /* pointer to ->SYSTEM CONFIGURATION BLOCK */
        !            22: };
        !            23: 
        !            24: struct scp * SCP;      /* absolute address - jumpered on the controller */
        !            25:                        /* set to 0xC06 for Tahoe */
        !            26: 
        !            27: struct scb     /* SYSTEM CONFIGUREATION BLOCK */
        !            28: {
        !            29:   char sysblk[1] ;     /* 0x03 fixed value code */
        !            30:   char nu2[1] ;
        !            31:   char pt_ccb[4] ;     /* pointer to ->CHANNEL CONTROL BLOCK */
        !            32: }scb;
        !            33: 
        !            34: struct ccb     /* CHANNEL CONTROL BLOCK */
        !            35: {
        !            36:   char ccw[1] ;                /* 0x11 normal; 0x09 clear non_vect interrupt */
        !            37:   char gate[1] ;       /* This is "the" GATE */
        !            38:   char pt_tpb[4] ;     /* pointer to ->TAPE OPERATION BLOCK or MOVE BLOCK */
        !            39: }ccb;
        !            40: 
        !            41: struct tpb     /* TAPE OPERATIONS PARAMETER BLOCK */
        !            42: {
        !            43:   long cmd ;           /* COMMAND (input) */
        !            44:   char control[2] ;    /* CONTROL (input) */
        !            45:   short count ;                /* RETURN COUNT (output) */
        !            46:   short size ;         /* BUFFER SIZE (input/output) */
        !            47:   short rec_over ;     /* RECORDS/OVERRUN (input/output) */
        !            48:   char pt_data[4] ;    /* pointer to ->SOURCE/DEST (input) */
        !            49:   char status[2] ;     /* STATUS (output) */
        !            50:   char pt_link[4] ;    /* pointer to ->INTERRUPT/PARAMETER BLOCK (input) */
        !            51: } tpb;
        !            52: 
        !            53: struct tpb cycool      /* tape parameter block to clear interrupts */
        !            54: = {
        !            55:        0L,             /* command */
        !            56:        0,0,            /* control */
        !            57:        0,              /* count */
        !            58:        0,              /* size */
        !            59:        0,              /* rec_over */
        !            60:        0,0,0,0,        /* pt_data */
        !            61:        0,0,            /* status */
        !            62:        0,0,0,0         /* pt_link */
        !            63: } ;    
        !            64: int cyblksiz = 1024;   /* foreign tape size as found in open routine */
        !            65: long cyblock;          /* next block number for i/o */
        !            66: /*
        !            67:  * Reset the controller.
        !            68:  */
        !            69: cyopen(io)
        !            70:        register struct iob *io;
        !            71: {
        !            72:        register ctlradr;
        !            73: 
        !            74:        ctlradr = cystd[0] + IOBASE;
        !            75:        SCP = (struct scp *)0xc06;              /* absolute - for setup */
        !            76:        TM_RESET(ctlradr,0xff); /* reset the controller */
        !            77:        /*
        !            78:         * Initialize the system configuration pointer
        !            79:         */
        !            80:        SCP->sysbus = 1;                        /* system width = 16 bits. */
        !            81:        /* initialize the pointer to the system configuration block */
        !            82:        set_pointer((long)&scb.sysblk[0],(char *)SCP->pt_scb);
        !            83:        /*
        !            84:         * Initialize the system configuration block.
        !            85:         */
        !            86:        scb.sysblk[0] = 0x3;            /* fixed value */
        !            87:        /* initialize the pointer to the channel control block */
        !            88:        set_pointer((long)&ccb.ccw[0],(char *)scb.pt_ccb);
        !            89:        /*
        !            90:         * Initialize the channel control block.
        !            91:         */
        !            92:        ccb.ccw[0] = 0x11;              /* normal interrupts */
        !            93:        /* initialize the pointer to the tape parameter block */
        !            94:        set_pointer((long)&tpb,(char *)ccb.pt_tpb);
        !            95:        /*
        !            96:         * set the command to be NO_OP.
        !            97:         */
        !            98:        tpb.cmd = NO_OP;
        !            99:        tpb.control[0] = CW_BL;         /* TPB not used on first attention */
        !           100:        tpb.control[1] = CW_16bits;
        !           101:        ccb.gate[0] = GATE_CLOSED;      
        !           102:        TM_ATTENTION(ctlradr, 0xff);    /* execute! */
        !           103:        cywait(10*1000);
        !           104:        /*
        !           105:         * set the command to be CONFIGURE.
        !           106:         */
        !           107:        tpb.cmd = CONFIG;
        !           108:        tpb.control[0] = CW_BL;         /* NO interrupt on completion */
        !           109:        tpb.control[1] = CW_16bits;
        !           110:        tpb.status[0] = tpb.status[1] = 0;
        !           111:        ccb.gate[0] = GATE_CLOSED;      
        !           112:        TM_ATTENTION(ctlradr, 0xff);    /* execute! */
        !           113:        cywait(10*1000);
        !           114:        uncache (&tpb.status[1]) ;
        !           115:        if (tpb.status[1] & CS_ERm) {
        !           116:           printf("Cypher initialization error!\n");
        !           117:           cy_decode_error(tpb.status[1]&CS_ERm);
        !           118:           _stop("");
        !           119:        }
        !           120:        if(cycmd(io,REWD_TA) == -1)
        !           121:                _stop("Rewind failed!\n");
        !           122:        while(io->i_boff > 0) {
        !           123:                if(cycmd(io,SPAC_FM) == -1)
        !           124:                        _stop("cy: seek failure!\n");
        !           125:                io->i_boff--;
        !           126:        }
        !           127: #ifdef NOBLOCK
        !           128:        if (io->i_flgs & F_READ) {
        !           129:                if((cyblksiz = cycmd(io,READ_FO)) == -1)
        !           130:                        _stop("Read foriegn tape failed!\n");
        !           131:                if(cycmd(io,REWD_TA) == -1)
        !           132:                        _stop("Rewind after read failed\n");
        !           133:        }
        !           134: #endif
        !           135: }
        !           136: 
        !           137: /* if tape was open for writing write a file mark */
        !           138: cyclose(io)
        !           139:        register struct iob *io;
        !           140: {
        !           141:        if (io->i_flgs & F_WRITE) cycmd(io,WRITE_FMARK);
        !           142:        cycmd(io,REWD_TA);
        !           143:        cyblock = 0;
        !           144: }
        !           145: 
        !           146: cystrategy(io,func)
        !           147:        register struct iob *io;
        !           148:        register long   func;
        !           149: {
        !           150: 
        !           151: #ifndef NOBLOCK
        !           152:        if ((func != SPACE) && (func != REWD_TA) && (io->i_bn != cyblock)) {
        !           153:                cycmd(io,SPACE);
        !           154:                tpb.rec_over = 0;
        !           155:        }
        !           156:        if(func==READ || func==WRITE) {
        !           157:                struct iob liob;
        !           158:                register struct iob *lio = &liob;
        !           159:                register count;
        !           160: 
        !           161:                liob = *io;
        !           162:                while(lio->i_cc > 0) {
        !           163:                        if((count = cycmd(lio, func)) == 0)
        !           164:                                return(-1);
        !           165:                        lio->i_cc -= count;
        !           166:                        lio->i_ma += count;
        !           167:                }
        !           168:                return(io->i_cc);
        !           169:        }
        !           170: #endif
        !           171:        return(cycmd(io, func));
        !           172: }
        !           173: 
        !           174: cycmd(io,func)
        !           175:        register struct iob *io;
        !           176:        long    func;
        !           177: {
        !           178:        register ctlradr;
        !           179:        short j;
        !           180: 
        !           181:        ctlradr = cystd[0] + IOBASE;
        !           182:        cywait(9000); 
        !           183:        if (func == READ) func = READ_TA;
        !           184:        else if (func == WRITE) func = WRIT_TA;
        !           185:        else if (func == WRITE_FMARK) func = WRIT_FM;
        !           186:        tpb.cmd = func;
        !           187:        uncache(&ccb.gate[0]);
        !           188:        while(ccb.gate[0] == GATE_CLOSED)
        !           189:                uncache(&ccb.gate[0]);
        !           190:        ccb.gate[0] = GATE_CLOSED;
        !           191:        tpb.control[0] = CW_BL;
        !           192:        tpb.control[1] = CW_16bits;
        !           193:        tpb.status[0] = tpb.status[1] = 0;
        !           194:        tpb.count = 0;
        !           195:        set_pointer((long)&tpb,(char *)ccb.pt_tpb);
        !           196:        switch (func) 
        !           197:        {
        !           198:        case READ_TA:
        !           199:                if (io->i_cc > cyblksiz)
        !           200:                        tpb.size = TM_SHORT(cyblksiz);
        !           201:                else tpb.size = TM_SHORT(io->i_cc);
        !           202:                set_pointer((long)io->i_ma,(char *)tpb.pt_data);
        !           203:                cyblock += 1;
        !           204:                break;
        !           205:        case WRIT_TA:
        !           206:                tpb.size = TM_SHORT(io->i_cc);
        !           207:                set_pointer((long)io->i_ma,(char *)tpb.pt_data);
        !           208:                cyblock += 1;
        !           209:                break;
        !           210:        case SPACE:
        !           211:                if ((j = io->i_bn - cyblock) < 0) {
        !           212:                        j = -j;
        !           213:                        tpb.control[1] |= CW_R;
        !           214:                        cyblock -= j;
        !           215:                }
        !           216:                else
        !           217:                        cyblock += j;
        !           218:                tpb.rec_over = TM_SHORT(j);
        !           219:                break;
        !           220:        case REWD_TA:
        !           221:                cyblock = 0;
        !           222:                break;
        !           223:        }
        !           224:        TM_ATTENTION(ctlradr, 0xff);    /* execute! */
        !           225:        if (func == REWD_TA || func == SPACE) {
        !           226:                cywait(60*5*1000);
        !           227:        }
        !           228:        else cywait(10*1000);
        !           229:        /*
        !           230:         * First we clear the interrupt and close the gate.
        !           231:         */
        !           232:        mtpr (0, PADC);
        !           233:        ccb.gate[0] = GATE_CLOSED;
        !           234:        set_pointer((int)&cycool,(char *)ccb.pt_tpb);
        !           235:        cycool.cmd = NO_OP;     /* no operation */
        !           236:        cycool.control[0] = CW_BL;      /* No INTERRUPTS */
        !           237:        cycool.control[1] = 0;
        !           238:        TM_ATTENTION(ctlradr,0xff);     /* cool it ! */
        !           239:        cywait(20000); 
        !           240:        uncache (&tpb.status[1] ) ; 
        !           241:        if (tpb.status[1] & CS_ERm) {
        !           242:                cy_decode_error(tpb.status[1]&CS_ERm);
        !           243:                return -1;
        !           244:        }
        !           245:        uncache (&tpb.count);
        !           246:        return((long)TM_SHORT(tpb.count));
        !           247: }
        !           248:        
        !           249: 
        !           250: 
        !           251: cyprint_error(message)
        !           252: register char  *message;
        !           253: {
        !           254:        printf("cy0: %s.\n", message);
        !           255: }
        !           256: 
        !           257: /*
        !           258: */
        !           259: 
        !           260: cy_decode_error(status)
        !           261: register int   status;
        !           262: {
        !           263:        switch(status) {
        !           264:        case ER_TO1:
        !           265:        case ER_TO2:
        !           266:        case ER_TO3:
        !           267:        case ER_TO4:
        !           268:        case ER_TO5:
        !           269:                cyprint_error("Drive timed out during transfer");
        !           270:                break;
        !           271:        case ER_TO6:    
        !           272:                cyprint_error("Non-existant system memory reference");
        !           273:                break;
        !           274:        case ER_DIAG:
        !           275:        case ER_JUMP:
        !           276:                cyprint_error("Controller micro diagnostics failed");
        !           277:                break;
        !           278:        case ER_HARD:
        !           279:                cyprint_error("Unrecoverble media error");
        !           280:                break;
        !           281:        case ER_TOF:
        !           282:                if (tpb.cmd == WRIT_TA)
        !           283:                        cyprint_error("Unsatisfactory media");
        !           284:                break;
        !           285:        case ER_FIFO:
        !           286:                cyprint_error("Data transfer over run");
        !           287:                break;
        !           288:        case ER_TRN:
        !           289:                cyprint_error("Drive is not ready");
        !           290:                break;
        !           291:        case ER_PRO:
        !           292:                cyprint_error("Tape is write protected");
        !           293:                break;
        !           294:        case ER_PSUM:
        !           295:                cyprint_error("Checksum error in controller proms");
        !           296:                break;
        !           297:        case ER_PARI:
        !           298:                cyprint_error("Unrecoverable tape parity error");
        !           299:                break;
        !           300:        case ER_BLAN:
        !           301:                cyprint_error("Blank tape found where data was expected");
        !           302:                break;
        !           303:        case ER_ER:
        !           304:                cyprint_error("Unrecoverble hardware error");
        !           305:        default:
        !           306:                break;
        !           307:        }
        !           308: }
        !           309: 
        !           310: 
        !           311: long 
        !           312: cywait(timeout)
        !           313:        long timeout;
        !           314: {
        !           315:        long dummy;
        !           316: 
        !           317:        uncache (&ccb.gate[0]) ;
        !           318:        while (ccb.gate[0] != GATE_OPEN) {
        !           319:                uncache (&ccb.gate[0]) ;
        !           320:                DELAY(1000);
        !           321:                if (--timeout == 0) {
        !           322:                        cyprint_error("Transfer timeout");
        !           323:                        _stop("");
        !           324:                }
        !           325:        }
        !           326: }
        !           327: 
        !           328: /*
        !           329:  *  Set a TAPEMASTER pointer (first parameter), into the
        !           330:  *  4 bytes array pointed by the second parameter.
        !           331:  */
        !           332: set_pointer(pointer,dest)
        !           333: long pointer;
        !           334: char * dest;
        !           335: {
        !           336:        *dest++ = pointer & 0xff;               /* low byte - offset */
        !           337:        *dest++ = (pointer >> 8) & 0xff;        /* high byte - offset */
        !           338:        *dest++ = 0; 
        !           339:        *dest   = (pointer & 0xf0000) >> 12;    /* base */
        !           340: }
        !           341: 
        !           342: movow(word, destination)
        !           343: long word, destination;
        !           344: {
        !           345:        asm("movow      6(fp),*8(fp);");
        !           346: }
        !           347: 
        !           348: movob(byte, destination)
        !           349: long byte, destination;
        !           350: {
        !           351:        asm("movob      7(fp),*8(fp);");
        !           352: }

unix.superglobalmegacorp.com

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