|
@@ -23,6 +23,7 @@
|
23
|
23
|
#include <string.h>
|
24
|
24
|
#include <errno.h>
|
25
|
25
|
#include <getopt.h>
|
|
26
|
+#include <byteswap.h>
|
26
|
27
|
#include <ipxe/settings.h>
|
27
|
28
|
#include <ipxe/command.h>
|
28
|
29
|
#include <ipxe/parseopt.h>
|
|
@@ -255,6 +256,73 @@ static int read_exec ( int argc, char **argv ) {
|
255
|
256
|
return set_core_exec ( argc, argv, &clear_read_cmd, read_value );
|
256
|
257
|
}
|
257
|
258
|
|
|
259
|
+/** "inc" options */
|
|
260
|
+struct inc_options {};
|
|
261
|
+
|
|
262
|
+/** "inc" option list */
|
|
263
|
+static struct option_descriptor inc_opts[] = {};
|
|
264
|
+
|
|
265
|
+/** "inc" command descriptor */
|
|
266
|
+static struct command_descriptor inc_cmd =
|
|
267
|
+ COMMAND_DESC ( struct inc_options, inc_opts, 1, 2,
|
|
268
|
+ "<setting> [<increment>]" );
|
|
269
|
+
|
|
270
|
+/**
|
|
271
|
+ * "inc" command
|
|
272
|
+ *
|
|
273
|
+ * @v argc Argument count
|
|
274
|
+ * @v argv Argument list
|
|
275
|
+ * @ret rc Return status code
|
|
276
|
+ */
|
|
277
|
+static int inc_exec ( int argc, char **argv ) {
|
|
278
|
+ struct inc_options opts;
|
|
279
|
+ struct named_setting setting;
|
|
280
|
+ unsigned int increment = 1;
|
|
281
|
+ unsigned long value;
|
|
282
|
+ int rc;
|
|
283
|
+
|
|
284
|
+ /* Parse options */
|
|
285
|
+ if ( ( rc = parse_options ( argc, argv, &inc_cmd, &opts ) ) != 0 )
|
|
286
|
+ goto err_parse_options;
|
|
287
|
+
|
|
288
|
+ /* Parse setting name */
|
|
289
|
+ if ( ( rc = parse_existing_setting ( argv[optind], &setting ) ) != 0 )
|
|
290
|
+ goto err_parse_setting;
|
|
291
|
+
|
|
292
|
+ /* Parse increment (if present) */
|
|
293
|
+ if ( ( ( optind + 1 ) < argc ) &&
|
|
294
|
+ ( ( rc = parse_integer ( argv[ optind + 1 ], &increment ) ) != 0))
|
|
295
|
+ goto err_parse_increment;
|
|
296
|
+
|
|
297
|
+ /* Fetch existing setting value, if any, allowing for the fact
|
|
298
|
+ * that numeric settings are big-endian and variable-length.
|
|
299
|
+ */
|
|
300
|
+ if ( ( rc = fetchn_setting ( setting.settings, &setting.setting,
|
|
301
|
+ &value ) ) != 0 ) {
|
|
302
|
+ /* Treat as a non-existent :int32 setting with a zero value */
|
|
303
|
+ value = 0;
|
|
304
|
+ if ( ! setting.setting.type )
|
|
305
|
+ setting.setting.type = &setting_type_int32;
|
|
306
|
+ }
|
|
307
|
+
|
|
308
|
+ /* Increment value */
|
|
309
|
+ value += increment;
|
|
310
|
+
|
|
311
|
+ /* Store updated setting value */
|
|
312
|
+ if ( ( rc = storen_setting ( setting.settings, &setting.setting,
|
|
313
|
+ value ) ) != 0 ) {
|
|
314
|
+ printf ( "Could not store \"%s\": %s\n",
|
|
315
|
+ setting.setting.name, strerror ( rc ) );
|
|
316
|
+ goto err_store;
|
|
317
|
+ }
|
|
318
|
+
|
|
319
|
+ err_store:
|
|
320
|
+ err_parse_increment:
|
|
321
|
+ err_parse_setting:
|
|
322
|
+ err_parse_options:
|
|
323
|
+ return rc;
|
|
324
|
+}
|
|
325
|
+
|
258
|
326
|
/** Non-volatile option commands */
|
259
|
327
|
struct command nvo_commands[] __command = {
|
260
|
328
|
{
|
|
@@ -273,4 +341,8 @@ struct command nvo_commands[] __command = {
|
273
|
341
|
.name = "read",
|
274
|
342
|
.exec = read_exec,
|
275
|
343
|
},
|
|
344
|
+ {
|
|
345
|
+ .name = "inc",
|
|
346
|
+ .exec = inc_exec,
|
|
347
|
+ },
|
276
|
348
|
};
|