Annotation of 43BSDTahoe/sys/tahoestand/ncy.c, revision 1.1

1.1     ! root        1: /*     cy.c    7.7     88/05/24        */
        !             2: 
        !             3: /*
        !             4:  * Cypher tape driver. Stand alone version.
        !             5:  */
        !             6: #include "../machine/pte.h"
        !             7: #include "../machine/mtpr.h"
        !             8: 
        !             9: #include "param.h"
        !            10: #include "inode.h"
        !            11: #include "fs.h"
        !            12: 
        !            13: #include "saio.h"
        !            14: 
        !            15: #define CYERROR
        !            16: #include "../tahoevba/cyreg.h"
        !            17: #include "../tahoevba/vbaparam.h"
        !            18: 
        !            19: /*
        !            20:  * NB: this driver assumes unit 0 throughout.
        !            21:  */
        !            22: long   cystd[] = { 0xf4000, 0 };
        !            23: #define        CYADDR(i)       (cystd[i] + (int)VBIOBASE)
        !            24: 
        !            25: struct cyscp *cyscp[] = { (struct cyscp *)0xc06, (struct cyscp *)0 };
        !            26: #define        CYSCP(i)        (cyscp[i])
        !            27: 
        !            28: struct cyscp *SCP;
        !            29: struct cyscb scb;
        !            30: struct cyccb ccb;
        !            31: struct cytpb tpb;
        !            32: struct cytpb cycool;           /* tape parameter block to clear interrupts */
        !            33: #ifdef notdef
        !            34: int    cyblocksize = 1024;     /* foreign tape size as found in open routine */
        !            35: #endif
        !            36: int    cybufsize;              /* controller buffer size */
        !            37: long   cyblock;                /* next block number for i/o */
        !            38: 
        !            39: /*
        !            40:  * Reset the controller.
        !            41:  */
        !            42: cyopen(io)
        !            43:        register struct iob *io;
        !            44: {
        !            45:        register ctlradr = CYADDR(0);
        !            46:        register int skip;
        !            47: 
        !            48:        if ((u_int)io->i_adapt)
        !            49:                return (EADAPT);
        !            50:        if ((u_int)io->i_ctlr)
        !            51:                return (ECTLR);
        !            52:        SCP = CYSCP(0);                         /* absolute - for setup */
        !            53:        CY_RESET(ctlradr);                      /* reset the controller */
        !            54:        /*
        !            55:         * Initialize the system configuration pointer
        !            56:         */
        !            57:        SCP->csp_buswidth = 1;                  /* system width = 16 bits. */
        !            58:        SCP->csp_unused = 0;
        !            59:        /* initialize the pointer to the system configuration block */
        !            60:        cyldmba(SCP->csp_scb, (caddr_t)&scb);
        !            61:        /*
        !            62:         * Initialize the system configuration block.
        !            63:         */
        !            64:        scb.csb_fixed = CSB_FIXED;              /* fixed value */
        !            65:        /* initialize the pointer to the channel control block */
        !            66:        cyldmba(scb.csb_ccb, (caddr_t)&ccb);
        !            67:        /*
        !            68:         * Initialize the channel control block.
        !            69:         */
        !            70:        ccb.cbcw = CBCW_IE;             /* normal interrupts */
        !            71:        /* initialize the pointer to the tape parameter block */
        !            72:        cyldmba(ccb.cbtpb, (caddr_t)&tpb);
        !            73:        /*
        !            74:         * set the command to be CY_NOP.
        !            75:         */
        !            76:        tpb.tpcmd = CY_NOP;
        !            77:        /*
        !            78:         * TPB not used on first attention
        !            79:         */
        !            80:        tpb.tpcontrol = CYCW_LOCK | CYCW_16BITS;
        !            81:        ccb.cbgate = GATE_CLOSED;       
        !            82:        CY_GO(ctlradr);                 /* execute! */
        !            83:        cywait(10*1000);
        !            84:        /*
        !            85:         * set the command to be CY_CONFIGURE.
        !            86:         * NO interrupt on completion.
        !            87:         */
        !            88:        tpb.tpcmd = CY_CONFIG;
        !            89:        tpb.tpcontrol = CYCW_LOCK | CYCW_16BITS;
        !            90:        tpb.tpstatus = 0;
        !            91:        ccb.cbgate = GATE_CLOSED;       
        !            92:        CY_GO(ctlradr);                 /* execute! */
        !            93:        cywait(10*1000);
        !            94:        uncache(&tpb.tpstatus);
        !            95:        if (tpb.tpstatus & CYS_ERR) {
        !            96:                printf("Cypher initialization error!\n");
        !            97:                cy_print_error(tpb.tpcmd, tpb.tpstatus);
        !            98:                return (ENXIO);
        !            99:        }
        !           100:        uncache(&tpb.tpcount);
        !           101:        cybufsize = tpb.tpcount;
        !           102:        if (cycmd(io, CY_REW) == -1) {
        !           103:                printf("cy%d: Rewind failed!\n", io->i_unit);
        !           104:                return (ENXIO);
        !           105:        }
        !           106:        for (skip = io->i_part; skip--;)
        !           107:                if (cycmd(io, CY_FSF) == -1) {
        !           108:                        printf("cy%d: seek failure!\n", io->i_unit);
        !           109:                        return (ENXIO);
        !           110:                }
        !           111: #ifdef notdef
        !           112: #ifdef NOBLOCK
        !           113:        if (io->i_flgs & F_READ) {
        !           114:                cyblocksize = cycmd(io, CY_READFORN);
        !           115:                if (cyblocksize == -1)
        !           116:                        _stop("Read foreign tape failed\n");
        !           117:                cyblock++;              /* XXX force backspace record */
        !           118:                if (cycmd(io, CY_SFORW) == -1)
        !           119:                        _stop("Backspace after read foreign failed\n");
        !           120:        }
        !           121: #endif
        !           122: #endif
        !           123:        return (0);
        !           124: }
        !           125: 
        !           126: cyclose(io)
        !           127:        register struct iob *io;
        !           128: {
        !           129: 
        !           130:        if (io->i_flgs & F_WRITE) {     /* if writing, write file marks */
        !           131:                cycmd(io, CY_WEOF);
        !           132:                cycmd(io, CY_WEOF);
        !           133:        }
        !           134:        cycmd(io, CY_REW);
        !           135: }
        !           136: 
        !           137: cystrategy(io, func)
        !           138:        register struct iob *io;
        !           139:        register func;
        !           140: {
        !           141:        register count;
        !           142: 
        !           143: #ifndef NOBLOCK
        !           144:        if (func != CY_SFORW && func != CY_REW && io->i_bn != cyblock) {
        !           145:                cycmd(io, CY_SFORW);
        !           146:                tpb.tprec = 0;
        !           147:        }
        !           148:        if (func == READ || func == WRITE) {
        !           149:                struct iob liob;
        !           150:                register struct iob *lio = &liob;
        !           151: 
        !           152:                liob = *io;
        !           153:                while (lio->i_cc > 0) {
        !           154:                        if ((count = cycmd(lio, func)) == 0) {
        !           155:                                printf("cy%d: I/O error bn %d\n",
        !           156:                                    io->i_unit, io->i_bn);
        !           157:                                return (-1);
        !           158:                        }
        !           159:                        lio->i_cc -= count;
        !           160:                        lio->i_ma += count;
        !           161:                }
        !           162:                return (io->i_cc);
        !           163:        }
        !           164: #endif
        !           165:        count = cycmd(io, func);
        !           166:        if (count == -1)
        !           167:                printf("cy%d: I/O error bn %d\n", io->i_unit, io->i_bn);
        !           168:        return (count);
        !           169: }
        !           170: 
        !           171: cycmd(io, func)
        !           172:        register struct iob *io;
        !           173:        long func;
        !           174: {
        !           175:        register ctlradr = CYADDR(0);
        !           176:        int timeout = 0;
        !           177:        int err;
        !           178:        short j;
        !           179: 
        !           180:        cywait(9000);                   /* shouldn't be needed */
        !           181: #define        PACKUNIT(unit)  (((unit&1)<<11)|((unit&2)<<9)|((unit&4)>>2))
        !           182:        tpb.tpcontrol = CYCW_LOCK | CYCW_16BITS | PACKUNIT(io->i_unit);
        !           183:        tpb.tpstatus = 0;
        !           184:        tpb.tpcount = 0;
        !           185:        cyldmba(ccb.cbtpb, (caddr_t)&tpb);
        !           186:        tpb.tpcmd = func;
        !           187:        switch (func) {
        !           188:        case READ:
        !           189: #ifdef notdef
        !           190:                if (io->i_cc > cyblocksize)
        !           191:                        tpb.tpsize = htoms(cyblocksize);
        !           192:                else
        !           193: #endif
        !           194:                tpb.tpsize = htoms(io->i_cc);
        !           195:                cyldmba(tpb.tpdata, io->i_ma);
        !           196:                tpb.tpcmd = CY_RCOM;
        !           197:                cyblock++;
        !           198:                break;
        !           199:        case WRITE:
        !           200:                tpb.tpcmd = CY_WCOM;
        !           201:                tpb.tpsize = htoms(io->i_cc);
        !           202:                cyldmba(tpb.tpdata, io->i_ma);
        !           203:                cyblock++;
        !           204:                break;
        !           205:        case CY_SFORW:
        !           206:                if ((j = io->i_bn - cyblock) < 0) {
        !           207:                        j = -j;
        !           208:                        tpb.tpcontrol |= CYCW_REV;
        !           209:                        cyblock -= j;
        !           210:                } else
        !           211:                        cyblock += j;
        !           212:                tpb.tprec = htoms(j);
        !           213:                timeout = 60*5;
        !           214:                break;
        !           215:        case CY_FSF:
        !           216:                tpb.tprec = htoms(1);
        !           217:                /* fall thru... */
        !           218:        case CY_REW:
        !           219:                cyblock = 0;
        !           220:                timeout = 60*5;
        !           221:                break;
        !           222:        }
        !           223:        ccb.cbgate = GATE_CLOSED;
        !           224:        CY_GO(ctlradr);                 /* execute! */
        !           225:        if (timeout == 0)
        !           226:                timeout = 10;
        !           227:        cywait(timeout*1000);
        !           228:        /*
        !           229:         * First we clear the interrupt and close the gate.
        !           230:         */
        !           231:        mtpr(PADC, 0);
        !           232:        ccb.cbgate = GATE_CLOSED;
        !           233:        cyldmba(ccb.cbtpb, (caddr_t)&cycool);
        !           234:        cycool.tpcontrol = CYCW_LOCK;   /* No INTERRUPTS */
        !           235:        CY_GO(ctlradr);
        !           236:        cywait(20000); 
        !           237:        uncache(&tpb.tpstatus); 
        !           238:        if ((err = (tpb.tpstatus & CYS_ERR)) &&
        !           239:            err != CYER_FM && (err != CYER_STROBE || tpb.tpcmd != CY_RCOM)) {
        !           240:                cy_print_error(tpb.tpcmd, tpb.tpstatus);
        !           241:                io->i_error = EIO;
        !           242:                return (-1);
        !           243:        }
        !           244:        uncache(&tpb.tpcount);
        !           245:        return ((int)htoms(tpb.tpcount));
        !           246: }
        !           247: 
        !           248: cy_print_error(op, status)
        !           249:        int op, status;
        !           250: {
        !           251:        register char *message;
        !           252: 
        !           253:        if ((status & CYS_ERR) < NCYERROR)
        !           254:                message = cyerror[status & CYS_ERR];
        !           255:        else
        !           256:                message = "unknown error";
        !           257:        printf("cy0: cmd %x %s, status=%b.\n", op, message, status, CYS_BITS);
        !           258: }
        !           259: 
        !           260: cywait(timeout)
        !           261:        register timeout;
        !           262: {
        !           263:        do {
        !           264:                DELAY(1000);
        !           265:                uncache(&ccb.cbgate);
        !           266:        } while (ccb.cbgate != GATE_OPEN && --timeout > 0);
        !           267:        if (timeout <= 0)
        !           268:                _stop("cy: Transfer timeout");
        !           269: }
        !           270: 
        !           271: /*
        !           272:  * Load a 20 bit pointer into a Tapemaster pointer.
        !           273:  */
        !           274: cyldmba(reg, value)
        !           275:        register caddr_t reg;
        !           276:        caddr_t value;
        !           277: {
        !           278:        register int v = (int)value;
        !           279: 
        !           280:        *reg++ = v;
        !           281:        *reg++ = v >> 8;
        !           282:        *reg++ = 0;
        !           283:        *reg = (v&0xf0000) >> 12;
        !           284: }

unix.superglobalmegacorp.com

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