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