[OPENSM] set opensm cache & config folder as %ProgramFiles%\WinOF\OpenSM; integrated...
[mirror/winof/.git] / ulp / libibnetdisc / src / ibnetdisc.c
index 1e93ff8..97e369c 100644 (file)
@@ -35,7 +35,7 @@
 
 #if HAVE_CONFIG_H
 #  include <config.h>
 
 #if HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif                         /* HAVE_CONFIG_H */
 
 #define _GNU_SOURCE
 #include <stdio.h>
 
 #define _GNU_SOURCE
 #include <stdio.h>
 #include "internal.h"
 #include "chassis.h"
 
 #include "internal.h"
 #include "chassis.h"
 
-static int timeout_ms = 2000;
 static int show_progress = 0;
 int ibdebug;
 
 static int show_progress = 0;
 int ibdebug;
 
-void
-decode_port_info(ibnd_port_t *port)
+void decode_port_info(ibnd_port_t * port)
 {
        port->base_lid = (uint16_t) mad_get_field(port->info, 0, IB_PORT_LID_F);
        port->lmc = (uint8_t) mad_get_field(port->info, 0, IB_PORT_LMC_F);
 }
 
 {
        port->base_lid = (uint16_t) mad_get_field(port->info, 0, IB_PORT_LID_F);
        port->lmc = (uint8_t) mad_get_field(port->info, 0, IB_PORT_LMC_F);
 }
 
-static int
-get_port_info(struct ibnd_fabric *fabric, struct ibnd_port *port,
-               int portnum, ib_portid_t *portid)
+static int get_port_info(struct ibmad_port *ibmad_port,
+                        ibnd_fabric_t * fabric, ibnd_port_t * port,
+                        int portnum, ib_portid_t * portid)
 {
        char width[64], speed[64];
        int iwidth;
        int ispeed;
 
 {
        char width[64], speed[64];
        int iwidth;
        int ispeed;
 
-       port->port.portnum = portnum;
-       iwidth = mad_get_field(port->port.info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F);
-       ispeed = mad_get_field(port->port.info, 0, IB_PORT_LINK_SPEED_ACTIVE_F);
+       port->portnum = portnum;
+       iwidth = mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F);
+       ispeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F);
 
 
-       if (!smp_query_via(port->port.info, portid, IB_ATTR_PORT_INFO, portnum, timeout_ms,
-                       fabric->fabric.ibmad_port))
+       if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO,
+                          portnum, 0, ibmad_port))
                return -1;
 
                return -1;
 
-       decode_port_info(&(port->port));
+       decode_port_info(port);
 
 
-       IBND_DEBUG("portid %s portnum %d: base lid %d state %d physstate %d %s %s\n",
-               portid2str(portid), portnum, port->port.base_lid,
-               mad_get_field(port->port.info, 0, IB_PORT_STATE_F),
-               mad_get_field(port->port.info, 0, IB_PORT_PHYS_STATE_F),
-               mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F, width, 64, &iwidth),
-               mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F, speed, 64, &ispeed));
+       IBND_DEBUG
+           ("portid %s portnum %d: base lid %d state %d physstate %d %s %s\n",
+            portid2str(portid), portnum, port->base_lid,
+            mad_get_field(port->info, 0, IB_PORT_STATE_F),
+            mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F),
+            mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F, width, 64, &iwidth),
+            mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F, speed, 64, &ispeed));
        return 0;
 }
 
 /*
  * Returns -1 if error.
  */
        return 0;
 }
 
 /*
  * Returns -1 if error.
  */
-static int
-query_node_info(struct ibnd_fabric *fabric, struct ibnd_node *node, ib_portid_t *portid)
+static int query_node_info(struct ibmad_port *ibmad_port,
+                          ibnd_fabric_t * fabric, ibnd_node_t * node,
+                          ib_portid_t * portid)
 {
 {
-       if (!smp_query_via(&(node->node.info), portid, IB_ATTR_NODE_INFO, 0, timeout_ms,
-                       fabric->fabric.ibmad_port))
+       if (!smp_query_via(&(node->info), portid, IB_ATTR_NODE_INFO, 0, 0,
+                          ibmad_port))
                return -1;
 
        /* decode just a couple of fields for quicker reference. */
                return -1;
 
        /* decode just a couple of fields for quicker reference. */
-       mad_decode_field(node->node.info, IB_NODE_GUID_F, &(node->node.guid));
-       mad_decode_field(node->node.info, IB_NODE_TYPE_F, &(node->node.type));
-       mad_decode_field(node->node.info, IB_NODE_NPORTS_F,
-                       &(node->node.numports));
+       mad_decode_field(node->info, IB_NODE_GUID_F, &(node->guid));
+       mad_decode_field(node->info, IB_NODE_TYPE_F, &(node->type));
+       mad_decode_field(node->info, IB_NODE_NPORTS_F, &(node->numports));
 
        return (0);
 }
 
        return (0);
 }
