grub-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]