|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* This software is available to you under a choice of one of two
|
|
Packit |
13e616 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
13e616 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
13e616 |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
13e616 |
* OpenIB.org BSD license below:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
13e616 |
* without modification, are permitted provided that the following
|
|
Packit |
13e616 |
* conditions are met:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions of source code must retain the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer in the documentation and/or other materials
|
|
Packit |
13e616 |
* provided with the distribution.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
13e616 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
13e616 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
13e616 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
13e616 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
13e616 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
13e616 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
13e616 |
* SOFTWARE.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Abstract:
|
|
Packit |
13e616 |
* Implementation of osm_req_t.
|
|
Packit |
13e616 |
* This object represents the generic attribute requester.
|
|
Packit |
13e616 |
* This object is part of the opensm family of objects.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Next available error code: 0x300
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if HAVE_CONFIG_H
|
|
Packit |
13e616 |
# include <config.h>
|
|
Packit |
13e616 |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#ifdef OSM_VENDOR_INTF_UMADT
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <stdlib.h>
|
|
Packit |
13e616 |
#include <stdio.h>
|
|
Packit |
13e616 |
#include <dlfcn.h>
|
|
Packit |
13e616 |
#include <string.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <complib/cl_qlist.h>
|
|
Packit |
13e616 |
#include <complib/cl_thread.h>
|
|
Packit |
13e616 |
#include <complib/cl_timer.h>
|
|
Packit |
13e616 |
#include <iba/ib_types.h>
|
|
Packit |
13e616 |
#include <opensm/osm_madw.h>
|
|
Packit |
13e616 |
#include <opensm/osm_log.h>
|
|
Packit |
13e616 |
#include <opensm/osm_mad_pool.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_umadt.h>
|
|
Packit |
13e616 |
#include <vendor/osm_umadt.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* GEN1 includes */
|
|
Packit |
13e616 |
#include "umadt_so.h"
|
|
Packit |
13e616 |
#include "ibt.h"
|
|
Packit |
13e616 |
#include "statustext.h"
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* VENDOR_MAD_INTF */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* //////////////////// */
|
|
Packit |
13e616 |
/* Globals // */
|
|
Packit |
13e616 |
/* //////////////////// */
|
|
Packit |
13e616 |
typedef struct _ib_sa_mad_vM3 {
|
|
Packit |
13e616 |
uint8_t base_ver;
|
|
Packit |
13e616 |
uint8_t mgmt_class;
|
|
Packit |
13e616 |
uint8_t class_ver;
|
|
Packit |
13e616 |
uint8_t method;
|
|
Packit |
13e616 |
ib_net16_t status;
|
|
Packit |
13e616 |
ib_net16_t resv;
|
|
Packit |
13e616 |
ib_net64_t trans_id;
|
|
Packit |
13e616 |
ib_net16_t attr_id;
|
|
Packit |
13e616 |
ib_net16_t resv1;
|
|
Packit |
13e616 |
ib_net32_t attr_mod;
|
|
Packit |
13e616 |
ib_net64_t resv2;
|
|
Packit |
13e616 |
ib_net64_t sm_key;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_net32_t seg_num;
|
|
Packit |
13e616 |
ib_net32_t payload_len;
|
|
Packit |
13e616 |
uint8_t frag_flag;
|
|
Packit |
13e616 |
uint8_t edit_mod;
|
|
Packit |
13e616 |
ib_net16_t window;
|
|
Packit |
13e616 |
ib_net16_t attr_offset;
|
|
Packit |
13e616 |
ib_net16_t resv3;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_net64_t comp_mask;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
uint8_t data[IB_SA_DATA_SIZE];
|
|
Packit |
13e616 |
} ib_sa_mad_t_vM3;
|
|
Packit |
13e616 |
#define DEFAULT_TIMER_INTERVAL_MSEC 500 /* 500msec timer interval */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void __mad_recv_processor(void *context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
boolean_t __valid_mad_handle(IN mad_bind_info_t * p_mad_bind_info);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_status_t
|
|
Packit |
13e616 |
__match_tid_context(const cl_list_item_t * const p_list_item, void *context);
|
|
Packit |
13e616 |
void __osm_vendor_timer_callback(IN void *context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_vendor_t *osm_vendor_new(IN osm_log_t * const p_log,
|
|
Packit |
13e616 |
IN const uint32_t timeout)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status;
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_umadt_obj = malloc(sizeof(umadt_obj_t));
|
|
Packit |
13e616 |
if (p_umadt_obj) {
|
|
Packit |
13e616 |
memset(p_umadt_obj, 0, sizeof(umadt_obj_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_vendor_init((osm_vendor_t *) p_umadt_obj, p_log,
|
|
Packit |
13e616 |
timeout);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS) {
|
|
Packit |
13e616 |
osm_vendor_delete((osm_vendor_t **) & p_umadt_obj);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
printf
|
|
Packit |
13e616 |
("osm_vendor_construct: ERROR! Unable to create Umadt object!\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return ((osm_vendor_t *) p_umadt_obj);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj = (umadt_obj_t *) * pp_vend;
|
|
Packit |
13e616 |
cl_list_item_t *p_list_item;
|
|
Packit |
13e616 |
uint32_t count, i;
|
|
Packit |
13e616 |
mad_bind_info_t *p_mad_bind_info;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_umadt_obj->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_umadt_obj->register_lock);
|
|
Packit |
13e616 |
p_mad_bind_info =
|
|
Packit |
13e616 |
(mad_bind_info_t *) cl_qlist_head(&p_umadt_obj->register_list);
|
|
Packit |
13e616 |
count = cl_qlist_count(&p_umadt_obj->register_list);
|
|
Packit |
13e616 |
cl_spinlock_release(&p_umadt_obj->register_lock);
|
|
Packit |
13e616 |
for (i = 0; i < count; i++) {
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_umadt_obj->register_lock);
|
|
Packit |
13e616 |
p_list_item = cl_qlist_next(&p_mad_bind_info->list_item);
|
|
Packit |
13e616 |
cl_spinlock_release(&p_umadt_obj->register_lock);
|
|
Packit |
13e616 |
/* Unbind this handle */
|
|
Packit |
13e616 |
/* osm_vendor_ubind also removesd the item from the list */
|
|
Packit |
13e616 |
/* osm_vendor_unbind takes the list lock so release it here */
|
|
Packit |
13e616 |
osm_vendor_unbind((osm_bind_handle_t) p_mad_bind_info);
|
|
Packit |
13e616 |
p_mad_bind_info = (mad_bind_info_t *) p_list_item;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
dlclose(p_umadt_obj->umadt_handle);
|
|
Packit |
13e616 |
free(p_umadt_obj);
|
|
Packit |
13e616 |
*pp_vend = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_umadt_obj->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* See VendorAbstractMadIntf.h for info */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osm_vendor_init(IN osm_vendor_t * const p_vend,
|
|
Packit |
13e616 |
IN osm_log_t * const p_log, IN const uint32_t timeout)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
FSTATUS Status;
|
|
Packit |
13e616 |
PUMADT_GET_INTERFACE uMadtGetInterface;
|
|
Packit |
13e616 |
char *error;
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj = (umadt_obj_t *) p_vend;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_umadt_obj->p_log = p_log;
|
|
Packit |
13e616 |
p_umadt_obj->timeout = timeout;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_umadt_obj->umadt_handle = dlopen("libibt.so", RTLD_NOW);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_umadt_obj->umadt_handle) {
|
|
Packit |
13e616 |
printf("Could not load libibt.so <%s>\n", dlerror());
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
uMadtGetInterface =
|
|
Packit |
13e616 |
dlsym(p_umadt_obj->umadt_handle, "uMadtGetInterface");
|
|
Packit |
13e616 |
if ((error = dlerror()) != NULL) {
|
|
Packit |
13e616 |
printf("Could not resolve symbol uMadtGetInterface ERROR<%s>\n",
|
|
Packit |
13e616 |
error);
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Status = (*uMadtGetInterface) (&p_umadt_obj->uMadtInterface);
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
printf(" Error in getting uMADT interface ERROR<%d>\n", Status);
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Initialize the register list and register list lock */
|
|
Packit |
13e616 |
cl_qlist_init(&p_umadt_obj->register_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_construct(&p_umadt_obj->register_lock);
|
|
Packit |
13e616 |
CL_ASSERT(cl_spinlock_init(&p_umadt_obj->register_lock) == CL_SUCCESS);
|
|
Packit |
13e616 |
p_umadt_obj->init_done = TRUE;
|
|
Packit |
13e616 |
printf("*****SUCCESS*****\n");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return IB_SUCCESS;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* See VendorAbstractMadIntf.h for info */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osm_vendor_get_ports(IN osm_vendor_t * const p_vend,
|
|
Packit |
13e616 |
IN ib_net64_t * const p_guids,
|
|
Packit |
13e616 |
IN uint32_t * const p_num_guids)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
char *error = NULL;
|
|
Packit |
13e616 |
PIBT_GET_INTERFACE pfnIbtGetInterface;
|
|
Packit |
13e616 |
PIBT_INIT pfnIbtInitFunc;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
FSTATUS Status;
|
|
Packit |
13e616 |
uint32_t caCount, caGuidCount;
|
|
Packit |
13e616 |
IB_CA_ATTRIBUTES caAttributes;
|
|
Packit |
13e616 |
IB_HANDLE caHandle;
|
|
Packit |
13e616 |
uint32_t i;
|
|
Packit |
13e616 |
IB_PORT_ATTRIBUTES *pPortAttributesList;
|
|
Packit |
13e616 |
EUI64 CaGuidArray[8];
|
|
Packit |
13e616 |
void *context;
|
|
Packit |
13e616 |
uint64_t *p_port_guid;
|
|
Packit |
13e616 |
uint32_t free_guids;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj = (umadt_obj_t *) p_vend;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_umadt_obj->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_guids);
|
|
Packit |
13e616 |
CL_ASSERT(p_num_guids);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
pfnIbtInitFunc =
|
|
Packit |
13e616 |
(PIBT_INIT) dlsym(p_umadt_obj->umadt_handle, "IbtInit");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!pfnIbtInitFunc) {
|
|
Packit |
13e616 |
printf("Error getting IbtInit function address.\n");
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
(*pfnIbtInitFunc) ();
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
pfnIbtGetInterface =
|
|
Packit |
13e616 |
(PIBT_GET_INTERFACE) dlsym(p_umadt_obj->umadt_handle,
|
|
Packit |
13e616 |
"IbtGetInterface");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!pfnIbtGetInterface || (error = dlerror()) != NULL) {
|
|
Packit |
13e616 |
printf("Error getting IbtGetInterface function address.<%s>\n",
|
|
Packit |
13e616 |
error);
|
|
Packit |
13e616 |
return FALSE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
(*pfnIbtGetInterface) (&p_umadt_obj->IbtInterface);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
caGuidCount = 8;
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->IbtInterface.GetCaGuidArray(&caGuidCount,
|
|
Packit |
13e616 |
&CaGuidArray[0]);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if ((Status != FSUCCESS) || (caGuidCount == 0)) {
|
|
Packit |
13e616 |
return FALSE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free_guids = *p_num_guids;
|
|
Packit |
13e616 |
p_port_guid = p_guids;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* query each ca & copy its info into callers buffer */
|
|
Packit |
13e616 |
for (caCount = 0; caCount < caGuidCount; caCount++) {
|
|
Packit |
13e616 |
memset(&caAttributes, 0, sizeof(IB_CA_ATTRIBUTES));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Open the CA */
|
|
Packit |
13e616 |
Status = p_umadt_obj->IbtInterface.Vpi.OpenCA(CaGuidArray[caCount], NULL, /* CACompletionCallback */
|
|
Packit |
13e616 |
NULL, /* AsyncEventCallback */
|
|
Packit |
13e616 |
NULL, &caHandle);
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Status = p_umadt_obj->IbtInterface.Vpi.QueryCA(caHandle,
|
|
Packit |
13e616 |
&caAttributes,
|
|
Packit |
13e616 |
&context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
p_umadt_obj->IbtInterface.Vpi.CloseCA(caHandle);
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (caAttributes.Ports > free_guids) {
|
|
Packit |
13e616 |
*p_num_guids = 0;
|
|
Packit |
13e616 |
memset(p_guids, 0, (*p_num_guids) * sizeof(uint64_t));
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
pPortAttributesList =
|
|
Packit |
13e616 |
(IB_PORT_ATTRIBUTES *) malloc(caAttributes.
|
|
Packit |
13e616 |
PortAttributesListSize);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (pPortAttributesList == NULL) {
|
|
Packit |
13e616 |
p_umadt_obj->IbtInterface.Vpi.CloseCA(caHandle);
|
|
Packit |
13e616 |
*p_num_guids = 0;
|
|
Packit |
13e616 |
memset(p_guids, 0, (*p_num_guids) * sizeof(uint64_t));
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(pPortAttributesList, 0,
|
|
Packit |
13e616 |
caAttributes.PortAttributesListSize);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
caAttributes.PortAttributesList = pPortAttributesList;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Status = p_umadt_obj->IbtInterface.Vpi.QueryCA(caHandle,
|
|
Packit |
13e616 |
&caAttributes,
|
|
Packit |
13e616 |
&context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
p_umadt_obj->IbtInterface.Vpi.CloseCA(caHandle);
|
|
Packit |
13e616 |
*p_num_guids = 0;
|
|
Packit |
13e616 |
memset(p_guids, 0, (*p_num_guids) * sizeof(uint64_t));
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
pPortAttributesList = caAttributes.PortAttributesList;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for (i = 0; i < caAttributes.Ports; i++) {
|
|
Packit |
13e616 |
*(p_port_guid) =
|
|
Packit |
13e616 |
cl_hton64((uint64_t) pPortAttributesList->GUID);
|
|
Packit |
13e616 |
pPortAttributesList = pPortAttributesList->Next;
|
|
Packit |
13e616 |
p_port_guid++;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
free(caAttributes.PortAttributesList);
|
|
Packit |
13e616 |
p_umadt_obj->IbtInterface.Vpi.CloseCA(caHandle);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free_guids = free_guids - caAttributes.Ports;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
*p_num_guids = *p_num_guids - free_guids;
|
|
Packit |
13e616 |
return IB_SUCCESS;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* See VendorAbstractMadIntf.h for info */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
ib_mad_t *osm_vendor_get(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN const uint32_t mad_size,
|
|
Packit |
13e616 |
IN osm_vend_wrap_t * p_vend_wrap)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
/* FSTATUS Status; */
|
|
Packit |
13e616 |
/* uint32_t mad_count = 0; */
|
|
Packit |
13e616 |
/* MadtStruct *p_madt_struct; */
|
|
Packit |
13e616 |
mad_bind_info_t *p_mad_bind_info = (mad_bind_info_t *) h_bind;
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj = p_mad_bind_info->p_umadt_obj;
|
|
Packit |
13e616 |
ib_mad_t *p_mad;
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_umadt_obj->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(h_bind);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_umadt_obj = p_mad_bind_info->p_umadt_obj;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Sanity check */
|
|
Packit |
13e616 |
CL_ASSERT(p_umadt_obj->init_done);
|
|
Packit |
13e616 |
CL_ASSERT(p_vend_wrap);
|
|
Packit |
13e616 |
CL_ASSERT(__valid_mad_handle(p_mad_bind_info));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if 0
|
|
Packit |
13e616 |
mad_count = 1;
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.uMadtGetSendMad(p_mad_bind_info->
|
|
Packit |
13e616 |
umadt_handle,
|
|
Packit |
13e616 |
&mad_count,
|
|
Packit |
13e616 |
&p_madt_struct);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (Status != FSUCCESS || p_madt_struct == NULL) {
|
|
Packit |
13e616 |
p_vend_wrap->p_madt_struct = NULL;
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
p_vend_wrap->p_madt_struct = p_madt_struct;
|
|
Packit |
13e616 |
p_vend_wrap->direction = SEND;
|
|
Packit |
13e616 |
return ((ib_mad_t *) & p_madt_struct->IBMad);
|
|
Packit |
13e616 |
#endif /* 0 */
|
|
Packit |
13e616 |
p_mad = (ib_mad_t *) malloc(mad_size);
|
|
Packit |
13e616 |
if (!p_mad) {
|
|
Packit |
13e616 |
p_vend_wrap->p_madt_struct = NULL;
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_mad, 0, mad_size);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_vend_wrap->p_madt_struct = NULL;
|
|
Packit |
13e616 |
p_vend_wrap->direction = SEND;
|
|
Packit |
13e616 |
p_vend_wrap->size = mad_size;
|
|
Packit |
13e616 |
return (p_mad);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* See VendorAbstractMadIntf.h for info */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
void
|
|
Packit |
13e616 |
osm_vendor_put(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN osm_vend_wrap_t * const p_vend_wrap,
|
|
Packit |
13e616 |
IN ib_mad_t * const p_mad)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
FSTATUS Status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
mad_bind_info_t *p_mad_bind_info;
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* Validate the vendor mad transport handle */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
CL_ASSERT(h_bind);
|
|
Packit |
13e616 |
p_mad_bind_info = (mad_bind_info_t *) h_bind;
|
|
Packit |
13e616 |
p_umadt_obj = p_mad_bind_info->p_umadt_obj;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* sanity check */
|
|
Packit |
13e616 |
CL_ASSERT(p_umadt_obj->init_done);
|
|
Packit |
13e616 |
CL_ASSERT(h_bind);
|
|
Packit |
13e616 |
CL_ASSERT(__valid_mad_handle(p_mad_bind_info));
|
|
Packit |
13e616 |
CL_ASSERT(p_vend_wrap);
|
|
Packit |
13e616 |
/* CL_ASSERT( (ib_mad_t*)&p_vend_wrap->p_madt_struct->IBMad == p_mad ); */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Release the MAD based on the direction of the MAD */
|
|
Packit |
13e616 |
if (p_vend_wrap->direction == SEND) {
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* For a send the PostSend released the MAD with Umadt. Simply dealloacte the */
|
|
Packit |
13e616 |
/* local memory that was allocated on the osm_vendor_get() call. */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
free(p_mad);
|
|
Packit |
13e616 |
#if 0
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.
|
|
Packit |
13e616 |
uMadtReleaseSendMad(p_mad_bind_info->umadt_handle,
|
|
Packit |
13e616 |
p_vend_wrap->p_madt_struct);
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
/* printf("uMadtReleaseSendMad: Status = <%d>\n", Status); */
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
} else if (p_vend_wrap->direction == RECEIVE) {
|
|
Packit |
13e616 |
CL_ASSERT((ib_mad_t *) & p_vend_wrap->p_madt_struct->IBMad ==
|
|
Packit |
13e616 |
p_mad);
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.
|
|
Packit |
13e616 |
uMadtReleaseRecvMad(p_mad_bind_info->umadt_handle,
|
|
Packit |
13e616 |
p_vend_wrap->p_madt_struct);
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
/* printf("uMadtReleaseRecvMad Status=<%d>\n", Status); */
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* See VendorAbstractMadIntf.h for info */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osm_vendor_send(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN osm_vend_wrap_t * const p_vend_wrap,
|
|
Packit |
13e616 |
IN osm_mad_addr_t * const p_mad_addr,
|
|
Packit |
13e616 |
IN ib_mad_t * const p_mad,
|
|
Packit |
13e616 |
IN void *transaction_context, IN boolean_t const resp_expected)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
FSTATUS Status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
MadAddrStruct destAddr = { 0 };
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
mad_bind_info_t *p_mad_bind_info;
|
|
Packit |
13e616 |
trans_context_t *p_trans_context;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
uint32_t mad_count = 0;
|
|
Packit |
13e616 |
MadtStruct *p_madt_struct = NULL;
|
|
Packit |
13e616 |
uint32_t i;
|
|
Packit |
13e616 |
uint32_t num_mads = 0;
|
|
Packit |
13e616 |
uint32_t seg_num = 0;
|
|
Packit |
13e616 |
uint8_t *p_frag_data = NULL;
|
|
Packit |
13e616 |
ib_sa_mad_t_vM3 *p_sa_mad = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(h_bind);
|
|
Packit |
13e616 |
p_mad_bind_info = (mad_bind_info_t *) h_bind;
|
|
Packit |
13e616 |
p_umadt_obj = p_mad_bind_info->p_umadt_obj;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* sanity check */
|
|
Packit |
13e616 |
CL_ASSERT(p_umadt_obj);
|
|
Packit |
13e616 |
CL_ASSERT(p_umadt_obj->init_done);
|
|
Packit |
13e616 |
CL_ASSERT(__valid_mad_handle(p_mad_bind_info));
|
|
Packit |
13e616 |
CL_ASSERT(p_vend_wrap);
|
|
Packit |
13e616 |
CL_ASSERT(p_mad_addr);
|
|
Packit |
13e616 |
CL_ASSERT(p_mad);
|
|
Packit |
13e616 |
/* CL_ASSERT( (ib_mad_t*)&p_vend_wrap->p_madt_struct->IBMad == p_mad ); */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* based on the class, fill out the address info */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
destAddr.DestLid = p_mad_addr->dest_lid;
|
|
Packit |
13e616 |
destAddr.PathBits = p_mad_addr->path_bits;
|
|
Packit |
13e616 |
destAddr.StaticRate = p_mad_addr->static_rate;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_LID ||
|
|
Packit |
13e616 |
p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_DIR) {
|
|
Packit |
13e616 |
CL_ASSERT(p_mad_addr->addr_type.smi.source_lid);
|
|
Packit |
13e616 |
destAddr.AddrType.Smi.SourceLid =
|
|
Packit |
13e616 |
p_mad_addr->addr_type.smi.source_lid;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
destAddr.AddrType.Gsi.RemoteQpNumber =
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.remote_qp;
|
|
Packit |
13e616 |
destAddr.AddrType.Gsi.RemoteQkey =
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.remote_qkey;
|
|
Packit |
13e616 |
destAddr.AddrType.Gsi.PKey = OSM_DEFAULT_PKEY;
|
|
Packit |
13e616 |
destAddr.AddrType.Gsi.ServiceLevel =
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.service_level;
|
|
Packit |
13e616 |
destAddr.AddrType.Gsi.GlobalRoute =
|
|
Packit |
13e616 |
p_mad_addr->addr_type.gsi.global_route;
|
|
Packit |
13e616 |
/* destAddr.AddrType.Gsi.GRHInfo = p_mad_addr->addr_type.gsi.grh_info; */
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
p_mad->trans_id = cl_ntoh64(p_mad->trans_id) << 24;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* Create a transaction context for this send and save the TID and client context. */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (resp_expected) {
|
|
Packit |
13e616 |
p_trans_context = malloc(sizeof(trans_context_t));
|
|
Packit |
13e616 |
CL_ASSERT(p_trans_context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_trans_context, 0, sizeof(trans_context_t));
|
|
Packit |
13e616 |
p_trans_context->trans_id = p_mad->trans_id;
|
|
Packit |
13e616 |
p_trans_context->context = transaction_context;
|
|
Packit |
13e616 |
p_trans_context->sent_time = cl_get_time_stamp();
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);
|
|
Packit |
13e616 |
cl_qlist_insert_tail(&p_mad_bind_info->trans_ctxt_list,
|
|
Packit |
13e616 |
&p_trans_context->list_item);
|
|
Packit |
13e616 |
cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_LID ||
|
|
Packit |
13e616 |
p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_DIR) {
|
|
Packit |
13e616 |
/* Get one mad from uMadt */
|
|
Packit |
13e616 |
mad_count = 1;
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.
|
|
Packit |
13e616 |
uMadtGetSendMad(p_mad_bind_info->umadt_handle, &mad_count,
|
|
Packit |
13e616 |
&p_madt_struct);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (Status != FSUCCESS || p_madt_struct == NULL) {
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* No Segmentation required */
|
|
Packit |
13e616 |
memcpy(&p_madt_struct->IBMad, p_mad, MAD_BLOCK_SIZE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Post the MAD */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.uMadtPostSend(p_mad_bind_info->
|
|
Packit |
13e616 |
umadt_handle,
|
|
Packit |
13e616 |
p_madt_struct,
|
|
Packit |
13e616 |
&destAddr);
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
printf("uMadtPostSendMad: Status = <%d>\n", Status);
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Release send MAD */
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.
|
|
Packit |
13e616 |
uMadtReleaseSendMad(p_mad_bind_info->umadt_handle,
|
|
Packit |
13e616 |
p_madt_struct);
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
printf("uMadtReleaseSendMad: Status = <%d>\n", Status);
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* Segment the MAD, get the required send mads from uMadt and post the MADs. */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
uint32_t payload_len;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
payload_len =
|
|
Packit |
13e616 |
cl_ntoh32(((ib_sa_mad_t_vM3 *) p_mad)->payload_len);
|
|
Packit |
13e616 |
num_mads = payload_len / IB_SA_DATA_SIZE;
|
|
Packit |
13e616 |
if (payload_len % IB_SA_DATA_SIZE != 0) {
|
|
Packit |
13e616 |
num_mads++; /* Get one additional mad for the remainder */
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
for (i = 0; i < num_mads; i++) {
|
|
Packit |
13e616 |
/* Get one mad from uMadt */
|
|
Packit |
13e616 |
mad_count = 1;
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.
|
|
Packit |
13e616 |
uMadtGetSendMad(p_mad_bind_info->umadt_handle,
|
|
Packit |
13e616 |
&mad_count, &p_madt_struct);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (Status != FSUCCESS || p_madt_struct == NULL) {
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
/* Copy client MAD into uMadt's MAD. */
|
|
Packit |
13e616 |
if (i == 0) { /* First Packet */
|
|
Packit |
13e616 |
/* Since this is the first MAD, copy the entire MAD_SIZE */
|
|
Packit |
13e616 |
memcpy(&p_madt_struct->IBMad, p_mad,
|
|
Packit |
13e616 |
MAD_BLOCK_SIZE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_frag_data =
|
|
Packit |
13e616 |
(uint8_t *) p_mad + MAD_BLOCK_SIZE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa_mad =
|
|
Packit |
13e616 |
(ib_sa_mad_t_vM3 *) & p_madt_struct->IBMad;
|
|
Packit |
13e616 |
if (num_mads == 1) { /* Only one Packet */
|
|
Packit |
13e616 |
p_sa_mad->seg_num = 0;
|
|
Packit |
13e616 |
p_sa_mad->frag_flag = 5; /* Set bit 0 for first pkt and b4 for last pkt */
|
|
Packit |
13e616 |
/* the payload length gets copied with the mad header above */
|
|
Packit |
13e616 |
} else { /* More than one packet in this response */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
seg_num = 1;
|
|
Packit |
13e616 |
p_sa_mad->seg_num =
|
|
Packit |
13e616 |
cl_ntoh32(seg_num++);
|
|
Packit |
13e616 |
p_sa_mad->frag_flag = 1; /* Set bit 0 for first pkt */
|
|
Packit |
13e616 |
/* the payload length gets copied with the mad header above */
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
} else if (i < num_mads - 1) { /* Not last packet */
|
|
Packit |
13e616 |
/* First copy only the header */
|
|
Packit |
13e616 |
memcpy(&p_madt_struct->IBMad, p_mad,
|
|
Packit |
13e616 |
IB_SA_MAD_HDR_SIZE);
|
|
Packit |
13e616 |
/* Set the relevant fields in the SA_MAD_HEADER */
|
|
Packit |
13e616 |
p_sa_mad =
|
|
Packit |
13e616 |
(ib_sa_mad_t_vM3 *) & p_madt_struct->IBMad;
|
|
Packit |
13e616 |
p_sa_mad->payload_len =
|
|
Packit |
13e616 |
cl_ntoh32(IB_SA_DATA_SIZE);
|
|
Packit |
13e616 |
p_sa_mad->seg_num = cl_ntoh32(seg_num++);
|
|
Packit |
13e616 |
p_sa_mad->frag_flag = 0;
|
|
Packit |
13e616 |
/* Now copy the fragmented data */
|
|
Packit |
13e616 |
memcpy(((uint8_t *) & p_madt_struct->IBMad) +
|
|
Packit |
13e616 |
IB_SA_MAD_HDR_SIZE, p_frag_data,
|
|
Packit |
13e616 |
IB_SA_DATA_SIZE);
|
|
Packit |
13e616 |
p_frag_data = p_frag_data + IB_SA_DATA_SIZE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
} else if (i == num_mads - 1) { /* Last packet */
|
|
Packit |
13e616 |
/* First copy only the header */
|
|
Packit |
13e616 |
memcpy(&p_madt_struct->IBMad, p_mad,
|
|
Packit |
13e616 |
IB_SA_MAD_HDR_SIZE);
|
|
Packit |
13e616 |
/* Set the relevant fields in the SA_MAD_HEADER */
|
|
Packit |
13e616 |
p_sa_mad =
|
|
Packit |
13e616 |
(ib_sa_mad_t_vM3 *) & p_madt_struct->IBMad;
|
|
Packit |
13e616 |
p_sa_mad->seg_num = cl_ntoh32(seg_num++);
|
|
Packit |
13e616 |
p_sa_mad->frag_flag = 4; /* Set Bit 2 for last pkt */
|
|
Packit |
13e616 |
p_sa_mad->payload_len =
|
|
Packit |
13e616 |
cl_ntoh32(cl_ntoh32
|
|
Packit |
13e616 |
(((ib_sa_mad_t_vM3 *) p_mad)->
|
|
Packit |
13e616 |
payload_len) % IB_SA_DATA_SIZE);
|
|
Packit |
13e616 |
/* Now copy the fragmented data */
|
|
Packit |
13e616 |
memcpy((((uint8_t *) & p_madt_struct->IBMad)) +
|
|
Packit |
13e616 |
IB_SA_MAD_HDR_SIZE, p_frag_data,
|
|
Packit |
13e616 |
cl_ntoh32(p_sa_mad->payload_len));
|
|
Packit |
13e616 |
p_frag_data = p_frag_data + IB_SA_DATA_SIZE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
/* Post the MAD */
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.
|
|
Packit |
13e616 |
uMadtPostSend(p_mad_bind_info->umadt_handle,
|
|
Packit |
13e616 |
p_madt_struct, &destAddr);
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
printf("uMadtPostSendMad: Status = <%d>\n",
|
|
Packit |
13e616 |
Status);
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Release send MAD */
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.
|
|
Packit |
13e616 |
uMadtReleaseSendMad(p_mad_bind_info->umadt_handle,
|
|
Packit |
13e616 |
p_madt_struct);
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
printf("uMadtReleaseSendMad: Status = <%d>\n",
|
|
Packit |
13e616 |
Status);
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
return (IB_SUCCESS);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
/* See VendorAbstractMadIntf.h for info */
|
|
Packit |
13e616 |
/* //////////////////////////////////////////////////////////////////////// */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_bind_handle_t
|
|
Packit |
13e616 |
osm_vendor_bind(IN osm_vendor_t * const p_vend,
|
|
Packit |
13e616 |
IN osm_bind_info_t * const p_osm_bind_info,
|
|
Packit |
13e616 |
IN osm_mad_pool_t * const p_mad_pool,
|
|
Packit |
13e616 |
IN osm_vend_mad_recv_callback_t mad_recv_callback,
|
|
Packit |
13e616 |
IN void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_status_t cl_status;
|
|
Packit |
13e616 |
FSTATUS Status; /* GEN1 Status for Umadt */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
mad_bind_info_t *p_mad_bind_info;
|
|
Packit |
13e616 |
RegisterClassStruct *p_umadt_reg_class;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj;
|
|
Packit |
13e616 |
OSM_LOG_ENTER(((umadt_obj_t *) p_vend)->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_vend);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_umadt_obj = (umadt_obj_t *) p_vend;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Sanity check */
|
|
Packit |
13e616 |
CL_ASSERT(p_umadt_obj->init_done);
|
|
Packit |
13e616 |
CL_ASSERT(p_osm_bind_info);
|
|
Packit |
13e616 |
CL_ASSERT(p_mad_pool);
|
|
Packit |
13e616 |
CL_ASSERT(mad_recv_callback);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Allocate memory for registering the handle. */
|
|
Packit |
13e616 |
p_mad_bind_info = (mad_bind_info_t *) malloc(sizeof(*p_mad_bind_info));
|
|
Packit |
13e616 |
if (p_mad_bind_info) {
|
|
Packit |
13e616 |
memset(p_mad_bind_info, 0, sizeof(*p_mad_bind_info));
|
|
Packit |
13e616 |
p_umadt_reg_class = &p_mad_bind_info->umadt_reg_class;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
p_umadt_reg_class->PortGuid = cl_ntoh64(p_osm_bind_info->port_guid);
|
|
Packit |
13e616 |
p_umadt_reg_class->ClassId = p_osm_bind_info->mad_class;
|
|
Packit |
13e616 |
p_umadt_reg_class->ClassVersion = p_osm_bind_info->class_version;
|
|
Packit |
13e616 |
p_umadt_reg_class->isResponder = p_osm_bind_info->is_responder;
|
|
Packit |
13e616 |
p_umadt_reg_class->isTrapProcessor = p_osm_bind_info->is_trap_processor;
|
|
Packit |
13e616 |
p_umadt_reg_class->isReportProcessor =
|
|
Packit |
13e616 |
p_osm_bind_info->is_report_processor;
|
|
Packit |
13e616 |
p_umadt_reg_class->SendQueueSize = p_osm_bind_info->send_q_size;
|
|
Packit |
13e616 |
p_umadt_reg_class->RecvQueueSize = p_osm_bind_info->recv_q_size;
|
|
Packit |
13e616 |
p_umadt_reg_class->NotifySendCompletion = TRUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_mad_bind_info->p_umadt_obj = p_umadt_obj;
|
|
Packit |
13e616 |
p_mad_bind_info->p_mad_pool = p_mad_pool;
|
|
Packit |
13e616 |
p_mad_bind_info->mad_recv_callback = mad_recv_callback;
|
|
Packit |
13e616 |
p_mad_bind_info->client_context = context;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* register with Umadt for MAD interface */
|
|
Packit |
13e616 |
Status = p_umadt_obj->uMadtInterface.uMadtRegister(p_umadt_reg_class,
|
|
Packit |
13e616 |
&p_mad_bind_info->
|
|
Packit |
13e616 |
umadt_handle);
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
free(p_mad_bind_info);
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_umadt_obj->p_log);
|
|
Packit |
13e616 |
return (OSM_BIND_INVALID_HANDLE);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
CL_ASSERT(p_mad_bind_info->umadt_handle);
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* Start a worker thread to process receives. */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
cl_thread_construct(&p_mad_bind_info->recv_processor_thread);
|
|
Packit |
13e616 |
cl_status = cl_thread_init(&p_mad_bind_info->recv_processor_thread,
|
|
Packit |
13e616 |
__mad_recv_processor,
|
|
Packit |
13e616 |
(void *)p_mad_bind_info, "mad_recv_worker");
|
|
Packit |
13e616 |
CL_ASSERT(cl_status == CL_SUCCESS);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_qlist_init(&p_mad_bind_info->trans_ctxt_list);
|
|
Packit |
13e616 |
cl_spinlock_construct(&p_mad_bind_info->trans_ctxt_lock);
|
|
Packit |
13e616 |
cl_spinlock_init(&p_mad_bind_info->trans_ctxt_lock);
|
|
Packit |
13e616 |
cl_spinlock_construct(&p_mad_bind_info->timeout_list_lock);
|
|
Packit |
13e616 |
cl_spinlock_init(&p_mad_bind_info->timeout_list_lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_status = cl_timer_init(&p_mad_bind_info->timeout_timer,
|
|
Packit |
13e616 |
__osm_vendor_timer_callback,
|
|
Packit |
13e616 |
(void *)p_mad_bind_info);
|
|
Packit |
13e616 |
CL_ASSERT(cl_status == CL_SUCCESS);
|
|
Packit |
13e616 |
cl_qlist_init(&p_mad_bind_info->timeout_list);
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* Insert the mad_reg_struct in list and return pointer to it as the handle */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_umadt_obj->register_lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_qlist_insert_head(&p_umadt_obj->register_list,
|
|
Packit |
13e616 |
&p_mad_bind_info->list_item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_release(&p_umadt_obj->register_lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
A timeout value of 0 means disable timeouts.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_umadt_obj->timeout) {
|
|
Packit |
13e616 |
cl_timer_start(&p_mad_bind_info->timeout_timer,
|
|
Packit |
13e616 |
DEFAULT_TIMER_INTERVAL_MSEC);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_umadt_obj->p_log);
|
|
Packit |
13e616 |
return ((osm_bind_handle_t) p_mad_bind_info);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_vendor_unbind(IN osm_bind_handle_t h_bind)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
mad_bind_info_t *p_mad_bind_info;
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj;
|
|
Packit |
13e616 |
cl_list_item_t *p_list_item, *p_next_list_item;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(h_bind);
|
|
Packit |
13e616 |
p_mad_bind_info = (mad_bind_info_t *) h_bind;
|
|
Packit |
13e616 |
p_umadt_obj = p_mad_bind_info->p_umadt_obj;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* sanity check */
|
|
Packit |
13e616 |
CL_ASSERT(p_umadt_obj);
|
|
Packit |
13e616 |
CL_ASSERT(p_umadt_obj->init_done);
|
|
Packit |
13e616 |
CL_ASSERT(__valid_mad_handle(p_mad_bind_info));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.uMadtDestroy(&p_mad_bind_info->
|
|
Packit |
13e616 |
umadt_handle);
|
|
Packit |
13e616 |
cl_timer_destroy(&p_mad_bind_info->timeout_timer);
|
|
Packit |
13e616 |
cl_thread_destroy(&p_mad_bind_info->recv_processor_thread);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);
|
|
Packit |
13e616 |
p_list_item = cl_qlist_head(&p_mad_bind_info->trans_ctxt_list);
|
|
Packit |
13e616 |
while (p_list_item != cl_qlist_end(&p_mad_bind_info->trans_ctxt_list)) {
|
|
Packit |
13e616 |
p_next_list_item = cl_qlist_next(p_list_item);
|
|
Packit |
13e616 |
cl_qlist_remove_item(&p_mad_bind_info->trans_ctxt_list,
|
|
Packit |
13e616 |
p_list_item);
|
|
Packit |
13e616 |
free(p_list_item);
|
|
Packit |
13e616 |
p_list_item = p_next_list_item;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_mad_bind_info->timeout_list_lock);
|
|
Packit |
13e616 |
p_list_item = cl_qlist_head(&p_mad_bind_info->timeout_list);
|
|
Packit |
13e616 |
while (p_list_item != cl_qlist_end(&p_mad_bind_info->timeout_list)) {
|
|
Packit |
13e616 |
p_next_list_item = cl_qlist_next(p_list_item);
|
|
Packit |
13e616 |
cl_qlist_remove_item(&p_mad_bind_info->timeout_list,
|
|
Packit |
13e616 |
p_list_item);
|
|
Packit |
13e616 |
free(p_list_item);
|
|
Packit |
13e616 |
p_list_item = p_next_list_item;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_spinlock_release(&p_mad_bind_info->timeout_list_lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p_mad_bind_info);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void __mad_recv_processor(IN void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
mad_bind_info_t *p_mad_bind_info = (mad_bind_info_t *) context;
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj;
|
|
Packit |
13e616 |
osm_madw_t *p_osm_madw = NULL;
|
|
Packit |
13e616 |
osm_vend_wrap_t *p_vend_wrap = NULL;
|
|
Packit |
13e616 |
osm_mad_addr_t osm_mad_addr = { 0 };
|
|
Packit |
13e616 |
cl_list_item_t *p_list_item;
|
|
Packit |
13e616 |
void *transaction_context;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
FSTATUS Status;
|
|
Packit |
13e616 |
MadtStruct *pRecvMad = NULL;
|
|
Packit |
13e616 |
MadWorkCompletion *pRecvCmp = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_mad_bind_info = (mad_bind_info_t *) context;
|
|
Packit |
13e616 |
p_umadt_obj = p_mad_bind_info->p_umadt_obj;
|
|
Packit |
13e616 |
/* PollFor a completion */
|
|
Packit |
13e616 |
/* if FNOTFOND, then wait for a completion then again poll and return the MAD */
|
|
Packit |
13e616 |
while (1) {
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.
|
|
Packit |
13e616 |
uMadtPollForRecvCompletion(p_mad_bind_info->umadt_handle,
|
|
Packit |
13e616 |
&pRecvMad, &pRecvCmp);
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
if (Status == FNOT_FOUND) {
|
|
Packit |
13e616 |
/* Wait for a completion */
|
|
Packit |
13e616 |
Status = p_umadt_obj->uMadtInterface.uMadtWaitForAnyCompletion(p_mad_bind_info->umadt_handle, RECV_COMPLETION, 0x5000); /* 5 sec timeout */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (Status == FTIMEOUT) {
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
CL_ASSERT(Status == FSUCCESS);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.
|
|
Packit |
13e616 |
uMadtPollForRecvCompletion(p_mad_bind_info->
|
|
Packit |
13e616 |
umadt_handle,
|
|
Packit |
13e616 |
&pRecvMad,
|
|
Packit |
13e616 |
&pRecvCmp);
|
|
Packit |
13e616 |
if (Status != FSUCCESS) {
|
|
Packit |
13e616 |
printf
|
|
Packit |
13e616 |
(" mad_recv_worker: Error in PollForRecv returning <%x>\n",
|
|
Packit |
13e616 |
Status);
|
|
Packit |
13e616 |
CL_ASSERT(0);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
printf
|
|
Packit |
13e616 |
("uMadtPollForRecvCompletion Status=<%x>\n",
|
|
Packit |
13e616 |
Status);
|
|
Packit |
13e616 |
CL_ASSERT(0);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
CL_ASSERT(pRecvMad);
|
|
Packit |
13e616 |
CL_ASSERT(pRecvCmp);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (((ib_sa_mad_t_vM3 *) (&pRecvMad->IBMad))->frag_flag & 0x20) {
|
|
Packit |
13e616 |
/* Ignore the ACK packet */
|
|
Packit |
13e616 |
Status =
|
|
Packit |
13e616 |
p_umadt_obj->uMadtInterface.
|
|
Packit |
13e616 |
uMadtReleaseRecvMad(p_mad_bind_info->umadt_handle,
|
|
Packit |
13e616 |
pRecvMad);
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* Extract the return address to pass it on to the client */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
osm_mad_addr.dest_lid = pRecvCmp->AddressInfo.DestLid;
|
|
Packit |
13e616 |
osm_mad_addr.path_bits = pRecvCmp->AddressInfo.PathBits;
|
|
Packit |
13e616 |
osm_mad_addr.static_rate = pRecvCmp->AddressInfo.StaticRate;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_mad_bind_info->umadt_reg_class.ClassId ==
|
|
Packit |
13e616 |
IB_MCLASS_SUBN_LID
|
|
Packit |
13e616 |
|| p_mad_bind_info->umadt_reg_class.ClassId ==
|
|
Packit |
13e616 |
IB_MCLASS_SUBN_DIR) {
|
|
Packit |
13e616 |
osm_mad_addr.addr_type.smi.source_lid =
|
|
Packit |
13e616 |
pRecvCmp->AddressInfo.AddrType.Smi.SourceLid;
|
|
Packit |
13e616 |
/* osm_mad_addr.addr_type.smi.port_num = pRecvCmp->AddressInfo.AddrType.Smi.PortNumber; */
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
osm_mad_addr.addr_type.gsi.remote_qp =
|
|
Packit |
13e616 |
pRecvCmp->AddressInfo.AddrType.Gsi.RemoteQpNumber;
|
|
Packit |
13e616 |
osm_mad_addr.addr_type.gsi.remote_qkey =
|
|
Packit |
13e616 |
pRecvCmp->AddressInfo.AddrType.Gsi.RemoteQkey;
|
|
Packit |
13e616 |
osm_mad_addr.addr_type.gsi.pkey_ix = 0;
|
|
Packit |
13e616 |
osm_mad_addr.addr_type.gsi.service_level =
|
|
Packit |
13e616 |
pRecvCmp->AddressInfo.AddrType.Gsi.ServiceLevel;
|
|
Packit |
13e616 |
osm_mad_addr.addr_type.gsi.global_route =
|
|
Packit |
13e616 |
pRecvCmp->AddressInfo.AddrType.Gsi.GlobalRoute;
|
|
Packit |
13e616 |
/* osm_mad_addr.addr_type.gsi.grh_info = pRecvCmp->AddressInfo.AddrType.Gsi.GRHInfo; */
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
p_osm_madw =
|
|
Packit |
13e616 |
osm_mad_pool_get_wrapper(p_mad_bind_info->p_mad_pool,
|
|
Packit |
13e616 |
p_mad_bind_info, MAD_BLOCK_SIZE,
|
|
Packit |
13e616 |
(ib_mad_t *) & pRecvMad->IBMad,
|
|
Packit |
13e616 |
&osm_mad_addr);
|
|
Packit |
13e616 |
CL_ASSERT(p_osm_madw);
|
|
Packit |
13e616 |
p_vend_wrap = osm_madw_get_vend_ptr(p_osm_madw);
|
|
Packit |
13e616 |
CL_ASSERT(p_vend_wrap);
|
|
Packit |
13e616 |
p_vend_wrap->p_madt_struct = pRecvMad;
|
|
Packit |
13e616 |
p_vend_wrap->direction = RECEIVE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_mad_bind_info->p_umadt_obj->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__mad_recv_processor: "
|
|
Packit |
13e616 |
"Received data p_osm_madw[0x%p].\n", p_osm_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* Do TID Processing. */
|
|
Packit |
13e616 |
/* */
|
|
Packit |
13e616 |
/* If R bit is set swap the TID */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);
|
|
Packit |
13e616 |
p_list_item =
|
|
Packit |
13e616 |
cl_qlist_find_from_head(&p_mad_bind_info->trans_ctxt_list,
|
|
Packit |
13e616 |
__match_tid_context,
|
|
Packit |
13e616 |
&p_osm_madw->p_mad->trans_id);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_list_item ==
|
|
Packit |
13e616 |
cl_qlist_end(&p_mad_bind_info->trans_ctxt_list)) {
|
|
Packit |
13e616 |
transaction_context = NULL;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
transaction_context =
|
|
Packit |
13e616 |
((trans_context_t *) p_list_item)->context;
|
|
Packit |
13e616 |
cl_qlist_remove_item(&p_mad_bind_info->trans_ctxt_list,
|
|
Packit |
13e616 |
p_list_item);
|
|
Packit |
13e616 |
free(p_list_item);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);
|
|
Packit |
13e616 |
((ib_mad_t *) p_osm_madw->p_mad)->trans_id =
|
|
Packit |
13e616 |
cl_ntoh64(p_osm_madw->p_mad->trans_id >> 24);
|
|
Packit |
13e616 |
osm_log(p_mad_bind_info->p_umadt_obj->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__mad_recv_processor: "
|
|
Packit |
13e616 |
"Received data p_osm_madw [0x%p]" "\n\t\t\t\tTID[0x%"
|
|
Packit |
13e616 |
PRIx64 ", context[%p]. \n", p_osm_madw,
|
|
Packit |
13e616 |
((ib_mad_t *) p_osm_madw->p_mad)->trans_id,
|
|
Packit |
13e616 |
transaction_context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
(*(p_mad_bind_info->mad_recv_callback)) (p_osm_madw,
|
|
Packit |
13e616 |
p_mad_bind_info->
|
|
Packit |
13e616 |
client_context,
|
|
Packit |
13e616 |
transaction_context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_status_t
|
|
Packit |
13e616 |
__match_tid_context(const cl_list_item_t * const p_list_item, void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
if (((trans_context_t *) p_list_item)->trans_id ==
|
|
Packit |
13e616 |
*((uint64_t *) context))
|
|
Packit |
13e616 |
return CL_SUCCESS;
|
|
Packit |
13e616 |
return CL_NOT_FOUND;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
boolean_t __valid_mad_handle(IN mad_bind_info_t * p_mad_bind_info)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_umadt_obj = p_mad_bind_info->p_umadt_obj;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_umadt_obj->register_lock);
|
|
Packit |
13e616 |
if (!cl_is_item_in_qlist(&p_umadt_obj->register_list,
|
|
Packit |
13e616 |
&p_mad_bind_info->list_item)) {
|
|
Packit |
13e616 |
cl_spinlock_release(&p_umadt_obj->register_lock);
|
|
Packit |
13e616 |
return FALSE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_spinlock_release(&p_umadt_obj->register_lock);
|
|
Packit |
13e616 |
return TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void __osm_vendor_timer_callback(IN void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
uint64_t current_time;
|
|
Packit |
13e616 |
mad_bind_info_t *p_mad_bind_info;
|
|
Packit |
13e616 |
umadt_obj_t *p_umadt_obj;
|
|
Packit |
13e616 |
uint32_t timeout;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_item_t *p_list_item, *p_next_list_item;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_mad_bind_info = (mad_bind_info_t *) context;
|
|
Packit |
13e616 |
p_umadt_obj = p_mad_bind_info->p_umadt_obj;
|
|
Packit |
13e616 |
timeout = p_umadt_obj->timeout * 1000;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
current_time = cl_get_time_stamp();
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_list_item = cl_qlist_head(&p_mad_bind_info->trans_ctxt_list);
|
|
Packit |
13e616 |
while (p_list_item != cl_qlist_end(&p_mad_bind_info->trans_ctxt_list)) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_next_list_item = cl_qlist_next(p_list_item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* DEFAULT_PKT_TIMEOUT is in milli seconds */
|
|
Packit |
13e616 |
if (current_time - ((trans_context_t *) p_list_item)->sent_time
|
|
Packit |
13e616 |
> timeout) {
|
|
Packit |
13e616 |
/* Add this transaction to the timeout_list */
|
|
Packit |
13e616 |
cl_qlist_remove_item(&p_mad_bind_info->trans_ctxt_list,
|
|
Packit |
13e616 |
p_list_item);
|
|
Packit |
13e616 |
cl_qlist_insert_tail(&p_mad_bind_info->timeout_list,
|
|
Packit |
13e616 |
p_list_item);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_list_item = p_next_list_item;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_list_item = cl_qlist_head(&p_mad_bind_info->timeout_list);
|
|
Packit |
13e616 |
while (p_list_item != cl_qlist_end(&p_mad_bind_info->timeout_list)) {
|
|
Packit |
13e616 |
osm_log(p_mad_bind_info->p_umadt_obj->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osm_vendor_timer_callback: "
|
|
Packit |
13e616 |
"Timing out transaction context [0x%p].\n",
|
|
Packit |
13e616 |
((trans_context_t *) p_list_item)->context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
(*(p_mad_bind_info->mad_recv_callback)) (NULL,
|
|
Packit |
13e616 |
p_mad_bind_info->
|
|
Packit |
13e616 |
client_context,
|
|
Packit |
13e616 |
((trans_context_t *)
|
|
Packit |
13e616 |
p_list_item)->
|
|
Packit |
13e616 |
context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_next_list_item = cl_qlist_next(p_list_item);
|
|
Packit |
13e616 |
cl_qlist_remove_item(&p_mad_bind_info->timeout_list,
|
|
Packit |
13e616 |
p_list_item);
|
|
Packit |
13e616 |
free(p_list_item);
|
|
Packit |
13e616 |
p_list_item = p_next_list_item;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_timer_start(&p_mad_bind_info->timeout_timer,
|
|
Packit |
13e616 |
DEFAULT_TIMER_INTERVAL_MSEC);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#endif /* OSM_VENDOR_INTF_UMADT */
|