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