Annotation of researchv10dc/sys/md/mba.c, revision 1.1.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.