1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#include <stdlib.h>
34#include <stdio.h>
35#include <fcntl.h>
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <sys/errno.h>
39
40#include "dgap_types.h"
41#include "digi.h"
42#include "dgap_fep5.h"
43
44#include "dgap_downld.h"
45
46#include <string.h>
47#include <malloc.h>
48#include <stddef.h>
49#include <unistd.h>
50
51char *pgm;
52void myperror();
53
54
55
56
57
58
59
60struct image_info {
61 short type;
62 short family;
63 short subtype;
64 int len;
65 char *image;
66 char *name;
67 char *fname;
68 char *pathname;
69 time_t mtime;
70};
71
72#define IBIOS 0
73#define IFEP 1
74#define ICONC 2
75#define ICONFIG 3
76#define IBAD 4
77
78#define DEFAULT_LOC "/lib/firmware/dgap/"
79
80struct image_info *image_list;
81int nimages, count;
82
83struct image_info images[] = {
84{IBIOS, T_EPC, SUBTYPE, 0, NULL, "EPC/X", "fxbios.bin", DEFAULT_LOC "fxbios.bin", 0 },
85{IFEP, T_EPC, SUBTYPE, 0, NULL, "EPC/X", "fxfep.bin", DEFAULT_LOC "fxfep.bin", 0 },
86{ICONC, T_EPC, SUBTYPE, 0, NULL, "EPC/X", "fxcon.bin", DEFAULT_LOC "fxcon.bin", 0 },
87
88{IBIOS, T_CX, SUBTYPE, 0, NULL, "C/X", "cxbios.bin", DEFAULT_LOC "cxbios.bin", 0 },
89{IFEP, T_CX, SUBTYPE, 0, NULL, "C/X", "cxhost.bin", DEFAULT_LOC "cxhost.bin", 0 },
90
91{IBIOS, T_CX, T_PCIBUS, 0, NULL, "C/X PCI", "cxpbios.bin", DEFAULT_LOC "cxpbios.bin", 0 },
92{IFEP, T_CX, T_PCIBUS, 0, NULL, "C/X PCI", "cxpfep.bin", DEFAULT_LOC "cxpfep.bin", 0 },
93
94{ICONC, T_CX, SUBTYPE, 0, NULL, "C/X", "cxcon.bin", DEFAULT_LOC "cxcon.bin", 0 },
95{ICONC, T_CX, SUBTYPE, 0, NULL, "C/X", "ibmcxcon.bin", DEFAULT_LOC "ibmcxcon.bin", 0 },
96{ICONC, T_CX, SUBTYPE, 0, NULL, "C/X", "ibmencon.bin", DEFAULT_LOC "ibmencon.bin", 0 },
97
98{IBIOS, FAMILY, T_PCXR, 0, NULL, "PCXR", "xrbios.bin", DEFAULT_LOC "xrbios.bin", 0 },
99{IFEP, FAMILY, T_PCXR, 0, NULL, "PCXR", "xrfep.bin", DEFAULT_LOC "xrfep.bin", 0 },
100
101{IBIOS, T_PCLITE, SUBTYPE, 0, NULL, "X/em", "sxbios.bin", DEFAULT_LOC "sxbios.bin", 0 },
102{IFEP, T_PCLITE, SUBTYPE, 0, NULL, "X/em", "sxfep.bin", DEFAULT_LOC "sxfep.bin", 0 },
103
104{IBIOS, T_EPC, T_PCIBUS, 0, NULL, "PCI", "pcibios.bin", DEFAULT_LOC "pcibios.bin", 0 },
105{IFEP, T_EPC, T_PCIBUS, 0, NULL, "PCI", "pcifep.bin", DEFAULT_LOC "pcifep.bin", 0 },
106{ICONFIG, 0, 0, 0, NULL, NULL, "dgap.conf", "/etc/dgap.conf", 0 },
107
108
109
110{IBAD, 0, 0, 0, NULL, NULL, NULL, NULL, 0 }
111
112} ;
113
114int errorprint = 1;
115int nodldprint = 1;
116int debugflag;
117int fd;
118
119struct downld_t *ip;
120struct downld_t *dp;
121
122
123
124
125
126
127
128
129void squirt(int req_type, int bdid, struct image_info *ii)
130{
131 struct downldio *dliop;
132 int size_buf;
133 int sfd;
134 struct stat sb;
135
136
137
138
139
140
141
142 if (ii->pathname) {
143 sfd = open(ii->pathname, O_RDONLY);
144
145 if (sfd < 0 ) {
146 myperror(ii->pathname);
147 goto squirt_end;
148 }
149
150 if (fstat(sfd, &sb) == -1 ) {
151 myperror(ii->pathname);
152 goto squirt_end;
153 }
154
155 ii->len = sb.st_size ;
156 }
157
158 size_buf = ii->len + sizeof(struct downldio);
159
160
161
162
163
164
165 dliop = (struct downldio *) malloc(size_buf);
166
167 if (dliop == NULL) {
168 fprintf(stderr,"%s: can't get %d bytes of memory; aborting\n",
169 pgm, size_buf);
170 exit (1);
171 }
172
173
174
175
176 if (ii->pathname)
177 read(sfd, dliop->image.fi.fepimage, ii->len);
178 else
179 memcpy(dliop ->image.fi.fepimage, ii->image, ii->len);
180
181 dliop->req_type = req_type;
182 dliop->bdid = bdid;
183
184 dliop->image.fi.len = ii->len;
185
186 if (debugflag)
187 printf("sending %d bytes of %s %s from %s\n",
188 ii->len,
189 (ii->type == IFEP) ? "FEP" : (ii->type == IBIOS) ? "BIOS" : "CONFIG",
190 ii->name ? ii->name : "",
191 (ii->pathname) ? ii->pathname : "internal image" );
192
193 if (ioctl(fd, DIGI_DLREQ_SET, (char *) dliop) == -1) {
194 if(errorprint) {
195 fprintf(stderr,
196 "%s: warning - download ioctl failed\n",pgm);
197 errorprint = 0;
198 }
199 sleep(2);
200 }
201
202squirt_end:
203
204 if (ii->pathname) {
205 close(sfd);
206 }
207 free(dliop);
208}
209
210
211
212
213
214
215void consider_file_rescan(struct image_info *ii)
216{
217 int sfd ;
218 int len ;
219 struct stat sb;
220
221
222
223 if (ii->pathname) {
224
225 sfd = open (ii->pathname, O_RDONLY) ;
226 if (sfd < 0 ) {
227 myperror(ii->pathname);
228 exit(1) ;
229 }
230
231 if( fstat(sfd,&sb) == -1 ) {
232 myperror(ii->pathname);
233 exit(1);
234 }
235
236
237
238
239 if (ii->image && (sb.st_mtime == ii->mtime))
240 goto end_rescan;
241
242 ii->len = len = sb.st_size ;
243
244
245 ii->mtime = sb.st_mtime;
246
247
248
249
250
251 if ( ii->image ) {
252 free( ii->image );
253
254 }
255
256
257
258
259
260 ii->image = malloc(len) ;
261
262 if (ii->image == NULL) {
263 fprintf(stderr,
264 "%s: can't get %d bytes of memory; aborting\n",
265 pgm, len);
266 exit (1);
267 }
268
269 if (read(sfd, ii->image, len) < len) {
270 fprintf(stderr,"%s: read error on %s; aborting\n",
271 pgm, ii->pathname);
272 exit (1);
273 }
274
275end_rescan:
276 close(sfd);
277
278 }
279}
280
281
282
283
284
285struct image_info * find_conc_image()
286{
287 int x ;
288 struct image_info *i = NULL ;
289
290 for ( x = 0; x < nimages; x++ ) {
291 i=&image_list[x];
292
293 if(i->type != ICONC)
294 continue;
295
296 consider_file_rescan(i) ;
297
298 ip = (struct downld_t *) image_list[x].image;
299 if (ip == NULL) continue;
300
301
302
303
304
305
306 if ((dp->dl_type != 'P' ) && ( ip->dl_srev == dp->dl_srev ))
307 return i;
308 }
309 return NULL ;
310}
311
312
313int main(int argc, char **argv)
314{
315 struct downldio dlio;
316 int offset, bsize;
317 int x;
318 char *down, *image, *fname;
319 struct image_info *ii;
320
321 pgm = argv[0];
322 dp = &dlio.image.dl;
323
324 while((argc > 2) && !strcmp(argv[1],"-d")) {
325 debugflag++ ;
326 argc-- ;
327 argv++ ;
328 }
329
330 if(argc < 2) {
331 fprintf(stderr,
332 "usage: %s download-device [image-file] ...\n",
333 pgm);
334 exit(1);
335 }
336
337
338
339
340
341
342 if (debugflag == 0) {
343 switch (fork())
344 {
345 case 0:
346 break;
347
348 case -1:
349 return 1;
350
351 default:
352 return 0;
353 }
354
355 setsid();
356
357
358
359
360
361 fclose(stdin);
362 fclose(stdout);
363 fclose(stderr);
364
365 }
366
367 while (1) {
368 if( (fd = open(argv[1], O_RDWR)) == -1 ) {
369 sleep(1);
370 }
371 else
372 break;
373 }
374
375
376
377
378
379
380
381
382
383
384 nimages = argc - 2;
385
386
387
388 for (count = 0; images[count].type != IBAD; ++count) ;
389
390 nimages += count;
391
392
393 image_list = images ;
394
395
396 for(x = 2; x < argc; x++) {
397 int xx;
398
399
400
401
402
403 if( (fname = strrchr(argv[x],'/')) == NULL)
404 fname = argv[x];
405 else
406 fname++;
407
408 for (xx = 0; xx < count; xx++) {
409 if (strcmp(fname, images[xx].fname) == 0 ) {
410 images[xx].pathname = argv[x];
411
412
413
414 images[xx].image = NULL ;
415 }
416 }
417 }
418
419 sleep(3);
420
421
422
423
424 for(;;) {
425
426 if (debugflag)
427 printf("b4 get ioctl...");
428
429 if (ioctl(fd,DIGI_DLREQ_GET, &dlio) == -1 ) {
430 if (errorprint) {
431 fprintf(stderr,
432 "%s: warning - download ioctl failed\n",
433 pgm);
434 errorprint = 0;
435 }
436 sleep(2);
437 } else {
438 if (debugflag)
439 printf("dlio.req_type is %d bd %d\n",
440 dlio.req_type,dlio.bdid);
441
442 switch(dlio.req_type) {
443 case DLREQ_BIOS:
444
445
446
447 for ( x = 0; x < nimages; x++ ) {
448 if(image_list[x].type != IBIOS)
449 continue;
450
451 if ((dlio.image.fi.type & FAMILY) ==
452 image_list[x].family) {
453
454 if ( image_list[x].family == T_CX ) {
455 if ((dlio.image.fi.type & BUSTYPE)
456 == T_PCIBUS ) {
457 if ( image_list[x].subtype
458 == T_PCIBUS )
459 break;
460 }
461 else {
462 break;
463 }
464 }
465 else if ( image_list[x].family == T_EPC ) {
466
467
468
469 if ((dlio.image.fi.type & BUSTYPE)
470 == T_PCIBUS ) {
471 if ( image_list[x].subtype
472 == T_PCIBUS )
473 break;
474 }
475 else {
476
477 if ( image_list[x].subtype
478 != T_PCIBUS )
479 break;
480 }
481 }
482 else
483 break;
484 }
485 else if ((dlio.image.fi.type & SUBTYPE) == image_list[x].subtype) {
486
487 if ( image_list[x].subtype == T_PCXR ) {
488 break;
489 }
490 }
491 }
492
493 if ( x >= nimages) {
494
495
496
497 if(nodldprint) {
498 fprintf(stderr,
499 "%s: cannot find correct BIOS image\n",
500 pgm);
501 nodldprint = 0;
502 }
503 dlio.image.fi.type = -1;
504 if (ioctl(fd, DIGI_DLREQ_SET, &dlio) == -1) {
505 if (errorprint) {
506 fprintf(stderr,
507 "%s: warning - download ioctl failed\n",
508 pgm);
509 errorprint = 0;
510 }
511 sleep(2);
512 }
513 break;
514 }
515 squirt(dlio.req_type, dlio.bdid, &image_list[x]);
516 break ;
517
518 case DLREQ_FEP:
519
520
521
522 for ( x = 0; x < nimages; x++ ) {
523 if(image_list[x].type != IFEP)
524 continue;
525 if( (dlio.image.fi.type & FAMILY) ==
526 image_list[x].family ) {
527 if ( image_list[x].family == T_CX ) {
528
529 if ((dlio.image.fi.type & BUSTYPE)
530 == T_PCIBUS ) {
531 if ( image_list[x].subtype
532 == T_PCIBUS )
533 break;
534 }
535 else {
536
537 break;
538 }
539 }
540 else if ( image_list[x].family == T_EPC ) {
541
542
543
544 if ((dlio.image.fi.type & BUSTYPE)
545 == T_PCIBUS ) {
546 if ( image_list[x].subtype
547 == T_PCIBUS )
548 break;
549 }
550 else {
551
552 if ( image_list[x].subtype
553 != T_PCIBUS )
554 break;
555 }
556 }
557 else
558 break;
559 }
560 else if ((dlio.image.fi.type & SUBTYPE) == image_list[x].subtype) {
561
562 if ( image_list[x].subtype == T_PCXR ) {
563 break;
564 }
565 }
566 }
567
568 if ( x >= nimages) {
569
570
571
572 if(nodldprint) {
573 fprintf(stderr,
574 "%s: cannot find correct FEP image\n",
575 pgm);
576 nodldprint = 0;
577 }
578 dlio.image.fi.type=-1;
579 if( ioctl(fd,DIGI_DLREQ_SET,&dlio) == -1 ) {
580 if(errorprint) {
581 fprintf(stderr,
582 "%s: warning - download ioctl failed\n",
583 pgm);
584 errorprint=0;
585 }
586 sleep(2);
587 }
588 break;
589 }
590 squirt(dlio.req_type, dlio.bdid, &image_list[x]);
591 break;
592
593 case DLREQ_DEVCREATE:
594 {
595 char string[1024];
596#if 0
597 sprintf(string, "%s /proc/dgap/%d/mknod", DEFSHELL, dlio.bdid);
598#endif
599 sprintf(string, "%s /usr/sbin/dgap_updatedevs %d", DEFSHELL, dlio.bdid);
600 system(string);
601
602 if (debugflag)
603 printf("Created Devices.\n");
604 if (ioctl(fd, DIGI_DLREQ_SET, &dlio) == -1 ) {
605 if(errorprint) {
606 fprintf(stderr, "%s: warning - DEVCREATE ioctl failed\n",pgm);
607 errorprint = 0;
608 }
609 sleep(2);
610 }
611 if (debugflag)
612 printf("After ioctl set - Created Device.\n");
613 }
614
615 break;
616
617 case DLREQ_CONFIG:
618 for ( x = 0; x < nimages; x++ ) {
619 if(image_list[x].type != ICONFIG)
620 continue;
621 else
622 break;
623 }
624
625 if ( x >= nimages) {
626
627
628
629 if(nodldprint) {
630 fprintf(stderr,
631 "%s: cannot find correct CONFIG image\n",
632 pgm);
633 nodldprint = 0;
634 }
635 dlio.image.fi.type=-1;
636 if (ioctl(fd, DIGI_DLREQ_SET, &dlio) == -1 ) {
637 if(errorprint) {
638 fprintf(stderr,
639 "%s: warning - download ioctl failed\n",
640 pgm);
641 errorprint=0;
642 }
643 sleep(2);
644 }
645 break;
646 }
647
648 squirt(dlio.req_type, dlio.bdid, &image_list[x]);
649 break;
650
651 case DLREQ_CONC:
652
653
654
655 if ( dp->dl_seq == 0 ) {
656
657
658
659 for ( x = 0; x < nimages; x++ ) {
660 ii=&image_list[x];
661
662 if(image_list[x].type != ICONC)
663 continue;
664
665 consider_file_rescan(ii) ;
666
667 ip = (struct downld_t *) image_list[x].image;
668 if (ip == NULL) continue;
669
670
671
672
673
674
675
676 if ((dp->dl_type != 'P' ) &&
677 (ip->dl_lrev <= dp->dl_lrev ) &&
678 ( dp->dl_lrev <= ip->dl_hrev))
679 break;
680 }
681
682 if ( x >= nimages ) {
683
684
685
686 if(nodldprint) {
687 fprintf(stderr,
688 "%s: cannot find correct download image %d\n",
689 pgm, dp->dl_lrev);
690 nodldprint=0;
691 }
692 continue;
693 }
694
695 } else {
696
697
698
699 if ((ii = find_conc_image()) == NULL ) {
700
701
702
703 fprintf(stderr,
704 "%s: can't find rest of download image??\n",
705 pgm);
706 continue;
707 }
708 }
709
710
711
712
713
714 offset = 1024 * dp->dl_seq;
715
716
717
718
719 if ( offset < ii->len ) {
720
721
722
723
724
725 if (( bsize = ii->len - offset ) > 1024 )
726 bsize = 1024;
727
728
729
730
731 dp->dl_srev = ip->dl_srev;
732 dp->dl_lrev = ip->dl_lrev;
733 dp->dl_hrev = ip->dl_hrev;
734
735 dp->dl_seg = (64 * dp->dl_seq) + ip->dl_seg;
736 dp->dl_size = bsize;
737
738 down = (char *)&dp->dl_data[0];
739 image = (char *)((char *)ip + offset);
740
741 memcpy(down, image, bsize);
742 }
743 else {
744
745
746
747
748 dp->dl_seg = ip->dl_seg;
749 dp->dl_size = 0;
750
751
752
753
754
755 if (ii->pathname)
756 if (ii->image) {
757 free(ii->image);
758 ii->image = NULL ;
759 }
760 }
761
762 if (debugflag)
763 printf(
764 "sending conc dl section %d to %s from %s\n",
765 dp->dl_seq, ii->name,
766 ii->pathname ? ii->pathname : "Internal Image");
767
768 if (ioctl(fd, DIGI_DLREQ_SET, &dlio) == -1 ) {
769 if (errorprint) {
770 fprintf(stderr,
771 "%s: warning - download ioctl failed\n",
772 pgm);
773 errorprint=0;
774 }
775 sleep(2);
776 }
777 break;
778 }
779 }
780 if (debugflag > 1) {
781 printf("pausing: "); fflush(stdout);
782 fflush(stdin);
783 while(getchar() != '\n');
784 printf("continuing\n");
785 }
786 }
787}
788
789
790
791
792
793
794
795void myperror(char *s)
796{
797 fprintf(stderr,"%s: %s: %s.\n",pgm, s, strerror(errno));
798}
799