This provides RPC like API which may work with several ports.

Signed-off-by: Sasha Khapyorsky <[EMAIL PROTECTED]>
---

 libibmad/include/infiniband/mad.h |    9 +++
 libibmad/src/libibmad.map         |    4 +
 libibmad/src/register.c           |   20 +++++--
 libibmad/src/rpc.c                |  106 +++++++++++++++++++++++++++++++++++--
 libibumad/src/umad.c              |    4 +
 5 files changed, 130 insertions(+), 13 deletions(-)

diff --git a/libibmad/include/infiniband/mad.h 
b/libibmad/include/infiniband/mad.h
index 45ff572..bd8a80b 100644
--- a/libibmad/include/infiniband/mad.h
+++ b/libibmad/include/infiniband/mad.h
@@ -660,6 +660,7 @@ uint64_t mad_trid(void);
 int    mad_build_pkt(void *umad, ib_rpc_t *rpc, ib_portid_t *dport, 
ib_rmpp_hdr_t *rmpp, void *data);
 
 /* register.c */
+int    mad_register_port_client(int port_id, int mgmt, uint8_t rmpp_version);
 int    mad_register_client(int mgmt, uint8_t rmpp_version);
 int    mad_register_server(int mgmt, uint8_t rmpp_version,
                            uint32_t method_mask[4], uint32_t class_oui);
@@ -704,6 +705,14 @@ void       madrpc_lock(void);
 void   madrpc_unlock(void);
 void   madrpc_show_errors(int set);
 
+void * mad_rpc_open_port(char *dev_name, int dev_port, int *mgmt_classes,
+                         int num_classes);
+void   mad_rpc_close_port(void *ibmad_port);
+void * mad_rpc(void *ibmad_port, ib_rpc_t *rpc, ib_portid_t *dport,
+               void *payload, void *rcvdata);
+void *  mad_rpc_rmpp(void *ibmad_port, ib_rpc_t *rpc, ib_portid_t *dport,
+                    ib_rmpp_hdr_t *rmpp, void *data);
+
 /* smp.c */
 uint8_t * smp_query(void *buf, ib_portid_t *id, uint attrid, uint mod,
                    uint timeout);
diff --git a/libibmad/src/libibmad.map b/libibmad/src/libibmad.map
index bf81bd1..78b7ff0 100644
--- a/libibmad/src/libibmad.map
+++ b/libibmad/src/libibmad.map
@@ -62,6 +62,10 @@ IBMAD_1.0 {
                ib_resolve_self;
                ib_resolve_smlid;
                ibdebug;
+               mad_rpc_open_port;
+               mad_rpc_close_port;
+               mad_rpc;
+               mad_rpc_rmpp;
                madrpc;
                madrpc_def_timeout;
                madrpc_init;
diff --git a/libibmad/src/register.c b/libibmad/src/register.c
index 4f44625..52d6989 100644
--- a/libibmad/src/register.c
+++ b/libibmad/src/register.c
@@ -43,6 +43,7 @@ #include <unistd.h>
 #include <pthread.h>
 #include <sys/time.h>
 #include <string.h>
+#include <errno.h>
 
 #include <umad.h>
 #include "mad.h"
@@ -118,7 +119,7 @@ mad_agent_class(int agent)
 }
 
 int
