Annotation of coherent/b/kernel/tools/asymkdev.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * File:       asymkdev.c
                      3:  *
                      4:  * Purpose:    read a spec from stdin, ask questions, and make nodes
                      5:  *
                      6:  * $Log:       asymkdev.c,v $
                      7:  * Revision 1.3  93/05/18  07:32:18  bin
                      8:  * *** empty log message ***
                      9:  * 
                     10:  */
                     11: 
                     12: /*
                     13:  * ----------------------------------------------------------------------
                     14:  * Includes.
                     15:  */
                     16: #include <stdio.h>
                     17: #include <termio.h>
                     18: #include <sys/ktty.h>
                     19: #include <sys/asy.h>
                     20: #include <sys/devices.h>
                     21: 
                     22: /*
                     23:  * ----------------------------------------------------------------------
                     24:  * Definitions.
                     25:  *     Constants.
                     26:  *     Macros with argument lists.
                     27:  *     Typedefs.
                     28:  *     Enums.
                     29:  */
                     30: #define BSZ            256
                     31: #define ASYNC_SPECFILE "/etc/default/async"
                     32: #define ASYNC_MKNODS   "asy_mknod"
                     33: 
                     34: #define L_             0
                     35: #define R_             1
                     36: #define PL_            2
                     37: #define PR_            3
                     38: #define FL_            4
                     39: #define FR_            5
                     40: #define FPL_           6
                     41: #define FPR_           7
                     42: 
                     43: #define NO(a,b,c,d)    {use_opt[a]=0;use_opt[b]=0;use_opt[c]=0;use_opt[d]=0;}
                     44: #define MAX_OPT                8
                     45: #define prompt         if(!uflag)printf
                     46: 
                     47: /*
                     48:  * ----------------------------------------------------------------------
                     49:  * Functions.
                     50:  *     Import Functions.
                     51:  *     Export Functions.
                     52:  *     Local Functions.
                     53:  */
                     54: void fatal();
                     55: void g_rec();
                     56: void get_opts();
                     57: void m_rec();
                     58: void make_nodes();
                     59: void p_rec();
                     60: void usage();
                     61: 
                     62: /*
                     63:  * ----------------------------------------------------------------------
                     64:  * Global Data.
                     65:  *     Import Variables.
                     66:  *     Export Variables.
                     67:  *     Local Variables.
                     68:  */
                     69: int    line;                   /* line number in input file            */
                     70: unsigned int   x1,x2,x3,x4,x5,x6,x7;
                     71: char   *cmd;
                     72: char   chan_found[MAX_ASY];    /* true if record seen for the channel  */
                     73: int    port[MAX_ASY];          /* port address for the channel         */
                     74: char   buf[BSZ];               /* input line buffer                    */
                     75: char   msg[BSZ];               /* error message line buffer                    */
                     76: char   expect_chan;            /* number of "M" records expected       */
                     77: char   uflag;                  /* unprompted mode                              */
                     78: char   *suffix[MAX_OPT] = {
                     79:        "l",                    /* L_   */
                     80:        "r",                    /* R_   */
                     81:        "pl",                   /* PL_  */
                     82:        "pr",                   /* PR_  */
                     83:        "fl",                   /* FL_  */
                     84:        "fr",                   /* FR_  */
                     85:        "fpl",                  /* FPL_ */
                     86:        "fpr"                   /* FPR_ */
                     87: };
                     88: char   *ofile, *sfile;
                     89: unsigned char  nmod, poll, flow;
                     90: 
                     91: /*
                     92:  * ----------------------------------------------------------------------
                     93:  * Code.
                     94:  */
                     95: 
                     96: /*
                     97:  * main()
                     98:  *
                     99:  * while able to read a line from input
                    100:  *     call routine to process the record type
                    101:  */
                    102: main(argc, argv)
                    103: int argc;
                    104: char **argv;
                    105: {
                    106:        char    *cp;
                    107:        FILE    *fp;
                    108: 
                    109:        cmd = argv[0];
                    110: 
                    111:        if (!isatty(1))
                    112:                usage();
                    113: 
                    114:        /*
                    115:         * Scan command arguments.
                    116:         */
                    117:        while (cp = *++argv) {
                    118:                if (*cp == '-') {
                    119:                        while(*++cp) {
                    120:                                switch (*cp) {
                    121:                                case 'u':
                    122:                                        uflag = 1;
                    123:                                        break;
                    124:                                default:
                    125:                                        usage();
                    126:                                }
                    127:                        }
                    128:                } else {
                    129:                        if (ofile) {
                    130:                                usage();
                    131:                        } else {
                    132:                                if (sfile)
                    133:                                        ofile = cp;
                    134:                                else
                    135:                                        sfile = cp;
                    136:                        }
                    137:                }
                    138:        }
                    139:        if (!ofile)
                    140:                ofile = ASYNC_MKNODS;
                    141:        if (!sfile)
                    142:                sfile = ASYNC_SPECFILE;
                    143: 
                    144:        /*
                    145:         * Find out which channels are in use.
                    146:         */
                    147:        if ((fp = fopen(sfile, "r")) == 0) {
                    148:                sprintf(msg, "%s: can't open spec file %s", cmd, sfile);
                    149:                fatal(msg);
                    150:        }
                    151:        while (fgets(buf, BSZ, fp)) {
                    152:                line++;
                    153:                switch (buf[0]) {
                    154:                        case 'P':  p_rec();  break;
                    155:                        case 'G':  g_rec();  break;
                    156:                        case 'M':  m_rec();  break;
                    157:                }
                    158:        }
                    159:        fclose(fp);
                    160: 
                    161:        if (expect_chan) {
                    162:                sprintf(msg, "expecting %d \"M\" entries", expect_chan);
                    163:                fatal(msg);
                    164:        }
                    165: 
                    166:        make_nodes();
                    167: 
                    168:        prompt("Done.\n");
                    169:        exit(0);
                    170: }
                    171: 
                    172: void
                    173: p_rec()
                    174: {
                    175:        if (expect_chan) {
                    176:                sprintf(msg, "expecting %d \"M\" entries", expect_chan);
                    177:                fatal(msg);
                    178:        }
                    179: 
                    180:        /*
                    181:         * "P" record is:
                    182:         * P port irq outs excl speed channel nms
                    183:         * port and outs are in hex, others in decimal
                    184:         */
                    185:        if (sscanf(buf+1, "%x%d%x%d%d%d%d",&x1,&x2,&x3,&x4,&x5,&x6,&x7) != 7)
                    186:                fatal("need 7 parameters");
                    187: 
                    188:        if (x6 >= MAX_ASY) {
                    189:                sprintf(msg, "invalid channel #%d\n", x6);
                    190:                fatal(msg);
                    191:        }
                    192: 
                    193:        if (chan_found[x6]) {
                    194:                sprintf(msg, "duplicate channel #%d\n", x6);
                    195:                fatal(msg);
                    196:        }
                    197:        chan_found[x6] = 1;
                    198:        port[x6] = x1;
                    199: }
                    200: 
                    201: void
                    202: g_rec()
                    203: {
                    204:        if (expect_chan) {
                    205:                fprintf(stderr, "expecting %d \"M\" entries", expect_chan);
                    206:                fatal("record out of order");
                    207:        }
                    208: 
                    209:        /*
                    210:         * "G" record is:
                    211:         * G port irq outs type number-of-channels nms
                    212:         * port and outs are in hex, others in decimal
                    213:         * see asy.h for valid types
                    214:         */
                    215:        if (sscanf(buf+1, "%x%d%x%d%d%d",&x1,&x2,&x3,&x4,&x5,&x6) != 6)
                    216:                fatal("need 6 parameters");
                    217:        if (x5 >= MAX_ASY || x5 == 0)
                    218:                fatal("number of channels must be in range 1..8");
                    219:        expect_chan = x5;
                    220: }
                    221: 
                    222: void
                    223: usage()
                    224: {
                    225:        fprintf(stderr, "Usage: %s [-u] specfile outfile\n", cmd);
                    226:        exit(1);
                    227: }
                    228: 
                    229: void
                    230: fatal(s)
                    231: char *s;
                    232: {
                    233:        fprintf(stderr, "%s: line %d  %s\n", cmd, line, s);
                    234:        exit(1);
                    235: }
                    236: 
                    237: void
                    238: m_rec()
                    239: {
                    240:        if (expect_chan == 0) {
                    241:                fatal("unexpected \"M\" record");
                    242:        }
                    243: 
                    244:        /*
                    245:         * "M" record is:
                    246:         * M port speed slot channel
                    247:         * port is in hex, speed in decimal
                    248:         */
                    249:        if (sscanf(buf+1, "%x%d%d%d",&x1,&x2,&x3,&x4) != 4)
                    250:                fatal("need 4 parameters");
                    251: 
                    252:        if (x4 >= MAX_ASY) {
                    253:                sprintf(msg, "invalid channel #%d\n", x4);
                    254:                fatal(msg);
                    255:        }
                    256: 
                    257:        chan_found[x4] = 1;
                    258:        port[x4] = x1;
                    259:        expect_chan--;
                    260: }
                    261: 
                    262: void
                    263: make_nodes()
                    264: {
                    265:        char    chan;
                    266:        char    devname[20] = "";
                    267:        int     last;
                    268:        unsigned char   minor;
                    269:        char    use_opt[MAX_OPT], opt;
                    270:        FILE    *ofp;
                    271: 
                    272:        if ((ofp = fopen(ofile, "w")) == 0) {
                    273:                sprintf(msg, "%s: can't open outfile %s", cmd, ofile);
                    274:                fatal(msg);
                    275:        }
                    276:        fprintf(ofp,
                    277:          "set -x\n"
                    278:          "DEV=${DEV-/dev}\n"
                    279:          "if [ -d $DEV ]\n"
                    280:          "then\n"
                    281:          "\t:\n"
                    282:          "else\n"
                    283:          "\techo \"Invalid device directory $DEV\"\n"
                    284:          "\texit 1\n"
                    285:          "fi\n");
                    286: 
                    287:        line = 0;
                    288:        for (chan = 0; chan < MAX_ASY; chan++) {
                    289:                if (chan_found[chan]) {
                    290:                        /*
                    291:                         * Make default device name.
                    292:                         * Add 1 to last character of previous name, with carry.
                    293:                         * Start with "asy00".
                    294:                         */
                    295:                        if (devname[0]) {
                    296:                                last = strlen(devname) - 1;
                    297:                                if (last > 0 && devname[last]++ == '9') {
                    298:                                        devname[last--] = '0';
                    299:                                        devname[last]++;
                    300:                                }
                    301:                        } else {
                    302:                                strcpy(devname, "asy00");
                    303:                        }
                    304:                        prompt("Channel %2d is port %4x\n", chan, port[chan]);
                    305:                        prompt("Device name [%s]: ", devname);
                    306:                        line++;
                    307:                        if (!fgets(buf, BSZ, stdin)) {
                    308:                                sprintf(msg, "%s: input error at channel %d",
                    309:                                  cmd, chan);
                    310:                                fatal(msg);
                    311:                        }
                    312:                        sscanf(buf, "%s", devname);
                    313: 
                    314:                        /*
                    315:                         * Get user preferences about which devices to make.
                    316:                         */
                    317:                        get_opts(chan);
                    318: 
                    319:                        /*
                    320:                         * Make up to 8 nodes per device.
                    321:                         */
                    322:                        for (opt = 0; opt < MAX_OPT; opt++)
                    323:                                use_opt[opt] = 1;
                    324:                        if (nmod == 0)
                    325:                                NO(L_, PL_, FL_, FPL_)
                    326:                        else if (nmod == 1)
                    327:                                NO(R_, PR_, FR_, FPR_)
                    328:                        if (poll == 0)
                    329:                                NO(PL_, PR_, FPL_, FPR_)
                    330:                        else if (poll == 1)
                    331:                                NO(L_, R_, FL_, FR_)
                    332:                        if (flow == 0)
                    333:                                NO(FL_, FR_, FPL_, FPR_)
                    334:                        else if (flow == 1)
                    335:                                NO(L_, R_, PL_, PR_)
                    336:                        for (opt = 0; opt < MAX_OPT; opt++)
                    337:                                if (use_opt[opt]) {
                    338:                                        minor = chan;
                    339:                                        if ((opt & 1) == 0)
                    340:                                                minor |= 0x80;
                    341:                                        if (opt & 2)
                    342:                                                minor |= 0x40;
                    343:                                        if (opt & 4)
                    344:                                                minor |= 0x20;
                    345: fprintf(ofp, "/etc/mknod -f $DEV/%s%s c %d %d          || exit 1\n",
                    346:   devname, suffix[opt], ASY_MAJOR, minor);
                    347: fprintf(ofp, "/bin/chmog 666 sys sys $DEV/%s%s || exit 1\n",
                    348:   devname, suffix[opt]);
                    349:                                }
                    350:                }
                    351:        }
                    352:        fclose(ofp);
                    353: }
                    354: 
                    355: /*
                    356:  * get_opts()
                    357:  *
                    358:  * set nmod, poll, flow
                    359:  */
                    360: void
                    361: get_opts(chan)
                    362: int chan;
                    363: {
                    364:        static char my_opts[20] = "lrin";
                    365:        char    *cp;
                    366: 
                    367:        prompt("options - (l|r) (i|p) (f|n) [%s]: ", my_opts);
                    368:        line++;
                    369:        if (!fgets(buf, BSZ, stdin)) {
                    370:                sprintf(msg, "input error at channel %d", chan);
                    371:                fatal(msg);
                    372:        }
                    373:        sscanf(buf, "%s", my_opts);
                    374: 
                    375:        /*
                    376:         * Must have at least one of each pair of switches.
                    377:         */
                    378:        nmod = 0;
                    379:        poll = 0;
                    380:        flow = 0;
                    381:        for (cp = my_opts; *cp; cp++) {
                    382:                switch (*cp) {
                    383:                        case 'r': nmod |= 1; break;
                    384:                        case 'l': nmod |= 2; break;
                    385:                        case 'i': poll |= 1; break;
                    386:                        case 'p': poll |= 2; break;
                    387:                        case 'n': flow |= 1; break;
                    388:                        case 'f': flow |= 2; break;
                    389:                        default:
                    390:                                sprintf(msg,
                    391:                                  "invalid option [%s],  channel %d",
                    392:                                  my_opts, chan);
                    393:                                fatal(msg);
                    394:                }
                    395:        }
                    396:        if (nmod)
                    397:                nmod--;
                    398:        else {
                    399:                sprintf(msg, "missing (l|r) option [%s],  channel %d",
                    400:                  my_opts, chan);
                    401:                fatal(msg);
                    402:        }
                    403:        if (poll)
                    404:                poll--;
                    405:        else {
                    406:                sprintf(msg, "missing (i|p) option [%s],  channel %d",
                    407:                  my_opts, chan);
                    408:                fatal(msg);
                    409:        }
                    410:        if (flow)
                    411:                flow--;
                    412:        else {
                    413:                sprintf(msg, "missing (f|n) option [%s],  channel %d",
                    414:                  my_opts, chan);
                    415:                fatal(msg);
                    416:        }
                    417: }

unix.superglobalmegacorp.com

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