|
|
1.1 root 1: /*
2: * Ram Pipe Device Driver
3: */
4:
5: #include <coherent.h>
6: #include <con.h>
7: #include <seg.h>
8: #include <stat.h>
9: #include <sched.h>
10: #include <termio.h>
11: #include <v7sgtty.h>
12: #include <uproc.h>
13: #include <errno.h>
14:
15: #define MAXNRP 30 /* Maximum number of ram pipes (must be < 32) */
16: #define NCPQ 2048 /* Size of pipe in bytes */
17: #define RPMAJOR 22 /* Major device for ram pipes */
18:
19: /*
20: * function definitions
21: */
22: int rpopen();
23: int rpread();
24: int rpwrite();
25: int rpioctl();
26: int rppoll();
27: void rpuload();
28: int nulldev();
29: int nonedev();
30:
31:
32: /*
33: * configuration table
34: */
35: CON rpcon = {
36: DFCHR|DFPOL, /* flags */
37: RPMAJOR, /* major index */
38: rpopen, /* open */
39: nulldev, /* close */
40: nonedev, /* block */
41: rpread, /* read */
42: rpwrite, /* write */
43: rpioctl, /* ioctl */
44: nulldev, /* power fail */
45: nulldev, /* timeout */
46: nulldev, /* load */
47: rpuload, /* unload */
48: rppoll /* poll */
49: };
50:
51: /*
52: * Ram Pipe Headers
53: */
54: static
55: struct ring {
56: unsigned short q_size; /* Number of characters in queue */
57: unsigned short q_mask; /* Ring buffer Mask: NCPQ-1 */
58: faddr_t q_ifaddr; /* Input virtual address */
59: faddr_t q_ofaddr; /* Output virtual address */
60: GATE q_igate; /* Read lock */
61: GATE q_ogate; /* Write lock */
62: event_t q_ipoll; /* Input polls */
63: event_t q_opoll; /* Output polls */
64:
65: } rpq[MAXNRP];
66:
67: static SEG * rpsegp;
68: unsigned NRP = MAXNRP;
69:
70: /*
71: * Initialization Routine
72: */
73: static
74: rpinit()
75: {
76: register struct ring *rp;
77: faddr_t faddr;
78: paddr_t paddr;
79:
80: /*
81: * Ensure valid number of ram pipes
82: */
83: if ( NRP > MAXNRP )
84: NRP = MAXNRP;
85:
86: /*
87: * Allocate ram pipe segment, initialize ram pipe queues
88: */
89: if ( NRP != 0 ) {
90: rpsegp = salloc((fsize_t)NRP*NCPQ, SFSYST|SFHIGH|SFNSWP|SFNCLR);
91:
92: if ( rpsegp == NULL )
93: return -1;
94:
95: paddr = rpsegp->s_paddr;
96:
97: for ( rp = &rpq[0]; rp < &rpq[NRP]; rp++, paddr += NCPQ ) {
98:
99: faddr = ptov( paddr, (fsize_t)NCPQ );
100: rp->q_size = 0;
101: rp->q_mask = NCPQ - 1;
102:
103: rp->q_ifaddr = faddr;
104: rp->q_ofaddr = faddr;
105: }
106: }
107: return 0;
108: }
109:
110: /*
111: * Unload Routine.
112: */
113: static void
114: rpuload()
115: {
116: register struct ring *rp;
117:
118: /*
119: * Release virtual address mappers.
120: */
121: for ( rp = &rpq[0]; rp < &rpq[NRP]; rp++ ) {
122: if ( rp->q_ifaddr )
123: vrelse( rp->q_ifaddr );
124: }
125:
126: /*
127: * Release ring buffer storage.
128: */
129: if ( rpsegp != NULL ) {
130: sfree( rpsegp );
131: rpsegp = NULL;
132: }
133:
134: /*
135: * Erase private data.
136: */
137: memset( &rpq[0], 0, sizeof(rpq) );
138: }
139:
140: /*
141: * Open Routine
142: */
143: static
144: rpopen( dev, mode )
145: dev_t dev;
146: {
147: int s;
148:
149: s = sphi();
150: if ( rpq[0].q_mask == 0 )
151: if ( rpinit() < 0 )
152: u.u_error = ENOSPC;
153: spl( s );
154: if ( minor(dev) >= NRP )
155: u.u_error = ENXIO;
156: }
157:
158: /*
159: * Ioctl Routine
160: */
161: static
162: rpioctl( dev, com, vec )
163: dev_t dev;
164: {
165: switch ( com ) {
166:
167: case TIOCQUERY:
168: putuwd( vec, rpq[ minor(dev) ].q_size );
169: return;
170:
171: case TIOCOUTQ:
172: putuwd( vec, rpq[ minor(dev) ].q_size );
173: return;
174:
175: case TIOCFLUSH:
176: case TCFLSH:
177: rpflush( &rpq[minor(dev)] );
178: return;
179:
180: default:
181: u.u_error = EINVAL;
182: return;
183: }
184: }
185:
186: /*
187: * Read Routine
188: */
189: static
190: rpread( dev, iop )
191: dev_t dev;
192: register IO *iop;
193: {
194: register struct ring *rp;
195: unsigned n;
196: int s;
197:
198: rp = &rpq[ minor(dev) ];
199: s = sphi();
200:
201: /*
202: * Wait until read is unlocked, and there is data to read
203: */
204: while ( (rp->q_igate[0] != 0) || ((n = rp->q_size) == 0) ) {
205:
206: /*
207: * Non-blocking reads.
208: */
209: if ( iop->io_flag & IONDLY ) {
210: u.u_error = EAGAIN;
211: return;
212: }
213:
214: ++rp->q_igate[1];
215: sleep( rp->q_igate, CVTTOUT, IVTTOUT, SVTTOUT );
216: --rp->q_igate[1];
217:
218: if ( SELF->p_ssig && nondsig() ) { /* signal received */
219:
220: spl( s );
221: u.u_error = EINTR;
222: return;
223: }
224: }
225: rp->q_igate[0] = 1; /* lock read gate */
226: spl( s );
227:
228: if ( n > iop->io_ioc ) /* more data than requested */
229: n = iop->io_ioc;
230:
231: rucopy( rp, iop->io_base, n ); /* copy data to user space */
232: iop->io_base += n;
233: iop->io_ioc -= n;
234:
235: if ( rp->q_ogate[1] != 0 ) /* someone waiting to write */
236: wakeup( rp->q_ogate );
237: if ( rp->q_opoll.e_procp ) /* someone polling to write */
238: pollwake( &rp->q_opoll );
239:
240: rp->q_igate[0] = 0; /* unlock read gate */
241:
242: if ( rp->q_igate[1] != 0 ) /* others waiting to read */
243: wakeup( rp->q_igate );
244: }
245:
246: /*
247: * Write Routine
248: */
249: static
250: rpwrite( dev, iop )
251: dev_t dev;
252: register IO *iop;
253: {
254: register struct ring *rp;
255: unsigned n;
256: int s;
257:
258: rp = &rpq[ minor(dev) ];
259:
260: do {
261: s = sphi();
262: /*
263: * Wait until write is unlocked and 512 free slots exist
264: */
265:
266: while ((rp->q_ogate[0] != 0) || ((n = NCPQ-rp->q_size) < 512)) {
267:
268: /*
269: * Non-blocking writes.
270: */
271: if ( iop->io_flag & IONDLY ) {
272: u.u_error = EAGAIN;
273: return;
274: }
275:
276: ++rp->q_ogate[1];
277: sleep( rp->q_ogate, CVTTOUT, IVTTOUT, SVTTOUT );
278: --rp->q_ogate[1];
279:
280: if (SELF->p_ssig && nondsig()) { /* received signal */
281:
282: spl( s );
283: u.u_error = EINTR;
284: return;
285: }
286: }
287: rp->q_ogate[0] = 1; /* lock write gate */
288: spl( s );
289:
290: if ( n > iop->io_ioc )
291: n = iop->io_ioc;
292:
293: urcopy( iop->io_base, rp, n ); /* copy data from user space */
294: iop->io_base += n;
295: iop->io_ioc -= n;
296:
297: rp->q_ogate[0] = 0; /* unlock write gate */
298:
299: if ( rp->q_igate[1] != 0 ) /* someone waiting to read */
300: wakeup( rp->q_igate );
301:
302: if ( rp->q_ipoll.e_procp ) /* someone polling to read */
303: pollwake( &rp->q_ipoll );
304:
305: } while ( iop->io_ioc != 0 ); /* until all data copied */
306:
307: if (rp->q_ogate[1] != 0) /* someone waiting to write */
308: wakeup( rp->q_ogate );
309: }
310:
311: /*
312: * Poll.
313: */
314: rppoll( dev, ev, msec )
315: dev_t dev;
316: int ev;
317: int msec;
318: {
319: register struct ring *rp = &rpq[ minor(dev) ];
320:
321: ev &= ~POLLPRI;
322:
323: /*
324: * Input poll.
325: */
326: if ( ev & POLLIN ) {
327:
328: /*
329: * Pipe empty.
330: */
331: if ( FP_OFF(rp->q_ifaddr) == FP_OFF(rp->q_ofaddr) ) {
332: if ( msec != 0 )
333: pollopen( &rp->q_ipoll );
334: ev &= ~POLLIN;
335: }
336: }
337:
338: /*
339: * Output poll.
340: */
341: if ( ev & POLLOUT ) {
342:
343: /*
344: * Pipe not empty.
345: */
346: if ( FP_OFF(rp->q_ifaddr) != FP_OFF(rp->q_ofaddr) ) {
347: if ( msec != 0 )
348: pollopen( &rp->q_opoll );
349: ev &= ~POLLOUT;
350: }
351: }
352:
353: return ev;
354: }
355:
356: /*
357: * Flush queue
358: */
359: static
360: rpflush( rp )
361: register struct ring *rp;
362: {
363: register int s;
364:
365: s = sphi();
366:
367: /*
368: * Wait until read is unlocked, or nothing in queue
369: */
370:
371: while ((rp->q_size != 0) && (rp->q_igate[0] != 0) ) {
372:
373: ++rp->q_igate[1];
374: sleep( rp->q_igate, CVTTOUT, IVTTOUT, SVTTOUT );
375: --rp->q_igate[1];
376:
377: if (SELF->p_ssig && nondsig()) { /* received signal */
378:
379: spl( s );
380: u.u_error = EINTR;
381: return;
382: }
383: }
384:
385: if (rp->q_size != 0) { /* flush ram pipe */
386:
387: rp->q_ofaddr = rp->q_ifaddr;
388: rp->q_size = 0;
389: }
390: spl( s );
391:
392: if (rp->q_ogate[1] != 0) /* someone waiting to write */
393: wakeup( rp->q_ogate );
394:
395: if ( rp->q_opoll.e_procp ) /* someone polling to write */
396: pollwake( &rp->q_opoll );
397: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.