@@ -117,26 +116,24 @@ query_node_info(struct ibnd_fabric *fabric, struct ibnd_node *node, ib_portid_t
 /*
  * Returns 0 if non switch node is found, 1 if switch is found, -1 if error.
  */
 /*
  * Returns 0 if non switch node is found, 1 if switch is found, -1 if error.
  */
-static int
-query_node(struct ibnd_fabric *fabric, struct ibnd_node *inode,
-               struct ibnd_port *iport, ib_portid_t *portid)
+static int query_node(struct ibmad_port *ibmad_port, ibnd_fabric_t * fabric,
+                     ibnd_node_t * node, ibnd_port_t * port,
+                     ib_portid_t * portid)
 {
 {
-       ibnd_node_t *node = &(inode->node);
-       ibnd_port_t *port = &(iport->port);
-       void *nd = inode->node.nodedesc;
+       int rc = 0;
+       void *nd = node->nodedesc;
 
 
-       if (query_node_info(fabric, inode, portid))
-               return -1;
+       if ((rc = query_node_info(ibmad_port, fabric, node, portid)) != 0)
+               return rc;
 
        port->portnum = mad_get_field(node->info, 0, IB_NODE_LOCAL_PORT_F);
        port->guid = mad_get_field64(node->info, 0, IB_NODE_PORT_GUID_F);
 
 
        port->portnum = mad_get_field(node->info, 0, IB_NODE_LOCAL_PORT_F);
        port->guid = mad_get_field64(node->info, 0, IB_NODE_PORT_GUID_F);
 
-       if (!smp_query_via(nd, portid, IB_ATTR_NODE_DESC, 0, timeout_ms,
-                       fabric->fabric.ibmad_port))
+       if (!smp_query_via(nd, portid, IB_ATTR_NODE_DESC, 0, 0, ibmad_port))
                return -1;
 
                return -1;
 
-       if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO, 0, timeout_ms,
-                       fabric->fabric.ibmad_port))
+       if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO, 0, 0,
+                          ibmad_port))
                return -1;
        decode_port_info(port);
 
                return -1;
        decode_port_info(port);
 
@@ -147,152 +144,200 @@ query_node(struct ibnd_fabric *fabric, struct ibnd_node *inode,
        node->smalmc = port->lmc;
 
        /* after we have the sma information find out the real PortInfo for this port */
        node->smalmc = port->lmc;
 
        /* after we have the sma information find out the real PortInfo for this port */
-       if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO, port->portnum, timeout_ms,
-                       fabric->fabric.ibmad_port))
+       if (!smp_query_via(port->info, portid, IB_ATTR_PORT_INFO,
+                          port->portnum, 0, ibmad_port))
                return -1;
        decode_port_info(port);
 
                return -1;
        decode_port_info(port);
 
-       port->base_lid = (uint16_t) node->smalid;  /* LID is still defined by port 0 */
+       port->base_lid = (uint16_t) node->smalid;       /* LID is still defined by port 0 */
        port->lmc = (uint8_t) node->smalmc;
 
        port->lmc = (uint8_t) node->smalmc;
 
-        if (!smp_query_via(node->switchinfo, portid, IB_ATTR_SWITCH_INFO, 0, timeout_ms,
-                       fabric->fabric.ibmad_port))
+       if (!smp_query_via(node->switchinfo, portid, IB_ATTR_SWITCH_INFO, 0, 0,
+                          ibmad_port))
                node->smaenhsp0 = 0;    /* assume base SP0 */
        else
                node->smaenhsp0 = 0;    /* assume base SP0 */
        else
-               mad_decode_field(node->switchinfo, IB_SW_ENHANCED_PORT0_F, &node->smaenhsp0);
+               mad_decode_field(node->switchinfo, IB_SW_ENHANCED_PORT0_F,
+                                &node->smaenhsp0);
 
        IBND_DEBUG("portid %s: got switch node %" PRIx64 " '%s'\n",
 
        IBND_DEBUG("portid %s: got switch node %" PRIx64 " '%s'\n",
-             portid2str(portid), node->guid, node->nodedesc);
+                  portid2str(portid), node->guid, node->nodedesc);
        return 0;
 }
 
        return 0;
 }
 
-static int
-add_port_to_dpath(ib_dr_path_t *path, int nextport)
+static int add_port_to_dpath(ib_dr_path_t * path, int nextport)
 {
 {
-       if (path->cnt+2 >= sizeof(path->p))
+       if (path->cnt + 2 >= sizeof(path->p)) {
+               IBND_ERROR("DR path has grown too long\n");
                return -1;
                return -1;
+       }
        ++path->cnt;
        path->p[path->cnt] = (uint8_t) nextport;
        return path->cnt;
 }
 
        ++path->cnt;
        path->p[path->cnt] = (uint8_t) nextport;
        return path->cnt;
 }
 
-static int
-extend_dpath(struct ibnd_fabric *f, ib_portid_t *portid, int nextport)
+static void retract_dpath(ib_portid_t * path)
+{
+       path->drpath.cnt--;     /* restore path */
+       if (path->drpath.cnt == 0 && path->lid) {
+               /* return to lid based routing on this path */
+               path->drpath.drslid = 0;
+               path->drpath.drdlid = 0;
+       }
+}
+
+static int extend_dpath(struct ibmad_port *ibmad_port, ibnd_fabric_t * fabric,
+                       ib_portid_t * portid, int nextport)
 {
        int rc = 0;
 
        if (portid->lid) {
                /* If we were LID routed we need to set up the drslid */
 {
        int rc = 0;
 
        if (portid->lid) {
                /* If we were LID routed we need to set up the drslid */
-               if (!f->selfportid.lid)
-                       if (ib_resolve_self_via(&f->selfportid, NULL, NULL,
-                                       f->fabric.ibmad_port) < 0)
+               if (!fabric->selfportid.lid)
+                       if (ib_resolve_self_via(&fabric->selfportid, NULL, NULL,
+                                               ibmad_port) < 0) {
+                               IBND_ERROR("Failed to resolve self\n");
                                return -1;
                                return -1;
+                       }
 
 
-               portid->drpath.drslid = f->selfportid.lid;
+               portid->drpath.drslid = (uint16_t) fabric->selfportid.lid;
                portid->drpath.drdlid = 0xFFFF;
        }
 
        rc = add_port_to_dpath(&portid->drpath, nextport);
 
                portid->drpath.drdlid = 0xFFFF;
        }
 
        rc = add_port_to_dpath(&portid->drpath, nextport);
 
-       if ((rc != -1) && (portid->drpath.cnt > f->fabric.maxhops_discovered))
-               f->fabric.maxhops_discovered = portid->drpath.cnt;
+       if ((rc != -1) && (portid->drpath.cnt > fabric->maxhops_discovered))
+               fabric->maxhops_discovered = portid->drpath.cnt;
        return (rc);
 }
 
        return (rc);
 }
 
