Annotation of 43BSDTahoe/sys/tahoestand/cy.c, revision 1.1.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.