From 366c120e29e73979bcd84a4a81fd4c0054f80cfe Mon Sep 17 00:00:00 2001 From: Pascal Terjan Date: Thu, 11 Jun 2020 20:59:10 +0000 Subject: Add support for NVME disks (mga#26708) The code is generic using sysfs and the only NVME specific code is the path, we should switch to it for all disks. --- mdk-stage1/NEWS | 2 ++ mdk-stage1/probing.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) (limited to 'mdk-stage1') diff --git a/mdk-stage1/NEWS b/mdk-stage1/NEWS index 43966418c..8577d216a 100644 --- a/mdk-stage1/NEWS +++ b/mdk-stage1/NEWS @@ -1,3 +1,5 @@ +- add support for NVME disks + 2.43 - sync with kernel 5.5 diff --git a/mdk-stage1/probing.c b/mdk-stage1/probing.c index 3c70ca952..e9cc60af0 100644 --- a/mdk-stage1/probing.c +++ b/mdk-stage1/probing.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "stage1.h" #include "log.h" @@ -875,6 +876,82 @@ void find_media(enum media_bus bus) count++; } } + /* ----------------------------------------------- */ + /* TODO: This code is generic for any block device, we should switch to only use it + * and add some support to check capabilities and type. + * The glob can not be changed before removing the rest of the code or disks would be listed twice. + * */ + log_message("looking for NVME"); + { + glob_t globbuf; + glob("/sys/block/nvme*/device/vendor", 0, NULL, &globbuf); + + for (int i = 0; i < globbuf.gl_pathc; i++) { + char *path = globbuf.gl_pathv[i]; + char *model = "Unknown NVME Disk"; + + // Get device name by skipping /sys/block/ + char *name_end = strchr(path + 11, '/'); + if (!name_end) { + log_message("Strange path: %s", path); + continue; + } + + // Read vendor name + int fd = open(path, O_RDONLY); + int vendor_length = 0; + buf[0] = '\0'; + if (fd == -1) { + log_message("Failed to open %s for reading", path); + } else { + int n = read(fd, buf, sizeof(buf)); + if (n == -1) { + log_message("Couldn't read vendor file (%s)", path); + } else { + // Strip whitespaces and newline + for (int j = n-1; j >= 0; j--) { + if (buf[j] == '\n' || buf[j] == ' ') + continue; + vendor_length = j+1; + break; + } + buf[vendor_length] = ' '; + buf[vendor_length+1] = '\0'; + vendor_length++; + } + close(fd); + } + + // Read model name + char *dirpath = strrchr(path, '/'); + strcpy(dirpath+1, "model"); + fd = open(path, O_RDONLY); + if (fd == -1) { + log_message("Failed to open %s for reading", path); + } else { + int n = read(fd, buf+vendor_length, sizeof(buf)-vendor_length); + if (n == -1) { + log_message("Couldn't read model file (%s)", path); + } else { + // Strip whitespaces and newline + for (int j = n-1; j >= 0; j--) { + if (buf[vendor_length+j] == '\n' || buf[vendor_length+j] == ' ') + continue; + buf[vendor_length+j+1] = '\0'; + break; + } + model = buf; + } + close(fd); + } + + tmp[count].name = strndup(path + 11, name_end - path - 11); + tmp[count].type = DISK; + tmp[count].model = strdup(model); + count++; + } + globfree(&globbuf); + } find_media_after_scsi: /* ----------------------------------------------- */ -- cgit v1.2.1