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