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