Fix the open firmware path property for sun4v SPARC systems. These platforms do not have a /sas/ within their path. Over time different OF addressing schemes have been supported. There is no generic addressing scheme that works across every HBA.
Signed-off-by: Eric Snowberg <eric.snowb...@oracle.com> --- grub-core/osdep/linux/ofpath.c | 192 +++++++++++++++++++++++++++++++++++++++- 1 files changed, 190 insertions(+), 2 deletions(-) diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c index a79682a..de51c57 100644 --- a/grub-core/osdep/linux/ofpath.c +++ b/grub-core/osdep/linux/ofpath.c @@ -336,6 +336,85 @@ vendor_is_ATA(const char *path) } static void +check_hba_identifiers(const char *sysfs_path, int *vendor, int *device_id) +{ + char *ed = strstr (sysfs_path, "host"); + size_t path_size; + char *p, *path; + char buf[8]; + int fd; + + if (!ed) + return; + + p = xstrdup (sysfs_path); + ed = strstr (p, "host"); + + if (!ed) + { + free (p); + return; + } + *ed = '\0'; + + path_size = (strlen (p) + sizeof("vendor")); + path = xmalloc (path_size); + + if (!path) + { + free (p); + return; + } + + snprintf (path, path_size, "%svendor", p); + fd = open (path, O_RDONLY); + + if (fd < 0) + { + free (p); + free (path); + return; + } + + memset (buf, 0, sizeof (buf)); + + if (read (fd, buf, sizeof (buf) - 1) < 0) + { + close (fd); + free (p); + free (path); + return; + } + + close (fd); + sscanf (buf, "%x", vendor); + snprintf (path, path_size, "%sdevice", p); + fd = open (path, O_RDONLY); + + if (fd < 0) + { + free (p); + free (path); + return; + } + + memset (buf, 0, sizeof (buf)); + + if (read (fd, buf, sizeof (buf) - 1) < 0) + { + close (fd); + free (p); + free (path); + return; + } + + close (fd); + sscanf (buf, "%x", device_id); + free (path); + free (p); +} + +static void check_sas (const char *sysfs_path, int *tgt, unsigned long int *sas_address) { char *ed = strstr (sysfs_path, "end_device"); @@ -413,9 +492,11 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev } of_path = find_obppath(sysfs_path); - free (sysfs_path); if (!of_path) - return NULL; + { + free (sysfs_path); + return NULL; + } if (strstr (of_path, "qlc")) strcat (of_path, "/fp@0,0"); @@ -444,6 +525,111 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev } else { +#ifdef __sparc__ + int vendor = 0, device_id = 0; + check_hba_identifiers(sysfs_path, &vendor, &device_id); + + if (vendor == 0x1000) /* LSI Logic Vendor ID */ + { + /* Over time different OF addressing schemes have been supported */ + /* There is no generic addressing scheme that works across */ + /* every HBA */ + switch (device_id) + { + case 0x30: /* Rhea, Jasper 320, LSI53C1020/1030 */ + case 0x50: /* SAS-1068E */ + case 0x56: /* SAS-1064E */ + case 0x58: /* Pandora SAS-1068E */ + case 0x5d: /* Aspen, Invader, LSI SAS-3108 */ + case 0x79: /* Niwot, SAS 2108 */ + /* Use Target/lun OF path */ + if (*digit_string == '\0') + { + if ( lun == 0 ) + { + snprintf(disk, sizeof (disk), "/%s@%x", disk_name, tgt); + } + else + { + snprintf(disk, sizeof (disk), "/%s@%x,%x", + disk_name, tgt, lun); + } + } + else + { + int part; + + sscanf(digit_string, "%d", &part); + if ( lun == 0 ) + { + snprintf(disk, sizeof (disk), + "/%s@%x:%c", disk_name, tgt, 'a' + (part - 1)); + } + else + { + snprintf(disk, sizeof (disk), + "/%s@%x,%x:%c", disk_name, tgt, + lun, 'a' + (part - 1)); + } + } + break; + case 0x72: /* Erie, Falcon, LSI SAS 2008 */ + case 0x7e: /* LSI WarpDrive 6203 */ + case 0x87: /* LSI SAS 2308 */ + case 0x97: /* LSI SAS 3008 */ + default: + if (*digit_string == '\0') + { + if ( lun == 0 ) + { + /* Use non-standard disk@p<PHY> OF path */ + snprintf(disk, sizeof (disk), "/%s@p%x", disk_name, tgt); + } + else + { + /* Use WWN OF path */ + snprintf(disk, sizeof (disk), "/%s@w%lx", disk_name, + sas_address); + } + } + else + { + int part; + + sscanf(digit_string, "%d", &part); + if ( lun == 0) + { + /* Use non-standard disk@p<PHY> OF path */ + snprintf(disk, sizeof (disk), "/%s@p%x:%c", + disk_name, tgt, 'a' + (part - 1)); + } + else + { + /* Use WWN OF path */ + snprintf(disk, sizeof (disk), "/%s@w%lx:%c", + disk_name, sas_address, 'a' + (part - 1)); + } + } + break; + } + } + else + { + /* Use Target OF path */ + if (*digit_string == '\0') + { + snprintf(disk, sizeof (disk), "/%s@%x", disk_name, tgt); + } + else + { + int part; + + sscanf(digit_string, "%d", &part); + snprintf(disk, sizeof (disk), + "/%s@%x:%c", disk_name, tgt, 'a' + (part - 1)); + } + } +#else if (lun == 0) { int sas_id = 0; @@ -491,7 +677,9 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev } free (lunstr); } +#endif } + free (sysfs_path); strcat(of_path, disk); return of_path; } -- 1.7.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel