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