aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-06-23 08:46:26 -0400
committerTom Rini <trini@konsulko.com>2021-06-23 08:46:26 -0400
commitfcf3981161140d265b873a5b609b8867328dc9dc (patch)
tree5542a322551d604c1f0ba5ff910984480b57ec7c
parentc3a095d1ce16c4a416d831223e10dd95c15f3780 (diff)
parentf68d5a66cd53a238d64d79cdd330b4dce17c7197 (diff)
downloadu-boot-WIP/23Jun2021.zip
u-boot-WIP/23Jun2021.tar.gz
u-boot-WIP/23Jun2021.tar.bz2
Merge https://source.denx.de/u-boot/custodians/u-boot-x86WIP/23Jun2021
- x86: Discard .note.gnu.property sections - nvme: Skip block device creation for inactive namespaces - nvme: Convert NVMe doc to reST, and various minor fixes
-rw-r--r--MAINTAINERS8
-rw-r--r--arch/x86/cpu/u-boot-64.lds1
-rw-r--r--arch/x86/cpu/u-boot-spl.lds1
-rw-r--r--arch/x86/cpu/u-boot.lds1
-rw-r--r--doc/develop/driver-model/index.rst1
-rw-r--r--doc/develop/driver-model/nvme.rst (renamed from doc/README.nvme)25
-rw-r--r--drivers/nvme/nvme-uclass.c30
-rw-r--r--drivers/nvme/nvme.c57
-rw-r--r--drivers/nvme/nvme.h2
9 files changed, 77 insertions, 49 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 5ec1e36..11e11d5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -914,6 +914,14 @@ S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-nios.git
F: arch/nios2/
+NVMe
+M: Bin Meng <bmeng.cn@gmail.com>
+S: Maintained
+F: drivers/nvme/
+F: cmd/nvme.c
+F: include/nvme.h
+F: doc/develop/driver-model/nvme.rst
+
ONENAND
#M: Lukasz Majewski <l.majewski@majess.pl>
S: Orphaned (Since 2017-01)
diff --git a/arch/x86/cpu/u-boot-64.lds b/arch/x86/cpu/u-boot-64.lds
index 98c7f8e..ee0812a 100644
--- a/arch/x86/cpu/u-boot-64.lds
+++ b/arch/x86/cpu/u-boot-64.lds
@@ -107,4 +107,5 @@ SECTIONS
/DISCARD/ : { *(.plt*) }
/DISCARD/ : { *(.interp*) }
/DISCARD/ : { *(.gnu*) }
+ /DISCARD/ : { *(.note.gnu.property) }
}
diff --git a/arch/x86/cpu/u-boot-spl.lds b/arch/x86/cpu/u-boot-spl.lds
index 4a655bf..346f60b 100644
--- a/arch/x86/cpu/u-boot-spl.lds
+++ b/arch/x86/cpu/u-boot-spl.lds
@@ -82,6 +82,7 @@ SECTIONS
/DISCARD/ : { *(.plt*) }
/DISCARD/ : { *(.interp*) }
/DISCARD/ : { *(.gnu*) }
+ /DISCARD/ : { *(.note.gnu.property) }
#if defined(CONFIG_SPL_X86_16BIT_INIT) || defined(CONFIG_TPL_X86_16BIT_INIT)
/*
diff --git a/arch/x86/cpu/u-boot.lds b/arch/x86/cpu/u-boot.lds
index a283c29..22fde01 100644
--- a/arch/x86/cpu/u-boot.lds
+++ b/arch/x86/cpu/u-boot.lds
@@ -105,6 +105,7 @@ SECTIONS
/DISCARD/ : { *(.plt*) }
/DISCARD/ : { *(.interp*) }
/DISCARD/ : { *(.gnu*) }
+ /DISCARD/ : { *(.note.gnu.property) }
#ifdef CONFIG_X86_16BIT_INIT
/*
diff --git a/doc/develop/driver-model/index.rst b/doc/develop/driver-model/index.rst
index 10a7625..7366ef8 100644
--- a/doc/develop/driver-model/index.rst
+++ b/doc/develop/driver-model/index.rst
@@ -19,6 +19,7 @@ subsystems
i2c-howto
livetree
migration
+ nvme
of-plat
pci-info
pmic-framework
diff --git a/doc/README.nvme b/doc/develop/driver-model/nvme.rst
index e8f9be1..736c0a0 100644
--- a/doc/README.nvme
+++ b/doc/develop/driver-model/nvme.rst
@@ -1,11 +1,13 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# Copyright (C) 2017 NXP Semiconductors
-# Copyright (C) 2017 Bin Meng <bmeng.cn@gmail.com>
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright (C) 2017 NXP Semiconductors
+.. Copyright (C) 2017 Bin Meng <bmeng.cn@gmail.com>
-What is NVMe
+NVMe Support
============
+What is NVMe
+------------
+
NVM Express (NVMe) is a register level interface that allows host software to
communicate with a non-volatile memory subsystem. This interface is optimized
for enterprise and client solid state drives, typically attached to the PCI
@@ -48,6 +50,8 @@ identified.
To list all of the NVMe hard disks, try:
+.. code-block:: none
+
=> nvme info
Device 0: Vendor: 0x8086 Rev: 8DV10131 Prod: CVFT535600LS400BGN
Type: Hard Disk
@@ -55,10 +59,14 @@ To list all of the NVMe hard disks, try:
and print out detailed information for controller and namespaces via:
+.. code-block:: none
+
=> nvme detail
Raw block read/write to can be done via the 'nvme read/write' commands:
+.. code-block:: none
+
=> nvme read a0000000 0 11000
=> tftp 80000000 /tftpboot/kernel.itb
@@ -66,6 +74,8 @@ Raw block read/write to can be done via the 'nvme read/write' commands:
Of course, file system command can be used on the NVMe hard disk as well:
+.. code-block:: none
+
=> fatls nvme 0:1
32376967 kernel.itb
22929408 100m
@@ -81,4 +91,7 @@ QEMU supports NVMe emulation and we can test NVMe driver with QEMU x86 running
U-Boot. Please see README.x86 for how to build u-boot.rom image for QEMU x86.
Example command line to call QEMU x86 below with emulated NVMe device:
-$ ./qemu-system-i386 -drive file=nvme.img,if=none,id=drv0 -device nvme,drive=drv0,serial=QEMUNVME0001 -bios u-boot.rom
+
+.. code-block:: bash
+
+ $ ./qemu-system-i386 -drive file=nvme.img,if=none,id=drv0 -device nvme,drive=drv0,serial=QEMUNVME0001 -bios u-boot.rom
diff --git a/drivers/nvme/nvme-uclass.c b/drivers/nvme/nvme-uclass.c
index 277e31e..610166d 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 c61dab2..f6465ea 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -81,7 +81,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
u64 *prp_pool;
int length = total_len;
int i, nprps;
- u32 prps_per_page = (page_size >> 3) - 1;
+ u32 prps_per_page = page_size >> 3;
u32 num_pages;
length -= (page_size - offset);
@@ -157,7 +157,7 @@ static u16 nvme_read_completion_status(struct nvme_queue *nvmeq, u16 index)
invalidate_dcache_range(start, stop);
- return le16_to_cpu(readw(&(nvmeq->cqes[index].status)));
+ return readw(&(nvmeq->cqes[index].status));
}
/**
@@ -221,7 +221,7 @@ static int nvme_submit_sync_cmd(struct nvme_queue *nvmeq,
}
if (result)
- *result = le32_to_cpu(readl(&(nvmeq->cqes[head].result)));
+ *result = readl(&(nvmeq->cqes[head].result));
if (++head == nvmeq->q_depth) {
head = 0;
@@ -304,7 +304,7 @@ static int nvme_enable_ctrl(struct nvme_dev *dev)
{
dev->ctrl_config &= ~NVME_CC_SHN_MASK;
dev->ctrl_config |= NVME_CC_ENABLE;
- writel(cpu_to_le32(dev->ctrl_config), &dev->bar->cc);
+ writel(dev->ctrl_config, &dev->bar->cc);
return nvme_wait_ready(dev, true);
}
@@ -313,7 +313,7 @@ static int nvme_disable_ctrl(struct nvme_dev *dev)
{
dev->ctrl_config &= ~NVME_CC_SHN_MASK;
dev->ctrl_config &= ~NVME_CC_ENABLE;
- writel(cpu_to_le32(dev->ctrl_config), &dev->bar->cc);
+ writel(dev->ctrl_config, &dev->bar->cc);
return nvme_wait_ready(dev, false);
}
@@ -387,7 +387,6 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
aqa = nvmeq->q_depth - 1;
aqa |= aqa << 16;
- aqa |= aqa << 16;
dev->page_size = 1 << page_shift;
@@ -706,10 +705,9 @@ static int nvme_blk_probe(struct udevice *udev)
if (!id)
return -ENOMEM;
- 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 = trailing_strtol(udev->name);
if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) {
free(id);
return -EIO;
@@ -719,11 +717,9 @@ static int nvme_blk_probe(struct udevice *udev)
flbas = id->flbas & NVME_NS_FLBAS_LBA_MASK;
ns->flbas = flbas;
ns->lba_shift = id->lbaf[flbas].ds;
- ns->mode_select_num_blocks = le64_to_cpu(id->nsze);
- ns->mode_select_block_len = 1 << ns->lba_shift;
list_add(&ns->list, &ndev->namespaces);
- desc->lba = ns->mode_select_num_blocks;
+ desc->lba = le64_to_cpu(id->nsze);
desc->log2blksz = ns->lba_shift;
desc->blksz = 1 << ns->lba_shift;
desc->bdev = udev;
@@ -835,6 +831,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,8 +876,46 @@ 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 = 1; i <= ndev->nn; i++) {
+ struct udevice *ns_udev;
+ char name[20];
+
+ memset(id, 0, sizeof(*id));
+ if (nvme_identify(ndev, i, 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.
+ */
+ 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_id;
+ }
+
+ free(id);
return 0;
+free_id:
+ free(id);
free_queue:
free((void *)ndev->queues);
free_nvme:
diff --git a/drivers/nvme/nvme.h b/drivers/nvme/nvme.h
index aa4b3ba..c6aae4d 100644
--- a/drivers/nvme/nvme.h
+++ b/drivers/nvme/nvme.h
@@ -633,8 +633,6 @@ struct nvme_ns {
int devnum;
int lba_shift;
u8 flbas;
- u64 mode_select_num_blocks;
- u32 mode_select_block_len;
};
#endif /* __DRIVER_NVME_H__ */