Annotation of researchv9/sys/boot/stand/tm.c, revision 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.