imsm: add support for NVMe devices

Recognize Intel(R) NVMe devices as IMSM-capable.

Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
Pawel Baldysiak 2014-11-19 13:53:28 +01:00 committed by NeilBrown
parent 81188ef870
commit 614902f64e
3 changed files with 56 additions and 6 deletions

View File

@ -65,6 +65,8 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver)
type = SYS_DEV_SAS; type = SYS_DEV_SAS;
else if (strcmp(driver, "ahci") == 0) else if (strcmp(driver, "ahci") == 0)
type = SYS_DEV_SATA; type = SYS_DEV_SATA;
else if (strcmp(driver, "nvme") == 0)
type = SYS_DEV_NVME;
else else
type = SYS_DEV_UNKNOWN; type = SYS_DEV_UNKNOWN;
@ -174,7 +176,7 @@ static __u16 devpath_to_vendor(const char *dev_path)
struct sys_dev *find_intel_devices(void) struct sys_dev *find_intel_devices(void)
{ {
struct sys_dev *ahci, *isci; struct sys_dev *ahci, *isci, *nvme;
if (valid_time > time(0) - 10) if (valid_time > time(0) - 10)
return intel_devices; return intel_devices;
@ -184,14 +186,24 @@ struct sys_dev *find_intel_devices(void)
isci = find_driver_devices("pci", "isci"); isci = find_driver_devices("pci", "isci");
ahci = find_driver_devices("pci", "ahci"); ahci = find_driver_devices("pci", "ahci");
nvme = find_driver_devices("pci", "nvme");
if (!ahci) { if (!isci && !ahci) {
ahci = nvme;
} else if (!ahci) {
ahci = isci; ahci = isci;
struct sys_dev *elem = ahci;
while (elem->next)
elem = elem->next;
elem->next = nvme;
} else { } else {
struct sys_dev *elem = ahci; struct sys_dev *elem = ahci;
while (elem->next) while (elem->next)
elem = elem->next; elem = elem->next;
elem->next = isci; elem->next = isci;
while (elem->next)
elem = elem->next;
elem->next = nvme;
} }
intel_devices = ahci; intel_devices = ahci;
valid_time = time(0); valid_time = time(0);
@ -497,6 +509,33 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba)
return ret; return ret;
} }
const struct imsm_orom *find_imsm_nvme(struct sys_dev *hba)
{
static const struct imsm_orom *nvme_orom;
if (hba->type != SYS_DEV_NVME)
return NULL;
if (!nvme_orom) {
struct imsm_orom nvme_orom_compat = {
.signature = IMSM_NVME_OROM_COMPAT_SIGNATURE,
.rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 |
IMSM_OROM_RLC_RAID10 | IMSM_OROM_RLC_RAID5,
.sss = IMSM_OROM_SSS_4kB | IMSM_OROM_SSS_8kB |
IMSM_OROM_SSS_16kB | IMSM_OROM_SSS_32kB |
IMSM_OROM_SSS_64kB | IMSM_OROM_SSS_128kB,
.dpa = IMSM_OROM_DISKS_PER_ARRAY_NVME,
.tds = IMSM_OROM_TOTAL_DISKS_NVME,
.vpa = IMSM_OROM_VOLUMES_PER_ARRAY,
.vphba = IMSM_OROM_TOTAL_DISKS_NVME / 2 * IMSM_OROM_VOLUMES_PER_ARRAY,
.attr = IMSM_OROM_ATTR_2TB | IMSM_OROM_ATTR_2TB_DISK,
};
nvme_orom = add_orom(&nvme_orom_compat);
}
add_orom_device_id(nvme_orom, hba->dev_id);
return nvme_orom;
}
const struct imsm_orom *find_imsm_capability(struct sys_dev *hba) const struct imsm_orom *find_imsm_capability(struct sys_dev *hba)
{ {
const struct imsm_orom *cap = get_orom_by_device_id(hba->dev_id); const struct imsm_orom *cap = get_orom_by_device_id(hba->dev_id);
@ -504,10 +543,13 @@ const struct imsm_orom *find_imsm_capability(struct sys_dev *hba)
if (cap) if (cap)
return cap; return cap;
if (hba->type == SYS_DEV_NVME)
return find_imsm_nvme(hba);
if ((cap = find_imsm_efi(hba)) != NULL) if ((cap = find_imsm_efi(hba)) != NULL)
return cap; return cap;
if ((cap = find_imsm_hba_orom(hba)) != NULL) if ((cap = find_imsm_hba_orom(hba)) != NULL)
return cap; return cap;
return NULL; return NULL;
} }

View File

