date and time created 87/11/15 14:33:54 by sam
authorSam Leffler <sam@ucbvax.Berkeley.EDU>
Mon, 16 Nov 1987 06:33:54 +0000 (22:33 -0800)
committerSam Leffler <sam@ucbvax.Berkeley.EDU>
Mon, 16 Nov 1987 06:33:54 +0000 (22:33 -0800)
SCCS-vsn: old/dlmpcc/dlmpcc.c 5.1

usr/src/old/dlmpcc/dlmpcc.c [new file with mode: 0644]

diff --git a/usr/src/old/dlmpcc/dlmpcc.c b/usr/src/old/dlmpcc/dlmpcc.c
new file mode 100644 (file)
index 0000000..9956710
--- /dev/null
@@ -0,0 +1,622 @@
+#ifndef lint
+static char sccsid[] = "@(#)dlmpcc.c   5.1 (Berkeley from CCI) %G%";
+#endif
+
+/*
+ * MPCC Download and Configuration Program.
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <tahoevba/mpreg.h>
+#include <stdio.h>
+
+#include "scnhdr.h"
+
+#define MAXMPCC 16
+
+char   *MPCCTAB = "/etc/mpcctab";
+int    resetflg = 0;
+
+main(argc, argv)
+       char *argv[];
+{
+       int bd;
+
+       if (argc == 1) {
+               for (bd = 0; bd < MAXMPCC; bd++)
+                       if (bldmap(bd) != -1)
+                               download(bd);
+               exit(0);
+       }
+       for (argc--, argv++; argc > 0; argc--, argv++) {
+               bd = atoi(argv[0]);
+               if (strcmp(argv[0], "-r") == 0) {
+                       resetflg = 1;
+                       continue;
+               }
+               if (bd > MAXMPCC || bd < 0) {
+                       printf("Illegal Board Number=> %d\n", bd);
+                       continue;
+               }
+               if (bldmap(bd) == -1)
+                       continue;
+               download(bd);
+       }
+       exit(0);
+}
+
+/*     
+ * Build Load Module Map
+ */
+struct  bdcf cf;
+struct abdcf bdasy;
+
+#define LINESIZE 128
+
+bldmap(dlbd)
+       int dlbd;               /* board to be downloaded */
+{
+       FILE *tabfp;
+       int bd, port, count;
+       char *bdstr, *strtok(), protocol, line[LINESIZE];
+       char *lptr, *lptr1, *lptr2;
+       
+       protocol = '\0';
+       /* open the configuration file for reading */
+       if ((tabfp = fopen(MPCCTAB, "r")) == NULL) {
+               printf("No Configuration File: %s\n", MPCCTAB);
+               return (-1);
+       }
+       for (;;) {
+               if (fgets(&line[0], LINESIZE-1, tabfp) == NULL) {
+                       fclose(tabfp);
+                       return (-1);
+               }
+               count++;
+               line[strlen(line)-1] = '\0';
+               lptr = strtok(line, ':');
+               if (tolower(*lptr) != 'm')
+                       continue;
+               lptr = strtok((char *)0, ':');
+               bd = atoi(lptr);
+               if (bd == dlbd)
+                       break;
+       }
+       cf.fccstimer = 20;      /* default to 1 sec (20 * 50ms) */
+       cf.fccsports = 0;       /* no ports are fccs */
+       cf.fccssoc = 0;         /* no ports switch on close */
+       for (port = 0; port < MPMAXPORT; port++)
+               cf.protoports[port] = MPPROTO_UNUSED;
+       /* check for the keywords following the board number */
+       lptr1 = (char *)0;
+       lptr2 = (char *)0;
+       while (*lptr) {
+               lptr = strtok((char *)0, ':');
+               if (!strncmp(lptr, "FCCS", 4)) {
+                       lptr1 = lptr;
+                       continue;
+               }
+               if (!strncmp(lptr, "SOC", 3)) {
+                       lptr2 = lptr;
+                       continue;
+               }
+       }
+       /* process the board and port characteristics */
+       while (fgets(&line[0], LINESIZE-1, tabfp) != NULL) {
+               count++;
+               line[strlen(line)-1] = '\0';
+               if (!line[0])           /* if newline only */
+                       continue;
+               lptr = strtok(line, ':');
+               if (tolower(*lptr) == 'm')
+                       break;
+               if (*lptr == '#')       /* ignore comment */
+                       continue;
+               if (tolower(*lptr) == 'p' && tolower(*(lptr+1)) == 'o') {
+                       /* PORT */
+                       port = atoi(lptr = strtok((char *)0, ':'));
+                       protocol = *(lptr = strtok((char *)0, ':'));
+                       switch (cf.protoports[port] = protocol) {
+                       case '3' :              /* ASYNCH 32 port */
+                       case 'A' :              /* ASYNCH */
+                               break;
+                       case 'B':               /* BISYNCH */
+                               break;
+                       case 'S':               /* SDLC */
+                               snapargs(port, lptr);
+                               break;
+                       case 'X':               /* X25 */
+                               x25pargs(port, lptr);
+                               break;
+                       default:
+                               printf(
+"No protocol specified on PROTOCOL line in configuration file %s:%d: %s\n",
+                                   MPCCTAB, count, line);
+                               protocol = 'A';
+                               break;
+                       }
+                       continue;
+               }
+               if (tolower(*lptr) == 'p' && tolower(*(lptr+1)) == 'r') {
+                       /* PROTOCOL */
+#ifdef notdef
+                       if(protocol) {
+                               printf(
+"second protocol specified on PROTOCOL line in configuration file %s:%d: %s\n",
+                                   MPCCTAB, count, line);
+                               continue;
+                       }
+#endif
+                       lptr = strtok((char *) 0, ':');
+                       switch (protocol = *lptr) {
+                       case '3':               /* ASYNCH 32 port */
+                       case 'A':               /* ASYNCH */
+                               asybargs(lptr);
+                               break;
+                       case 'B':               /* BISYNCH */
+                               break;
+                       case 'S':               /* SDLC */
+                               snabargs(lptr);
+                               break;
+                       case 'X':               /* X25 */
+                               x25bargs(lptr);
+                               break;
+                       default:
+                               printf(
+"No protocol specified on PROTOCOL line in configuration file %s:%d: %s\n",
+                                   MPCCTAB, count, line);
+                               protocol = 'A';
+                               break;
+                       }
+                       continue;
+               }
+               printf("Error in configuration file %s,line %d, %s\n",
+                   MPCCTAB, count, line);
+       }
+       fclose(tabfp);
+       mkldnm();
+       return (0);
+}
+
+/*
+ * decode x25 arguments for board
+ *
+ * for X.25, the arguments are N1, N2, T1, T2, T3, T4, K).
+ */
+x25bargs(args)
+       char *args;
+{
+}
+
+/*
+ * decode sna arguments for board
+ * for SNA, the arguments are N1, N2, T1, T2, T3, T4, K).
+ */
+snabargs(args)
+       char *args;
+{
+}
+
+/*
+ * decode async arguments for board
+ */
+asybargs(args)
+char *args;
+{
+
+       bdasy.xmtbsz = atoi(strtok((char *)0, ':'));
+}
+
+/*
+ * decode x25 arguments for port
+ */
+x25pargs(port,args)
+       int port;
+       char *args;
+{
+}
+
+/*
+ * decode sna arguments for port
+ */
+snapargs(port, args)
+       int port;
+       char *args;
+{
+}
+
+gethi()
+{
+       int i;
+
+       for (i = MPMAXPORT-1; i >= 0 && cf.protoports[i] == 0; i--)
+               ;
+       return (i);
+}
+
+getlo()
+{
+       int i;
+
+       for (i = 0; i < MPMAXPORT && cf.protoports[i] == 0; i++)
+               ;
+       return (i);
+}
+
+prntmap(board)
+       int board;
+{
+       int j;
+
+       printf("\nMPCC #: %d\n", board);
+       for (j = 0; j < MPMAXPORT; j++) {
+               printf("port: %d  %c", j, cf.protoports[j]);
+               switch (cf.protoports[j]) {
+               case '3': case 'A':
+                       printf("\n");
+                       break;
+               case 'B':
+                       break;
+               case 'S':
+                       break;
+               case 'X':
+                       break;
+               default:
+                       printf("Unused\n");
+                       break;
+               }
+       }
+       printf("ldname: %s, ", cf.loadname);
+       printf("hiport: %d, loport: %d\n", gethi(), getlo());
+       if (cf.fccsports != 0)
+               printf("FCCS\n");
+       switch (cf.protoports[0]) {
+       case '3': case 'A':
+               printf("xmtsize: %d\n", bdasy.xmtbsz);
+               break;
+       case 'B':
+               break;
+       case 'S':
+               break;
+       case 'X':
+               break;
+       }
+       printf("protoports: %s\n", cf.protoports);
+}
+
+/*
+ * Make Load Module Name
+ *
+ * if any port is 'ASYNCH"
+ *     add 'a' to load module name
+ * if any port is 'BISYNCH'
+ *     add 'b' to load module name
+ * if any port is 'SDLC'
+ *     add 's' to load module name
+ * if any port is 'X25'
+ *     add 'x' to load module name
+ */
+mkldnm()
+{
+       static char *pcols = "ABSX3";
+       char *proto;
+       int j, offset;
+
+       offset = 0;
+       for (proto = pcols; *proto; proto++) {
+               for (j = 0; j < MPMAXPORT; j++) {
+                       if (cf.protoports[j] == *proto) {
+                               if (*proto == '3')
+                                       cf.loadname[offset] = '3';
+                               else
+                                       cf.loadname[offset] = tolower(*proto);
+                               offset++;
+                               break;
+                       }
+               }
+               cf.loadname[offset] = '\0';
+       }
+}
+
+/*
+ * if a string is passed as an argument,
+ *     save it in the local string area
+ *     set the local index to the start of the string
+ * else
+ *     set start to the current character in the string
+ *     while the character is not the separator,
+ *             and the character is not NULL
+ *                     skip the character
+ */
+static
+char *
+strtok(s, c)
+       char *s, c;
+{
+       static char locals[LINESIZE];
+       static int i;
+       char *start;
+
+       if (s != 0) {
+               strcpy(locals, s);
+               i = 0;
+       }
+       for (start = &locals[i] ; locals[i] && locals[i] != c; i++)
+               ;
+       if (locals[i]) {
+               locals[i] = '\0';
+               i++;
+       }
+       while (*start == ' ')
+               start++;
+       return (start);
+}
+
+short  bits[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+fccs(line, tptr, pptr)
+       char *line, *tptr, *pptr;
+{
+       u_short ports, num, time;
+
+       ports = 0;
+       line = strtok(line, ',');
+       while (*(line = strtok((char *) 0, ',')) != '\0') {
+               num = (short) atoi(line);
+               if (num >= 0 && num < 8)
+                       ports |= bits[num];
+               else if (num >= 50 && num < 6400)
+                       time = num / 50;
+               else
+                       printf("bad value for FCCS: %d\n", num);
+       }
+       *pptr = ports;
+       *tptr = time;
+}
+
+soc(line, sptr)
+       char *line, *sptr;
+{
+       u_short ports, num;
+
+       ports = 0;
+       line = strtok(line, ',');
+       while (*(line = strtok((char *) 0, ',')) != '\0') {
+               num = atoi(line);
+               if (num >= 0 && num < 8)
+                       ports |= bits[num];
+               else
+                       printf("bad value for SOC: %d\n",num);
+       }
+       *sptr = ports;
+}
+
+char   buffer[MPDLBUFSIZE];
+extern int errno;
+struct head1 {
+       long    magic;
+       long    fill[12];
+       struct  scnhdr text;
+       struct  scnhdr data;
+       struct  scnhdr bss;
+} header1;
+
+download(mpccnum)
+       int mpccnum;
+{
+       char dlname[LINESIZE], fullname[LINESIZE];
+       char *ldname, *ppmap;
+       int dlfd, ldfd;
+       char *it;
+       short i;
+       char hilo[2];
+       long realsize;
+
+       sprintf(dlname, "/dev/mpcc%d", mpccnum);
+       if (*cf.loadname == '3')
+               sprintf(fullname, "/etc/mpcc32");
+       else
+               sprintf(fullname, "/etc/mpcc%s", cf.loadname);
+       if ((cf.loadname[0]) == '\0')
+               return (-1);
+       if ((dlfd = open(dlname, O_RDWR)) == MP_DLERROR) {
+               printf("Can not open %s\n",dlname);
+               return (-1);
+       }
+       if ((ldfd = open(fullname, O_RDONLY)) == MP_DLERROR) {
+               close(dlfd);
+               printf("Can not access protocol code file: %s\n", fullname);
+               return (-1);
+       }
+       if (dlokay(dlfd,mpccnum) == MP_DLERROR) {
+               close(ldfd);
+               close(dlfd);
+               return (-1);
+       }
+       printf("Downloading MPCC #%x\n", mpccnum);
+       /* read executable file header */
+       if (read(ldfd, &header1, sizeof(header1)) != sizeof(header1)) {
+               printf("Can not read %s\n", fullname);
+               return (-1);
+       }
+       /* place at start of text space */
+       if (lseek(ldfd, header1.text.s_scnptr , (int) 0) == -1) {
+               printf("lseek error(text): %d", errno);
+               return (-1);
+       }
+       /* send text */
+       realsize = header1.data.s_paddr - header1.text.s_paddr;
+       if (dl(ldfd, dlfd, realsize) == -1) {
+               ioctl(dlfd, MPIORESETBOARD, 0L);
+               return (-1);
+       }
+       /* place at start of data space */
+       if (lseek(ldfd, header1.data.s_scnptr , (int) 0) == -1) {
+               printf("lseek error(data): %d", errno);
+               return (-1);
+       }
+       /* send initialized data */
+       realsize = header1.bss.s_paddr - header1.data.s_paddr;
+       if (dl(ldfd, dlfd, realsize) == -1) {
+               ioctl(dlfd, MPIORESETBOARD, 0L);
+               return (-1);
+       }
+       /* signal end of code */
+       if (ioctl(dlfd, MPIOENDCODE, (char *) 0) == MP_DLERROR) {
+               printf("MPIOENDCODE ioctl failed\n");
+               ioctl(dlfd, MPIORESETBOARD, 0L);
+               return (-1);
+       }
+       /* download configuration information   */
+       if (config(dlfd) == -1) {
+               ioctl(dlfd, MPIORESETBOARD, 0L);
+               return (-1);
+       }
+       /* write port/protocol map */
+       ppmap = (char *)&cf.protoports[0];
+       tknzmap(ppmap);
+       if (ioctl(dlfd, MPIOPORTMAP, ppmap) == MP_DLERROR) {
+               printf("MPIOPORTMAP ioctl failed\n");
+               ioctl(dlfd, MPIORESETBOARD, 0L);
+               return (-1);
+       }
+       /* signal end of download */
+       if (ioctl(dlfd, MPIOENDDL, (char *) 0) == MP_DLERROR) {
+               printf("MPIOENDDL ioctl failed\n");
+               ioctl(dlfd, MPIORESETBOARD, 0L);
+               return (-1);
+       }
+       close(dlfd);
+       close(ldfd);
+       printf("Download Complete and Successful\n");
+       return (0);
+}
+
+dlokay(bdfd, mpccnum)
+       int bdfd, mpccnum;
+{
+       char answer;
+
+       if (resetflg) {
+               printf("Reseting MPCC #%x\n",mpccnum);
+               ioctl(bdfd, MPIORESETBOARD, 0L);
+               sleep(10);
+       }
+       if (ioctl(bdfd, MPIOSTARTDL, 0) == MP_DLERROR) {
+               if (errno == EBUSY) {
+                       printf("MPCC #%x has already been downloaded.\n",
+                           mpccnum);
+                       printf("Do you want to re-download it?: ");
+                       fscanf(stdin,"%c",&answer);
+                       while (getchar() != '\n')
+                               ;
+                       if ((answer | 0x60) != 'y')
+                               return (MP_DLERROR);
+                       ioctl(bdfd, MPIORESETBOARD, 0L);
+                       sleep(10);
+                       if (ioctl(bdfd, MPIOSTARTDL, (char *) 0) == MP_DLERROR) {
+                               printf("Can't download MPCC #%x\n", mpccnum);
+                               return (MP_DLERROR);
+                       }
+               } else {
+                       switch (errno) {
+                       case ENODEV:
+                               printf("MPCC #%x not in system\n", mpccnum);
+                               break;
+                       case EACCES:
+                               printf("Download area in use, try later\n");
+                               break;
+                       case ENOSPC:
+                               printf("MPCC #%x already being downloaded\n",
+                                   mpccnum);
+                               break;
+                       default:
+                               printf("Unknown response from MPCC #%x\n",
+                                   mpccnum);
+                               break;
+                       }
+                       return (MP_DLERROR);
+               }
+       }
+       return (0);
+}
+
+dl(dskfd, bdfd, size)
+       int dskfd, bdfd;
+       long size;
+{
+       int bytes;
+
+       while (size > 0) {
+               bytes = (size < MPDLBUFSIZE) ? (int) size : MPDLBUFSIZE;
+               if ((bytes = read(dskfd, buffer, bytes)) == MP_DLERROR) {
+                       close(dskfd);
+                       close(bdfd);
+                       printf("Download-Can't read buffer\n");
+                       return (-1);
+               }
+               if (write(bdfd, buffer, bytes) == MP_DLERROR) {
+                       close(dskfd);
+                       close(bdfd);
+                       printf("Download-Can't write buffer\n");
+                       return (-1);
+               }
+               size -= bytes;
+       }
+       return (0);
+}
+
+/*
+ * download each protocol's configuration data
+ * and the configuration data for tboard.
+ */
+config(dlfd)
+       int dlfd;
+{
+       register int i;
+       char *ldname;
+
+       for (ldname = cf.loadname; *ldname; ldname++) {
+               switch (*ldname) {
+               case '3': case 'a':
+                       if (ioctl(dlfd, MPIOASYNCNF, &bdasy) == MP_DLERROR) {
+                               printf("async ioctl failed\n");
+                               return (-1);
+                       }
+                       break;
+               case 'b':
+                       break;
+               case 'x':
+                       break;
+
+               case 's':
+                       break;
+               }
+       }
+}
+
+/*
+ * tokenize the protoport string,
+ * (change from the letter to the corresponding number).
+ */
+tknzmap(map)
+       char *map;
+{
+       short i;
+
+       for (i = 0; i < MPMAXPORT; i++) {
+               switch (*map) {
+               case '3' :      *map = MPPROTO_ASYNC; break;
+               case 'A' :      *map = MPPROTO_ASYNC; break;
+               case 'B' :      *map = MPPROTO_BISYNC; break;
+               case 'S' :      *map = MPPROTO_SNA; break;
+               case 'X' :      *map = MPPROTO_X25; break;
+               default:        *map = MPPROTO_UNUSED; break;
+               }
+               map++;
+       }
+}