|
|
1.1 root 1: /*
2: * File: fifo.c
3: *
4: * Purpose: allow kernel to fetch data from real-mode bootstrap data area
5: *
6: * $Log: fifo.c,v $
7: * Revision 1.3 93/04/14 10:06:27 root
8: * r75
9: *
10: * Revision 1.2 92/01/06 11:59:11 hal
11: * Compile with cc.mwc.
12: *
13: */
14:
15: /*
16: * Includes.
17: */
18: #define KERNEL
19: #include <sys/typed.h>
20:
21: /*
22: * Definitions.
23: * Constants.
24: * Macros with argument lists.
25: * Typedefs.
26: * Enums.
27: */
28:
29: typedef unsigned char uchar;
30: typedef unsigned int uint;
31: typedef unsigned long ulong;
32:
33: /*
34: * Functions.
35: * Import Functions.
36: * Export Functions.
37: * Local Functions.
38: */
39: FIFO * fifo_open();
40: int fifo_close();
41: typed_space * fifo_read();
42:
43: /*
44: * Global Data.
45: * Import Variables.
46: * Export Variables.
47: * Local Variables.
48: *
49: * Arguments are passed into the kernel through boot_gift.
50: * If you start getting "Not enough room for all arguments." messages
51: * at boot time, just increase the BG_LEN to whatever you need.
52: * This structure is EXACTLY BG_LEN bytes long.
53: */
54: TYPED_SPACE(boot_gift, BG_LEN, T_FIFO_SIC);
55:
56: /*
57: * fifo_open()
58: *
59: * Open a typed space as a fifo.
60: *
61: * Takes a typed_space that is already allocated, and a mode. The type of
62: * the typed space must be a FIFO. Only T_FIFO_SIC has been implemented
63: * (static, in-core fifo).
64: *
65: * The mode indicates whether to open for reading or writing.
66: * mode == 0 means read only.
67: * mode == 1 means write only.
68: * Other values are illegal.
69: *
70: * Returns a pointer to an initialized FIFO structure. FIFO structures are
71: * allocated from a pre-allocated array. Returns F_NULL if it can't open
72: * the fifo.
73: */
74: FIFO *
75: fifo_open(fifo_space, mode)
76: typed_space *fifo_space;
77: int mode;
78: {
79: /* ff_table is a table of FIFO structures which can be allocated on
80: * demand. It is functionally similiar to the file descriptor table
81: * in the kernel.
82: */
83: static FIFO ff_table[NFIFOS];
84: static int inited = 0; /* Has ff_table been initialized? */
85:
86: int i; /* A handy counter. */
87: FIFO *the_fifo; /* The fifo we are going to allocate. */
88:
89: /* Initialize ff_table the first time we get called. */
90: if (!inited) {
91: for (i = 0; i < NFIFOS; ++i) {
92: ff_table[i].f_space = F_NULL;
93: ff_table[i].f_flags = 0;
94: }
95: inited = 1;
96: }
97:
98: /* Check the type of the space we were passed. */
99: switch (fifo_space->ts_type) {
100: case T_FIFO: /* Overly general type, assuming SIC. */
101: fifo_space->ts_type = T_FIFO_SIC;
102: break;
103: case T_FIFO_SIC: /* Static In-core Fifo. */
104: break;
105: case T_FIFO_DIC: /* Dynamic In-core Fifo (can grow). */
106: return(F_NULL); /* Unimplemented. */
107: case T_FIFO_SP: /* Static Permanent Fifo (fixed size file). */
108: return(F_NULL); /* Unimplemented. */
109: case T_FIFO_DP: /* Dynamic Permanent Fifo (ordinary file). */
110: return(F_NULL); /* Unimplemented. */
111: default:
112: return(F_NULL); /* Illegal type encountered. */
113: }
114:
115: /* ASSERTION: fifo_space is a valid and implemented FIFO. */
116:
117: /* Find the first free FIFO structure. */
118:
119: /* This should be re-implemented using a malloc-based scheme.
120: * At the moment, the tertiary boot libraries do not include a
121: * malloc.
122: */
123: for (i = 0; (i < NFIFOS) && (0 != ff_table[i].f_flags); ++i) {
124: /* Do nothing else. */
125: }
126:
127: if (NFIFOS == i) {
128: return(F_NULL); /* No more free fifo structs. */
129: }
130:
131: the_fifo = &(ff_table[i]);
132:
133: /* ASSERTION: the_fifo points at a FIFO we can take. */
134:
135: /* Initialize the FIFO struct. */
136: the_fifo->f_space = fifo_space;
137: the_fifo->f_offset = fifo_space->ts_data;
138:
139: /* Initilize the flags. */
140: switch(mode) {
141: case 0: /* read */
142: the_fifo->f_flags |= F_READ;
143: break;
144: case 1: /* write */
145: the_fifo->f_flags |= F_WRITE;
146: break;
147: default:
148: return(F_NULL); /* Illegal mode flag. */
149: }
150:
151: return(the_fifo);
152: } /* fifo_open() */
153:
154: /*
155: * fifo_close()
156: *
157: * Finish with using a typed space as a fifo.
158: * Free up FIFO structure associated with a typed space.
159: * Returns 0 if ffp was not open, 1 otherwise.
160: */
161: int
162: fifo_close(ffp)
163: FIFO *ffp;
164: {
165: if (0 == ffp->f_flags) {
166: return(0); /* This ffp is not open. */
167: }
168: ffp->f_space = F_NULL;
169: ffp->f_offset = 0;
170: ffp->f_flags = 0;
171:
172: return(1);
173: } /* fifo_close() */
174:
175: /*
176: * fifo_read()
177: *
178: * Read a typed space from a fifo.
179: * Return a pointer to the next typed space in the fifo ffp. Returns
180: * NULL on end of fifo.
181: *
182: * This read assumes that ffp->f_space has type T_FIFO_SIC.
183: */
184: typed_space *
185: fifo_read(ffp)
186: register FIFO *ffp;
187: {
188: typed_space *retval;
189:
190: /* Read MUST be set. */
191: if (F_READ != F_READ & ffp->f_flags ) {
192: printf(" fifo_read: READ not set ");
193: return 0; /* This ffp is not open for reading. */
194: }
195:
196: /* From here to the end of fifo_read is really fifo_read_sic(). */
197:
198:
199: /* Space of size 0 marks EOFIFO. */
200: if ((long)0 == ffp->f_offset->ts_size) {
201: printf(" fifo_read: space of size 0 ");
202: retval = 0;
203: } else {
204: /* Return the next space. */
205: retval = ffp->f_offset;
206: /* Advance to the next space. */
207: (char *) ffp->f_offset += ffp->f_offset->ts_size;
208: }
209:
210: return retval;
211: } /* fifo_read() */
212:
213: #ifdef TEST
214: #include <stdio.h>
215:
216: /* This is the typed space we will use for our FIFO operations. */
217: TYPED_SPACE(global_space, 128, T_FIFO_SIC); /* Static In-Core Fifo. */
218:
219: void
220: main()
221: {
222: FIFO *ffp; /* Fifo pointer for a handle. */
223: char line[1024]; /* Place to put input lines. */
224: long size; /* Length for line. (Sizes are all long.) */
225: int i;
226:
227: typed_space *local_space;
228:
229: /* Open the fifo for writing. */
230: if (F_NULL == (ffp = fifo_open(&global_space, 1))) {
231: fprintf(stderr, "Can't open global_space for writing.\n");
232: exit(1);
233: }
234:
235: do {
236: printf("Feed me: ");
237: gets(line);
238: size = (long) (strlen(line) + 1);
239: } while (fifo_write_untyped(ffp, line, size, T_STR_STR));
240:
241: if (0 == fifo_close(ffp)) {
242: fprintf(stderr, "Failed to close global_space.\n");
243: exit(1);
244: }
245:
246: printf("OK, global_space is now full.\n");
247: /* ASSERTION: We've filled global_space with strings. */
248:
249: /* Open the fifo for reading. */
250: if (F_NULL == (ffp = fifo_open(&global_space, 0))) {
251: fprintf(stderr, "Can't open global_space for reading.\n");
252: exit(1);
253: }
254:
255: /* Dump the contents of this FIFO. */
256: for (i = 1; (local_space = fifo_read(ffp)); ++i) {
257: printf("%d: size: %ld: type: 0x%x\n", i,
258: local_space->ts_size,
259: local_space->ts_type);
260:
261: /* Assume everything is a NUL terminated string. */
262: printf("datum: %s\n\n", local_space->ts_data);
263: printf("Hit <RETURN>");
264: gets(line);
265: }
266:
267:
268: /* Rewind the file, and dump it out again. */
269: printf("Rewinding.\n");
270: if (0 == fifo_rewind(ffp)) {
271: fprintf("Can't rewind global_space.\n");
272: exit(1);
273: }
274:
275: for (i = 1; (local_space = fifo_read(ffp)); ++i) {
276: printf("%d: size: %ld: type: 0x%x\n", i,
277: local_space->ts_size,
278: local_space->ts_type);
279:
280: /* Assume everything is a NUL terminated string. */
281: printf("datum: %s\n\n", local_space->ts_data);
282: }
283:
284: if (0 == fifo_close(ffp)) {
285: fprintf(stderr, "Failed to close global_space.\n");
286: exit(1);
287: }
288:
289: exit(0);
290: } /* main() */
291:
292: #endif /* TEST */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.