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

*** 19,28 **** --- 19,31 ---- * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ + /* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <strings.h> #include <devid.h> #include <pthread.h> #include <inttypes.h>
*** 31,57 **** #include <fm/topo_mod.h> #include <fm/topo_list.h> #include <fm/libdiskstatus.h> #include <sys/fm/protocol.h> #include "disk.h" static int disk_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, topo_instance_t, void *, void *); static const topo_modops_t disk_ops = { disk_enum, NULL }; static const topo_modinfo_t disk_info = {DISK, FM_FMRI_SCHEME_HC, DISK_VERSION, &disk_ops}; /*ARGSUSED*/ static int disk_enum(topo_mod_t *mod, tnode_t *baynode, const char *name, topo_instance_t min, topo_instance_t max, void *arg, void *notused) { ! char *device; int err; nvlist_t *fmri; topo_list_t *dlistp = topo_mod_getspecific(mod); if (strcmp(name, DISK) != 0) { --- 34,86 ---- #include <fm/topo_mod.h> #include <fm/topo_list.h> #include <fm/libdiskstatus.h> #include <sys/fm/protocol.h> #include "disk.h" + #include "disk_drivers.h" static int disk_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, topo_instance_t, void *, void *); static const topo_modops_t disk_ops = { disk_enum, NULL }; static const topo_modinfo_t disk_info = {DISK, FM_FMRI_SCHEME_HC, DISK_VERSION, &disk_ops}; + static int + disk_declare_driver(topo_mod_t *mod, tnode_t *baynode, topo_list_t *dlistp, + char *driver) + { + int err; + + if (strcmp("mpt_sas", driver) == 0) { + char *sas_address = NULL; + tnode_t *child = NULL; + + if ((err = disk_mptsas_find_disk(mod, baynode, + &sas_address)) != 0) + return (err); + + err = disk_declare_addr(mod, baynode, dlistp, + sas_address, &child); + topo_mod_strfree(mod, sas_address); + + return (err); + } + + topo_mod_dprintf(mod, "unknown disk driver '%s'\n", driver); + return (-1); + } + /*ARGSUSED*/ static int disk_enum(topo_mod_t *mod, tnode_t *baynode, const char *name, topo_instance_t min, topo_instance_t max, void *arg, void *notused) { ! char *device, *driver; int err; nvlist_t *fmri; topo_list_t *dlistp = topo_mod_getspecific(mod); if (strcmp(name, DISK) != 0) {
*** 73,82 **** --- 102,127 ---- return (-1); } nvlist_free(fmri); /* + * For internal storage, first check to see if we need to + * request more detail from an HBA driver. + */ + if (topo_prop_get_string(baynode, TOPO_PGROUP_BINDING, + TOPO_BINDING_DRIVER, &driver, &err) == 0) { + err = disk_declare_driver(mod, baynode, dlistp, driver); + + topo_mod_strfree(mod, driver); + return (err); + } else if (err != ETOPO_PROP_NOENT) { + topo_mod_dprintf(mod, "disk_enum: " + "binding error %s\n", topo_strerror(err)); + return (-1); + } + + /* * For internal storage, get the path to the occupant from the * binding group of the bay node */ if (topo_prop_get_string(baynode, TOPO_PGROUP_BINDING, TOPO_BINDING_OCCUPANT, &device, &err) != 0) {