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


  17 #include <sys/stat.h>
  18 #include <fcntl.h>
  19 #include <unistd.h>
  20 #include <stropts.h>
  21 #include <string.h>
  22 #include <strings.h>
  23 
  24 #include <fm/topo_mod.h>
  25 #include <fm/topo_list.h>
  26 
  27 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
  28 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
  29 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
  30 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
  31 
  32 #include "disk.h"
  33 #include "disk_drivers.h"
  34 
  35 /*
  36  * Request the SAS address of the disk (if any) attached to this mpt_sas
  37  * instance at (Enclosure Number, Slot Number).
  38  *
  39  * Returns:
  40  *   -2   /devices node (*devctl) does not exist
  41  *   -1   All other failures
  42  *    0   Success
  43  */
  44 static int
  45 get_sas_address(topo_mod_t *mod, char *devctl, uint32_t enclosure,
  46     uint32_t slot, char **sas_address)
  47 {
  48         int fd, err, i;

  49         mptsas_get_disk_info_t gdi;
  50         mptsas_disk_info_t *di;
  51         size_t disz;
  52 
  53         bzero(&gdi, sizeof (gdi));
  54 
  55         if ((fd = open(devctl, O_RDWR)) == -1) {
  56                 int rc = (errno == ENOENT ? -2 : -1);
  57                 topo_mod_dprintf(mod, "could not open '%s' for ioctl: %s\n",
  58                     devctl, strerror(errno));
  59                 return (rc);

  60         }
  61 
  62         if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) {


  63                 topo_mod_dprintf(mod, "ioctl 1 on '%s' failed: %s\n", devctl,
  64                     strerror(errno));
  65                 (void) close(fd);
  66                 return (-1);
  67         }
  68 
  69         gdi.DiskInfoArraySize = disz = sizeof (mptsas_disk_info_t) *
  70             gdi.DiskCount;
  71         gdi.PtrDiskInfoArray = di = topo_mod_alloc(mod, disz);
  72         if (di == NULL) {
  73                 topo_mod_dprintf(mod, "memory allocation failed\n");
  74                 (void) close(fd);
  75                 return (-1);
  76         }
  77 
  78         if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) {


  79                 topo_mod_dprintf(mod, "ioctl 2 on '%s' failed: %s\n", devctl,
  80                     strerror(errno));
  81                 topo_mod_free(mod, di, disz);
  82                 (void) close(fd);
  83                 return (-1);
  84         }
  85 
  86         err = -1;
  87         for (i = 0; i < gdi.DiskCount; i++) {
  88                 if (di[i].Enclosure == enclosure && di[i].Slot == slot) {
  89                         char sas[17]; /* 16 hex digits and NUL */
  90                         (void) snprintf(sas, 17, "%llx", di[i].SasAddress);
  91                         topo_mod_dprintf(mod, "found mpt_sas disk (%d/%d) "
  92                             "with adddress %s\n", enclosure, slot, sas);
  93                         *sas_address = topo_mod_strdup(mod, sas);
  94                         err = 0;
  95                         break;
  96                 }
  97         }
  98 
  99         topo_mod_free(mod, di, disz);

 100         (void) close(fd);
 101         return (err);

 102 }
 103 
 104 int
 105 disk_mptsas_find_disk(topo_mod_t *mod, tnode_t *baynode, char **sas_address)
 106 {
 107         char *devctl = NULL;
 108         uint32_t enclosure, slot;
 109         int err;
 110         char *elem, *lastp;
 111         int ret = -1;
 112 
 113         /*
 114          * Get the required properties from the node.  These come from
 115          * the static XML mapping.
 116          */
 117         if (topo_prop_get_string(baynode, TOPO_PGROUP_BINDING,
 118             TOPO_BINDING_DEVCTL, &devctl, &err) != 0 ||
 119             topo_prop_get_uint32(baynode, TOPO_PGROUP_BINDING,
 120             TOPO_BINDING_ENCLOSURE, &enclosure, &err) != 0 ||
 121             topo_prop_get_uint32(baynode, TOPO_PGROUP_BINDING,
 122             TOPO_BINDING_SLOT, &slot, &err) != 0) {
 123                 if (devctl != NULL)
 124                         topo_mod_strfree(mod, devctl);
 125                 topo_mod_dprintf(mod, "bay node was missing mpt_sas binding "
 126                     "properties\n");
 127                 return (-1);
 128         }
 129 
 130         /*
 131          * devctl is a (potentially) pipe-separated list of different device
 132          * paths to try.
 133          */
 134         if ((elem = topo_mod_strsplit(mod, devctl, "|", &lastp)) != NULL) {

 135                 do {
 136                         topo_mod_dprintf(mod, "trying mpt_sas instance at %s\n",
 137                             elem);
 138 
 139                         ret = get_sas_address(mod, elem, enclosure,
 140                             slot, sas_address);
 141 
 142                         topo_mod_strfree(mod, elem);
 143 
 144                         /*
 145                          * Only try further devctl paths from the list if this
 146                          * one was not found:
 147                          */
 148                         if (ret != -2) {
 149                                 break;
 150                         } else {
 151                                 topo_mod_dprintf(mod, "instance not found\n");
 152                         }
 153 
 154                 } while ((elem = topo_mod_strsplit(mod, NULL, "|",


 155                     &lastp)) != NULL);
 156         }
 157 
 158         topo_mod_strfree(mod, devctl);
 159         return (ret);
 160 }


  17 #include <sys/stat.h>
  18 #include <fcntl.h>
  19 #include <unistd.h>
  20 #include <stropts.h>
  21 #include <string.h>
  22 #include <strings.h>
  23 
  24 #include <fm/topo_mod.h>
  25 #include <fm/topo_list.h>
  26 
  27 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
  28 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
  29 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
  30 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
  31 
  32 #include "disk.h"
  33 #include "disk_drivers.h"
  34 
  35 /*
  36  * Request the SAS address of the disk (if any) attached to this mpt_sas
  37  * instance at (Enclosure Number, Slot Number).  The function returns
  38  * -1 on error and sets errno to ENOENT _only_ if the /devices node
  39  * (*devctl) does not exist.



  40  */
  41 static int
  42 get_sas_address(topo_mod_t *mod, char *devctl, uint32_t enclosure,
  43     uint32_t slot, char **sas_address)
  44 {
  45         int ret = -1, en = ENXIO;
  46         int fd, i;
  47         mptsas_get_disk_info_t gdi;
  48         mptsas_disk_info_t *di;
  49         size_t disz;
  50 
  51         bzero(&gdi, sizeof (gdi));
  52 
  53         if ((fd = open(devctl, O_RDWR)) == -1) {
  54                 en = errno;
  55                 topo_mod_dprintf(mod, "could not open '%s' for ioctl: %s\n",
  56                     devctl, strerror(errno));
  57                 errno = en;
  58                 return (-1);
  59         }
  60 
  61         if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) {
  62                 if (errno != ENOENT)
  63                         en = errno;
  64                 topo_mod_dprintf(mod, "ioctl 1 on '%s' failed: %s\n", devctl,
  65                     strerror(errno));
  66                 goto out;

  67         }
  68 
  69         gdi.DiskInfoArraySize = disz = sizeof (mptsas_disk_info_t) *
  70             gdi.DiskCount;
  71         gdi.PtrDiskInfoArray = di = topo_mod_alloc(mod, disz);
  72         if (di == NULL) {
  73                 topo_mod_dprintf(mod, "memory allocation failed\n");
  74                 en = ENOMEM;
  75                 goto out;
  76         }
  77 
  78         if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) {
  79                 if (errno != ENOENT)
  80                         en = errno;
  81                 topo_mod_dprintf(mod, "ioctl 2 on '%s' failed: %s\n", devctl,
  82                     strerror(errno));
  83                 topo_mod_free(mod, di, disz);
  84                 goto out;

  85         }
  86 

  87         for (i = 0; i < gdi.DiskCount; i++) {
  88                 if (di[i].Enclosure == enclosure && di[i].Slot == slot) {
  89                         char sas[17]; /* 16 hex digits and NUL */
  90                         (void) snprintf(sas, 17, "%llx", di[i].SasAddress);
  91                         topo_mod_dprintf(mod, "found mpt_sas disk (%d/%d) "
  92                             "with adddress %s\n", enclosure, slot, sas);
  93                         *sas_address = topo_mod_strdup(mod, sas);
  94                         en = ret = 0;
  95                         break;
  96                 }
  97         }
  98 
  99         topo_mod_free(mod, di, disz);
 100 out:
 101         (void) close(fd);
 102         errno = en;
 103         return (ret);
 104 }
 105 
 106 int
 107 disk_mptsas_find_disk(topo_mod_t *mod, tnode_t *baynode, char **sas_address)
 108 {
 109         char *devctl = NULL;
 110         uint32_t enclosure, slot;
 111         int err;
 112         char *elem, *lastp;
 113         int ret = -1;
 114 
 115         /*
 116          * Get the required properties from the node.  These come from
 117          * the static XML mapping.
 118          */
 119         if (topo_prop_get_string(baynode, TOPO_PGROUP_BINDING,
 120             TOPO_BINDING_DEVCTL, &devctl, &err) != 0 ||
 121             topo_prop_get_uint32(baynode, TOPO_PGROUP_BINDING,
 122             TOPO_BINDING_ENCLOSURE, &enclosure, &err) != 0 ||
 123             topo_prop_get_uint32(baynode, TOPO_PGROUP_BINDING,
 124             TOPO_BINDING_SLOT, &slot, &err) != 0) {
 125                 if (devctl != NULL)
 126                         topo_mod_strfree(mod, devctl);
 127                 topo_mod_dprintf(mod, "bay node was missing mpt_sas binding "
 128                     "properties\n");
 129                 return (-1);
 130         }
 131 
 132         /*
 133          * devctl is a (potentially) pipe-separated list of different device
 134          * paths to try.
 135          */
 136         if ((elem = topo_mod_strsplit(mod, devctl, "|", &lastp)) != NULL) {
 137                 boolean_t done = B_FALSE;
 138                 do {
 139                         topo_mod_dprintf(mod, "trying mpt_sas instance at %s\n",
 140                             elem);
 141 
 142                         ret = get_sas_address(mod, elem, enclosure,
 143                             slot, sas_address);
 144 


 145                         /*
 146                          * Only try further devctl paths from the list if this
 147                          * one was not found:
 148                          */
 149                         if (ret == 0 || errno != ENOENT) {
 150                                 done = B_TRUE;
 151                         } else {
 152                                 topo_mod_dprintf(mod, "instance not found\n");
 153                         }
 154 
 155                         topo_mod_strfree(mod, elem);
 156 
 157                 } while (!done && (elem = topo_mod_strsplit(mod, NULL, "|",
 158                     &lastp)) != NULL);
 159         }
 160 
 161         topo_mod_strfree(mod, devctl);
 162         return (ret);
 163 }