-static void
-dump_endnode(ib_portid_t *path, char *prompt,
-               struct ibnd_node *node, struct ibnd_port *port)
+static void dump_endnode(ib_portid_t * path, char *prompt,
+                        ibnd_node_t * node, ibnd_port_t * port)
 {
        char type[64];
        if (!show_progress)
                return;
 
 {
        char type[64];
        if (!show_progress)
                return;
 
-       mad_dump_node_type(type, 64, &(node->node.type), sizeof(int)),
-
+       mad_dump_node_type(type, 64, &(node->type), sizeof(int));
        printf("%s -> %s %s {%016" PRIx64 "} portnum %d base lid %d-%d\"%s\"\n",
        printf("%s -> %s %s {%016" PRIx64 "} portnum %d base lid %d-%d\"%s\"\n",
-               portid2str(path), prompt, type,
-               node->node.guid,
-               node->node.type == IB_NODE_SWITCH ? 0 : port->port.portnum,
-               port->port.base_lid, port->port.base_lid + (1 << port->port.lmc) - 1,
-               node->node.nodedesc);
+              portid2str(path), prompt, type, node->guid,
+              node->type == IB_NODE_SWITCH ? 0 : port->portnum,
+              port->base_lid,
+              port->base_lid + (1 << port->lmc) - 1, node->nodedesc);
 }
 
 }
 
-static struct ibnd_node *
-find_existing_node(struct ibnd_fabric *fabric, struct ibnd_node *new)
+static ibnd_node_t *find_existing_node(ibnd_fabric_t * fabric,
+                                      ibnd_node_t * new)
 {
 {
-       int hash = HASHGUID(new->node.guid) % HTSZ;
-       struct ibnd_node *node;
+       int hash = HASHGUID(new->guid) % HTSZ;
+       ibnd_node_t *node;
 
        for (node = fabric->nodestbl[hash]; node; node = node->htnext)
 
        for (node = fabric->nodestbl[hash]; node; node = node->htnext)
-               if (node->node.guid == new->node.guid)
+               if (node->guid == new->guid)
                        return node;
 
        return NULL;
 }
 
                        return node;
 
        return NULL;
 }
 
-ibnd_node_t *
-ibnd_find_node_guid(ibnd_fabric_t *fabric, uint64_t guid)
+ibnd_node_t *ibnd_find_node_guid(ibnd_fabric_t * fabric, uint64_t guid)
 {
 {
-       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
        int hash = HASHGUID(guid) % HTSZ;
        int hash = HASHGUID(guid) % HTSZ;
-       struct ibnd_node *node;
+       ibnd_node_t *node;
 
 
-       for (node = f->nodestbl[hash]; node; node = node->htnext)
-               if (node->node.guid == guid)
-                       return (ibnd_node_t *)node;
+       if (!fabric) {
+               IBND_DEBUG("fabric parameter NULL\n");
+               return (NULL);
+       }
+
+       for (node = fabric->nodestbl[hash]; node; node = node->htnext)
+               if (node->guid == guid)
+                       return (ibnd_node_t *) node;
 
        return NULL;
 }
 
 
        return NULL;
 }
 
-ibnd_node_t *
-ibnd_update_node(ibnd_node_t *node)
+static int _check_ibmad_port(struct ibmad_port *ibmad_port)
+{
+       if (!ibmad_port) {
+               IBND_DEBUG("ibmad_port must be specified\n");
+               return (-1);
+       }
+       if (mad_rpc_class_agent(ibmad_port, IB_SMI_CLASS) == -1
+           || mad_rpc_class_agent(ibmad_port, IB_SMI_DIRECT_CLASS) == -1) {
+               IBND_DEBUG("ibmad_port must be opened with "
+                          "IB_SMI_CLASS && IB_SMI_DIRECT_CLASS\n");
+               return (-1);
+       }
+       return (0);
+}
+
+ibnd_node_t *ibnd_update_node(struct ibmad_port * ibmad_port,
+                             ibnd_fabric_t * fabric, ibnd_node_t * node)
 {
        char portinfo_port0[IB_SMP_DATA_SIZE];
        void *nd = node->nodedesc;
        int p = 0;
 {
        char portinfo_port0[IB_SMP_DATA_SIZE];
        void *nd = node->nodedesc;
        int p = 0;
-       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(node->fabric);
-       struct ibnd_node *n = CONV_NODE_INTERNAL(node);
 
 
-       if (query_node_info(f, n, &(n->node.path_portid)))
+       if (_check_ibmad_port(ibmad_port) < 0)
                return (NULL);
 
                return (NULL);
 
-       if (!smp_query_via(nd, &(n->node.path_portid), IB_ATTR_NODE_DESC, 0, timeout_ms,
-                       f->fabric.ibmad_port))
+       if (!fabric) {
+               IBND_DEBUG("fabric parameter NULL\n");
+               return (NULL);
+       }
+
+       if (!node) {
+               IBND_DEBUG("node parameter NULL\n");
+               return (NULL);
+       }
+
+       if (query_node_info(ibmad_port, fabric, node, &(node->path_portid)))
+               return (NULL);
+
+       if (!smp_query_via(nd, &(node->path_portid), IB_ATTR_NODE_DESC, 0, 0,
+                          ibmad_port))
                return (NULL);
 
        /* update all the port info's */
                return (NULL);
 
        /* update all the port info's */
-       for (p = 1; p >= n->node.numports; p++) {
-               get_port_info(f, CONV_PORT_INTERNAL(n->node.ports[p]), p, &(n->node.path_portid));
+       for (p = 1; p >= node->numports; p++) {
+               get_port_info(ibmad_port, fabric, node->ports[p],
+                             p, &(node->path_portid));
        }
 
        }
 
-       if (n->node.type != IB_NODE_SWITCH)
+       if (node->type != IB_NODE_SWITCH)
                goto done;
 
                goto done;
 
-       if (!smp_query_via(portinfo_port0, &(n->node.path_portid), IB_ATTR_PORT_INFO, 0, timeout_ms,
-                       f->fabric.ibmad_port))
+       if (!smp_query_via
+           (portinfo_port0, &(node->path_portid), IB_ATTR_PORT_INFO, 0, 0,
+            ibmad_port))
                return (NULL);
 
                return (NULL);
 
-       n->node.smalid = mad_get_field(portinfo_port0, 0, IB_PORT_LID_F);
-       n->node.smalmc = mad_get_field(portinfo_port0, 0, IB_PORT_LMC_F);
+       node->smalid = mad_get_field(portinfo_port0, 0, IB_PORT_LID_F);
+       node->smalmc = mad_get_field(portinfo_port0, 0, IB_PORT_LMC_F);
 
 
-        if (!smp_query_via(node->switchinfo, &(n->node.path_portid), IB_ATTR_SWITCH_INFO, 0, timeout_ms,
-                       f->fabric.ibmad_port))
-                node->smaenhsp0 = 0;   /* assume base SP0 */
+       if (!smp_query_via(node->switchinfo, &(node->path_portid),
+                          IB_ATTR_SWITCH_INFO, 0, 0, ibmad_port))
+               node->smaenhsp0 = 0;    /* assume base SP0 */
        else
        else
-               mad_decode_field(node->switchinfo, IB_SW_ENHANCED_PORT0_F, &n->node.smaenhsp0);
+               mad_decode_field(node->switchinfo, IB_SW_ENHANCED_PORT0_F,
+                                &node->smaenhsp0);
 
 done:
        return (node);
 }
 
 
 done:
        return (node);
 }
 
