forked from rrcarlosr/Jetpack
182 lines
3.8 KiB
C
182 lines
3.8 KiB
C
|
/*
|
||
|
* (C) Copyright 2007 Schindler Lift Inc.
|
||
|
* (C) Copyright 2007 DENX Software Engineering
|
||
|
*
|
||
|
* Author: Michel Marti <mma@objectxp.com>
|
||
|
* Adapted for U-Boot 1.2 by Piotr Kruszynski <ppk@semihalf.com>:
|
||
|
* - code clean-up
|
||
|
* - bugfix for overwriting bootargs by user
|
||
|
*
|
||
|
* SPDX-License-Identifier: GPL-2.0+
|
||
|
*/
|
||
|
|
||
|
#include <common.h>
|
||
|
#include <command.h>
|
||
|
#include <fat.h>
|
||
|
#include <malloc.h>
|
||
|
#include <image.h>
|
||
|
#include <usb.h>
|
||
|
#include <fat.h>
|
||
|
|
||
|
#include "fwupdate.h"
|
||
|
|
||
|
static int load_rescue_image(ulong);
|
||
|
|
||
|
void cm5200_fwupdate(void)
|
||
|
{
|
||
|
cmd_tbl_t *bcmd;
|
||
|
char *rsargs;
|
||
|
char *tmp = NULL;
|
||
|
char ka[16];
|
||
|
char * const argv[3] = { "bootm", ka, NULL };
|
||
|
|
||
|
/* Check if rescue system is disabled... */
|
||
|
if (getenv("norescue")) {
|
||
|
printf(LOG_PREFIX "Rescue System disabled.\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Check if we have a USB storage device and load image */
|
||
|
if (load_rescue_image(LOAD_ADDR))
|
||
|
return;
|
||
|
|
||
|
bcmd = find_cmd("bootm");
|
||
|
if (!bcmd)
|
||
|
return;
|
||
|
|
||
|
sprintf(ka, "%lx", (ulong)LOAD_ADDR);
|
||
|
|
||
|
/* prepare our bootargs */
|
||
|
rsargs = getenv("rs-args");
|
||
|
if (!rsargs)
|
||
|
rsargs = RS_BOOTARGS;
|
||
|
else {
|
||
|
tmp = malloc(strlen(rsargs+1));
|
||
|
if (!tmp) {
|
||
|
printf(LOG_PREFIX "Memory allocation failed\n");
|
||
|
return;
|
||
|
}
|
||
|
strcpy(tmp, rsargs);
|
||
|
rsargs = tmp;
|
||
|
}
|
||
|
|
||
|
setenv("bootargs", rsargs);
|
||
|
|
||
|
if (rsargs == tmp)
|
||
|
free(rsargs);
|
||
|
|
||
|
printf(LOG_PREFIX "Starting update system (bootargs=%s)...\n", rsargs);
|
||
|
do_bootm(bcmd, 0, 2, argv);
|
||
|
}
|
||
|
|
||
|
static int load_rescue_image(ulong addr)
|
||
|
{
|
||
|
disk_partition_t info;
|
||
|
int devno;
|
||
|
int partno;
|
||
|
int i;
|
||
|
char fwdir[64];
|
||
|
char nxri[128];
|
||
|
char *tmp;
|
||
|
char dev[7];
|
||
|
char addr_str[16];
|
||
|
char * const argv[6] = { "fatload", "usb", dev, addr_str, nxri, NULL };
|
||
|
struct blk_desc *stor_dev = NULL;
|
||
|
cmd_tbl_t *bcmd;
|
||
|
|
||
|
/* Get name of firmware directory */
|
||
|
tmp = getenv("fw-dir");
|
||
|
|
||
|
/* Copy it into fwdir */
|
||
|
strncpy(fwdir, tmp ? tmp : FW_DIR, sizeof(fwdir));
|
||
|
fwdir[sizeof(fwdir) - 1] = 0; /* Terminate string */
|
||
|
|
||
|
printf(LOG_PREFIX "Checking for firmware image directory '%s' on USB"
|
||
|
" storage...\n", fwdir);
|
||
|
usb_stop();
|
||
|
if (usb_init() != 0)
|
||
|
return 1;
|
||
|
|
||
|
/* Check for storage device */
|
||
|
if (usb_stor_scan(1) != 0) {
|
||
|
usb_stop();
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/* Detect storage device */
|
||
|
for (devno = 0; devno < USB_MAX_STOR_DEV; devno++) {
|
||
|
stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, devno);
|
||
|
if (stor_dev->type != DEV_TYPE_UNKNOWN)
|
||
|
break;
|
||
|
}
|
||
|
if (!stor_dev || stor_dev->type == DEV_TYPE_UNKNOWN) {
|
||
|
printf(LOG_PREFIX "No valid storage device found...\n");
|
||
|
usb_stop();
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/* Detect partition */
|
||
|
for (partno = -1, i = 0; i < 6; i++) {
|
||
|
if (part_get_info(stor_dev, i, &info) == 0) {
|
||
|
if (fat_register_device(stor_dev, i) == 0) {
|
||
|
/* Check if rescue image is present */
|
||
|
FW_DEBUG("Looking for firmware directory '%s'"
|
||
|
" on partition %d\n", fwdir, i);
|
||
|
if (!fat_exists(fwdir)) {
|
||
|
FW_DEBUG("No NX rescue image on "
|
||
|
"partition %d.\n", i);
|
||
|
partno = -2;
|
||
|
} else {
|
||
|
partno = i;
|
||
|
FW_DEBUG("Partition %d contains "
|
||
|
"firmware directory\n", partno);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (partno < 0) {
|
||
|
switch (partno) {
|
||
|
case -1:
|
||
|
printf(LOG_PREFIX "Error: No valid (FAT) partition "
|
||
|
"detected\n");
|
||
|
break;
|
||
|
case -2:
|
||
|
printf(LOG_PREFIX "Error: No NX rescue image on FAT "
|
||
|
"partition\n");
|
||
|
break;
|
||
|
default:
|
||
|
printf(LOG_PREFIX "Error: Failed with code %d\n",
|
||
|
partno);
|
||
|
}
|
||
|
usb_stop();
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/* Load the rescue image */
|
||
|
bcmd = find_cmd("fatload");
|
||
|
if (!bcmd) {
|
||
|
printf(LOG_PREFIX "Error - 'fatload' command not present.\n");
|
||
|
usb_stop();
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
tmp = getenv("nx-rescue-image");
|
||
|
sprintf(nxri, "%s/%s", fwdir, tmp ? tmp : RESCUE_IMAGE);
|
||
|
sprintf(dev, "%d:%d", devno, partno);
|
||
|
sprintf(addr_str, "%lx", addr);
|
||
|
|
||
|
FW_DEBUG("fat_fsload device='%s', addr='%s', file: %s\n",
|
||
|
dev, addr_str, nxri);
|
||
|
|
||
|
if (do_fat_fsload(bcmd, 0, 5, argv) != 0) {
|
||
|
usb_stop();
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/* Stop USB */
|
||
|
usb_stop();
|
||
|
return 0;
|
||
|
}
|