Annotation of coherent/d/PS2_KERNEL/tools/asypatch.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * File:       asypatch.c
        !             3:  *
        !             4:  * Purpose:    read a spec from stdin and patch the asy driver
        !             5:  *
        !             6:  * $Log:       asypatch.c,v $
        !             7:  * Revision 1.1  92/07/17  15:28:54  bin
        !             8:  * Initial revision
        !             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: #ifdef _I386
        !            21: #include <coff.h>
        !            22: #endif
        !            23: 
        !            24: /*
        !            25:  * ----------------------------------------------------------------------
        !            26:  * Definitions.
        !            27:  *     Constants.
        !            28:  *     Macros with argument lists.
        !            29:  *     Typedefs.
        !            30:  *     Enums.
        !            31:  */
        !            32: #define BSZ            256
        !            33: #ifdef _I386
        !            34: #define MAKEPATCH(a1,a2,a3,a4,a5)      coffp0(a1,a2,a3,a4,a5)
        !            35: #else
        !            36: #define MAKEPATCH(a1,a2,a3,a4,a5)      loutpatch(a1,a2,a3,a4,a5)
        !            37: #endif
        !            38: 
        !            39: /*
        !            40:  * ----------------------------------------------------------------------
        !            41:  * Functions.
        !            42:  *     Import Functions.
        !            43:  *     Export Functions.
        !            44:  *     Local Functions.
        !            45:  */
        !            46: void p_rec();
        !            47: void g_rec();
        !            48: void m_rec();
        !            49: void fatal();
        !            50: void asydump();
        !            51: int  asy_ver();
        !            52: int get_speed();
        !            53: void usage();
        !            54: 
        !            55: /*
        !            56:  * ----------------------------------------------------------------------
        !            57:  * Global Data.
        !            58:  *     Import Variables.
        !            59:  *     Export Variables.
        !            60:  *     Local Variables.
        !            61:  */
        !            62: int    line;                   /* line number in input file            */
        !            63: int    num_chan;               /* highest channel number used          */
        !            64: int    group;                  /* next port group to be assigned       */
        !            65: unsigned int   x1,x2,x3,x4,x5,x6,x7;
        !            66: asy0_t asy0[MAX_ASY];
        !            67: asy_gp_t asy_gp[MAX_ASY];
        !            68: char   chan_found[MAX_ASY];    /* true if record seen for the channel  */
        !            69: char   buf[BSZ];               /* input line buffer                    */
        !            70: char   msg[BSZ];               /* error message line buffer                    */
        !            71: char   expect_chan;            /* number of "M" records expected       */
        !            72: char   outs, irq, nms;
        !            73: char   vflag;                  /* verbose mode                         */
        !            74: char   xflag;                  /* debug mode                           */
        !            75: char   *cmd;                   /* command name                         */
        !            76: 
        !            77: /*
        !            78:  * ----------------------------------------------------------------------
        !            79:  * Code.
        !            80:  */
        !            81: 
        !            82: /*
        !            83:  * main()
        !            84:  *
        !            85:  * while able to read a line from input
        !            86:  *     call routine to process the record type
        !            87:  */
        !            88: main(argc, argv)
        !            89: int argc;
        !            90: char **argv;
        !            91: {
        !            92:        int     fd, len, ch, hi_chan, p_ver;
        !            93:        char    *pfile = 0, *cp;
        !            94: 
        !            95:        cmd = argv[0];
        !            96: 
        !            97:        /*
        !            98:         * Scan command arguments.
        !            99:         */
        !           100:        while (cp = *++argv) {
        !           101:                if (*cp == '-') {
        !           102:                        while(*++cp) {
        !           103:                                switch (*cp) {
        !           104:                                case 'v':
        !           105:                                        vflag = 1;
        !           106:                                        break;
        !           107:                                case 'x':
        !           108:                                        xflag = 1;
        !           109:                                        break;
        !           110:                                default:
        !           111:                                        usage();
        !           112:                                }
        !           113:                        }
        !           114:                } else {
        !           115:                        if (pfile)
        !           116:                                usage();
        !           117:                        pfile = cp;
        !           118:                }
        !           119:        }
        !           120: 
        !           121:        if (!pfile)
        !           122:                usage();
        !           123: 
        !           124:        if (vflag)
        !           125:                printf("%s Version %d\n", cmd, ASY_VERSION);
        !           126: 
        !           127:        while (fgets(buf, BSZ, stdin)) {
        !           128:                line++;
        !           129:                switch (buf[0]) {
        !           130:                        case 'P':  p_rec();  break;
        !           131:                        case 'G':  g_rec();  break;
        !           132:                        case 'M':  m_rec();  break;
        !           133:                }
        !           134:        }
        !           135: 
        !           136:        if (expect_chan) {
        !           137:                sprintf(msg, "expecting %d \"M\" entries", expect_chan);
        !           138:                fatal(msg);
        !           139:        }
        !           140: 
        !           141:        /*
        !           142:         * Find highest channel number in use.
        !           143:         */
        !           144:        for (hi_chan = -1, ch = 0; ch < MAX_ASY; ch++)
        !           145:                if (chan_found[ch])
        !           146:                        hi_chan = ch;
        !           147: 
        !           148:        num_chan = hi_chan + 1;
        !           149: 
        !           150:        if (num_chan == 0)
        !           151:                fatal("No channels specified");
        !           152: 
        !           153:        /*
        !           154:         * Make sure the file to be patched is accessible.
        !           155:         */
        !           156:        if ((fd = open(pfile, 2)) == -1) {
        !           157:                sprintf(msg, "can't open file %s\n", pfile);
        !           158:                fatal(msg);
        !           159:        }
        !           160:        close(fd);
        !           161: 
        !           162:        /*
        !           163:         * Version numbers in patch program and driver must match.
        !           164:         */
        !           165:        p_ver = asy_ver(pfile);
        !           166:        if (p_ver != ASY_VERSION) {
        !           167:                sprintf(msg, "Wrong versions: asypatch=%d  %s=%d\n",
        !           168:                  ASY_VERSION, pfile, p_ver);
        !           169:                fatal(msg);
        !           170:        }
        !           171: 
        !           172:        if (vflag)
        !           173:                asydump();
        !           174: 
        !           175:        /*
        !           176:         * Make three or four patches.
        !           177:         */
        !           178:        if (MAKEPATCH(pfile, "ASY_NUM", &num_chan, sizeof(int), 0) == 0)
        !           179:                fatal("can't patch ASY_NUM");
        !           180: 
        !           181:        if (MAKEPATCH(pfile, "ASYGP_NUM", &group, sizeof(int), 0) == 0)
        !           182:                fatal("can't patch ASYGP_NUM");
        !           183: 
        !           184:        len = num_chan * sizeof(asy0[0]);
        !           185:        if (MAKEPATCH(pfile, "asy0", asy0, len, 0) == 0)
        !           186:                fatal("can't patch asy0");
        !           187: 
        !           188:        if (group) {
        !           189:                len = group * sizeof(asy_gp[0]);
        !           190:                if (MAKEPATCH(pfile, "asy_gp", asy_gp, len, 0) == 0)
        !           191:                        fatal("can't patch asy_gp");
        !           192:        }
        !           193: 
        !           194:        exit(0);
        !           195: }
        !           196: 
        !           197: void
        !           198: p_rec()
        !           199: {
        !           200:        asy0_t  *a0;
        !           201:        int     speed;
        !           202: 
        !           203:        if (expect_chan) {
        !           204:                sprintf(msg, "expecting %d \"M\" entries", expect_chan);
        !           205:                fatal(msg);
        !           206:        }
        !           207: 
        !           208:        /*
        !           209:         * Load a struct from input.
        !           210:         *
        !           211:         * "P" record is:
        !           212:         * P port irq outs excl speed channel nms
        !           213:         * port and outs are in hex, others in decimal
        !           214:         */
        !           215:        if (sscanf(buf+1, "%x%d%x%d%d%d%d",&x1,&x2,&x3,&x4,&x5,&x6,&x7) != 7)
        !           216:                fatal("need 7 parameters");
        !           217: 
        !           218:        if (x6 >= MAX_ASY) {
        !           219:                sprintf(msg, "invalid channel #%d\n", x6);
        !           220:                fatal(msg);
        !           221:        }
        !           222: 
        !           223:        if (chan_found[x6]) {
        !           224:                sprintf(msg, "duplicate channel #%d\n", x6);
        !           225:                fatal(msg);
        !           226:        }
        !           227: 
        !           228:        a0 = asy0 + x6;
        !           229: #ifdef _I386
        !           230:        if (x1 >= 0x10000)
        !           231:                fatal("address must be ffff or less");
        !           232: #endif
        !           233:        a0->a_port = x1;
        !           234:        if (x2 >= 16)
        !           235:                fatal("irq must be 15 or less");
        !           236:        a0->a_irqno = x2;
        !           237: #ifdef _I386
        !           238:        if (x3 & 0xfffffff3)
        !           239: #else
        !           240:        if (x3 & 0xfff3)
        !           241: #endif
        !           242:                fatal("only bits 2 & 3 of outs may be nonzero");
        !           243:        a0->a_outs = x3;
        !           244:        if (x4 > 1)
        !           245:                fatal("excl must be 0 or 1");
        !           246:        a0->a_ixc = x4;
        !           247:        speed = get_speed(x5);
        !           248:        if (speed < 0)
        !           249:                fatal("invalid speed");
        !           250:        else
        !           251:                a0->a_speed = speed;
        !           252:        a0->a_asy_gp = NO_ASYGP;
        !           253:        chan_found[x6] = 1;
        !           254:        if (x7 > 1)
        !           255:                fatal("nms must be 0 or 1");
        !           256:        a0->a_nms = x7;
        !           257: }
        !           258: 
        !           259: void
        !           260: g_rec()
        !           261: {
        !           262:        int slot;
        !           263:        asy_gp_t *gp = asy_gp + group;
        !           264: 
        !           265:        if (expect_chan) {
        !           266:                fprintf(stderr, "expecting %d \"M\" entries", expect_chan);
        !           267:                fatal("record out of order");
        !           268:        }
        !           269: 
        !           270:        if (group >= MAX_ASYGP) {
        !           271:                fprintf(stderr, "Just found group #%d\n", group);
        !           272:                fatal("too many groups");
        !           273:        }
        !           274: 
        !           275:        /*
        !           276:         * Load a struct from input.
        !           277:         *
        !           278:         * "G" record is:
        !           279:         * G port irq outs type number-of-channels nms
        !           280:         * port and outs are in hex, others in decimal
        !           281:         * see asy.h for valid types
        !           282:         */
        !           283:        if (sscanf(buf+1, "%x%d%x%d%d%d",&x1,&x2,&x3,&x4,&x5,&x6) != 6)
        !           284:                fatal("need 6 parameters");
        !           285: #ifdef _I386
        !           286:        if (x1 >= 0x10000)
        !           287:                fatal("address must be ffff or less");
        !           288: #endif
        !           289:        gp->stat_port = x1;
        !           290:        if (x2 >= 16)
        !           291:                fatal("irq must be 15 or less");
        !           292:        irq = gp->irq = x2;
        !           293: #ifdef _I386
        !           294:        if (x3 & 0xfffffff3)
        !           295: #else
        !           296:        if (x3 & 0xfff3)
        !           297: #endif
        !           298:                fatal("only bits 2 & 3 of outs may be nonzero");
        !           299:        outs = x3;
        !           300:        if (x4 >= PT_MAX)
        !           301:                fatal("invalid type");
        !           302:        gp->gp_type = x4;
        !           303:        if (x5 > MAX_SLOTS || x5 == 0)
        !           304:                fatal("number of channels must be in range 1..16");
        !           305:        expect_chan = x5;
        !           306:        if (x6 > 1)
        !           307:                fatal("nms must be 0 or 1");
        !           308:        nms = x6;
        !           309:        for (slot = 0; slot < MAX_SLOTS; slot++)
        !           310:                gp->chan_list[slot] = NO_CHANNEL;
        !           311:        group++;
        !           312: }
        !           313: 
        !           314: void
        !           315: usage()
        !           316: {
        !           317:        fprintf(stderr, "%s Version %d\n", cmd, ASY_VERSION);
        !           318:        fprintf(stderr, "Usage: %s [-vx] patchfile < specfile\n", cmd);
        !           319:        exit(1);
        !           320: }
        !           321: 
        !           322: void
        !           323: fatal(s)
        !           324: char *s;
        !           325: {
        !           326:        fprintf(stderr, "%s: line %d  %s\n", cmd, line, s);
        !           327:        exit(1);
        !           328: }
        !           329: 
        !           330: void
        !           331: m_rec()
        !           332: {
        !           333:        asy0_t *a0;
        !           334:        int speed;
        !           335: 
        !           336:        if (expect_chan == 0) {
        !           337:                fatal("unexpected \"M\" record");
        !           338:        }
        !           339: 
        !           340:        /*
        !           341:         * Load a struct from input.
        !           342:         *
        !           343:         * "M" record is:
        !           344:         * M port speed slot channel
        !           345:         * port is in hex, speed in decimal
        !           346:         */
        !           347:        if (sscanf(buf+1, "%x%d%d%d",&x1,&x2,&x3,&x4) != 4)
        !           348:                fatal("need 4 parameters");
        !           349: 
        !           350:        if (x4 >= MAX_ASY) {
        !           351:                sprintf(msg, "invalid channel #%d\n", x4);
        !           352:                fatal(msg);
        !           353:        }
        !           354: 
        !           355:        if (chan_found[x4]) {
        !           356:                sprintf(msg, "duplicate channel #%d\n", x4);
        !           357:                fatal(msg);
        !           358:        }
        !           359: 
        !           360:        if (x3 >= MAX_SLOTS) {
        !           361:                sprintf(msg, "slot number %d must be less than 16\n", x3);
        !           362:                fatal(msg);
        !           363:        }
        !           364:        a0 = asy0 + x4;
        !           365: 
        !           366: #ifdef _I386
        !           367:        if (x1 >= 0x10000)
        !           368:                fatal("address must be ffff or less");
        !           369: #endif
        !           370:        a0->a_port = x1;
        !           371:        speed = get_speed(x2);
        !           372:        if (speed < 0)
        !           373:                fatal("invalid speed");
        !           374:        else
        !           375:                a0->a_speed = speed;
        !           376: 
        !           377:        a0->a_outs = outs;
        !           378:        a0->a_nms = nms;
        !           379:        a0->a_ixc = 0;
        !           380:        a0->a_irqno = irq;
        !           381:        a0->a_asy_gp = group - 1;
        !           382:        asy_gp[group - 1].chan_list[x3] = x4;
        !           383:        chan_found[x4] = 1;
        !           384:        expect_chan--;
        !           385: }
        !           386: 
        !           387: int
        !           388: get_speed(rate)
        !           389: int rate;
        !           390: {
        !           391:        int ret;
        !           392: 
        !           393:        switch (rate) {
        !           394:                case 0:         ret = B0;       break;
        !           395:                case 50:        ret = B50;      break;
        !           396:                case 75:        ret = B75;      break;
        !           397:                case 110:       ret = B110;     break;
        !           398:                case 134:       ret = B134;     break;
        !           399:                case 150:       ret = B150;     break;
        !           400:                case 200:       ret = B200;     break;
        !           401:                case 300:       ret = B300;     break;
        !           402:                case 600:       ret = B600;     break;
        !           403:                case 1200:      ret = B1200;    break;
        !           404:                case 1800:      ret = B1800;    break;
        !           405:                case 2400:      ret = B2400;    break;
        !           406:                case 4800:      ret = B4800;    break;
        !           407:                case 9600:      ret = B9600;    break;
        !           408:                case 19200:     ret = B19200;   break;
        !           409: #ifdef _I386
        !           410:                case 38400:     ret = B38400;   break;
        !           411: #endif
        !           412:                default:        ret = -1;
        !           413:        }
        !           414:        return ret;
        !           415: }
        !           416: 
        !           417: #ifdef _I386
        !           418: /*
        !           419:  * coffp0()
        !           420:  *
        !           421:  * Given a file name, a symbol name, a buffer, and number of bytes in
        !           422:  * the buffer, read or write the buffer into the COFF file at the
        !           423:  * symbol specified.
        !           424:  *
        !           425:  * Read the given file if argument "do_read" is 1, else write to the file.
        !           426:  * Return nonzero if success; zero if failure.
        !           427:  */
        !           428: int
        !           429: coffp0(fname, sym, data, len, do_read)
        !           430: char *fname, *sym, *data;
        !           431: int len, do_read;
        !           432: {
        !           433:        int     ret;
        !           434:        SYMENT  se;
        !           435: 
        !           436:        /*
        !           437:         * put together SYMENT stuff for coffnlist
        !           438:         */
        !           439:        se._n._n_n._n_zeroes = 0;
        !           440:        se._n._n_n._n_offset = sizeof(long);
        !           441:        se.n_type = -1;
        !           442:        ret = coffnlist(fname, &se, sym, 1);
        !           443: 
        !           444:        if (ret)
        !           445:                ret = coffpatch(fname, &se, sym, data, len, do_read);
        !           446: 
        !           447:        return ret;
        !           448: }
        !           449: #endif
        !           450: 
        !           451: void
        !           452: asydump()
        !           453: {
        !           454:        char chan, g;
        !           455:        asy0_t *a0;
        !           456:        asy_gp_t *gp;
        !           457: 
        !           458:        /*
        !           459:         * Display totals.
        !           460:         */
        !           461:        printf("Channels = %2d  Groups = %d\n", num_chan, group);
        !           462: 
        !           463:        /*
        !           464:         * Display channel table asy0.
        !           465:         */
        !           466:        printf("Ch port Ir S O Gp X N\n");
        !           467:        for (chan = 0; chan < num_chan; chan++) {
        !           468:                a0 = asy0 + chan;
        !           469:                printf("%2d %4x %2d %1x %1x %2d %1d %1d\n",
        !           470:                  chan, a0->a_port, a0->a_irqno, a0->a_speed, a0->a_outs,
        !           471:                  a0->a_asy_gp, a0->a_ixc, a0->a_nms);
        !           472:        }
        !           473: 
        !           474:        /*
        !           475:         * Display group table asy_gp.
        !           476:         */
        !           477:        if (group) {
        !           478:                printf("Gp Port T Irq  Channels...............\n");
        !           479:                for (g = 0; g < group; g++) {
        !           480:                        int s;
        !           481: 
        !           482:                        gp = asy_gp + g;
        !           483:                        printf("%2d %4x %1d %2d ",
        !           484:                          g,gp->stat_port,gp->gp_type,gp->irq);
        !           485:                        for (s = 0; s < MAX_SLOTS; s++)
        !           486:                                if (gp->chan_list[s] == NO_CHANNEL)
        !           487:                                        printf("   ", gp->chan_list[s]);
        !           488:                                else
        !           489:                                        printf(" %2d", gp->chan_list[s]);
        !           490:                        putchar('\n');
        !           491:                }
        !           492:        }
        !           493: }
        !           494: 
        !           495: /*
        !           496:  * asy_ver()
        !           497:  *
        !           498:  * Fetch the initial value at symbol ASY_VER (ASY_VER_ for 286)
        !           499:  * in file "fname".
        !           500:  *
        !           501:  * Return -1 on failure;  otherwise return the value at the symbol.
        !           502:  */
        !           503: int
        !           504: asy_ver(fname)
        !           505: char * fname;
        !           506: {
        !           507:        int ret = -1;
        !           508:        int version;
        !           509: 
        !           510:        if (MAKEPATCH(fname, "ASY_VER", &version, sizeof(int), 1))
        !           511:                ret = version;
        !           512:        return ret;
        !           513: }

unix.superglobalmegacorp.com

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