Annotation of researchv10no/sys/io/rco.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * to do:
                      3:  *     check overflow of user read (bp->b_count)
                      4:  *     does the address loaded into the registers
                      5:  *     have to be on a 2k boundary?
                      6:  */
                      7: #include "sys/param.h"
                      8: #include "sys/conf.h"
                      9: #include "sys/user.h"
                     10: #include "sys/buf.h"
                     11: #include "sys/ubaddr.h"
                     12: #include "sys/pte.h"
                     13: 
                     14: #include "sys/rco.h"
                     15: #include "sys/rcocmd.h"
                     16: 
                     17: /*
                     18:  * hardware
                     19:  */
                     20: struct device {
                     21:        u_short csr;            /* control/status register */
                     22:        u_short vr;             /* virtual register (write only)*/
                     23:        u_short ar;             /* address register */
                     24:        u_short xar;            /* extended address register */
                     25: };
                     26: 
                     27: #define        GO      01
                     28: #define ERROR  016             /* 02 = FAULT, 04 = TIMEOUT, 010 = OVERFLO */
                     29: #define RESL   060
                     30: #define HALF   0100
                     31: #define READY  0200
                     32: #define UBACT  07400
                     33: #define UBALOW 010000
                     34: #define TEOP   020000
                     35: #define        IENABLE 040000
                     36: 
                     37: #define NUBMREG        4
                     38: #define IOCHUNK (NBPG*NUBMREG)
                     39: 
                     40: /*
                     41:  * config glue
                     42:  */
                     43: int rcoopen(), rcoclose(), rcoread(), rcoioctl();
                     44: 
                     45: extern struct rco rco[];
                     46: extern struct ubaddr rcoaddr[];
                     47: extern int rcocnt;
                     48: struct cdevsw rcocdev = cdinit(rcoopen, rcoclose, rcoread, nodev, rcoioctl);
                     49: 
                     50: #define OPEN   0x01
                     51: #define BUSY   0x02
                     52: 
                     53: rcoopen(d, f)
                     54: {
                     55:        register int dev;
                     56:        register struct rco *rp;
                     57: 
                     58:        if((dev = minor(d)) >= rcocnt) {
                     59:                u.u_error = ENODEV;
                     60:                return;
                     61:        }
                     62:        if((rp = &rco[dev])->flags&OPEN) {
                     63:                u.u_error = EBUSY;
                     64:                return;
                     65:        }
                     66:        if((rp->addr = (struct device *)ubaddr(&rcoaddr[dev])) == 0
                     67:          || ubbadaddr(rcoaddr[dev].ubno, (caddr_t)rp->addr, sizeof(u_short))) {
                     68:                printf("rco%d absent\n", dev);
                     69:                u.u_error = ENODEV;
                     70:                return;
                     71:        }
                     72:        rp->flags = OPEN;
                     73:        rp->addr->csr = 0;
                     74:        rp->dither = 0;
                     75:        rp->resol = 2;
                     76: }
                     77: 
                     78: rcoclose(d)
                     79: {
                     80:        rco[minor(d)].flags &= ~OPEN;
                     81: }
                     82: 
                     83: rcominp(bp)
                     84: struct buf *bp;
                     85: {
                     86: }
                     87: 
                     88: rcostrategy(bp)
                     89: register struct buf *bp;
                     90: {
                     91:        register struct rco *rp = &rco[minor(bp->b_dev)];
                     92:        register uaddr_t uaddr;
                     93:        register int s, ubno;
                     94:        u_short csr;
                     95: 
                     96:        csr = IENABLE | ((rp->dither << 6) & HALF) | ((rp->resol << 4) & RESL);
                     97:        ubno = rcoaddr[minor(bp->b_dev)].ubno;
                     98:        rp->ubm = ubmalloc(ubno, IOCHUNK+(IOCHUNK-1), UBDP|USLP);
                     99:        rp->chunkubm = (rp->ubm + (NUBMREG-1)) & ~(NUBMREG-1);
                    100:        rp->pte = btopte(bp);
                    101:        uaddr = ubmsetmap(ubno, rp->pte, NUBMREG, rp->chunkubm);
                    102:        rp->pte += NUBMREG;
                    103:        s = spl5();
                    104:        rp->flags |= BUSY;
                    105:        rp->addr->ar = uaddr & 0x7FE;           /* bits 10-1 */
                    106:        rp->addr->xar = (uaddr >> 8) & 0x3FF8;  /* bits 21-11 */
                    107:        while((rp->addr->csr&READY) == 0)
                    108:                ;
                    109:        rp->addr->csr = csr;
                    110:        for(rp->mreg = NUBMREG; rp->mreg; rp->mreg--)
                    111:                rp->addr->vr = 1;
                    112:        DELAY(50000);
                    113:        rp->addr->csr = csr | GO;
                    114:        if(tsleep((caddr_t)bp, PRIBIO+1, 20) != TS_OK) {
                    115:                bp->b_flags |=  B_ERROR;
                    116:                iodone(bp);
                    117:        }
                    118:        rp->addr->csr = 0;
                    119:        rp->flags &= ~BUSY;
                    120:        splx(s);
                    121:        bp->b_resid = 0;
                    122:        ubmfree(ubno, rp->ubm);
                    123: }
                    124: 
                    125: rcoread(d)
                    126: {
                    127:        if((((int)u.u_base) & (IOALIGN-1))) {
                    128:                u.u_error = EFAULT;
                    129:                return;
                    130:        }
                    131:        physio(rcostrategy, &rco[minor(d)].buf, d, B_READ, rcominp);
                    132: }
                    133: 
                    134: rcoioctl(dev, cmd, addr, flag)
                    135: caddr_t addr;
                    136: {
                    137:        register struct rco *rp = &rco[minor(dev)];
                    138:        int i;
                    139: 
                    140:        if(copyin(addr, (caddr_t)&i, sizeof(i))) {
                    141:                u.u_error = EFAULT;
                    142:                return;
                    143:        }
                    144:        switch(cmd) {
                    145: 
                    146:        case RCORES:
                    147:                rp->resol = i;
                    148:                break;
                    149: 
                    150:        case RCODITHER:
                    151:                rp->dither = i;
                    152:                break;
                    153: 
                    154:        default:
                    155:                u.u_error = ENXIO;
                    156:        }
                    157: }
                    158: 
                    159: rco0int(d)
                    160: {
                    161:        register struct rco *rp = &rco[d];
                    162:        register struct buf *bp;
                    163:        ubm_t ubm;
                    164:        u_short csr;
                    165: 
                    166:        if((rp->flags & (BUSY|OPEN)) != (BUSY|OPEN)) {
                    167:                printf("rco%d: not busy interrupt\n", d);
                    168:                rp->addr->csr = 0;
                    169:                return;
                    170:        }
                    171:        if((csr = rp->addr->csr) & GO) {
                    172:                ubm = rp->chunkubm + rp->mreg++;
                    173:                (void) ubmsetmap(rcoaddr[d].ubno, rp->pte++, 1, ubm);
                    174:                if(rp->mreg > (NUBMREG-1))
                    175:                        rp->mreg = 0;
                    176:                rp->addr->vr = 1;
                    177:                return;
                    178:        }
                    179:        bp = &rp->buf;
                    180:        if((csr & ERROR) || (csr & TEOP) == 0) {
                    181:                printf("rco%d: csr=0%o\n", d, csr);
                    182:                bp->b_flags |= B_ERROR;
                    183:        }
                    184:        rp->addr->csr = 0;
                    185:        iodone(bp);
                    186: }

unix.superglobalmegacorp.com

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