|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.