xref: /csrg-svn/old/dlmpcc/dlmpcc.c (revision 35523)
1*35523Sbostic /*
2*35523Sbostic  * Copyright (c) 1988 The Regents of the University of California.
3*35523Sbostic  * All rights reserved.
4*35523Sbostic  *
5*35523Sbostic  * This code is derived from software contributed to Berkeley by
6*35523Sbostic  * Computer Consoles Inc.
7*35523Sbostic  *
8*35523Sbostic  * Redistribution and use in source and binary forms are permitted
9*35523Sbostic  * provided that the above copyright notice and this paragraph are
10*35523Sbostic  * duplicated in all such forms and that any documentation,
11*35523Sbostic  * advertising materials, and other materials related to such
12*35523Sbostic  * distribution and use acknowledge that the software was developed
13*35523Sbostic  * by the University of California, Berkeley.  The name of the
14*35523Sbostic  * University may not be used to endorse or promote products derived
15*35523Sbostic  * from this software without specific prior written permission.
16*35523Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17*35523Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18*35523Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19*35523Sbostic  */
20*35523Sbostic 
2132618Ssam #ifndef lint
22*35523Sbostic char copyright[] =
23*35523Sbostic "@(#) Copyright (c) 1988 The Regents of the University of California.\n\
24*35523Sbostic  All rights reserved.\n";
25*35523Sbostic #endif /* not lint */
2632618Ssam 
27*35523Sbostic #ifndef lint
28*35523Sbostic static char sccsid[] = "@(#)dlmpcc.c	5.2 (Berkeley) 09/18/88";
29*35523Sbostic #endif /* not lint */
30*35523Sbostic 
3132618Ssam /*
3232618Ssam  * MPCC Download and Configuration Program.
3332618Ssam  */
3432618Ssam #include <stdio.h>
3532618Ssam #include <ctype.h>
3632618Ssam #include <fcntl.h>
3732618Ssam #include <sys/ioctl.h>
3832618Ssam #include <errno.h>
3932618Ssam 
4032618Ssam #include <sys/types.h>
4132618Ssam #include <tahoevba/mpreg.h>
4232618Ssam #include <stdio.h>
4332618Ssam 
4432618Ssam #include "scnhdr.h"
4532618Ssam 
4632618Ssam #define MAXMPCC 16
4732618Ssam 
4832618Ssam char	*MPCCTAB = "/etc/mpcctab";
4932618Ssam int	resetflg = 0;
5032618Ssam 
5132618Ssam main(argc, argv)
5232618Ssam 	char *argv[];
5332618Ssam {
5432618Ssam 	int bd;
5532618Ssam 
5632618Ssam 	if (argc == 1) {
5732618Ssam 		for (bd = 0; bd < MAXMPCC; bd++)
5832618Ssam 			if (bldmap(bd) != -1)
5932618Ssam 				download(bd);
6032618Ssam 		exit(0);
6132618Ssam 	}
6232618Ssam 	for (argc--, argv++; argc > 0; argc--, argv++) {
6332618Ssam 		bd = atoi(argv[0]);
6432618Ssam 		if (strcmp(argv[0], "-r") == 0) {
6532618Ssam 			resetflg = 1;
6632618Ssam 			continue;
6732618Ssam 		}
6832618Ssam 		if (bd > MAXMPCC || bd < 0) {
6932618Ssam 			printf("Illegal Board Number=> %d\n", bd);
7032618Ssam 			continue;
7132618Ssam 		}
7232618Ssam 		if (bldmap(bd) == -1)
7332618Ssam 			continue;
7432618Ssam 		download(bd);
7532618Ssam 	}
7632618Ssam 	exit(0);
7732618Ssam }
7832618Ssam 
7932618Ssam /*
8032618Ssam  * Build Load Module Map
8132618Ssam  */
8232618Ssam struct  bdcf cf;
8332618Ssam struct	abdcf bdasy;
8432618Ssam 
8532618Ssam #define LINESIZE 128
8632618Ssam 
8732618Ssam bldmap(dlbd)
8832618Ssam 	int dlbd;		/* board to be downloaded */
8932618Ssam {
9032618Ssam 	FILE *tabfp;
9132618Ssam 	int bd, port, count;
9232618Ssam 	char *bdstr, *strtok(), protocol, line[LINESIZE];
9332618Ssam 	char *lptr, *lptr1, *lptr2;
9432618Ssam 
9532618Ssam 	protocol = '\0';
9632618Ssam 	/* open the configuration file for reading */
9732618Ssam 	if ((tabfp = fopen(MPCCTAB, "r")) == NULL) {
9832618Ssam 		printf("No Configuration File: %s\n", MPCCTAB);
9932618Ssam 		return (-1);
10032618Ssam 	}
10132618Ssam 	for (;;) {
10232618Ssam 		if (fgets(&line[0], LINESIZE-1, tabfp) == NULL) {
10332618Ssam 			fclose(tabfp);
10432618Ssam 			return (-1);
10532618Ssam 		}
10632618Ssam 		count++;
10732618Ssam 		line[strlen(line)-1] = '\0';
10832618Ssam 		lptr = strtok(line, ':');
10932618Ssam 		if (tolower(*lptr) != 'm')
11032618Ssam 			continue;
11132618Ssam 		lptr = strtok((char *)0, ':');
11232618Ssam 		bd = atoi(lptr);
11332618Ssam 		if (bd == dlbd)
11432618Ssam 			break;
11532618Ssam 	}
11632618Ssam 	cf.fccstimer = 20;      /* default to 1 sec (20 * 50ms) */
11732618Ssam 	cf.fccsports = 0;       /* no ports are fccs */
11832618Ssam 	cf.fccssoc = 0;         /* no ports switch on close */
11932618Ssam 	for (port = 0; port < MPMAXPORT; port++)
12032618Ssam 		cf.protoports[port] = MPPROTO_UNUSED;
12132618Ssam 	/* check for the keywords following the board number */
12232618Ssam 	lptr1 = (char *)0;
12332618Ssam 	lptr2 = (char *)0;
12432618Ssam 	while (*lptr) {
12532618Ssam 		lptr = strtok((char *)0, ':');
12632618Ssam 		if (!strncmp(lptr, "FCCS", 4)) {
12732618Ssam 			lptr1 = lptr;
12832618Ssam 			continue;
12932618Ssam 		}
13032618Ssam 		if (!strncmp(lptr, "SOC", 3)) {
13132618Ssam 			lptr2 = lptr;
13232618Ssam 			continue;
13332618Ssam 		}
13432618Ssam 	}
13532618Ssam 	/* process the board and port characteristics */
13632618Ssam 	while (fgets(&line[0], LINESIZE-1, tabfp) != NULL) {
13732618Ssam 		count++;
13832618Ssam 		line[strlen(line)-1] = '\0';
13932618Ssam 		if (!line[0])		/* if newline only */
14032618Ssam 			continue;
14132618Ssam 		lptr = strtok(line, ':');
14232618Ssam 		if (tolower(*lptr) == 'm')
14332618Ssam 			break;
14432618Ssam 		if (*lptr == '#')	/* ignore comment */
14532618Ssam 			continue;
14632618Ssam 		if (tolower(*lptr) == 'p' && tolower(*(lptr+1)) == 'o') {
14732618Ssam 			/* PORT */
14832618Ssam 			port = atoi(lptr = strtok((char *)0, ':'));
14932618Ssam 			protocol = *(lptr = strtok((char *)0, ':'));
15032618Ssam 			switch (cf.protoports[port] = protocol) {
15132618Ssam 			case '3' :		/* ASYNCH 32 port */
15232618Ssam 			case 'A' :		/* ASYNCH */
15332618Ssam 				break;
15432618Ssam 			case 'B':		/* BISYNCH */
15532618Ssam 				break;
15632618Ssam 			case 'S':		/* SDLC */
15732618Ssam 				snapargs(port, lptr);
15832618Ssam 				break;
15932618Ssam 			case 'X':		/* X25 */
16032618Ssam 				x25pargs(port, lptr);
16132618Ssam 				break;
16232618Ssam 			default:
16332618Ssam 				printf(
16432618Ssam "No protocol specified on PROTOCOL line in configuration file %s:%d: %s\n",
16532618Ssam 				    MPCCTAB, count, line);
16632618Ssam 				protocol = 'A';
16732618Ssam 				break;
16832618Ssam 			}
16932618Ssam 			continue;
17032618Ssam 		}
17132618Ssam 		if (tolower(*lptr) == 'p' && tolower(*(lptr+1)) == 'r') {
17232618Ssam 			/* PROTOCOL */
17332618Ssam #ifdef notdef
17432618Ssam 			if(protocol) {
17532618Ssam 				printf(
17632618Ssam "second protocol specified on PROTOCOL line in configuration file %s:%d: %s\n",
17732618Ssam 				    MPCCTAB, count, line);
17832618Ssam 				continue;
17932618Ssam 			}
18032618Ssam #endif
18132618Ssam 			lptr = strtok((char *) 0, ':');
18232618Ssam 			switch (protocol = *lptr) {
18332618Ssam 			case '3':		/* ASYNCH 32 port */
18432618Ssam 			case 'A':		/* ASYNCH */
18532618Ssam 				asybargs(lptr);
18632618Ssam 				break;
18732618Ssam 			case 'B':		/* BISYNCH */
18832618Ssam 				break;
18932618Ssam 			case 'S':		/* SDLC */
19032618Ssam 				snabargs(lptr);
19132618Ssam 				break;
19232618Ssam 			case 'X':		/* X25 */
19332618Ssam 				x25bargs(lptr);
19432618Ssam 				break;
19532618Ssam 			default:
19632618Ssam 				printf(
19732618Ssam "No protocol specified on PROTOCOL line in configuration file %s:%d: %s\n",
19832618Ssam 				    MPCCTAB, count, line);
19932618Ssam 				protocol = 'A';
20032618Ssam 				break;
20132618Ssam 			}
20232618Ssam 			continue;
20332618Ssam 		}
20432618Ssam 		printf("Error in configuration file %s,line %d, %s\n",
20532618Ssam 		    MPCCTAB, count, line);
20632618Ssam 	}
20732618Ssam 	fclose(tabfp);
20832618Ssam 	mkldnm();
20932618Ssam 	return (0);
21032618Ssam }
21132618Ssam 
21232618Ssam /*
21332618Ssam  * decode x25 arguments for board
21432618Ssam  *
21532618Ssam  * for X.25, the arguments are N1, N2, T1, T2, T3, T4, K).
21632618Ssam  */
21732618Ssam x25bargs(args)
21832618Ssam 	char *args;
21932618Ssam {
22032618Ssam }
22132618Ssam 
22232618Ssam /*
22332618Ssam  * decode sna arguments for board
22432618Ssam  * for SNA, the arguments are N1, N2, T1, T2, T3, T4, K).
22532618Ssam  */
22632618Ssam snabargs(args)
22732618Ssam 	char *args;
22832618Ssam {
22932618Ssam }
23032618Ssam 
23132618Ssam /*
23232618Ssam  * decode async arguments for board
23332618Ssam  */
23432618Ssam asybargs(args)
23532618Ssam char *args;
23632618Ssam {
23732618Ssam 
23832618Ssam 	bdasy.xmtbsz = atoi(strtok((char *)0, ':'));
23932618Ssam }
24032618Ssam 
24132618Ssam /*
24232618Ssam  * decode x25 arguments for port
24332618Ssam  */
24432618Ssam x25pargs(port,args)
24532618Ssam 	int port;
24632618Ssam 	char *args;
24732618Ssam {
24832618Ssam }
24932618Ssam 
25032618Ssam /*
25132618Ssam  * decode sna arguments for port
25232618Ssam  */
25332618Ssam snapargs(port, args)
25432618Ssam 	int port;
25532618Ssam 	char *args;
25632618Ssam {
25732618Ssam }
25832618Ssam 
25932618Ssam gethi()
26032618Ssam {
26132618Ssam 	int i;
26232618Ssam 
26332618Ssam 	for (i = MPMAXPORT-1; i >= 0 && cf.protoports[i] == 0; i--)
26432618Ssam 		;
26532618Ssam 	return (i);
26632618Ssam }
26732618Ssam 
26832618Ssam getlo()
26932618Ssam {
27032618Ssam 	int i;
27132618Ssam 
27232618Ssam 	for (i = 0; i < MPMAXPORT && cf.protoports[i] == 0; i++)
27332618Ssam 		;
27432618Ssam 	return (i);
27532618Ssam }
27632618Ssam 
27732618Ssam prntmap(board)
27832618Ssam 	int board;
27932618Ssam {
28032618Ssam 	int j;
28132618Ssam 
28232618Ssam 	printf("\nMPCC #: %d\n", board);
28332618Ssam 	for (j = 0; j < MPMAXPORT; j++) {
28432618Ssam 		printf("port: %d  %c", j, cf.protoports[j]);
28532618Ssam 		switch (cf.protoports[j]) {
28632618Ssam 		case '3': case 'A':
28732618Ssam 			printf("\n");
28832618Ssam 			break;
28932618Ssam 		case 'B':
29032618Ssam 			break;
29132618Ssam 		case 'S':
29232618Ssam 			break;
29332618Ssam 		case 'X':
29432618Ssam 			break;
29532618Ssam 		default:
29632618Ssam 			printf("Unused\n");
29732618Ssam 			break;
29832618Ssam 		}
29932618Ssam 	}
30032618Ssam 	printf("ldname: %s, ", cf.loadname);
30132618Ssam 	printf("hiport: %d, loport: %d\n", gethi(), getlo());
30232618Ssam 	if (cf.fccsports != 0)
30332618Ssam 		printf("FCCS\n");
30432618Ssam 	switch (cf.protoports[0]) {
30532618Ssam 	case '3': case 'A':
30632618Ssam 		printf("xmtsize: %d\n", bdasy.xmtbsz);
30732618Ssam 		break;
30832618Ssam 	case 'B':
30932618Ssam 		break;
31032618Ssam 	case 'S':
31132618Ssam 		break;
31232618Ssam 	case 'X':
31332618Ssam 		break;
31432618Ssam 	}
31532618Ssam 	printf("protoports: %s\n", cf.protoports);
31632618Ssam }
31732618Ssam 
31832618Ssam /*
31932618Ssam  * Make Load Module Name
32032618Ssam  *
32132618Ssam  * if any port is 'ASYNCH"
32232618Ssam  * 	add 'a' to load module name
32332618Ssam  * if any port is 'BISYNCH'
32432618Ssam  * 	add 'b' to load module name
32532618Ssam  * if any port is 'SDLC'
32632618Ssam  * 	add 's' to load module name
32732618Ssam  * if any port is 'X25'
32832618Ssam  * 	add 'x' to load module name
32932618Ssam  */
33032618Ssam mkldnm()
33132618Ssam {
33232618Ssam 	static char *pcols = "ABSX3";
33332618Ssam 	char *proto;
33432618Ssam 	int j, offset;
33532618Ssam 
33632618Ssam 	offset = 0;
33732618Ssam 	for (proto = pcols; *proto; proto++) {
33832618Ssam 		for (j = 0; j < MPMAXPORT; j++) {
33932618Ssam 			if (cf.protoports[j] == *proto) {
34032618Ssam 				if (*proto == '3')
34132618Ssam 					cf.loadname[offset] = '3';
34232618Ssam 				else
34332618Ssam 					cf.loadname[offset] = tolower(*proto);
34432618Ssam 				offset++;
34532618Ssam 				break;
34632618Ssam 			}
34732618Ssam 		}
34832618Ssam 		cf.loadname[offset] = '\0';
34932618Ssam 	}
35032618Ssam }
35132618Ssam 
35232618Ssam /*
35332618Ssam  * if a string is passed as an argument,
35432618Ssam  * 	save it in the local string area
35532618Ssam  * 	set the local index to the start of the string
35632618Ssam  * else
35732618Ssam  * 	set start to the current character in the string
35832618Ssam  * 	while the character is not the separator,
35932618Ssam  * 		and the character is not NULL
36032618Ssam  * 			skip the character
36132618Ssam  */
36232618Ssam static
36332618Ssam char *
36432618Ssam strtok(s, c)
36532618Ssam 	char *s, c;
36632618Ssam {
36732618Ssam 	static char locals[LINESIZE];
36832618Ssam 	static int i;
36932618Ssam 	char *start;
37032618Ssam 
37132618Ssam 	if (s != 0) {
37232618Ssam 		strcpy(locals, s);
37332618Ssam 		i = 0;
37432618Ssam 	}
37532618Ssam 	for (start = &locals[i] ; locals[i] && locals[i] != c; i++)
37632618Ssam 		;
37732618Ssam 	if (locals[i]) {
37832618Ssam 		locals[i] = '\0';
37932618Ssam 		i++;
38032618Ssam 	}
38132618Ssam 	while (*start == ' ')
38232618Ssam 		start++;
38332618Ssam 	return (start);
38432618Ssam }
38532618Ssam 
38632618Ssam short	bits[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
38732618Ssam fccs(line, tptr, pptr)
38832618Ssam 	char *line, *tptr, *pptr;
38932618Ssam {
39032618Ssam 	u_short ports, num, time;
39132618Ssam 
39232618Ssam 	ports = 0;
39332618Ssam 	line = strtok(line, ',');
39432618Ssam 	while (*(line = strtok((char *) 0, ',')) != '\0') {
39532618Ssam 		num = (short) atoi(line);
39632618Ssam 		if (num >= 0 && num < 8)
39732618Ssam 			ports |= bits[num];
39832618Ssam 		else if (num >= 50 && num < 6400)
39932618Ssam 			time = num / 50;
40032618Ssam 		else
40132618Ssam 			printf("bad value for FCCS: %d\n", num);
40232618Ssam 	}
40332618Ssam 	*pptr = ports;
40432618Ssam 	*tptr = time;
40532618Ssam }
40632618Ssam 
40732618Ssam soc(line, sptr)
40832618Ssam 	char *line, *sptr;
40932618Ssam {
41032618Ssam 	u_short ports, num;
41132618Ssam 
41232618Ssam 	ports = 0;
41332618Ssam 	line = strtok(line, ',');
41432618Ssam 	while (*(line = strtok((char *) 0, ',')) != '\0') {
41532618Ssam 		num = atoi(line);
41632618Ssam 		if (num >= 0 && num < 8)
41732618Ssam 			ports |= bits[num];
41832618Ssam 		else
41932618Ssam 			printf("bad value for SOC: %d\n",num);
42032618Ssam 	}
42132618Ssam 	*sptr = ports;
42232618Ssam }
42332618Ssam 
42432618Ssam char	buffer[MPDLBUFSIZE];
42532618Ssam extern	int errno;
42632618Ssam struct head1 {
42732618Ssam 	long	magic;
42832618Ssam 	long	fill[12];
42932618Ssam 	struct	scnhdr text;
43032618Ssam 	struct	scnhdr data;
43132618Ssam 	struct	scnhdr bss;
43232618Ssam } header1;
43332618Ssam 
43432618Ssam download(mpccnum)
43532618Ssam 	int mpccnum;
43632618Ssam {
43732618Ssam 	char dlname[LINESIZE], fullname[LINESIZE];
43832618Ssam 	char *ldname, *ppmap;
43932618Ssam 	int dlfd, ldfd;
44032618Ssam 	char *it;
44132618Ssam 	short i;
44232618Ssam 	char hilo[2];
44332618Ssam 	long realsize;
44432618Ssam 
44532618Ssam 	sprintf(dlname, "/dev/mpcc%d", mpccnum);
44632618Ssam 	if (*cf.loadname == '3')
44732618Ssam 		sprintf(fullname, "/etc/mpcc32");
44832618Ssam 	else
44932618Ssam 		sprintf(fullname, "/etc/mpcc%s", cf.loadname);
45032618Ssam 	if ((cf.loadname[0]) == '\0')
45132618Ssam 		return (-1);
45232618Ssam 	if ((dlfd = open(dlname, O_RDWR)) == MP_DLERROR) {
45332618Ssam 		printf("Can not open %s\n",dlname);
45432618Ssam 		return (-1);
45532618Ssam 	}
45632618Ssam 	if ((ldfd = open(fullname, O_RDONLY)) == MP_DLERROR) {
45732618Ssam 		close(dlfd);
45832618Ssam 		printf("Can not access protocol code file: %s\n", fullname);
45932618Ssam 		return (-1);
46032618Ssam 	}
46132618Ssam 	if (dlokay(dlfd,mpccnum) == MP_DLERROR) {
46232618Ssam 		close(ldfd);
46332618Ssam 		close(dlfd);
46432618Ssam 		return (-1);
46532618Ssam 	}
46632618Ssam 	printf("Downloading MPCC #%x\n", mpccnum);
46732618Ssam 	/* read executable file header */
46832618Ssam 	if (read(ldfd, &header1, sizeof(header1)) != sizeof(header1)) {
46932618Ssam 		printf("Can not read %s\n", fullname);
47032618Ssam 		return (-1);
47132618Ssam 	}
47232618Ssam 	/* place at start of text space */
47332618Ssam 	if (lseek(ldfd, header1.text.s_scnptr , (int) 0) == -1) {
47432618Ssam 		printf("lseek error(text): %d", errno);
47532618Ssam 		return (-1);
47632618Ssam 	}
47732618Ssam 	/* send text */
47832618Ssam 	realsize = header1.data.s_paddr - header1.text.s_paddr;
47932618Ssam 	if (dl(ldfd, dlfd, realsize) == -1) {
48032618Ssam 		ioctl(dlfd, MPIORESETBOARD, 0L);
48132618Ssam 		return (-1);
48232618Ssam 	}
48332618Ssam 	/* place at start of data space	*/
48432618Ssam 	if (lseek(ldfd, header1.data.s_scnptr , (int) 0) == -1) {
48532618Ssam 		printf("lseek error(data): %d", errno);
48632618Ssam 		return (-1);
48732618Ssam 	}
48832618Ssam 	/* send initialized data */
48932618Ssam 	realsize = header1.bss.s_paddr - header1.data.s_paddr;
49032618Ssam 	if (dl(ldfd, dlfd, realsize) == -1) {
49132618Ssam 		ioctl(dlfd, MPIORESETBOARD, 0L);
49232618Ssam 		return (-1);
49332618Ssam 	}
49432618Ssam 	/* signal end of code */
49532618Ssam 	if (ioctl(dlfd, MPIOENDCODE, (char *) 0) == MP_DLERROR) {
49632618Ssam 		printf("MPIOENDCODE ioctl failed\n");
49732618Ssam 		ioctl(dlfd, MPIORESETBOARD, 0L);
49832618Ssam 		return (-1);
49932618Ssam 	}
50032618Ssam 	/* download configuration information	*/
50132618Ssam 	if (config(dlfd) == -1) {
50232618Ssam 		ioctl(dlfd, MPIORESETBOARD, 0L);
50332618Ssam 		return (-1);
50432618Ssam 	}
50532618Ssam 	/* write port/protocol map */
50632618Ssam 	ppmap = (char *)&cf.protoports[0];
50732618Ssam 	tknzmap(ppmap);
50832618Ssam 	if (ioctl(dlfd, MPIOPORTMAP, ppmap) == MP_DLERROR) {
50932618Ssam 		printf("MPIOPORTMAP ioctl failed\n");
51032618Ssam 		ioctl(dlfd, MPIORESETBOARD, 0L);
51132618Ssam 		return (-1);
51232618Ssam 	}
51332618Ssam 	/* signal end of download */
51432618Ssam 	if (ioctl(dlfd, MPIOENDDL, (char *) 0) == MP_DLERROR) {
51532618Ssam 		printf("MPIOENDDL ioctl failed\n");
51632618Ssam 		ioctl(dlfd, MPIORESETBOARD, 0L);
51732618Ssam 		return (-1);
51832618Ssam 	}
51932618Ssam 	close(dlfd);
52032618Ssam 	close(ldfd);
52132618Ssam 	printf("Download Complete and Successful\n");
52232618Ssam 	return (0);
52332618Ssam }
52432618Ssam 
52532618Ssam dlokay(bdfd, mpccnum)
52632618Ssam 	int bdfd, mpccnum;
52732618Ssam {
52832618Ssam 	char answer;
52932618Ssam 
53032618Ssam 	if (resetflg) {
53132618Ssam 		printf("Reseting MPCC #%x\n",mpccnum);
53232618Ssam 		ioctl(bdfd, MPIORESETBOARD, 0L);
53332618Ssam 		sleep(10);
53432618Ssam 	}
53532618Ssam 	if (ioctl(bdfd, MPIOSTARTDL, 0) == MP_DLERROR) {
53632618Ssam 		if (errno == EBUSY) {
53732618Ssam 			printf("MPCC #%x has already been downloaded.\n",
53832618Ssam 			    mpccnum);
53932618Ssam 			printf("Do you want to re-download it?: ");
54032618Ssam 			fscanf(stdin,"%c",&answer);
54132618Ssam 			while (getchar() != '\n')
54232618Ssam 				;
54332618Ssam 			if ((answer | 0x60) != 'y')
54432618Ssam 				return (MP_DLERROR);
54532618Ssam 			ioctl(bdfd, MPIORESETBOARD, 0L);
54632618Ssam 			sleep(10);
54732618Ssam 			if (ioctl(bdfd, MPIOSTARTDL, (char *) 0) == MP_DLERROR) {
54832618Ssam 				printf("Can't download MPCC #%x\n", mpccnum);
54932618Ssam 				return (MP_DLERROR);
55032618Ssam 			}
55132618Ssam 		} else {
55232618Ssam 			switch (errno) {
55332618Ssam 			case ENODEV:
55432618Ssam 				printf("MPCC #%x not in system\n", mpccnum);
55532618Ssam 				break;
55632618Ssam 			case EACCES:
55732618Ssam 				printf("Download area in use, try later\n");
55832618Ssam 				break;
55932618Ssam 			case ENOSPC:
56032618Ssam 				printf("MPCC #%x already being downloaded\n",
56132618Ssam 				    mpccnum);
56232618Ssam 				break;
56332618Ssam 			default:
56432618Ssam 				printf("Unknown response from MPCC #%x\n",
56532618Ssam 				    mpccnum);
56632618Ssam 				break;
56732618Ssam 			}
56832618Ssam 			return (MP_DLERROR);
56932618Ssam 		}
57032618Ssam 	}
57132618Ssam 	return (0);
57232618Ssam }
57332618Ssam 
57432618Ssam dl(dskfd, bdfd, size)
57532618Ssam 	int dskfd, bdfd;
57632618Ssam 	long size;
57732618Ssam {
57832618Ssam 	int bytes;
57932618Ssam 
58032618Ssam 	while (size > 0) {
58132618Ssam 		bytes = (size < MPDLBUFSIZE) ? (int) size : MPDLBUFSIZE;
58232618Ssam 		if ((bytes = read(dskfd, buffer, bytes)) == MP_DLERROR) {
58332618Ssam 			close(dskfd);
58432618Ssam 			close(bdfd);
58532618Ssam 			printf("Download-Can't read buffer\n");
58632618Ssam 			return (-1);
58732618Ssam 		}
58832618Ssam 		if (write(bdfd, buffer, bytes) == MP_DLERROR) {
58932618Ssam 			close(dskfd);
59032618Ssam 			close(bdfd);
59132618Ssam 			printf("Download-Can't write buffer\n");
59232618Ssam 			return (-1);
59332618Ssam 		}
59432618Ssam 		size -= bytes;
59532618Ssam 	}
59632618Ssam 	return (0);
59732618Ssam }
59832618Ssam 
59932618Ssam /*
60032618Ssam  * download each protocol's configuration data
60132618Ssam  * and the configuration data for tboard.
60232618Ssam  */
60332618Ssam config(dlfd)
60432618Ssam 	int dlfd;
60532618Ssam {
60632618Ssam 	register int i;
60732618Ssam 	char *ldname;
60832618Ssam 
60932618Ssam 	for (ldname = cf.loadname; *ldname; ldname++) {
61032618Ssam 		switch (*ldname) {
61132618Ssam 		case '3': case 'a':
61232618Ssam 			if (ioctl(dlfd, MPIOASYNCNF, &bdasy) == MP_DLERROR) {
61332618Ssam 				printf("async ioctl failed\n");
61432618Ssam 				return (-1);
61532618Ssam 			}
61632618Ssam 			break;
61732618Ssam 		case 'b':
61832618Ssam 			break;
61932618Ssam 		case 'x':
62032618Ssam 			break;
62132618Ssam 
62232618Ssam 		case 's':
62332618Ssam 			break;
62432618Ssam 		}
62532618Ssam 	}
62632618Ssam }
62732618Ssam 
62832618Ssam /*
62932618Ssam  * tokenize the protoport string,
63032618Ssam  * (change from the letter to the corresponding number).
63132618Ssam  */
63232618Ssam tknzmap(map)
63332618Ssam 	char *map;
63432618Ssam {
63532618Ssam 	short i;
63632618Ssam 
63732618Ssam 	for (i = 0; i < MPMAXPORT; i++) {
63832618Ssam 		switch (*map) {
63932618Ssam 		case '3' :	*map = MPPROTO_ASYNC; break;
64032618Ssam 		case 'A' :	*map = MPPROTO_ASYNC; break;
64132618Ssam 		case 'B' :	*map = MPPROTO_BISYNC; break;
64232618Ssam 		case 'S' :	*map = MPPROTO_SNA; break;
64332618Ssam 		case 'X' :	*map = MPPROTO_X25; break;
64432618Ssam 		default:	*map = MPPROTO_UNUSED; break;
64532618Ssam 		}
64632618Ssam 		map++;
64732618Ssam 	}
64832618Ssam }
649