-ibnd_node_t *
-ibnd_find_node_dr(ibnd_fabric_t *fabric, char *dr_str)
+ibnd_node_t *ibnd_find_node_dr(ibnd_fabric_t * fabric, char *dr_str)
 {
 {
-       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
        int i = 0;
        int i = 0;
-       ibnd_node_t *rc = f->fabric.from_node;
+       ibnd_node_t *rc;
        ib_dr_path_t path;
 
        ib_dr_path_t path;
 
+       if (!fabric) {
+               IBND_DEBUG("fabric parameter NULL\n");
+               return (NULL);
+       }
+
+       rc = fabric->from_node;
+
        if (str2drpath(&path, dr_str, 0, 0) == -1) {
                return (NULL);
        }
        if (str2drpath(&path, dr_str, 0, 0) == -1) {
                return (NULL);
        }
@@ -314,76 +359,71 @@ ibnd_find_node_dr(ibnd_fabric_t *fabric, char *dr_str)
        return (rc);
 }
 
        return (rc);
 }
 
-static void
-add_to_nodeguid_hash(struct ibnd_node *node, struct ibnd_node *hash[])
+static void add_to_nodeguid_hash(ibnd_node_t * node, ibnd_node_t * hash[])
 {
 {
-       int hash_idx = HASHGUID(node->node.guid) % HTSZ;
+       int hash_idx = HASHGUID(node->guid) % HTSZ;
 
        node->htnext = hash[hash_idx];
        hash[hash_idx] = node;
 }
 
 
        node->htnext = hash[hash_idx];
        hash[hash_idx] = node;
 }
 
-static void
-add_to_portguid_hash(struct ibnd_port *port, struct ibnd_port *hash[])
+static void add_to_portguid_hash(ibnd_port_t * port, ibnd_port_t * hash[])
 {
 {
-       int hash_idx = HASHGUID(port->port.guid) % HTSZ;
+       int hash_idx = HASHGUID(port->guid) % HTSZ;
 
        port->htnext = hash[hash_idx];
        hash[hash_idx] = port;
 }
 
 
        port->htnext = hash[hash_idx];
        hash[hash_idx] = port;
 }
 
-static void
-add_to_type_list(struct ibnd_node*node, struct ibnd_fabric *fabric)
+static void add_to_type_list(ibnd_node_t * node, ibnd_fabric_t * fabric)
 {
 {
-       switch (node->node.type) {
-               case IB_NODE_CA:
-                       node->type_next = fabric->ch_adapters;
-                       fabric->ch_adapters = node;
-                       break;
-               case IB_NODE_SWITCH:
-                       node->type_next = fabric->switches;
-                       fabric->switches = node;
-                       break;
-               case IB_NODE_ROUTER:
-                       node->type_next = fabric->routers;
-                       fabric->routers = node;
-                       break;
+       switch (node->type) {
+       case IB_NODE_CA:
+               node->type_next = fabric->ch_adapters;
+               fabric->ch_adapters = node;
+               break;
+       case IB_NODE_SWITCH:
+               node->type_next = fabric->switches;
+               fabric->switches = node;
+               break;
+       case IB_NODE_ROUTER:
+               node->type_next = fabric->routers;
+               fabric->routers = node;
+               break;
        }
 }
 
        }
 }
 
-static void
-add_to_nodedist(struct ibnd_node *node, struct ibnd_fabric *fabric)
+static void add_to_nodedist(ibnd_node_t * node, ibnd_fabric_t * fabric)
 {
 {
-       int dist = node->node.dist;
-       if (node->node.type != IB_NODE_SWITCH)
-                       dist = MAXHOPS;         /* special Ca list */
+       int dist = node->dist;
+       if (node->type != IB_NODE_SWITCH)
+               dist = MAXHOPS; /* special Ca list */
 
        node->dnext = fabric->nodesdist[dist];
        fabric->nodesdist[dist] = node;
 }
 
 
        node->dnext = fabric->nodesdist[dist];
        fabric->nodesdist[dist] = node;
 }
 
