Print this page
OS-1996 mpt_sas: allow physical topology enumeration in libtopo
Reviewed by: Keith Wesolowski <keith.wesolowski@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/fm/topo/modules/common/disk/disk.c
          +++ new/usr/src/lib/fm/topo/modules/common/disk/disk.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   */
       24 +/*
       25 + * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
       26 + */
  24   27  
  25   28  #include <strings.h>
  26   29  #include <devid.h>
  27   30  #include <pthread.h>
  28   31  #include <inttypes.h>
  29   32  #include <sys/dkio.h>
  30   33  #include <sys/scsi/scsi_types.h>
  31   34  #include <fm/topo_mod.h>
  32   35  #include <fm/topo_list.h>
  33   36  #include <fm/libdiskstatus.h>
  34   37  #include <sys/fm/protocol.h>
  35   38  #include "disk.h"
       39 +#include "disk_drivers.h"
  36   40  
  37   41  static int disk_enum(topo_mod_t *, tnode_t *, const char *,
  38   42          topo_instance_t, topo_instance_t, void *, void *);
  39   43  
  40   44  static const topo_modops_t disk_ops =
  41   45          { disk_enum, NULL };
  42   46  
  43   47  static const topo_modinfo_t disk_info =
  44   48          {DISK, FM_FMRI_SCHEME_HC, DISK_VERSION, &disk_ops};
  45   49  
       50 +static int
       51 +disk_declare_driver(topo_mod_t *mod, tnode_t *baynode, topo_list_t *dlistp,
       52 +    char *driver)
       53 +{
       54 +        int err;
       55 +
       56 +        if (strcmp("mpt_sas", driver) == 0) {
       57 +                char *sas_address = NULL;
       58 +                tnode_t *child = NULL;
       59 +
       60 +                if ((err = disk_mptsas_find_disk(mod, baynode,
       61 +                    &sas_address)) != 0)
       62 +                        return (err);
       63 +
       64 +                err = disk_declare_addr(mod, baynode, dlistp,
       65 +                    sas_address, &child);
       66 +                topo_mod_strfree(mod, sas_address);
       67 +
       68 +                return (err);
       69 +        }
       70 +
       71 +        topo_mod_dprintf(mod, "unknown disk driver '%s'\n", driver);
       72 +        return (-1);
       73 +}
       74 +
  46   75  /*ARGSUSED*/
  47   76  static int
  48   77  disk_enum(topo_mod_t *mod, tnode_t *baynode,
  49   78      const char *name, topo_instance_t min, topo_instance_t max,
  50   79      void *arg, void *notused)
  51   80  {
  52      -        char            *device;
       81 +        char            *device, *driver;
  53   82          int             err;
  54   83          nvlist_t        *fmri;
  55   84          topo_list_t     *dlistp = topo_mod_getspecific(mod);
  56   85  
  57   86          if (strcmp(name, DISK) != 0) {
  58   87                  topo_mod_dprintf(mod, "disk_enum: "
  59   88                      "only know how to enumerate %s components.\n", DISK);
  60   89                  return (-1);
  61   90          }
  62   91  
↓ open down ↓ 5 lines elided ↑ open up ↑
  68   97          }
  69   98          if (topo_node_fru_set(baynode, fmri, 0, &err) != 0) {
  70   99                  topo_mod_dprintf(mod, "disk_enum: "
  71  100                      "topo_node_fru error %s\n", topo_strerror(err));
  72  101                  nvlist_free(fmri);
  73  102                  return (-1);
  74  103          }
  75  104          nvlist_free(fmri);
  76  105  
  77  106          /*
      107 +         * For internal storage, first check to see if we need to
      108 +         * request more detail from an HBA driver.
      109 +         */
      110 +        if (topo_prop_get_string(baynode, TOPO_PGROUP_BINDING,
      111 +            TOPO_BINDING_DRIVER, &driver, &err) == 0) {
      112 +                err = disk_declare_driver(mod, baynode, dlistp, driver);
      113 +
      114 +                topo_mod_strfree(mod, driver);
      115 +                return (err);
      116 +        } else if (err != ETOPO_PROP_NOENT) {
      117 +                topo_mod_dprintf(mod, "disk_enum: "
      118 +                    "binding error %s\n", topo_strerror(err));
      119 +                return (-1);
      120 +        }
      121 +
      122 +        /*
  78  123           * For internal storage, get the path to the occupant from the
  79  124           * binding group of the bay node
  80  125           */
  81  126          if (topo_prop_get_string(baynode, TOPO_PGROUP_BINDING,
  82  127              TOPO_BINDING_OCCUPANT, &device, &err) != 0) {
  83  128                  topo_mod_dprintf(mod, "disk_enum: "
  84  129                      "binding error %s\n", topo_strerror(err));
  85  130                  return (-1);
  86  131          }
  87  132  
↓ open down ↓ 60 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX