[U-Boot] [RFC, 1/2] NVMe: add NVMe driver support

Zhikang and Tom,
Sorry for entering the list like this, however I wanted to reply to this topic from my work account. I attempted to email Zhikang separately however the email was bounced back.
I needed to make some changes in order to get Zhikang's work running on our Macchiattobin board with a Samsung 960 EVO NVMe drive. I wanted to make this patchset accessible so it could be included in the next submission to mainline it. No reason to duplicate work.
Since this is just a patchset for the RFC I will only leave it here for whomever integrates the NVMe support, or if additional users want to test against it.
-Jon

Hi Jon,
On Fri, Jul 28, 2017 at 3:51 PM, Jon Nettleton jon@solid-run.com wrote:
Zhikang and Tom,
Sorry for entering the list like this, however I wanted to reply to this topic from my work account. I attempted to email Zhikang separately however the email was bounced back.
I needed to make some changes in order to get Zhikang's work running on our Macchiattobin board with a Samsung 960 EVO NVMe drive. I wanted to make this patchset accessible so it could be included in the next submission to mainline it. No reason to duplicate work.
Since this is just a patchset for the RFC I will only leave it here for whomever integrates the NVMe support, or if additional users want to test against it.
Can you send the patch out instead of attachment? I may have some time to try the NVMe driver next week.
Regards, Bin