-
-static struct ibnd_node *
-create_node(struct ibnd_fabric *fabric, struct ibnd_node *temp, ib_portid_t *path, int dist)
+static ibnd_node_t *create_node(ibnd_fabric_t * fabric,
+                               ibnd_node_t * temp, ib_portid_t * path,
+                               int dist)
 {
 {
-       struct ibnd_node *node;
+       ibnd_node_t *node;
 
        node = malloc(sizeof(*node));
        if (!node) {
 
        node = malloc(sizeof(*node));
        if (!node) {
-               IBPANIC("OOM: node creation failed\n");
-               return NULL;
+               IBND_ERROR("OOM: node creation failed\n");
+               return (NULL);
        }
 
        memcpy(node, temp, sizeof(*node));
        }
 
        memcpy(node, temp, sizeof(*node));
-       node->node.dist = dist;
-       node->node.path_portid = *path;
-       node->node.fabric = (ibnd_fabric_t *)fabric;
+       node->dist = dist;
+       node->path_portid = *path;
 
        add_to_nodeguid_hash(node, fabric->nodestbl);
 
        /* add this to the all nodes list */
 
        add_to_nodeguid_hash(node, fabric->nodestbl);
 
        /* add this to the all nodes list */
-       node->node.next = fabric->fabric.nodes;
-       fabric->fabric.nodes = (ibnd_node_t *)node;
+       node->next = fabric->nodes;
+       fabric->nodes = (ibnd_node_t *) node;
 
        add_to_type_list(node, fabric);
        add_to_nodedist(node, fabric);
 
        add_to_type_list(node, fabric);
        add_to_nodedist(node, fabric);
@@ -391,134 +431,136 @@ create_node(struct ibnd_fabric *fabric, struct ibnd_node *temp, ib_portid_t *pat
        return node;
 }
 
        return node;
 }
 
-static struct ibnd_port *
-find_existing_port_node(struct ibnd_node *node, struct ibnd_port *port)
+static struct ibnd_port *find_existing_port_node(ibnd_node_t * node,
+                                                ibnd_port_t * port)
 {
 {
-       if (port->port.portnum > node->node.numports || node->node.ports == NULL )
+       if (port->portnum > node->numports || node->ports == NULL)
                return (NULL);
 
                return (NULL);
 
-       return (CONV_PORT_INTERNAL(node->node.ports[port->port.portnum]));
+       return (node->ports[port->portnum]);
 }
 
 }
 
-static struct ibnd_port *
-add_port_to_node(struct ibnd_fabric *fabric, struct ibnd_node *node, struct ibnd_port *temp)
+static struct ibnd_port *add_port_to_node(ibnd_fabric_t * fabric,
+                                         ibnd_node_t * node,
+                                         ibnd_port_t * temp)
 {
 {
-       struct ibnd_port *port;
-
-       port = malloc(sizeof(*port));
-       if (!port)
-               return NULL;
+       ibnd_port_t *port;
 
 
-       memcpy(port, temp, sizeof(*port));
-       port->port.node = (ibnd_node_t *)node;
-       port->port.ext_portnum = 0;
-
-       if (node->node.ports == NULL) {
-               node->node.ports = calloc(sizeof(*node->node.ports), node->node.numports + 1);
-               if (!node->node.ports) {
+       if (node->ports == NULL) {
+               node->ports = calloc(sizeof(*node->ports), node->numports + 1);
+               if (!node->ports) {
                        IBND_ERROR("Failed to allocate the ports array\n");
                        return (NULL);
                }
        }
 
                        IBND_ERROR("Failed to allocate the ports array\n");
                        return (NULL);
                }
        }
 
-       node->node.ports[temp->port.portnum] = (ibnd_port_t *)port;
+       port = malloc(sizeof(*port));
+       if (!port) {
+               IBND_ERROR("Failed to allocate port\n");
+               return NULL;
+       }
+
+       memcpy(port, temp, sizeof(*port));
+       port->node = (ibnd_node_t *) node;
+       port->ext_portnum = 0;
+
+       node->ports[temp->portnum] = (ibnd_port_t *) port;
 
        add_to_portguid_hash(port, fabric->portstbl);
        return port;
 }
 
 
        add_to_portguid_hash(port, fabric->portstbl);
        return port;
 }
 
-static void
-link_ports(struct ibnd_node *node, struct ibnd_port *port,
-               struct ibnd_node *remotenode, struct ibnd_port *remoteport)
+static void link_ports(ibnd_node_t * node, ibnd_port_t * port,
+                      ibnd_node_t * remotenode, ibnd_port_t * remoteport)
 {
 {
-       IBND_DEBUG("linking: 0x%" PRIx64 " %p->%p:%u and 0x%" PRIx64 " %p->%p:%u\n",
-               node->node.guid, node, port, port->port.portnum,
-               remotenode->node.guid, remotenode,
-               remoteport, remoteport->port.portnum);
-       if (port->port.remoteport)
-               port->port.remoteport->remoteport = NULL;
-       if (remoteport->port.remoteport)
-               remoteport->port.remoteport->remoteport = NULL;
-       port->port.remoteport = (ibnd_port_t *)remoteport;
-       remoteport->port.remoteport = (ibnd_port_t *)port;
+       IBND_DEBUG("linking: 0x%" PRIx64 " %p->%p:%u and 0x%" PRIx64
+                  " %p->%p:%u\n", node->guid, node, port, port->portnum,
+                  remotenode->guid, remotenode, remoteport,
+                  remoteport->portnum);
+       if (port->remoteport)
+               port->remoteport->remoteport = NULL;
+       if (remoteport->remoteport)
+               remoteport->remoteport->remoteport = NULL;
+       port->remoteport = (ibnd_port_t *) remoteport;
+       remoteport->remoteport = (ibnd_port_t *) port;
 }
 
 }
 
-static int
-get_remote_node(struct ibnd_fabric *fabric, struct ibnd_node *node, struct ibnd_port *port, ib_portid_t *path,
-               int portnum, int dist)
+static int get_remote_node(struct ibmad_port *ibmad_port,
+                          ibnd_fabric_t * fabric, ibnd_node_t * node,
+                          ibnd_port_t * port, ib_portid_t * path,
+                          int portnum, int dist)
 {
 {
-       struct ibnd_node node_buf;
-       struct ibnd_port port_buf;
-       struct ibnd_node *remotenode, *oldnode;
-       struct ibnd_port *remoteport, *oldport;
+       int rc = 0;
+       ibnd_node_t node_buf;
+       ibnd_port_t port_buf;
+       ibnd_node_t *remotenode, *oldnode;
+       ibnd_port_t *remoteport, *oldport;
 
        memset(&node_buf, 0, sizeof(node_buf));
        memset(&port_buf, 0, sizeof(port_buf));
 
 
        memset(&node_buf, 0, sizeof(node_buf));
        memset(&port_buf, 0, sizeof(port_buf));
 
-       IBND_DEBUG("handle node %p port %p:%d dist %d\n", node, port, portnum, dist);
+       IBND_DEBUG("handle node %p port %p:%d dist %d\n", node, port, portnum,
+                  dist);
 
 
-       if (mad_get_field(port->port.info, 0, IB_PORT_PHYS_STATE_F)
-                       != IB_PORT_PHYS_STATE_LINKUP)
-               return -1;
+       if (mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F)
+           != IB_PORT_PHYS_STATE_LINKUP)
+               return 1;       /* positive == non-fatal error */
 
 
-       if (extend_dpath(fabric, path, portnum) < 0)
+       if (extend_dpath(ibmad_port, fabric, path, portnum) < 0)
                return -1;
 
                return -1;
 
-       if (query_node(fabric, &node_buf, &port_buf, path)) {
-               IBWARN("NodeInfo on %s failed, skipping port",
-                       portid2str(path));
-               path->drpath.cnt--;     /* restore path */
-               return -1;
+       if (query_node(ibmad_port, fabric, &node_buf, &port_buf, path)) {
+               IBND_ERROR("Query remote node (%s) failed, skipping port\n",
+                          portid2str(path));
+               retract_dpath(path);
+               return 1;       /* positive == non-fatal error */
        }
 
        oldnode = find_existing_node(fabric, &node_buf);
        if (oldnode)
                remotenode = oldnode;
        }
 
        oldnode = find_existing_node(fabric, &node_buf);
        if (oldnode)
                remotenode = oldnode;
-       else if (!(remotenode = create_node(fabric, &node_buf, path, dist + 1)))
-               IBPANIC("no memory");
+       else if (!(remotenode = create_node(fabric, &node_buf, path, dist + 1))) {
+               rc = -1;
+               goto error;
+       }
 
        oldport = find_existing_port_node(remotenode, &port_buf);
        if (oldport) {
                remoteport = oldport;
 
        oldport = find_existing_port_node(remotenode, &port_buf);
        if (oldport) {
                remoteport = oldport;
-       } else if (!(remoteport = add_port_to_node(fabric, remotenode, &port_buf)))
-               IBPANIC("no memory");
+       } else if (!(remoteport = add_port_to_node(fabric, remotenode,
+                                                  &port_buf))) {
+               IBND_ERROR("OOM failed to add port to node\n");
+               rc = -1;
+               goto error;
+       }
 
        dump_endnode(path, oldnode ? "known remote" : "new remote",
 
        dump_endnode(path, oldnode ? "known remote" : "new remote",
-                       remotenode, remoteport);
+                    remotenode, remoteport);
 
        link_ports(node, port, remotenode, remoteport);
 
 
        link_ports(node, port, remotenode, remoteport);
 
-       path->drpath.cnt--;     /* restore path */
-       return 0;
+error:
+       retract_dpath(path);
+       return (rc);
 }
 
 }
 
