Annotation of coherent/b/kernel/io.386/rm.c, revision 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.