/*
 * (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;
}
