|
43 | 43 | #include <sys/stat.h> |
44 | 44 | #include <fcntl.h> |
45 | 45 | #include <errno.h> |
| 46 | +#include <dirent.h> |
46 | 47 | #include <linux/types.h> /* __be64 */ |
47 | 48 |
|
48 | 49 | #include <infiniband/umad.h> |
49 | 50 |
|
50 | 51 | #include <ibdiag_common.h> |
51 | 52 |
|
| 53 | +/* IB spec: Port supports Connection Manager (cap_mask bit 16) */ |
| 54 | +#define IB_PORT_CAP_CM (0x10000) |
| 55 | +#define SYS_PORT_GID "gids/0" |
| 56 | + |
52 | 57 | static const char * const node_type_str[] = { |
53 | 58 | "???", |
54 | 59 | "CA", |
@@ -193,13 +198,55 @@ static int port_dump(umad_port_t * port, int alone) |
193 | 198 | return 0; |
194 | 199 | } |
195 | 200 |
|
| 201 | +static bool port_has_gid(const char *ca_name, int portnum) |
| 202 | +{ |
| 203 | + char path[256]; |
| 204 | + FILE *f; |
| 205 | + |
| 206 | + snprintf(path, sizeof(path), |
| 207 | + SYS_INFINIBAND "/%s/ports/%d/" SYS_PORT_GID, ca_name, portnum); |
| 208 | + |
| 209 | + f = fopen(path, "r"); |
| 210 | + if (!f) |
| 211 | + return false; |
| 212 | + |
| 213 | + fclose(f); |
| 214 | + return true; |
| 215 | +} |
| 216 | + |
| 217 | +static int port_has_cm_cap(const char *ca_name, int portnum) |
| 218 | +{ |
| 219 | + char path[256], buf[32]; |
| 220 | + uint32_t capmask; |
| 221 | + |
| 222 | + snprintf(path, sizeof(path), |
| 223 | + SYS_INFINIBAND "/%s/ports/%d", ca_name, portnum); |
| 224 | + |
| 225 | + if (sys_read_string(path, SYS_PORT_CAPMASK, buf, sizeof(buf)) < 0) |
| 226 | + return 0; |
| 227 | + |
| 228 | + capmask = strtoul(buf, NULL, 0); |
| 229 | + return (capmask & IB_PORT_CAP_CM); |
| 230 | +} |
| 231 | + |
196 | 232 | static int ca_stat(const char *ca_name, int portnum, int no_ports) |
197 | 233 | { |
198 | 234 | umad_ca_t ca; |
199 | | - int r; |
200 | | - |
201 | | - if ((r = umad_get_ca(ca_name, &ca)) < 0) |
| 235 | + int r, check_port; |
| 236 | + |
| 237 | + r = umad_get_ca(ca_name, &ca); |
| 238 | + if (r < 0) { |
| 239 | + if (portnum == -1) |
| 240 | + check_port = 1; |
| 241 | + else |
| 242 | + check_port = portnum; |
| 243 | + |
| 244 | + if ((!port_has_gid(ca_name, check_port)) && (!port_has_cm_cap(ca_name, check_port))) { |
| 245 | + DEBUG("The device %s is not RDMA endpoint device", ca_name); |
| 246 | + return 0; |
| 247 | + } |
202 | 248 | return r; |
| 249 | + } |
203 | 250 |
|
204 | 251 | if (!ca.node_type) |
205 | 252 | return 0; |
|
0 commit comments