Annotation of coherent/d/kernel/USRSRC/i8086/drv/rm.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Block or character device RAM disk driver.
                      3:  */
                      4: 
                      5: #include       <sys/coherent.h>
                      6: #include       <sys/buf.h>
                      7: #include       <errno.h>
                      8: #include       <sys/uproc.h>
                      9: #include       <sys/seg.h>
                     10: #include       <sys/con.h>
                     11: #include       <sys/devices.h>
                     12: #include       <sys/inode.h>
                     13: #include       <sys/stat.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:        fsize_t rm_size;        /* Size in allocation chunks */
                     53:        paddr_t rm_paddr;       /* Physical base of ram disc segment */
                     54:        SEG     *rm_segp;       /* Segment pointer of ram device */
                     55:        BUF     rm_buf;         /* Static buffer for raw requests */
                     56:        int     rm_nopen;       /* Open count to avoid blowups */
                     57: } RM;
                     58: static RM      rm[NUM_RM];
                     59: 
                     60: /*
                     61:  * Load.
                     62:  */
                     63: static
                     64: rmload()
                     65: {
                     66: }
                     67: 
                     68: /*
                     69:  * Unload.
                     70:  * Release the allocated buffers.
                     71:  */
                     72: static
                     73: rmuload()
                     74: {
                     75:        int i;
                     76: 
                     77:        for (i = 0; i < NUM_RM; i++){
                     78:                if (rm[i].rm_size != 0)
                     79:                        sfree(rm[i].rm_segp);
                     80:        }
                     81: }
                     82: 
                     83: /*
                     84:  * Open.
                     85:  * Allocate on the first call.
                     86:  * Increment the open count.
                     87:  */
                     88: static
                     89: rmopen(dev, mode) dev_t dev; int mode;
                     90: {
                     91:        register RM *rmp;
                     92:        register fsize_t asize, osize;
                     93:        register SEG *segp;
                     94: 
                     95:        rmp = &rm[rm_drive(dev)];
                     96:        asize = rm_asize(dev);
                     97:        osize = rmp->rm_size;
                     98: 
                     99:        /* Fail on read before creation or bogus size. */
                    100:        if ((mode == IPR && osize == 0)
                    101:         || (asize != 0 && osize != 0 && asize != osize)
                    102:         || (asize == 0 && osize == 0)) {
                    103:                u.u_error = ENXIO;
                    104:                return;
                    105:        }
                    106: 
                    107:        /*
                    108:         * Allocate as required.
                    109:         * Ignore case asize==0 && osize!=0, handled by rmclose().
                    110:         * If asize!=0 && asize==osize, just bump the open count.
                    111:         */
                    112:        if (asize != 0 && osize == 0) {
                    113:                segp = rmp->rm_segp = salloc((fsize_t)ASIZE*BSIZE*asize,
                    114:                        SFSYST|SFNSWP|SFNCLR|SFHIGH);
                    115:                if (segp == NULL) {
                    116:                        u.u_error = ENOMEM;
                    117:                        return;
                    118:                }
                    119:                rmp->rm_size = asize;
                    120:                rmp->rm_paddr = segp->s_paddr;
                    121:                rmp->rm_nopen = 0;
                    122:                pclear(rmp->rm_paddr, 1024L);   /* clear 1st 2 blocks */
                    123:        }
                    124:        rmp->rm_nopen++;
                    125: }
                    126: 
                    127: /*
                    128:  * Close.
                    129:  * Decrement the open count.
                    130:  * Release the allocated buffer if minor number is 0.
                    131:  */
                    132: static
                    133: rmclose(dev) dev_t dev;
                    134: {
                    135:        register RM *rmp;
                    136:        register fsize_t asize, osize;
                    137: 
                    138:        rmp = &rm[rm_drive(dev)];
                    139:        asize = rm_asize(dev);
                    140:        osize = rmp->rm_size;
                    141: 
                    142:        if (osize == 0
                    143:         || (asize != 0 && asize != osize)
                    144:         || rmp->rm_nopen == 0) {
                    145:                u.u_error = ENXIO;
                    146:                return;
                    147:        }
                    148:        rmp->rm_nopen--;
                    149:        if (asize == 0) {
                    150:                if (rmp->rm_nopen != 0) {
                    151:                        u.u_error = EDBUSY;
                    152:                        return;
                    153:                }
                    154:                sfree(rmp->rm_segp);
                    155:                rmp->rm_size = 0;
                    156:        }
                    157: }
                    158: 
                    159: static
                    160: rmblock(bp) register BUF *bp;
                    161: {
                    162:        paddr_t base;
                    163:        dev_t dev;
                    164:        register RM *rmp;
                    165:        register fsize_t asize, osize;
                    166: 
                    167:        dev = bp->b_dev;
                    168:        rmp = &rm[rm_drive(dev)];
                    169:        asize = rm_asize(dev);
                    170:        osize = rmp->rm_size;
                    171:        if (osize == 0 || asize != osize)
                    172:                bp->b_flag |= BFERR;
                    173:        /*
                    174:         * Make sure last block requested is within range of device.
                    175:         */     
                    176:        else if ((bp->b_bno + bp->b_count/BSIZE - 1) >= asize*ASIZE)
                    177:                bp->b_flag |= BFERR;
                    178:        else {
                    179:                base = rmp->rm_paddr + (paddr_t)bp->b_bno * BSIZE;
                    180:                if (bp->b_req == BREAD)
                    181:                        plrcopy(base, bp->b_paddr, (fsize_t)bp->b_count);
                    182:                else
                    183:                        plrcopy(bp->b_paddr, base, (fsize_t)bp->b_count);
                    184:        }
                    185:        bdone(bp);
                    186: }
                    187: 
                    188: /*
                    189:  * The read routine calls the common raw I/O processing code,
                    190:  * using a static buffer header in the driver.
                    191:  */
                    192: static
                    193: rmread(dev, iop) register dev_t dev; IO *iop;
                    194: {
                    195:        register BUF *bufp;
                    196: 
                    197:        bufp = &rm[rm_drive(dev)].rm_buf;
                    198:        ioreq(bufp, iop, dev, BREAD, BFIOC|BFRAW);
                    199: }
                    200: 
                    201: /*
                    202:  * The write routine is just like the read routine,
                    203:  * except that the function code is write instead of read.
                    204:  */
                    205: static
                    206: rmwrite(dev, iop) register dev_t dev; IO *iop;
                    207: {
                    208:        register BUF *bufp;
                    209: 
                    210:        bufp = &rm[rm_drive(dev)].rm_buf;
                    211:        ioreq(bufp, iop, dev, BWRITE, BFIOC|BFRAW);
                    212: }
                    213: 
                    214: /* 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.