Annotation of 43BSDReno/sys/tahoestand/cy.c, revision 1.1

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

unix.superglobalmegacorp.com

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