From 478f7fc6a04ae81af550b56b31f18af24cf3f262 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 22 Jun 2021 21:16:18 +0800 Subject: nvme: Skip block device creation for inactive namespaces At present for each namespace there is a block device created for it. There is no issue if the number of supported namespaces reported from the NVMe device is only 1. Since QEMU commit 7f0f1acedf15 ("hw/block/nvme: support multiple namespaces"), the number of supported namespaces reported has been changed from 1 to 256, but not all of them are active namespaces. The actual active one depends on the QEMU command line parameters. A common case is that namespace 1 being active and all other 255 being inactive. If a namespace is inactive, the namespace identify command returns a zero filled data structure. We can use field NSZE (namespace size) to decide whether a block device should be created for it. Reported-by: Heinrich Schuchardt Signed-off-by: Bin Meng --- drivers/nvme/nvme.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers/nvme') diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index afb1a7e..acf337a 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -834,6 +834,7 @@ static int nvme_probe(struct udevice *udev) { int ret; struct nvme_dev *ndev = dev_get_priv(udev); + struct nvme_id_ns *id; ndev->instance = trailing_strtol(udev->name); @@ -879,10 +880,27 @@ static int nvme_probe(struct udevice *udev) nvme_get_info_from_identify(ndev); /* Create a blk device for each namespace */ + + id = memalign(ndev->page_size, sizeof(struct nvme_id_ns)); + if (!id) { + ret = -ENOMEM; + goto free_queue; + } + for (int i = 0; i < ndev->nn; i++) { struct udevice *ns_udev; char name[20]; + memset(id, 0, sizeof(*id)); + if (nvme_identify(ndev, i + 1, 0, (dma_addr_t)(long)id)) { + ret = -EIO; + goto free_id; + } + + /* skip inactive namespace */ + if (!id->nsze) + continue; + /* * Encode the namespace id to the device name so that * we can extract it when doing the probe. @@ -893,11 +911,14 @@ static int nvme_probe(struct udevice *udev) ret = blk_create_devicef(udev, "nvme-blk", name, IF_TYPE_NVME, -1, 512, 0, &ns_udev); if (ret) - goto free_queue; + goto free_id; } + free(id); return 0; +free_id: + free(id); free_queue: free((void *)ndev->queues); free_nvme: -- cgit v1.1