Merge https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq
[platform/kernel/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 <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
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         struct disk_partition 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         struct disk_partition 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 };