03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License, Version 1.0 only
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (the "License"). You may not use this file except in compliance
03831d35f7499c87d51205817c93e9a8d42c4baestevel * with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#pragma ident "%Z%%M% %I% %E% SMI"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * send_file.c: to support firmware download (get fw S-records from the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * user-specified file and send S-records string down to the service processor
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <libintl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <stdio.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <string.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <time.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "librsc.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "adm.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelADM_Send_file(FILE *FilePtr)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static char ADM_Line[ADM_LINE_SIZE];
03831d35f7499c87d51205817c93e9a8d42c4baestevel static bp_msg_t Message;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static struct timespec Timeout;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int LinesWritten;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int Status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int BootRetry;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int LastRecord;
03831d35f7499c87d51205817c93e9a8d42c4baestevel long FileLength = 0L;
03831d35f7499c87d51205817c93e9a8d42c4baestevel long FilePos;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Determine the length of the file
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (fseek(FilePtr, 0L, SEEK_END) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel FileLength = ftell(FilePtr);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rewind(FilePtr);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel LinesWritten = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel LastRecord = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while ((fgets(ADM_Line, ADM_LINE_SIZE, FilePtr) != NULL) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (LastRecord == 0)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ADM_Line[0] == 'S') &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel ((ADM_Line[1] == '7') || (ADM_Line[1] == '8') ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel (ADM_Line[1] == '9'))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel LastRecord = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel BootRetry = ADM_BOOT_RETRY;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (BootRetry > 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((Status =
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_raw_write(ADM_Line, strlen(ADM_Line))) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (Status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initialize Timeout each time just to be robust.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Since this operation is not time critical, this is
03831d35f7499c87d51205817c93e9a8d42c4baestevel * not a concern.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel Timeout.tv_nsec = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Timeout.tv_sec = ADM_BOOT_LOAD_TIMEOUT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* If we timeout, decrement BootRetry and try again */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((Status = ADM_Boot_recv(&Message, &Timeout)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* We got a timeout */
03831d35f7499c87d51205817c93e9a8d42c4baestevel BootRetry = BootRetry - 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* we got a message back, see what it is */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((Message.cmd == BP_RSC_BOOTOK) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (Message.dat1 == 0) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (Message.dat2 == 0)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel LastRecord = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((Message.cmd != BP_RSC_BOOTACK) ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel (Message.dat1 != BP_DAT1_SRECORD_ACK)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (Message.dat1 ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel BP_DAT1_SRECORD_NAK) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Display_download_error(
03831d35f7499c87d51205817c93e9a8d42c4baestevel (int)Message.cmd,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (int)Message.dat1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We got a valid acknowledge, break out of
03831d35f7499c87d51205817c93e9a8d42c4baestevel * loop and start to download next s-record
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* See if we ever got a response */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (BootRetry <= 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: SC failed to respond during "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "download"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel LinesWritten++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((LinesWritten % 100) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) printf(".");
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fflush(stdout);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((LinesWritten % 4000) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (FileLength) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Show % progress */
03831d35f7499c87d51205817c93e9a8d42c4baestevel FilePos = ftell(FilePtr);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) printf(" (%ld%%)",
03831d35f7499c87d51205817c93e9a8d42c4baestevel (FilePos * 100) / FileLength);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) printf("\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fflush(stdout);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((FileLength) && ((LinesWritten % 4000) != 0)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Show final % progress (should normally be 100%) */
03831d35f7499c87d51205817c93e9a8d42c4baestevel FilePos = ftell(FilePtr);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) printf(" (%ld%%)",
03831d35f7499c87d51205817c93e9a8d42c4baestevel (FilePos * 100) / FileLength);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) printf("\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelADM_Display_download_error(int cmd, int dat1)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (cmd == BP_RSC_BOOTFAIL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (dat1 == BP_DAT1_REJECTED) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: download rejected"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (dat1 == BP_DAT1_RANGE_ERR) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: download failed, "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SC reported range error"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (dat1 == BP_DAT1_VERIFY_ERR) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: download failed, "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SC reported verify error"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (dat1 == BP_DAT1_ERASE_ERR) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: download failed, "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SC reported erase error"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (dat1 == BP_DAT1_INT_WP_ERR) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: download failed, "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SC reported int_wp error"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (dat1 == BP_DAT1_WP_ERR) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: download failed, "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SC reported wp error"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (dat1 == BP_DAT1_VPP_ERR) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: download failed, "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SC reported vpp error"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "%s 0x%08x\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: SC returned fatal error"), dat1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (cmd == BP_RSC_BOOTACK) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (dat1 == BP_DAT1_SRECORD_ACK) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: download failed"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "%s 0x%08x\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: SC returned fatal error"), dat1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "%s 0x%08x:0x%08x\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: SC returned unknown error"), cmd, dat1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}