All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zhikang Zhang <zhikang.zhang@nxp.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [RFC,v2 2/2] NVMe: add nvme commands
Date: Fri, 21 Apr 2017 11:01:29 +0800	[thread overview]
Message-ID: <1492743689-40341-3-git-send-email-zhikang.zhang@nxp.com> (raw)
In-Reply-To: <1492743689-40341-1-git-send-email-zhikang.zhang@nxp.com>

Add nvme commands in U-Boot command line.

1. "nvme list" - show all available NVMe blk devices
2. "nvme info" - show current or a specific NVMe blk device
3. "nvme device" - show or set current device
4. "nvme part" - print partition table
5. "nvme read" - read data from NVMe blk device
6. "nvme write" - write data to NVMe blk device

Signed-off-by: Zhikang Zhang <zhikang.zhang@nxp.com>
Signed-off-by: Wenbin Song <wenbin.song@nxp.com>
---
Changes for v2:
	- remove the calling of "initialie" in fuction "do_nvmecops"
	- change the function "do_nvme_info" to support BLK uclass
---
 cmd/Kconfig     |   9 +++
 cmd/Makefile    |   1 +
 cmd/nvme.c      | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 disk/part.c     |   6 ++
 doc/README.nvme |  54 ++++++++++++++++++
 5 files changed, 243 insertions(+)
 create mode 100644 cmd/nvme.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 13dc46a..e30814b 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -502,6 +502,15 @@ config CMD_USB
 	help
 	  USB support.
 
+config CMD_NVME
+	bool "NVMe"
+	depends on NVME
+	help
+	  NVMe support.
+	  This enables nvme commands in command line
+	  You can use comamnd "nvme" to show what commands it supports
+	  such as "nvme info" "nvme list".
+
 config CMD_DFU
 	bool "dfu"
 	select USB_FUNCTION_DFU
diff --git a/cmd/Makefile b/cmd/Makefile
index 97c862f..941100e 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_CMD_REISER) += reiser.o
 obj-$(CONFIG_CMD_REMOTEPROC) += remoteproc.o
 obj-$(CONFIG_SANDBOX) += host.o
 obj-$(CONFIG_CMD_SATA) += sata.o
+obj-$(CONFIG_CMD_NVME) += nvme.o
 obj-$(CONFIG_CMD_SF) += sf.o
 obj-$(CONFIG_SCSI) += scsi.o disk.o
 obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
