file reorg, pathnames.h, paths.h
[unix-history] / usr / src / old / dlmpcc / dlmpcc.c
CommitLineData
0b9ebc2c
KB
1/*
2 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Computer Consoles Inc.
7 *
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the University of California, Berkeley. The name of the
14 * University may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 */
20
21#ifndef lint
22char copyright[] =
23"@(#) Copyright (c) 1988 The Regents of the University of California.\n\
24 All rights reserved.\n";
25#endif /* not lint */
26
706ab6e2 27#ifndef lint
7abf8d65 28static char sccsid[] = "@(#)dlmpcc.c 5.4 (Berkeley) %G%";
0b9ebc2c 29#endif /* not lint */
706ab6e2
SL
30
31/*
32 * MPCC Download and Configuration Program.
33 */
706ab6e2 34#include <sys/ioctl.h>
706ab6e2
SL
35#include <sys/types.h>
36#include <tahoevba/mpreg.h>
7abf8d65
KB
37#include <fcntl.h>
38#include <errno.h>
706ab6e2 39#include <stdio.h>
7abf8d65 40#include <ctype.h>
706ab6e2 41#include "scnhdr.h"
7abf8d65 42#include "pathnames.h"
706ab6e2
SL
43
44#define MAXMPCC 16
45
7abf8d65 46char *MPCCTAB = _PATH_MPCCTAB;
706ab6e2
SL
47int resetflg = 0;
48
49main(argc, argv)
50 char *argv[];
51{
52 int bd;
53
54 if (argc == 1) {
55 for (bd = 0; bd < MAXMPCC; bd++)
56 if (bldmap(bd) != -1)
57 download(bd);
58 exit(0);
59 }
60 for (argc--, argv++; argc > 0; argc--, argv++) {
61 bd = atoi(argv[0]);
62 if (strcmp(argv[0], "-r") == 0) {
63 resetflg = 1;
64 continue;
65 }
66 if (bd > MAXMPCC || bd < 0) {
67 printf("Illegal Board Number=> %d\n", bd);
68 continue;
69 }
70 if (bldmap(bd) == -1)
71 continue;
72 download(bd);
73 }
74 exit(0);
75}
76
77/*
78 * Build Load Module Map
79 */
80struct bdcf cf;
81struct abdcf bdasy;
82
83#define LINESIZE 128
84
85bldmap(dlbd)
86 int dlbd; /* board to be downloaded */
87{
88 FILE *tabfp;
89 int bd, port, count;
90 char *bdstr, *strtok(), protocol, line[LINESIZE];
91 char *lptr, *lptr1, *lptr2;
92
93 protocol = '\0';
94 /* open the configuration file for reading */
95 if ((tabfp = fopen(MPCCTAB, "r")) == NULL) {
96 printf("No Configuration File: %s\n", MPCCTAB);
97 return (-1);
98 }
99 for (;;) {
100 if (fgets(&line[0], LINESIZE-1, tabfp) == NULL) {
101 fclose(tabfp);
102 return (-1);
103 }
104 count++;
105 line[strlen(line)-1] = '\0';
106 lptr = strtok(line, ':');
107 if (tolower(*lptr) != 'm')
108 continue;
109 lptr = strtok((char *)0, ':');
110 bd = atoi(lptr);
111 if (bd == dlbd)
112 break;
113 }
114 cf.fccstimer = 20; /* default to 1 sec (20 * 50ms) */
115 cf.fccsports = 0; /* no ports are fccs */
116 cf.fccssoc = 0; /* no ports switch on close */
117 for (port = 0; port < MPMAXPORT; port++)
118 cf.protoports[port] = MPPROTO_UNUSED;
119 /* check for the keywords following the board number */
120 lptr1 = (char *)0;
121 lptr2 = (char *)0;
122 while (*lptr) {
123 lptr = strtok((char *)0, ':');
124 if (!strncmp(lptr, "FCCS", 4)) {
125 lptr1 = lptr;
126 continue;
127 }
128 if (!strncmp(lptr, "SOC", 3)) {
129 lptr2 = lptr;
130 continue;
131 }
132 }
133 /* process the board and port characteristics */
134 while (fgets(&line[0], LINESIZE-1, tabfp) != NULL) {
135 count++;
136 line[strlen(line)-1] = '\0';
137 if (!line[0]) /* if newline only */
138 continue;
139 lptr = strtok(line, ':');
140 if (tolower(*lptr) == 'm')
141 break;
142 if (*lptr == '#') /* ignore comment */
143 continue;
144 if (tolower(*lptr) == 'p' && tolower(*(lptr+1)) == 'o') {
145 /* PORT */
146 port = atoi(lptr = strtok((char *)0, ':'));
147 protocol = *(lptr = strtok((char *)0, ':'));
148 switch (cf.protoports[port] = protocol) {
149 case '3' : /* ASYNCH 32 port */
150 case 'A' : /* ASYNCH */
151 break;
152 case 'B': /* BISYNCH */
153 break;
154 case 'S': /* SDLC */
155 snapargs(port, lptr);
156 break;
157 case 'X': /* X25 */
158 x25pargs(port, lptr);
159 break;
160 default:
161 printf(
162"No protocol specified on PROTOCOL line in configuration file %s:%d: %s\n",
163 MPCCTAB, count, line);
164 protocol = 'A';
165 break;
166 }
167 continue;
168 }
169 if (tolower(*lptr) == 'p' && tolower(*(lptr+1)) == 'r') {
170 /* PROTOCOL */
171#ifdef notdef
172 if(protocol) {
173 printf(
174"second protocol specified on PROTOCOL line in configuration file %s:%d: %s\n",
175 MPCCTAB, count, line);
176 continue;
177 }
178#endif
179 lptr = strtok((char *) 0, ':');
180 switch (protocol = *lptr) {
181 case '3': /* ASYNCH 32 port */
182 case 'A': /* ASYNCH */
183 asybargs(lptr);
184 break;
185 case 'B': /* BISYNCH */
186 break;
187 case 'S': /* SDLC */
188 snabargs(lptr);
189 break;
190 case 'X': /* X25 */
191 x25bargs(lptr);
192 break;
193 default:
194 printf(
195"No protocol specified on PROTOCOL line in configuration file %s:%d: %s\n",
196 MPCCTAB, count, line);
197 protocol = 'A';
198 break;
199 }
200 continue;
201 }
202 printf("Error in configuration file %s,line %d, %s\n",
203 MPCCTAB, count, line);
204 }
205 fclose(tabfp);
206 mkldnm();
207 return (0);
208}
209
210/*
211 * decode x25 arguments for board
212 *
213 * for X.25, the arguments are N1, N2, T1, T2, T3, T4, K).
214 */
215x25bargs(args)
216 char *args;
217{
218}
219
220/*
221 * decode sna arguments for board
222 * for SNA, the arguments are N1, N2, T1, T2, T3, T4, K).
223 */
224snabargs(args)
225 char *args;
226{
227}
228
229/*
230 * decode async arguments for board
231 */
232asybargs(args)
233char *args;
234{
235
236 bdasy.xmtbsz = atoi(strtok((char *)0, ':'));
237}
238
239/*
240 * decode x25 arguments for port
241 */
242x25pargs(port,args)
243 int port;
244 char *args;
245{
246}
247
248/*
249 * decode sna arguments for port
250 */
251snapargs(port, args)
252 int port;
253 char *args;
254{
255}
256
257gethi()
258{
259 int i;
260
261 for (i = MPMAXPORT-1; i >= 0 && cf.protoports[i] == 0; i--)
262 ;
263 return (i);
264}
265
266getlo()
267{
268 int i;
269
270 for (i = 0; i < MPMAXPORT && cf.protoports[i] == 0; i++)
271 ;
272 return (i);
273}
274
275prntmap(board)
276 int board;
277{
278 int j;
279
280 printf("\nMPCC #: %d\n", board);
281 for (j = 0; j < MPMAXPORT; j++) {
282 printf("port: %d %c", j, cf.protoports[j]);
283 switch (cf.protoports[j]) {
284 case '3': case 'A':
285 printf("\n");
286 break;
287 case 'B':
288 break;
289 case 'S':
290 break;
291 case 'X':
292 break;
293 default:
294 printf("Unused\n");
295 break;
296 }
297 }
298 printf("ldname: %s, ", cf.loadname);
299 printf("hiport: %d, loport: %d\n", gethi(), getlo());
300 if (cf.fccsports != 0)
301 printf("FCCS\n");
302 switch (cf.protoports[0]) {
303 case '3': case 'A':
304 printf("xmtsize: %d\n", bdasy.xmtbsz);
305 break;
306 case 'B':
307 break;
308 case 'S':
309 break;
310 case 'X':
311 break;
312 }
313 printf("protoports: %s\n", cf.protoports);
314}
315
316/*
317 * Make Load Module Name
318 *
319 * if any port is 'ASYNCH"
320 * add 'a' to load module name
321 * if any port is 'BISYNCH'
322 * add 'b' to load module name
323 * if any port is 'SDLC'
324 * add 's' to load module name
325 * if any port is 'X25'
326 * add 'x' to load module name
327 */
328mkldnm()
329{
330 static char *pcols = "ABSX3";
331 char *proto;
332 int j, offset;
333
334 offset = 0;
335 for (proto = pcols; *proto; proto++) {
336 for (j = 0; j < MPMAXPORT; j++) {
337 if (cf.protoports[j] == *proto) {
338 if (*proto == '3')
339 cf.loadname[offset] = '3';
340 else
341 cf.loadname[offset] = tolower(*proto);
342 offset++;
343 break;
344 }
345 }
346 cf.loadname[offset] = '\0';
347 }
348}
349
350/*
351 * if a string is passed as an argument,
352 * save it in the local string area
353 * set the local index to the start of the string
354 * else
355 * set start to the current character in the string
356 * while the character is not the separator,
357 * and the character is not NULL
358 * skip the character
359 */
360static
361char *
362strtok(s, c)
363 char *s, c;
364{
365 static char locals[LINESIZE];
366 static int i;
367 char *start;
368
369 if (s != 0) {
370 strcpy(locals, s);
371 i = 0;
372 }
373 for (start = &locals[i] ; locals[i] && locals[i] != c; i++)
374 ;
375 if (locals[i]) {
376 locals[i] = '\0';
377 i++;
378 }
379 while (*start == ' ')
380 start++;
381 return (start);
382}
383
384short bits[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
385fccs(line, tptr, pptr)
386 char *line, *tptr, *pptr;
387{
388 u_short ports, num, time;
389
390 ports = 0;
391 line = strtok(line, ',');
392 while (*(line = strtok((char *) 0, ',')) != '\0') {
393 num = (short) atoi(line);
394 if (num >= 0 && num < 8)
395 ports |= bits[num];
396 else if (num >= 50 && num < 6400)
397 time = num / 50;
398 else
399 printf("bad value for FCCS: %d\n", num);
400 }
401 *pptr = ports;
402 *tptr = time;
403}
404
405soc(line, sptr)
406 char *line, *sptr;
407{
408 u_short ports, num;
409
410 ports = 0;
411 line = strtok(line, ',');
412 while (*(line = strtok((char *) 0, ',')) != '\0') {
413 num = atoi(line);
414 if (num >= 0 && num < 8)
415 ports |= bits[num];
416 else
417 printf("bad value for SOC: %d\n",num);
418 }
419 *sptr = ports;
420}
421
422char buffer[MPDLBUFSIZE];
423extern int errno;
424struct head1 {
425 long magic;
426 long fill[12];
427 struct scnhdr text;
428 struct scnhdr data;
429 struct scnhdr bss;
430} header1;
431
432download(mpccnum)
433 int mpccnum;
434{
435 char dlname[LINESIZE], fullname[LINESIZE];
436 char *ldname, *ppmap;
437 int dlfd, ldfd;
438 char *it;
439 short i;
440 char hilo[2];
441 long realsize;
442
7abf8d65 443 sprintf(dlname, "%s/mpcc%d", _PATH_DEV, mpccnum);
706ab6e2 444 if (*cf.loadname == '3')
7abf8d65 445 sprintf(fullname, _PATH_MPCC32);
706ab6e2 446 else
7abf8d65 447 sprintf(fullname, _PATH_MPCCDL);
706ab6e2
SL
448 if ((cf.loadname[0]) == '\0')
449 return (-1);
450 if ((dlfd = open(dlname, O_RDWR)) == MP_DLERROR) {
451 printf("Can not open %s\n",dlname);
452 return (-1);
453 }
454 if ((ldfd = open(fullname, O_RDONLY)) == MP_DLERROR) {
455 close(dlfd);
456 printf("Can not access protocol code file: %s\n", fullname);
457 return (-1);
458 }
459 if (dlokay(dlfd,mpccnum) == MP_DLERROR) {
460 close(ldfd);
461 close(dlfd);
462 return (-1);
463 }
464 printf("Downloading MPCC #%x\n", mpccnum);
465 /* read executable file header */
466 if (read(ldfd, &header1, sizeof(header1)) != sizeof(header1)) {
467 printf("Can not read %s\n", fullname);
468 return (-1);
469 }
470 /* place at start of text space */
471 if (lseek(ldfd, header1.text.s_scnptr , (int) 0) == -1) {
472 printf("lseek error(text): %d", errno);
473 return (-1);
474 }
475 /* send text */
476 realsize = header1.data.s_paddr - header1.text.s_paddr;
477 if (dl(ldfd, dlfd, realsize) == -1) {
478 ioctl(dlfd, MPIORESETBOARD, 0L);
479 return (-1);
480 }
481 /* place at start of data space */
482 if (lseek(ldfd, header1.data.s_scnptr , (int) 0) == -1) {
483 printf("lseek error(data): %d", errno);
484 return (-1);
485 }
486 /* send initialized data */
487 realsize = header1.bss.s_paddr - header1.data.s_paddr;
488 if (dl(ldfd, dlfd, realsize) == -1) {
489 ioctl(dlfd, MPIORESETBOARD, 0L);
490 return (-1);
491 }
492 /* signal end of code */
493 if (ioctl(dlfd, MPIOENDCODE, (char *) 0) == MP_DLERROR) {
494 printf("MPIOENDCODE ioctl failed\n");
495 ioctl(dlfd, MPIORESETBOARD, 0L);
496 return (-1);
497 }
498 /* download configuration information */
499 if (config(dlfd) == -1) {
500 ioctl(dlfd, MPIORESETBOARD, 0L);
501 return (-1);
502 }
503 /* write port/protocol map */
504 ppmap = (char *)&cf.protoports[0];
505 tknzmap(ppmap);
506 if (ioctl(dlfd, MPIOPORTMAP, ppmap) == MP_DLERROR) {
507 printf("MPIOPORTMAP ioctl failed\n");
508 ioctl(dlfd, MPIORESETBOARD, 0L);
509 return (-1);
510 }
511 /* signal end of download */
512 if (ioctl(dlfd, MPIOENDDL, (char *) 0) == MP_DLERROR) {
513 printf("MPIOENDDL ioctl failed\n");
514 ioctl(dlfd, MPIORESETBOARD, 0L);
515 return (-1);
516 }
517 close(dlfd);
518 close(ldfd);
519 printf("Download Complete and Successful\n");
520 return (0);
521}
522
523dlokay(bdfd, mpccnum)
524 int bdfd, mpccnum;
525{
526 char answer;
527
528 if (resetflg) {
529 printf("Reseting MPCC #%x\n",mpccnum);
530 ioctl(bdfd, MPIORESETBOARD, 0L);
531 sleep(10);
532 }
533 if (ioctl(bdfd, MPIOSTARTDL, 0) == MP_DLERROR) {
534 if (errno == EBUSY) {
535 printf("MPCC #%x has already been downloaded.\n",
536 mpccnum);
537 printf("Do you want to re-download it?: ");
538 fscanf(stdin,"%c",&answer);
539 while (getchar() != '\n')
540 ;
541 if ((answer | 0x60) != 'y')
542 return (MP_DLERROR);
543 ioctl(bdfd, MPIORESETBOARD, 0L);
544 sleep(10);
545 if (ioctl(bdfd, MPIOSTARTDL, (char *) 0) == MP_DLERROR) {
546 printf("Can't download MPCC #%x\n", mpccnum);
547 return (MP_DLERROR);
548 }
549 } else {
550 switch (errno) {
551 case ENODEV:
552 printf("MPCC #%x not in system\n", mpccnum);
553 break;
554 case EACCES:
555 printf("Download area in use, try later\n");
556 break;
557 case ENOSPC:
558 printf("MPCC #%x already being downloaded\n",
559 mpccnum);
560 break;
561 default:
562 printf("Unknown response from MPCC #%x\n",
563 mpccnum);
564 break;
565 }
566 return (MP_DLERROR);
567 }
568 }
569 return (0);
570}
571
572dl(dskfd, bdfd, size)
573 int dskfd, bdfd;
574 long size;
575{
576 int bytes;
577
578 while (size > 0) {
579 bytes = (size < MPDLBUFSIZE) ? (int) size : MPDLBUFSIZE;
580 if ((bytes = read(dskfd, buffer, bytes)) == MP_DLERROR) {
581 close(dskfd);
582 close(bdfd);
583 printf("Download-Can't read buffer\n");
584 return (-1);
585 }
586 if (write(bdfd, buffer, bytes) == MP_DLERROR) {
587 close(dskfd);
588 close(bdfd);
589 printf("Download-Can't write buffer\n");
590 return (-1);
591 }
592 size -= bytes;
593 }
594 return (0);
595}
596
597/*
598 * download each protocol's configuration data
599 * and the configuration data for tboard.
600 */
601config(dlfd)
602 int dlfd;
603{
604 register int i;
605 char *ldname;
606
607 for (ldname = cf.loadname; *ldname; ldname++) {
608 switch (*ldname) {
609 case '3': case 'a':
610 if (ioctl(dlfd, MPIOASYNCNF, &bdasy) == MP_DLERROR) {
611 printf("async ioctl failed\n");
612 return (-1);
613 }
614 break;
615 case 'b':
616 break;
617 case 'x':
618 break;
619
620 case 's':
621 break;
622 }
623 }
624}
625
626/*
627 * tokenize the protoport string,
628 * (change from the letter to the corresponding number).
629 */
630tknzmap(map)
631 char *map;
632{
633 short i;
634
635 for (i = 0; i < MPMAXPORT; i++) {
636 switch (*map) {
637 case '3' : *map = MPPROTO_ASYNC; break;
638 case 'A' : *map = MPPROTO_ASYNC; break;
639 case 'B' : *map = MPPROTO_BISYNC; break;
640 case 'S' : *map = MPPROTO_SNA; break;
641 case 'X' : *map = MPPROTO_X25; break;
642 default: *map = MPPROTO_UNUSED; break;
643 }
644 map++;
645 }
646}