-ibnd_fabric_t *
-ibnd_discover_fabric(struct ibmad_port *ibmad_port, int timeout_ms,
-                       ib_portid_t *from, int hops)
+ibnd_fabric_t *ibnd_discover_fabric(struct ibmad_port * ibmad_port,
+                                   ib_portid_t * from, int hops)
 {
 {
-       struct ibnd_fabric *fabric = NULL;
-       ib_portid_t my_portid = {0};
-       struct ibnd_node node_buf;
-       struct ibnd_port port_buf;
-       struct ibnd_node *node;
-       struct ibnd_port *port;
+       int rc = 0;
+       ibnd_fabric_t *fabric = NULL;
+       ib_portid_t my_portid = { 0 };
+       ibnd_node_t node_buf;
+       ibnd_port_t port_buf;
+       ibnd_node_t *node;
+       ibnd_port_t *port;
        int i;
        int dist = 0;
        ib_portid_t *path;
        int i;
        int dist = 0;
        ib_portid_t *path;
-       int max_hops = MAXHOPS-1; /* default find everything */
+       int max_hops = MAXHOPS - 1;     /* default find everything */
 
 
-       if (!ibmad_port) {
-               IBPANIC("ibmad_port must be specified to "
-                       "ibnd_discover_fabric\n");
-               return (NULL);
-       }
-       if (mad_rpc_class_agent(ibmad_port, IB_SMI_CLASS) == -1
-                       ||
-               mad_rpc_class_agent(ibmad_port, IB_SMI_DIRECT_CLASS) == -1) {
-               IBPANIC("ibmad_port must be opened with "
-                       "IB_SMI_CLASS && IB_SMI_DIRECT_CLASS\n");
+       if (_check_ibmad_port(ibmad_port) < 0)
                return (NULL);
                return (NULL);
-       }
 
        /* if not everything how much? */
        if (hops >= 0) {
 
        /* if not everything how much? */
        if (hops >= 0) {
@@ -532,21 +574,19 @@ ibnd_discover_fabric(struct ibmad_port *ibmad_port, int timeout_ms,
        fabric = malloc(sizeof(*fabric));
 
        if (!fabric) {
        fabric = malloc(sizeof(*fabric));
 
        if (!fabric) {
-               IBPANIC("OOM: failed to malloc ibnd_fabric_t\n");
+               IBND_ERROR("OOM: failed to malloc ibnd_fabric_t\n");
                return (NULL);
        }
 
        memset(fabric, 0, sizeof(*fabric));
 
                return (NULL);
        }
 
        memset(fabric, 0, sizeof(*fabric));
 
-       fabric->fabric.ibmad_port = ibmad_port;
-
        IBND_DEBUG("from %s\n", portid2str(from));
 
        memset(&node_buf, 0, sizeof(node_buf));
        memset(&port_buf, 0, sizeof(port_buf));
 
        IBND_DEBUG("from %s\n", portid2str(from));
 
        memset(&node_buf, 0, sizeof(node_buf));
        memset(&port_buf, 0, sizeof(port_buf));
 
-       if (query_node(fabric, &node_buf, &port_buf, from)) {
-               IBWARN("can't reach node %s\n", portid2str(from));
+       if (query_node(ibmad_port, fabric, &node_buf, &port_buf, from)) {
+               IBND_DEBUG("can't reach node %s\n", portid2str(from));
                goto error;
        }
 
                goto error;
        }
 
@@ -554,33 +594,41 @@ ibnd_discover_fabric(struct ibmad_port *ibmad_port, int timeout_ms,
        if (!node)
                goto error;
 
        if (!node)
                goto error;
 
-       fabric->fabric.from_node = (ibnd_node_t *)node;
+       fabric->from_node = (ibnd_node_t *) node;
 
        port = add_port_to_node(fabric, node, &port_buf);
        if (!port)
 
        port = add_port_to_node(fabric, node, &port_buf);
        if (!port)
-               IBPANIC("out of memory");
+               goto error;
 
 
-       if(get_remote_node(fabric, node, port, from,
-                               mad_get_field(node->node.info, 0, IB_NODE_LOCAL_PORT_F),
-                               0) < 0)
-               return ((ibnd_fabric_t *)fabric);
+       if (node->type != IB_NODE_SWITCH) {
+               rc = get_remote_node(ibmad_port, fabric, node, port, from,
+                                    mad_get_field(node->info, 0,
+                                                  IB_NODE_LOCAL_PORT_F), 0);
+               if (rc < 0)
+                       goto error;
+               if (rc > 0)             /* non-fatal error, nothing more to be done */
+                       return ((ibnd_fabric_t *) fabric);
+       }
 
        for (dist = 0; dist <= max_hops; dist++) {
 
                for (node = fabric->nodesdist[dist]; node; node = node->dnext) {
 
 
        for (dist = 0; dist <= max_hops; dist++) {
 
                for (node = fabric->nodesdist[dist]; node; node = node->dnext) {
 
-                       path = &node->node.path_portid;
+                       path = &node->path_portid;
 
                        IBND_DEBUG("dist %d node %p\n", dist, node);
                        dump_endnode(path, "processing", node, port);
 
 
                        IBND_DEBUG("dist %d node %p\n", dist, node);
                        dump_endnode(path, "processing", node, port);
 
-                       for (i = 1; i <= node->node.numports; i++) {
-                               if (i == mad_get_field(node->node.info, 0,
-                                                       IB_NODE_LOCAL_PORT_F))
+                       for (i = 1; i <= node->numports; i++) {
+                               if (i == mad_get_field(node->info, 0,
+                                                      IB_NODE_LOCAL_PORT_F))
                                        continue;
 
                                        continue;
 
-                               if (get_port_info(fabric, &port_buf, i, path)) {
-                                       IBWARN("can't reach node %s port %d", portid2str(path), i);
+                               if (get_port_info(ibmad_port, fabric,
+                                                 &port_buf, i, path)) {
+                                       IBND_ERROR
+                                           ("can't reach node %s port %d\n",
+                                            portid2str(path), i);
                                        continue;
                                }
 
                                        continue;
                                }
 
@@ -588,69 +636,73 @@ ibnd_discover_fabric(struct ibmad_port *ibmad_port, int timeout_ms,
                                if (port)
                                        continue;
 
                                if (port)
                                        continue;
 
-                               port = add_port_to_node(fabric, node, &port_buf);
+                               port =
+                                   add_port_to_node(fabric, node, &port_buf);
                                if (!port)
                                if (!port)
-                                       IBPANIC("out of memory");
+                                       goto error;
 
                                /* If switch, set port GUID to node port GUID */
 
                                /* If switch, set port GUID to node port GUID */
-                               if (node->node.type == IB_NODE_SWITCH) {
-                                       port->port.guid = mad_get_field64(node->node.info,
-                                                               0, IB_NODE_PORT_GUID_F);
+                               if (node->type == IB_NODE_SWITCH) {
+                                       port->guid =
+                                           mad_get_field64(node->info, 0,
+                                                           IB_NODE_PORT_GUID_F);
                                }
 
                                }
 
-                               get_remote_node(fabric, node, port, path, i, dist);
+                               if (get_remote_node(ibmad_port, fabric, node,
+                                                   port, path, i, dist) < 0)
+                                       goto error;
                        }
                }
        }
 
                        }
                }
        }
 
-       fabric->fabric.chassis = group_nodes(fabric);
+       if (group_nodes(fabric))
+               goto error;
 
 
-       return ((ibnd_fabric_t *)fabric);
+       return ((ibnd_fabric_t *) fabric);
 error:
 error:
-       free(fabric);
+       ibnd_destroy_fabric((ibnd_fabric_t *) fabric);
        return (NULL);
 }
 
        return (NULL);
 }
 
-static void
-destroy_node(struct ibnd_node *node)
+static void destroy_node(ibnd_node_t * node)
 {
        int p = 0;
 
 {
        int p = 0;
 
-       for (p = 0; p <= node->node.numports; p++) {
-               free(node->node.ports[p]);
+       for (p = 0; p <= node->numports; p++) {
+               free(node->ports[p]);
        }
        }
-       free(node->node.ports);
+       free(node->ports);
        free(node);
 }
 
        free(node);
 }
 
-void
-ibnd_destroy_fabric(ibnd_fabric_t *fabric)
+void ibnd_destroy_fabric(ibnd_fabric_t * fabric)
 {
 {
-       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
        int dist = 0;
        int dist = 0;
-       struct ibnd_node *node = NULL;
-       struct ibnd_node *next = NULL;
+       ibnd_node_t *node = NULL;
+       ibnd_node_t *next = NULL;
        ibnd_chassis_t *ch, *ch_next;
 
        ibnd_chassis_t *ch, *ch_next;
 
-       ch = f->first_chassis;
+       if (!fabric)
+               return;
+
+       ch = fabric->first_chassis;
        while (ch) {
                ch_next = ch->next;
                free(ch);
                ch = ch_next;
        }
        for (dist = 0; dist <= MAXHOPS; dist++) {
        while (ch) {
                ch_next = ch->next;
                free(ch);
                ch = ch_next;
        }
        for (dist = 0; dist <= MAXHOPS; dist++) {
-               node = f->nodesdist[dist];
+               node = fabric->nodesdist[dist];
                while (node) {
                        next = node->dnext;
                        destroy_node(node);
                        node = next;
                }
        }
                while (node) {
                        next = node->dnext;
                        destroy_node(node);
                        node = next;
                }
        }
-       free(f);
+       free(fabric);
 }
 
 }
 
-void
-ibnd_debug(int i)
+void ibnd_debug(int i)
 {
        if (i) {
                ibdebug++;
 {
        if (i) {
                ibdebug++;
@@ -663,52 +715,63 @@ ibnd_debug(int i)
        }
 }
 
        }
 }
 
-void
-ibnd_show_progress(int i)
+void ibnd_show_progress(int i)
 {
        show_progress = i;
 }
 
 {
        show_progress = i;
 }
 
-void
-ibnd_iter_nodes(ibnd_fabric_t *fabric,
-               ibnd_iter_node_func_t func,
-               void *user_data)
+void ibnd_iter_nodes(ibnd_fabric_t * fabric, ibnd_iter_node_func_t func,
+                    void *user_data)
 {
        ibnd_node_t *cur = NULL;
 
 {
        ibnd_node_t *cur = NULL;
 
+       if (!fabric) {
+               IBND_DEBUG("fabric parameter NULL\n");
+               return;
+       }
+
+       if (!func) {
+               IBND_DEBUG("func parameter NULL\n");
+               return;
+       }
+
        for (cur = fabric->nodes; cur; cur = cur->next) {
                func(cur, user_data);
        }
 }
 
        for (cur = fabric->nodes; cur; cur = cur->next) {
                func(cur, user_data);
        }
 }
 
-
-void
-ibnd_iter_nodes_type(ibnd_fabric_t *fabric,
-               ibnd_iter_node_func_t func,
-               int node_type,
-               void *user_data)
+void ibnd_iter_nodes_type(ibnd_fabric_t * fabric, ibnd_iter_node_func_t func,
+                         int node_type, void *user_data)
 {
 {
-       struct ibnd_fabric *f = CONV_FABRIC_INTERNAL(fabric);
-       struct ibnd_node *list = NULL;
-       struct ibnd_node *cur = NULL;
+       ibnd_node_t *list = NULL;
+       ibnd_node_t *cur = NULL;
+
+       if (!fabric) {
+               IBND_DEBUG("fabric parameter NULL\n");
+               return;
+       }
+
+       if (!func) {
+               IBND_DEBUG("func parameter NULL\n");
+               return;
+       }
 
        switch (node_type) {
 
        switch (node_type) {
-               case IB_NODE_SWITCH:
-                       list = f->switches;
-                       break;
-               case IB_NODE_CA:
-                       list = f->ch_adapters;
-                       break;
-               case IB_NODE_ROUTER:
-                       list = f->routers;
-                       break;
-               default:
-                       IBND_DEBUG("Invalid node_type specified %d\n", node_type);
-                       break;
+       case IB_NODE_SWITCH:
+               list = fabric->switches;
+               break;
+       case IB_NODE_CA:
+               list = fabric->ch_adapters;
+               break;
+       case IB_NODE_ROUTER:
+               list = fabric->routers;
+               break;
+       default:
+               IBND_DEBUG("Invalid node_type specified %d\n", node_type);
+               break;
        }
 
        for (cur = list; cur; cur = cur->type_next) {
        }
 
        for (cur = list; cur; cur = cur->type_next) {
-               func((ibnd_node_t *)cur, user_data);
+               func((ibnd_node_t *) cur, user_data);
        }
 }
        }
 }
-