blob: 207717e17b160f2cc4403eeb69c2f0cc65723da7 [file] [log] [blame]
Varadarajan Narayanan9dc5ad82025-05-13 14:47:08 +05301// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2008-2011 Freescale Semiconductor, Inc.
4 */
5
6/* #define DEBUG */
7
8#include <asm/global_data.h>
9
10#include <command.h>
11#include <env.h>
12#include <env_internal.h>
13#include <fdtdec.h>
14#include <linux/stddef.h>
15#include <malloc.h>
16#include <memalign.h>
17#include <part.h>
18#include <search.h>
19#include <scsi.h>
20#include <errno.h>
21#include <dm/ofnode.h>
22
23DECLARE_GLOBAL_DATA_PTR;
24static env_t envbuf;
25
26struct env_scsi_info {
27 struct blk_desc *blk;
28 struct disk_partition part;
29 int count;
30};
31
32static struct env_scsi_info env_part;
33
34static inline struct env_scsi_info *env_scsi_get_part(void)
35{
36 struct env_scsi_info *ep = &env_part;
37
38 if (scsi_get_blk_by_uuid(CONFIG_SCSI_ENV_PART_UUID, &ep->blk, &ep->part))
39 return NULL;
40
41 ep->count = CONFIG_ENV_SIZE / ep->part.blksz;
42
43 return ep;
44}
45
46static int env_scsi_save(void)
47{
48 struct env_scsi_info *ep = env_scsi_get_part();
49 int ret;
50
51 if (!ep)
52 return -ENOENT;
53
54 ret = env_export(&envbuf);
55 if (ret)
56 return ret;
57
58 if (blk_dwrite(ep->blk, ep->part.start, ep->count, &envbuf) != ep->count)
59 return -EIO;
60
61 return 0;
62}
63
64static int env_scsi_erase(void)
65{
66 struct env_scsi_info *ep = env_scsi_get_part();
67
68 if (!ep)
69 return -ENOENT;
70
71 return (int)blk_derase(ep->blk, ep->part.start, ep->count);
72}
73
74#if defined(ENV_IS_EMBEDDED)
75static int env_scsi_load(void)
76{
77 return 0;
78}
79#else
80static int env_scsi_load(void)
81{
82 struct env_scsi_info *ep = env_scsi_get_part();
83 int ret;
84
85 if (!ep) {
86 env_set_default(CONFIG_SCSI_ENV_PART_UUID " partition not found", 0);
87 return -ENOENT;
88 }
89
90 if (blk_dread(ep->blk, ep->part.start, ep->count, &envbuf) != ep->count) {
91 env_set_default(CONFIG_SCSI_ENV_PART_UUID " partition read failed", 0);
92 return -EIO;
93 }
94
95 ret = env_import((char *)&envbuf, 1, H_EXTERNAL);
96 if (ret) {
97 debug("ENV import failed\n");
98 env_set_default("Cannot load environment", 0);
99 } else {
100 gd->env_addr = (ulong)envbuf.data;
101 }
102
103 return ret;
104}
105#endif
106
107U_BOOT_ENV_LOCATION(scsi) = {
108 .location = ENVL_SCSI,
109 ENV_NAME("SCSI")
110 .load = env_scsi_load,
111#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_XPL_BUILD)
112 .save = env_save_ptr(env_scsi_save),
113 .erase = ENV_ERASE_PTR(env_scsi_erase),
114#endif
115};