Annotation of cci/sys/stand/cy.c, revision 1.1.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.