Well it is a series. Some can probably be squashed. I can post it to a branch in github if it is easier. Otherwise here is the rest.
From f1ab1f30fe52bea7dc5c647b0570d73d907b8d90 Mon Sep 17 00:00:00 2001
From: Jon Nettleton jon@solid-run.com Date: Fri, 28 Jul 2017 08:54:09 +0200 Subject: [PATCH 1/6] nvme: Only support CONFIG_BLK
There is no reason to support devices that don't work with CONFIG_BLK. If needed the other drivers should be fixed.
Signed-off-by: Jon Nettleton jon@solid-run.com --- common/nvme.c | 33 --------------------------- drivers/block/Kconfig | 1 + drivers/block/nvme.c | 63 --------------------------------------------------- drivers/block/nvme.h | 2 -- include/nvme.h | 10 +------- 5 files changed, 2 insertions(+), 107 deletions(-)
diff --git a/common/nvme.c b/common/nvme.c index ed3250f43f..cdbfa665a0 100644 --- a/common/nvme.c +++ b/common/nvme.c @@ -21,7 +21,6 @@ struct blk_desc *nvme_get_dev(int dev) } #endif
-#ifdef CONFIG_BLK struct udevice *udev; static unsigned long nvme_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst) @@ -34,19 +33,6 @@ static unsigned long nvme_bwrite(struct udevice *dev, lbaint_t start, { return nvme_write(dev, start, blkcnt, buffer); } -#else -static unsigned long nvme_bread(struct blk_desc *block_dev, lbaint_t start, - lbaint_t blkcnt, void *dst) -{ - return nvme_read(block_dev->devnum, start, blkcnt, dst); -} - -static unsigned long nvme_bwrite(struct blk_desc *block_dev, lbaint_t start, - lbaint_t blkcnt, const void *buffer) -{ - return nvme_write(block_dev->devnum, start, blkcnt, buffer); -} -#endif
int __nvme_initialize(void) { @@ -54,25 +40,15 @@ int __nvme_initialize(void) int i;
for (i = 0; i < CONFIG_SYS_NVME_MAX_DEVICE; i++) { -#ifdef CONFIG_BLK rc = init_nvme(udev); if (!rc) rc = scan_nvme(udev); -#else - rc = init_nvme(i); - if (!rc) - rc = scan_nvme(i); -#endif
if (!rc && nvme_dev_desc[i].lba > 0) { nvme_dev_desc[i].if_type = IF_TYPE_NVME; nvme_dev_desc[i].devnum = i; nvme_dev_desc[i].part_type = PART_TYPE_UNKNOWN; nvme_dev_desc[i].type = DEV_TYPE_HARDDISK; -#ifndef CONFIG_BLK - nvme_dev_desc[i].block_read = nvme_bread; - nvme_dev_desc[i].block_write = nvme_bwrite; -#endif
part_init(&nvme_dev_desc[i]); ret = i; @@ -88,7 +64,6 @@ int __nvme_initialize(void) } int nvme_initialize(void) __attribute__((weak, alias("__nvme_initialize")));
-#ifdef CONFIG_BLK static void nvme_name(char *str, int cardnum) { sprintf(str, "nvme#%u", cardnum); @@ -117,11 +92,3 @@ U_BOOT_DRIVER(nvme) = { .priv_auto_alloc_size = sizeof(struct nvme_ns), }; U_BOOT_PCI_DEVICE(nvme, nvme_supported); -#else -U_BOOT_LEGACY_BLK(nvme) = { - .if_typename = "nvme", - .if_type = IF_TYPE_NVME, - .max_devs = CONFIG_SYS_NVME_MAX_DEVICE, - .desc = nvme_dev_desc, -}; -#endif diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 129208f980..de1a3a50c1 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -63,6 +63,7 @@ endmenu config NVME bool "Support NVMe devices" depends on PCI + depends on BLK help This option enables supporting for all NVMe devices. It supports the basic functions before using NVMe devices diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c index 2e06477206..80fbd27d95 100644 --- a/drivers/block/nvme.c +++ b/drivers/block/nvme.c @@ -549,13 +549,8 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev) if (ctrl->mdts) dev->max_transfer_shift = (ctrl->mdts + shift);
-#ifdef CONFIG_BLK dm_pci_read_config16(dev->pdev, PCI_VENDOR_ID, &vendor); dm_pci_read_config16(dev->pdev, PCI_DEVICE_ID, &device); -#else - pci_read_config_word(dev->pci_dev, PCI_VENDOR_ID, &vendor); - pci_read_config_word(dev->pci_dev, PCI_DEVICE_ID, &device); -#endif if ((vendor == PCI_VENDOR_ID_INTEL) && (device == 0x0953) && ctrl->vs[3]) { unsigned int max_transfer_shift; @@ -571,22 +566,14 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev) return 0; }
-#ifdef CONFIG_BLK int init_nvme(struct udevice *udev) -#else -int init_nvme(int devnum) -#endif { static int init_done; pci_dev_t pci_dev; int ret; -#ifdef CONFIG_BLK struct nvme_ns *ns = dev_get_priv(udev); struct nvme_dev *dev = ns->dev; int devnum = trailing_strtol(udev->name); -#else - struct nvme_dev *dev; -#endif u32 val; u64 cap;
@@ -611,15 +598,9 @@ int init_nvme(int devnum)
dev->instance = nvme_info.idx - 1; INIT_LIST_HEAD(&dev->namespaces); -#ifdef CONFIG_BLK dev->pdev = udev; dev->bar = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); -#else - dev->pci_dev = pci_dev; - dev->bar = pci_map_bar(dev->pci_dev, PCI_BASE_ADDRESS_0, - PCI_REGION_MEM); -#endif if (readl(&dev->bar->csts) == -1) { ret = -ENODEV; printf("Error: nvme%d: Out of Memory!\n", nvme_info.idx - 1); @@ -644,25 +625,13 @@ int init_nvme(int devnum)
/* Try to enable I/O accesses and bus-mastering */ val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; -#ifdef CONFIG_BLK dm_pci_write_config32(udev, PCI_COMMAND, val); -#else - pci_write_config_dword(dev->pci_dev, PCI_COMMAND, val); -#endif
/* Print a debug message with the IO base address */ -#ifdef CONFIG_BLK dm_pci_read_config32(udev, PCI_BASE_ADDRESS_0, &val); -#else - pci_read_config_dword(dev->pci_dev, PCI_BASE_ADDRESS_0, &val); -#endif
/* Make sure it worked */ -#ifdef CONFIG_BLK dm_pci_read_config32(udev, PCI_COMMAND, &val); -#else - pci_read_config_dword(dev->pci_dev, PCI_COMMAND, &val); -#endif if (!(val & PCI_COMMAND_MEMORY)) { printf("Can't enable I/O memory\n"); ret = -ENOSPC; @@ -732,18 +701,11 @@ static struct nvme_ns *find_ns_by_devnum(int devnum) return NULL; }
-#ifdef CONFIG_BLK int scan_nvme(struct udevice *udev) { struct nvme_ns *ns = dev_get_priv(udev); struct nvme_dev *dev = ns->dev; int devnum = trailing_strtol(udev->name); -#else -int scan_nvme(int devnum) -{ - struct nvme_ns *ns; - struct nvme_dev *dev; -#endif int ret; u8 flbas; u16 vendor; @@ -783,15 +745,10 @@ int scan_nvme(int devnum) nvme_dev_desc[devnum].lba = ns->mode_select_num_blocks; nvme_dev_desc[devnum].log2blksz = ns->lba_shift; nvme_dev_desc[devnum].blksz = 1 << ns->lba_shift; -#ifdef CONFIG_BLK nvme_dev_desc[devnum].bdev = dev->pdev; dm_pci_read_config16(dev->pdev, PCI_VENDOR_ID, &vendor); udev->priv = ns; udev->uclass_platdata = (void *)&nvme_dev_desc[devnum]; -#else - nvme_dev_desc[devnum].priv = (void *)ns; - pci_read_config_word(dev->pci_dev, PCI_VENDOR_ID, &vendor); -#endif sprintf(vendor_c, "0x%.4x", vendor); memcpy(nvme_dev_desc[devnum].product, dev->serial, sizeof(dev->serial)); @@ -895,13 +852,9 @@ static void print_metadata_cap(u8 mc, int devnum)
int nvme_print_info(int devnum) { -#ifdef CONFIG_BLK struct udevice *udev; blk_get_device(IF_TYPE_NVME, devnum, &udev); struct nvme_ns *ns = dev_get_priv(udev); -#else - struct nvme_ns *ns = nvme_dev_desc[devnum].priv; -#endif if (!ns) { printf("Can not find device %d\n", devnum); return -EINVAL; @@ -927,20 +880,12 @@ int nvme_print_info(int devnum) return 0; }
-#ifdef CONFIG_BLK ulong nvme_write(struct udevice *udev, ulong blknr, lbaint_t blkcnt, const void *buffer) { struct nvme_ns *ns = dev_get_priv(udev); struct nvme_dev *dev = ns->dev; int devnum = ns->devnum; -#else -ulong nvme_write(int devnum, ulong blknr, lbaint_t blkcnt, - const void *buffer) -{ - struct nvme_ns *ns = nvme_dev_desc[devnum].priv; - struct nvme_dev *dev = ns->dev; -#endif struct nvme_command c; int status; u64 prp2; @@ -987,20 +932,12 @@ ulong nvme_write(int devnum, ulong blknr, lbaint_t blkcnt, return (total_len - temp_len) >> nvme_dev_desc[devnum].log2blksz; }
-#ifdef CONFIG_BLK ulong nvme_read(struct udevice *udev, ulong blknr, lbaint_t blkcnt, void *buffer) { struct nvme_ns *ns = dev_get_priv(udev); struct nvme_dev *dev = ns->dev; int devnum = ns->devnum; -#else -ulong nvme_read(int devnum, ulong blknr, lbaint_t blkcnt, - void *buffer) -{ - struct nvme_ns *ns = nvme_dev_desc[devnum].priv; - struct nvme_dev *dev = ns->dev; -#endif struct nvme_command c; int status; u64 prp2; diff --git a/drivers/block/nvme.h b/drivers/block/nvme.h index 9345f90a1c..f0fad95b7b 100644 --- a/drivers/block/nvme.h +++ b/drivers/block/nvme.h @@ -61,9 +61,7 @@ struct nvme_dev { struct nvme_queue **queues; u32 __iomem *dbs; unsigned int cardnum; -#ifdef CONFIG_BLK struct udevice *pdev; -#endif pci_dev_t pci_dev; int instance; uint8_t *hw_addr; diff --git a/include/nvme.h b/include/nvme.h index 3f8f94f462..e13de19163 100644 --- a/include/nvme.h +++ b/include/nvme.h @@ -7,22 +7,14 @@ #ifndef __NVME_H__ #define __NVME_H__ #include <part.h> +#include <pci.h>
-#ifdef CONFIG_BLK int init_nvme(struct udevice *udev); int scan_nvme(struct udevice *udev); ulong nvme_read(struct udevice *udev, ulong blknr, lbaint_t blkcnt, void *buffer); ulong nvme_write(struct udevice *udev, ulong blknr, lbaint_t blkcnt, const void *buffer); -#else -int init_nvme(int devnum); -int scan_nvme(int devnum); -ulong nvme_read(int devnum, ulong blknr, lbaint_t blkcnt, - void *buffer); -ulong nvme_write(int devnum, ulong blknr, lbaint_t blkcnt, - const void *buffer); -#endif int nvme_print_info(int devnum); int nvme_initialize(void); int __nvme_initialize(void);
participants (2)
-
Bin Meng
-
Jon Nettleton