grub2/0001-ieee1275-add-support-for-NVMeoFC.patch

251 lines
8.6 KiB
Diff

From c125cb45a7885d7bf168a05cfa4da3e681244649 Mon Sep 17 00:00:00 2001
From: Diego Domingos <diegodo@br.ibm.com>
Date: Tue, 15 Feb 2022 13:11:48 -0500
Subject: [PATCH 1/4] ieee1275: add support for NVMeoFC
Implements the functions to scan and discovery of NVMeoFC.
---
grub-core/disk/ieee1275/ofdisk.c | 217 ++++++++++++++++++++++++++++++-
1 file changed, 213 insertions(+), 4 deletions(-)
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
index 410f4b849..852bb95be 100644
--- a/grub-core/disk/ieee1275/ofdisk.c
+++ b/grub-core/disk/ieee1275/ofdisk.c
@@ -206,12 +206,10 @@ dev_iterate_real (const char *name, const char *path)
return;
}
+
static void
-dev_iterate (const struct grub_ieee1275_devalias *alias)
+dev_iterate_fcp_disks(const struct grub_ieee1275_devalias *alias)
{
- 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;
@@ -323,6 +321,217 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
grub_free (buf);
return;
+}
+
+static void
+dev_iterate_fcp_nvmeof (const struct grub_ieee1275_devalias *alias)
+{
+
+
+ char *bufptr;
+ grub_ieee1275_ihandle_t ihandle;
+
+
+ // Create the structs for the parameters passing to PFW
+ struct nvme_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;
+ } nvme_discovery_controllers_args, nvme_controllers_args, nvme_namespaces_args;
+
+
+ // Create the structs for the results from PFW
+
+ struct discovery_controllers_table_struct_
+ {
+ grub_uint64_t table[256];
+ grub_uint32_t len;
+ } discovery_controllers_table;
+
+ /* struct nvme_controllers_table_entry
+ * this the return of nvme-controllers method tables, containing:
+ * - 2-byte controller ID
+ * - 256-byte transport address string
+ * - 256-byte field containing null-terminated NVM subsystem NQN string up to 223 characters
+ */
+ struct nvme_controllers_table_entry_
+ {
+ grub_uint16_t id;
+ char wwpn[256];
+ char nqn[256];
+ };
+
+ struct nvme_controllers_table_entry_* nvme_controllers_table = grub_malloc(sizeof(struct nvme_controllers_table_entry_)*256);
+
+ grub_uint32_t nvme_controllers_table_entries;
+
+ struct nvme_controllers_table_entry_real
+ {
+ grub_uint16_t id;
+ char wwpn[256];
+ char nqn[256];
+ };
+
+ /* Allocate memory for building the NVMeoF path */
+ char *buf = grub_malloc (grub_strlen (alias->path) + 512);
+ if (!buf)
+ {
+ grub_ieee1275_close(ihandle);
+ return;
+ }
+
+ /* Copy the alias->path to buf so we can work with */
+ bufptr = grub_stpcpy (buf, alias->path);
+ grub_snprintf (bufptr, 32, "/nvme-of");
+
+ /*
+ * Open the nvme-of layer
+ * Ex. /pci@bus/fibre-channel@@dev,func/nvme-of
+ */
+ if(grub_ieee1275_open (buf, &ihandle))
+ {
+ grub_dprintf("disk", "failed to open the disk while iterating FCP disk path=%s\n", buf);
+ return;
+ }
+
+ /*
+ * Call to nvme-discovery-controllers method from the nvme-of layer
+ * to get a list of the NVMe discovery controllers per the binding
+ */
+
+ INIT_IEEE1275_COMMON (&nvme_discovery_controllers_args.common, "call-method", 2, 2);
+ nvme_discovery_controllers_args.method = (grub_ieee1275_cell_t) "nvme-discovery-controllers";
+ nvme_discovery_controllers_args.ihandle = ihandle;
+
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_discovery_controllers_args) == -1)
+ {
+ grub_dprintf("disk", "failed to get the targets while iterating FCP disk path=%s\n", buf);
+ grub_ieee1275_close(ihandle);
+ return;
+ }
+
+ /* After closing the device, the info is lost. So lets copy each buffer in the buffers table */
+
+ discovery_controllers_table.len = (grub_uint32_t) nvme_discovery_controllers_args.nentries;
+
+ unsigned int i=0;
+ for(i = 0; i < discovery_controllers_table.len; i++){
+ discovery_controllers_table.table[i] = ((grub_uint64_t*)nvme_discovery_controllers_args.table)[i];
+ }
+
+ grub_ieee1275_close(ihandle);
+
+ grub_dprintf("ofdisk","NVMeoF: Found %d discovery controllers\n",discovery_controllers_table.len);
+
+ /* For each nvme discovery controller */
+ int current_buffer_index;
+ for(current_buffer_index = 0; current_buffer_index < (int) discovery_controllers_table.len; current_buffer_index++){
+
+
+ grub_snprintf (bufptr, 64, "/nvme-of/controller@%" PRIxGRUB_UINT64_T ",ffff",
+ discovery_controllers_table.table[current_buffer_index]);
+
+ grub_dprintf("ofdisk","nvmeof controller=%s\n",buf);
+
+ if(grub_ieee1275_open (buf, &ihandle))
+ {
+ grub_dprintf("ofdisk", "failed to open the disk while getting nvme-controllers path=%s\n", buf);
+ continue;
+ }
+
+
+ INIT_IEEE1275_COMMON (&nvme_controllers_args.common, "call-method", 2, 2);
+ nvme_controllers_args.method = (grub_ieee1275_cell_t) "nvme-controllers";
+ nvme_controllers_args.ihandle = ihandle;
+ nvme_controllers_args.catch_result = 0;
+
+
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_controllers_args) == -1)
+ {
+ grub_dprintf("ofdisk", "failed to get the nvme-controllers while iterating FCP disk path\n");
+ grub_ieee1275_close(ihandle);
+ continue;
+ }
+
+
+ /* Copy the buffer list to nvme_controllers_table */
+ nvme_controllers_table_entries = ((grub_uint32_t) nvme_controllers_args.nentries);
+ struct nvme_controllers_table_entry_* nvme_controllers_table_ = (struct nvme_controllers_table_entry_*) nvme_controllers_args.table;
+
+ for(i = 0; i < nvme_controllers_table_entries; i++){
+ nvme_controllers_table[i].id = (grub_uint16_t) nvme_controllers_table_[i].id;
+ grub_strcpy(nvme_controllers_table[i].wwpn, nvme_controllers_table_[i].wwpn);
+ grub_strcpy(nvme_controllers_table[i].nqn, nvme_controllers_table_[i].nqn);
+ }
+
+ grub_ieee1275_close(ihandle);
+
+ int nvme_controller_index;
+ int bufptr_pos2;
+ grub_dprintf("ofdisk","NVMeoF: found %d nvme controllers\n",(int) nvme_controllers_args.nentries);
+
+ /* For each nvme controller */
+ for(nvme_controller_index = 0; nvme_controller_index < (int) nvme_controllers_args.nentries; nvme_controller_index++){
+ /* Open the nvme controller
+ * /pci@bus/fibre-channel@dev,func/nvme-of/controller@transport-addr,ctlr-id:nqn=tgt-subsystem-nqn
+ */
+
+ bufptr_pos2 = grub_snprintf (bufptr, 512, "/nvme-of/controller@%s,ffff:nqn=%s",
+ nvme_controllers_table[nvme_controller_index].wwpn, nvme_controllers_table[nvme_controller_index].nqn);
+
+ grub_dprintf("ofdisk","NVMeoF: nvmeof controller=%s\n",buf);
+
+ if(grub_ieee1275_open (buf, &ihandle)){
+ grub_dprintf("ofdisk","failed to open the path=%s\n",buf);
+ continue;
+ }
+
+ INIT_IEEE1275_COMMON (&nvme_namespaces_args.common, "call-method", 2, 2);
+ nvme_namespaces_args.method = (grub_ieee1275_cell_t) "get-namespace-list";
+ nvme_namespaces_args.ihandle = ihandle;
+ nvme_namespaces_args.catch_result = 0;
+
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_namespaces_args) == -1)
+ {
+ grub_dprintf("ofdisk", "failed to get the nvme-namespace-list while iterating FCP disk path\n");
+ grub_ieee1275_close(ihandle);
+ continue;
+ }
+
+ grub_uint32_t *namespaces = (grub_uint32_t*) nvme_namespaces_args.table;
+ grub_dprintf("ofdisk","NVMeoF: found %d namespaces\n",(int)nvme_namespaces_args.nentries);
+
+ grub_ieee1275_close(ihandle);
+
+ grub_uint32_t namespace_index = 0;
+ for(namespace_index=0; namespace_index < nvme_namespaces_args.nentries; namespace_index++){
+ grub_snprintf (bufptr+bufptr_pos2, 512, "/namespace@%"PRIxGRUB_UINT32_T,namespaces[namespace_index]);
+ grub_dprintf("ofdisk","NVMeoF: namespace=%s\n",buf);
+ dev_iterate_real(buf,buf);
+ }
+
+ dev_iterate_real(buf,buf);
+ }
+ }
+ grub_free(buf);
+ return;
+}
+
+static void
+dev_iterate (const struct grub_ieee1275_devalias *alias)
+{
+ if (grub_strcmp (alias->type, "fcp") == 0)
+ {
+ // Iterate disks
+ dev_iterate_fcp_disks(alias);
+
+ // Iterate NVMeoF
+ dev_iterate_fcp_nvmeof(alias);
+
}
else if (grub_strcmp (alias->type, "vscsi") == 0)
{
--
2.35.3