components/open-fabrics/libibverbs/solaris_compatibility.c
branchs11u3-sru
changeset 4996 739983ef315c
parent 3679 c058dce9610f
child 6322 c8b38df3868d
equal deleted inserted replaced
4993:efe17d59c020 4996:739983ef315c
    45 #include <sys/processor.h>
    45 #include <sys/processor.h>
    46 #include <stdio.h>
    46 #include <stdio.h>
    47 #include <stdlib.h>
    47 #include <stdlib.h>
    48 #include <strings.h>
    48 #include <strings.h>
    49 #include <sys/param.h>
    49 #include <sys/param.h>
    50 #include <sys/ib/adapters/hermon/hermon_ioctl.h>
       
    51 #include <sys/ib/adapters/tavor/tavor_ioctl.h>
       
    52 #include <sys/ib/clients/of/sol_uverbs/sol_uverbs_ioctl.h>
    50 #include <sys/ib/clients/of/sol_uverbs/sol_uverbs_ioctl.h>
    53 #include <sys/ib/clients/of/sol_umad/sol_umad_ioctl.h>
    51 #include <sys/ib/clients/of/sol_umad/sol_umad_ioctl.h>
    54 #include <sys/ib/adapters/MELLANOX.h>
       
    55 
       
    56 #include <alloca.h>
    52 #include <alloca.h>
    57 #include "../include/infiniband/arch.h"
    53 #include "../include/infiniband/arch.h"
    58 #include "../include/infiniband/verbs.h"
    54 #include "../include/infiniband/verbs.h"
    59 #include "../include/infiniband/kern-abi.h"
    55 #include "../include/infiniband/kern-abi.h"
    60 #include "../include/infiniband/driver.h"
    56 #include "../include/infiniband/driver.h"
    62 #include <pthread.h>
    58 #include <pthread.h>
    63 #include <kstat.h>
    59 #include <kstat.h>
    64 
    60 
    65 #define	min(a, b)	((a) < (b) ? (a) : (b))
    61 #define	min(a, b)	((a) < (b) ? (a) : (b))
    66 
    62 
    67 
       
    68 /*
       
    69  * The followings will be removed when changes in hermon_ioctl.h
       
    70  * are delivered through ON.
       
    71  */
       
    72 #ifndef	HERMON_GET_HWINFO_IOCTL_SUP
       
    73 #define	HERMON_IOCTL_GET_HWINFO	(('t' << 8) | 0x32)
       
    74 #pragma	pack(1)
       
    75 
       
    76 /* Structure used for getting HW info */
       
    77 typedef struct hermon_hw_info_ioctl_s {
       
    78 	uint32_t	af_hw_info_version;
       
    79 	uint32_t	af_padding1;	/* Padding for af_hwpn to be on */
       
    80 					/* 64 byte boundary */
       
    81 	char		af_hwpn[64];
       
    82 	uint16_t	af_pn_len;
       
    83 	uint64_t	af_padding2:48;	/* Padding for af_psid to be on */
       
    84 					/* 64 byte boundary */
       
    85 	char		af_psid[16];
       
    86 	uint16_t	af_psid_len;
       
    87 	uint32_t	af_padding3;	/* Padding for reserved to be on */
       
    88 					/* 64 byte boundary */
       
    89 	uint8_t		reserved[64];
       
    90 } hermon_hw_info_ioctl_t;
       
    91 #pragma	pack()
       
    92 #endif
       
    93 
       
    94 
       
    95 /*
    63 /*
    96  * duplicate ABI definitions for HCAs as the HCA abi headers are not
    64  * duplicate ABI definitions for HCAs as the HCA abi headers are not
    97  * installed in proto.
    65  * installed in proto.
    98  */
    66  */
    99 #define	MLX4_UVERBS_MAX_ABI_VERSION	3 /* mlx4-abi.h */
       
   100 #define	RDMA_USER_CM_MIN_ABI_VERSION	3 /* rdma_cma_abi.h */
    67 #define	RDMA_USER_CM_MIN_ABI_VERSION	3 /* rdma_cma_abi.h */
   101 #define	RDMA_USER_CM_MAX_ABI_VERSION	4 /* rdma_cma_abi.h */
    68 #define	RDMA_USER_CM_MAX_ABI_VERSION	4 /* rdma_cma_abi.h */
   102 
    69 
   103 #define	MLX4	0
    70 /*
       
    71  * Some useful definitions.
       
    72  */
   104 #define	HW_DRIVER_MAX_NAME_LEN			20
    73 #define	HW_DRIVER_MAX_NAME_LEN			20
   105 #define	UVERBS_KERNEL_SYSFS_NAME_BASE		"uverbs"
    74 #define	UVERBS_KERNEL_SYSFS_NAME_BASE		"uverbs"
   106 #define	UMAD_KERNEL_SYSFS_NAME_BASE		"umad"
    75 #define	UMAD_KERNEL_SYSFS_NAME_BASE		"umad"
   107 #define	IB_HCA_DEVPATH_PREFIX			"/dev/infiniband/hca"
    76 #define	IB_HCA_DEVPATH_PREFIX			"/dev/infiniband/hca"
   108 #define	IB_OFS_DEVPATH_PREFIX			"/dev/infiniband/ofs"
    77 #define	IB_OFS_DEVPATH_PREFIX			"/dev/infiniband/ofs"
   109 #define	CONNECTX_NAME				"mlx4_"
    78 #define	IB_HCA_DEVPATH_SZ			64
   110 
    79 #define	MAX_OFS_DEVPATH_LEN			64
   111 #define	MELLANOX_VENDOR_ID			0x15b3
       
   112 #define	PCI_DEVICE_ID_MELLANOX_HERMON_SDR	0x6340
       
   113 #define	PCI_DEVICE_ID_MELLANOX_HERMON_DDR	0x634a
       
   114 #define	PCI_DEVICE_ID_MELLANOX_HERMON_QDR	0x6354
       
   115 #define	PCI_DEVICE_ID_MELLANOX_HERMON_DDR_PCIE2	0x6732
       
   116 #define	PCI_DEVICE_ID_MELLANOX_HERMON_QDR_PCIE2	0x673c
       
   117 #define	INFINIHOST_DEVICE_ID_2			0x5a45
       
   118 #define	INFINIHOST_DEVICE_ID_4			0x6279
       
   119 
    80 
   120 #define	MAX_HCAS				(64*16)
    81 #define	MAX_HCAS				(64*16)
   121 #define	MAX_PORTS				(MAX_HCAS*2)
    82 #define	MAX_PORTS				(MAX_HCAS*2)
   122 
    83 
   123 /*
    84 /*
   129 #define	SOL_UVERBS_DRV_STATUS_UNLOADED	0x02
    90 #define	SOL_UVERBS_DRV_STATUS_UNLOADED	0x02
   130 
    91 
   131 static kstat_ctl_t	*kc = NULL;	/* libkstat cookie */
    92 static kstat_ctl_t	*kc = NULL;	/* libkstat cookie */
   132 static int sol_uverbs_drv_status = SOL_UVERBS_DRV_STATUS_UNKNOWN;
    93 static int sol_uverbs_drv_status = SOL_UVERBS_DRV_STATUS_UNKNOWN;
   133 static int sol_uverbs_minor_dev = -1;
    94 static int sol_uverbs_minor_dev = -1;
       
    95 
       
    96 /*
       
    97  * Ugly, evil and rest of the names that qualify for it.
       
    98  * This is a side definition for the uverbs hca_info till the
       
    99  * new header file can appear in the userland build environment once that
       
   100  * happens this code will go.
       
   101  */
       
   102 #if	(IB_USER_VERBS_SOLARIS_ABI_VERSION == 2)
       
   103 #undef	IB_USER_VERBS_SOLARIS_ABI_VERSION
       
   104 #define	IB_USER_VERBS_SOLARIS_ABI_VERSION	3
       
   105 #define	__VERBS_COMPAT_MODE	1
       
   106 
       
   107 /*
       
   108  * Some useful definitions.
       
   109  */
       
   110 #define	PSID_STR_SZ		40
       
   111 #define	IBDEV_NAME_SZ		64
       
   112 #define	HCA_DRIVER_NAME_SZ	40
       
   113 #define	DEVID_STR_SZ		40
       
   114 
       
   115 /*
       
   116  * These are duplicate definitions to help the build complete on userland
       
   117  * build machines till the header files are populated with the new versions.
       
   118  * Once the new header file is available in the build system this code will
       
   119  * be removed.
       
   120  */
       
   121 typedef struct sol_uverbs_hca_infov3_s {
       
   122 	char		uverbs_hca_psid_string[PSID_STR_SZ];
       
   123 	char		uverbs_hca_ibdev_name[IBDEV_NAME_SZ];
       
   124 	char		uverbs_hca_driver_name[HCA_DRIVER_NAME_SZ];
       
   125 	uint32_t	uverbs_hca_driver_instance;
       
   126 	uint32_t	uverbs_hca_vendorid;
       
   127 	uint16_t	uverbs_hca_deviceid;
       
   128 	uint16_t	uverbs_hca_devidx;
       
   129 	int32_t		uverbs_hca_abi_version;
       
   130 	uint64_t	uverbs_hca_fw_ver;
       
   131 	uint64_t	uverbs_hca_node_guid;
       
   132 	uint64_t	uverbs_hca_node_external_guid;
       
   133 	uint64_t	uverbs_hca_sys_image_guid;
       
   134 	uint32_t	uverbs_hca_hw_version;
       
   135 	uint8_t		uverbs_hca_pad1[4];
       
   136 	char		uverbs_hca_devid_string[DEVID_STR_SZ];
       
   137 } sol_uverbs_hca_infov3_t;
       
   138 
       
   139 typedef struct sol_uverbs_info_v3_s {
       
   140 	int32_t			uverbs_abi_version;
       
   141 	int32_t			uverbs_solaris_abi_version;
       
   142 	int16_t			uverbs_hca_cnt;
       
   143 	int8_t			uverbs_pad1[6]; /* Padding for alignment */
       
   144 	sol_uverbs_hca_infov3_t uverbs_hca_info[];
       
   145 } sol_uverbs_infov3_t;
       
   146 
       
   147 #define	SIZEOF_UVERBS_INFO	(sizeof (sol_uverbs_infov3_t))
       
   148 #define	SIZEOF_HCA_INFO		(sizeof (sol_uverbs_hca_infov3_t))
       
   149 #define	UVERBS_INFO(x)		((sol_uverbs_infov3_t *)x)
       
   150 #define	HCA_INFO(x)		((sol_uverbs_hca_infov3_t *)x)
       
   151 
       
   152 #else /* (IB_USER_VERBS_SOLARIS_ABI_VERSION == 3) */
       
   153 
       
   154 #define	SIZEOF_UVERBS_INFO	(sizeof (sol_uverbs_info_t))
       
   155 #define	SIZEOF_HCA_INFO		(sizeof (sol_uverbs_hca_info_t))
       
   156 #define	UVERBS_INFO(x)		((sol_uverbs_info_t *)x)
       
   157 #define	HCA_INFO(x)		((sol_uverbs_hca_info_t *)x)
       
   158 
       
   159 #endif /* END */
   134 
   160 
   135 /*
   161 /*
   136  * check_path() prefixs
   162  * check_path() prefixs
   137  */
   163  */
   138 typedef enum cp_prefix_e {
   164 typedef enum cp_prefix_e {
   139 	CP_SOL_UVERBS		= 1,
   165 	CP_SOL_UVERBS		= 1,
   140 	CP_DEVICE		= 2,
   166 	CP_DEVICE		= 2,
   141 	CP_D			= 3,
   167 	CP_D			= 3,
   142 	CP_GIDS			= 4,
   168 	CP_GIDS			= 4,
   143 	CP_PKEYS		= 5,
   169 	CP_PKEYS		= 5,
   144 	CP_MLX4			= 6,
   170 	CP_PORTS		= 6,
   145 	CP_PORTS		= 7,
   171 	CP_UMAD			= 7,
   146 	CP_UMAD			= 8,
   172 	CP_SLASH		= 8,
   147 	CP_SLASH		= 9,
   173 	CP_SYS			= 9,
   148 	CP_SYS			= 10,
   174 	CP_CLASS		= 10,
   149 	CP_CLASS		= 11,
   175 	CP_INFINIBAND_VERBS	= 11,
   150 	CP_INFINIBAND_VERBS	= 12,
   176 	CP_INFINIBAND		= 12,
   151 	CP_INFINIBAND		= 13,
   177 	CP_INFINIBAND_MAD	= 13,
   152 	CP_INFINIBAND_MAD	= 14,
   178 	CP_MISC			= 14,
   153 	CP_MISC			= 15,
   179 	CP_RDMA_CM		= 15
   154 	CP_RDMA_CM		= 16
       
   155 } cp_prefix_t;
   180 } cp_prefix_t;
   156 
   181 
   157 /*
   182 /*
   158  * Some temporary cache code, until things are cleaned up as part of DR
   183  * Some temporary cache code, until things are cleaned up as part of DR
   159  * work. This will speed up the sysfs emulation.
   184  * work. This will speed up the sysfs emulation.
   160  */
   185  */
   161 typedef struct ibdev_cache_info_s {
   186 typedef struct ibdev_cache_info_s {
   162 	uint_t		ibd_valid;
   187 	boolean_t			ibd_valid;
   163 	uint_t		ibd_hw_rev;
   188 	uint_t				ibd_hw_rev;
   164 	char		ibd_node_guid_str[20];
   189 	uint_t				ibd_abi_version;
   165 	char		ibd_node_guid_external_str[20];
   190 	uint_t				ibd_vendor_id;
   166 	char		ibd_sys_image_guid[20];
   191 	uint_t				ibd_device_id;
   167 	char		ibd_fw_ver[16];
   192 	char				ibd_hca_path[IB_HCA_DEVPATH_SZ];
   168 	char		ibd_name[16];
   193 	char				ibd_node_guid_str[20];
   169 	int		ibd_boardid_index;
   194 	char				ibd_node_guid_external_str[20];
   170 	uint_t		ibd_device_id;
   195 	char				ibd_sys_image_guid[20];
       
   196 	char				ibd_fw_ver[16];
       
   197 	char				ibd_name[IBDEV_NAME_SZ];
       
   198 	char				ibd_boardid_string[PSID_STR_SZ];
       
   199 	char				ibd_devid_string[DEVID_STR_SZ];
   171 } ibdev_cache_info_t;
   200 } ibdev_cache_info_t;
   172 
   201 
   173 /* hermon - hence 2 */
   202 /* IB device info cache */
   174 static ibdev_cache_info_t ibdev_cache[2][MAX_HCAS];
   203 static ibdev_cache_info_t	ibdev_cache[MAX_HCAS];
   175 
       
   176 typedef struct uverbs_cache_info_s {
       
   177 	uint_t		uvc_valid;
       
   178 	uint_t		uvc_ibdev_abi_version;
       
   179 	uint_t		uvc_vendor_id;
       
   180 	uint_t		uvc_device_id;
       
   181 	int		uvc_hca_instance;
       
   182 	char		uvc_ibdev_name[16];
       
   183 	char		uvc_ibdev_hca_path[MAXPATHLEN];
       
   184 } uverbs_cache_info_t;
       
   185 static uverbs_cache_info_t	uverbs_dev_cache[MAX_HCAS];
       
   186 static int			uverbs_abi_version = -1;
   204 static int			uverbs_abi_version = -1;
   187 
   205 
   188 typedef struct umad_cache_info_s {
   206 typedef struct umad_cache_info_s {
   189 	uint_t		umc_valid;
   207 	uint_t		umc_valid;
   190 	int		umc_port;
   208 	int		umc_port;
   193 static umad_cache_info_t	umad_dev_cache[MAX_PORTS];
   211 static umad_cache_info_t	umad_dev_cache[MAX_PORTS];
   194 static int			umad_abi_version = -1;
   212 static int			umad_abi_version = -1;
   195 
   213 
   196 pthread_once_t		oneTimeInit = PTHREAD_ONCE_INIT;
   214 pthread_once_t		oneTimeInit = PTHREAD_ONCE_INIT;
   197 static int 		umad_cache_cnt = 0;
   215 static int 		umad_cache_cnt = 0;
   198 static int 		ibdev_cache_cnt = 0;
       
   199 static int 		uverbs_cache_cnt = 0;
       
   200 static boolean_t	initialized = B_FALSE;
   216 static boolean_t	initialized = B_FALSE;
   201 static boolean_t	umad_cache_initialized = B_FALSE;
   217 static boolean_t	umad_cache_initialized = B_FALSE;
   202 static boolean_t	ibdev_cache_initialized = B_FALSE;
   218 static boolean_t	ibdev_cache_initialized = B_FALSE;
   203 static boolean_t	uverbs_cache_initialized = B_FALSE;
       
   204 static pthread_mutex_t	umad_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
   219 static pthread_mutex_t	umad_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
   205 static pthread_mutex_t	ibdev_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
   220 static pthread_mutex_t	ibdev_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
   206 static pthread_mutex_t	uverbs_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
       
   207 
   221 
   208 int sol_ibv_query_gid(struct ibv_context *, uint8_t, int, union ibv_gid *);
   222 int sol_ibv_query_gid(struct ibv_context *, uint8_t, int, union ibv_gid *);
   209 int sol_ibv_query_pkey(struct ibv_context *, uint8_t, int, uint16_t *);
   223 int sol_ibv_query_pkey(struct ibv_context *, uint8_t, int, uint16_t *);
   210 void __attribute__((constructor))solaris_init(void);
   224 void __attribute__((constructor))solaris_init(void);
   211 void __attribute__((destructor))solaris_fini(void);
   225 void __attribute__((destructor))solaris_fini(void);
   212 
   226 
   213 int sol_ibv_query_device(struct ibv_device *device,
   227 int sol_ibv_query_device(struct ibv_device *device,
   214     struct ibv_device_attr *device_attr);
   228     struct ibv_device_attr *device_attr);
   215 
   229 
   216 int sol_ibv_query_port(struct ibv_context *, uint8_t, struct ibv_port_attr *);
   230 int sol_ibv_query_port(struct ibv_context *, uint8_t, struct ibv_port_attr *);
   217 
       
   218 
   231 
   219 void
   232 void
   220 solaris_init(void)
   233 solaris_init(void)
   221 {
   234 {
   222 	while ((kc = kstat_open()) == NULL) {
   235 	while ((kc = kstat_open()) == NULL) {
   232 solaris_fini(void)
   245 solaris_fini(void)
   233 {
   246 {
   234 	(void) kstat_close(kc);
   247 	(void) kstat_close(kc);
   235 }
   248 }
   236 
   249 
       
   250 #define	isdigit(c)	((c) >= '0' && (c) <= '9')
       
   251 
       
   252 /*
       
   253  * Given a device name of the form <driver-prefix><instance>,
       
   254  * get the device number. Device name is of the form
       
   255  * for example:- mlx4_0, mlx4_2 etc. Function will return the device instance
       
   256  * extracted from the name.
       
   257  * for example:- mlx4_0 will return 0 and mlx4_2 will return 2.
       
   258  */
   237 static int
   259 static int
   238 umad_cache_add(uint_t dev_num, int port, char *ibdev)
   260 get_device_num(const char *device_name)
   239 {
   261 {
   240 	if ((dev_num >= MAX_PORTS) || (umad_cache_cnt >= MAX_PORTS)) {
   262 	const char *temp;
   241 		fprintf(stderr, "dev %d: exceeds umad cache size\n", dev_num);
   263 	const char *end;
   242 		return (1);
   264 	const char *start = device_name;
   243 	}
   265 	int len;
   244 
   266 	int devnum;
   245 	umad_dev_cache[dev_num].umc_port = port;
   267 
   246 	strcpy(umad_dev_cache[dev_num].umc_ib_dev, ibdev);
   268 	if (!start)
   247 	umad_dev_cache[dev_num].umc_valid = 1;
   269 		return (-1);
   248 	umad_cache_cnt++;
   270 
   249 	return (0);
   271 	len = strlen(device_name);
   250 }
   272 	end = &device_name[len - 1];
   251 
   273 
   252 static int
   274 	for (temp = end; temp >= start && isdigit(*temp); temp--)
   253 ibdev_cache_add(uint_t dev_num, ibdev_cache_info_t *info_p)
   275 		/* Null body */;
   254 {
   276 
   255 	if ((dev_num >= MAX_HCAS) || (ibdev_cache_cnt >= (MAX_HCAS * 2))) {
   277 	/*
   256 		fprintf(stderr, "dev %d: exceeds hca cache size\n", dev_num);
   278 	 * Check if the device number is invalid.
   257 		return (1);
   279 	 */
   258 	}
   280 	if (temp == end || temp < start)
   259 
   281 		return (-1);
   260 	if (!(strncmp(info_p->ibd_name, "mlx4", 4))) {
   282 
   261 		memcpy(&(ibdev_cache[MLX4][dev_num]), info_p,
   283 	devnum = atoi(temp + 1);
   262 		    sizeof (ibdev_cache_info_t));
   284 	if (devnum < 0 || devnum >= MAX_HCAS)
   263 		ibdev_cache[MLX4][dev_num].ibd_valid = 1;
   285 		return (-1);
   264 	} else {
   286 
   265 		fprintf(stderr, "dev %d: has no proper ibdev name\n", dev_num);
   287 	return (devnum);
   266 		return (1);
   288 }
   267 	}
   289 
   268 
   290 /*
   269 	ibdev_cache_cnt++;
   291  * For usages where ibdev cache needs to be read based on the IB device
   270 	return (0);
   292  * name instead of uverbs device name a simple compare against the cache
   271 }
   293  * entries is used to retrieve the corresponding ibdev cache entry.
   272 
   294  */
   273 static int
   295 static ibdev_cache_info_t *
   274 uverbs_cache_add(uint_t dev_num, uverbs_cache_info_t *info_p)
   296 ibdev_cache_read_by_devname(const char *devname)
   275 {
   297 {
   276 	if ((dev_num >= MAX_HCAS) || (uverbs_cache_cnt >= MAX_HCAS)) {
   298 	int idx;
   277 		fprintf(stderr, "dev %d: exceeds uverbs cache size\n", dev_num);
   299 	ibdev_cache_info_t *cache = NULL;
   278 		return (1);
   300 
   279 	}
   301 	if (!devname)
   280 
   302 		return (NULL);
   281 	memcpy(&(uverbs_dev_cache[dev_num]), info_p,
   303 
   282 	    sizeof (uverbs_cache_info_t));
   304 	for (idx = 0; idx < MAX_HCAS; idx++) {
   283 
   305 		cache = &ibdev_cache[idx];
   284 	uverbs_dev_cache[dev_num].uvc_valid = 1;
   306 		if (strcmp(cache->ibd_name, devname) == 0)
   285 	uverbs_cache_cnt++;
   307 			break;
   286 	return (0);
   308 	}
   287 }
   309 
   288 
   310 	/*
       
   311 	 * If we failed to find an entry return NULL.
       
   312 	 */
       
   313 	if (idx == MAX_HCAS)
       
   314 		cache = NULL;
       
   315 
       
   316 	return (cache);
       
   317 }
       
   318 
       
   319 /*
       
   320  * Helper function to update the ibdev cache entries with the values obtained
       
   321  * from the uverbs HCA info ioctl.
       
   322  */
   289 static int
   323 static int
   290 ibdev_cache_init()
   324 ibdev_cache_init()
   291 {
   325 {
   292 	ibdev_cache_info_t	info;
   326 	ibdev_cache_info_t		*info;
   293 	struct ibv_device	**root_dev_list, **dev_list = NULL;
   327 	int				fd, i, hca_cnt;
   294 	struct ibv_device_attr	device_attr;
   328 	char				uverbs_devpath[MAX_OFS_DEVPATH_LEN];
   295 	int			i, num_dev, dev_num, ret = 1;
   329 #ifdef	__VERBS_COMPAT_MODE
   296 	uint64_t		guid;
   330 	sol_uverbs_infov3_t		*uverbs_infop;
   297 	const char		*p, *ibdev;
   331 	sol_uverbs_hca_infov3_t		*hca_infop;
   298 
   332 #else
   299 
   333 	sol_uverbs_info_t		*uverbs_infop;
   300 	root_dev_list = dev_list = ibv_get_device_list(&num_dev);
   334 	sol_uverbs_hca_info_t		*hca_infop;
   301 	if (!dev_list) {
   335 #endif /* END __VERBS_COMPAT_MODE */
   302 		fprintf(stderr, "No HCA devices found");
   336 	char 				*buf;
   303 		goto error_exit1;
   337 	size_t				bufsize;
   304 	}
   338 	uint16_t			major, minor, sub_minor;
   305 
   339 	uint64_t			raw_fw_ver;
   306 	for (i = 0; i < num_dev; i++, dev_list++) {
   340 	uint64_t			guid;
   307 
   341 
   308 		if (sol_ibv_query_device(*dev_list, &device_attr)) {
   342 	snprintf(uverbs_devpath, MAX_OFS_DEVPATH_LEN, "%s/%s%d",
   309 			fprintf(stderr, "failed to query device %p\n",
       
   310 			    *dev_list);
       
   311 			goto error_exit2;
       
   312 		}
       
   313 
       
   314 		guid = ntohll(device_attr.node_guid);
       
   315 		sprintf(info.ibd_node_guid_str, "%04x:%04x:%04x:%04x",
       
   316 		    (unsigned)(guid >> 48) & 0xffff,
       
   317 		    (unsigned)(guid >> 32) & 0xffff,
       
   318 		    (unsigned)(guid >> 16) & 0xffff,
       
   319 		    (unsigned)(guid >>  0) & 0xffff);
       
   320 
       
   321 		guid = ntohll(device_attr.node_guid_external);
       
   322 		sprintf(info.ibd_node_guid_external_str, "%04x:%04x:%04x:%04x",
       
   323 		    (unsigned)(guid >> 48) & 0xffff,
       
   324 		    (unsigned)(guid >> 32) & 0xffff,
       
   325 		    (unsigned)(guid >> 16) & 0xffff,
       
   326 		    (unsigned)(guid >>  0) & 0xffff);
       
   327 
       
   328 		guid = ntohll(device_attr.sys_image_guid);
       
   329 		sprintf(info.ibd_sys_image_guid, "%04x:%04x:%04x:%04x",
       
   330 		    (unsigned)(guid >> 48) & 0xffff,
       
   331 		    (unsigned)(guid >> 32) & 0xffff,
       
   332 		    (unsigned)(guid >> 16) & 0xffff,
       
   333 		    (unsigned)(guid >>  0) & 0xffff);
       
   334 
       
   335 		(void) strcpy(info.ibd_fw_ver, device_attr.fw_ver);
       
   336 		info.ibd_hw_rev = device_attr.hw_ver;
       
   337 		info.ibd_device_id = device_attr.vendor_part_id;
       
   338 
       
   339 		ibdev = ibv_get_device_name(*dev_list);
       
   340 		if (strncmp(ibdev, "mlx4_", 5) == 0) {
       
   341 			p = ibdev + (strlen("mlx4_"));
       
   342 		} else {
       
   343 			fprintf(stderr, "Invalid device %s\n", ibdev);
       
   344 			goto error_exit2;
       
   345 		}
       
   346 		dev_num = atoi(p);
       
   347 		(void) strcpy(info.ibd_name, ibdev);
       
   348 
       
   349 		info.ibd_boardid_index = -1;
       
   350 
       
   351 		if (ibdev_cache_add(dev_num, &info)) {
       
   352 			fprintf(stderr, "failed to add dev %d to ibdev cache\n",
       
   353 			    dev_num);
       
   354 			goto error_exit2;
       
   355 		}
       
   356 	}
       
   357 
       
   358 	ret = 0;
       
   359 
       
   360 	/* clean up and Return */
       
   361 error_exit2:
       
   362 	if (root_dev_list)
       
   363 		ibv_free_device_list(root_dev_list);
       
   364 error_exit1:
       
   365 	return (ret);
       
   366 }
       
   367 
       
   368 static int
       
   369 uverbs_cache_init()
       
   370 {
       
   371 	uverbs_cache_info_t	info;
       
   372 	int			dev_num, fd, i, bufsize, hca_cnt;
       
   373 	char			uverbs_devpath[MAXPATHLEN];
       
   374 	sol_uverbs_info_t	*uverbs_infop;
       
   375 	sol_uverbs_hca_info_t	*hca_infop;
       
   376 	char *buf;
       
   377 
       
   378 	snprintf(uverbs_devpath, MAXPATHLEN, "%s/%s%d",
       
   379 	    IB_OFS_DEVPATH_PREFIX, UVERBS_KERNEL_SYSFS_NAME_BASE,
   343 	    IB_OFS_DEVPATH_PREFIX, UVERBS_KERNEL_SYSFS_NAME_BASE,
   380 	    sol_uverbs_minor_dev);
   344 	    sol_uverbs_minor_dev);
   381 
   345 
   382 	/*
   346 	/*
   383 	 * using the first sol_uverbs minor node that can be opened to get
   347 	 * using the first sol_uverbs minor node that can be opened to get
   384 	 * all the HCA information
   348 	 * all the HCA information
   385 	 */
   349 	 */
   386 	if ((fd = open(uverbs_devpath, O_RDWR)) < 0) {
   350 	if ((fd = open(uverbs_devpath, O_RDWR)) < 0) {
   387 		fprintf(stderr, "sol_uverbs failed to open: %s\n",
   351 		fprintf(stderr, "sol_uverbs failed to open: %s\n",
   388 		    strerror(errno));
   352 		    strerror(errno));
   389 		goto error_exit1;
   353 		return (-1);
   390 	}
   354 	}
   391 
   355 
   392 	bufsize = sizeof (sol_uverbs_info_t) + sizeof (sol_uverbs_hca_info_t) *
   356 	bufsize = SIZEOF_UVERBS_INFO + (MAX_HCAS * SIZEOF_HCA_INFO);
   393 	    MAX_HCAS;
       
   394 	buf = malloc(bufsize);
   357 	buf = malloc(bufsize);
       
   358 	if (!buf) {
       
   359 		fprintf(stderr, "ibdev_cache_update() failed to alloc\n");
       
   360 		close(fd);
       
   361 		return (-1);
       
   362 	}
   395 	memset(buf, 0, bufsize);
   363 	memset(buf, 0, bufsize);
   396 	uverbs_infop = (sol_uverbs_info_t *)buf;
   364 
       
   365 	uverbs_infop = UVERBS_INFO(buf);
   397 	uverbs_infop->uverbs_hca_cnt = MAX_HCAS;
   366 	uverbs_infop->uverbs_hca_cnt = MAX_HCAS;
   398 
   367 
   399 	if (ioctl(fd, UVERBS_IOCTL_GET_HCA_INFO, uverbs_infop) != 0) {
   368 	if (ioctl(fd, UVERBS_IOCTL_GET_HCA_INFO, uverbs_infop) != 0) {
   400 		fprintf(stderr, "sol_uverbs ioctl failed: %s\n",
   369 		fprintf(stderr, "sol_uverbs ioctl failed: %s\n",
   401 		    strerror(errno));
   370 		    strerror(errno));
   402 
   371 
   403 		goto error_exit2;
   372 		goto error_exit1;
   404 	}
   373 	}
   405 
   374 
   406 	if (uverbs_infop->uverbs_solaris_abi_version !=
   375 	if (uverbs_infop->uverbs_solaris_abi_version !=
   407 	    IB_USER_VERBS_SOLARIS_ABI_VERSION) {
   376 	    IB_USER_VERBS_SOLARIS_ABI_VERSION) {
   408 		fprintf(stderr, "sol_uverbs solaris_abi_version !="
   377 		fprintf(stderr, "sol_uverbs solaris_abi_version !="
   409 		    "IB_USER_VERBS_SOLARIS_ABI_VERSION : %d\n",
   378 		    "IB_USER_VERBS_SOLARIS_ABI_VERSION : %d\n",
   410 		    uverbs_infop->uverbs_solaris_abi_version);
   379 		    uverbs_infop->uverbs_solaris_abi_version);
   411 		goto error_exit2;
   380 		goto error_exit1;
   412 	}
   381 	}
   413 
   382 
   414 	hca_cnt = uverbs_infop->uverbs_hca_cnt;	/* hca count returned */
   383 	hca_cnt = uverbs_infop->uverbs_hca_cnt;	/* hca count returned */
   415 	hca_infop = uverbs_infop->uverbs_hca_info;
   384 	hca_infop = uverbs_infop->uverbs_hca_info;
   416 
   385 
       
   386 	if (hca_cnt > MAX_HCAS) {
       
   387 		fprintf(stderr, "Number of HCAs returned exceeds max\n");
       
   388 		goto error_exit1;
       
   389 	}
       
   390 
   417 	if (uverbs_abi_version == -1)
   391 	if (uverbs_abi_version == -1)
   418 		uverbs_abi_version = uverbs_infop->uverbs_abi_version;
   392 		uverbs_abi_version = uverbs_infop->uverbs_abi_version;
   419 
   393 
   420 	for (i = 0; i < hca_cnt; i++, hca_infop++) {
   394 	for (i = 0; i < hca_cnt; i++, hca_infop++) {
   421 		info.uvc_vendor_id = hca_infop->uverbs_hca_vendorid;
   395 
   422 		info.uvc_device_id = hca_infop->uverbs_hca_deviceid;
   396 		/*
   423 		info.uvc_hca_instance =
   397 		 * Update the cache.
   424 		    hca_infop->uverbs_hca_driver_instance;
   398 		 */
   425 
   399 		info = &ibdev_cache[hca_infop->uverbs_hca_devidx];
   426 		snprintf(info.uvc_ibdev_hca_path,
   400 
   427 		    sizeof (info.uvc_ibdev_hca_path),
   401 		(void) strncpy(info->ibd_name,
       
   402 		    hca_infop->uverbs_hca_ibdev_name, IBDEV_NAME_SZ);
       
   403 
       
   404 		guid = hca_infop->uverbs_hca_node_guid;
       
   405 		sprintf(info->ibd_node_guid_str, "%04x:%04x:%04x:%04x",
       
   406 		    (unsigned)(guid >> 48) & 0xffff,
       
   407 		    (unsigned)(guid >> 32) & 0xffff,
       
   408 		    (unsigned)(guid >> 16) & 0xffff,
       
   409 		    (unsigned)(guid >>  0) & 0xffff);
       
   410 
       
   411 		guid = hca_infop->uverbs_hca_node_external_guid;
       
   412 		sprintf(info->ibd_node_guid_external_str, "%04x:%04x:%04x:%04x",
       
   413 		    (unsigned)(guid >> 48) & 0xffff,
       
   414 		    (unsigned)(guid >> 32) & 0xffff,
       
   415 		    (unsigned)(guid >> 16) & 0xffff,
       
   416 		    (unsigned)(guid >>  0) & 0xffff);
       
   417 
       
   418 		guid = hca_infop->uverbs_hca_sys_image_guid;
       
   419 		sprintf(info->ibd_sys_image_guid, "%04x:%04x:%04x:%04x",
       
   420 		    (unsigned)(guid >> 48) & 0xffff,
       
   421 		    (unsigned)(guid >> 32) & 0xffff,
       
   422 		    (unsigned)(guid >> 16) & 0xffff,
       
   423 		    (unsigned)(guid >>  0) & 0xffff);
       
   424 
       
   425 		raw_fw_ver = hca_infop->uverbs_hca_fw_ver;
       
   426 		major	   = (raw_fw_ver >> 32) & 0xffff;
       
   427 		minor	   = (raw_fw_ver >> 16) & 0xffff;
       
   428 		sub_minor  = raw_fw_ver & 0xffff;
       
   429 
       
   430 		snprintf(info->ibd_fw_ver, sizeof (info->ibd_fw_ver),
       
   431 		    "%d.%d.%03d", major, minor, sub_minor);
       
   432 
       
   433 		info->ibd_hw_rev	= hca_infop->uverbs_hca_hw_version;
       
   434 		info->ibd_vendor_id	= hca_infop->uverbs_hca_vendorid;
       
   435 		info->ibd_device_id	= hca_infop->uverbs_hca_deviceid;
       
   436 		info->ibd_abi_version	= hca_infop->uverbs_hca_abi_version;
       
   437 
       
   438 		snprintf(info->ibd_hca_path, sizeof (info->ibd_hca_path),
   428 		    "%s/%s%d", IB_HCA_DEVPATH_PREFIX,
   439 		    "%s/%s%d", IB_HCA_DEVPATH_PREFIX,
   429 		    hca_infop->uverbs_hca_driver_name,
   440 		    hca_infop->uverbs_hca_driver_name,
   430 		    hca_infop->uverbs_hca_driver_instance);
   441 		    hca_infop->uverbs_hca_driver_instance);
   431 
   442 
   432 		if (strncmp(hca_infop->uverbs_hca_ibdev_name, "mlx4_", 5) == 0)
   443 		strncpy(info->ibd_boardid_string,
   433 			info.uvc_ibdev_abi_version =
   444 		    hca_infop->uverbs_hca_psid_string, PSID_STR_SZ);
   434 			    MLX4_UVERBS_MAX_ABI_VERSION;
   445 
   435 		else {
   446 		strncpy(info->ibd_devid_string,
   436 			fprintf(stderr, "libibverbs: sol_uverbs unsupported "
   447 		    hca_infop->uverbs_hca_devid_string, DEVID_STR_SZ);
   437 			    "device: %s\n", hca_infop->uverbs_hca_ibdev_name);
   448 
   438 			goto error_exit2;
   449 		info->ibd_valid = B_TRUE;
   439 		}
       
   440 
       
   441 		strcpy(info.uvc_ibdev_name, hca_infop->uverbs_hca_ibdev_name);
       
   442 
       
   443 		dev_num = hca_infop->uverbs_hca_devidx;
       
   444 		if (uverbs_cache_add(dev_num, &info)) {
       
   445 			fprintf(stderr, "failed to add dev %d to uverbs "
       
   446 			    "cache\n", dev_num);
       
   447 			goto error_exit2;
       
   448 		}
       
   449 	}
   450 	}
   450 
   451 
   451 	free(buf);
   452 	free(buf);
   452 	close(fd);
   453 	close(fd);
   453 	return (1);
   454 	return (0);
   454 
   455 
   455 error_exit2:
   456 error_exit1:
   456 	free(buf);
   457 	free(buf);
   457 	close(fd);
   458 	close(fd);
   458 
   459 	return (-1);
   459 error_exit1:
   460 }
       
   461 
       
   462 static int
       
   463 umad_cache_add(uint_t dev_num, int port, char *ibdev)
       
   464 {
       
   465 	if ((dev_num >= MAX_PORTS) || (umad_cache_cnt >= MAX_PORTS)) {
       
   466 		fprintf(stderr, "dev %d: exceeds umad cache size\n", dev_num);
       
   467 		return (1);
       
   468 	}
       
   469 
       
   470 	umad_dev_cache[dev_num].umc_port = port;
       
   471 	strcpy(umad_dev_cache[dev_num].umc_ib_dev, ibdev);
       
   472 	umad_dev_cache[dev_num].umc_valid = 1;
       
   473 	umad_cache_cnt++;
   460 	return (0);
   474 	return (0);
   461 }
   475 }
   462 
   476 
   463 static int
   477 static int
   464 umad_cache_init()
   478 umad_cache_init()
   465 {
   479 {
   466 	int				i, fd, minor;
   480 	int				i, fd, minor;
   467 	int				save_errno = 0;
   481 	int				save_errno = 0;
   468 	int				port_cnt, bufsize;
   482 	int				port_cnt, bufsize;
   469 	char				umad_devpath[MAXPATHLEN], *buf;
   483 	char				umad_devpath[MAX_OFS_DEVPATH_LEN], *buf;
   470 	sol_umad_ioctl_info_t		*umad_infop;
   484 	sol_umad_ioctl_info_t		*umad_infop;
   471 	sol_umad_ioctl_port_info_t	*port_infop;
   485 	sol_umad_ioctl_port_info_t	*port_infop;
   472 
   486 
   473 	for (minor = 0; minor < MAX_PORTS; minor++) {
   487 	for (minor = 0; minor < MAX_PORTS; minor++) {
   474 		snprintf(umad_devpath, MAXPATHLEN, "%s/%s%d",
   488 		snprintf(umad_devpath, MAX_OFS_DEVPATH_LEN, "%s/%s%d",
   475 		    IB_OFS_DEVPATH_PREFIX, UMAD_KERNEL_SYSFS_NAME_BASE,
   489 		    IB_OFS_DEVPATH_PREFIX, UMAD_KERNEL_SYSFS_NAME_BASE,
   476 		    minor);
   490 		    minor);
   477 
   491 
   478 		if ((fd = open(umad_devpath, O_RDWR)) > 0)
   492 		if ((fd = open(umad_devpath, O_RDWR)) > 0)
   479 			break;
   493 			break;
   485 	if ((minor == MAX_PORTS) && (fd < 0)) {
   499 	if ((minor == MAX_PORTS) && (fd < 0)) {
   486 		if (! save_errno)
   500 		if (! save_errno)
   487 			save_errno = errno;
   501 			save_errno = errno;
   488 		fprintf(stderr, "failed to open sol_umad: %s\n",
   502 		fprintf(stderr, "failed to open sol_umad: %s\n",
   489 		    strerror(save_errno));
   503 		    strerror(save_errno));
   490 		return (0);
   504 		return (-1);
   491 	}
   505 	}
   492 
   506 
   493 	bufsize = sizeof (sol_umad_ioctl_info_t) +
   507 	bufsize = sizeof (sol_umad_ioctl_info_t) +
   494 	    (sizeof (sol_umad_ioctl_port_info_t) * MAX_PORTS);
   508 	    (sizeof (sol_umad_ioctl_port_info_t) * MAX_PORTS);
   495 
   509 
   532 		}
   546 		}
   533 	}
   547 	}
   534 
   548 
   535 	free(buf);
   549 	free(buf);
   536 	close(fd);
   550 	close(fd);
   537 	return (1);
   551 	return (0);
   538 
   552 
   539 error_exit:
   553 error_exit:
   540 	free(buf);
   554 	free(buf);
   541 	close(fd);
   555 	close(fd);
   542 	return (0);
   556 	return (-1);
   543 }
   557 }
   544 
   558 
   545 void
   559 void
   546 initialize(void)
   560 initialize(void)
   547 {
   561 {
   548 	int		fd, minor;
   562 	int		fd, minor;
   549 	char		uverbs_devpath[MAXPATHLEN];
   563 	char		uverbs_devpath[MAX_OFS_DEVPATH_LEN];
   550 
   564 
   551 	/*
   565 	/*
   552 	 * find the first sol_uverbs minor node that can be opened successfully
   566 	 * find the first sol_uverbs minor node that can be opened successfully
   553 	 * and set sol_uverbs_mino_dev to that minor no.
   567 	 * and set sol_uverbs_mino_dev to that minor no.
   554 	 */
   568 	 */
   555 	for (minor = 0; minor < MAX_HCAS; minor++) {
   569 	for (minor = 0; minor < MAX_HCAS; minor++) {
   556 		snprintf(uverbs_devpath, MAXPATHLEN, "%s/%s%d",
   570 		snprintf(uverbs_devpath, MAX_OFS_DEVPATH_LEN, "%s/%s%d",
   557 		    IB_OFS_DEVPATH_PREFIX, UVERBS_KERNEL_SYSFS_NAME_BASE,
   571 		    IB_OFS_DEVPATH_PREFIX, UVERBS_KERNEL_SYSFS_NAME_BASE,
   558 		    minor);
   572 		    minor);
   559 
   573 
   560 		if ((fd = open(uverbs_devpath, O_RDWR)) < 0) {
   574 		if ((fd = open(uverbs_devpath, O_RDWR)) < 0) {
   561 			continue;
   575 			continue;
   574 	if (minor == MAX_HCAS && sol_uverbs_minor_dev == -1) {
   588 	if (minor == MAX_HCAS && sol_uverbs_minor_dev == -1) {
   575 		sol_uverbs_drv_status = SOL_UVERBS_DRV_STATUS_UNLOADED;
   589 		sol_uverbs_drv_status = SOL_UVERBS_DRV_STATUS_UNLOADED;
   576 		return;
   590 		return;
   577 	}
   591 	}
   578 
   592 
   579 	memset(&uverbs_dev_cache, 0, (sizeof (uverbs_cache_info_t) * MAX_HCAS));
   593 	memset(&ibdev_cache, 0, (sizeof (ibdev_cache_info_t) * MAX_HCAS));
   580 	memset(&ibdev_cache, 0, (sizeof (ibdev_cache_info_t) * MAX_HCAS * 2));
       
   581 	memset(&umad_dev_cache, 0,
   594 	memset(&umad_dev_cache, 0,
   582 	    (sizeof (umad_cache_info_t) * MAX_PORTS));
   595 	    (sizeof (umad_cache_info_t) * MAX_PORTS));
   583 
   596 
   584 	initialized = B_TRUE;
   597 	initialized = B_TRUE;
   585 }
   598 }
   586 
   599 
   587 /*
   600 /*
   588  * Some sysfs emulation software
   601  * Some sysfs emulation software
   589  */
   602  */
   590 
   603 
       
   604 /*
       
   605  * Extract the HCA dev name from the path and remove it from the path.
       
   606  * Given a path extract the HCA dev name of the form <dev-prefix><dev-instance>
       
   607  * During parsing the device instance number is validated to make sure it is
       
   608  * within MAX_HCAS limit, the routine also skips over the duplicate slashes.
       
   609  */
       
   610 static int
       
   611 check_path_for_hca(char *path, char *device_name)
       
   612 {
       
   613 	int pos = 0;
       
   614 	int len;
       
   615 
       
   616 	while ((path[pos] != '/') || (path[pos] == '\0'))
       
   617 		pos++;
       
   618 
       
   619 	if (path[pos] != '/')
       
   620 		return (0);
       
   621 
       
   622 	strncpy(device_name, path, (pos + 1));
       
   623 	device_name[pos] = '\0';
       
   624 
       
   625 	if (get_device_num(device_name) < 0)
       
   626 		return (0);
       
   627 
       
   628 	while (path[pos] == '/')
       
   629 		pos++;
       
   630 
       
   631 	len = strlen(path);
       
   632 	memmove(path, &path[pos], (len - pos) + 1);
       
   633 	return (1);
       
   634 }
   591 
   635 
   592 /*
   636 /*
   593  * Check whether a path starts with prefix, and if it does, remove it
   637  * Check whether a path starts with prefix, and if it does, remove it
   594  * from the string. The prefix can also contain one %d scan argument.
   638  * from the string. The prefix can also contain one %d scan argument.
   595  */
   639  */
   613 			ret = sscanf(path, "gids%n/", &pos);
   657 			ret = sscanf(path, "gids%n/", &pos);
   614 			break;
   658 			break;
   615 		case CP_PKEYS:
   659 		case CP_PKEYS:
   616 			ret = sscanf(path, "pkeys%n/", &pos);
   660 			ret = sscanf(path, "pkeys%n/", &pos);
   617 			break;
   661 			break;
   618 		case CP_MLX4:
       
   619 			ret = sscanf(path, "mlx4_%d%n/", arg, &pos);
       
   620 			break;
       
   621 		case CP_PORTS:
   662 		case CP_PORTS:
   622 			ret = sscanf(path, "ports%n/", &pos);
   663 			ret = sscanf(path, "ports%n/", &pos);
   623 			break;
   664 			break;
   624 		case CP_UMAD:
   665 		case CP_UMAD:
   625 			ret = sscanf(path, "umad%d%n/", arg, &pos);
   666 			ret = sscanf(path, "umad%d%n/", arg, &pos);
   667 
   708 
   668 static ibdev_cache_info_t *
   709 static ibdev_cache_info_t *
   669 get_device_info(const char *devname)
   710 get_device_info(const char *devname)
   670 {
   711 {
   671 	ibdev_cache_info_t 	*info = NULL;
   712 	ibdev_cache_info_t 	*info = NULL;
   672 	const char		*p = devname;
       
   673 	int			dev_num;
       
   674 
   713 
   675 	if (pthread_mutex_lock(&ibdev_cache_mutex) != 0) {
   714 	if (pthread_mutex_lock(&ibdev_cache_mutex) != 0) {
   676 		fprintf(stderr, "failed: to acquire ibdev_cache_mutex %s\n",
   715 		fprintf(stderr, "failed: to acquire ibdev_cache_mutex %s\n",
   677 		    strerror(errno));
   716 		    strerror(errno));
   678 		return (NULL);
   717 		return (NULL);
   679 	}
   718 	}
   680 
   719 
   681 	if (!ibdev_cache_initialized) {
   720 	if (ibdev_cache_initialized == B_FALSE) {
   682 		if (ibdev_cache_init()) {
   721 		if (ibdev_cache_init() != 0) {
   683 			(void) pthread_mutex_unlock(&ibdev_cache_mutex);
   722 			(void) pthread_mutex_unlock(&ibdev_cache_mutex);
   684 			fprintf(stderr, "failed to init ibdev_cache\n");
   723 			fprintf(stderr, "failed to init ibdev_cache\n");
   685 			return (NULL);
   724 			return (NULL);
   686 		} else {
   725 		}
   687 			ibdev_cache_initialized = B_TRUE;
   726 		ibdev_cache_initialized = B_TRUE;
   688 		}
       
   689 	}
   727 	}
   690 	(void) pthread_mutex_unlock(&ibdev_cache_mutex);
   728 	(void) pthread_mutex_unlock(&ibdev_cache_mutex);
   691 
   729 
   692 	if (strncmp(p, "mlx4_", 5) == 0) {
   730 	info = ibdev_cache_read_by_devname(devname);
   693 		p = p+(strlen("mlx4_"));
       
   694 	} else {
       
   695 		fprintf(stderr, "libibverbs: sol_uverbs unsupported "
       
   696 		    "device: %s\n", p);
       
   697 		return (NULL);
       
   698 	}
       
   699 	dev_num = atoi(p);
       
   700 
       
   701 	if (dev_num >= MAX_HCAS) {
       
   702 		fprintf(stderr, "Invalid device %s\n", devname);
       
   703 		return (NULL);
       
   704 	}
       
   705 
       
   706 	if (strncmp(devname, "mlx4", 4) == 0) {
       
   707 		if (ibdev_cache[MLX4][dev_num].ibd_valid)
       
   708 			info = &(ibdev_cache[MLX4][dev_num]);
       
   709 		else
       
   710 			info = NULL;
       
   711 	} else {
       
   712 		fprintf(stderr, "libibverbs: sol_uverbs unsupported "
       
   713 		    "device: %s\n", devname);
       
   714 		info = NULL;
       
   715 	}
       
   716 
   731 
   717 	return (info);
   732 	return (info);
   718 }
   733 }
   719 
   734 
   720 /*
   735 /*
   734 	struct ibv_device 	**root_dev_list, **dev_list = NULL;
   749 	struct ibv_device 	**root_dev_list, **dev_list = NULL;
   735 	struct ibv_context	ctx;
   750 	struct ibv_context	ctx;
   736 	union ibv_gid 		*gids = NULL;
   751 	union ibv_gid 		*gids = NULL;
   737 	uint16_t		*pkeys = NULL;
   752 	uint16_t		*pkeys = NULL;
   738 	int 			i, num_dev, rv, ret = 1;
   753 	int 			i, num_dev, rv, ret = 1;
   739 	char			uverbs_devpath[MAXPATHLEN];
   754 	char			uverbs_devpath[MAX_OFS_DEVPATH_LEN];
   740 
   755 
   741 	root_dev_list = dev_list = ibv_get_device_list(&num_dev);
   756 	root_dev_list = dev_list = ibv_get_device_list(&num_dev);
   742 	if (!dev_list) {
   757 	if (!dev_list) {
   743 		fprintf(stderr, "No HCA devices found\n");
   758 		fprintf(stderr, "No HCA devices found\n");
   744 		goto error_exit1;
   759 		goto error_exit1;
   753 	if (i == num_dev) {
   768 	if (i == num_dev) {
   754 		fprintf(stderr, "failed to find %s\n", devname);
   769 		fprintf(stderr, "failed to find %s\n", devname);
   755 		goto error_exit2;
   770 		goto error_exit2;
   756 	}
   771 	}
   757 
   772 
   758 	snprintf(uverbs_devpath, MAXPATHLEN, "%s/%s", IB_OFS_DEVPATH_PREFIX,
   773 	snprintf(uverbs_devpath, MAX_OFS_DEVPATH_LEN, "%s/%s",
   759 	    (*dev_list)->dev_name);
   774 	    IB_OFS_DEVPATH_PREFIX, (*dev_list)->dev_name);
   760 
   775 
   761 	ctx.device = *dev_list;
   776 	ctx.device = *dev_list;
   762 
   777 
   763 	if ((ctx.cmd_fd = open(uverbs_devpath, O_RDWR)) < 0)
   778 	if ((ctx.cmd_fd = open(uverbs_devpath, O_RDWR)) < 0)
   764 		goto error_exit2;
   779 		goto error_exit2;
   837 {
   852 {
   838 	int			fd;
   853 	int			fd;
   839 #ifndef _LP64
   854 #ifndef _LP64
   840 	int			tmpfd;
   855 	int			tmpfd;
   841 #endif
   856 #endif
   842 	int			uverbs_indx;
   857 	int			indx;
   843 
   858 
   844 	/*
   859 	/*
   845 	 * Map the user verbs device (uverbs) to the associated
   860 	 * Map the user verbs device (uverbs) to the associated
   846 	 * hca device.
   861 	 * hca device. ibdev_cache is indexed by uverbs device minor number
       
   862 	 * so extracting the index here to refer to the ibdev_cache value,
   847 	 */
   863 	 */
   848 	uverbs_indx = strtol(dev_name + strlen(UVERBS_KERNEL_SYSFS_NAME_BASE),
   864 	indx = strtol(dev_name + strlen(UVERBS_KERNEL_SYSFS_NAME_BASE),
   849 	    NULL, 0);
   865 	    NULL, 0);
   850 	if (uverbs_indx >= MAX_HCAS) {
   866 	if (indx >= MAX_HCAS) {
   851 		fprintf(stderr, "Invalid device %s\n", dev_name);
   867 		fprintf(stderr, "Invalid device %s\n", dev_name);
   852 		goto err_dev;
   868 		goto err_dev;
   853 	}
   869 	}
   854 
   870 
   855 	if (!uverbs_dev_cache[uverbs_indx].uvc_valid) {
   871 	if (!ibdev_cache[indx].ibd_valid) {
   856 		fprintf(stderr, "Invalid Device %s\n", dev_name);
   872 		fprintf(stderr, "Invalid Device %s\n", dev_name);
   857 		goto err_dev;
   873 		goto err_dev;
   858 	}
   874 	}
   859 
   875 
   860 	fd = open(uverbs_dev_cache[uverbs_indx].uvc_ibdev_hca_path, O_RDWR);
   876 	fd = open(ibdev_cache[indx].ibd_hca_path, O_RDWR);
   861 	if (fd < 0) {
   877 	if (fd < 0) {
   862 		goto err_dev;
   878 		goto err_dev;
   863 	}
   879 	}
   864 
   880 
   865 #ifndef _LP64
   881 #ifndef _LP64
   890 static int
   906 static int
   891 infiniband_verbs(char *path, char *buf, size_t size)
   907 infiniband_verbs(char *path, char *buf, size_t size)
   892 {
   908 {
   893 	unsigned int		device_num;
   909 	unsigned int		device_num;
   894 	int 			len = -1;
   910 	int 			len = -1;
   895 	uverbs_cache_info_t	*info_p;
   911 	ibdev_cache_info_t	*info_p;
   896 
   912 
   897 	if (pthread_mutex_lock(&uverbs_cache_mutex) != 0) {
   913 	if (pthread_mutex_lock(&ibdev_cache_mutex) != 0) {
   898 		fprintf(stderr, "failed: to acquire uverbs_cache_mutex %s\n",
   914 		fprintf(stderr, "failed: to acquire ibdev_cache_mutex %s\n",
   899 		    strerror(errno));
   915 		    strerror(errno));
   900 		goto exit;
   916 		goto exit;
   901 	}
   917 	}
   902 
   918 
   903 	if (!uverbs_cache_initialized) {
   919 	if (ibdev_cache_initialized == B_FALSE) {
   904 		if (uverbs_cache_init())
   920 		if (ibdev_cache_init() == 0)
   905 			uverbs_cache_initialized = B_TRUE;
   921 			ibdev_cache_initialized = B_TRUE;
   906 		else {
   922 		else {
   907 			(void) pthread_mutex_unlock(&uverbs_cache_mutex);
   923 			(void) pthread_mutex_unlock(&ibdev_cache_mutex);
   908 #ifdef	DEBUG
   924 #ifdef	DEBUG
   909 			fprintf(stderr, "failed: to init uverbs cache %s\n",
   925 			fprintf(stderr, "failed: to init ibdev cache %s\n",
   910 			    strerror(errno));
   926 			    strerror(errno));
   911 #endif
   927 #endif
   912 			goto exit;
   928 			goto exit;
   913 		}
   929 		}
   914 	}
   930 	}
   915 	(void) pthread_mutex_unlock(&uverbs_cache_mutex);
   931 	(void) pthread_mutex_unlock(&ibdev_cache_mutex);
   916 
   932 
   917 	if (check_path(path, CP_SOL_UVERBS, &device_num)) {
   933 	if (check_path(path, CP_SOL_UVERBS, &device_num)) {
   918 
   934 
   919 		if (device_num >= MAX_HCAS) {
   935 		if (device_num >= MAX_HCAS) {
   920 			fprintf(stderr, "Invalid path%s\n", path);
   936 			fprintf(stderr, "Invalid path%s\n", path);
   921 			goto exit;
   937 			goto exit;
   922 		}
   938 		}
   923 
   939 
   924 		if (!uverbs_dev_cache[device_num].uvc_valid) {
   940 		if (!ibdev_cache[device_num].ibd_valid)
   925 			goto exit;
   941 			goto exit;
   926 		}
   942 
   927 
   943 		info_p = &ibdev_cache[device_num];
   928 		info_p = &uverbs_dev_cache[device_num];
       
   929 
   944 
   930 		if (check_path(path, CP_DEVICE, NULL)) {
   945 		if (check_path(path, CP_DEVICE, NULL)) {
   931 			/*
   946 			/*
   932 			 * Under Linux, this is a link to the PCI device entry
   947 			 * Under Linux, this is a link to the PCI device entry
   933 			 * in /sys/devices/pci...../....
   948 			 * in /sys/devices/pci...../....
   934 			 */
   949 			 */
   935 			if (strcmp(path, "vendor") == 0) {
   950 			if (strcmp(path, "vendor") == 0) {
   936 				len = 1 + sprintf(buf, "0x%x",
   951 				len = 1 + sprintf(buf, "0x%x",
   937 				    info_p->uvc_vendor_id);
   952 				    info_p->ibd_vendor_id);
   938 			} else if (strcmp(path, "device") == 0) {
   953 			} else if (strcmp(path, "device") == 0) {
   939 				len = 1 + sprintf(buf, "0x%x",
   954 				len = 1 + sprintf(buf, "0x%x",
   940 				    info_p->uvc_device_id);
   955 				    info_p->ibd_device_id);
   941 			}
   956 			}
   942 		} else if (strcmp(path, "ibdev") == 0) {
   957 		} else if (strcmp(path, "ibdev") == 0) {
   943 			len = 1 + sprintf(buf, "%s",
   958 			len = 1 + sprintf(buf, "%s", info_p->ibd_name);
   944 			    info_p->uvc_ibdev_name);
       
   945 		} else if (strcmp(path, "abi_version") == 0) {
   959 		} else if (strcmp(path, "abi_version") == 0) {
   946 			len = 1 + sprintf(buf, "%d",
   960 			len = 1 + sprintf(buf, "%d", info_p->ibd_abi_version);
   947 			    info_p->uvc_ibdev_abi_version);
       
   948 		}
   961 		}
   949 	} else if (strcmp(path, "abi_version") == 0) {
   962 	} else if (strcmp(path, "abi_version") == 0) {
   950 
   963 
   951 		if (uverbs_abi_version == -1) {
   964 		if (uverbs_abi_version == -1) {
   952 			fprintf(stderr, "UVerbs ABI Version invalid\n");
   965 			fprintf(stderr, "UVerbs ABI Version invalid\n");
  1106 				break;
  1119 				break;
  1107 			case 2:
  1120 			case 2:
  1108 				rate = 5;
  1121 				rate = 5;
  1109 				break;
  1122 				break;
  1110 			case 4:
  1123 			case 4:
       
  1124 				/* FALLTHROUGH */
       
  1125 			case 8:
  1111 				rate = 10;
  1126 				rate = 10;
       
  1127 				break;
       
  1128 			case 16:
       
  1129 				rate = 14.0625;
       
  1130 				break;
       
  1131 			case 32:
       
  1132 				rate = 25.78125;
  1112 				break;
  1133 				break;
  1113 			default:
  1134 			default:
  1114 				rate = 0;
  1135 				rate = 0;
  1115 			}
  1136 			}
  1116 			switch (port_attr.active_width) {
  1137 			switch (port_attr.active_width) {
  1149 	}
  1170 	}
  1150 exit:
  1171 exit:
  1151 	return (len);
  1172 	return (len);
  1152 }
  1173 }
  1153 
  1174 
  1154 /*
       
  1155  * This function passes the HW PSID / HWPN string obtained from
       
  1156  * driver HERMON_IOCTL_GET_HWINFO IOCTL. The memory for "hca_hwpsid"
       
  1157  * & "hca_hwpn" argument has to be passed by the caller and has to
       
  1158  * be at least 16 bytes & 64 bytes in size.
       
  1159  */
       
  1160 static int
       
  1161 get_hca_psid_pn(char *ibd_name, int fd, char *hca_hwpsid,
       
  1162     char *hca_hwpn)
       
  1163 {
       
  1164 	hermon_hw_info_ioctl_t		hermon_hw_info;
       
  1165 	int				rc;
       
  1166 
       
  1167 	if (strncmp(ibd_name, "mlx4_", 5) == 0) {
       
  1168 		if ((rc = ioctl(fd, HERMON_IOCTL_GET_HWINFO,
       
  1169 		    &hermon_hw_info)) != 0)
       
  1170 			return (rc);
       
  1171 
       
  1172 		strncpy(hca_hwpsid, hermon_hw_info.af_psid, 16);
       
  1173 		strncpy(hca_hwpn, hermon_hw_info.af_hwpn, 64);
       
  1174 	} else {
       
  1175 		fprintf(stderr, "libibverbs: sol_uverbs unsupported "
       
  1176 		    "device: %s\n", ibd_name);
       
  1177 		return (1);
       
  1178 	}
       
  1179 	return (0);
       
  1180 }
       
  1181 
       
  1182 /*
       
  1183  * This function passes the HW Part number string obtained from driver
       
  1184  * IOCTL. The memory for "hca_hwpn" argument has to be passed by the
       
  1185  * caller and has to be at least 64 bytes in size.
       
  1186  */
       
  1187 static int
       
  1188 get_hca_hwpn_str(char *ibd_name, int fd, char *hca_hwpn)
       
  1189 {
       
  1190 	hermon_flash_init_ioctl_t	hermon_flash_info;
       
  1191 	int				rc;
       
  1192 
       
  1193 	if (strncmp(ibd_name, "mlx4_", 5) == 0) {
       
  1194 		if ((rc = ioctl(fd, HERMON_IOCTL_FLASH_INIT,
       
  1195 		    &hermon_flash_info)) != 0)
       
  1196 			return (rc);
       
  1197 		strncpy(hca_hwpn, hermon_flash_info.af_hwpn, 64);
       
  1198 	} else {
       
  1199 		fprintf(stderr, "libibverbs: sol_uverbs unsupported "
       
  1200 		    "device: %s\n", ibd_name);
       
  1201 		return (1);
       
  1202 	}
       
  1203 	return (0);
       
  1204 }
       
  1205 
       
  1206 static void
       
  1207 init_boardid_index(ibdev_cache_info_t *ibd_info)
       
  1208 {
       
  1209 	int		i;
       
  1210 	int		fd;
       
  1211 	char		hca_hwpsid[16];
       
  1212 	char		hca_hwpn[64];
       
  1213 	char		*pn_psidp;
       
  1214 	boolean_t	psid_valid, pn_valid;
       
  1215 
       
  1216 	if (pthread_mutex_lock(&uverbs_cache_mutex) != 0) {
       
  1217 		fprintf(stderr, "failed: to acquire "
       
  1218 		    "uverbs_cache_mutex %s\n",
       
  1219 		    strerror(errno));
       
  1220 		goto boardid_err;
       
  1221 	}
       
  1222 	if (!uverbs_cache_initialized) {
       
  1223 		if (uverbs_cache_init())
       
  1224 			uverbs_cache_initialized = B_TRUE;
       
  1225 		else {
       
  1226 			(void) pthread_mutex_unlock(&uverbs_cache_mutex);
       
  1227 #ifdef	DEBUG
       
  1228 			fprintf(stderr, "failed: to init uverbs cache %s\n",
       
  1229 			    strerror(errno));
       
  1230 #endif
       
  1231 			goto boardid_err;
       
  1232 		}
       
  1233 	}
       
  1234 	(void) pthread_mutex_unlock(&uverbs_cache_mutex);
       
  1235 
       
  1236 	for (i = 0; i < MAX_HCAS; i++) {
       
  1237 		if (uverbs_dev_cache[i].uvc_valid &&
       
  1238 		    strcmp(uverbs_dev_cache[i].uvc_ibdev_name,
       
  1239 		    ibd_info->ibd_name) == 0) {
       
  1240 			break;
       
  1241 		}
       
  1242 	}
       
  1243 
       
  1244 	if (i == MAX_HCAS) {
       
  1245 		fprintf(stderr, "failed to find uverbs_dev for %s\n",
       
  1246 		    ibd_info->ibd_name);
       
  1247 		goto boardid_err;
       
  1248 	}
       
  1249 
       
  1250 	fd = open(uverbs_dev_cache[i].uvc_ibdev_hca_path, O_RDWR);
       
  1251 	if (fd < 0) {
       
  1252 		goto boardid_err;
       
  1253 	}
       
  1254 
       
  1255 	psid_valid = pn_valid = B_FALSE;
       
  1256 	if (get_hca_psid_pn(ibd_info->ibd_name, fd,
       
  1257 	    hca_hwpsid, hca_hwpn)) {
       
  1258 		if (get_hca_hwpn_str(ibd_info->ibd_name, fd, hca_hwpn)) {
       
  1259 			close(fd);
       
  1260 			goto boardid_err;
       
  1261 		} else {
       
  1262 			if (hca_hwpn[0]) {
       
  1263 				if ((pn_psidp = strchr(
       
  1264 				    hca_hwpn, ' ')) != NULL)
       
  1265 					*pn_psidp = '\0';
       
  1266 				pn_valid = B_TRUE;
       
  1267 			}
       
  1268 		}
       
  1269 	} else {
       
  1270 		if (hca_hwpsid[0]) {
       
  1271 			if ((pn_psidp = strchr(
       
  1272 			    hca_hwpsid, ' ')) != NULL)
       
  1273 				*pn_psidp = '\0';
       
  1274 			psid_valid = B_TRUE;
       
  1275 		} else if (hca_hwpn[0]) {
       
  1276 			if ((pn_psidp = strchr(
       
  1277 			    hca_hwpn, ' ')) != NULL)
       
  1278 				*pn_psidp = '\0';
       
  1279 			pn_valid = B_TRUE;
       
  1280 		}
       
  1281 	}
       
  1282 	close(fd);
       
  1283 
       
  1284 	if (pn_valid == B_FALSE && psid_valid == B_FALSE)
       
  1285 		goto boardid_err;
       
  1286 
       
  1287 	for (i = 0; i < MLX_MAX_ID; i++) {
       
  1288 		/*
       
  1289 		 * Find PSID number, set the boardid_index,
       
  1290 		 * Skip index 0, as it is for failure "unknown"
       
  1291 		 * case
       
  1292 		 */
       
  1293 		if ((psid_valid == B_TRUE &&
       
  1294 		    strncmp(mlx_mdr[i].mlx_psid,
       
  1295 		    (const char *)hca_hwpsid,
       
  1296 		    min(strlen(hca_hwpsid),
       
  1297 		    strlen(mlx_mdr[i].mlx_psid))) == 0) ||
       
  1298 		    (pn_valid == B_TRUE &&
       
  1299 		    strncmp(mlx_mdr[i].mlx_pn,
       
  1300 		    (const char *)hca_hwpn,
       
  1301 		    min(strlen(hca_hwpn),
       
  1302 		    strlen(mlx_mdr[i].mlx_pn))) == 0)) {
       
  1303 			/* Set boardid_index */
       
  1304 			ibd_info->ibd_boardid_index = i;
       
  1305 			return;
       
  1306 		}
       
  1307 	}
       
  1308 
       
  1309 boardid_err:
       
  1310 	/* Failure case, default to "unknown" */
       
  1311 	ibd_info->ibd_boardid_index = -2;
       
  1312 }
       
  1313 
       
  1314 static int
  1175 static int
  1315 infiniband(char *path, char *buf, size_t size)
  1176 infiniband(char *path, char *buf, size_t size)
  1316 {
  1177 {
  1317 	int			len = -1;
  1178 	int			len = -1;
  1318 	unsigned int		device_num;
  1179 	char			dev_name[MAXNAMELEN];
  1319 	char			dev_name[10];
       
  1320 	ibdev_cache_info_t	*info;
  1180 	ibdev_cache_info_t	*info;
  1321 
  1181 
  1322 	memset(dev_name, 0, 10);
  1182 	memset(dev_name, 0, MAXNAMELEN);
  1323 
  1183 
  1324 	if (check_path(path, CP_MLX4, &device_num)) {
  1184 	if (!check_path_for_hca(path, dev_name))
  1325 		sprintf(dev_name, "mlx4_%d", device_num);
       
  1326 	} else {
       
  1327 		goto exit;
  1185 		goto exit;
  1328 	}
       
  1329 
  1186 
  1330 	if (check_path(path, CP_PORTS, NULL)) {
  1187 	if (check_path(path, CP_PORTS, NULL)) {
  1331 		len = infiniband_ports(path, buf, size, dev_name);
  1188 		len = infiniband_ports(path, buf, size, dev_name);
  1332 	} else if (strcmp(path, "node_type") == 0) {
  1189 	} else if (strcmp(path, "node_type") == 0) {
  1333 		len = 1 + sprintf(buf, "%d", IBV_NODE_CA);
  1190 		len = 1 + sprintf(buf, "%d", IBV_NODE_CA);
  1345 		} else if (strcmp(path, "fw_ver") == 0) {
  1202 		} else if (strcmp(path, "fw_ver") == 0) {
  1346 			len = 1 + sprintf(buf, "%s", info->ibd_fw_ver);
  1203 			len = 1 + sprintf(buf, "%s", info->ibd_fw_ver);
  1347 		} else if (strcmp(path, "hw_rev") == 0) {
  1204 		} else if (strcmp(path, "hw_rev") == 0) {
  1348 			len = 1 + sprintf(buf, "%d", info->ibd_hw_rev);
  1205 			len = 1 + sprintf(buf, "%d", info->ibd_hw_rev);
  1349 		} else if (strcmp(path, "hca_type") == 0) {
  1206 		} else if (strcmp(path, "hca_type") == 0) {
  1350 			if (!(strncmp(info->ibd_name, "mlx4", 4)))
  1207 			len = 1 + sprintf(buf, "%s", info->ibd_devid_string);
  1351 				len = 1 + sprintf(buf, "MT%d",
       
  1352 				    info->ibd_device_id);
       
  1353 			else
       
  1354 				len = 1 + sprintf(buf, "unavailable");
       
  1355 		} else if (strcmp(path, "board_id") == 0) {
  1208 		} else if (strcmp(path, "board_id") == 0) {
  1356 			if (info->ibd_boardid_index == -1)
  1209 			len = 1 + sprintf(buf, "%s", info->ibd_boardid_string);
  1357 				init_boardid_index(info);
       
  1358 
       
  1359 			if (info->ibd_boardid_index >= 0) {
       
  1360 				len = 1 + sprintf(buf, "%s",
       
  1361 				    mlx_mdr[info->ibd_boardid_index].mlx_psid);
       
  1362 			} else {
       
  1363 				len = 1 + sprintf(buf, "%s",
       
  1364 				    "unknown");
       
  1365 			}
       
  1366 		}
  1210 		}
  1367 	}
  1211 	}
  1368 exit:
  1212 exit:
  1369 	return (len);
  1213 	return (len);
  1370 }
  1214 }
  1378 	if (pthread_mutex_lock(&umad_cache_mutex) != 0) {
  1222 	if (pthread_mutex_lock(&umad_cache_mutex) != 0) {
  1379 		fprintf(stderr, "failed: to acquire umad_cache_mutex %s\n",
  1223 		fprintf(stderr, "failed: to acquire umad_cache_mutex %s\n",
  1380 		    strerror(errno));
  1224 		    strerror(errno));
  1381 		goto exit;
  1225 		goto exit;
  1382 	}
  1226 	}
  1383 	if (!umad_cache_initialized) {
  1227 	if (umad_cache_initialized == B_FALSE) {
  1384 		if (umad_cache_init())
  1228 		if (umad_cache_init() == 0)
  1385 			umad_cache_initialized = B_TRUE;
  1229 			umad_cache_initialized = B_TRUE;
  1386 		else {
  1230 		else {
  1387 			(void) pthread_mutex_unlock(&umad_cache_mutex);
  1231 			(void) pthread_mutex_unlock(&umad_cache_mutex);
  1388 #ifdef	DEBUG
  1232 #ifdef	DEBUG
  1389 			fprintf(stderr, "failed: to init umad cache %s\n",
  1233 			fprintf(stderr, "failed: to init umad cache %s\n",
  1537 {
  1381 {
  1538 	size_t		i, nr_cpus;
  1382 	size_t		i, nr_cpus;
  1539 	kstat_t		*ksp;
  1383 	kstat_t		*ksp;
  1540 	kstat_named_t	*knp;
  1384 	kstat_named_t	*knp;
  1541 
  1385 
  1542 	memset(stats, 0, sizeof (stats));
  1386 	memset(stats, 0, sizeof (sol_cpu_stats_t));
  1543 	nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
  1387 	nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
  1544 
  1388 
  1545 	/* Aggregate the value of all CPUs */
  1389 	/* Aggregate the value of all CPUs */
  1546 	for (i = 0; i < nr_cpus; i++) {
  1390 	for (i = 0; i < nr_cpus; i++) {
  1547 		/*
  1391 		/*
  1733 int
  1577 int
  1734 sol_ibv_query_device(struct ibv_device *device, struct ibv_device_attr *attr)
  1578 sol_ibv_query_device(struct ibv_device *device, struct ibv_device_attr *attr)
  1735 {
  1579 {
  1736 	struct ibv_query_device cmd;
  1580 	struct ibv_query_device cmd;
  1737 	struct ibv_context	context;
  1581 	struct ibv_context	context;
  1738 	char			uverbs_devpath[MAXPATHLEN];
  1582 	char			uverbs_devpath[MAX_OFS_DEVPATH_LEN];
  1739 	int			uverbs_fd, ret;
  1583 	int			ret;
  1740 	uint64_t		raw_fw_ver;
  1584 	uint64_t		raw_fw_ver;
  1741 	unsigned		major, minor, sub_minor;
  1585 	unsigned		major, minor, sub_minor;
  1742 
  1586 
  1743 	context.device = device;
  1587 	context.device = device;
  1744 
  1588 
  1745 	if (!device || !attr)
  1589 	if (!device || !attr)
  1746 		return (-1);
  1590 		return (-1);
  1747 
  1591 
  1748 	snprintf(uverbs_devpath, MAXPATHLEN, "%s/%s", IB_OFS_DEVPATH_PREFIX,
  1592 	snprintf(uverbs_devpath, MAX_OFS_DEVPATH_LEN, "%s/%s",
  1749 	    device->dev_name);
  1593 	    IB_OFS_DEVPATH_PREFIX, device->dev_name);
  1750 
  1594 
  1751 	if ((context.cmd_fd = open(uverbs_devpath, O_RDWR)) <  0)
  1595 	if ((context.cmd_fd = open(uverbs_devpath, O_RDWR)) <  0)
  1752 		return (-1);
  1596 		return (-1);
  1753 
  1597 
  1754 	ret = ibv_cmd_query_device(&context, attr, &raw_fw_ver, &cmd,
  1598 	ret = ibv_cmd_query_device(&context, attr, &raw_fw_ver, &cmd,