-mad_register_client(int mgmt, uint8_t rmpp_version)
+mad_register_port_client(int port_id, int mgmt, uint8_t rmpp_version)
 {
        int vers, agent;
 
@@ -126,7 +127,7 @@ mad_register_client(int mgmt, uint8_t rm
                DEBUG("Unknown class %d mgmt_class", mgmt);
                return -1;
        }
-       if ((agent = umad_register(madrpc_portid(), mgmt,
+       if ((agent = umad_register(port_id, mgmt,
                                   vers, rmpp_version, 0)) < 0) {
                DEBUG("Can't register agent for class %d", mgmt);
                return -1;
@@ -137,13 +138,22 @@ mad_register_client(int mgmt, uint8_t rm
                return -1;
        }
 
-       if (register_agent(agent, mgmt) < 0)
-               return -1;
-
        return agent;
 }
 
 int
+mad_register_client(int mgmt, uint8_t rmpp_version)
+{
+       int agent;
+
+       agent = mad_register_port_client(madrpc_portid(), mgmt, rmpp_version);
+       if (agent < 0)
+               return agent;
+
+       return register_agent(agent, mgmt);
+}
+
+int
 mad_register_server(int mgmt, uint8_t rmpp_version,
                    uint32_t method_mask[4], uint32_t class_oui)
 {
diff --git a/libibmad/src/rpc.c b/libibmad/src/rpc.c
index b2d3e77..ac4f361 100644
--- a/libibmad/src/rpc.c
+++ b/libibmad/src/rpc.c
@@ -48,6 +48,13 @@ #include <errno.h>
 #include <umad.h>
 #include "mad.h"
 
+#define MAX_CLASS 256
+
+struct ibmad_port {
+       int port_id;  /* file descriptor returned by umad_open() */
+       int class_agents[MAX_CLASS]; /* class2agent mapper */
+};
+
 int ibdebug;
 
 static int mad_portid = -1;
@@ -105,7 +112,8 @@ madrpc_portid(void)
 }
 
 static int 
-_do_madrpc(void *sndbuf, void *rcvbuf, int agentid, int len, int timeout)
+_do_madrpc(int port_id, void *sndbuf, void *rcvbuf, int agentid, int len,
+          int timeout)
 {
        uint32_t trid; /* only low 32 bits */
        int retries;
@@ -133,7 +141,7 @@ _do_madrpc(void *sndbuf, void *rcvbuf, i
                }
 
                length = len;
-               if (umad_send(mad_portid, agentid, sndbuf, length, timeout, 0) 
< 0) {
+               if (umad_send(port_id, agentid, sndbuf, length, timeout, 0) < 
0) {
                        IBWARN("send failed; %m");
                        return -1;
                }
@@ -141,7 +149,7 @@ _do_madrpc(void *sndbuf, void *rcvbuf, i
                /* Use same timeout on receive side just in case */
                /* send packet is lost somewhere. */
                do {
-                       if (umad_recv(mad_portid, rcvbuf, &length, timeout) < 
0) {
+                       if (umad_recv(port_id, rcvbuf, &length, timeout) < 0) {
                                IBWARN("recv failed: %m");
                                return -1;
                        }
@@ -164,8 +172,10 @@ _do_madrpc(void *sndbuf, void *rcvbuf, i
 }
 
 void *
-madrpc(ib_rpc_t *rpc, ib_portid_t *dport, void *payload, void *rcvdata)
+mad_rpc(void *port_id, ib_rpc_t *rpc, ib_portid_t *dport, void *payload,
+       void *rcvdata)
 {
+       struct ibmad_port *p = port_id;
        int status, len;
        uint8_t sndbuf[1024], rcvbuf[1024], *mad;
 
@@ -175,7 +185,8 @@ madrpc(ib_rpc_t *rpc, ib_portid_t *dport
        if ((len = mad_build_pkt(sndbuf, rpc, dport, 0, payload)) < 0)
                return 0;
 
-       if ((len = _do_madrpc(sndbuf, rcvbuf, mad_class_agent(rpc->mgtclass),
+       if ((len = _do_madrpc(p->port_id, sndbuf, rcvbuf,
+                             p->class_agents[rpc->mgtclass],
                              len, rpc->timeout)) < 0)
                return 0;
 
@@ -198,8 +209,10 @@ madrpc(ib_rpc_t *rpc, ib_portid_t *dport
 }
 
 void *
-madrpc_rmpp(ib_rpc_t *rpc, ib_portid_t *dport, ib_rmpp_hdr_t *rmpp, void *data)
+mad_rpc_rmpp(void *port_id, ib_rpc_t *rpc, ib_portid_t *dport,
+            ib_rmpp_hdr_t *rmpp, void *data)
 {
+       struct ibmad_port *p = port_id;
        int status, len;
        uint8_t sndbuf[1024], rcvbuf[1024], *mad;
 
@@ -210,7 +223,8 @@ madrpc_rmpp(ib_rpc_t *rpc, ib_portid_t *
        if ((len = mad_build_pkt(sndbuf, rpc, dport, rmpp, data)) < 0)
                return 0;
 
-       if ((len = _do_madrpc(sndbuf, rcvbuf, mad_class_agent(rpc->mgtclass),
+       if ((len = _do_madrpc(p->port_id, sndbuf, rcvbuf,
+                             p->class_agents[rpc->mgtclass],
                              len, rpc->timeout)) < 0)
                return 0;
 
@@ -249,6 +263,24 @@ madrpc_rmpp(ib_rpc_t *rpc, ib_portid_t *
        return data;
 }
 
+void *
+madrpc(ib_rpc_t *rpc, ib_portid_t *dport, void *payload, void *rcvdata)
+{
+       struct ibmad_port port;
+       port.port_id = mad_portid;
+       port.class_agents[rpc->mgtclass] = mad_class_agent(rpc->mgtclass);
+       return mad_rpc(&port, rpc, dport, payload, rcvdata);
+}
+
+void *
+madrpc_rmpp(ib_rpc_t *rpc, ib_portid_t *dport, ib_rmpp_hdr_t *rmpp, void *data)
+{
+       struct ibmad_port port;
+       port.port_id = mad_portid;
+       port.class_agents[rpc->mgtclass] = mad_class_agent(rpc->mgtclass);
+       return mad_rpc_rmpp(&port, rpc, dport, rmpp, data);
+}
+
 static pthread_mutex_t rpclock = PTHREAD_MUTEX_INITIALIZER;
 
 void
@@ -282,3 +314,63 @@ madrpc_init(char *dev_name, int dev_port
                        IBPANIC("client_register for mgmt %d failed", mgmt);
        }
 }
+
+void *
+mad_rpc_open_port(char *dev_name, int dev_port,
+                 int *mgmt_classes, int num_classes)
+{
+       struct ibmad_port *p;
+       int port_id;
+
+       if (umad_init() < 0) {
+               IBWARN("can't init UMAD library");
+               errno = ENODEV;
+               return NULL;
+       }
+
+       p = malloc(sizeof(*p));
+       if (!p) {
+               errno = ENOMEM;
+               return NULL;
+       }
+       memset(p, 0, sizeof(*p));
+
+       if ((port_id = umad_open_port(dev_name, dev_port)) < 0) {
+               IBWARN("can't open UMAD port (%s:%d)", dev_name, dev_port);
+               if (!errno)
+                       errno = EIO;
+               free(p);
+               return NULL;
+       }
+
+       while (num_classes--) {
+               int rmpp_version = 0;
+               int mgmt = *mgmt_classes++;
+               int agent;
+
+               if (mgmt == IB_SA_CLASS)
+                       rmpp_version = 1;
+               if (mgmt < 0 || mgmt >= MAX_CLASS ||
+                   (agent = mad_register_port_client(port_id, mgmt,
+                                                     rmpp_version)) < 0) {
+                       IBWARN("client_register for mgmt %d failed", mgmt);
+                       if(!errno)
+                               errno = EINVAL;
+                       umad_close_port(port_id);
+                       free(p);
+                       return NULL;
+               }
+               p->class_agents[mgmt] = agent;
+       }
+
+       p->port_id = port_id;
+       return p;
+}
+
+void
+mad_rpc_close_port(void *port_id)
+{
+       struct ibmad_port *p = port_id;
+       umad_close_port(p->port_id);
+       free(p);
+}
diff --git a/libibumad/src/umad.c b/libibumad/src/umad.c
index a99fb5a..cb9eef6 100644
--- a/libibumad/src/umad.c
+++ b/libibumad/src/umad.c
@@ -93,12 +93,14 @@ port_alloc(int portid, char *dev, int po
 
        if (portid < 0 || portid >= UMAD_MAX_PORTS) {
                IBWARN("bad umad portid %d", portid);
+               errno = EINVAL;
                return 0;
        }
 
        if (port->dev_name[0]) {
                IBWARN("umad port id %d is already allocated for %s %d",
                        portid, port->dev_name, port->dev_port);
+               errno = EBUSY;
                return 0;
        }
 
@@ -567,7 +569,7 @@ umad_open_port(char *ca_name, int portnu
                return -EINVAL;
 
        if (!(port = port_alloc(umad_id, ca_name, portnum)))
-               return -EINVAL;
+               return -errno;
 
        snprintf(port->dev_file, sizeof port->dev_file - 1, "%s/umad%d",
                 UMAD_DEV_DIR , umad_id);

_______________________________________________
openib-general mailing list
openib-general@openib.org
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to