diff --git a/debian/libibumad3.symbols b/debian/libibumad3.symbols index 5f61e1c57..9b6e74682 100644 --- a/debian/libibumad3.symbols +++ b/debian/libibumad3.symbols @@ -3,6 +3,7 @@ libibumad.so.3 libibumad3 #MINVER# IBUMAD_1.0@IBUMAD_1.0 1.3.9 IBUMAD_1.1@IBUMAD_1.1 3.1.26 IBUMAD_1.2@IBUMAD_1.2 3.2.30 + IBUMAD_1.3@IBUMAD_1.3 3.3.53 umad_addr_dump@IBUMAD_1.0 1.3.9 umad_attribute_str@IBUMAD_1.0 1.3.10.2 umad_class_str@IBUMAD_1.0 1.3.10.2 @@ -25,6 +26,7 @@ libibumad.so.3 libibumad3 #MINVER# umad_init@IBUMAD_1.0 1.3.9 umad_method_str@IBUMAD_1.0 1.3.10.2 umad_open_port@IBUMAD_1.0 1.3.9 + umad_open_smi_port@IBUMAD_1.3 3.3.53 umad_poll@IBUMAD_1.0 1.3.9 umad_recv@IBUMAD_1.0 1.3.9 umad_register2@IBUMAD_1.0 1.3.10.2 diff --git a/libibumad/CMakeLists.txt b/libibumad/CMakeLists.txt index 074396c02..3ee12c83d 100644 --- a/libibumad/CMakeLists.txt +++ b/libibumad/CMakeLists.txt @@ -10,7 +10,7 @@ publish_headers(infiniband rdma_library(ibumad libibumad.map # See Documentation/versioning.md - 3 3.2.${PACKAGE_VERSION} + 3 3.3.${PACKAGE_VERSION} sysfs.c umad.c umad_str.c diff --git a/libibumad/libibumad.map b/libibumad/libibumad.map index 1d5367709..694d1dd2a 100644 --- a/libibumad/libibumad.map +++ b/libibumad/libibumad.map @@ -50,3 +50,8 @@ IBUMAD_1.2 { global: umad_sort_ca_device_list; } IBUMAD_1.1; + +IBUMAD_1.3 { + global: + umad_open_smi_port; +} IBUMAD_1.2; diff --git a/libibumad/man/umad_open_smi_port.3 b/libibumad/man/umad_open_smi_port.3 new file mode 100644 index 000000000..973581c44 --- /dev/null +++ b/libibumad/man/umad_open_smi_port.3 @@ -0,0 +1,37 @@ +.\" -*- nroff -*- +.\" Licensed under the OpenIB.org BSD license (FreeBSD Variant) - See COPYING.md +.\" +.TH UMAD_OPEN_SMI_PORT 3 "June 18, 2024" "OpenIB" "OpenIB Programmer's Manual" +.SH "NAME" +umad_open_smi_port \- open InfiniBand device SMI port for umad access +.SH "SYNOPSIS" +.nf +.B #include +.sp +.BI "int umad_open_smi_port(char " "*ca_name" ", int " "portnum" ); +.fi +.SH "DESCRIPTION" +.B umad_open_smi_port() +opens the SMI port +.I portnum +of the IB device +.I ca_name +for umad access. The port is selected by the library if not all parameters +are provided (see +.B umad_get_port() +for details). Only SMI ports will be selected. +.fi +.SH "RETURN VALUE" +.B umad_open_smi_port() +returns 0 or an unique positive value of umad device descriptor on success, and a negative value on error as follows: + -EOPNOTSUPP ABI version doesn't match + -ENODEV IB device with SMI port can't be resolved + -EINVAL port is not valid (bad +.I portnum\fR +or no umad device) + -EIO umad device for this port can't be opened +.SH "SEE ALSO" +.BR umad_open_port (3), +.SH "AUTHOR" +.TP +Amir Nir diff --git a/libibumad/umad.c b/libibumad/umad.c index 28980d61c..9de39c7ea 100644 --- a/libibumad/umad.c +++ b/libibumad/umad.c @@ -51,6 +51,7 @@ #include #define IB_OPENIB_OUI (0x001405) +#define CAPMASK_IS_SM_DISABLED (0x400) #include #include "sysfs.h" @@ -128,6 +129,11 @@ static int put_ca(umad_ca_t * ca) return 0; /* caching not implemented yet */ } +static unsigned is_smi_disabled(umad_port_t *port) +{ + return (be32toh(port->capmask) & CAPMASK_IS_SM_DISABLED); +} + static int release_port(umad_port_t * port) { free(port->pkeys); @@ -248,8 +254,9 @@ static int release_ca(umad_ca_t * ca) * the first port that is active, and if such is not found, to * the first port that is link up and if none are linkup, then * the first port that is not disabled. Otherwise return -1. + * if enforce_smi > 0, only search smi ports. if none are found, return -1. */ -static int resolve_ca_port(const char *ca_name, int *port) +static int resolve_ca_port(const char *ca_name, int *port, unsigned enforce_smi) { umad_ca_t ca; int active = -1, up = -1; @@ -280,6 +287,10 @@ static int resolve_ca_port(const char *ca_name, int *port) ret = -1; goto Exit; } + if (enforce_smi && is_smi_disabled(ca.ports[*port])) { + ret = -1; + goto Exit; + } if (ca.ports[*port]->state == 4) { ret = 1; goto Exit; @@ -297,6 +308,8 @@ static int resolve_ca_port(const char *ca_name, int *port) if (strcmp(ca.ports[i]->link_layer, "InfiniBand") && strcmp(ca.ports[i]->link_layer, "IB")) continue; + if (enforce_smi && is_smi_disabled(ca.ports[i])) + continue; if (up < 0 && ca.ports[i]->phys_state == 5) up = *port = i; if (ca.ports[i]->state == 4) { @@ -311,6 +324,8 @@ static int resolve_ca_port(const char *ca_name, int *port) DEBUG("checking port %d", i); if (!ca.ports[i]) continue; + if (enforce_smi && is_smi_disabled(ca.ports[i])) + continue; if (ca.ports[i]->phys_state != 3) { up = *port = i; break; @@ -333,7 +348,7 @@ static int resolve_ca_port(const char *ca_name, int *port) } static int resolve_ca_name(const char *ca_in, int *best_port, - char **ca_name) + char **ca_name, unsigned enforce_smi) { struct umad_device_node *device_list; struct umad_device_node *node; @@ -350,7 +365,7 @@ static int resolve_ca_name(const char *ca_in, int *best_port, } if (ca_in) { - if (resolve_ca_port(ca_in, best_port) < 0) + if (resolve_ca_port(ca_in, best_port, enforce_smi) < 0) return -1; *ca_name = strdup(ca_in); if (!(*ca_name)) @@ -370,7 +385,7 @@ static int resolve_ca_name(const char *ca_in, int *best_port, TRACE("checking ca '%s'", name_found); port = best_port ? *best_port : 0; - port_type = resolve_ca_port(name_found, &port); + port_type = resolve_ca_port(name_found, &port, enforce_smi); if (port_type < 0) continue; @@ -626,7 +641,7 @@ int umad_get_ca_portguids(const char *ca_name, __be64 *portguids, int max) char *found_ca_name; TRACE("ca name %s max port guids %d", ca_name, max); - if (resolve_ca_name(ca_name, NULL, &found_ca_name) < 0) { + if (resolve_ca_name(ca_name, NULL, &found_ca_name, 0) < 0) { result = -ENODEV; goto exit; } @@ -665,7 +680,7 @@ int umad_get_issm_path(const char *ca_name, int portnum, char path[], int max) TRACE("ca %s port %d", ca_name, portnum); - if (resolve_ca_name(ca_name, &portnum, &found_ca_name) < 0) { + if (resolve_ca_name(ca_name, &portnum, &found_ca_name, 0) < 0) { result = -ENODEV; goto exit; } @@ -685,7 +700,7 @@ int umad_get_issm_path(const char *ca_name, int portnum, char path[], int max) return result; } -int umad_open_port(const char *ca_name, int portnum) +static int do_umad_open_port(const char *ca_name, int portnum, unsigned enforce_smi) { char dev_file[UMAD_DEV_FILE_SZ]; int umad_id, fd, result; @@ -699,7 +714,7 @@ int umad_open_port(const char *ca_name, int portnum) goto exit; } - if (resolve_ca_name(ca_name, &portnum, &found_ca_name) < 0) { + if (resolve_ca_name(ca_name, &portnum, &found_ca_name, enforce_smi) < 0) { result = -ENODEV; goto exit; } @@ -735,13 +750,23 @@ int umad_open_port(const char *ca_name, int portnum) return result; } +int umad_open_port(const char *ca_name, int portnum) +{ + return do_umad_open_port(ca_name, portnum, 0); +} + +int umad_open_smi_port(const char *ca_name, int portnum) +{ + return do_umad_open_port(ca_name, portnum, 1); +} + int umad_get_ca(const char *ca_name, umad_ca_t *ca) { int r = 0; char *found_ca_name; TRACE("ca_name %s", ca_name); - if (resolve_ca_name(ca_name, NULL, &found_ca_name) < 0) { + if (resolve_ca_name(ca_name, NULL, &found_ca_name, 0) < 0) { r = -ENODEV; goto exit; } @@ -783,7 +808,7 @@ int umad_get_port(const char *ca_name, int portnum, umad_port_t *port) TRACE("ca_name %s portnum %d", ca_name, portnum); - if (resolve_ca_name(ca_name, &portnum, &found_ca_name) < 0) { + if (resolve_ca_name(ca_name, &portnum, &found_ca_name, 0) < 0) { result = -ENODEV; goto exit; } diff --git a/libibumad/umad.h b/libibumad/umad.h index f1fb2d0df..195216e1b 100644 --- a/libibumad/umad.h +++ b/libibumad/umad.h @@ -188,6 +188,7 @@ int umad_release_port(umad_port_t * port); int umad_get_issm_path(const char *ca_name, int portnum, char path[], int max); int umad_open_port(const char *ca_name, int portnum); +int umad_open_smi_port(const char *ca_name, int portnum); int umad_close_port(int portid); void *umad_get_mad(void *umad);