[ofa-general] [PATCH RFC] libibumad: store pkeys in umad_port structure

Sasha Khapyorsky sashak at voltaire.com
Thu Nov 1 01:10:11 PDT 2007


This fetches pkey values from sysfs and stores it in umad_port structure,
so an user can find which proper pkey index to use with now working
umad_set_pkey().

Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
 libibumad/include/infiniband/umad.h |    2 +
 libibumad/src/umad.c                |   52 +++++++++++++++++++++++++++++++---
 2 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/libibumad/include/infiniband/umad.h b/libibumad/include/infiniband/umad.h
index 21cf729..681b440 100644
--- a/libibumad/include/infiniband/umad.h
+++ b/libibumad/include/infiniband/umad.h
@@ -132,6 +132,8 @@ typedef struct umad_port {
 	uint64_t capmask;
 	uint64_t gid_prefix;
 	uint64_t port_guid;
+	unsigned pkeys_size;
+	uint16_t *pkeys;
 } umad_port_t;
 
 typedef struct umad_ca {
diff --git a/libibumad/src/umad.c b/libibumad/src/umad.c
index 9d9f9c3..b63f220 100644
--- a/libibumad/src/umad.c
+++ b/libibumad/src/umad.c
@@ -46,6 +46,7 @@
 #include <netinet/in.h>
 #include <dirent.h>
 #include <stdlib.h>
+#include <ctype.h>
 
 #include "umad.h"
 
@@ -106,20 +107,33 @@ put_ca(umad_ca_t *ca)
 static int
 release_port(umad_port_t *port)
 {
-	return 0;	/* nothing yet */
+	free(port->pkeys);
+	port->pkeys = NULL;
+	port->pkeys_size = 0;
+	return 0;
+}
+
+static int check_for_digit_name(const struct dirent *dent)
+{
+	const char *p = dent->d_name;
+	while (*p && isdigit(*p))
+		p++;
+	return *p ? 0 : 1;
 }
 
 static int
-get_port(char *ca_name, char *dir_name, int portnum, umad_port_t *port)
+get_port(char *ca_name, char *dir, int portnum, umad_port_t *port)
 {
 	char port_dir[256];
 	uint8_t gid[16];
+	struct dirent **namelist = NULL;
+	int i, len, ret;
 
 	strncpy(port->ca_name, ca_name, sizeof port->ca_name - 1);
 	port->portnum = portnum;
+	port->pkeys = NULL;
 
-	snprintf(port_dir, sizeof port_dir - 1, "%s/%d", dir_name, portnum);
-	port_dir[sizeof port_dir - 1] = 0;
+	len = snprintf(port_dir, sizeof port_dir - 1, "%s/%d", dir, portnum);
 
 	if (sys_read_uint(port_dir, SYS_PORT_LMC, &port->lmc) < 0)
 		goto clean;
@@ -146,10 +160,38 @@ get_port(char *ca_name, char *dir_name, int portnum, umad_port_t *port)
 	memcpy(&port->gid_prefix, gid, sizeof port->gid_prefix);
 	memcpy(&port->port_guid, gid + 8, sizeof port->port_guid);
 
-	/* FIXME: handle pkeys and gids */
+	snprintf(port_dir + len, sizeof(port_dir) - len, "/pkeys");
+	ret = scandir(port_dir, &namelist, check_for_digit_name, NULL);
+	if (ret <= 0) {
+		IBWARN("no pkeys found for %s:%u (at dir %s)...",
+		       port->ca_name, port->portnum, port_dir);
+		goto clean;
+	}
+	port->pkeys = calloc(ret, sizeof(port->pkeys[0]));
+	if (!port->pkeys) {
+		IBWARN("get_port: calloc failed: %s", strerror(errno));
+		goto clean;
+	}
+	for (i = 0; i < ret ; i++) {
+		unsigned idx, val;
+		idx = strtoul(namelist[i]->d_name, NULL, 0);
+		sys_read_uint(port_dir, namelist[i]->d_name, &val);
+		port->pkeys[idx] = val;
+	}
+	port->pkeys_size = ret;
+	free(namelist);
+	namelist = NULL;
+	port_dir[len] = '\0';
+
+	/* FIXME: handle gids */
+
 	return 0;
 
 clean:
+	if (namelist)
+		free(namelist);
+	if (port->pkeys)
+		free(port->pkeys);
 	return -EIO;
 }
 
-- 
1.5.3.rc2.29.gc4640f




More information about the general mailing list