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