All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] sparc64: fix OF path names for sun4v systems
@ 2016-02-15 19:11 Eric Snowberg
  2016-02-16  8:16 ` Andrei Borzenkov
  0 siblings, 1 reply; 16+ messages in thread
From: Eric Snowberg @ 2016-02-15 19:11 UTC (permalink / raw)
  To: grub-devel; +Cc: Eric Snowberg, daniel.kiper

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.snowberg@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



^ permalink raw reply related	[flat|nested] 16+ messages in thread
* [PATCH] sparc64: fix OF path names for sun4v systems
@ 2017-12-06 23:53 Eric Snowberg
  2017-12-18 15:22 ` Daniel Kiper
  0 siblings, 1 reply; 16+ messages in thread
From: Eric Snowberg @ 2017-12-06 23:53 UTC (permalink / raw)
  To: grub-devel; +Cc: daniel.kiper, Eric Snowberg

Fix the Open Firmware (OF) 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.snowberg@oracle.com>
---
 grub-core/osdep/linux/ofpath.c | 147 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 144 insertions(+), 3 deletions(-)

diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
index 3a8bc95a9..525a42ae6 100644
--- a/grub-core/osdep/linux/ofpath.c
+++ b/grub-core/osdep/linux/ofpath.c
@@ -38,6 +38,44 @@
 #include <errno.h>
 #include <ctype.h>
 
+#ifdef __sparc__
+typedef enum
+  {
+    GRUB_OFPATH_SPARC_WWN_ADDR = 1,
+    GRUB_OFPATH_SPARC_TGT_LUN,
+  } ofpath_sparc_addressing;
+
+struct ofpath_sparc_hba
+{
+  grub_uint32_t device_id;
+  ofpath_sparc_addressing addressing;
+};
+
+static struct ofpath_sparc_hba sparc_lsi_hba[] = {
+  /* Rhea, Jasper 320, LSI53C1020/1030.  */
+  {0x30, GRUB_OFPATH_SPARC_TGT_LUN},
+  /* SAS-1068E.  */
+  {0x50, GRUB_OFPATH_SPARC_TGT_LUN},
+  /* SAS-1064E.  */
+  {0x56, GRUB_OFPATH_SPARC_TGT_LUN},
+  /* Pandora SAS-1068E.  */
+  {0x58, GRUB_OFPATH_SPARC_TGT_LUN},
+  /* Aspen, Invader, LSI SAS-3108.  */
+  {0x5d, GRUB_OFPATH_SPARC_TGT_LUN},
+  /* Niwot, SAS 2108.  */
+  {0x79, GRUB_OFPATH_SPARC_TGT_LUN},
+  /* Erie, Falcon, LSI SAS 2008.  */
+  {0x72, GRUB_OFPATH_SPARC_WWN_ADDR},
+  /* LSI WarpDrive 6203.  */
+  {0x7e, GRUB_OFPATH_SPARC_WWN_ADDR},
+  /* LSI SAS 2308.  */
+  {0x87, GRUB_OFPATH_SPARC_WWN_ADDR},
+  /* LSI SAS 3008.  */
+  {0x97, GRUB_OFPATH_SPARC_WWN_ADDR},
+  {0, 0}
+};
+#endif
+
 #ifdef OFPATH_STANDALONE
 #define xmalloc malloc
 void
@@ -337,6 +375,66 @@ vendor_is_ATA(const char *path)
   return (memcmp(bufcont, "ATA", 3) == 0);
 }
 
