|
34 | 34 | #include "log.h" |
35 | 35 | #include "private.h" |
36 | 36 |
|
| 37 | +const char *nvme_slots_sysfs_dir = "/sys/bus/pci/slots"; |
| 38 | + |
37 | 39 | static struct nvme_host *default_host; |
38 | 40 |
|
39 | 41 | static void __nvme_free_host(nvme_host_t h); |
@@ -822,6 +824,11 @@ const char *nvme_ctrl_get_address(nvme_ctrl_t c) |
822 | 824 | return c->address ? c->address : ""; |
823 | 825 | } |
824 | 826 |
|
| 827 | +const char *nvme_ctrl_get_phy_slot(nvme_ctrl_t c) |
| 828 | +{ |
| 829 | + return c->phy_slot ? c->phy_slot : ""; |
| 830 | +} |
| 831 | + |
825 | 832 | const char *nvme_ctrl_get_firmware(nvme_ctrl_t c) |
826 | 833 | { |
827 | 834 | return c->firmware; |
@@ -1009,6 +1016,7 @@ void nvme_deconfigure_ctrl(nvme_ctrl_t c) |
1009 | 1016 | FREE_CTRL_ATTR(c->address); |
1010 | 1017 | FREE_CTRL_ATTR(c->dctype); |
1011 | 1018 | FREE_CTRL_ATTR(c->cntrltype); |
| 1019 | + FREE_CTRL_ATTR(c->phy_slot); |
1012 | 1020 | } |
1013 | 1021 |
|
1014 | 1022 | int nvme_disconnect_ctrl(nvme_ctrl_t c) |
@@ -1256,6 +1264,50 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_root_t r, |
1256 | 1264 | return subsys_name; |
1257 | 1265 | } |
1258 | 1266 |
|
| 1267 | +static char *nvme_ctrl_lookup_phy_slot(nvme_root_t r, const char *address) |
| 1268 | +{ |
| 1269 | + char *target_addr; |
| 1270 | + char *addr; |
| 1271 | + char *path; |
| 1272 | + int found = 0; |
| 1273 | + int ret; |
| 1274 | + DIR *slots_dir; |
| 1275 | + struct dirent *entry; |
| 1276 | + |
| 1277 | + slots_dir = opendir(nvme_slots_sysfs_dir); |
| 1278 | + if (!slots_dir) { |
| 1279 | + nvme_msg(r, LOG_WARNING, "failed to open slots dir %s\n", |
| 1280 | + nvme_slots_sysfs_dir); |
| 1281 | + return NULL; |
| 1282 | + } |
| 1283 | + |
| 1284 | + target_addr = strndup(address, 10); |
| 1285 | + while (!(entry = readdir(slots_dir))) { |
| 1286 | + if (entry->d_type == DT_DIR && |
| 1287 | + strncmp(entry->d_name, ".", 1) != 0 && |
| 1288 | + strncmp(entry->d_name, "..", 2) != 0) { |
| 1289 | + ret = asprintf(&path, "/sys/bus/pci/slots/%s", entry->d_name); |
| 1290 | + if (ret < 0) { |
| 1291 | + errno = ENOMEM; |
| 1292 | + return NULL; |
| 1293 | + } |
| 1294 | + addr = nvme_get_attr(path, "address"); |
| 1295 | + if (strcmp(addr, target_addr) == 0) { |
| 1296 | + found = 1; |
| 1297 | + free(path); |
| 1298 | + free(addr); |
| 1299 | + break; |
| 1300 | + } |
| 1301 | + free(path); |
| 1302 | + free(addr); |
| 1303 | + } |
| 1304 | + } |
| 1305 | + free(target_addr); |
| 1306 | + if (found) |
| 1307 | + return strdup(entry->d_name); |
| 1308 | + return NULL; |
| 1309 | +} |
| 1310 | + |
1259 | 1311 | static int nvme_configure_ctrl(nvme_root_t r, nvme_ctrl_t c, const char *path, |
1260 | 1312 | const char *name) |
1261 | 1313 | { |
@@ -1297,6 +1349,7 @@ static int nvme_configure_ctrl(nvme_root_t r, nvme_ctrl_t c, const char *path, |
1297 | 1349 | } |
1298 | 1350 | c->cntrltype = nvme_get_ctrl_attr(c, "cntrltype"); |
1299 | 1351 | c->dctype = nvme_get_ctrl_attr(c, "dctype"); |
| 1352 | + c->phy_slot = nvme_ctrl_lookup_phy_slot(r, c->address); |
1300 | 1353 |
|
1301 | 1354 | errno = 0; /* cleanup after nvme_get_ctrl_attr() */ |
1302 | 1355 | return 0; |
|
0 commit comments