diff --git a/cmd/nvme.c b/cmd/nvme.c
new file mode 100644
index 0000000..8dc1f14
--- /dev/null
+++ b/cmd/nvme.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2017 NXP Semiconductors
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <part.h>
+#include <nvme.h>
+#include <linux/math64.h>
+
+static int nvme_curr_device;
+
+static int do_nvme_list(cmd_tbl_t *cmdtp, int flag,
+		int argc, char * const argv[])
+{
+	blk_list_devices(IF_TYPE_NVME);
+	return CMD_RET_SUCCESS;
+}
+
+static int do_nvme_info(cmd_tbl_t *cmdtp, int flag,
+		int argc, char * const argv[])
+{
+	int devnum;
+	struct udevice *udev;
+	int ret;
+	if (argc > 1)
+		devnum = (int)simple_strtoul(argv[1], NULL, 10);
+	else
+		devnum = nvme_curr_device;
+	ret = blk_get_device(IF_TYPE_NVME, devnum, &udev);
+	if (ret < 0)
+		return ret;
+
+	nvme_print_info(udev);
+	return CMD_RET_SUCCESS;
+}
+
+static int do_nvme_device(cmd_tbl_t *cmdtp, int flag,
+		int argc, char * const argv[])
+{
+	if (argc > 1) {
+		int devnum = (int)simple_strtoul(argv[1], NULL, 10);
+		if (!blk_show_device(IF_TYPE_NVME, devnum)) {
+			nvme_curr_device = devnum;
+			printf("... is now current device\n");
+		} else {
+			return CMD_RET_FAILURE;
+		}
+	} else {
+		blk_show_device(IF_TYPE_NVME, nvme_curr_device);
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_nvme_part(cmd_tbl_t *cmdtp, int flag,
+		int argc, char * const argv[])
+{
+	if (argc > 1) {
+		int devnum = (int)simple_strtoul(argv[2], NULL, 10);
+		if (blk_print_part_devnum(IF_TYPE_NVME, devnum)) {
+			printf("\nNVME device %d not available\n", devnum);
+			return CMD_RET_FAILURE;
+		}
+	} else {
+		blk_print_part_devnum(IF_TYPE_NVME, nvme_curr_device);
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_nvme_read(cmd_tbl_t *cmdtp, int flag, int argc,
+		char * const argv[])
+{
+	unsigned long time;
+	if (argc != 4)
+		return CMD_RET_USAGE;
+
+	ulong addr = simple_strtoul(argv[1], NULL, 16);
+	ulong cnt = simple_strtoul(argv[3], NULL, 16);
+	ulong n;
+	lbaint_t blk = simple_strtoul(argv[2], NULL, 16);
+
+	printf("\nNVME read: device %d block # %ld, count %ld ... ",
+	       nvme_curr_device, blk, cnt);
+
+	time = get_timer(0);
+	n = blk_read_devnum(IF_TYPE_NVME, nvme_curr_device, blk,
+			    cnt, (ulong *)addr);
+	time = get_timer(time);
+
+	printf("read: %s\n", (n == cnt) ? "OK" : "ERROR");
+	printf("%lu bytes read in %lu ms", cnt * 512, time);
+	if (time > 0) {
+		puts(" (");
+		print_size(div_u64(cnt * 512, time) * 1000, "/s");
+		puts(")");
+	}
+	puts("\n");
+	return (n == cnt) ? 0 : 1;
+}
+
+static int do_nvme_write(cmd_tbl_t *cmdtp, int flag, int argc,
+		char * const argv[])
+{
+	unsigned long time;
+	if (argc != 4)
+		return CMD_RET_USAGE;
+
+	ulong addr = simple_strtoul(argv[1], NULL, 16);
+	ulong cnt = simple_strtoul(argv[3], NULL, 16);
+	ulong n;
+	lbaint_t blk = simple_strtoul(argv[2], NULL, 16);
+
+	printf("\nNVME write: device %d block # %ld, count %ld ... ",
+	       nvme_curr_device, blk, cnt);
+
+	time = get_timer(0);
+	n = blk_write_devnum(IF_TYPE_NVME, nvme_curr_device, blk,
+			    cnt, (ulong *)addr);
+	time = get_timer(time);
+
+	printf("write: %s\n", (n == cnt) ? "OK" : "ERROR");
+	printf("%lu bytes read in %lu ms", cnt * 512, time);
+	if (time > 0) {
+		puts(" (");
+		print_size(div_u64(cnt * 512, time) * 1000, "/s");
+		puts(")");
+	}
+	puts("\n");
+	return (n == cnt) ? 0 : 1;
+}
+
+static cmd_tbl_t cmd_nvme[] = {
+	U_BOOT_CMD_MKENT(list, 1, 1, do_nvme_list, "", ""),
+	U_BOOT_CMD_MKENT(info, 2, 1, do_nvme_info, "", ""),
+	U_BOOT_CMD_MKENT(device, 2, 1, do_nvme_device, "", ""),
+	U_BOOT_CMD_MKENT(part, 2, 1, do_nvme_part, "", ""),
+	U_BOOT_CMD_MKENT(write, 4, 0, do_nvme_write, "", ""),
+	U_BOOT_CMD_MKENT(read, 4, 0, do_nvme_read, "", "")
+};
+
+static int do_nvmecops(cmd_tbl_t *cmdtp, int flag, int argc,
+		char * const argv[])
+{
+	cmd_tbl_t *cp;
+
+	cp = find_cmd_tbl(argv[1], cmd_nvme, ARRAY_SIZE(cmd_nvme));
+
+	argc--;
+	argv++;
+
+	if (cp == NULL || argc > cp->maxargs)
+		return CMD_RET_USAGE;
+
+	if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
+		return CMD_RET_SUCCESS;
+
+	return cp->cmd(cmdtp, flag, argc, argv);
+}
+
+U_BOOT_CMD(
+	nvme, 8, 1, do_nvmecops,
+	"NVME sub system",
+	"\nnvme list - show all available NVME blk devices\n"
+	"nvme info [dev]- show current or a specific NVME blk device\n"
+	"nvme device [dev] - show or set current device\n"
+	"nvme part [dev] - print partition table\n"
+	"nvme read  addr blk# cnt\n"
+	"nvme write addr blk# cnt"
+);
diff --git a/disk/part.c b/disk/part.c
index cd44702..983104e 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -140,6 +140,12 @@ void dev_print (struct blk_desc *dev_desc)
 	case IF_TYPE_DOC:
 		puts("device type DOC\n");
 		return;
+	case IF_TYPE_NVME:
+		printf("Vendor: %s Rev: %s Prod: %s\n",
+		       dev_desc->vendor,
+		       dev_desc->revision,
+		       dev_desc->product);
+	break;
 	case IF_TYPE_UNKNOWN:
 		puts("device type unknown\n");
 		return;
diff --git a/doc/README.nvme b/doc/README.nvme
index b429715..9ecb314 100644
--- a/doc/README.nvme
+++ b/doc/README.nvme
@@ -28,3 +28,57 @@ You can also get/set other features through standard commands.
 NVMe Config Switches:
 ---------------------
 CONFIG_NVME		enables basic NVMe device support
+CONFIG_CMD_NVME		enables basic NVMe command
+
+
+NVMe usage in U-boot:
+---------------------
+
+Two ways to operate the hard disk
+
+* Raw read/write block from/to NVMe hard disk;
+* load read file from ext2/fat/ext4 filesytems in hard disk
+
+1 How to know the information of all the NVMe hard disk?
+
+	=> nvme info
+
+2 How to list all of the NVMe hard disks?
+
+	=> nvme list
+
+Device 0: Vendor: 0x8086 Rev: 8DV10131 Prod: CVFT535600LS400BGN
+	    Type: Hard Disk
+	    Capacity: 381554.0 MB = 372.6 GB (781422768 x 512)
+
+3 How to raw write the kernel.itb to a NVMe hard disk?
+
+	Notes: Hard disk sectors are normally 512 bytes, so
+		0x1000 sectors = 2 MBytes
+
+	wirte kernel.itb
+	=> tftp 80000000 /tftpboot/kernel.itb
+	=> nvme write 80000000 0 11000
+
+4 How to raw read the kernel.itb from a NVMe hard disk?
+
+	load kernel.itb
+	=> nvme read a0000000 0 11000
+
+	boot
+	=> bootm a0000000
+
+5 How to load image from fat filesystem in U-boot?
+
+	U-boot doesn't support fat write to hard disk, so
+	the files must be written by other means (e.g. linux).
+
+	=> fatls nvme 0:1
+	 32376967   kernel.itb
+	 22929408   100m
+
+	2 file(s), 0 dir(s)
+
+	=> fatload nvme 0:1 a0000000 /kernel.itb
+
+	=> bootm a0000000
-- 
2.1.0.27.g96db324

      parent reply	other threads:[~2017-04-21  3:01 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-21  3:01 [U-Boot] (no subject) Zhikang Zhang
2017-04-21  3:01 ` [U-Boot] [RFC,v2 1/2] NVMe: add NVMe driver support Zhikang Zhang
2017-04-21  3:01 ` Zhikang Zhang [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1492743689-40341-3-git-send-email-zhikang.zhang@nxp.com \
    --to=zhikang.zhang@nxp.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.