[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] sparc64: fix OF path names for sun4v systems
From: |
Eric Snowberg |
Subject: |
[PATCH] sparc64: fix OF path names for sun4v systems |
Date: |
Mon, 15 Feb 2016 11:11:21 -0800 |
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 <address@hidden>
---
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, "/address@hidden,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), "/address@hidden",
disk_name, tgt);
+ }
+ else
+ {
+ snprintf(disk, sizeof (disk), "/address@hidden,%x",
+ disk_name, tgt, lun);
+ }
+ }
+ else
+ {
+ int part;
+
+ sscanf(digit_string, "%d", &part);
+ if ( lun == 0 )
+ {
+ snprintf(disk, sizeof (disk),
+ "/address@hidden:%c", disk_name, tgt, 'a' +
(part - 1));
+ }
+ else
+ {
+ snprintf(disk, sizeof (disk),
+ "/address@hidden,%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 address@hidden<PHY> OF path */
+ snprintf(disk, sizeof (disk), "/address@hidden",
disk_name, tgt);
+ }
+ else
+ {
+ /* Use WWN OF path */
+ snprintf(disk, sizeof (disk), "/address@hidden",
disk_name,
+ sas_address);
+ }
+ }
+ else
+ {
+ int part;
+
+ sscanf(digit_string, "%d", &part);
+ if ( lun == 0)
+ {
+ /* Use non-standard address@hidden<PHY> OF path */
+ snprintf(disk, sizeof (disk), "/address@hidden:%c",
+ disk_name, tgt, 'a' + (part - 1));
+ }
+ else
+ {
+ /* Use WWN OF path */
+ snprintf(disk, sizeof (disk), "/address@hidden:%c",
+ disk_name, sas_address, 'a' + (part - 1));
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ /* Use Target OF path */
+ if (*digit_string == '\0')
+ {
+ snprintf(disk, sizeof (disk), "/address@hidden", disk_name, tgt);
+ }
+ else
+ {
+ int part;
+
+ sscanf(digit_string, "%d", &part);
+ snprintf(disk, sizeof (disk),
+ "/address@hidden:%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
- [PATCH] sparc64: fix OF path names for sun4v systems,
Eric Snowberg <=