251 lines
8.6 KiB
Diff
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
|
||
|
|