summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-01-22 09:49:21 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2018-01-22 09:49:21 +0100
commit5ebdae4863f64a32826c25c6e0d1dfbc1612d904 (patch)
treef7c8ae79050fd00a708bfcda11f6681ebb9a32ce
parent034637fbd9dfc5cbcffca1f8f392c6ab0dd6f229 (diff)
parent2f9b25f41362e99e2b31684b5c9a1a02abc1ae8b (diff)
downloadbarebox-5ebdae4863f64a32826c25c6e0d1dfbc1612d904.tar.gz
barebox-5ebdae4863f64a32826c25c6e0d1dfbc1612d904.tar.xz
Merge branch 'for-next/misc'
-rw-r--r--commands/mmc_extcsd.c2
-rw-r--r--commands/usbgadget.c14
-rw-r--r--common/bootm.c9
-rw-r--r--common/env.c54
-rw-r--r--common/image-fit.c77
-rw-r--r--common/misc.c7
-rw-r--r--common/partitions/dos.c25
-rw-r--r--common/ubiformat.c18
-rw-r--r--drivers/efi/Kconfig1
-rw-r--r--drivers/mci/mci-core.c16
-rw-r--r--drivers/of/base.c32
-rw-r--r--fs/Makefile2
-rw-r--r--fs/fs.c3
-rw-r--r--fs/nfs.c3
-rw-r--r--fs/parseopt.c60
-rw-r--r--fs/parseopt.h2
-rw-r--r--include/common.h3
-rw-r--r--include/image-fit.h8
-rw-r--r--include/linux/kernel.h1
-rw-r--r--include/linux/string.h3
-rw-r--r--include/mci.h3
-rw-r--r--include/of.h1
-rw-r--r--include/parseopt.h9
-rw-r--r--lib/Makefile1
-rw-r--r--lib/libscan.c9
-rw-r--r--lib/misc.c35
-rw-r--r--lib/parseopt.c124
-rw-r--r--lib/string.c20
28 files changed, 387 insertions, 155 deletions
diff --git a/commands/mmc_extcsd.c b/commands/mmc_extcsd.c
index 7a6d39075d..acd23a466b 100644
--- a/commands/mmc_extcsd.c
+++ b/commands/mmc_extcsd.c
@@ -2357,7 +2357,7 @@ static void write_field(struct mci *mci, u8 *reg, u16 index, u8 value,
break;
}
- mci_switch(mci, 0, index, value);
+ mci_switch(mci, index, value);
out:
return;
diff --git a/commands/usbgadget.c b/commands/usbgadget.c
index 507871edd2..a1744cbe13 100644
--- a/commands/usbgadget.c
+++ b/commands/usbgadget.c
@@ -119,13 +119,13 @@ BAREBOX_CMD_HELP_START(usbgadget)
BAREBOX_CMD_HELP_TEXT("Enable / disable a USB composite gadget on the USB device interface.")
BAREBOX_CMD_HELP_TEXT("")
BAREBOX_CMD_HELP_TEXT("Options:")
-BAREBOX_CMD_HELP_OPT ("-a", "Create CDC ACM function")
-BAREBOX_CMD_HELP_OPT ("-s", "Create Generic Serial function")
-BAREBOX_CMD_HELP_OPT ("-A [desc]", "Create Android Fastboot function. If 'desc' is not provided,")
-BAREBOX_CMD_HELP_OPT ("", "trying to use 'global.usbgadget.fastboot_function' variable.")
-BAREBOX_CMD_HELP_OPT ("-b", "include registered barebox update handlers (fastboot specific)")
-BAREBOX_CMD_HELP_OPT ("-D <desc>", "Create DFU function")
-BAREBOX_CMD_HELP_OPT ("-d", "Disable the currently running gadget")
+BAREBOX_CMD_HELP_OPT ("-a\t", "Create CDC ACM function")
+BAREBOX_CMD_HELP_OPT ("-s\t", "Create Generic Serial function")
+BAREBOX_CMD_HELP_OPT ("-A <desc>", "Create Android Fastboot function. If 'desc' is not provided, "
+ "try to use 'global.usbgadget.fastboot_function' variable.")
+BAREBOX_CMD_HELP_OPT ("-b\t", "include registered barebox update handlers (fastboot specific)")
+BAREBOX_CMD_HELP_OPT ("-D <desc>", "Create DFU function")
+BAREBOX_CMD_HELP_OPT ("-d\t", "Disable the currently running gadget")
BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(usbgadget)
diff --git a/common/bootm.c b/common/bootm.c
index c23898bea7..05314a0a10 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -568,7 +568,7 @@ int bootm_boot(struct bootm_data *bootm_data)
if (IS_ENABLED(CONFIG_FITIMAGE) && os_type == filetype_oftree) {
struct fit_handle *fit;
- fit = fit_open(data->os_file, data->os_part, data->verbose, data->verify);
+ fit = fit_open(data->os_file, data->verbose, data->verify);
if (IS_ERR(fit)) {
printf("Loading FIT image %s failed with: %s\n", data->os_file,
strerrorp(fit));
@@ -577,6 +577,13 @@ int bootm_boot(struct bootm_data *bootm_data)
}
data->os_fit = fit;
+
+ ret = fit_open_configuration(data->os_fit, data->os_part);
+ if (ret) {
+ printf("Cannot open FIT image configuration '%s'\n",
+ data->os_part ? data->os_part : "default");
+ goto err_out;
+ }
}
if (os_type == filetype_uimage) {
diff --git a/common/env.c b/common/env.c
index df8a4dff60..80d3f7ab50 100644
--- a/common/env.c
+++ b/common/env.c
@@ -223,34 +223,50 @@ static int setenv_raw(struct list_head *l, const char *name, const char *value)
return 0;
}
-int setenv(const char *_name, const char *value)
+static int dev_setenv(const char *name, const char *val)
{
- char *name = strdup(_name);
- char *par;
- int ret = 0;
- struct list_head *list;
+ const char *pos, *dot, *varname;
+ char *devname;
+ struct device_d *dev;
- if (value && !*value)
- value = NULL;
+ pos = name;
+
+ while (1) {
+ dot = strchr(pos, '.');
+ if (!dot)
+ break;
+
+ devname = xstrndup(name, dot - name);
+ varname = dot + 1;
+ dev = get_device_by_name(devname);
- if ((par = strchr(name, '.'))) {
- struct device_d *dev;
+ free(devname);
- *par++ = 0;
- dev = get_device_by_name(name);
if (dev) {
- ret = dev_set_param(dev, par, value);
- if (ret)
- eprintf("%s: set parameter %s: %s\n",
- dev_name(dev), par, strerror(-ret));
- } else {
- ret = -ENODEV;
- eprintf("set parameter: no such device %s\n", name);
+ if (get_param_by_name(dev, varname))
+ return dev_set_param(dev, varname, val);
}
- errno = -ret;
+ pos = dot + 1;
+ }
+
+ return -ENODEV;
+}
+
+int setenv(const char *_name, const char *value)
+{
+ char *name = strdup(_name);
+ int ret = 0;
+ struct list_head *list;
+
+ if (value && !*value)
+ value = NULL;
+ if (strchr(name, '.')) {
+ ret = dev_setenv(name, value);
+ if (ret)
+ eprintf("Cannot set parameter: %s\n", strerror(-ret));
goto out;
}
diff --git a/common/image-fit.c b/common/image-fit.c
index db5d142147..12379a67ff 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -397,14 +397,37 @@ err_digest_free:
return ret;
}
-static int fit_open_image(struct fit_handle *handle, const char *unit, const void **outdata,
- unsigned long *outsize)
+int fit_has_image(struct fit_handle *handle, const char *name)
+{
+ const char *unit;
+ struct device_node *conf_node = handle->conf_node;
+
+ if (!conf_node)
+ return -EINVAL;
+
+ if (of_property_read_string(conf_node, name, &unit))
+ return 0;
+
+ return 1;
+}
+
+int fit_open_image(struct fit_handle *handle, const char *name,
+ const void **outdata, unsigned long *outsize)
{
struct device_node *image = NULL, *hash;
- const char *type = NULL, *desc= "(no description)";
+ const char *unit, *type = NULL, *desc= "(no description)";
const void *data;
int data_len;
int ret = 0;
+ struct device_node *conf_node = handle->conf_node;
+
+ if (!conf_node)
+ return -EINVAL;
+
+ if (of_property_read_string(conf_node, name, &unit)) {
+ pr_err("No image named '%s'\n", name);
+ return -ENOENT;
+ }
image = of_get_child_by_name(handle->root, "images");
if (!image)
@@ -523,7 +546,7 @@ default_unit:
return -ENOENT;
}
-static int fit_open_configuration(struct fit_handle *handle, const char *name)
+int fit_open_configuration(struct fit_handle *handle, const char *name)
{
struct device_node *conf_node = NULL;
const char *unit, *desc = "(no description)";
@@ -556,22 +579,25 @@ static int fit_open_configuration(struct fit_handle *handle, const char *name)
if (ret)
return ret;
- if (of_property_read_string(conf_node, "kernel", &unit) == 0) {
- ret = fit_open_image(handle, unit, &handle->kernel, &handle->kernel_size);
+ handle->conf_node = conf_node;
+
+ if (fit_has_image(handle, "kernel")) {
+ ret = fit_open_image(handle, "kernel", &handle->kernel,
+ &handle->kernel_size);
if (ret)
return ret;
- } else {
- return -ENOENT;
}
- if (of_property_read_string(conf_node, "fdt", &unit) == 0) {
- ret = fit_open_image(handle, unit, &handle->oftree, &handle->oftree_size);
+ if (fit_has_image(handle, "ramdisk")) {
+ ret = fit_open_image(handle, "ramdisk", &handle->initrd,
+ &handle->initrd_size);
if (ret)
return ret;
}
- if (of_property_read_string(conf_node, "ramdisk", &unit) == 0) {
- ret = fit_open_image(handle, unit, &handle->initrd, &handle->initrd_size);
+ if (fit_has_image(handle, "fdt")) {
+ ret = fit_open_image(handle, "fdt", &handle->oftree,
+ &handle->oftree_size);
if (ret)
return ret;
}
@@ -579,7 +605,7 @@ static int fit_open_configuration(struct fit_handle *handle, const char *name)
return 0;
}
-struct fit_handle *fit_open(const char *filename, const char *config, bool verbose,
+struct fit_handle *fit_open(const char *filename, bool verbose,
enum bootm_verify verify)
{
struct fit_handle *handle = NULL;
@@ -609,10 +635,6 @@ struct fit_handle *fit_open(const char *filename, const char *config, bool verbo
of_property_read_string(handle->root, "description", &desc);
pr_info("'%s': %s\n", filename, desc);
- ret = fit_open_configuration(handle, config);
- if (ret)
- goto err;
-
return handle;
err:
if (handle->root)
@@ -636,10 +658,23 @@ void fit_close(struct fit_handle *handle)
static int do_bootm_sandbox_fit(struct image_data *data)
{
struct fit_handle *handle;
- handle = fit_open(data->os_file, data->os_part, data->verbose);
- if (handle)
- fit_close(handle);
- return 0;
+ int ret;
+ void *kernel;
+ unsigned long kernel_size;
+
+ handle = fit_open(data->os_file, data->verbose);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+
+ ret = fit_open_configuration(handle, data->os_part);
+ if (ret)
+ goto out;
+
+ ret = 0;
+out:
+ fit_close(handle);
+
+ return ret;
}
static struct image_handler sandbox_fit_handler = {
diff --git a/common/misc.c b/common/misc.c
index c5d3704c82..0888f1f4f6 100644
--- a/common/misc.c
+++ b/common/misc.c
@@ -187,6 +187,13 @@ const char *barebox_get_hostname(void)
}
EXPORT_SYMBOL(barebox_get_hostname);
+void barebox_set_hostname_no_overwrite(const char *__hostname)
+{
+ if (!barebox_get_hostname())
+ barebox_set_hostname(__hostname);
+}
+EXPORT_SYMBOL(barebox_set_hostname_no_overwrite);
+
BAREBOX_MAGICVAR_NAMED(global_hostname, global.hostname,
"shortname of the board. Also used as hostname for DHCP requests");
diff --git a/common/partitions/dos.c b/common/partitions/dos.c
index 91b5399079..488c2936f7 100644
--- a/common/partitions/dos.c
+++ b/common/partitions/dos.c
@@ -21,6 +21,22 @@
#include "parser.h"
+
+enum {
+/* These three have identical behaviour; use the second one if DOS FDISK gets
+ confused about extended/logical partitions starting past cylinder 1023. */
+ DOS_EXTENDED_PARTITION = 5,
+ LINUX_EXTENDED_PARTITION = 0x85,
+ WIN98_EXTENDED_PARTITION = 0x0f,
+};
+
+static inline int is_extended_partition(struct partition *p)
+{
+ return (p->dos_partition_type == DOS_EXTENDED_PARTITION ||
+ p->dos_partition_type == WIN98_EXTENDED_PARTITION ||
+ p->dos_partition_type == LINUX_EXTENDED_PARTITION);
+}
+
/**
* Guess the size of the disk, based on the partition table entries
* @param dev device to create partitions for
@@ -212,13 +228,8 @@ static void dos_partition(void *buf, struct block_device *blk,
sprintf(pd->parts[n].partuuid, "%08x-%02d",
signature, i + 1);
pd->used_entries++;
- /*
- * Partitions of type 0x05 and 0x0f (and some more)
- * contain extended partitions. Only check for type 0x0f
- * here as this is the easiest to parse and common
- * enough.
- */
- if (pentry.dos_partition_type == 0x0f) {
+
+ if (is_extended_partition(&pentry)) {
if (!extended_partition)
extended_partition = &pd->parts[n];
else
diff --git a/common/ubiformat.c b/common/ubiformat.c
index 4c5f1f5794..f728119b9a 100644
--- a/common/ubiformat.c
+++ b/common/ubiformat.c
@@ -190,6 +190,7 @@ static int flash_image(struct ubiformat_args *args, struct mtd_info *mtd,
int fd, img_ebs, eb, written_ebs = 0, ret = -1, eb_cnt;
off_t st_size;
char *buf = NULL;
+ uint64_t lastprint = 0;
eb_cnt = mtd_num_pebs(mtd);
@@ -229,8 +230,12 @@ static int flash_image(struct ubiformat_args *args, struct mtd_info *mtd,
long long ec;
if (!args->quiet && !args->verbose) {
- printf("\rubiformat: flashing eraseblock %d -- %2u %% complete ",
- eb, (eb + 1) * 100 / eb_cnt);
+ if (is_timeout(lastprint, 300 * MSECOND) ||
+ eb == eb_cnt - 1) {
+ printf("\rubiformat: flashing eraseblock %d -- %2u %% complete ",
+ eb, (eb + 1) * 100 / eb_cnt);
+ lastprint = get_time_ns();
+ }
}
if (si->ec[eb] == EB_BAD)
@@ -325,6 +330,7 @@ static int format(struct ubiformat_args *args, struct mtd_info *mtd,
struct ubi_vtbl_record *vtbl;
int eb1 = -1, eb2 = -1;
long long ec1 = -1, ec2 = -1;
+ uint64_t lastprint = 0;
eb_cnt = mtd_num_pebs(mtd);
@@ -340,8 +346,12 @@ static int format(struct ubiformat_args *args, struct mtd_info *mtd,
long long ec;
if (!args->quiet && !args->verbose) {
- printf("\rubiformat: formatting eraseblock %d -- %2u %% complete ",
- eb, (eb + 1 - start_eb) * 100 / (eb_cnt - start_eb));
+ if (is_timeout(lastprint, 300 * MSECOND) ||
+ eb == eb_cnt - 1) {
+ printf("\rubiformat: formatting eraseblock %d -- %2u %% complete ",
+ eb, (eb + 1 - start_eb) * 100 / (eb_cnt - start_eb));
+ lastprint = get_time_ns();
+ }
}
if (si->ec[eb] == EB_BAD)
diff --git a/drivers/efi/Kconfig b/drivers/efi/Kconfig
index d6beeb07ce..cca1a2e1d6 100644
--- a/drivers/efi/Kconfig
+++ b/drivers/efi/Kconfig
@@ -1,5 +1,4 @@
config EFI_BOOTUP
bool
- select HAS_POWEROFF
select BLOCK
select PARTITION_DISK
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 208b7666d6..c6b4e02cbc 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -396,8 +396,7 @@ int mci_send_ext_csd(struct mci *mci, char *ext_csd)
* @param value FIXME
* @return Transaction status (0 on success)
*/
-int mci_switch(struct mci *mci, unsigned set, unsigned index,
- unsigned value)
+int mci_switch(struct mci *mci, unsigned index, unsigned value)
{
struct mci_cmd cmd;
@@ -471,7 +470,7 @@ static int mmc_change_freq(struct mci *mci)
cardtype = mci->ext_csd[EXT_CSD_DEVICE_TYPE] & EXT_CSD_CARD_TYPE_MASK;
- err = mci_switch(mci, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
+ err = mci_switch(mci, EXT_CSD_HS_TIMING, 1);
if (err) {
dev_dbg(&mci->dev, "MMC frequency changing failed: %d\n", err);
@@ -1044,9 +1043,7 @@ static int mci_startup_mmc(struct mci *mci)
* 4bit transfer mode. On success set the corresponding
* bus width on the host.
*/
- err = mci_switch(mci, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_BUS_WIDTH,
- ext_csd_bits[idx]);
+ err = mci_switch(mci, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx]);
if (err) {
if (idx == 0)
dev_warn(&mci->dev, "Changing MMC bus width failed: %d\n", err);
@@ -1253,8 +1250,7 @@ static int mci_blk_part_switch(struct mci_part *part)
part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
part_config |= part->part_cfg;
- ret = mci_switch(mci, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_PARTITION_CONFIG, part_config);
+ ret = mci_switch(mci, EXT_CSD_PARTITION_CONFIG, part_config);
if (ret)
return ret;
@@ -1568,8 +1564,8 @@ static int mci_set_boot(struct param_d *param, void *priv)
mci->ext_csd_part_config &= ~(7 << 3);
mci->ext_csd_part_config |= mci->bootpart << 3;
- return mci_switch(mci, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_PARTITION_CONFIG, mci->ext_csd_part_config);
+ return mci_switch(mci,
+ EXT_CSD_PARTITION_CONFIG, mci->ext_csd_part_config);
}
static const char *mci_boot_names[] = {
diff --git a/drivers/of/base.c b/drivers/of/base.c
index eabbf3d957..6a582177bf 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2360,3 +2360,35 @@ int of_graph_port_is_available(struct device_node *node)
return available;
}
EXPORT_SYMBOL(of_graph_port_is_available);
+
+/**
+ * of_get_machine_compatible - get first compatible string from the root node.
+ *
+ * Returns the string or NULL.
+ */
+const char *of_get_machine_compatible(void)
+{
+ struct property *prop;
+ const char *name, *p;
+
+ if (!root_node)
+ return NULL;
+
+ prop = of_find_property(root_node, "compatible", NULL);
+ name = of_prop_next_string(prop, NULL);
+
+ p = strchr(name, ',');
+ return p ? p + 1 : name;
+}
+EXPORT_SYMBOL(of_get_machine_compatible);
+
+static int of_init_hostname(void)
+{
+ const char *name;
+
+ name = of_get_machine_compatible();
+ barebox_set_hostname_no_overwrite(name ?: "barebox");
+
+ return 0;
+}
+late_initcall(of_init_hostname);
diff --git a/fs/Makefile b/fs/Makefile
index b3f929f506..8e3fd78e92 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_FS_RAMFS) += ramfs.o
obj-y += devfs-core.o
obj-$(CONFIG_FS_DEVFS) += devfs.o
obj-$(CONFIG_FS_FAT) += fat/
-obj-y += fs.o parseopt.o
+obj-y += fs.o
obj-$(CONFIG_FS_UBIFS) += ubifs/
obj-$(CONFIG_FS_TFTP) += tftp.o
obj-$(CONFIG_FS_OMAP4_USBBOOT) += omap4_usbbootfs.o
diff --git a/fs/fs.c b/fs/fs.c
index 051af8d19f..6f15e93ba9 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -35,8 +35,7 @@
#include <libgen.h>
#include <block.h>
#include <libfile.h>
-
-#include "parseopt.h"
+#include <parseopt.h>
char *mkmodestr(unsigned long mode, char *str)
{
diff --git a/fs/nfs.c b/fs/nfs.c
index 97f01cfb34..75cd127eeb 100644
--- a/fs/nfs.c
+++ b/fs/nfs.c
@@ -36,8 +36,7 @@
#include <linux/sizes.h>
#include <byteorder.h>
#include <globalvar.h>
-
-#include "parseopt.h"
+#include <parseopt.h>
#define SUNRPC_PORT 111
diff --git a/fs/parseopt.c b/fs/parseopt.c
deleted file mode 100644
index 8ff83019a7..0000000000
--- a/fs/parseopt.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <common.h>
-
-#include "parseopt.h"
-
-void parseopt_b(const char *options, const char *opt, bool *val)
-{
- const char *start;
- size_t optlen = strlen(opt);
-
-again:
- start = strstr(options, opt);
-
- if (!start) {
- *val = false;
- return;
- }
-
- if (start > options && start[-1] != ',') {
- options = start;
- goto again;
- }
-
- if (start[optlen] != ',' && start[optlen] != '\0') {
- options = start;
- goto again;
- }
-
- *val = true;
-}
-
-void parseopt_hu(const char *options, const char *opt, unsigned short *val)
-{
- const char *start;
- size_t optlen = strlen(opt);
- ulong v;
- char *endp;
-
-again:
- start = strstr(options, opt);
-
- if (!start)
- return;
-
- if (start > options && start[-1] != ',') {
- options = start;
- goto again;
- }
-
- if (start[optlen] != '=') {
- options = start;
- goto again;
- }
-
- v = simple_strtoul(start + optlen + 1, &endp, 0);
- if (v > USHRT_MAX)
- return;
-
- if (*endp == ',' || *endp == '\0')
- *val = v;
-}
diff --git a/fs/parseopt.h b/fs/parseopt.h
deleted file mode 100644
index abf3be3f35..0000000000
--- a/fs/parseopt.h
+++ /dev/null
@@ -1,2 +0,0 @@
-void parseopt_b(const char *options, const char *opt, bool *val);
-void parseopt_hu(const char *options, const char *opt, unsigned short *val);
diff --git a/include/common.h b/include/common.h
index dd7445e9b6..60e5005b8e 100644
--- a/include/common.h
+++ b/include/common.h
@@ -93,8 +93,6 @@ extern int (*barebox_main)(void);
void __noreturn start_barebox(void);
void shutdown_barebox(void);
-#define ALIGN_DOWN(x, a) ((x) & ~((typeof(x))(a) - 1))
-
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
/*
@@ -139,6 +137,7 @@ const char *barebox_get_model(void);
void barebox_set_model(const char *);
const char *barebox_get_hostname(void);
void barebox_set_hostname(const char *);
+void barebox_set_hostname_no_overwrite(const char *);
#if defined(CONFIG_MIPS)
#include <asm/addrspace.h>
diff --git a/include/image-fit.h b/include/image-fit.h
index c49f958268..62f44dcc8d 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -29,6 +29,7 @@ struct fit_handle {
enum bootm_verify verify;
struct device_node *root;
+ struct device_node *conf_node;
const void *kernel;
unsigned long kernel_size;
@@ -38,8 +39,13 @@ struct fit_handle {
unsigned long initrd_size;
};
-struct fit_handle *fit_open(const char *filename, const char *config, bool verbose,
+struct fit_handle *fit_open(const char *filename, bool verbose,
enum bootm_verify verify);
+int fit_open_configuration(struct fit_handle *handle, const char *name);
+int fit_has_image(struct fit_handle *handle, const char *name);
+int fit_open_image(struct fit_handle *handle, const char *name,
+ const void **outdata, unsigned long *outsize);
+
void fit_close(struct fit_handle *handle);
#endif /* __IMAGE_FIT_H__ */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index b4d2f09081..ab713f20e9 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -33,6 +33,7 @@
#define S64_MIN ((s64)(-S64_MAX - 1))
#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1)
+#define ALIGN_DOWN(x, a) ALIGN((x) - ((a) - 1), (a))
#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
diff --git a/include/linux/string.h b/include/linux/string.h
index 5df8c50e57..ed4eeb5519 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -80,6 +80,9 @@ extern __kernel_size_t strnlen(const char *,__kernel_size_t);
#ifndef __HAVE_ARCH_STRDUP
extern char * strdup(const char *);
#endif
+#ifndef __HAVE_ARCH_STRNDUP
+extern char *strndup(const char *, size_t);
+#endif
#ifndef __HAVE_ARCH_STRSWAB
extern char * strswab(const char *);
#endif
diff --git a/include/mci.h b/include/mci.h
index 1f6533391a..072008ef9d 100644
--- a/include/mci.h
+++ b/include/mci.h
@@ -478,8 +478,7 @@ void mci_of_parse(struct mci_host *host);
void mci_of_parse_node(struct mci_host *host, struct device_node *np);
int mci_detect_card(struct mci_host *);
int mci_send_ext_csd(struct mci *mci, char *ext_csd);
-int mci_switch(struct mci *mci, unsigned set, unsigned index,
- unsigned value);
+int mci_switch(struct mci *mci, unsigned index, unsigned value);
static inline int mmc_host_is_spi(struct mci_host *host)
{
diff --git a/include/of.h b/include/of.h
index 9bdbbb5ed2..1b9719d603 100644
--- a/include/of.h
+++ b/include/of.h
@@ -148,6 +148,7 @@ extern struct device_node *of_copy_node(struct device_node *parent,
const struct device_node *other);
extern void of_delete_node(struct device_node *node);
+extern const char *of_get_machine_compatible(void);
extern int of_machine_is_compatible(const char *compat);
extern int of_device_is_compatible(const struct device_node *device,
const char *compat);
diff --git a/include/parseopt.h b/include/parseopt.h
new file mode 100644
index 0000000000..1f9763f8c9
--- /dev/null
+++ b/include/parseopt.h
@@ -0,0 +1,9 @@
+#ifndef __PARSEOPT_H__
+#define __PARSEOPT_H__
+
+void parseopt_b(const char *options, const char *opt, bool *val);
+void parseopt_hu(const char *options, const char *opt, unsigned short *val);
+void parseopt_u16(const char *options, const char *opt, uint16_t *val);
+void parseopt_str(const char *options, const char *opt, char **val);
+
+#endif /* __PARSEOPT_H__ */
diff --git a/lib/Makefile b/lib/Makefile
index 0d5ac6586c..66c59fe15e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -60,3 +60,4 @@ obj-y += reed_solomon/
obj-$(CONFIG_RATP) += ratp.o
obj-y += list_sort.o
obj-y += int_sqrt.o
+obj-y += parseopt.o
diff --git a/lib/libscan.c b/lib/libscan.c
index 74a24b5011..c4139e69d1 100644
--- a/lib/libscan.c
+++ b/lib/libscan.c
@@ -39,6 +39,7 @@ int libscan_ubi_scan(struct mtd_info *mtd, struct ubi_scan_info **info,
int eb, v = (verbose == 2), pr = (verbose == 1), eb_cnt;
struct ubi_scan_info *si;
unsigned long long sum = 0;
+ uint64_t lastprint = 0;
eb_cnt = mtd_div_by_eb(mtd->size, mtd);
@@ -66,8 +67,12 @@ int libscan_ubi_scan(struct mtd_info *mtd, struct ubi_scan_info **info,
if (v)
normsg_cont("scanning eraseblock %d", eb);
if (pr) {
- printf("\r" PROGRAM_NAME ": scanning eraseblock %d -- %2u %% complete ",
- eb, (eb + 1) * 100 / eb_cnt);
+ if (is_timeout(lastprint, 300 * MSECOND) ||
+ eb == eb_cnt - 1) {
+ printf("\r" PROGRAM_NAME ": scanning eraseblock %d -- %2u %% complete ",
+ eb, (eb + 1) * 100 / eb_cnt);
+ lastprint = get_time_ns();
+ }
}
ret = mtd_peb_is_bad(mtd, eb);
diff --git a/lib/misc.c b/lib/misc.c
index 62ddd66779..1d20e1b092 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -79,38 +79,53 @@ EXPORT_SYMBOL(strtoul_suffix);
int parse_area_spec(const char *str, loff_t *start, loff_t *size)
{
char *endp;
- loff_t end;
+ loff_t end, _start, _size;
if (!isdigit(*str))
return -1;
- *start = strtoull_suffix(str, &endp, 0);
+ _start = strtoull_suffix(str, &endp, 0);
str = endp;
if (!*str) {
/* beginning given, but no size, assume maximum size */
- *size = ~0;
- return 0;
+ _size = ~0;
+ goto success;
}
if (*str == '-') {
/* beginning and end given */
- end = strtoull_suffix(str + 1, NULL, 0);
- if (end < *start) {
+ if (!isdigit(*(str + 1)))
+ return -1;
+
+ end = strtoull_suffix(str + 1, &endp, 0);
+ str = endp;
+ if (end < _start) {
printf("end < start\n");
return -1;
}
- *size = end - *start + 1;
- return 0;
+ _size = end - _start + 1;
+ goto success;
}
if (*str == '+') {
/* beginning and size given */
- *size = strtoull_suffix(str + 1, NULL, 0);
- return 0;
+ if (!isdigit(*(str + 1)))
+ return -1;
+
+ _size = strtoull_suffix(str + 1, &endp, 0);
+ str = endp;
+ goto success;
}
return -1;
+
+success:
+ if (*str && !isspace(*str))
+ return -1;
+ *start = _start;
+ *size = _size;
+ return 0;
}
EXPORT_SYMBOL(parse_area_spec);
diff --git a/lib/parseopt.c b/lib/parseopt.c
new file mode 100644
index 0000000000..8211733e3b
--- /dev/null
+++ b/lib/parseopt.c
@@ -0,0 +1,124 @@
+#include <common.h>
+
+#include "parseopt.h"
+
+void parseopt_b(const char *options, const char *opt, bool *val)
+{
+ const char *start;
+ size_t optlen = strlen(opt);
+
+again:
+ start = strstr(options, opt);
+
+ if (!start) {
+ *val = false;
+ return;
+ }
+
+ if (start > options && start[-1] != ',') {
+ options = start;
+ goto again;
+ }
+
+ if (start[optlen] != ',' && start[optlen] != '\0') {
+ options = start;
+ goto again;
+ }
+
+ *val = true;
+}
+
+void parseopt_hu(const char *options, const char *opt, unsigned short *val)
+{
+ const char *start;
+ size_t optlen = strlen(opt);
+ ulong v;
+ char *endp;
+
+again:
+ start = strstr(options, opt);
+
+ if (!start)
+ return;
+
+ if (start > options && start[-1] != ',') {
+ options = start;
+ goto again;
+ }
+
+ if (start[optlen] != '=') {
+ options = start;
+ goto again;
+ }
+
+ v = simple_strtoul(start + optlen + 1, &endp, 0);
+ if (v > USHRT_MAX)
+ return;
+
+ if (*endp == ',' || *endp == '\0')
+ *val = v;
+}
+
+void parseopt_u16(const char *options, const char *opt, uint16_t *val)
+{
+ const char *start;
+ size_t optlen = strlen(opt);
+ ulong v;
+ char *endp;
+
+again:
+ start = strstr(options, opt);
+
+ if (!start)
+ return;
+
+ if (start > options && start[-1] != ',') {
+ options = start;
+ goto again;
+ }
+
+ if (start[optlen] != '=') {
+ options = start;
+ goto again;
+ }
+
+ v = simple_strtoul(start + optlen + 1, &endp, 0);
+ if (v > U16_MAX)
+ return;
+
+ if (*endp == ',' || *endp == '\0')
+ *val = v;
+}
+
+void parseopt_str(const char *options, const char *opt, char **val)
+{
+ const char *start;
+ size_t optlen = strlen(opt);
+ char *endp;
+ char *parsed;
+
+again:
+ start = strstr(options, opt);
+
+ if (!start)
+ return;
+
+ if (start > options && start[-1] != ',') {
+ options = start;
+ goto again;
+ }
+
+ if (start[optlen] != '=') {
+ options = start;
+ goto again;
+ }
+
+ parsed = (char *)start + optlen + 1;
+ endp = parsed;
+ while (*endp != '\0' && *endp != ',') {
+
+ endp++;
+ }
+
+ *val = xstrndup(parsed, endp - parsed);
+}
diff --git a/lib/string.c b/lib/string.c
index 1d491c9c2f..f588933e81 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -323,6 +323,26 @@ char * strdup(const char *s)
#endif
EXPORT_SYMBOL(strdup);
+#ifndef __HAVE_ARCH_STRNDUP
+char *strndup(const char *s, size_t n)
+{
+ char *new;
+ size_t len = strnlen(s, n);
+
+ if ((s == NULL) ||
+ ((new = malloc(len + 1)) == NULL)) {
+ return NULL;
+ }
+
+ memcpy(new, s, len);
+ new[len] = '\0';
+
+ return new;
+}
+
+#endif
+EXPORT_SYMBOL(strndup);
+
#ifndef __HAVE_ARCH_STRSPN
/**
* strspn - Calculate the length of the initial substring of @s which only