|
|
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.