+#ifdef __sparc__
+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 = NULL, *path = NULL;
+  char buf[8];
+  int fd;
+
+  if (!ed)
+    return;
+
+  p = xstrdup (sysfs_path);
+  ed = strstr (p, "host");
+
+  if (!ed)
+    goto out;
+
+  *ed = '\0';
+
+  path_size = (strlen (p) + sizeof ("vendor"));
+  path = xmalloc (path_size);
+
+  if (!path)
+    goto out;
+
+  snprintf (path, path_size, "%svendor", p);
+  fd = open (path, O_RDONLY);
+
+  if (fd < 0)
+    goto out;
+
+  memset (buf, 0, sizeof (buf));
+
+  if (read (fd, buf, sizeof (buf) - 1) < 0)
+    goto out;
+
+  close (fd);
+  sscanf (buf, "%x", vendor);
+  snprintf (path, path_size, "%sdevice", p);
+  fd = open (path, O_RDONLY);
+
+  if (fd < 0)
+    goto out;
+
+  memset (buf, 0, sizeof (buf));
+
+  if (read (fd, buf, sizeof (buf) - 1) < 0)
+    goto out;
+
+  close (fd);
+  sscanf (buf, "%x", device_id);
+
+out:
+  free (path);
+  free (p);
+}
+#endif
+
 static void
 check_sas (const char *sysfs_path, int *tgt, unsigned long int *sas_address)
 {
@@ -398,7 +496,7 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
 {
   const char *p, *digit_string, *disk_name;
   int host, bus, tgt, lun;
-  unsigned long int sas_address;
+  unsigned long int sas_address = 0;
   char *sysfs_path, disk[MAX_DISK_CAT - sizeof ("/fp@0,0")];
   char *of_path;
 
@@ -415,9 +513,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");
@@ -446,6 +546,45 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
     }
   else
     {
+#ifdef __sparc__
+      ofpath_sparc_addressing addressing = GRUB_OFPATH_SPARC_TGT_LUN;
+      int vendor = 0, device_id = 0;
+      char *optr = disk;
+
+      check_hba_identifiers (sysfs_path, &vendor, &device_id);
+
+      /* LSI Logic Vendor ID */
+      if (vendor == 0x1000)
+        {
+          struct ofpath_sparc_hba *lsi_hba;
+
+          /* Over time different OF addressing schemes have been supported.
+             There is no generic addressing scheme that works across
+             every HBA. */
+          for (lsi_hba = sparc_lsi_hba; lsi_hba->device_id; lsi_hba++)
+            if (lsi_hba->device_id == device_id)
+              {
+                addressing = lsi_hba->addressing;
+                break;
+              }
+        }
+
+      if (addressing == GRUB_OFPATH_SPARC_WWN_ADDR)
+        optr += snprintf (disk, sizeof (disk), "/%s@w%lx,%x", disk_name,
+                          sas_address, lun);
+      else
+        optr += snprintf (disk, sizeof (disk), "/%s@%x,%x", disk_name, tgt,
+                          lun);
+
+      if (*digit_string != '\0')
+        {
+          int part;
+
+          sscanf (digit_string, "%d", &part);
+          snprintf (optr, sizeof (disk) - (optr - disk - 1), ":%c", 'a'
+                    + (part - 1));
+        }
+#else
       if (lun == 0)
         {
           int sas_id = 0;
@@ -493,7 +632,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;
 }


^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-01-29 12:21 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-15 19:11 [PATCH] sparc64: fix OF path names for sun4v systems Eric Snowberg
2016-02-16  8:16 ` Andrei Borzenkov
2016-02-17  2:02   ` Eric Snowberg
2016-02-17  3:24     ` Andrei Borzenkov
2016-02-17  6:21       ` Andrei Borzenkov
2016-02-17 18:05         ` Eric Snowberg
2016-02-17  6:45       ` Seth Goldberg
2016-02-17  9:50         ` Toomas Soome
2016-02-17 18:11         ` Eric Snowberg
  -- strict thread matches above, loose matches on Subject: below --
2017-12-06 23:53 Eric Snowberg
2017-12-18 15:22 ` Daniel Kiper
2017-12-18 21:30   ` Eric Snowberg
2017-12-18 22:58     ` John Paul Adrian Glaubitz
2017-12-19 21:36       ` Daniel Kiper
2018-01-29 12:20         ` John Paul Adrian Glaubitz
2017-12-19 20:56     ` Daniel Kiper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.