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