|
|
1.1 root 1: #define _DDI_DKI 1
2: #define _SYSV4 1
3:
4: /*
5: * This file contains routines for writing processed configuration data from
6: * 'mkdev.c' out into a C-language configuration file, "conf.c".
7: */
8:
9: /*
10: *-IMPORTS:
11: * <sys/compat.h>
12: * CONST
13: * PROTO
14: * ARGS ()
15: * LOCAL
16: * <kernel/v_types.h>
17: * NODEV
18: * major_t
19: * minor_t
20: * <stddef.h>
21: * size_t
22: * offsetof ()
23: * NULL
24: * <stdio.h>
25: * FILE
26: * stdout
27: * fopen ()
28: * fclose ()
29: * fprintf ()
30: * <time.h>
31: * time_t
32: * strftime ()
33: * localtime ()
34: * "ehand.h"
35: * ehand_t
36: * PUSH_HANDLER ()
37: * POP_HANDLER ()
38: * CHAIN_ERROR ()
39: * throw_error ()
40: * "mdev.h"
41: * MD_ENABLED
42: * mdev_t
43: * mdevices ()
44: * "sdev.h"
45: * sdev_sort ()
46: * "symbol.h"
47: * symbol_t
48: * "assign.h"
49: * extinfo_t
50: */
51:
52: #include <sys/compat.h>
53: #include <kernel/v_types.h>
54: #include <stddef.h>
55: #include <stdio.h>
56: #include <time.h>
57:
58: #include "ehand.h"
59: #include "mdev.h"
60: #include "sdev.h"
61: #include "symbol.h"
62: #include "assign.h"
63:
64: #include "mkconf.h"
65:
66:
67: /*
68: * We define a table to ease the otherwise tedious process of building the
69: * output for the entry point specifications.
70: *
71: * Sadly, we can't use the MDEV_... constants in this table.
72: */
73:
74: struct extern_tab {
75: CONST char * flags;
76: char func;
77: CONST char * outstr;
78: };
79:
80: LOCAL struct extern_tab _exttab [] = {
81: /*
82: * For STREAMS we have to generate an external reference to the
83: * STREAMS function table. We also have to generate stubs for the
84: * character-device entry points to map the SysV calling sequence
85: * into calls to the STREAMS-device entry points.
86: *
87: * Rather than generate those stubs here, we simply call up a generic
88: * template-style macro that will generate all the stubs we need. This
89: * is necessary since we may also be generating stubs for mapping from
90: * some non-SVR4 calling convention to SVR4 for regular devices, and
91: * the macro can deal with that, building the non-SVR4 to STREAMS
92: * mapping in one step.
93: *
94: * The stub generation happens in the second part of this table along
95: * with stub generation for regular devices.
96: */
97:
98: { "Sc", 0, "DECLARE_STREAMS (%s)" },
99: { "S!c", 0, "DECLARE_MODULE (%s)" },
100:
101:
102: /*
103: * Now the regular device entry-point stuff.
104: */
105:
106: { "b", 0, "DECLARE_STRATEGY (%s)" },
107: { "b", 0, "DECLARE_PRINT (%s)" },
108:
109:
110: /*
111: * We assume that a STREAMS driver will only define the entry points
112: * below if it is also capable of acting as a block device or if the
113: * entry is applicable regardless of type.
114: *
115: * For practical reasons other parts of this system may not permit
116: * combination STREAMS and block drivers, because with a common entry
117: * point table for both types of device the block-mode entry points
118: * like open () will conflict with the stub generated for STREAMS.
119: */
120:
121: { NULL, MDEV_OPEN, "DECLARE_OPEN (%s)" },
122: { NULL, MDEV_CLOSE, "DECLARE_CLOSE (%s)" },
123: { NULL, MDEV_READ, "DECLARE_READ (%s)" },
124: { NULL, MDEV_WRITE, "DECLARE_WRITE (%s)" },
125: { NULL, MDEV_IOCTL, "DECLARE_IOCTL (%s)" },
126: { NULL, MDEV_CHPOLL, "DECLARE_CHPOLL (%s)" },
127:
128: { NULL, MDEV_INIT, "DECLARE_INIT (%s)" },
129: { NULL, MDEV_STARTUP, "DECLARE_STARTUP (%s)" },
130: { NULL, MDEV_EXIT, "DECLARE_EXIT (%s)" },
131: { NULL, MDEV_HALT, "DECLARE_HALT (%s)" },
132:
133:
134: /*
135: * The SVR4-MP DDI/DDK defines an optional mmap () entry point
136: * for character devices, yet there is no function code for
137: * this defined in the System Files and Devices manual. Block
138: * drivers have the same problem with the size () entry.
139: */
140:
141: { "b", MDEV_SIZE, "DECLARE_SIZE (%s)" },
142: { "c", MDEV_MMAP, "DECLARE_MMAP (%s)" }
143:
144: /*
145: * The fork (), exec (), kenter () and kexit () entry points aren't
146: * defined for device drivers. In fact, I'm not sure what they *are*
147: * for unless it's for system services - processes that run in the
148: * kernel at higher priority than any user process (but usually at a
149: * lower priority than real-time processes).
150: *
151: * Since what Coherent has can barely be called a scheduler, these
152: * aren't defined here.
153: */
154: };
155:
156:
157: /*
158: * Optionally write based on function test.
159: */
160:
161: #ifdef USE_PROTO
162: LOCAL void (write_func) (FILE * out, mdev_t * mdevp, struct extern_tab * tab)
163: #else
164: LOCAL void
165: write_func ARGS ((out, mdevp, tab))
166: FILE * out;
167: mdev_t * mdevp;
168: struct extern_tab * tab;
169: #endif
170: {
171: CONST char * fcheck;
172:
173: if (out == NULL || mdevp == NULL || tab == NULL)
174: throw_error ("NULL pointer passed to write_func ()");
175:
176: if (tab->outstr == NULL)
177: throw_error ("bad table parameter passed to write_func ()");
178:
179: if ((fcheck = tab->flags) != NULL) {
180: /*
181: * Test for the logical "and" of the functions specified.
182: */
183:
184: while (* fcheck) {
185:
186: if (* fcheck == '!') {
187:
188: if (mdev_flag (mdevp, * ++ fcheck))
189: return;
190: fcheck ++;
191: } else if (! mdev_flag (mdevp, * fcheck ++))
192: return;
193: }
194: }
195:
196: if (tab->func && ! mdev_func (mdevp, tab->func))
197: return;
198:
199: (void) fprintf (out, tab->outstr, mdevp->md_prefix->s_data);
200: (void) fputc ('\n', out);
201: }
202:
203:
204: /*
205: * Output "extern" declarations for device-driver entry points.
206: */
207:
208: #ifdef USE_PROTO
209: LOCAL void (write_extern) (FILE * out, mdev_t * mdevp)
210: #else
211: LOCAL void
212: write_extern ARGS ((out, mdevp))
213: FILE * out;
214: mdev_t * mdevp;
215: #endif
216: {
217: int i;
218:
219: if (mdevp == NULL)
220: throw_error ("NULL 'mdevp' passed to write_extern ()");
221:
222: /*
223: * Test to see whether it is a driver we are dealing with.
224: */
225:
226: if (mdev_flag (mdevp, MDEV_BLOCK) || mdev_flag (mdevp, MDEV_CHAR) ||
227: mdev_flag (mdevp, MDEV_STREAM)) {
228:
229: (void) fprintf (out, "/* entry points for \"%s\" driver */\n\n",
230: mdevp->md_devname->s_data);
231: (void) fprintf (out, "extern int %sdevflag;\n",
232: mdevp->md_prefix->s_data);
233: } else
234: (void) fprintf (out, "/* entry points for \"%s\" facility */\n\n",
235: mdevp->md_devname->s_data);
236:
237: for (i = 0 ; i < sizeof (_exttab) / sizeof (* _exttab) ; i ++)
238: write_func (out, mdevp, & _exttab [i]);
239:
240: if (mdevp->md_interrupt)
241: (void) fprintf (out, "DECLARE_INTR (%s)\n",
242: mdevp->md_prefix->s_data);
243:
244: (void) fprintf (out, "\n\n");
245: }
246:
247:
248: /*
249: * Output all the extern declarations needed to generate the tables.
250: */
251:
252: #ifdef USE_PROTO
253: void (write_externs) (FILE * out)
254: #else
255: void
256: write_externs ARGS ((out))
257: FILE * out;
258: #endif
259: {
260: mdev_t * mdevp;
261:
262: for (mdevp = mdevices () ; mdevp != NULL ; mdevp = mdevp->md_next)
263: if (mdevp->md_configure == MD_ENABLED)
264: write_extern (out, mdevp);
265: }
266:
267:
268: /*
269: * Write a table of (init, start, exit, halt) routines.
270: */
271:
272: #ifdef USE_PROTO
273: LOCAL void (write_ISEH) (FILE * out, char func, CONST char * name,
274: CONST char * capsname)
275: #else
276: LOCAL void
277: write_ISEH ARGS ((out, func, name, capsname))
278: FILE * out;
279: char func;
280: CONST char * name;
281: CONST char * capsname;
282: #endif
283: {
284: mdev_t * mdevp;
285: int any = 0;
286:
287: for (mdevp = mdevices () ; mdevp != NULL ; mdevp = mdevp->md_next) {
288:
289: if (mdevp->md_configure != MD_ENABLED ||
290: ! mdev_func (mdevp, func))
291: continue;
292:
293: if (! any) {
294:
295: any = 1;
296: (void) fprintf (out, "%s_t %stab [] = {\n", name, name);
297: } else
298: (void) fprintf (out, ",\n");
299:
300: (void) fprintf (out, "\t%s (%s)", capsname,
301: mdevp->md_prefix->s_data);
302: }
303:
304: if (any) {
305: (void) fprintf (out, "\n};\n\nunsigned int n%s = sizeof "
306: "(%stab) / sizeof (* %stab);\n\n",
307: name, name, name);
308: } else
309: (void) fprintf (out, "%s_t %stab [1];\n\nunsigned int n%s"
310: "= 0;\n\n",
311: name, name, name);
312: }
313:
314:
315: /*
316: * Write the init, startup, exit and halt-routine tables.
317: */
318:
319: #ifdef USE_PROTO
320: void (write_misc) (FILE * out)
321: #else
322: void
323: write_misc ARGS ((out))
324: FILE * out;
325: #endif
326: {
327: write_ISEH (out, MDEV_INIT, "init", "INIT");
328: write_ISEH (out, MDEV_STARTUP, "start","START");
329: write_ISEH (out, MDEV_EXIT, "exit", "EXIT");
330: write_ISEH (out, MDEV_HALT, "halt", "HALT");
331: }
332:
333:
334: /*
335: * A table to help simplify the process of writing out device-switch table
336: * entries.
337: */
338:
339: typedef struct {
340: char func;
341: CONST char * str;
342: CONST char * nullstr;
343: } devtab_t;
344:
345:
346: LOCAL devtab_t _cdevswtab [] = {
347: { MDEV_OPEN, "OPEN (%s)", "NULL_OPEN" },
348: { MDEV_CLOSE, "CLOSE (%s)", "NULL_CLOSE" },
349: { MDEV_READ, "READ (%s)", "NULL_READ" },
350: { MDEV_WRITE, "WRITE (%s)", "NULL_WRITE" },
351: { MDEV_IOCTL, "\n\t\tIOCTL (%s)",
352: "\n\t\tNULL_IOCTL" },
353: { MDEV_CHPOLL, "CHPOLL (%s)", "NULL_CHPOLL" },
354: { MDEV_MMAP, "MMAP (%s)", "NULL_MMAP" },
355: { 0, NULL, NULL }
356: };
357:
358:
359: LOCAL devtab_t _bdevswtab [] = {
360: { MDEV_OPEN, "OPEN (%s)", "NULL_OPEN" },
361: { MDEV_CLOSE, "CLOSE (%s)", "NULL_CLOSE" },
362: { 0, "STRATEGY (%s)", NULL },
363: { 0, "PRINT (%s)", NULL },
364: { MDEV_SIZE, "SIZE (%s)", "NULL_SIZE" },
365: { 0, NULL, NULL }
366: };
367:
368:
369: /*
370: * Output an entry for a device-switch table.
371: */
372:
373: #ifdef USE_PROTO
374: LOCAL void (write_devsw_line) (FILE * out, mdev_t * mdevp, devtab_t * devtab)
375: #else
376: LOCAL void
377: write_devsw_line ARGS ((out, mdevp, devtab))
378: FILE * out;
379: mdev_t * mdevp;
380: devtab_t * devtab;
381: #endif
382: {
383: (void) fprintf (out, "_ENTRY (& %sdevflag, ",
384: mdevp->md_prefix->s_data);
385:
386: while (devtab->str != NULL) {
387:
388: if (devtab->func == 0 || mdev_func (mdevp, devtab->func))
389: (void) fprintf (out, devtab->str,
390: mdevp->md_prefix->s_data);
391: else
392: (void) fprintf (out, devtab->nullstr);
393:
394: if ((++ devtab)->str != NULL)
395: (void) fprintf (out, ", ");
396: }
397:
398: (void) fprintf (out, ")");
399: }
400:
401:
402: /*
403: * Write an cdevsw [] and bdevsw [] tables.
404: */
405:
406: #ifdef USE_PROTO
407: LOCAL void (write_devsw) (FILE * out, extinfo_t * extinfop)
408: #else
409: LOCAL void
410: write_devsw ARGS ((out, extinfop))
411: FILE * out;
412: extinfo_t * extinfop;
413: #endif
414: {
415: int i;
416:
417: if (extinfop->ei_ncdevs > 0) {
418:
419: (void) fprintf (out, "cdevsw_t cdevsw [] = {\n");
420:
421: for (i = 0 ; i < extinfop->ei_ncdevs ; i ++) {
422: mdev_t * mdevp = extinfop->ei_cdevsw [i];
423:
424: if (i > 0)
425: (void) fprintf (out, ",\n");
426:
427: if (mdevp == NULL)
428: (void) fprintf (out, "\tNULL_CDEVSW ()");
429: else if (mdev_flag (mdevp, MDEV_STREAM) != 0) {
430:
431: (void) fprintf (out, "\tSTREAMS_ENTRY (%s)",
432: mdevp->md_prefix->s_data);
433: } else {
434:
435: (void) fprintf (out, "\tCDEVSW");
436:
437: write_devsw_line (out, mdevp, _cdevswtab);
438: }
439: }
440:
441: (void) fprintf (out, "\n};\n\nunsigned int ncdevsw = sizeof "
442: "(cdevsw) / sizeof (* cdevsw);\n\n");
443: } else {
444:
445: (void) fprintf (out, "cdevsw_t cdevsw [1];\n\n");
446: (void) fprintf (out, "unsigned int ncdevsw = 0;\n\n");
447: }
448:
449:
450: if (extinfop->ei_nbdevs > 0) {
451:
452: (void) fprintf (out, "bdevsw_t bdevsw [] = {\n");
453:
454: for (i = 0 ; i < extinfop->ei_nbdevs ; i ++) {
455:
456: if (i > 0)
457: (void) fprintf (out, ",\n");
458:
459: if (extinfop->ei_bdevsw [i] != NULL) {
460:
461: (void) fprintf (out, "\tBDEVSW");
462:
463: write_devsw_line (out,
464: extinfop->ei_bdevsw [i],
465: _bdevswtab);
466: } else
467: (void) fprintf (out, "\tNULL_BDEVSW ()");
468: }
469:
470: (void) fprintf (out, "\n};\n\nunsigned int nbdevsw = sizeof "
471: "(bdevsw) / sizeof (* bdevsw);\n\n");
472: } else {
473:
474: (void) fprintf (out, "bdevsw_t bdevsw [1];\n\n");
475: (void) fprintf (out, "unsigned int nbdevsw = 0;\n\n");
476: }
477: }
478:
479:
480: /*
481: * Write a STREAMS module table.
482: */
483:
484: #ifdef USE_PROTO
485: LOCAL void (write_modtab) (FILE * out, extinfo_t * extinfop)
486: #else
487: LOCAL void
488: write_modtab ARGS ((out, extinfop))
489: FILE * out;
490: extinfo_t * extinfop;
491: #endif
492: {
493: int i;
494:
495: if (extinfop->ei_nmodules > 0) {
496:
497: (void) fprintf (out, "modsw_t modsw [] = {\n");
498:
499: for (i = 0 ; i < extinfop->ei_nmodules ; i ++) {
500:
501: if (i > 0)
502: (void) fprintf (out, ",\n");
503:
504: (void) fprintf (out, "\tMODSW_ENTRY (%s)",
505: extinfop->ei_modules [i]->md_devname->s_data);
506: }
507:
508: (void) fprintf (out, "\n};\n\nunsigned int nmodsw = sizeof "
509: "(modsw) / sizeof (* modsw);\n\n");
510: } else {
511:
512: (void) fprintf (out, "modsw_t modsw [1];\n\n");
513: (void) fprintf (out, "unsigned int nmodsw = 0;\n\n");
514: }
515: }
516:
517:
518: /*
519: * Write the external-to-internal device number mapping tables.
520: */
521:
522: #ifdef USE_PROTO
523: LOCAL void (write_mappings) (FILE * out, extinfo_t * extinfop)
524: #else
525: LOCAL void
526: write_mappings ARGS ((out, extinfop))
527: FILE * out;
528: extinfo_t * extinfop;
529: #endif
530: {
531: int i;
532:
533: (void) fprintf (out, "major_t _maxmajor = %d;\n\n",
534: extinfop->ei_nemajors);
535:
536: (void) fprintf (out, "major_t _major [] = {");
537:
538: for (i = 0 ; i < extinfop->ei_nemajors ; i ++) {
539:
540: if (i % 8 == 0)
541: (void) fprintf (out, "\n\t");
542:
543: if (extinfop->ei_etoimajor [i] == NODEV)
544: (void) fprintf (out, "NODEV, ");
545: else
546: (void) fprintf (out, "%d, ",
547: extinfop->ei_etoimajor [i]);
548: }
549:
550: (void) fprintf (out, "NODEV\n};\n\n");
551:
552: (void) fprintf (out, "minor_t _minor [] = {");
553:
554: for (i = 0 ; i < extinfop->ei_nemajors ; i ++) {
555:
556: if (i % 16 == 0)
557: (void) fprintf (out, "\n\t");
558:
559: (void) fprintf (out, "%d, ", extinfop->ei_minoroffset [i]);
560: }
561:
562: (void) fprintf (out, "0\n};\n\n");
563: }
564:
565:
566: /*
567: * Selection predicate for choosing "sdevice" entries that specify interrupt
568: * vectors.
569: */
570:
571: #ifdef USE_PROTO
572: LOCAL int (sel_vector) (sdev_t * sdevp)
573: #else
574: LOCAL int
575: sel_vector ARGS ((sdevp))
576: sdev_t * sdevp;
577: #endif
578: {
579: return sdevp->sd_itype > 0;
580: }
581:
582:
583: /*
584: * Comparison predicate for sorting "sdevice" entries by vector number.
585: */
586:
587: #ifdef USE_PROTO
588: LOCAL int (cmp_vector) (sdev_t * left, sdev_t * right)
589: #else
590: LOCAL int
591: cmp_vector ARGS ((left, right))
592: sdev_t * left;
593: sdev_t * right;
594: #endif
595: {
596: return left->sd_vector < right->sd_vector;
597: }
598:
599:
600: /*
601: * Function for generating tables of interrupt information.
602: */
603:
604: #ifdef USE_PROTO
605: LOCAL void (write_vectors) (FILE * out)
606: #else
607: LOCAL void
608: write_vectors ARGS ((out))
609: FILE * out;
610: #endif
611: {
612: sdlist_t veclist;
613: sdev_t * sdevp;
614: int i;
615: unsigned long masks [MAX_IPL + 1];
616:
617:
618: /*
619: * We select all the "sdevice" entries that request vectors and sort
620: * them into order by vector so it's simple to determine what is
621: * going on.
622: */
623:
624: sdev_sort (& veclist, sel_vector, cmp_vector,
625: offsetof (sdev_t, sd_link));
626:
627:
628: /*
629: * A first pass through the list determines which vectors are being
630: * used at which priority to build masks for the various levels.
631: */
632:
633: for (i = 0 ; i <= MAX_IPL ; i ++)
634: masks [i] = 0;
635:
636: for (sdevp = veclist.sdl_first ; sdevp != NULL ;
637: sdevp = sdevp->sd_link) {
638:
639: masks [sdevp->sd_ipl] = 1UL << sdevp->sd_vector;
640: }
641:
642: (void) fprintf (out, "intmask_t _masktab [] = {");
643:
644: for (i = 0 ; i < MAX_IPL ; i ++) {
645:
646: if (i % 4 == 0)
647: (void) fprintf (out, "\n\t");
648:
649: (void) fprintf (out, "0x%xUL, ", masks [i]);
650:
651: masks [i + 1] |= masks [i];
652: }
653:
654: (void) fprintf (out, "\n\t0xFFFFFFFFUL\n};\n\n");
655:
656:
657: /*
658: * Now we generate thunks for the various interrupt entry points that
659: * can wrap up any mask-manipulation magic.
660: */
661:
662: i = -1;
663:
664: for (sdevp = veclist.sdl_first ; sdevp != NULL ;
665: sdevp = sdevp->sd_link) {
666:
667: if (sdevp->sd_vector != i) {
668: if (i != -1)
669: (void) fprintf (out, "END_THUNK (%d)\n\n", i);
670:
671: i = sdevp->sd_vector;
672:
673: (void) fprintf (out, "BEGIN_THUNK (%d, 0x%xUL)\n",
674: i, masks [sdevp->sd_ipl]);
675: }
676:
677: (void) fprintf (out, "\tCALL_INTR (%d, %s)\n", i,
678: sdevp->sd_mdevp->md_prefix->s_data);
679: }
680:
681: if (i != -1)
682: (void) fprintf (out, "END_THUNK (%d)\n\n", i);
683:
684:
685: /*
686: * Now build a simple table which we can use to install the interrupt
687: * thunks we have built.
688: */
689:
690:
691: if (i == -1) {
692:
693: (void) fprintf (out, "intr_t inttab [1];\n\unsigned int "
694: "nintr = 0;\n\n");
695: return;
696: }
697:
698: (void) fprintf (out, "intr_t inttab [] = {\n");
699:
700:
701: i = -1;
702:
703: for (sdevp = veclist.sdl_first ; sdevp != NULL ;
704: sdevp = sdevp->sd_link) {
705:
706: if (sdevp->sd_vector != i) {
707: if (i != -1)
708: (void) fprintf (out, ",\n");
709:
710: i = sdevp->sd_vector;
711:
712: (void) fprintf (out, "\tINTR_THUNK (%d)", i);
713: }
714: }
715:
716: (void) fprintf (out, "\n};\n\nunsigned int nintr = sizeof (inttab) /"
717: " sizeof (* inttab);\n\n");
718: }
719:
720: #if _REMINDER
721: /*
722: * We output a bogus definition which needs the address of some functions we
723: * want around to use this file...
724: */
725:
726: #ifdef USE_PROTO
727: LOCAL void (write_reminder) (FILE * out)
728: #else
729: LOCAL void
730: write_reminder ARGS ((out))
731: FILE * out;
732: #endif
733: {
734: (void) fprintf (out, "/*\n * Make sure that the functions which use"
735: " this file are out there\n */\n\n");
736: (void) fprintf (out, "__EXTERN_C_BEGIN__\n\n");
737: (void) fprintf (out, "void\t\tSTREAMS_INIT\t__PROTO ((void));\n");
738: (void) fprintf (out, "\n__EXTERN_C_END__\n\n");
739: (void) fprintf (out, "\nvoid (* __bogus []) __PROTO ((void)) = {\n");
740: (void) fprintf (out, "\tSTREAMS_INIT\n};\n");
741: }
742: #endif /* ! _REMINDER */
743:
744:
745: /*
746: * Write out a C-language configuration file with definitions for all the data
747: * the implementation needs compiled from the plain-text configuration
748: * database.
749: */
750:
751: #ifdef __USE_PROTO__
752: int (write_conf_c) (CONST char * name, extinfo_t * extinfop)
753: #else
754: int
755: write_conf_c ARGS ((name, extinfop))
756: CONST char * name;
757: extinfo_t * extinfop;
758: #endif
759: {
760: time_t gentime;
761: char timebuf [70];
762: FILE * out;
763: ehand_t err;
764:
765: if (name == NULL)
766: out = stdout;
767: else if ((out = fopen (name, "w")) == NULL)
768: throw_error ("Unable to open output file for writing");
769:
770: if (PUSH_HANDLER (err) == 0) {
771: time (& gentime);
772:
773: fprintf (out, "/*\n");
774: fprintf (out, " * The code in this file was automatically "
775: "generated. Do not hand-modify!\n");
776:
777: #ifdef __COHERENT__
778: strncpy (timebuf, asctime (localtime (& gentime)),
779: sizeof (timebuf) - 1);
780: timebuf [sizeof (timebuf) - 1] = 0;
781: #else
782: strftime (timebuf, sizeof (timebuf) - 1, "%x %X %Z",
783: localtime (& gentime));
784: #endif
785:
786: fprintf (out, " * Generated at %s\n", timebuf);
787: fprintf (out, " */\n\n");
788: fprintf (out, "#define _KERNEL\t\t1\n");
789: fprintf (out, "#define _DDI_DKI\t1\n\n");
790: fprintf (out, "#include <kernel/confinfo.h>\n\n");
791:
792: write_externs (out);
793: write_misc (out);
794: write_devsw (out, extinfop);
795: write_modtab (out, extinfop);
796: write_mappings (out, extinfop);
797: write_vectors (out);
798:
799: #if _REMINDER
800: write_reminder (out);
801: #endif
802: if (out != stdout)
803: fclose (out);
804: } else {
805: if (out != stdout)
806: fclose (out);
807: CHAIN_ERROR (err);
808: }
809:
810: POP_HANDLER (err);
811: return 0;
812: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.