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