/*
* 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
*/
/*
*/
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <strings.h>
#include <fcntl.h>
#include <libdladm.h>
#include <libdlib.h>
#include <libdllink.h>
#include <libnetcfg.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"
/* function prototypes */
int try_blueflame);
int hca_idx);
#if defined(IBHOSTS_NAMING)
#include <stdio.h>
#endif /* IBHOSTS_NAMING */
{
int hca_idx = 0;
int check_for_bf = 0;
"init_hca: dladm_open failed\n");
return (DAT_INTERNAL_ERROR);
}
"init_hca: could not open ib nexus (%s)\n",
goto bail;
}
NULL) != DLADM_STATUS_OK) ||
(class != DATALINK_CLASS_PART) ||
DLADM_OPT_ACTIVE) != DLADM_STATUS_OK)) {
"init_hca: %s not found - couldn't get partition info\n",
goto bail;
}
"init_hca: %s not found; query_hca failed\n",
goto bail;
}
check_for_bf = 1;
} else {
goto bail;
}
if (dat_status != DAT_SUCCESS) {
"init_hcas: %s 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: %s process_ia failed(0x%x)\n",
goto bail;
}
bail:
if (ibnex_fd != -1)
return (dat_status);
}
static DAT_RETURN
{
#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));
}
for (i = 0; i < idx; i++) {
/* no need for a refcnt */
idx = i;
goto done;
}
}
/* 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
{
"process_ia: 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));
}
/* check if name will fit in lifr_name */
"process_ia: if name overflow %s\n",
return (DAT_ERROR(DAT_INVALID_PARAMETER, 0));
}
if (retval < 0) {
/*
* the interface is not plumbed.
*/
"process_ia: %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_ia: 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
*
*/
{
int fd;
#ifndef _LP64
int tmpfd;
#endif
int retval;
struct sockaddr *s;
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",
}
*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)
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 */