Annotation of coherent/f/etc/conf/bin/src/mkconf.c, revision 1.1.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:  * '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: }

unix.superglobalmegacorp.com

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