]> git.ipfire.org Git - thirdparty/u-boot.git/blob - env/fat.c
9772b87a19133f6a808909c5d65a98b600d980a2
[thirdparty/u-boot.git] / env / fat.c
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 <asm/cache.h>
11
12 #include <command.h>
13 #include <env.h>
14 #include <env_internal.h>
15 #include <linux/stddef.h>
16 #include <malloc.h>
17 #include <memalign.h>
18 #include <search.h>
19 #include <errno.h>
20 #include <fat.h>
21 #include <mmc.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
32 static int env_fat_save(void)
33 {
34 env_t __aligned(ARCH_DMA_MINALIGN) env_new;
35 struct blk_desc *dev_desc = NULL;
36 disk_partition_t info;
37 int dev, part;
38 int err;
39 loff_t size;
40
41 err = env_export(&env_new);
42 if (err)
43 return err;
44
45 part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
46 CONFIG_ENV_FAT_DEVICE_AND_PART,
47 &dev_desc, &info, 1);
48 if (part < 0)
49 return 1;
50
51 dev = dev_desc->devnum;
52 if (fat_set_blk_dev(dev_desc, &info) != 0) {
53 /*
54 * This printf is embedded in the messages from env_save that
55 * will calling it. The missing \n is intentional.
56 */
57 printf("Unable to use %s %d:%d... ",
58 CONFIG_ENV_FAT_INTERFACE, dev, part);
59 return 1;
60 }
61
62 err = file_fat_write(CONFIG_ENV_FAT_FILE, (void *)&env_new, 0, sizeof(env_t),
63 &size);
64 if (err == -1) {
65 /*
66 * This printf is embedded in the messages from env_save that
67 * will calling it. The missing \n is intentional.
68 */
69 printf("Unable to write \"%s\" from %s%d:%d... ",
70 CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part);
71 return 1;
72 }
73
74 return 0;
75 }
76
77 #ifdef LOADENV
78 static int env_fat_load(void)
79 {
80 ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
81 struct blk_desc *dev_desc = NULL;
82 disk_partition_t info;
83 int dev, part;
84 int err;
85
86 #ifdef CONFIG_MMC
87 if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc"))
88 mmc_initialize(NULL);
89 #endif
90
91 part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
92 CONFIG_ENV_FAT_DEVICE_AND_PART,
93 &dev_desc, &info, 1);
94 if (part < 0)
95 goto err_env_relocate;
96
97 dev = dev_desc->devnum;
98 if (fat_set_blk_dev(dev_desc, &info) != 0) {
99 /*
100 * This printf is embedded in the messages from env_save that
101 * will calling it. The missing \n is intentional.
102 */
103 printf("Unable to use %s %d:%d... ",
104 CONFIG_ENV_FAT_INTERFACE, dev, part);
105 goto err_env_relocate;
106 }
107
108 err = file_fat_read(CONFIG_ENV_FAT_FILE, buf, CONFIG_ENV_SIZE);
109 if (err == -1) {
110 /*
111 * This printf is embedded in the messages from env_save that
112 * will calling it. The missing \n is intentional.
113 */
114 printf("Unable to read \"%s\" from %s%d:%d... ",
115 CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part);
116 goto err_env_relocate;
117 }
118
119 return env_import(buf, 1);
120
121 err_env_relocate:
122 env_set_default(NULL, 0);
123
124 return -EIO;
125 }
126 #endif /* LOADENV */
127
128 U_BOOT_ENV_LOCATION(fat) = {
129 .location = ENVL_FAT,
130 ENV_NAME("FAT")
131 #ifdef LOADENV
132 .load = env_fat_load,
133 #endif
134 .save = ENV_SAVE_PTR(env_fat_save),
135 };