xref: /illumos-gate/usr/src/cmd/scadm/sparc/mpxu/common/send_file.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2002-2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * send_file.c: to support firmware download (get fw S-records from the
31  * user-specified file and send S-records string down to the service processor
32  */
33 
34 #include <libintl.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <time.h>
38 
39 #include "librsc.h"
40 #include "adm.h"
41 
42 
43 int
44 ADM_Send_file(FILE  *FilePtr)
45 {
46 	static char		ADM_Line[ADM_LINE_SIZE];
47 	static bp_msg_t		Message;
48 	static struct timespec	Timeout;
49 	int			LinesWritten;
50 	int			Status;
51 	int			BootRetry;
52 	int			LastRecord;
53 	long			FileLength = 0L;
54 	long			FilePos;
55 
56 
57 	/*
58 	 * Determine the length of the file
59 	 */
60 	if (fseek(FilePtr, 0L, SEEK_END) == 0) {
61 		FileLength = ftell(FilePtr);
62 		rewind(FilePtr);
63 	}
64 
65 	LinesWritten = 0;
66 	LastRecord   = 0;
67 	while ((fgets(ADM_Line, ADM_LINE_SIZE, FilePtr) != NULL) &&
68 	    (LastRecord == 0)) {
69 		if ((ADM_Line[0] == 'S') &&
70 		    ((ADM_Line[1] == '7') || (ADM_Line[1] == '8') ||
71 		    (ADM_Line[1] == '9'))) {
72 			LastRecord = 1;
73 		}
74 
75 		BootRetry = ADM_BOOT_RETRY;
76 		while (BootRetry > 0) {
77 			if ((Status =
78 			    rsc_raw_write(ADM_Line, strlen(ADM_Line))) != 0) {
79 				return (Status);
80 			}
81 
82 			/*
83 			 * Initialize Timeout each time just to be robust.
84 			 * Since this operation is not time critical, this is
85 			 * not a concern.
86 			 */
87 			Timeout.tv_nsec = 0;
88 			Timeout.tv_sec  = ADM_BOOT_LOAD_TIMEOUT;
89 			/* If we timeout, decrement BootRetry and try again */
90 			if ((Status = ADM_Boot_recv(&Message, &Timeout)) != 0) {
91 				/* We got a timeout */
92 				BootRetry = BootRetry - 1;
93 				continue;
94 
95 			} else {
96 
97 				/* we got a message back, see what it is */
98 				if ((Message.cmd  == BP_RSC_BOOTOK) &&
99 				    (Message.dat1 == 0) &&
100 				    (Message.dat2 == 0)) {
101 
102 					LastRecord = 1;
103 					break;
104 				}
105 
106 				if ((Message.cmd  != BP_RSC_BOOTACK) ||
107 				    (Message.dat1 != BP_DAT1_SRECORD_ACK)) {
108 
109 					if (Message.dat1 ==
110 					    BP_DAT1_SRECORD_NAK) {
111 						continue;
112 					}
113 					ADM_Display_download_error(
114 					    (int)Message.cmd,
115 					    (int)Message.dat1);
116 					exit(-1);
117 				}
118 
119 				/*
120 				 * We got a valid acknowledge, break out of
121 				 * loop and start to download next s-record
122 				 */
123 				break;
124 			}
125 		}
126 
127 		/* See if we ever got a response */
128 		if (BootRetry <= 0) {
129 			(void) fprintf(stderr, "\n%s\n\n",
130 			    gettext("scadm: SC failed to respond during "
131 			    "download"));
132 			exit(-1);
133 		}
134 
135 		LinesWritten++;
136 		if ((LinesWritten % 100) == 0) {
137 			(void) printf(".");
138 			(void) fflush(stdout);
139 		}
140 		if ((LinesWritten % 4000) == 0) {
141 			if (FileLength) {
142 				/* Show % progress */
143 				FilePos = ftell(FilePtr);
144 				(void) printf(" (%ld%%)",
145 				    (FilePos * 100) / FileLength);
146 			}
147 			(void) printf("\n");
148 			(void) fflush(stdout);
149 		}
150 	}
151 	if ((FileLength) && ((LinesWritten % 4000) != 0)) {
152 		/* Show final % progress (should normally be 100%) */
153 		FilePos = ftell(FilePtr);
154 		(void) printf(" (%ld%%)",
155 		    (FilePos * 100) / FileLength);
156 	}
157 	(void) printf("\n");
158 
159 	return (0);
160 }
161 
162 
163 void
164 ADM_Display_download_error(int cmd, int dat1)
165 {
166 	if (cmd == BP_RSC_BOOTFAIL) {
167 		if (dat1 == BP_DAT1_REJECTED) {
168 			(void) fprintf(stderr, "\n%s\n\n",
169 			    gettext("scadm: download rejected"));
170 
171 		} else if (dat1 == BP_DAT1_RANGE_ERR) {
172 			(void) fprintf(stderr, "\n%s\n\n",
173 			    gettext("scadm: download failed, "
174 			    "SC reported range error"));
175 
176 		} else if (dat1 == BP_DAT1_VERIFY_ERR) {
177 			(void) fprintf(stderr, "\n%s\n\n",
178 			    gettext("scadm: download failed, "
179 			    "SC reported verify error"));
180 
181 		} else if (dat1 == BP_DAT1_ERASE_ERR) {
182 			(void) fprintf(stderr, "\n%s\n\n",
183 			    gettext("scadm: download failed, "
184 			    "SC reported erase error"));
185 
186 		} else if (dat1 == BP_DAT1_INT_WP_ERR) {
187 			(void) fprintf(stderr, "\n%s\n\n",
188 			    gettext("scadm: download failed, "
189 			    "SC reported int_wp error"));
190 
191 		} else if (dat1 == BP_DAT1_WP_ERR) {
192 			(void) fprintf(stderr, "\n%s\n\n",
193 			    gettext("scadm: download failed, "
194 			    "SC reported wp error"));
195 
196 		} else if (dat1 == BP_DAT1_VPP_ERR) {
197 			(void) fprintf(stderr, "\n%s\n\n",
198 			    gettext("scadm: download failed, "
199 			    "SC reported vpp error"));
200 		} else {
201 			(void) fprintf(stderr, "%s 0x%08x\n",
202 			    gettext("scadm: SC returned fatal error"), dat1);
203 		}
204 	} else if (cmd == BP_RSC_BOOTACK) {
205 		if (dat1 == BP_DAT1_SRECORD_ACK) {
206 			(void) fprintf(stderr, "\n%s\n\n",
207 			    gettext("scadm: download failed"));
208 		} else {
209 			(void) fprintf(stderr, "%s 0x%08x\n",
210 			    gettext("scadm: SC returned fatal error"), dat1);
211 		}
212 	} else {
213 		(void) fprintf(stderr, "%s 0x%08x:0x%08x\n",
214 		    gettext("scadm: SC returned unknown error"), cmd, dat1);
215 	}
216 }
217