aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2024-11-05 01:28:40 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2024-11-05 01:28:40 +0000
commit9e1db51d4b5fce8a1ea7271018970760e396500c (patch)
tree466907080849d8c7680f83af06d00cd49da93e09
parent326e20fc1252577f96df0e53360507180cc9d153 (diff)
-rw-r--r--sbin/nvmecontrol/devlist.c19
-rw-r--r--sbin/nvmecontrol/nvmecontrol.c24
-rw-r--r--sbin/nvmecontrol/nvmecontrol.h1
3 files changed, 41 insertions, 3 deletions
diff --git a/sbin/nvmecontrol/devlist.c b/sbin/nvmecontrol/devlist.c
index b2816339bc80..d2386e7ea800 100644
--- a/sbin/nvmecontrol/devlist.c
+++ b/sbin/nvmecontrol/devlist.c
@@ -116,9 +116,10 @@ static bool
scan_controller(int ctrlr)
{
struct nvme_controller_data cdata;
+ struct nvme_ns_list nslist;
char name[64];
uint8_t mn[64];
- uint32_t i;
+ uint32_t nsid;
int fd, ret;
snprintf(name, sizeof(name), "%s%d", NVME_CTRLR_PREFIX, ctrlr);
@@ -139,8 +140,20 @@ scan_controller(int ctrlr)
nvme_strvis(mn, cdata.mn, sizeof(mn), NVME_MODEL_NUMBER_LENGTH);
printf("%6s: %s\n", name, mn);
- for (i = 0; i < cdata.nn; i++) {
- scan_namespace(fd, ctrlr, i + 1);
+ nsid = 0;
+ for (;;) {
+ if (read_active_namespaces(fd, nsid, &nslist) != 0)
+ break;
+ for (u_int i = 0; i < nitems(nslist.ns); i++) {
+ nsid = nslist.ns[i];
+ if (nsid == 0) {
+ break;
+ }
+
+ scan_namespace(fd, ctrlr, nsid);
+ }
+ if (nsid == 0 || nsid >= NVME_GLOBAL_NAMESPACE_TAG - 1)
+ break;
}
close(fd);
diff --git a/sbin/nvmecontrol/nvmecontrol.c b/sbin/nvmecontrol/nvmecontrol.c
index 8ad9703de9f6..b38fb8038fc3 100644
--- a/sbin/nvmecontrol/nvmecontrol.c
+++ b/sbin/nvmecontrol/nvmecontrol.c
@@ -143,6 +143,30 @@ read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata)
}
int
+read_active_namespaces(int fd, uint32_t nsid, struct nvme_ns_list *nslist)
+{
+ struct nvme_pt_command pt;
+
+ memset(&pt, 0, sizeof(pt));
+ pt.cmd.opc = NVME_OPC_IDENTIFY;
+ pt.cmd.nsid = htole32(nsid);
+ pt.cmd.cdw10 = htole32(2);
+ pt.buf = nslist;
+ pt.len = sizeof(*nslist);
+ pt.is_read = 1;
+
+ if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
+ return (errno);
+
+ /* Convert data to host endian */
+ nvme_ns_list_swapbytes(nslist);
+
+ if (nvme_completion_is_error(&pt.cpl))
+ return (EIO);
+ return (0);
+}
+
+int
open_dev(const char *str, int *fd, int write, int exit_on_error)
{
char full_path[MAXPATHLEN];
diff --git a/sbin/nvmecontrol/nvmecontrol.h b/sbin/nvmecontrol/nvmecontrol.h
index 394a88608692..968e9c20160e 100644
--- a/sbin/nvmecontrol/nvmecontrol.h
+++ b/sbin/nvmecontrol/nvmecontrol.h
@@ -81,6 +81,7 @@ int open_dev(const char *str, int *fd, int write, int exit_on_error);
void get_nsid(int fd, char **ctrlr_str, uint32_t *nsid);
int read_controller_data(int fd, struct nvme_controller_data *cdata);
int read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata);
+int read_active_namespaces(int fd, uint32_t nsid, struct nvme_ns_list *nslist);
void print_hex(void *data, uint32_t length);
void print_namespace(struct nvme_namespace_data *nsdata);
void read_logpage(int fd, uint8_t log_page, uint32_t nsid, uint8_t lsp,