Annotation of researchv10dc/sys/md/mba.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * massbus adapter subroutines
        !             3:  * this version for comet
        !             4:  */
        !             5: 
        !             6: #include "sys/param.h"
        !             7: #include "sys/nxaddr.h"
        !             8: #include "sys/mbaddr.h"
        !             9: #include "sys/mba.h"
        !            10: #include "sys/pte.h"
        !            11: #include "sys/buf.h"
        !            12: 
        !            13: /*
        !            14:  * hardware things
        !            15:  */
        !            16: 
        !            17: #define        NMAP    256
        !            18: 
        !            19: struct mbaregs {
        !            20:        long conf;      /* configuration register; unused */
        !            21:        long cr;        /* control register */
        !            22:        long sr;        /* status register */
        !            23:        long va;        /* address */
        !            24:        long bcr;       /* count */
        !            25:        long _junk0[251];       /* pad up to 0x400 */
        !            26:        long devreg[MBAUNITS][32];
        !            27:        long map[NMAP];
        !            28: };
        !            29: 
        !            30: #define        mbas    devreg[0][4]    /* attn summary reg; same in all devs */
        !            31: 
        !            32: #define        CRINIT  01      /* cr -- adapter init */
        !            33: #define        CRIE    04      /* cr -- interrupt enable */
        !            34: 
        !            35: #define        MRV     0x80000000      /* map register -- valid bit */
        !            36: #define        MPAGE   0x001fffff      /* map register -- page number */
        !            37:                /* really only 15 bits on comet; others seem to read 0 */
        !            38: 
        !            39: /*
        !            40:  * things from mkconf
        !            41:  */
        !            42: 
        !            43: extern int mbacnt;
        !            44: extern struct mba mba[];
        !            45: extern struct nxaddr mbaaddr[];
        !            46: extern int (*mbavec[][MBAUNITS])();
        !            47: extern char mbaid[][MBAUNITS];
        !            48: 
        !            49: #define        BUSY    01      /* this mba already transferring */
        !            50: #define        INIT    02      /* did init */
        !            51: 
        !            52: #define        NOUNIT  (-1)    /* in mbq */
        !            53: 
        !            54: caddr_t
        !            55: mbaddr(ap)
        !            56: register struct mbaddr *ap;
        !            57: {
        !            58:        register struct mba *mp;
        !            59: 
        !            60:        if (ap->mbno < 0 || ap->mbno >= mbacnt)
        !            61:                return (0);
        !            62:        if (ap->unit < 0 || ap->unit >= MBAUNITS)
        !            63:                return (0);
        !            64:        mp = &mba[ap->mbno];
        !            65:        if ((mp->flags & INIT) == 0
        !            66:        &&   mbinit(ap->mbno) == 0)
        !            67:                return (0);
        !            68:        return ((caddr_t)mp->addr->devreg[ap->unit]);
        !            69: }
        !            70: 
        !            71: mbinit(dev)
        !            72: int dev;
        !            73: {
        !            74:        register struct mba *mp;
        !            75: 
        !            76:        mp = &mba[dev];
        !            77:        if ((mp->addr = (struct mbaregs *)nxaddr(&mbaaddr[dev])) == NULL
        !            78:        ||  badaddr(&mp->addr->conf, sizeof(long))) {
        !            79:                printf("mba%d absent\n");
        !            80:                return (0);
        !            81:        }
        !            82:        mp->addr->cr = CRINIT;
        !            83:        mp->addr->cr = CRIE;
        !            84:        mp->first = NOUNIT;
        !            85:        mp->flags |= INIT;
        !            86:        return (1);
        !            87: }
        !            88: 
        !            89: /*
        !            90:  * enqueue a transfer for this unit;
        !            91:  * if not busy, start
        !            92:  * if there's already a transfer for this unit, something is wrong
        !            93:  */
        !            94: mbstart(ap, bp, go)
        !            95: register struct mbaddr *ap;
        !            96: register struct buf *bp;
        !            97: int (*go)();
        !            98: {
        !            99:        register struct mba *mp;
        !           100:        register int i;
        !           101: 
        !           102:        mp = &mba[ap->mbno];
        !           103:        i = ap->unit;
        !           104:        if (mp->mbuf[i])
        !           105:                panic("mbstart");
        !           106:        if (mp->first == NOUNIT)
        !           107:                mp->first = i;
        !           108:        else
        !           109:                mp->mbq[mp->last] = i;
        !           110:        mp->last = i;
        !           111:        mp->mbq[i] = NOUNIT;
        !           112:        mp->mbuf[i] = bp;
        !           113:        mp->xstart[i] = go;
        !           114:        if ((mp->flags & BUSY) == 0)
        !           115:                mbxfer(mp);
        !           116: }
        !           117: 
        !           118: /*
        !           119:  * really start a transfer
        !           120:  * mp->lastoff is saved only for mbadj
        !           121:  */
        !           122: 
        !           123: mbxfer(mp)
        !           124: register struct mba *mp;
        !           125: {
        !           126:        register struct mbaregs *reg;
        !           127:        register struct pte *p;
        !           128:        register long *map;
        !           129:        register long size;
        !           130:        register struct buf *bp;
        !           131: 
        !           132:        if (mp->first == NOUNIT)
        !           133:                return;
        !           134:        reg = mp->addr;
        !           135:        bp = mp->mbuf[mp->first];
        !           136:        mp->lastoff = (long)bp->b_un.b_addr & PGOFSET;
        !           137:        size = btoc(bp->b_bcount);
        !           138:        if (mp->lastoff)
        !           139:                size++;
        !           140:        if (size >= NMAP)
        !           141:                size = NMAP-1;  /* tough */
        !           142:        p = btopte(bp);
        !           143:        map = reg->map;
        !           144:        while (--size >= 0)
        !           145:                *map++ = p++->pg_pfnum | MRV;
        !           146:        *map = 0;               /* safety */
        !           147:        reg->bcr = -bp->b_bcount;
        !           148:        reg->va = mp->lastoff;
        !           149:        mp->flags |= BUSY;
        !           150:        (*mp->xstart[mp->first])(bp);
        !           151: }
        !           152: 
        !           153: /*
        !           154:  * cheats needed for ECC correction
        !           155:  * must be called from interrupt code,
        !           156:  * before we've started another transfer
        !           157:  */
        !           158: 
        !           159: long
        !           160: mbcuraddr(ap)
        !           161: struct mbaddr *ap;
        !           162: {
        !           163:        return (mba[ap->mbno].addr->va);
        !           164: }
        !           165: 
        !           166: /*
        !           167:  * adjust registers to redo current transfer
        !           168:  * somewhere in the middle, but not where we were
        !           169:  * new buffer address is original+aoff;
        !           170:  * new count is as given
        !           171:  */
        !           172: 
        !           173: mbadj(ap, aoff, count)
        !           174: struct mbaddr *ap;
        !           175: int aoff, count;
        !           176: {
        !           177:        register struct mba *mp;
        !           178:        register struct mbaregs *reg;
        !           179: 
        !           180:        mp = &mba[ap->mbno];
        !           181:        reg = mp->addr;
        !           182:        reg->bcr = -count;
        !           183:        reg->va = aoff + mp->lastoff;
        !           184: }
        !           185: 
        !           186: /*
        !           187:  * xfer was restarted
        !           188:  * just mark adapter busy again, and delicately re-insert us in the queue
        !           189:  * -- we know we were at the head before
        !           190:  */
        !           191: 
        !           192: mbcontin(ap)
        !           193: register struct mbaddr *ap;
        !           194: {
        !           195:        register struct mba *mp;
        !           196: 
        !           197:        mp = &mba[ap->mbno];
        !           198:        mp->flags |= BUSY;
        !           199:        mp->mbq[ap->unit] = mp->first;
        !           200:        mp->first = ap->unit;
        !           201: }
        !           202: 
        !           203: /*
        !           204:  * get, put a byte in MASSBUS space
        !           205:  */
        !           206: 
        !           207: static long
        !           208: mbphys(ap, addr)
        !           209: struct mbaddr *ap;
        !           210: long addr;
        !           211: {
        !           212:        register long m;
        !           213:        register int pg;
        !           214:        register struct mba *mp;
        !           215: 
        !           216:        mp = &mba[ap->mbno];
        !           217:        if (mp->addr == 0)
        !           218:                panic("mbphys");
        !           219:        pg = addr / NBPG;
        !           220:        if (pg >= NMAP)
        !           221:                return (-1);
        !           222:        m = mp->addr->map[pg];
        !           223:        if ((m & MRV) == 0)
        !           224:                return (-1);
        !           225:        return ((m & MPAGE) * NBPG + addr % NBPG);
        !           226: }
        !           227: 
        !           228: mbgetc(ap, addr)
        !           229: struct mbaddr *ap;
        !           230: long addr;
        !           231: {
        !           232:        register long phys;
        !           233: 
        !           234:        phys = mbphys(ap, addr);
        !           235:        if (phys < 0)
        !           236:                return (-1);
        !           237:        return (phgetc(phys));
        !           238: }
        !           239: 
        !           240: int
        !           241: mbputc(ap, addr, c)
        !           242: struct mbaddr *ap;
        !           243: long addr;
        !           244: char c;
        !           245: {
        !           246:        register long phys;
        !           247: 
        !           248:        phys = mbphys(ap, addr);
        !           249:        if (phys < 0)
        !           250:                return (-1);
        !           251:        return (phputc(phys, c));
        !           252: }
        !           253: 
        !           254: /*
        !           255:  * massbus interrupt
        !           256:  * if a transfer in progress, call the driver
        !           257:  * if attn, call drivers for that too
        !           258:  * it is up to the driver to clear attn
        !           259:  * (but for convenience, we promise to tell them what bit to clear)
        !           260:  */
        !           261: 
        !           262: mba0int(dev)
        !           263: register int dev;
        !           264: {
        !           265:        register struct mba *mp;
        !           266:        register struct mbaregs *reg;
        !           267:        register long sr;
        !           268:        register int as, i;
        !           269: 
        !           270:        if (dev < 0 || dev > mbacnt
        !           271:        ||  (mp = &mba[dev], (mp->flags & INIT)) == 0) {
        !           272:                mbshutup(dev);
        !           273:                return;
        !           274:        }
        !           275:        reg = mp->addr;
        !           276:        sr = reg->sr;
        !           277:        reg->sr = sr;           /* clear attn and error latches */
        !           278:        as = reg->mbas&0377;
        !           279:        if (mp->flags & BUSY) {
        !           280:                i = mp->first;
        !           281:                mp->mbuf[i] = NULL;
        !           282:                mp->first = mp->mbq[i];
        !           283:                mp->flags &=~ BUSY;
        !           284:                (*mbavec[dev][i])(mbaid[dev][i], sr, (-reg->bcr)&0xffff, as & (1<<i));
        !           285:                as &=~ (1<<i);
        !           286:        }
        !           287:        for (i = 0; as; i++, as >>= 1)
        !           288:                if (as & 01)
        !           289:                        (*mbavec[dev][i])(mbaid[dev][i], 0, 0, 1<<i);
        !           290:        if ((mp->flags & BUSY) == 0)
        !           291:                mbxfer(mp);
        !           292: }
        !           293: 
        !           294: /*
        !           295:  * mbavec for non-existent drives points here
        !           296:  */
        !           297: 
        !           298: mbastray(dev)
        !           299: int dev;
        !           300: {
        !           301:        printf("mba%d drive %d stray attn\n", dev>>3, dev&07);
        !           302: }
        !           303: 
        !           304: /*
        !           305:  * here if didn't expect mba interrupt
        !           306:  * might just be a leftover ATTN from a previous boot;
        !           307:  * not necessarily cleared
        !           308:  */
        !           309: 
        !           310: mbshutup(dev)
        !           311: int dev;
        !           312: {
        !           313:        register struct mbaregs *reg;
        !           314: 
        !           315:        if (dev < 0 || dev >= mbacnt
        !           316:        ||  (reg = (struct mbaregs *)nxaddr(&mbaaddr[dev])) == NULL
        !           317:        ||  badaddr(&reg->conf, sizeof(long))) {
        !           318:                printf("mb%d: unacceptable interrupt\n", dev);
        !           319:                return; /* and probably get stuck forever */
        !           320:        }
        !           321:        reg->cr = CRINIT;       /* quiet, please */
        !           322: }

unix.superglobalmegacorp.com

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