dapl_tavor_hca.c revision 9e39c5ba00a55fa05777cc94b148296af305e135
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libdevinfo.h>
#include "dapl.h"
#include "dapl_adapter_util.h"
#include "dapl_tavor_ibtf_impl.h"
#include "dapl_hca_util.h"
#include "dapl_name_service.h"
#define IF_NAME "ibd"
#define MAX_HCAS 64
#define PROP_HCA_GUID "hca-guid"
#define PROP_PORT_NUM "port-number"
#define PROP_PORT_PKEY "port-pkey"
/* function prototypes */
int try_blueflame);
int hca_idx);
#if defined(IBHOSTS_NAMING)
#include <stdio.h>
#endif /* IBHOSTS_NAMING */
static DAPL_OS_LOCK g_tavor_state_lock;
{
int hca_idx = 0;
int ia_instance;
int check_for_bf = 0;
NULL, 0);
if (root_node == DI_NODE_NIL) {
return (DAT_INTERNAL_ERROR);
}
while (ibd_node != DI_NODE_NIL) {
/* find the ibd node matching our ianame */
break;
}
}
if (ibd_node == DI_NODE_NIL) {
"init_hcas: ibd%d di_node not found\n", ia_instance);
goto bail;
}
check_for_bf = 1;
} else {
"init_hcas: ibd%d hca_node not found\n", ia_instance);
goto bail;
}
if (dat_status != DAT_SUCCESS) {
"init_hcas: ibd%d process_tavor_node failed(0x%x)\n",
goto bail;
}
#if defined(IBHOSTS_NAMING)
/* no entries were found */
}
#else
#endif
if (dat_status != DAT_SUCCESS) {
"init_hcas: ibd%d process_ibd_node failed(0x%x)\n",
goto bail;
}
"init_hcas: done ibd%d\n", ia_instance);
bail:
return (dat_status);
}
static DAT_RETURN
{
char *dev_path;
char path_buf[MAXPATHLEN];
#ifndef _LP64
int tmpfd;
#endif
void *mapaddr;
/*
* page size == 0 means this entry is not occupied
*/
break;
}
}
"process_tavor: all hcas are being used!\n");
return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0));
}
/* Add 16 to accomodate the prefix "/devices" and suffix ":devctl" */
MAXPATHLEN) {
"process_tavor: devfs path %s is too long\n",
dev_path);
return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
}
if (pagesize == 0) {
"process_tavor: page_size == 0\n");
return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
}
if (fd < 0) {
"process_tavor: cannot open %s: %s\n",
return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0));
}
#ifndef _LP64
/*
* libc can't handle fd's greater than 255, in order to
* ensure that these values remain available make fd > 255.
* Note: not needed for LP64
*/
if (tmpfd < 0) {
} else {
}
#endif /* _LP64 */
return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
}
if (mapaddr == MAP_FAILED) {
return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0));
}
if (try_blueflame == 0)
goto done;
/* Try to do the Hermon Blueflame page mapping */
if (mapaddr == MAP_FAILED) {
/* This is not considered to be fatal. Charge on! */
"process_tavor: mmap of blueflame page failed %s\n",
} else {
}
done:
return (DAT_SUCCESS);
}
static DAT_RETURN
{
uint32_t partition_key = 0;
int tmp;
int digits;
char *drv_name;
char addr_buf[64];
while (prop != DI_PROP_NIL) {
char *prop_name;
count = 0;
sizeof (ib_guid_t));
}
}
"process_ibd: invalid properties: guid 0x%016llx, "
return (DAT_ERROR(DAT_INVALID_PARAMETER, 0));
}
/*
* if an interface has both v4 and v6 addresses plumbed,
* we'll take the v4 address.
*/
if (sfd < 0) {
return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0));
}
/* calculate the number of digits in instance */
digits = 0;
do {
digits++;
} while (tmp > 0);
/* check if name will fit in lifr_name */
"process_ibd: if name overflow %s:%d\n",
return (DAT_ERROR(DAT_INVALID_PARAMETER, 0));
}
instance);
if (retval < 0) {
/*
* the interface is not plumbed.
*/
"process_ibd: %s: ip address not found\n",
return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0));
} else {
/*
* we've failed to find a v4 address. now
* let's try v6.
*/
goto again;
}
}
"process_ibd: interface %s, hca guid 0x%016llx, port %d, "
return (DAT_SUCCESS);
}
void
dapls_ib_state_init(void)
{
int i;
(void) dapl_os_lock_init(&g_tavor_state_lock);
(void) dapl_os_lock_init(&g_tavor_uar_lock);
(void) dapl_os_lock_init(&dapls_ib_dbp_lock);
for (i = 0; i < MAX_HCAS; i++) {
g_tavor_state[i].hca_fd = 0;
g_tavor_state[i].uarpg_size = 0;
}
}
void
dapls_ib_state_fini(void)
{
int i, count = 0;
/*
* Uinitialize the per hca instance state
*/
for (i = 0; i < MAX_HCAS; i++) {
if (g_tavor_state[i].uarpg_size == 0) {
NULL);
continue;
}
g_tavor_state[i].uarpg_size) < 0) {
"ib_state_fini: "
"munmap(0x%p, 0x%llx) failed(%d)\n",
}
g_tavor_state[i].uarpg_size) < 0)) {
"ib_state_fini: "
"munmap(0x%p, 0x%llx) of blueflame failed(%d)\n",
}
count++;
}
"ib_state_fini: cleaned %d hcas\n", count);
}
/*
* dapls_ib_open_hca
*
* Open HCA
*
* Input:
* *hca_ptr pointer to hca device
* *ib_hca_handle_p pointer to provide HCA handle
*
* Output:
* none
*
* Return:
* DAT_SUCCESS
* DAT_INSUFFICIENT_RESOURCES
*
*/
{
struct dapls_ib_hca_handle *hca_p;
int fd;
#ifndef _LP64
int tmpfd;
#endif
int retval;
struct sockaddr *s;
struct sockaddr_in6 *v6addr;
struct sockaddr_in *v4addr;
if (dat_status != DAT_SUCCESS) {
"dapls_ib_open_hca: init_hca failed %d\n", dat_status);
return (dat_status);
}
if (fd < 0) {
return (DAT_INSUFFICIENT_RESOURCES);
}
#ifndef _LP64
/*
* libc can't handle fd's greater than 255, in order to
* ensure that these values remain available make fd > 255.
* Note: not needed for LP64
*/
if (tmpfd < 0) {
"dapls_ib_open_hca: cannot F_DUPFD: %s\n",
} else {
}
#endif /* _LP64 */
return (DAT_INTERNAL_ERROR);
}
sizeof (struct dapls_ib_hca_handle));
return (DAT_INSUFFICIENT_RESOURCES);
}
/* pass down local ip address to be stored in SA */
/* LINTED: E_BAD_PTR_CAST_ALIGN */
switch (s->sa_family) {
case AF_INET:
/* LINTED: E_BAD_PTR_CAST_ALIGN */
v4addr = (struct sockaddr_in *)s;
break;
case AF_INET6:
/* LINTED: E_BAD_PTR_CAST_ALIGN */
v6addr = (struct sockaddr_in6 *)s;
break;
default:
break; /* fall through */
}
if (retval != 0) {
"open_hca: ia_create failed, fd %d, "
"guid 0x%016llx, port %d, pkey 0x%x, version %d\n",
}
hca_p->ia_bf_toggle = 0;
*ib_hca_handle_p = hca_p;
"open_hca: ia_created, hca_p 0x%p, fd %d, "
"rnum %d, guid 0x%016llx, port %d, pkey 0x%x\n",
return (DAT_SUCCESS);
}
/*
* dapls_ib_close_hca
*
* Open HCA
*
* Input:
* ib_hca_handle provide HCA handle
*
* Output:
* none
*
* Return:
* DAT_SUCCESS
* DAT_INSUFFICIENT_RESOURCES
*
*/
{
if (ib_hca_handle == NULL) {
"close_hca: ib_hca_handle == NULL\n");
return (DAT_SUCCESS);
}
"close_hca: closing hca 0x%p, fd %d, rnum %d\n",
dapl_os_free((void *)ib_hca_handle,
sizeof (struct dapls_ib_hca_handle));
return (DAT_SUCCESS);
}
#if defined(IBHOSTS_NAMING)
#define LINE_LEN 256
static int
{
int count = 0;
"fake_ibds: ibhosts not found!\n");
return (0);
}
"fake_ibds: hostname not found!\n");
return (0);
}
guid &= 0xfffffffffffffff0;
count++;
}
if (count >= 2) break;
}
return (count);
}
#endif /* IBHOSTS_NAMING */