2 * Copyright (C) 2010 Piotr JaroszyĆski <p.jaroszynski@gmail.com>
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 FILE_LICENCE(GPL2_OR_LATER);
21 #include <hci/linux_args.h>
25 #include <ipxe/settings.h>
26 #include <ipxe/linux.h>
27 #include <ipxe/malloc.h>
28 #include <ipxe/init.h>
31 static int saved_argc = 0;
33 static char ** saved_argv;
36 * Save argc and argv for later access.
38 * To be called by linuxprefix
40 __asmcall void save_args(int argc, char **argv)
46 /** Supported command-line options */
47 static struct option options[] = {
48 {"net", 1, NULL, 'n'},
49 {"settings", 1, NULL, 's'},
54 * Parse k1=v1[,k2=v2]* into linux_settings
56 static int parse_kv(char *kv, struct list_head *list)
61 struct linux_setting *setting;
63 while ((token = strsep(&kv, ",")) != NULL) {
64 name = strsep(&token, "=");
69 DBG("Bad parameter: '%s'\n", name);
73 setting = malloc(sizeof(*setting));
79 setting->value = value;
81 list_add(&setting->list, list);
88 * Parse --net arguments
90 * Format is --net driver_name[,name=value]*
92 static int parse_net_args(char *args)
95 struct linux_device_request *dev_request;
98 driver = strsep(&args, ",");
100 if (strlen(driver) == 0) {
101 printf("Missing driver name");
105 dev_request = malloc(sizeof(*dev_request));
107 dev_request->driver = driver;
108 INIT_LIST_HEAD(&dev_request->settings);
109 list_add_tail(&dev_request->list, &linux_device_requests);
111 /* Parse rest of the settings */
112 rc = parse_kv(args, &dev_request->settings);
115 printf("Parsing net settings failed");
121 * Parse --settings arguments
123 * Format is --settings name=value[,name=value]*
125 static int parse_settings_args(char *args)
127 return parse_kv(args, &linux_global_settings);
131 /** Parse passed command-line arguments */
132 void linux_args_parse()
139 int option_index = 0;
141 c = getopt_long(saved_argc, saved_argv, "", options, &option_index);
147 if ((rc = parse_net_args(optarg)) != 0)
151 if ((rc = parse_settings_args(optarg)) != 0)
162 /** Clean up requests and settings */
163 void linux_args_cleanup(int flags __unused)
165 struct linux_device_request *request;
166 struct linux_device_request *rtmp;
167 struct linux_setting *setting;
168 struct linux_setting *stmp;
170 /* Clean up requests and their settings */
171 list_for_each_entry_safe(request, rtmp, &linux_device_requests, list) {
172 list_for_each_entry_safe(setting, stmp, &request->settings, list) {
173 list_del(&setting->list);
176 list_del(&request->list);
180 /* Clean up global settings */
181 list_for_each_entry_safe(setting, stmp, &linux_global_settings, list) {
182 list_del(&setting->list);
187 struct startup_fn startup_linux_args __startup_fn(STARTUP_EARLY) = {
188 .startup = linux_args_parse,
189 .shutdown = linux_args_cleanup,