Merge tag 'arc-for-2018.11' of git://git.denx.de/u-boot-arc
[platform/kernel/u-boot.git] / env / sata.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2010-2016 Freescale Semiconductor, Inc.
4  */
5
6 /* #define DEBUG */
7
8 #include <common.h>
9
10 #include <command.h>
11 #include <environment.h>
12 #include <linux/stddef.h>
13 #include <errno.h>
14 #include <memalign.h>
15 #include <sata.h>
16 #include <search.h>
17
18 #if defined(CONFIG_ENV_SIZE_REDUND) || defined(CONFIG_ENV_OFFSET_REDUND)
19 #error ENV REDUND not supported
20 #endif
21
22 #if !defined(CONFIG_ENV_OFFSET) || !defined(CONFIG_ENV_SIZE)
23 #error CONFIG_ENV_OFFSET or CONFIG_ENV_SIZE not defined
24 #endif
25
26 __weak int sata_get_env_dev(void)
27 {
28         return CONFIG_SYS_SATA_ENV_DEV;
29 }
30
31 #ifdef CONFIG_CMD_SAVEENV
32 static inline int write_env(struct blk_desc *sata, unsigned long size,
33                             unsigned long offset, void *buffer)
34 {
35         uint blk_start, blk_cnt, n;
36
37         blk_start = ALIGN(offset, sata->blksz) / sata->blksz;
38         blk_cnt   = ALIGN(size, sata->blksz) / sata->blksz;
39
40         n = blk_dwrite(sata, blk_start, blk_cnt, buffer);
41
42         return (n == blk_cnt) ? 0 : -1;
43 }
44
45 static int env_sata_save(void)
46 {
47         ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
48         struct blk_desc *sata = NULL;
49         int env_sata, ret;
50
51         if (sata_initialize())
52                 return 1;
53
54         env_sata = sata_get_env_dev();
55
56         sata = sata_get_dev(env_sata);
57         if (sata == NULL) {
58                 printf("Unknown SATA(%d) device for environment!\n",
59                        env_sata);
60                 return 1;
61         }
62
63         ret = env_export(env_new);
64         if (ret)
65                 return 1;
66
67         printf("Writing to SATA(%d)...", env_sata);
68         if (write_env(sata, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, &env_new)) {
69                 puts("failed\n");
70                 return 1;
71         }
72
73         puts("done\n");
74         return 0;
75 }
76 #endif /* CONFIG_CMD_SAVEENV */
77
78 static inline int read_env(struct blk_desc *sata, unsigned long size,
79                            unsigned long offset, void *buffer)
80 {
81         uint blk_start, blk_cnt, n;
82
83         blk_start = ALIGN(offset, sata->blksz) / sata->blksz;
84         blk_cnt   = ALIGN(size, sata->blksz) / sata->blksz;
85
86         n = blk_dread(sata, blk_start, blk_cnt, buffer);
87
88         return (n == blk_cnt) ? 0 : -1;
89 }
90
91 static void env_sata_load(void)
92 {
93         ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
94         struct blk_desc *sata = NULL;
95         int env_sata;
96
97         if (sata_initialize())
98                 return -EIO;
99
100         env_sata = sata_get_env_dev();
101
102         sata = sata_get_dev(env_sata);
103         if (sata == NULL) {
104                 printf("Unknown SATA(%d) device for environment!\n", env_sata);
105                 return -EIO;
106         }
107
108         if (read_env(sata, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, buf)) {
109                 set_default_env(NULL, 0);
110                 return -EIO;
111         }
112
113         return env_import(buf, 1);
114 }
115
116 U_BOOT_ENV_LOCATION(sata) = {
117         .location       = ENVL_ESATA,
118         ENV_NAME("SATA")
119         .load           = env_sata_load,
120         .save           = env_save_ptr(env_sata_save),
121 };