[PATCH 1/2] nvme: Move block dev creation from uclass post probe to driver probe

Bin Meng bmeng.cn at gmail.com
Mon Jun 21 16:56:28 CEST 2021


At present the block device creation happens in the NVMe uclass driver
post probe phase. Move it to driver probe phase instead. A per-child
platdata is added to store the namespace id, so that we can obtain it
in the block driver probe phase, without the assumption that the ns id
is encoded in the block device name.

Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
---

 drivers/nvme/nvme-uclass.c | 30 ------------------------------
 drivers/nvme/nvme.c        | 30 +++++++++++++++++++++++++-----
 drivers/nvme/nvme.h        | 14 ++++++++++++++
 3 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/drivers/nvme/nvme-uclass.c b/drivers/nvme/nvme-uclass.c
index 277e31e1f3..610166d76e 100644
--- a/drivers/nvme/nvme-uclass.c
+++ b/drivers/nvme/nvme-uclass.c
@@ -5,39 +5,9 @@
  */
 
 #include <common.h>
-#include <blk.h>
-#include <errno.h>
 #include <dm.h>
-#include <dm/device.h>
-#include "nvme.h"
-
-static int nvme_uclass_post_probe(struct udevice *udev)
-{
-	char name[20];
-	struct udevice *ns_udev;
-	int i, ret;
-	struct nvme_dev *ndev = dev_get_priv(udev);
-
-	/* Create a blk device for each namespace */
-	for (i = 0; i < ndev->nn; i++) {
-		/*
-		 * Encode the namespace id to the device name so that
-		 * we can extract it when doing the probe.
-		 */
-		sprintf(name, "blk#%d", i);
-
-		/* The real blksz and size will be set by nvme_blk_probe() */
-		ret = blk_create_devicef(udev, "nvme-blk", name, IF_TYPE_NVME,
-					 -1, 512, 0, &ns_udev);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
 
 UCLASS_DRIVER(nvme) = {
 	.name	= "nvme",
 	.id	= UCLASS_NVME,
-	.post_probe = nvme_uclass_post_probe,
 };
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index c61dab20c5..0b4a73d170 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -696,10 +696,11 @@ int nvme_scan_namespace(void)
 static int nvme_blk_probe(struct udevice *udev)
 {
 	struct nvme_dev *ndev = dev_get_priv(udev->parent);
+	struct nvme_child_plat *nvme_pplat = dev_get_parent_plat(udev);
 	struct blk_desc *desc = dev_get_uclass_plat(udev);
 	struct nvme_ns *ns = dev_get_priv(udev);
 	u8 flbas;
-	struct pci_child_plat *pplat;
+	struct pci_child_plat *pci_pplat;
 	struct nvme_id_ns *id;
 
 	id = memalign(ndev->page_size, sizeof(struct nvme_id_ns));
@@ -708,8 +709,7 @@ static int nvme_blk_probe(struct udevice *udev)
 
 	memset(ns, 0, sizeof(*ns));
 	ns->dev = ndev;
-	/* extract the namespace id from the block device name */
-	ns->ns_id = trailing_strtol(udev->name) + 1;
+	ns->ns_id = nvme_pplat->ns_id;
 	if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) {
 		free(id);
 		return -EIO;
@@ -727,8 +727,8 @@ static int nvme_blk_probe(struct udevice *udev)
 	desc->log2blksz = ns->lba_shift;
 	desc->blksz = 1 << ns->lba_shift;
 	desc->bdev = udev;
-	pplat = dev_get_parent_plat(udev->parent);
-	sprintf(desc->vendor, "0x%.4x", pplat->vendor);
+	pci_pplat = dev_get_parent_plat(udev->parent);
+	sprintf(desc->vendor, "0x%.4x", pci_pplat->vendor);
 	memcpy(desc->product, ndev->serial, sizeof(ndev->serial));
 	memcpy(desc->revision, ndev->firmware_rev, sizeof(ndev->firmware_rev));
 
@@ -879,6 +879,25 @@ static int nvme_probe(struct udevice *udev)
 
 	nvme_get_info_from_identify(ndev);
 
+	/* Create a blk device for each namespace */
+	for (int i = 1; i <= ndev->nn; i++) {
+		struct udevice *ns_udev;
+		struct nvme_child_plat *pplat;
+		char name[20];
+
+		sprintf(name, "blk#%d", i);
+
+		/* The real blksz and size will be set by nvme_blk_probe() */
+		ret = blk_create_devicef(udev, "nvme-blk", name, IF_TYPE_NVME,
+					 -1, 512, 0, &ns_udev);
+		if (ret)
+			goto free_queue;
+
+		/* Update the platform data */
+		pplat = dev_get_parent_plat(ns_udev);
+		pplat->ns_id = i;
+	}
+
 	return 0;
 
 free_queue:
@@ -893,6 +912,7 @@ U_BOOT_DRIVER(nvme) = {
 	.bind	= nvme_bind,
 	.probe	= nvme_probe,
 	.priv_auto	= sizeof(struct nvme_dev),
+	.per_child_plat_auto	= sizeof(struct nvme_child_plat),
 };
 
 struct pci_device_id nvme_supported[] = {
diff --git a/drivers/nvme/nvme.h b/drivers/nvme/nvme.h
index aa4b3bac67..11b3ab6872 100644
--- a/drivers/nvme/nvme.h
+++ b/drivers/nvme/nvme.h
@@ -637,4 +637,18 @@ struct nvme_ns {
 	u32 mode_select_block_len;
 };
 
+/**
+ * An NVM Express child (namespace) platdata
+ *
+ * Every blk device on a NVMe bus has this per-child data.
+ *
+ * It can be accessed using dev_get_parent_plat(dev) if dev->parent is a
+ * NVMe device (i.e. UCLASS_NVME)
+ *
+ * @ns_id:	namespace id
+ */
+struct nvme_child_plat {
+	unsigned ns_id;
+};
+
 #endif /* __DRIVER_NVME_H__ */
-- 
2.25.1



More information about the U-Boot mailing list