From b9b16d5170f23433a30cb88eefd2ab30b48d151e Mon Sep 17 00:00:00 2001 From: Yair Elharrar Date: Thu, 23 Jan 2020 14:16:39 +0200 Subject: [PATCH] list-subsys: when running on old kernels, get PCIe B:D.f address from sysfs Signed-off-by: Yair Elharrar --- nvme-topology.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/nvme-topology.c b/nvme-topology.c index 4317939..55ad8c1 100644 --- a/nvme-topology.c +++ b/nvme-topology.c @@ -89,6 +89,56 @@ err_free_path: return NULL; } +static char *path_trim_last(char *path, char needle) +{ + int i; + i = strlen(path); + if (i>0 && path[i-1] == needle) // remove trailing slash + path[--i] = 0; + for (; i>0; i--) + if (path[i] == needle) { + path[i] = 0; + return path+i+1; + } + return NULL; +} + +static void legacy_get_pci_bdf(char *node, char *bdf) +{ + int ret; + char path[264], nodetmp[264]; + struct stat st; + char *p, *__path = path; + + bdf[0] = 0; + strcpy(nodetmp, node); + p = path_trim_last(nodetmp, '/'); + sprintf(path, "/sys/block/%s/device", p); + ret = readlink(path, nodetmp, sizeof(nodetmp)); + if (ret <= 0) + return; + nodetmp[ret] = 0; + /* The link value is either "device -> ../../../0000:86:00.0" or "device -> ../../nvme0" */ + (void) path_trim_last(path, '/'); + sprintf(path+strlen(path), "/%s/device", nodetmp); + ret = stat(path, &st); + if (ret < 0) + return; + if ((st.st_mode & S_IFLNK) == 0) { + /* follow the second link to get the PCI address */ + ret = readlink(path, __path, sizeof(path)); + if (ret <= 0) + return; + path[ret] = 0; + } + else + (void) path_trim_last(path, '/'); + + p = path_trim_last(path, '/'); + if (p && strlen(p) == 12) + strcpy(bdf, p); +} + static int scan_namespace(struct nvme_namespace *n) { int ret, fd; @@ -303,6 +353,15 @@ static int verify_legacy_ns(struct nvme_namespace *n) if (ret < 0) return ret; + if (!n->ctrl->transport && !n->ctrl->address) { + char tmp_address[64] = ""; + legacy_get_pci_bdf(path, tmp_address); + if (tmp_address[0]) { + asprintf(&n->ctrl->transport, "pcie"); + asprintf(&n->ctrl->address, tmp_address); + } + } + fd = open(path, O_RDONLY); free (path); -- 2.49.0