/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* download.c: support to the scadm download option (download service
* processor firmware)
*/
#include <libintl.h>
#include <stdio.h>
#include <string.h>
#include "adm.h"
#include "librsc.h"
#include "smq.h"
extern smq_t ADM_bpMsgQueue;
static void usage();
void
{
int BootRetry;
char *Filename;
int i, err;
int retry;
int bootOpt;
usage();
exit(-1);
}
if (argc == 4) {
usage();
exit(-1);
}
bootOpt = 1;
} else { /* no [boot] option */
bootOpt = 0;
}
exit(-1);
}
/* Verify file is s-record */
if (ADM_Valid_srecord(FilePtr) != 0) {
exit(-1);
}
/*
* Don't call rscp_start() because SC may still be in the
* boot monitor. The boot monitor will not respond to
* rscp_start()
*/
/*
* Initialize Message Queue used between ADM_Callback and
* ADM_Boot_recv(). ADM_Callback is called from seperate thread.
*/
ADM_BP_BUFF_SIZE) != 0) {
gettext("scadm: ERROR, unable to setup message queue"));
exit(-1);
}
/* Initialize callback for Boot Monitor RX */
if (rscp_register_bpmsg_cb(ADM_Callback) != 0) {
gettext("scadm: ERROR, callback init failed"));
exit(-1);
}
while (BootRetry > 0) {
/*
* Initialize Message each time because this structure is reused
* during receive. Since this operation is not time critical,
* this is not a concern
*/
/*
* Initialize Timeout each time just to be robust. Since this
* operation is not time critical, this is not a concern.
*/
/* If we timeout, decrement BootRetry and try again */
/* We got a timeout */
continue;
} else {
/* we got a message back, see what it is */
exit(-1);
}
/*
* We got a valid acknowledge, break out of loop and
* start to download s-record
*/
break;
}
}
/* See if we ever got a response */
if (BootRetry <= 0) {
gettext("scadm: SC did not respond during boot "
"initialization"));
exit(-1);
}
/* Download s-record */
if (ADM_Send_file(FilePtr) != 0) {
exit(-1);
}
/* wait a second for BootMonitor to catch up */
/* Send Reset boot protocol message to reboot SC */
/* Cleanup */
(void) smq_destroy(&ADM_bpMsgQueue);
/*
* scadm cannot tell if the SC successfully verified the
* download or not, but instead attempts to send a
* status message (up to 60 times) and assumes proper
* operation when sucessfully sent.
*
* When the boot option is used, the SC may hang after
* resetting itself (after it sucessfully downloads and
* verifies the boot file). To work around this, scadm
* will (1) do a hard reset and pause for 10 seconds
* (2) retry the sending of status messages.
*/
retry = 0;
do {
if (retry == 1) {
/* reset the SC before retrying */
if (rsc_nmi() != 0) {
"scadm: Unable to reset SC hardware"));
exit(-1);
}
/* delay while SC resets */
}
for (i = 0; i < 60; i++) {
if (err == 0)
break;
}
if (err == 0)
break;
retry++;
if (err == 0)
else
}
static void
usage()
{
gettext("USAGE: scadm download [boot] <file>"));
}