Print this page
OS-2444 richmond hardware maps need to support ivy bridge (review fixes)

@@ -32,75 +32,77 @@
 #include "disk.h"
 #include "disk_drivers.h"
 
 /*
  * Request the SAS address of the disk (if any) attached to this mpt_sas
- * instance at (Enclosure Number, Slot Number).
- *
- * Returns:
- *   -2   /devices node (*devctl) does not exist
- *   -1   All other failures
- *    0   Success
+ * instance at (Enclosure Number, Slot Number).  The function returns
+ * -1 on error and sets errno to ENOENT _only_ if the /devices node
+ * (*devctl) does not exist.
  */
 static int
 get_sas_address(topo_mod_t *mod, char *devctl, uint32_t enclosure,
     uint32_t slot, char **sas_address)
 {
-        int fd, err, i;
+        int ret = -1, en = ENXIO;
+        int fd, i;
         mptsas_get_disk_info_t gdi;
         mptsas_disk_info_t *di;
         size_t disz;
 
         bzero(&gdi, sizeof (gdi));
 
         if ((fd = open(devctl, O_RDWR)) == -1) {
-                int rc = (errno == ENOENT ? -2 : -1);
+                en = errno;
                 topo_mod_dprintf(mod, "could not open '%s' for ioctl: %s\n",
                     devctl, strerror(errno));
-                return (rc);
+                errno = en;
+                return (-1);
         }
 
         if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) {
+                if (errno != ENOENT)
+                        en = errno;
                 topo_mod_dprintf(mod, "ioctl 1 on '%s' failed: %s\n", devctl,
                     strerror(errno));
-                (void) close(fd);
-                return (-1);
+                goto out;
         }
 
         gdi.DiskInfoArraySize = disz = sizeof (mptsas_disk_info_t) *
             gdi.DiskCount;
         gdi.PtrDiskInfoArray = di = topo_mod_alloc(mod, disz);
         if (di == NULL) {
                 topo_mod_dprintf(mod, "memory allocation failed\n");
-                (void) close(fd);
-                return (-1);
+                en = ENOMEM;
+                goto out;
         }
 
         if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) {
+                if (errno != ENOENT)
+                        en = errno;
                 topo_mod_dprintf(mod, "ioctl 2 on '%s' failed: %s\n", devctl,
                     strerror(errno));
                 topo_mod_free(mod, di, disz);
-                (void) close(fd);
-                return (-1);
+                goto out;
         }
 
-        err = -1;
         for (i = 0; i < gdi.DiskCount; i++) {
                 if (di[i].Enclosure == enclosure && di[i].Slot == slot) {
                         char sas[17]; /* 16 hex digits and NUL */
                         (void) snprintf(sas, 17, "%llx", di[i].SasAddress);
                         topo_mod_dprintf(mod, "found mpt_sas disk (%d/%d) "
                             "with adddress %s\n", enclosure, slot, sas);
                         *sas_address = topo_mod_strdup(mod, sas);
-                        err = 0;
+                        en = ret = 0;
                         break;
                 }
         }
 
         topo_mod_free(mod, di, disz);
+out:
         (void) close(fd);
-        return (err);
+        errno = en;
+        return (ret);
 }
 
 int
 disk_mptsas_find_disk(topo_mod_t *mod, tnode_t *baynode, char **sas_address)
 {

@@ -130,30 +132,31 @@
         /*
          * devctl is a (potentially) pipe-separated list of different device
          * paths to try.
          */
         if ((elem = topo_mod_strsplit(mod, devctl, "|", &lastp)) != NULL) {
+                boolean_t done = B_FALSE;
                 do {
                         topo_mod_dprintf(mod, "trying mpt_sas instance at %s\n",
                             elem);
 
                         ret = get_sas_address(mod, elem, enclosure,
                             slot, sas_address);
 
-                        topo_mod_strfree(mod, elem);
-
                         /*
                          * Only try further devctl paths from the list if this
                          * one was not found:
                          */
-                        if (ret != -2) {
-                                break;
+                        if (ret == 0 || errno != ENOENT) {
+                                done = B_TRUE;
                         } else {
                                 topo_mod_dprintf(mod, "instance not found\n");
                         }
 
-                } while ((elem = topo_mod_strsplit(mod, NULL, "|",
+                        topo_mod_strfree(mod, elem);
+
+                } while (!done && (elem = topo_mod_strsplit(mod, NULL, "|",
                     &lastp)) != NULL);
         }
 
         topo_mod_strfree(mod, devctl);
         return (ret);