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