Annotation of coherent/b/kernel/io.386/rm.c, revision 1.1.1.1

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