Home | History | Annotate | Download | only in env
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (c) Copyright 2011 by Tigris Elektronik GmbH
      4  *
      5  * Author:
      6  *  Maximilian Schwerin <mvs (at) tigris.de>
      7  */
      8 
      9 #include <common.h>
     10 
     11 #include <command.h>
     12 #include <environment.h>
     13 #include <linux/stddef.h>
     14 #include <malloc.h>
     15 #include <memalign.h>
     16 #include <search.h>
     17 #include <errno.h>
     18 #include <fat.h>
     19 #include <mmc.h>
     20 
     21 #ifdef CONFIG_SPL_BUILD
     22 /* TODO(sjg (at) chromium.org): Figure out why this is needed */
     23 # if !defined(CONFIG_TARGET_AM335X_EVM) || defined(CONFIG_SPL_OS_BOOT)
     24 #  define LOADENV
     25 # endif
     26 #else
     27 # define LOADENV
     28 # if defined(CONFIG_CMD_SAVEENV)
     29 #  define CMD_SAVEENV
     30 # endif
     31 #endif
     32 
     33 #ifdef CMD_SAVEENV
     34 static int env_fat_save(void)
     35 {
     36 	env_t __aligned(ARCH_DMA_MINALIGN) env_new;
     37 	struct blk_desc *dev_desc = NULL;
     38 	disk_partition_t info;
     39 	int dev, part;
     40 	int err;
     41 	loff_t size;
     42 
     43 	err = env_export(&env_new);
     44 	if (err)
     45 		return err;
     46 
     47 	part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
     48 					CONFIG_ENV_FAT_DEVICE_AND_PART,
     49 					&dev_desc, &info, 1);
     50 	if (part < 0)
     51 		return 1;
     52 
     53 	dev = dev_desc->devnum;
     54 	if (fat_set_blk_dev(dev_desc, &info) != 0) {
     55 		/*
     56 		 * This printf is embedded in the messages from env_save that
     57 		 * will calling it. The missing \n is intentional.
     58 		 */
     59 		printf("Unable to use %s %d:%d... ",
     60 		       CONFIG_ENV_FAT_INTERFACE, dev, part);
     61 		return 1;
     62 	}
     63 
     64 	err = file_fat_write(CONFIG_ENV_FAT_FILE, (void *)&env_new, 0, sizeof(env_t),
     65 			     &size);
     66 	if (err == -1) {
     67 		/*
     68 		 * This printf is embedded in the messages from env_save that
     69 		 * will calling it. The missing \n is intentional.
     70 		 */
     71 		printf("Unable to write \"%s\" from %s%d:%d... ",
     72 			CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part);
     73 		return 1;
     74 	}
     75 
     76 	return 0;
     77 }
     78 #endif /* CMD_SAVEENV */
     79 
     80 #ifdef LOADENV
     81 static int env_fat_load(void)
     82 {
     83 	ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
     84 	struct blk_desc *dev_desc = NULL;
     85 	disk_partition_t info;
     86 	int dev, part;
     87 	int err;
     88 
     89 #ifdef CONFIG_MMC
     90 	if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc"))
     91 		mmc_initialize(NULL);
     92 #endif
     93 
     94 	part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
     95 					CONFIG_ENV_FAT_DEVICE_AND_PART,
     96 					&dev_desc, &info, 1);
     97 	if (part < 0)
     98 		goto err_env_relocate;
     99 
    100 	dev = dev_desc->devnum;
    101 	if (fat_set_blk_dev(dev_desc, &info) != 0) {
    102 		/*
    103 		 * This printf is embedded in the messages from env_save that
    104 		 * will calling it. The missing \n is intentional.
    105 		 */
    106 		printf("Unable to use %s %d:%d... ",
    107 		       CONFIG_ENV_FAT_INTERFACE, dev, part);
    108 		goto err_env_relocate;
    109 	}
    110 
    111 	err = file_fat_read(CONFIG_ENV_FAT_FILE, buf, CONFIG_ENV_SIZE);
    112 	if (err == -1) {
    113 		/*
    114 		 * This printf is embedded in the messages from env_save that
    115 		 * will calling it. The missing \n is intentional.
    116 		 */
    117 		printf("Unable to read \"%s\" from %s%d:%d... ",
    118 			CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part);
    119 		goto err_env_relocate;
    120 	}
    121 
    122 	return env_import(buf, 1);
    123 
    124 err_env_relocate:
    125 	set_default_env(NULL);
    126 
    127 	return -EIO;
    128 }
    129 #endif /* LOADENV */
    130 
    131 U_BOOT_ENV_LOCATION(fat) = {
    132 	.location	= ENVL_FAT,
    133 	ENV_NAME("FAT")
    134 #ifdef LOADENV
    135 	.load		= env_fat_load,
    136 #endif
    137 #ifdef CMD_SAVEENV
    138 	.save		= env_save_ptr(env_fat_save),
    139 #endif
    140 };
    141