1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004,2005 Voltaire Inc. All rights reserved. 3219820Sjeff * 4219820Sjeff * This software is available to you under a choice of one of two 5219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 6219820Sjeff * General Public License (GPL) Version 2, available from the file 7219820Sjeff * COPYING in the main directory of this source tree, or the 8219820Sjeff * OpenIB.org BSD license below: 9219820Sjeff * 10219820Sjeff * Redistribution and use in source and binary forms, with or 11219820Sjeff * without modification, are permitted provided that the following 12219820Sjeff * conditions are met: 13219820Sjeff * 14219820Sjeff * - Redistributions of source code must retain the above 15219820Sjeff * copyright notice, this list of conditions and the following 16219820Sjeff * disclaimer. 17219820Sjeff * 18219820Sjeff * - Redistributions in binary form must reproduce the above 19219820Sjeff * copyright notice, this list of conditions and the following 20219820Sjeff * disclaimer in the documentation and/or other materials 21219820Sjeff * provided with the distribution. 22219820Sjeff * 23219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30219820Sjeff * SOFTWARE. 31219820Sjeff * 32219820Sjeff */ 33219820Sjeff 34219820Sjeff#if HAVE_CONFIG_H 35219820Sjeff# include <config.h> 36219820Sjeff#endif /* HAVE_CONFIG_H */ 37219820Sjeff 38219820Sjeff#include <stdio.h> 39219820Sjeff#include <stdlib.h> 40219820Sjeff#include <unistd.h> 41219820Sjeff#include <string.h> 42219820Sjeff#include <pthread.h> 43219820Sjeff#include <sys/time.h> 44219820Sjeff 45219820Sjeff#include <mad.h> 46219820Sjeff#include <infiniband/common.h> 47219820Sjeff 48219820Sjeff#undef DEBUG 49219820Sjeff#define DEBUG if (ibdebug) IBWARN 50219820Sjeff 51219820Sjeffstatic inline int 52219820Sjeffresponse_expected(int method) 53219820Sjeff{ 54219820Sjeff return method == IB_MAD_METHOD_GET || 55219820Sjeff method == IB_MAD_METHOD_SET || 56219820Sjeff method == IB_MAD_METHOD_TRAP; 57219820Sjeff} 58219820Sjeff 59219820Sjeffuint8_t * 60219820Sjeffib_vendor_call(void *data, ib_portid_t *portid, ib_vendor_call_t *call) 61219820Sjeff{ 62219820Sjeff ib_rpc_t rpc = {0}; 63219820Sjeff int range1 = 0, resp_expected; 64219820Sjeff 65219820Sjeff DEBUG("route %s data %p", portid2str(portid), data); 66219820Sjeff if (portid->lid <= 0) 67219820Sjeff return 0; /* no direct SMI */ 68219820Sjeff 69219820Sjeff if (!(range1 = mad_is_vendor_range1(call->mgmt_class)) && 70219820Sjeff !(mad_is_vendor_range2(call->mgmt_class))) 71219820Sjeff return 0; 72219820Sjeff 73219820Sjeff resp_expected = response_expected(call->method); 74219820Sjeff 75219820Sjeff rpc.mgtclass = call->mgmt_class; 76219820Sjeff 77219820Sjeff rpc.method = call->method; 78219820Sjeff rpc.attr.id = call->attrid; 79219820Sjeff rpc.attr.mod = call->mod; 80219820Sjeff rpc.timeout = resp_expected ? call->timeout : 0; 81219820Sjeff rpc.datasz = range1 ? IB_VENDOR_RANGE1_DATA_SIZE : IB_VENDOR_RANGE2_DATA_SIZE; 82219820Sjeff rpc.dataoffs = range1 ? IB_VENDOR_RANGE1_DATA_OFFS : IB_VENDOR_RANGE2_DATA_OFFS; 83219820Sjeff 84219820Sjeff if (!range1) 85219820Sjeff rpc.oui = call->oui; 86219820Sjeff 87219820Sjeff DEBUG("class 0x%x method 0x%x attr 0x%x mod 0x%x datasz %d off %d res_ex %d", 88219820Sjeff rpc.mgtclass, rpc.method, rpc.attr.id, rpc.attr.mod, 89219820Sjeff rpc.datasz, rpc.dataoffs, resp_expected); 90219820Sjeff 91219820Sjeff portid->qp = 1; 92219820Sjeff if (!portid->qkey) 93219820Sjeff portid->qkey = IB_DEFAULT_QP1_QKEY; 94219820Sjeff 95219820Sjeff if (resp_expected) 96219820Sjeff return madrpc_rmpp(&rpc, portid, 0, data); /* FIXME: no RMPP for now */ 97219820Sjeff 98219820Sjeff return mad_send(&rpc, portid, 0, data) < 0 ? 0 : data; /* FIXME: no RMPP for now */ 99219820Sjeff} 100