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