4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * download.c: support to the scadm download option (download service
36 #include <time.h> /* required by rsc.h */
43 extern smq_t ADM_bpMsgQueue
;
44 extern smq_msg_t ADM_bpMsgBuffer
[ADM_BP_BUFF_SIZE
];
50 ADM_Process_download(int argc
, char *argv
[])
53 uint8_t DownloadLocation
;
54 static bp_msg_t Message
;
55 static struct timespec Timeout
;
63 if ((argc
!= 3) && (argc
!= 4)) {
69 if (strcasecmp(argv
[2], "boot") != 0) {
74 DownloadLocation
= BP_DAT2_FLASH_BOOT
;
76 } else { /* no [boot] option */
79 DownloadLocation
= BP_DAT2_FLASH_MAIN
;
83 if ((FilePtr
= fopen(Filename
, "r")) == NULL
) {
84 (void) fprintf(stderr
, "\n%s - \"%s\"\n\n",
85 gettext("scadm: file could not be opened"), Filename
);
90 /* Verify file is s-record */
91 if (ADM_Valid_srecord(FilePtr
) != 0) {
92 (void) fprintf(stderr
, "\n%s - \"%s\"\n\n",
93 gettext("scadm: file not a valid s-record"), Filename
);
98 * Don't call rscp_start() because SC may still be in the
99 * boot monitor. The boot monitor will not respond to
104 * Initialize Message Queue used between ADM_Callback and
105 * ADM_Boot_recv(). ADM_Callback is called from seperate thread.
107 if (smq_init(&ADM_bpMsgQueue
, ADM_bpMsgBuffer
,
108 ADM_BP_BUFF_SIZE
) != 0) {
110 (void) fprintf(stderr
, "\n%s\n\n",
111 gettext("scadm: ERROR, unable to setup message queue"));
115 /* Initialize callback for Boot Monitor RX */
116 if (rscp_register_bpmsg_cb(ADM_Callback
) != 0) {
117 (void) fprintf(stderr
, "\n%s\n\n",
118 gettext("scadm: ERROR, callback init failed"));
122 BootRetry
= ADM_BOOT_RETRY
;
123 while (BootRetry
> 0) {
126 * Initialize Message each time because this structure is reused
127 * during receive. Since this operation is not time critical,
128 * this is not a concern
130 Message
.cmd
= BP_OBP_BOOTINIT
;
132 Message
.dat2
= DownloadLocation
;
133 rscp_send_bpmsg(&Message
);
136 * Initialize Timeout each time just to be robust. Since this
137 * operation is not time critical, this is not a concern.
140 Timeout
.tv_sec
= ADM_BOOT_INIT_TIMEOUT
;
142 /* If we timeout, decrement BootRetry and try again */
143 if (ADM_Boot_recv(&Message
, &Timeout
) != 0) {
145 /* We got a timeout */
146 BootRetry
= BootRetry
- 1;
150 /* we got a message back, see what it is */
151 if ((Message
.cmd
!= BP_RSC_BOOTACK
) ||
152 (Message
.dat1
!= BP_DAT1_BOOTINIT_ACK
)) {
154 ADM_Display_download_error(Message
.cmd
,
160 * We got a valid acknowledge, break out of loop and
161 * start to download s-record
167 /* See if we ever got a response */
168 if (BootRetry
<= 0) {
169 (void) fprintf(stderr
, "\n%s\n\n",
170 gettext("scadm: SC did not respond during boot "
175 /* Download s-record */
176 if (ADM_Send_file(FilePtr
) != 0) {
177 (void) fprintf(stderr
, "\n%s - \"%s\"\n\n",
178 gettext("scadm: Error downloading file"), Filename
);
182 /* wait a second for BootMonitor to catch up */
185 (void) nanosleep(&Delay
, NULL
);
187 /* Send Reset boot protocol message to reboot SC */
188 Message
.cmd
= BP_OBP_RESET
;
191 rscp_send_bpmsg(&Message
);
194 rscp_unregister_bpmsg_cb(ADM_Callback
);
195 (void) smq_destroy(&ADM_bpMsgQueue
);
196 (void) fclose(FilePtr
);
198 (void) printf("%s\n\n", gettext("Download completed successfully"));
200 (void) printf("%s\n\n", gettext("Please wait for verification"));
203 * scadm cannot tell if the SC successfully verified the
204 * download or not, but instead attempts to send a
205 * status message (up to 60 times) and assumes proper
206 * operation when sucessfully sent.
208 * When the boot option is used, the SC may hang after
209 * resetting itself (after it sucessfully downloads and
210 * verifies the boot file). To work around this, scadm
211 * will (1) do a hard reset and pause for 10 seconds
212 * (2) retry the sending of status messages.
218 /* reset the SC before retrying */
219 if (rsc_nmi() != 0) {
220 (void) fprintf(stderr
, "\n%s\n\n",
222 "scadm: Unable to reset SC hardware"));
225 /* delay while SC resets */
227 Delay
.tv_sec
= ADM_BOOT_LOAD_TIMEOUT
;
228 (void) nanosleep(&Delay
, NULL
);
231 for (i
= 0; i
< 60; i
++) {
233 msg
.type
= DP_RSC_STATUS
;
237 (void) printf("%s", gettext("."));
238 (void) fflush(stdout
);
240 err
= rscp_send(&msg
);
247 } while (bootOpt
&& (retry
< 2));
249 (void) printf("\n%s\n\n", gettext("Complete"));
251 (void) printf("\n%s\n\n", gettext("Error during verification"));
258 (void) fprintf(stderr
, "\n%s\n\n",
259 gettext("USAGE: scadm download [boot] <file>"));