Annotation of researchv9/sys/boot/stand/tm.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)tm.c       1.1 86/02/03    Copyr 1985 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: /*
                     10:  * Standalone driver for Ciprico TapeMaster Multibus tape controller
                     11:  */
                     12: 
                     13: #include "saio.h"
                     14: #include "../sundev/tmreg.h"
                     15: #include "../mon/cpu.map.h"
                     16: #include "../mon/cpu.addrs.h"
                     17: 
                     18: /*
                     19:  * Standard addresses for this board
                     20:  */
                     21: #define NTMADDR        2
                     22: unsigned long tmstd[] = { 0xA0, 0xA2 };
                     23: 
                     24: /*
                     25:  * Structure of our dma space
                     26:  */
                     27: #define MAXTMREC       (20*1024)       /* max size tape rec allowed */
                     28: struct tmdma {
                     29:        struct tm_mbinfo tm_mbinfo;     /* Multibus IOPB crap */
                     30:        char            tmbuf[MAXTMREC];/* Block of data */
                     31: };
                     32: 
                     33: #define        MB_DMA_ADDR_MASK        0x000FFFFF      /* Low meg */
                     34: 
                     35: /*
                     36:  * Driver definition
                     37:  */
                     38: struct devinfo tminfo = {
                     39:        sizeof(struct tmdevice),        /* Size of device registers */
                     40:        sizeof(struct tmdma),           /* DMA space required */
                     41:        0,                              /* Local variable space */
                     42:        NTMADDR,                        /* # of standard addresses */
                     43:        tmstd,                          /* Standard addr vector */
                     44:        MAP_MBIO,                       /* Map type of device regs */
                     45:        MAXTMREC,                       /* transfer size */
                     46: };
                     47: 
                     48: /*
                     49:  * What facilities we export to the world
                     50:  */
                     51: int    tmstrategy(), tmopen(), tmclose();
                     52: extern int ttboot();
                     53: extern int nullsys();
                     54: 
                     55: struct boottab mtdriver = {
                     56:        "mt", nullsys, ttboot, tmopen, tmclose, tmstrategy,
                     57:        "mt: TapeMaster 9-track tape", &tminfo,
                     58: };
                     59: 
                     60: 
                     61: /*
                     62:  * Open a tape drive
                     63:  */
                     64: tmopen(sip)
                     65:        register struct saioreq *sip;
                     66: {
                     67:        register skip;
                     68: 
                     69:        if (tminit(sip) == -1)
                     70:                return (-1);
                     71:        tmcmd(sip, TM_REWINDX);
                     72:        skip = sip->si_boff;
                     73:        while (skip--) {
                     74:                sip->si_cc = 0;
                     75:                tmcmd(sip, TM_SEARCH);
                     76:        }
                     77:        return (0);
                     78: }
                     79: 
                     80: tmclose(sip)
                     81:        struct saioreq *sip;
                     82: {
                     83: 
                     84:        tmcmd(sip, TM_REWINDX);
                     85: }
                     86: 
                     87: tmstrategy(sip, rw)
                     88:        register struct saioreq *sip;
                     89:        int rw;
                     90: {
                     91:        int func = (rw == WRITE) ? TM_WRITE : TM_READ;
                     92: 
                     93:        return tmcmd(sip, func);
                     94: }
                     95: 
                     96: #define NOTZERO        1       /* don't care value-but not zero (clr inst botch) */
                     97: #define ATTN(c)        (((struct tmdevice *)c)->tmdev_attn=NOTZERO)
                     98: #define RESET(c)       (((struct tmdevice *)c)->tmdev_reset=NOTZERO)
                     99: #define clrtpb(tp)     bzero((caddr_t)(tp), sizeof *(tp));
                    100: 
                    101: tmcmd(sip, func)
                    102:        register struct saioreq *sip;
                    103: {
                    104: #      define  tmdmap  ((struct tmdma *)sip->si_dmaaddr)
                    105: #      define  tmb     (&tmdmap->tm_mbinfo)
                    106:        register struct tmdevice *tmaddr =
                    107:                (struct tmdevice *)sip->si_devaddr;
                    108:        register struct tpb *tpb = &tmb->tmb_tpb;
                    109:        int count = 1;
                    110:        int size = 0;
                    111:        struct tmstat tms;
                    112:        int err;
                    113: 
                    114:        switch (func) {
                    115: 
                    116:        case TM_READ:
                    117:                size = sip->si_cc;
                    118:                break;
                    119: 
                    120:        case TM_WRITE:
                    121:                size = sip->si_cc;
                    122:                swab((char *)sip->si_ma, tmdmap->tmbuf, size);
                    123:                break;
                    124:        }
                    125: 
                    126:        clrtpb(tpb);
                    127:        tpb->tm_cmd = func &~ TM_DIRBIT;
                    128:        tpb->tm_ctl.tmc_rev = func & TM_DIRBIT;
                    129:        tpb->tm_ctl.tmc_width = 1;
                    130:        tpb->tm_ctl.tmc_speed = sip->si_unit & 08;
                    131:        tpb->tm_ctl.tmc_tape = sip->si_unit & 03;
                    132:        tpb->tm_rcount = count;
                    133:        tpb->tm_bsize = size;
                    134:        c68t86((long)tmdmap->tmbuf, &tpb->tm_baddr);
                    135:        tmb->tmb_ccb.tmccb_gate = TMG_CLOSED;
                    136: 
                    137:        /* Start the command and wait for completion */
                    138:        ATTN(tmaddr);
                    139:        while (tmb->tmb_ccb.tmccb_gate == TMG_CLOSED)
                    140:                ;
                    141: 
                    142:        tms = tpb->tm_stat;
                    143:        err = tms.tms_error;
                    144: 
                    145:        /*
                    146:         * An operation completed... record status
                    147:         */
                    148:        if (err == E_EOT && tms.tms_load)
                    149:                err = E_NOERROR;
                    150:        /*
                    151:         * Check for errors.
                    152:         */
                    153:        if (err != E_NOERROR && err != E_SHORTREC) {
                    154:                if (err == E_EOF || err == E_EOT)
                    155:                        return (0);
                    156:                /* Note: TapeMaster does retries for us */
                    157:                printf("tm hard err %x\n", err);
                    158:                return (-1);
                    159:        }
                    160:        if (func == TM_READ)
                    161:                swab(tmdmap->tmbuf, sip->si_ma, tpb->tm_count);
                    162:        return (tpb->tm_count);
                    163: #      undef   tmdma
                    164: #      undef   tmb
                    165: }
                    166: 
                    167: #define SPININIT 1000000
                    168: /*
                    169:  * Initialize a controller
                    170:  * Reset it, set up SCP, SCB, and CCB,
                    171:  * and give it an attention.
                    172:  * Make sure its there by waiting for the gate to open
                    173:  * Once initialization is done, issue CONFIG just to be safe.
                    174:  */
                    175: tminit(sip)
                    176:        register struct saioreq *sip;
                    177: {
                    178:        register struct tm_mbinfo *tmb = 
                    179:                &((struct tmdma *)(sip->si_dmaaddr))->tm_mbinfo;
                    180:        register struct tmdevice *tmaddr =
                    181:                (struct tmdevice *)sip->si_devaddr;
                    182:        register struct tpb *tpb = &tmb->tmb_tpb;
                    183: 
                    184:        bzero((caddr_t)tmb, sizeof (struct tm_mbinfo));
                    185:        RESET(tmaddr);
                    186:        
                    187:        /* setup System Configuration Block */
                    188:        tmb->tmb_scb.tmscb_03 = tmb->tmb_scb.tmscb_03x = TMSCB_CONS;
                    189:        c68t86((long)&tmb->tmb_ccb, &tmb->tmb_scb.tmccb_ptr);
                    190: 
                    191:        /* setup Channel Control Block */
                    192:        tmb->tmb_ccb.tmccb_gate = TMG_CLOSED;
                    193: 
                    194:        {
                    195:                register struct tmscp *tmscp;
                    196:                char *temp;
                    197:                register int spin;
                    198:                int virtstart;
                    199: 
                    200:                /* Snatch the dma space that this screwy Intel device needs */
                    201:                /* get the virtual address */
                    202:                tmscp = (struct tmscp *)(DVMA_BASE + TM_SCPADDR);
                    203:                virtstart = getpgmap((char *)tmscp);
                    204:                /* get random page */
                    205:                temp = resalloc(RES_MAINMEM, sizeof (struct tmscp));
                    206:                /* point virt at new page */
                    207:                setpgmap((char *)tmscp, getpgmap(temp));
                    208: 
                    209:                /* setup System Configuration Pointer */
                    210:                tmscp->tmscb_bus = tmscp->tmscb_busx = TMSCB_BUS16;
                    211:                c68t86((long)&tmb->tmb_scb, &tmscp->tmscb_ptr);
                    212: 
                    213:                /* Start the TapeMaster and wait til it says "done" */
                    214:                ATTN(tmaddr); 
                    215:                for (spin = SPININIT; tmb->tmb_ccb.tmccb_gate != TMG_OPEN; )
                    216:                        if (--spin <= 0)
                    217:                                break;
                    218: 
                    219:                /* Give back the dma space this screwy Intel device needs */
                    220:                setpgmap((char *)tmscp, virtstart);
                    221: 
                    222:                if (spin <= 0) {
                    223:                        printf("tm: no response from ctlr %x\n", sip->si_ctlr);
                    224:                        return (-1);
                    225:                }
                    226:        }
                    227: 
                    228:        /* Finish CCB, point it at TPB */
                    229:        tmb->tmb_ccb.tmccb_ccw = TMC_NORMAL;
                    230:        c68t86((long)tpb, &tmb->tmb_ccb.tmtpb_ptr);
                    231: 
                    232:        /* Issue CONFIG command */
                    233:        clrtpb(tpb);
                    234:        tpb->tm_cmd = TM_CONFIG;
                    235:        tpb->tm_cmd2 = 0;
                    236:        tpb->tm_ctl.tmc_width = 1;
                    237: 
                    238:        /* Get the gate */
                    239:        while (tmb->tmb_ccb.tmccb_gate != TMG_OPEN)
                    240:                ;
                    241:        tmb->tmb_ccb.tmccb_gate = TMG_CLOSED;
                    242: 
                    243:        /* Start the command and wait for completion */
                    244:        ATTN(tmaddr);
                    245:        while (tmb->tmb_ccb.tmccb_gate == TMG_CLOSED)
                    246:                ;
                    247: 
                    248:        /* Check and report errors */
                    249:        if (tpb->tm_stat.tms_error) {
                    250:                printf("tm: error %d during config of ctlr %x\n", 
                    251:                        tpb->tm_stat.tms_error, sip->si_ctlr);
                    252:                tpb->tm_stat.tms_error = 0;
                    253:                return (-1);
                    254:        }
                    255:        return (0);
                    256: }
                    257: 
                    258: /*
                    259:  * Convert a 68000 address into a 8086 address
                    260:  * This involves translating a virtual address into a
                    261:  * physical multibus address and converting the 20 bit result
                    262:  * into a two word base and offset.
                    263:  */
                    264: static c68t86(a68, a86)
                    265:        long a68;
                    266:        ptr86_t *a86;
                    267: {
                    268: 
                    269:        a68 &= MB_DMA_ADDR_MASK;
                    270:        a86->a_offset = a68 & 0xFFFF;
                    271:        a86->a_base = (a68 & 0xF0000) >> 4;
                    272: }

unix.superglobalmegacorp.com

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