diff --git a/ipl_tools/ipl_tools.h b/ipl_tools/ipl_tools.h index 576d33a8..cd9167f0 100644 --- a/ipl_tools/ipl_tools.h +++ b/ipl_tools/ipl_tools.h @@ -75,6 +75,7 @@ extern void fcp_busid_get(const char *device, char *devno); * NVME */ #define FID_MAX_LEN 11 /* 8 characters + 0x + null */ +#define NVME_DEV_MAX_LEN 15 /* "nvme" + u32 in decimal + null */ #define NVME_PATH_MAX (PATH_MAX + NAME_MAX + 1) extern void nvme_fid_get(const char *device, char *fid); diff --git a/ipl_tools/nvme.c b/ipl_tools/nvme.c index 2a959729..05c2b87c 100644 --- a/ipl_tools/nvme.c +++ b/ipl_tools/nvme.c @@ -18,15 +18,31 @@ #include "lib/util_file.h" #include "ipl_tools.h" +static void nvme_dev_from_bdev(char *dev_name) +{ + char *delim = strrchr(dev_name, 'n'); + + if (delim) + *delim = 0; +} + /* * Return the fid of a device */ void nvme_fid_get(const char *device, char *fid) { char path[PATH_MAX], buf[FID_MAX_LEN]; + char nvme_dev[NVME_DEV_MAX_LEN]; - snprintf(path, PATH_MAX, "/sys/block/%s/device/device/function_id", - device); + /* + * An NVMe may present multiple namespaces and thus block devices, even + * before partitioning, so we need the nvme part of the block + * device name to get to the PCI function ID. + */ + util_strlcpy(nvme_dev, device, sizeof(nvme_dev)); + nvme_dev_from_bdev(nvme_dev); + + snprintf(path, PATH_MAX, "/sys/class/nvme/%s/device/function_id", nvme_dev); if (util_file_read_line(buf, FID_MAX_LEN, path)) ERR_EXIT_ERRNO("Could not read from \"%s\"", path);