Annotation of coherent/d/286_KERNEL/USRSRC/io/rm.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Block or character device RAM disk driver.
                      3:  * AT COHERENT (286 and 386).
                      4:  */
                      5: 
                      6: #include       <sys/coherent.h>
                      7: #include       <sys/con.h>
                      8: #include       <sys/buf.h>
                      9: #include       <errno.h>
                     10: #include       <sys/devices.h>
                     11: #include       <sys/inode.h>
                     12: #include       <sys/stat.h>
                     13: #include       <sys/seg.h>
                     14: #include       <sys/uproc.h>
                     15: 
                     16: /*
                     17:  * Minor number encoding: dsssssss
                     18:  * d       drive number (0 or 1)
                     19:  * sssssss allocation size: 0 to free, 1-127 allocsize (n*ASIZE*BSIZE bytes)
                     20:  */
                     21: #define        rm_drive(dev)   (minor(dev) >> 7)
                     22: #define        rm_asize(dev)   (minor(dev) & 0x7F)
                     23: #define        ASIZE           128     /* allocation chunk size in blocks (64KB) */
                     24: #define NUM_RM         2       /* number of ram disks
                     25:                                   - tied to dev encoding (see above) */
                     26: 
                     27: int    nulldev();
                     28: int    nonedev();
                     29: int    rmload();
                     30: int    rmuload();
                     31: int    rmopen();
                     32: int    rmclose();
                     33: int    rmread();
                     34: int    rmwrite();
                     35: int    rmblock();
                     36: 
                     37: CON    rmcon   = {
                     38:        DFBLK|DFCHR,
                     39:        RM_MAJOR,
                     40:        rmopen,                 /* Open */
                     41:        rmclose,                /* Close */
                     42:        rmblock,                /* Block */
                     43:        rmread,                 /* Read */
                     44:        rmwrite,                /* Write */
                     45:        nonedev,
                     46:        nulldev,
                     47:        nulldev,
                     48:        rmload,                 /* Load */
                     49:        rmuload                 /* Unload */
                     50: };
                     51: 
                     52: typedef struct rm {
                     53: #ifndef COH386
                     54:        fsize_t rm_size;        /* Size in allocation chunks */
                     55:        paddr_t rm_paddr;       /* Physical base of ram disc segment */
                     56:        SEG     *rm_segp;       /* Segment pointer of ram device */
                     57: #else
                     58:        off_t   rm_size;        /* Size in allocation chunks */
                     59:        SR      rm_sr;
                     60: #endif
                     61:        BUF     rm_buf;         /* Static buffer for raw requests */
                     62:        int     rm_nopen;       /* Open count to avoid blowups */
                     63: } RM;
                     64: static RM      rm[NUM_RM];
                     65: 
                     66: /*
                     67:  * Load.
                     68:  */
                     69: static
                     70: rmload()
                     71: {
                     72: }
                     73: 
                     74: /*
                     75:  * Unload.
                     76:  * Release the allocated buffers.
                     77:  */
                     78: static
                     79: rmuload()
                     80: {
                     81:        int i;
                     82: 
                     83:        for (i = 0; i < NUM_RM; i++){
                     84:                if (rm[i].rm_size != 0) {
                     85: #ifndef COH386
                     86:                        sfree(rm[i].rm_segp);
                     87: #else
                     88:                        unload(&rm[i].rm_sr);
                     89:                        sfree(rm[i].rm_sr.sr_segp);
                     90: #endif
                     91:                }
                     92:        }
                     93: }
                     94: 
                     95: /*
                     96:  * Open.
                     97:  * Allocate on the first call.
                     98:  * Increment the open count.
                     99:  */
                    100: static
                    101: rmopen(dev, mode) dev_t dev; int mode;
                    102: {
                    103:        register RM *rmp;
                    104: #ifndef COH386
                    105:        register fsize_t asize, osize;
                    106:        register SEG *segp;
                    107: #else
                    108:        register off_t asize, osize;
                    109: #endif
                    110: 
                    111:        rmp = &rm[rm_drive(dev)];
                    112:        asize = rm_asize(dev);
                    113:        osize = rmp->rm_size;
                    114: 
                    115:        /* Fail on read before creation or bogus size. */
                    116:        if ((mode == IPR && osize == 0)
                    117:         || (asize != 0 && osize != 0 && asize != osize)
                    118:         || (asize == 0 && osize == 0)) {
                    119:                u.u_error = ENXIO;
                    120:                return;
                    121:        }
                    122: 
                    123: #ifdef COH386
                    124:        if (ASIZE*BSIZE*asize > ctob(RAMSIZE)) {
                    125:                u.u_error = ENOMEM;
                    126:                return;
                    127:        }
                    128: #endif
                    129: 
                    130:        /*
                    131:         * Allocate as required.
                    132:         * Ignore case asize==0 && osize!=0, handled by rmclose().
                    133:         * If asize!=0 && asize==osize, just bump the open count.
                    134:         */
                    135:        if (asize != 0 && osize == 0) {
                    136: #ifndef COH386
                    137:                segp = rmp->rm_segp = salloc((fsize_t)ASIZE*BSIZE*asize,
                    138:                        SFSYST|SFNSWP|SFNCLR|SFHIGH);
                    139:                if (segp == NULL) {
                    140: #else
                    141:                rmp->rm_sr.sr_segp =
                    142:                    salloc((off_t)ASIZE*BSIZE*asize, SFSYST|SFNSWP|SFNCLR);
                    143:                if (rmp->rm_sr.sr_segp == NULL) {
                    144: #endif
                    145:                        u.u_error = ENOMEM;
                    146:                        return;
                    147:                }
                    148:                rmp->rm_size = asize;
                    149: #ifndef COH386
                    150:                rmp->rm_paddr = segp->s_paddr;
                    151:                rmp->rm_nopen = 0;
                    152:                pclear(rmp->rm_paddr, 1024L);   /* clear 1st 2 blocks */
                    153: #else
                    154:                rmp->rm_sr.sr_base = rm_drive(dev)==0 ?
                    155:                        ctob(RAM0) : ctob(RAM1);
                    156:                rmp->rm_sr.sr_size = rmp->rm_sr.sr_segp->s_size;
                    157:                doload(&rmp->rm_sr);
                    158: #endif
                    159:        }
                    160:        rmp->rm_nopen++;
                    161: }
                    162: 
                    163: /*
                    164:  * Close.
                    165:  * Decrement the open count.
                    166:  * Release the allocated buffer if minor number is 0.
                    167:  */
                    168: static
                    169: rmclose(dev) dev_t dev;
                    170: {
                    171:        register RM *rmp;
                    172: #ifndef COH386
                    173:        register fsize_t asize, osize;
                    174: #else
                    175:        register off_t asize, osize;
                    176: #endif
                    177: 
                    178:        rmp = &rm[rm_drive(dev)];
                    179:        asize = rm_asize(dev);
                    180:        osize = rmp->rm_size;
                    181: 
                    182:        if (osize == 0
                    183:         || (asize != 0 && asize != osize)
                    184:         || rmp->rm_nopen == 0) {
                    185:                u.u_error = ENXIO;
                    186:                return;
                    187:        }
                    188:        rmp->rm_nopen--;
                    189:        if (asize == 0) {
                    190:                if (rmp->rm_nopen != 0) {
                    191: #ifndef COH386
                    192:                        u.u_error = EDBUSY;
                    193: #else
                    194:                        u.u_error = EBUSY;
                    195: #endif
                    196:                        return;
                    197:                }
                    198: #ifndef COH386
                    199:                sfree(rmp->rm_segp);
                    200: #else
                    201:                unload(&rmp->rm_sr);
                    202:                sfree(rmp->rm_sr.sr_segp);
                    203: #endif
                    204:                rmp->rm_size = 0;
                    205:        }
                    206: }
                    207: 
                    208: static
                    209: rmblock(bp) register BUF *bp;
                    210: {
                    211: #ifndef COH386
                    212:        paddr_t base;
                    213:        register fsize_t asize, osize;
                    214: #else
                    215:        vaddr_t base;
                    216:        register off_t asize, osize;
                    217: #endif
                    218:        dev_t dev;
                    219:        register RM *rmp;
                    220: 
                    221:        dev = bp->b_dev;
                    222:        rmp = &rm[rm_drive(dev)];
                    223:        asize = rm_asize(dev);
                    224:        osize = rmp->rm_size;
                    225:        if (osize == 0 || asize != osize) {
                    226:                bp->b_flag |= BFERR;
                    227:                u.u_error = ENXIO;
                    228:        /*
                    229:         * Make sure last block requested is within range of device.
                    230:         */     
                    231:        } else if ((bp->b_bno + bp->b_count/BSIZE - 1) >= asize*ASIZE) {
                    232:                bp->b_flag |= BFERR;
                    233:                u.u_error = EIO;
                    234:        } else {
                    235: #ifndef COH386
                    236:                base = rmp->rm_paddr + (paddr_t)bp->b_bno * BSIZE;
                    237: #else
                    238:                base = rmp->rm_sr.sr_base + (paddr_t)bp->b_bno * BSIZE;
                    239: #endif
                    240:                if (bp->b_req == BREAD)
                    241: #ifndef COH386
                    242:                        plrcopy(base, bp->b_paddr, (fsize_t)bp->b_count);
                    243: #else
                    244:                        dmaout(bp->b_count, bp->b_paddr, base);
                    245: #endif
                    246:                else
                    247: #ifndef COH386
                    248:                        plrcopy(bp->b_paddr, base, (fsize_t)bp->b_count);
                    249: #else
                    250:                        dmaout(bp->b_count, bp->b_paddr, base);
                    251: #endif
                    252:        }
                    253:        bdone(bp);
                    254: }
                    255: 
                    256: /*
                    257:  * The read routine calls the common raw I/O processing code,
                    258:  * using a static buffer header in the driver.
                    259:  */
                    260: static
                    261: rmread(dev, iop) register dev_t dev; IO *iop;
                    262: {
                    263:        register BUF *bufp;
                    264: 
                    265:        bufp = &rm[rm_drive(dev)].rm_buf;
                    266:        ioreq(bufp, iop, dev, BREAD, BFIOC|BFRAW);
                    267: }
                    268: 
                    269: /*
                    270:  * The write routine is just like the read routine,
                    271:  * except that the function code is write instead of read.
                    272:  */
                    273: static
                    274: rmwrite(dev, iop) register dev_t dev; IO *iop;
                    275: {
                    276:        register BUF *bufp;
                    277: 
                    278:        bufp = &rm[rm_drive(dev)].rm_buf;
                    279:        ioreq(bufp, iop, dev, BWRITE, BFIOC|BFRAW);
                    280: }
                    281: 
                    282: /* end of rm.c */

unix.superglobalmegacorp.com

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