[U-Boot] [PATCH v2] efi: device path for nvme

Patrick Wildt patrick at blueri.se
Thu Oct 3 09:21:27 UTC 2019


[PATCH v2] efi: device path for nvme

This adds a device path node for NVMe block devices.  For that
nvme_get_namespace_id() is added to return the privately stored
namespace identifier and optionally also the EUI64.

Signed-off-by: Patrick Wildt <patrick at blueri.se>
---
Changes for v2:
  - the EUI64 is now also stored in the nvme device structure
  - nvme_get_namespace_id() optionally returns the EUI64 as well
  - EUI64 was changed from u64 to u8[8] for better handling
  - added support for the device path to text protocol

diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 47f101e280..b16ddc371a 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -621,6 +621,15 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev)
 	return 0;
 }
 
+u32
+nvme_get_namespace_id(struct udevice *udev, u8 *eui64)
+{
+	struct nvme_ns *ns = dev_get_priv(udev);
+	if (eui64)
+		memcpy(eui64, ns->eui64, sizeof(ns->eui64));
+	return ns->ns_id;
+}
+
 int nvme_scan_namespace(void)
 {
 	struct uclass *uc;
@@ -657,6 +666,7 @@ static int nvme_blk_probe(struct udevice *udev)
 	if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id))
 		return -EIO;
 
+	memcpy(&ns->eui64, &id->eui64, sizeof(id->eui64));
 	flbas = id->flbas & NVME_NS_FLBAS_LBA_MASK;
 	ns->flbas = flbas;
 	ns->lba_shift = id->lbaf[flbas].ds;
diff --git a/drivers/nvme/nvme.h b/drivers/nvme/nvme.h
index 922f7abfe8..0e8cb221a7 100644
--- a/drivers/nvme/nvme.h
+++ b/drivers/nvme/nvme.h
@@ -637,6 +637,7 @@ struct nvme_ns {
 	struct list_head list;
 	struct nvme_dev *dev;
 	unsigned ns_id;
+	u8 eui64[8];
 	int devnum;
 	int lba_shift;
 	u8 flbas;
diff --git a/include/efi_api.h b/include/efi_api.h
index 37e56da460..d2c2330f84 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -422,6 +422,7 @@ struct efi_device_path_acpi_path {
 #  define DEVICE_PATH_SUB_TYPE_MSG_USB		0x05
 #  define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR	0x0b
 #  define DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS	0x0f
+#  define DEVICE_PATH_SUB_TYPE_MSG_NVME		0x17
 #  define DEVICE_PATH_SUB_TYPE_MSG_SD		0x1a
 #  define DEVICE_PATH_SUB_TYPE_MSG_MMC		0x1d
 
@@ -459,6 +460,12 @@ struct efi_device_path_usb_class {
 	u8 device_protocol;
 } __packed;
 
+struct efi_device_path_nvme {
+	struct efi_device_path dp;
+	u32 nsid;
+	u8 eui64[8];
+} __packed;
+
 struct efi_device_path_sd_mmc_path {
 	struct efi_device_path dp;
 	u8 slot_number;
diff --git a/include/nvme.h b/include/nvme.h
index 2c3d14d241..c8fdd44da0 100644
--- a/include/nvme.h
+++ b/include/nvme.h
@@ -78,4 +78,15 @@ int nvme_scan_namespace(void);
  */
 int nvme_print_info(struct udevice *udev);
 
+/**
+ * nvme_get_namespace_id - return namespace identifier
+ *
+ * This returns the namespace identifier.
+ *
+ * @udev:	NVMe controller device
+ * @eui64:	IEEE Extended Unique Identifier
+ * @return:	namespace identifier
+ */
+u32 nvme_get_namespace_id(struct udevice *udev, u8 *eui64);
+
 #endif /* __NVME_H__ */
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 86297bb7c1..6cb5b9c0d4 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -10,6 +10,7 @@
 #include <dm.h>
 #include <usb.h>
 #include <mmc.h>
+#include <nvme.h>
 #include <efi_loader.h>
 #include <part.h>
 #include <sandboxblockdev.h>
@@ -451,6 +452,11 @@ static unsigned dp_size(struct udevice *dev)
 			return dp_size(dev->parent) +
 				sizeof(struct efi_device_path_sd_mmc_path);
 #endif
+#if defined(CONFIG_NVME)
+		case UCLASS_NVME:
+			return dp_size(dev->parent) +
+				sizeof(struct efi_device_path_nvme);
+#endif
 #ifdef CONFIG_SANDBOX
 		case UCLASS_ROOT:
 			 /*
@@ -583,6 +589,19 @@ static void *dp_fill(void *buf, struct udevice *dev)
 			sddp->slot_number = dev->seq;
 			return &sddp[1];
 			}
+#endif
+#if defined(CONFIG_NVME)
+		case UCLASS_NVME: {
+			struct efi_device_path_nvme *dp =
+				dp_fill(buf, dev->parent);
+
+			dp->dp.type     = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
+			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_NVME;
+			dp->dp.length   = sizeof(*dp);
+			dp->nsid        = nvme_get_namespace_id(dev,
+								&dp->eui64[0]);
+			return &dp[1];
+			}
 #endif
 		default:
 			debug("%s(%u) %s: unhandled parent class: %s (%u)\n",
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index 0f3796b373..9cfb7faa25 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -148,6 +148,20 @@ static char *dp_msging(char *s, struct efi_device_path *dp)
 
 		break;
 	}
+	case DEVICE_PATH_SUB_TYPE_MSG_NVME: {
+		struct efi_device_path_nvme *ndp =
+			(struct efi_device_path_nvme *)dp;
+		int i;
+
+		s += sprintf(s, "NVME(0x%x,",
+			     ndp->nsid);
+		for (i = 0; i < sizeof(ndp->eui64); ++i)
+			s += sprintf(s, "%s%02x", i ? "-" : "",
+				     ndp->eui64[i]);
+		s += sprintf(s, ")");
+
+		break;
+	}
 	case DEVICE_PATH_SUB_TYPE_MSG_SD:
 	case DEVICE_PATH_SUB_TYPE_MSG_MMC: {
 		const char *typename =


More information about the U-Boot mailing list