pxe: Allow calling the pxe_get logic directly
Refactor this code so that we can call the 'pxe get' command without going
through the command-line interpreter. This makes it easier to get the
information we need, without going through environment variables.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Artem Lapkin <email2tema@gmail.com>
Tested-by: Artem Lapkin <email2tema@gmail.com>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
diff --git a/cmd/pxe.c b/cmd/pxe.c
index 8170338..db8e469 100644
--- a/cmd/pxe.c
+++ b/cmd/pxe.c
@@ -104,6 +104,49 @@
return -ENOENT;
}
+
+int pxe_get(ulong pxefile_addr_r, char **bootdirp, ulong *sizep)
+{
+ struct cmd_tbl cmdtp[] = {}; /* dummy */
+ struct pxe_context ctx;
+ int i;
+
+ if (pxe_setup_ctx(&ctx, cmdtp, do_get_tftp, NULL, false,
+ env_get("bootfile")))
+ return -ENOMEM;
+ /*
+ * Keep trying paths until we successfully get a file we're looking
+ * for.
+ */
+ if (pxe_uuid_path(&ctx, pxefile_addr_r) > 0 ||
+ pxe_mac_path(&ctx, pxefile_addr_r) > 0 ||
+ pxe_ipaddr_paths(&ctx, pxefile_addr_r) > 0)
+ goto done;
+
+ i = 0;
+ while (pxe_default_paths[i]) {
+ if (get_pxelinux_path(&ctx, pxe_default_paths[i],
+ pxefile_addr_r) > 0)
+ goto done;
+ i++;
+ }
+
+ pxe_destroy_ctx(&ctx);
+
+ return -ENOENT;
+done:
+ *bootdirp = env_get("bootfile");
+
+ /*
+ * The PXE file size is returned but not the name. It is probably not
+ * that useful.
+ */
+ *sizep = ctx.pxe_file_size;
+ pxe_destroy_ctx(&ctx);
+
+ return 0;
+}
+
/*
* Entry point for the 'pxe get' command.
* This Follows pxelinux's rules to download a config file from a tftp server.
@@ -122,9 +165,10 @@
do_pxe_get(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
char *pxefile_addr_str;
- unsigned long pxefile_addr_r;
- struct pxe_context ctx;
- int err, i = 0;
+ ulong pxefile_addr_r;
+ char *fname;
+ ulong size;
+ int ret;
if (argc != 1)
return CMD_RET_USAGE;
@@ -134,43 +178,25 @@
if (!pxefile_addr_str)
return 1;
- err = strict_strtoul(pxefile_addr_str, 16,
+ ret = strict_strtoul(pxefile_addr_str, 16,
(unsigned long *)&pxefile_addr_r);
- if (err < 0)
+ if (ret < 0)
return 1;
- if (pxe_setup_ctx(&ctx, cmdtp, do_get_tftp, NULL, false,
- env_get("bootfile"))) {
+ ret = pxe_get(pxefile_addr_r, &fname, &size);
+ switch (ret) {
+ case 0:
+ printf("Config file '%s' found\n", fname);
+ break;
+ case -ENOMEM:
printf("Out of memory\n");
return CMD_RET_FAILURE;
- }
- /*
- * Keep trying paths until we successfully get a file we're looking
- * for.
- */
- if (pxe_uuid_path(&ctx, pxefile_addr_r) > 0 ||
- pxe_mac_path(&ctx, pxefile_addr_r) > 0 ||
- pxe_ipaddr_paths(&ctx, pxefile_addr_r) > 0) {
- printf("Config file found\n");
- pxe_destroy_ctx(&ctx);
-
- return 0;
- }
-
- while (pxe_default_paths[i]) {
- if (get_pxelinux_path(&ctx, pxe_default_paths[i],
- pxefile_addr_r) > 0) {
- printf("Config file found\n");
- pxe_destroy_ctx(&ctx);
- return 0;
- }
- i++;
+ default:
+ printf("Config file not found\n");
+ return CMD_RET_FAILURE;
}
- printf("Config file not found\n");
- pxe_destroy_ctx(&ctx);
-
- return 1;
+ return 0;
}
/*
diff --git a/include/pxe_utils.h b/include/pxe_utils.h
index 194a5ed..b7037f8 100644
--- a/include/pxe_utils.h
+++ b/include/pxe_utils.h
@@ -236,4 +236,18 @@
*/
int pxe_get_file_size(ulong *sizep);
+/**
+ * pxe_get() - Get the PXE file from the server
+ *
+ * This tries various filenames to obtain a PXE file
+ *
+ * @pxefile_addr_r: Address to put file
+ * @bootdirp: Returns the boot filename, or NULL if none. This is the 'bootfile'
+ * option provided by the DHCP server. If none, returns NULL. For example,
+ * "rpi/info", which indicates that all files should be fetched from the
+ * "rpi/" subdirectory
+ * @sizep: Size of the PXE file (not bootfile)
+ */
+int pxe_get(ulong pxefile_addr_r, char **bootdirp, ulong *sizep);
+
#endif /* __PXE_UTILS_H */