144 lines
5.5 KiB
Diff
144 lines
5.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Avnish Chouhan <avnish@linux.ibm.com>
|
|
Date: Mon, 23 Feb 2026 19:14:07 +0530
|
|
Subject: [PATCH] ieee1275: implement FCP methods for WWPN and LUNs
|
|
|
|
This patch enables the fcp-targets and fcp-luns methods which are
|
|
responsible to get WWPNs and LUNs for fibre channel devices.
|
|
|
|
Those methods are specially necessary if the boot directory and grub
|
|
installation are in different FCP disks, allowing the dev_iterate()
|
|
to find the WWPNs and LUNs when called by searchfs.uuid tool.
|
|
|
|
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
|
|
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
|
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
|
|
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
|
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
|
|
---
|
|
grub-core/disk/ieee1275/ofdisk.c | 111 ++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 110 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
|
index abb5082cdbfc..a16300a94745 100644
|
|
--- a/grub-core/disk/ieee1275/ofdisk.c
|
|
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
|
@@ -223,7 +223,116 @@ dev_iterate_real (const char *name, const char *path)
|
|
static void
|
|
dev_iterate (const struct grub_ieee1275_devalias *alias)
|
|
{
|
|
- if (grub_strcmp (alias->type, "vscsi") == 0)
|
|
+ if (grub_strcmp (alias->type, "fcp") == 0)
|
|
+ {
|
|
+ /*
|
|
+ * If we are dealing with fcp devices, we need
|
|
+ * to find the WWPNs and LUNs to iterate them
|
|
+ */
|
|
+ grub_ieee1275_ihandle_t ihandle;
|
|
+ grub_uint64_t *ptr_targets, *ptr_luns, k, l;
|
|
+ unsigned int i, j, pos;
|
|
+ char *buf, *bufptr;
|
|
+ struct set_fcp_targets_args
|
|
+ {
|
|
+ struct grub_ieee1275_common_hdr common;
|
|
+ grub_ieee1275_cell_t method;
|
|
+ grub_ieee1275_cell_t ihandle;
|
|
+ grub_ieee1275_cell_t catch_result;
|
|
+ grub_ieee1275_cell_t nentries;
|
|
+ grub_ieee1275_cell_t table;
|
|
+ } args_targets;
|
|
+
|
|
+ struct set_fcp_luns_args
|
|
+ {
|
|
+ struct grub_ieee1275_common_hdr common;
|
|
+ grub_ieee1275_cell_t method;
|
|
+ grub_ieee1275_cell_t ihandle;
|
|
+ grub_ieee1275_cell_t wwpn_h;
|
|
+ grub_ieee1275_cell_t wwpn_l;
|
|
+ grub_ieee1275_cell_t catch_result;
|
|
+ grub_ieee1275_cell_t nentries;
|
|
+ grub_ieee1275_cell_t table;
|
|
+ } args_luns;
|
|
+
|
|
+ struct args_ret
|
|
+ {
|
|
+ grub_uint64_t addr;
|
|
+ grub_uint64_t len;
|
|
+ };
|
|
+
|
|
+ if (grub_ieee1275_open (alias->path, &ihandle))
|
|
+ {
|
|
+ grub_dprintf ("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /* Setup the fcp-targets method to call via pfw*/
|
|
+ INIT_IEEE1275_COMMON (&args_targets.common, "call-method", 2, 3);
|
|
+ args_targets.method = (grub_ieee1275_cell_t) "fcp-targets";
|
|
+ args_targets.ihandle = ihandle;
|
|
+
|
|
+ /* Setup the fcp-luns method to call via pfw */
|
|
+ INIT_IEEE1275_COMMON (&args_luns.common, "call-method", 4, 3);
|
|
+ args_luns.method = (grub_ieee1275_cell_t) "fcp-luns";
|
|
+ args_luns.ihandle = ihandle;
|
|
+ if (IEEE1275_CALL_ENTRY_FN (&args_targets) == -1)
|
|
+ {
|
|
+ grub_dprintf ("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path);
|
|
+ grub_ieee1275_close (ihandle);
|
|
+ return;
|
|
+ }
|
|
+ buf = grub_malloc (grub_strlen (alias->path) + 32 + 32);
|
|
+ if (!buf)
|
|
+ {
|
|
+ grub_ieee1275_close (ihandle);
|
|
+ return;
|
|
+ }
|
|
+ bufptr = grub_stpcpy (buf, alias->path);
|
|
+
|
|
+ /*
|
|
+ * Iterate over entries returned by pfw. Each entry contains a
|
|
+ * pointer to wwpn table and his length.
|
|
+ */
|
|
+ struct args_ret *targets_table = (struct args_ret *) (args_targets.table);
|
|
+ for (i = 0; i < args_targets.nentries; i++)
|
|
+ {
|
|
+ ptr_targets = (grub_uint64_t*) targets_table[i].addr;
|
|
+ /* Iterate over all wwpns in given table */
|
|
+ for(k = 0; k < targets_table[i].len; k++)
|
|
+ {
|
|
+ args_luns.wwpn_l = (grub_ieee1275_cell_t) (*ptr_targets);
|
|
+ args_luns.wwpn_h = (grub_ieee1275_cell_t) (*ptr_targets >> 32);
|
|
+ pos = grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T,
|
|
+ grub_get_unaligned64 (*ptr_targets++));
|
|
+ /* Get the luns for given wwpn target */
|
|
+ if (IEEE1275_CALL_ENTRY_FN (&args_luns) == -1)
|
|
+ {
|
|
+ grub_dprintf ("disk", "failed to get the LUNS while iterating FCP disk path=%s\n", buf);
|
|
+ grub_ieee1275_close (ihandle);
|
|
+ grub_free (buf);
|
|
+ return;
|
|
+ }
|
|
+ struct args_ret *luns_table = (struct args_ret *) (args_luns.table);
|
|
+
|
|
+ /* Iterate over all LUNs */
|
|
+ for(j = 0; j < args_luns.nentries; j++)
|
|
+ {
|
|
+ ptr_luns = (grub_uint64_t*) luns_table[j].addr;
|
|
+ for(l = 0; l < luns_table[j].len; l++)
|
|
+ {
|
|
+ grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
|
|
+ grub_get_unaligned64 (*ptr_luns++));
|
|
+ dev_iterate_real (buf, buf);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ grub_ieee1275_close (ihandle);
|
|
+ grub_free (buf);
|
|
+ return;
|
|
+ }
|
|
+ else if (grub_strcmp (alias->type, "vscsi") == 0)
|
|
{
|
|
static grub_ieee1275_ihandle_t ihandle;
|
|
struct set_color_args
|