diff options
author | Bin Meng <bmeng.cn@gmail.com> | 2021-06-22 16:16:18 +0300 |
---|---|---|
committer | Bin Meng <bmeng.cn@gmail.com> | 2021-06-23 12:21:14 +0300 |
commit | 478f7fc6a04ae81af550b56b31f18af24cf3f262 (patch) | |
tree | 6fbda11b023a059981b8828269c42764d3c0524f | |
parent | 84344258f23fb9ac5abe7383c909f8606ac767b6 (diff) | |
download | u-boot-478f7fc6a04ae81af550b56b31f18af24cf3f262.tar.xz |
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 <xypron.glpk@gmx.de>
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
-rw-r--r-- | drivers/nvme/nvme.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index afb1a7ea97..acf337a58a 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: |