]>
git.ipfire.org Git - people/ms/u-boot.git/blob - common/hwconfig.c
2 * An inteface for configuring a hardware via u-boot environment.
4 * Copyright (c) 2009 MontaVista Software, Inc.
5 * Copyright 2011 Freescale Semiconductor, Inc.
7 * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
9 * SPDX-License-Identifier: GPL-2.0+
17 #include <linux/types.h>
18 #include <linux/string.h>
24 #define min(a, b) (((a) < (b)) ? (a) : (b))
25 #endif /* HWCONFIG_TEST */
27 DECLARE_GLOBAL_DATA_PTR
;
29 static const char *hwconfig_parse(const char *opts
, size_t maxlen
,
30 const char *opt
, char *stopchs
, char eqch
,
33 size_t optlen
= strlen(opt
);
35 const char *start
= opts
;
39 str
= strstr(opts
, opt
);
41 if (end
- start
> maxlen
)
44 if (str
&& (str
== opts
|| strpbrk(str
- 1, stopchs
) == str
- 1) &&
45 (strpbrk(end
, stopchs
) == end
|| *end
== eqch
||
55 arg_end
= strpbrk(str
, stopchs
);
57 *arglen
= min(maxlen
, strlen(str
)) - optlen
- 1;
59 *arglen
= arg_end
- end
- 1;
69 const char cpu_hwconfig
[] __attribute__((weak
)) = "";
70 const char board_hwconfig
[] __attribute__((weak
)) = "";
72 static const char *__hwconfig(const char *opt
, size_t *arglen
,
73 const char *env_hwconfig
)
77 /* if we are passed a buffer use it, otherwise try the environment */
79 if (!(gd
->flags
& GD_FLG_ENV_READY
)) {
80 printf("WARNING: Calling __hwconfig without a buffer "
81 "and before environment is ready\n");
84 env_hwconfig
= getenv("hwconfig");
88 ret
= hwconfig_parse(env_hwconfig
, strlen(env_hwconfig
),
89 opt
, ";", ':', arglen
);
94 ret
= hwconfig_parse(board_hwconfig
, strlen(board_hwconfig
),
95 opt
, ";", ':', arglen
);
99 return hwconfig_parse(cpu_hwconfig
, strlen(cpu_hwconfig
),
100 opt
, ";", ':', arglen
);
104 * hwconfig_f - query if a particular hwconfig option is specified
105 * @opt: a string representing an option
106 * @buf: if non-NULL use this buffer to parse, otherwise try env
108 * This call can be used to find out whether U-Boot should configure
109 * a particular hardware option.
111 * Returns non-zero value if the hardware option can be used and thus
112 * should be configured, 0 otherwise.
114 * This function also returns non-zero value if CONFIG_HWCONFIG is
117 * Returning non-zero value without CONFIG_HWCONFIG has its crucial
118 * purpose: the hwconfig() call should be a "transparent" interface,
119 * e.g. if a board doesn't need hwconfig facility, then we assume
120 * that the board file only calls things that are actually used, so
121 * hwconfig() will always return true result.
123 int hwconfig_f(const char *opt
, char *buf
)
125 return !!__hwconfig(opt
, NULL
, buf
);
129 * hwconfig_arg_f - get hwconfig option's argument
130 * @opt: a string representing an option
131 * @arglen: a pointer to an allocated size_t variable
132 * @buf: if non-NULL use this buffer to parse, otherwise try env
134 * Unlike hwconfig_f() function, this function returns a pointer to the
135 * start of the hwconfig arguments, if option is not found or it has
136 * no specified arguments, the function returns NULL pointer.
138 * If CONFIG_HWCONFIG is undefined, the function returns "", and
139 * arglen is set to 0.
141 const char *hwconfig_arg_f(const char *opt
, size_t *arglen
, char *buf
)
143 return __hwconfig(opt
, arglen
, buf
);
147 * hwconfig_arg_cmp_f - compare hwconfig option's argument
148 * @opt: a string representing an option
149 * @arg: a string for comparing an option's argument
150 * @buf: if non-NULL use this buffer to parse, otherwise try env
152 * This call is similar to hwconfig_arg_f, but instead of returning
153 * hwconfig argument and its length, it is comparing it to @arg.
155 * Returns non-zero value if @arg matches, 0 otherwise.
157 * If CONFIG_HWCONFIG is undefined, the function returns a non-zero
158 * value, i.e. the argument matches.
160 int hwconfig_arg_cmp_f(const char *opt
, const char *arg
, char *buf
)
165 argstr
= hwconfig_arg_f(opt
, &arglen
, buf
);
166 if (!argstr
|| arglen
!= strlen(arg
))
169 return !strncmp(argstr
, arg
, arglen
);
173 * hwconfig_sub_f - query if a particular hwconfig sub-option is specified
174 * @opt: a string representing an option
175 * @subopt: a string representing a sub-option
176 * @buf: if non-NULL use this buffer to parse, otherwise try env
178 * This call is similar to hwconfig_f(), except that it takes additional
179 * argument @subopt. In this example:
180 * "dr_usb:mode=peripheral"
181 * "dr_usb" is an option, "mode" is a sub-option, and "peripheral" is its
184 int hwconfig_sub_f(const char *opt
, const char *subopt
, char *buf
)
189 arg
= __hwconfig(opt
, &arglen
, buf
);
192 return !!hwconfig_parse(arg
, arglen
, subopt
, ",;", '=', NULL
);
196 * hwconfig_subarg_f - get hwconfig sub-option's argument
197 * @opt: a string representing an option
198 * @subopt: a string representing a sub-option
199 * @subarglen: a pointer to an allocated size_t variable
200 * @buf: if non-NULL use this buffer to parse, otherwise try env
202 * This call is similar to hwconfig_arg_f(), except that it takes an
203 * additional argument @subopt, and so works with sub-options.
205 const char *hwconfig_subarg_f(const char *opt
, const char *subopt
,
206 size_t *subarglen
, char *buf
)
211 arg
= __hwconfig(opt
, &arglen
, buf
);
214 return hwconfig_parse(arg
, arglen
, subopt
, ",;", '=', subarglen
);
218 * hwconfig_arg_cmp_f - compare hwconfig sub-option's argument
219 * @opt: a string representing an option
220 * @subopt: a string representing a sub-option
221 * @subarg: a string for comparing an sub-option's argument
222 * @buf: if non-NULL use this buffer to parse, otherwise try env
224 * This call is similar to hwconfig_arg_cmp_f, except that it takes an
225 * additional argument @subopt, and so works with sub-options.
227 int hwconfig_subarg_cmp_f(const char *opt
, const char *subopt
,
228 const char *subarg
, char *buf
)
233 argstr
= hwconfig_subarg_f(opt
, subopt
, &arglen
, buf
);
234 if (!argstr
|| arglen
!= strlen(subarg
))
237 return !strncmp(argstr
, subarg
, arglen
);
246 setenv("hwconfig", "key1:subkey1=value1,subkey2=value2;key2:value3;;;;"
247 "key3;:,:=;key4", 1);
249 ret
= hwconfig_arg("key1", &len
);
250 printf("%zd %.*s\n", len
, (int)len
, ret
);
252 assert(hwconfig_arg_cmp("key1", "subkey1=value1,subkey2=value2"));
253 assert(!strncmp(ret
, "subkey1=value1,subkey2=value2", len
));
255 ret
= hwconfig_subarg("key1", "subkey1", &len
);
256 printf("%zd %.*s\n", len
, (int)len
, ret
);
258 assert(hwconfig_subarg_cmp("key1", "subkey1", "value1"));
259 assert(!strncmp(ret
, "value1", len
));
261 ret
= hwconfig_subarg("key1", "subkey2", &len
);
262 printf("%zd %.*s\n", len
, (int)len
, ret
);
264 assert(hwconfig_subarg_cmp("key1", "subkey2", "value2"));
265 assert(!strncmp(ret
, "value2", len
));
267 ret
= hwconfig_arg("key2", &len
);
268 printf("%zd %.*s\n", len
, (int)len
, ret
);
270 assert(hwconfig_arg_cmp("key2", "value3"));
271 assert(!strncmp(ret
, "value3", len
));
273 assert(hwconfig("key3"));
274 assert(hwconfig_arg("key4", &len
) == NULL
);
275 assert(hwconfig_arg("bogus", &len
) == NULL
);
277 unsetenv("hwconfig");
279 assert(hwconfig(NULL
) == 0);
280 assert(hwconfig("") == 0);
281 assert(hwconfig("key3") == 0);
285 #endif /* HWCONFIG_TEST */