Blame view
env/mmc.c
8.21 KB
83d290c56 SPDX: Convert all... |
1 |
// SPDX-License-Identifier: GPL-2.0+ |
a80603598 Save environment ... |
2 |
/* |
97039ab98 env_mmc: Allow bo... |
3 |
* (C) Copyright 2008-2011 Freescale Semiconductor, Inc. |
a80603598 Save environment ... |
4 5 6 7 8 9 10 |
*/ /* #define DEBUG */ #include <common.h> #include <command.h> |
0ac7d722e env: Move get/set... |
11 |
#include <env.h> |
f3998fdc4 env: Rename envir... |
12 |
#include <env_internal.h> |
f8b8a5546 env_mmc: configur... |
13 |
#include <fdtdec.h> |
a80603598 Save environment ... |
14 15 |
#include <linux/stddef.h> #include <malloc.h> |
cf92e05c0 Move ALLOC_CACHE_... |
16 |
#include <memalign.h> |
a80603598 Save environment ... |
17 |
#include <mmc.h> |
c9e87ba66 env: Save environ... |
18 |
#include <part.h> |
6d1d51b32 env_mmc: fix comp... |
19 |
#include <search.h> |
e79f48393 env_mmc: fix cann... |
20 |
#include <errno.h> |
a80603598 Save environment ... |
21 |
|
c9e87ba66 env: Save environ... |
22 23 |
#define __STR(X) #X #define STR(X) __STR(X) |
a80603598 Save environment ... |
24 |
DECLARE_GLOBAL_DATA_PTR; |
f8b8a5546 env_mmc: configur... |
25 |
#if CONFIG_IS_ENABLED(OF_CONTROL) |
c9e87ba66 env: Save environ... |
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
static inline int mmc_offset_try_partition(const char *str, s64 *val) { disk_partition_t info; struct blk_desc *desc; int len, i, ret; ret = blk_get_device_by_str("mmc", STR(CONFIG_SYS_MMC_ENV_DEV), &desc); if (ret < 0) return (ret); for (i = 1;;i++) { ret = part_get_info(desc, i, &info); if (ret < 0) return ret; if (!strncmp((const char *)info.name, str, sizeof(str))) break; } /* round up to info.blksz */ len = (CONFIG_ENV_SIZE + info.blksz - 1) & ~(info.blksz - 1); /* use the top of the partion for the environment */ *val = (info.start + info.size - 1) - len / info.blksz; return 0; } |
f8b8a5546 env_mmc: configur... |
53 54 |
static inline s64 mmc_offset(int copy) { |
c9e87ba66 env: Save environ... |
55 56 57 58 59 60 61 62 63 |
const struct { const char *offset_redund; const char *partition; const char *offset; } dt_prop = { .offset_redund = "u-boot,mmc-env-offset-redundant", .partition = "u-boot,mmc-env-partition", .offset = "u-boot,mmc-env-offset", }; |
fd374665c env: suppress a s... |
64 |
s64 val = 0, defvalue; |
c9e87ba66 env: Save environ... |
65 66 67 68 69 70 71 72 73 74 75 76 |
const char *propname; const char *str; int err; /* look for the partition in mmc CONFIG_SYS_MMC_ENV_DEV */ str = fdtdec_get_config_string(gd->fdt_blob, dt_prop.partition); if (str) { /* try to place the environment at end of the partition */ err = mmc_offset_try_partition(str, &val); if (!err) return val; } |
9dca18a27 MLK-22279-1 env: ... |
77 |
defvalue = env_get_offset(CONFIG_ENV_OFFSET); |
c9e87ba66 env: Save environ... |
78 |
propname = dt_prop.offset; |
f8b8a5546 env_mmc: configur... |
79 80 81 |
#if defined(CONFIG_ENV_OFFSET_REDUND) if (copy) { |
f8b8a5546 env_mmc: configur... |
82 |
defvalue = CONFIG_ENV_OFFSET_REDUND; |
c9e87ba66 env: Save environ... |
83 |
propname = dt_prop.offset_redund; |
f8b8a5546 env_mmc: configur... |
84 85 |
} #endif |
f8b8a5546 env_mmc: configur... |
86 87 88 89 |
return fdtdec_get_config_int(gd->fdt_blob, propname, defvalue); } #else static inline s64 mmc_offset(int copy) |
97039ab98 env_mmc: Allow bo... |
90 |
{ |
9dca18a27 MLK-22279-1 env: ... |
91 |
s64 offset = env_get_offset(CONFIG_ENV_OFFSET); |
5c088ee84 env_mmc: allow ne... |
92 |
|
f8b8a5546 env_mmc: configur... |
93 |
#if defined(CONFIG_ENV_OFFSET_REDUND) |
d196bd880 env_mmc: add supp... |
94 |
if (copy) |
5c088ee84 env_mmc: allow ne... |
95 |
offset = CONFIG_ENV_OFFSET_REDUND; |
d196bd880 env_mmc: add supp... |
96 |
#endif |
f8b8a5546 env_mmc: configur... |
97 98 99 100 101 102 103 |
return offset; } #endif __weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr) { s64 offset = mmc_offset(copy); |
5c088ee84 env_mmc: allow ne... |
104 105 106 107 108 |
if (offset < 0) offset += mmc->capacity; *env_addr = offset; |
97039ab98 env_mmc: Allow bo... |
109 110 |
return 0; } |
97039ab98 env_mmc: Allow bo... |
111 |
|
e92029c0f env_mmc: support ... |
112 113 114 115 |
__weak int mmc_get_env_dev(void) { return CONFIG_SYS_MMC_ENV_DEV; } |
b9c8ccaba env_mmc.c: Allow ... |
116 |
#ifdef CONFIG_SYS_MMC_ENV_PART |
6e7b7df4d env_mmc: support ... |
117 118 119 120 |
__weak uint mmc_get_env_part(struct mmc *mmc) { return CONFIG_SYS_MMC_ENV_PART; } |
873cc1d77 mmc: store hwpart... |
121 |
static unsigned char env_mmc_orig_hwpart; |
6e7b7df4d env_mmc: support ... |
122 123 124 |
static int mmc_set_env_part(struct mmc *mmc) { uint part = mmc_get_env_part(mmc); |
e92029c0f env_mmc: support ... |
125 |
int dev = mmc_get_env_dev(); |
6e7b7df4d env_mmc: support ... |
126 |
int ret = 0; |
b9c8ccaba env_mmc.c: Allow ... |
127 |
|
69f45cd53 dm: mmc: Use the ... |
128 129 |
env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart; ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part); |
873cc1d77 mmc: store hwpart... |
130 131 132 |
if (ret) puts("MMC partition switch failed "); |
6e7b7df4d env_mmc: support ... |
133 134 135 136 137 |
return ret; } #else static inline int mmc_set_env_part(struct mmc *mmc) {return 0; }; |
b9c8ccaba env_mmc.c: Allow ... |
138 |
#endif |
c75648d75 env_mmc: add erro... |
139 |
static const char *init_mmc_for_env(struct mmc *mmc) |
6e7b7df4d env_mmc: support ... |
140 |
{ |
c75648d75 env_mmc: add erro... |
141 |
if (!mmc) |
c5d548a9f env: common: acce... |
142 |
return "No MMC card found"; |
a80603598 Save environment ... |
143 |
|
d48b8d113 env: Properly che... |
144 |
#if CONFIG_IS_ENABLED(BLK) |
01b73fe63 dm: mmc: Ensure t... |
145 146 147 |
struct udevice *dev; if (blk_get_from_parent(mmc->dev, &dev)) |
c5d548a9f env: common: acce... |
148 |
return "No block device"; |
01b73fe63 dm: mmc: Ensure t... |
149 |
#else |
c75648d75 env_mmc: add erro... |
150 |
if (mmc_init(mmc)) |
c5d548a9f env: common: acce... |
151 |
return "MMC init failed"; |
e7017a3c7 dm: mmc: Don't re... |
152 |
#endif |
c75648d75 env_mmc: add erro... |
153 |
if (mmc_set_env_part(mmc)) |
c5d548a9f env: common: acce... |
154 |
return "MMC partition switch failed"; |
a80603598 Save environment ... |
155 |
|
c75648d75 env_mmc: add erro... |
156 |
return NULL; |
a80603598 Save environment ... |
157 |
} |
9404a5fc7 env_mmc: allow en... |
158 159 160 |
static void fini_mmc_for_env(struct mmc *mmc) { #ifdef CONFIG_SYS_MMC_ENV_PART |
e92029c0f env_mmc: support ... |
161 |
int dev = mmc_get_env_dev(); |
b9c8ccaba env_mmc.c: Allow ... |
162 |
|
69f45cd53 dm: mmc: Use the ... |
163 |
blk_select_hwpart_devnum(IF_TYPE_MMC, dev, env_mmc_orig_hwpart); |
9404a5fc7 env_mmc: allow en... |
164 165 |
#endif } |
e5bce247b env: Switch over ... |
166 |
#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_SPL_BUILD) |
e8db8f71c env: clean env_mm... |
167 168 |
static inline int write_env(struct mmc *mmc, unsigned long size, unsigned long offset, const void *buffer) |
a80603598 Save environment ... |
169 170 |
{ uint blk_start, blk_cnt, n; |
5461acba4 dm: env: mmc: Con... |
171 |
struct blk_desc *desc = mmc_get_blk_desc(mmc); |
a80603598 Save environment ... |
172 |
|
e8db8f71c env: clean env_mm... |
173 174 |
blk_start = ALIGN(offset, mmc->write_bl_len) / mmc->write_bl_len; blk_cnt = ALIGN(size, mmc->write_bl_len) / mmc->write_bl_len; |
a80603598 Save environment ... |
175 |
|
5461acba4 dm: env: mmc: Con... |
176 |
n = blk_dwrite(desc, blk_start, blk_cnt, (u_char *)buffer); |
a80603598 Save environment ... |
177 178 179 |
return (n == blk_cnt) ? 0 : -1; } |
e5bce247b env: Switch over ... |
180 |
static int env_mmc_save(void) |
a80603598 Save environment ... |
181 |
{ |
cd0f4fa1c Revert "env: fix ... |
182 |
ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); |
e92029c0f env_mmc: support ... |
183 184 |
int dev = mmc_get_env_dev(); struct mmc *mmc = find_mmc_device(dev); |
e8db8f71c env: clean env_mm... |
185 |
u32 offset; |
d196bd880 env_mmc: add supp... |
186 |
int ret, copy = 0; |
c75648d75 env_mmc: add erro... |
187 |
const char *errmsg; |
a80603598 Save environment ... |
188 |
|
c75648d75 env_mmc: add erro... |
189 190 191 192 |
errmsg = init_mmc_for_env(mmc); if (errmsg) { printf("%s ", errmsg); |
97039ab98 env_mmc: Allow bo... |
193 |
return 1; |
c75648d75 env_mmc: add erro... |
194 |
} |
97039ab98 env_mmc: Allow bo... |
195 |
|
7ce1526ed env: Add env_expo... |
196 197 |
ret = env_export(env_new); if (ret) |
9404a5fc7 env_mmc: allow en... |
198 |
goto fini; |
d196bd880 env_mmc: add supp... |
199 200 |
#ifdef CONFIG_ENV_OFFSET_REDUND |
203e94f6c env: Add an enum ... |
201 |
if (gd->env_valid == ENV_VALID) |
d196bd880 env_mmc: add supp... |
202 203 204 205 206 207 208 |
copy = 1; #endif if (mmc_get_env_addr(mmc, copy, &offset)) { ret = 1; goto fini; } |
e92029c0f env_mmc: support ... |
209 |
printf("Writing to %sMMC(%d)... ", copy ? "redundant " : "", dev); |
4036b6301 env_mmc: align bu... |
210 |
if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) { |
a80603598 Save environment ... |
211 212 |
puts("failed "); |
9404a5fc7 env_mmc: allow en... |
213 214 |
ret = 1; goto fini; |
a80603598 Save environment ... |
215 |
} |
9404a5fc7 env_mmc: allow en... |
216 |
ret = 0; |
d196bd880 env_mmc: add supp... |
217 |
#ifdef CONFIG_ENV_OFFSET_REDUND |
203e94f6c env: Add an enum ... |
218 |
gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND; |
d196bd880 env_mmc: add supp... |
219 |
#endif |
9404a5fc7 env_mmc: allow en... |
220 221 222 |
fini: fini_mmc_for_env(mmc); return ret; |
a80603598 Save environment ... |
223 |
} |
348539250 env: mmc: add era... |
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
#if defined(CONFIG_CMD_ERASEENV) static inline int erase_env(struct mmc *mmc, unsigned long size, unsigned long offset) { uint blk_start, blk_cnt, n; struct blk_desc *desc = mmc_get_blk_desc(mmc); blk_start = ALIGN(offset, mmc->write_bl_len) / mmc->write_bl_len; blk_cnt = ALIGN(size, mmc->write_bl_len) / mmc->write_bl_len; n = blk_derase(desc, blk_start, blk_cnt); printf("%d blocks erased: %s ", n, (n == blk_cnt) ? "OK" : "ERROR"); return (n == blk_cnt) ? 0 : 1; } static int env_mmc_erase(void) { int dev = mmc_get_env_dev(); struct mmc *mmc = find_mmc_device(dev); int ret, copy = 0; u32 offset; const char *errmsg; errmsg = init_mmc_for_env(mmc); if (errmsg) { printf("%s ", errmsg); return 1; } if (mmc_get_env_addr(mmc, copy, &offset)) return CMD_RET_FAILURE; ret = erase_env(mmc, CONFIG_ENV_SIZE, offset); #ifdef CONFIG_ENV_OFFSET_REDUND copy = 1; if (mmc_get_env_addr(mmc, copy, &offset)) return CMD_RET_FAILURE; ret |= erase_env(mmc, CONFIG_ENV_SIZE, offset); #endif return ret; } #endif /* CONFIG_CMD_ERASEENV */ |
e5bce247b env: Switch over ... |
274 |
#endif /* CONFIG_CMD_SAVEENV && !CONFIG_SPL_BUILD */ |
a80603598 Save environment ... |
275 |
|
e8db8f71c env: clean env_mm... |
276 277 |
static inline int read_env(struct mmc *mmc, unsigned long size, unsigned long offset, const void *buffer) |
a80603598 Save environment ... |
278 279 |
{ uint blk_start, blk_cnt, n; |
5461acba4 dm: env: mmc: Con... |
280 |
struct blk_desc *desc = mmc_get_blk_desc(mmc); |
a80603598 Save environment ... |
281 |
|
e8db8f71c env: clean env_mm... |
282 283 |
blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len; blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len; |
a80603598 Save environment ... |
284 |
|
5461acba4 dm: env: mmc: Con... |
285 |
n = blk_dread(desc, blk_start, blk_cnt, (uchar *)buffer); |
a80603598 Save environment ... |
286 287 288 |
return (n == blk_cnt) ? 0 : -1; } |
d196bd880 env_mmc: add supp... |
289 |
#ifdef CONFIG_ENV_OFFSET_REDUND |
c59519919 env: Adjust the l... |
290 |
static int env_mmc_load(void) |
d196bd880 env_mmc: add supp... |
291 292 |
{ #if !defined(ENV_IS_EMBEDDED) |
b9c8ccaba env_mmc.c: Allow ... |
293 |
struct mmc *mmc; |
d196bd880 env_mmc: add supp... |
294 295 |
u32 offset1, offset2; int read1_fail = 0, read2_fail = 0; |
d196bd880 env_mmc: add supp... |
296 |
int ret; |
e92029c0f env_mmc: support ... |
297 |
int dev = mmc_get_env_dev(); |
c75648d75 env_mmc: add erro... |
298 |
const char *errmsg = NULL; |
d196bd880 env_mmc: add supp... |
299 |
|
452a2722e env_mmc: fix buff... |
300 301 |
ALLOC_CACHE_ALIGN_BUFFER(env_t, tmp_env1, 1); ALLOC_CACHE_ALIGN_BUFFER(env_t, tmp_env2, 1); |
26862b4a4 env: mmc/fat/ext4... |
302 |
mmc_initialize(NULL); |
b9c8ccaba env_mmc.c: Allow ... |
303 |
mmc = find_mmc_device(dev); |
c75648d75 env_mmc: add erro... |
304 305 |
errmsg = init_mmc_for_env(mmc); if (errmsg) { |
c59519919 env: Adjust the l... |
306 |
ret = -EIO; |
d196bd880 env_mmc: add supp... |
307 308 309 310 311 |
goto err; } if (mmc_get_env_addr(mmc, 0, &offset1) || mmc_get_env_addr(mmc, 1, &offset2)) { |
c59519919 env: Adjust the l... |
312 |
ret = -EIO; |
d196bd880 env_mmc: add supp... |
313 314 315 316 317 |
goto fini; } read1_fail = read_env(mmc, CONFIG_ENV_SIZE, offset1, tmp_env1); read2_fail = read_env(mmc, CONFIG_ENV_SIZE, offset2, tmp_env2); |
31f044bd9 env: move more co... |
318 319 |
ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2, read2_fail); |
d196bd880 env_mmc: add supp... |
320 321 322 323 324 |
fini: fini_mmc_for_env(mmc); err: if (ret) |
0ac7d722e env: Move get/set... |
325 |
env_set_default(errmsg, 0); |
c59519919 env: Adjust the l... |
326 |
|
d196bd880 env_mmc: add supp... |
327 |
#endif |
c59519919 env: Adjust the l... |
328 |
return ret; |
d196bd880 env_mmc: add supp... |
329 330 |
} #else /* ! CONFIG_ENV_OFFSET_REDUND */ |
c59519919 env: Adjust the l... |
331 |
static int env_mmc_load(void) |
a80603598 Save environment ... |
332 333 |
{ #if !defined(ENV_IS_EMBEDDED) |
cd0f4fa1c Revert "env: fix ... |
334 |
ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); |
b9c8ccaba env_mmc.c: Allow ... |
335 |
struct mmc *mmc; |
97039ab98 env_mmc: Allow bo... |
336 |
u32 offset; |
9404a5fc7 env_mmc: allow en... |
337 |
int ret; |
e92029c0f env_mmc: support ... |
338 |
int dev = mmc_get_env_dev(); |
c75648d75 env_mmc: add erro... |
339 |
const char *errmsg; |
0536b440a env: Update env_a... |
340 |
env_t *ep = NULL; |
b9c8ccaba env_mmc.c: Allow ... |
341 |
|
b9c8ccaba env_mmc.c: Allow ... |
342 |
mmc = find_mmc_device(dev); |
a80603598 Save environment ... |
343 |
|
c75648d75 env_mmc: add erro... |
344 345 |
errmsg = init_mmc_for_env(mmc); if (errmsg) { |
c59519919 env: Adjust the l... |
346 |
ret = -EIO; |
9404a5fc7 env_mmc: allow en... |
347 348 |
goto err; } |
a80603598 Save environment ... |
349 |
|
d196bd880 env_mmc: add supp... |
350 |
if (mmc_get_env_addr(mmc, 0, &offset)) { |
c59519919 env: Adjust the l... |
351 |
ret = -EIO; |
9404a5fc7 env_mmc: allow en... |
352 353 |
goto fini; } |
cd0f4fa1c Revert "env: fix ... |
354 |
if (read_env(mmc, CONFIG_ENV_SIZE, offset, buf)) { |
c75648d75 env_mmc: add erro... |
355 |
errmsg = "!read failed"; |
c59519919 env: Adjust the l... |
356 |
ret = -EIO; |
9404a5fc7 env_mmc: allow en... |
357 358 |
goto fini; } |
a80603598 Save environment ... |
359 |
|
2166ebf78 env: make env dri... |
360 |
ret = env_import(buf, 1); |
0536b440a env: Update env_a... |
361 362 363 364 |
if (!ret) { ep = (env_t *)buf; gd->env_addr = (ulong)&ep->data; } |
9404a5fc7 env_mmc: allow en... |
365 366 367 368 369 |
fini: fini_mmc_for_env(mmc); err: if (ret) |
0ac7d722e env: Move get/set... |
370 |
env_set_default(errmsg, 0); |
a80603598 Save environment ... |
371 |
#endif |
c59519919 env: Adjust the l... |
372 |
return ret; |
a80603598 Save environment ... |
373 |
} |
d196bd880 env_mmc: add supp... |
374 |
#endif /* CONFIG_ENV_OFFSET_REDUND */ |
4415f1d1f env: Create a loc... |
375 376 377 |
U_BOOT_ENV_LOCATION(mmc) = { .location = ENVL_MMC, |
ac358beb8 env: Drop the env... |
378 |
ENV_NAME("MMC") |
e5bce247b env: Switch over ... |
379 |
.load = env_mmc_load, |
4415f1d1f env: Create a loc... |
380 |
#ifndef CONFIG_SPL_BUILD |
e5bce247b env: Switch over ... |
381 |
.save = env_save_ptr(env_mmc_save), |
348539250 env: mmc: add era... |
382 383 384 |
#if defined(CONFIG_CMD_ERASEENV) .erase = env_mmc_erase, #endif |
4415f1d1f env: Create a loc... |
385 |
#endif |
4415f1d1f env: Create a loc... |
386 |
}; |