@ -23,6 +23,7 @@
struct imsm_orom { struct imsm_orom {
__u8 signature[4]; __u8 signature[4];
#define IMSM_OROM_SIGNATURE "$VER" #define IMSM_OROM_SIGNATURE "$VER"
#define IMSM_NVME_OROM_COMPAT_SIGNATURE "$NVM"
__u8 table_ver_major; /* Currently 2 (can change with future revs) */ __u8 table_ver_major; /* Currently 2 (can change with future revs) */
__u8 table_ver_minor; /* Currently 2 (can change with future revs) */ __u8 table_ver_minor; /* Currently 2 (can change with future revs) */
__u16 major_ver; /* Example: 8 as in 8.6.0.1020 */ __u16 major_ver; /* Example: 8 as in 8.6.0.1020 */
@ -60,12 +61,15 @@ struct imsm_orom {
#define IMSM_OROM_SSS_64MB (1 << 15) #define IMSM_OROM_SSS_64MB (1 << 15)
__u16 dpa; /* Disks Per Array supported */ __u16 dpa; /* Disks Per Array supported */
#define IMSM_OROM_DISKS_PER_ARRAY 6 #define IMSM_OROM_DISKS_PER_ARRAY 6
#define IMSM_OROM_DISKS_PER_ARRAY_NVME 12
__u16 tds; /* Total Disks Supported */ __u16 tds; /* Total Disks Supported */
#define IMSM_OROM_TOTAL_DISKS 6 #define IMSM_OROM_TOTAL_DISKS 6
#define IMSM_OROM_TOTAL_DISKS_NVME 12
__u8 vpa; /* # Volumes Per Array supported */ __u8 vpa; /* # Volumes Per Array supported */
#define IMSM_OROM_VOLUMES_PER_ARRAY 2 #define IMSM_OROM_VOLUMES_PER_ARRAY 2
__u8 vphba; /* # Volumes Per Host Bus Adapter supported */ __u8 vphba; /* # Volumes Per Host Bus Adapter supported */
#define IMSM_OROM_VOLUMES_PER_HBA 4 #define IMSM_OROM_VOLUMES_PER_HBA 4
#define IMSM_OROM_VOLUMES_PER_HBA_NVME 4
/* Attributes supported. This should map to the /* Attributes supported. This should map to the
* attributes in the MPB. Also, lower 16 bits * attributes in the MPB. Also, lower 16 bits
* should match/duplicate RLC bits above. * should match/duplicate RLC bits above.
@ -173,6 +177,7 @@ enum sys_dev_type {
SYS_DEV_UNKNOWN = 0, SYS_DEV_UNKNOWN = 0,
SYS_DEV_SAS, SYS_DEV_SAS,
SYS_DEV_SATA, SYS_DEV_SATA,
SYS_DEV_NVME,
SYS_DEV_MAX SYS_DEV_MAX
}; };

View File

@ -509,7 +509,8 @@ struct imsm_update_add_remove_disk {
static const char *_sys_dev_type[] = { static const char *_sys_dev_type[] = {
[SYS_DEV_UNKNOWN] = "Unknown", [SYS_DEV_UNKNOWN] = "Unknown",
[SYS_DEV_SAS] = "SAS", [SYS_DEV_SAS] = "SAS",
[SYS_DEV_SATA] = "SATA" [SYS_DEV_SATA] = "SATA",
[SYS_DEV_NVME] = "NVMe"
}; };
const char *get_sys_dev_type(enum sys_dev_type type) const char *get_sys_dev_type(enum sys_dev_type type)
@ -559,7 +560,7 @@ static int attach_hba_to_super(struct intel_super *super, struct sys_dev *device
hba = super->hba; hba = super->hba;
/* Intel metadata allows for all disks attached to the same type HBA. /* Intel metadata allows for all disks attached to the same type HBA.
* Do not sypport odf HBA types mixing * Do not support HBA types mixing
*/ */
if (device->type != hba->type) if (device->type != hba->type)
return 2; return 2;
@ -3841,9 +3842,9 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de
" but the container is assigned to Intel(R) " " but the container is assigned to Intel(R) "
"%s RAID controller (", "%s RAID controller (",
devname, devname,
hba_name->path, get_sys_dev_type(hba_name->type),
hba_name->pci_id ? : "Err!", hba_name->pci_id ? : "Err!",
get_sys_dev_type(hba_name->type)); get_sys_dev_type(super->hba->type));
while (hba) { while (hba) {
fprintf(stderr, "%s", hba->pci_id ? : "Err!"); fprintf(stderr, "%s", hba->pci_id ? : "Err!");
@ -3860,6 +3861,7 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de
super->orom = find_imsm_capability(hba_name); super->orom = find_imsm_capability(hba_name);
if (!super->orom) if (!super->orom)
return 3; return 3;
return 0; return 0;
} }
@ -5916,6 +5918,7 @@ validate_geometry_imsm_orom(struct intel_super *super, int level, int layout,
pr_vrb(": platform does not support a volume size over 2TB\n"); pr_vrb(": platform does not support a volume size over 2TB\n");
return 0; return 0;
} }
return 1; return 1;
} }