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