Annotation of coherent/b/STREAMS/conf_79/mkconf.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.