--- /dev/null
+/*\r
+ * Copyright (c) 2004-2007 Voltaire Inc. All rights reserved.\r
+ * Copyright (c) 2008 Intel Corporation. All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenFabrics.org BSD license\r
+ * below:\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+#pragma once\r
+\r
+#ifndef UMAD_H\r
+#define UMAD_H\r
+\r
+#include <windows.h>\r
+#include <iba\winmad.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*\r
+ * Interfaces based on libibumad 1.2.0\r
+ */\r
+\r
+typedef unsigned __int8 uint8_t;\r
+typedef unsigned __int16 uint16_t;\r
+typedef unsigned __int32 uint32_t;\r
+typedef unsigned __int64 uint64_t;\r
+\r
+#define EIO 5\r
+#define EWOULDBLOCK 11\r
+#define ENOMEM 12\r
+#define EINVAL 22\r
+#define ETIMEDOUT 110\r
+\r
+#define UMAD_ANY_PORT 1 // TODO: support this properly\r
+\r
+// Allow casting to WM_MAD_AV\r
+typedef struct ib_mad_addr\r
+{\r
+ uint32_t qpn;\r
+ uint32_t qkey;\r
+ uint32_t flow_label;\r
+ uint16_t pkey_index;\r
+ uint8_t hop_limit;\r
+ uint8_t gid_index;\r
+ uint8_t gid[16];\r
+\r
+ uint8_t grh_present;\r
+ uint8_t reserved_grh;\r
+ uint16_t lid;\r
+ uint8_t sl;\r
+ uint8_t path_bits;\r
+ uint8_t reserved_rate;\r
+ uint8_t traffic_class;\r
+\r
+} ib_mad_addr_t;\r
+\r
+// Allow casting to WM_MAD\r
+#pragma warning(push)\r
+#pragma warning(disable: 4200)\r
+typedef struct ib_user_mad\r
+{\r
+ uint32_t agent_id;\r
+ uint32_t reserved_id;\r
+ ib_mad_addr_t addr;\r
+\r
+ uint32_t status;\r
+ uint32_t timeout_ms;\r
+ uint32_t retries;\r
+ uint32_t length;\r
+ uint8_t data[0];\r
+\r
+} ib_user_mad_t;\r
+#pragma warning(pop)\r
+\r
+#define UMAD_CA_NAME_LEN 64\r
+#define UMAD_CA_MAX_PORTS 10 /* 0 - 9 */\r
+#define UMAD_MAX_PORTS 64\r
+\r
+typedef struct umad_port\r
+{\r
+ char ca_name[UMAD_CA_NAME_LEN];\r
+ int portnum;\r
+ unsigned base_lid;\r
+ unsigned lmc;\r
+ unsigned sm_lid;\r
+ unsigned sm_sl;\r
+ unsigned state;\r
+ unsigned phys_state;\r
+ unsigned rate;\r
+ uint64_t capmask;\r
+ uint64_t gid_prefix;\r
+ uint64_t port_guid;\r
+ unsigned pkeys_size;\r
+ uint16_t *pkeys;\r
+\r
+} umad_port_t;\r
+\r
+typedef struct umad_ca\r
+{\r
+ char ca_name[UMAD_CA_NAME_LEN];\r
+ unsigned node_type;\r
+ int numports;\r
+ char fw_ver[20];\r
+ char ca_type[40];\r
+ char hw_ver[20];\r
+ uint64_t node_guid;\r
+ uint64_t system_guid;\r
+ umad_port_t *ports[UMAD_CA_MAX_PORTS];\r
+\r
+} umad_ca_t;\r
+\r
+__declspec(dllexport)\r
+int umad_init(void);\r
+__declspec(dllexport)\r
+int umad_done(void);\r
+\r
+__declspec(dllexport)\r
+int umad_get_cas_names(char cas[][UMAD_CA_NAME_LEN], int max);\r
+__declspec(dllexport)\r
+int umad_get_ca_portguids(char *ca_name, uint64_t *portguids, int max);\r
+\r
+__declspec(dllexport)\r
+int umad_get_ca(char *ca_name, umad_ca_t *ca);\r
+__declspec(dllexport)\r
+int umad_release_ca(umad_ca_t *ca);\r
+\r
+__declspec(dllexport)\r
+int umad_get_port(char *ca_name, int portnum, umad_port_t *port);\r
+__declspec(dllexport)\r
+int umad_release_port(umad_port_t *port);\r
+\r
+__declspec(dllexport)\r
+int umad_get_issm_path(char *ca_name, int portnum, char path[], int max);\r
+\r
+__declspec(dllexport)\r
+int umad_open_port(char *ca_name, int portnum);\r
+__declspec(dllexport)\r
+int umad_close_port(int portid);\r
+\r
+__declspec(dllexport)\r
+void *umad_get_mad(void *umad);\r
+\r
+__declspec(dllexport)\r
+size_t umad_size(void);\r
+\r
+__declspec(dllexport)\r
+int umad_status(void *umad);\r
+\r
+__declspec(dllexport)\r
+ib_mad_addr_t *umad_get_mad_addr(void *umad);\r
+__declspec(dllexport)\r
+int umad_set_grh_net(void *umad, void *mad_addr);\r
+__declspec(dllexport)\r
+int umad_set_grh(void *umad, void *mad_addr);\r
+__declspec(dllexport)\r
+int umad_set_addr_net(void *umad, int dlid, int dqp, int sl, int qkey);\r
+__declspec(dllexport)\r
+int umad_set_addr(void *umad, int dlid, int dqp, int sl, int qkey);\r
+__declspec(dllexport)\r
+int umad_set_pkey(void *umad, int pkey_index);\r
+__declspec(dllexport)\r
+int umad_get_pkey(void *umad);\r
+\r
+__declspec(dllexport)\r
+int umad_send(int portid, int agentid, void *umad, int length,\r
+ int timeout_ms, int retries);\r
+__declspec(dllexport)\r
+int umad_recv(int portid, void *umad, int *length, int timeout_ms);\r
+__declspec(dllexport)\r
+int umad_poll(int portid, int timeout_ms);\r
+HANDLE umad_get_fd(int portid);\r
+\r
+__declspec(dllexport)\r
+int umad_register(int portid, int mgmt_class, int mgmt_version,\r
+ uint8_t rmpp_version, long method_mask[16/sizeof(long)]);\r
+__declspec(dllexport)\r
+int umad_register_oui(int portid, int mgmt_class, uint8_t rmpp_version,\r
+ uint8_t oui[3], long method_mask[16/sizeof(long)]);\r
+__declspec(dllexport)\r
+int umad_unregister(int portid, int agentid);\r
+\r
+\r
+__declspec(dllexport)\r
+int umad_debug(int level);\r
+__declspec(dllexport)\r
+void umad_addr_dump(ib_mad_addr_t *addr);\r
+__declspec(dllexport)\r
+void umad_dump(void *umad);\r
+\r
+__declspec(dllexport)\r
+void *umad_alloc(int num, size_t size);\r
+\r
+__declspec(dllexport)\r
+void umad_free(void *umad);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* UMAD_H */\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004-2007 Voltaire Inc. All rights reserved.\r
+ *\r
+ * This software is available to you under a choice of one of two\r
+ * licenses. You may choose to be licensed under the terms of the GNU\r
+ * General Public License (GPL) Version 2, available from the file\r
+ * COPYING in the main directory of this source tree, or the\r
+ * OpenIB.org BSD license below:\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ */\r
+\r
+#include <windows.h>\r
+#include <stdio.h>\r
+\r
+#include <infiniband/umad.h>\r
+#include <infiniband/verbs.h>\r
+#include "ibumad.h"\r
+\r
+#define IB_OPENIB_OUI (0x001405)\r
+\r
+#define UMAD_MAX_PKEYS 16\r
+\r
+typedef struct um_port\r
+{\r
+ IWMProvider *prov;\r
+ UINT64 dev_guid;\r
+ OVERLAPPED overlap;\r
+ BOOL pending;\r
+ UINT8 port_num;\r
+\r
+} um_port_t;\r
+\r
+CRITICAL_SECTION crit_sec;\r
+um_port_t ports[UMAD_MAX_PORTS];\r
+\r
+\r
+__declspec(dllexport)\r
+int umad_init(void)\r
+{\r
+ InitializeCriticalSection(&crit_sec);\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_done(void)\r
+{\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_get_cas_names(char cas[][UMAD_CA_NAME_LEN], int max)\r
+{\r
+ struct ibv_device **list;\r
+ int cnt, i;\r
+\r
+ list = ibv_get_device_list(&cnt);\r
+ if (list == NULL) {\r
+ return 0;\r
+ }\r
+\r
+ for (i = 0; i < min(cnt, max); i++) {\r
+ strcpy(cas[i], ibv_get_device_name(list[i]));\r
+ }\r
+\r
+ ibv_free_device_list(list);\r
+ return i;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_get_ca_portguids(char *ca_name, uint64_t *portguids, int max)\r
+{\r
+ umad_ca_t ca;\r
+ int ports = 0, i;\r
+\r
+ if (umad_get_ca(ca_name, &ca) < 0)\r
+ return -1;\r
+\r
+ if (ca.numports + 1 > max) {\r
+ umad_release_ca(&ca);\r
+ return -ENOMEM;\r
+ }\r
+\r
+ for (i = 0; i <= ca.numports; i++)\r
+ portguids[ports++] = ca.ports[i]->port_guid;\r
+\r
+ umad_release_ca(&ca);\r
+ return ports;\r
+}\r
+\r
+static void umad_convert_ca_attr(umad_ca_t *ca, ibv_device_attr *attr)\r
+{\r
+ ca->node_type = 1; // HCA\r
+ ca->numports = attr->phys_port_cnt;\r
+ strncpy(ca->fw_ver, attr->fw_ver, 20);\r
+ memset(ca->ca_type, 0, 40); // TODO: determine what this should be\r
+ sprintf(ca->hw_ver, "0x%x", attr->hw_ver);\r
+ ca->node_guid = attr->node_guid;\r
+ ca->system_guid = attr->sys_image_guid;\r
+}\r
+\r
+static int umad_query_port(struct ibv_context *context, umad_port_t *port)\r
+{\r
+ ibv_port_attr attr;\r
+ ibv_gid gid;\r
+ int i, ret;\r
+\r
+ ret = ibv_query_port(context, (uint8_t) port->portnum, &attr);\r
+ if (ret != 0) {\r
+ return ret;\r
+ }\r
+\r
+ port->base_lid = attr.lid;\r
+ port->lmc = attr.lmc;\r
+ port->sm_lid = attr.sm_lid;\r
+ port->sm_sl = attr.sm_sl;\r
+ port->state = attr.state;\r
+ port->phys_state = attr.phys_state;\r
+ port->rate = attr.active_speed;\r
+ port->capmask = attr.port_cap_flags;\r
+\r
+ // Assume GID 0 contains port GUID and gid prefix\r
+ ret = ibv_query_gid(context, (uint8_t) port->portnum, 0, &gid);\r
+ if (ret != 0) {\r
+ return ret;\r
+ }\r
+\r
+ port->gid_prefix = gid.global.subnet_prefix;\r
+ port->port_guid = gid.global.interface_id;\r
+\r
+ port->pkeys_size = min(UMAD_MAX_PKEYS, attr.pkey_tbl_len);\r
+ for (i = 0; i < (int) port->pkeys_size; i++) {\r
+ ret = ibv_query_pkey(context,(uint8_t) port->portnum, i, &port->pkeys[i]);\r
+ if (ret != 0) {\r
+ return ret;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_get_ca(char *ca_name, umad_ca_t *ca)\r
+{\r
+ struct ibv_device **list;\r
+ struct ibv_context *context;\r
+ ibv_device_attr dev_attr;\r
+ int cnt, i, ret = 0;\r
+ uint8_t *ports;\r
+ size_t port_size;\r
+\r
+ list = ibv_get_device_list(&cnt);\r
+ if (list == NULL) {\r
+ return -ENOMEM;\r
+ }\r
+\r
+ for (i = 0; i < cnt; i++) {\r
+ if (!strcmp(ca_name, ibv_get_device_name(list[i]))) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (i == cnt) {\r
+ ret = -EINVAL;\r
+ goto free;\r
+ }\r
+\r
+ context = ibv_open_device(list[i]);\r
+ if (context == NULL) {\r
+ ret = -ENOMEM;\r
+ goto free;\r
+ }\r
+\r
+ ret = ibv_query_device(context, &dev_attr);\r
+ if (ret != 0) {\r
+ goto close;\r
+ }\r
+\r
+ port_size = sizeof(umad_port_t) + sizeof(uint16_t) * UMAD_MAX_PKEYS;\r
+ ports = new uint8_t[port_size * dev_attr.phys_port_cnt];\r
+ if (ports == NULL) {\r
+ ret = -ENOMEM;\r
+ goto close;\r
+ }\r
+\r
+ strcpy(ca->ca_name, ca_name);\r
+ umad_convert_ca_attr(ca, &dev_attr);\r
+\r
+ for (i = 0; i < dev_attr.phys_port_cnt; i++, ports += port_size) {\r
+\r
+ ca->ports[i] = (umad_port_t *) ports;\r
+ strcpy(ca->ports[i]->ca_name, ca_name);\r
+ ca->ports[i]->portnum = i + 1;\r
+ ca->ports[i]->pkeys = (uint16_t *) (ports + sizeof(umad_port_t));\r
+\r
+ ret = umad_query_port(context, ca->ports[i]);\r
+ if (ret != 0) {\r
+ goto close;\r
+ }\r
+ }\r
+\r
+close:\r
+ ibv_close_device(context);\r
+free:\r
+ ibv_free_device_list(list);\r
+ if (ret != 0) {\r
+ delete ca;\r
+ }\r
+ return ret;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_release_ca(umad_ca_t *ca)\r
+{\r
+ delete ca->ports[0];\r
+ return 0;\r
+}\r
+\r
+static uint64_t umad_get_ca_guid(char *ca_name)\r
+{\r
+ umad_ca_t ca;\r
+ uint64_t guid;\r
+ int ret;\r
+\r
+ ret = umad_get_ca(ca_name, &ca);\r
+ if (ret != 0) {\r
+ return 0;\r
+ }\r
+\r
+ guid = ca.node_guid;\r
+ umad_release_ca(&ca);\r
+ return guid;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_get_port(char *ca_name, int portnum, umad_port_t *port)\r
+{\r
+ umad_ca_t ca;\r
+ int ret;\r
+\r
+ ret = umad_get_ca(ca_name, &ca);\r
+ if (ret != 0) {\r
+ return ret;\r
+ }\r
+\r
+ memcpy(port, ca.ports[portnum - 1], sizeof(umad_port_t));\r
+\r
+ port->pkeys = new uint16_t[ca.ports[portnum - 1]->pkeys_size];\r
+ if (port->pkeys == NULL) {\r
+ ret = -ENOMEM;\r
+ goto out;\r
+ }\r
+\r
+ memcpy(port->pkeys, ca.ports[portnum - 1]->pkeys,\r
+ sizeof(uint16_t) * ca.ports[portnum - 1]->pkeys_size);\r
+out:\r
+ umad_release_ca(&ca);\r
+ return ret;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_release_port(umad_port_t *port)\r
+{\r
+ delete port->pkeys;\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_get_issm_path(char *ca_name, int portnum, char path[], int max)\r
+{\r
+ return -EINVAL;\r
+}\r
+\r
+int umad_open_port(char *ca_name, int portnum)\r
+{\r
+ HRESULT hr;\r
+ int portid;\r
+\r
+ EnterCriticalSection(&crit_sec);\r
+ for (portid = 0; portid < UMAD_MAX_PORTS; portid++) {\r
+ if (ports[portid].prov == NULL) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (portid == UMAD_MAX_PORTS) {\r
+ portid = -ENOMEM;\r
+ goto out;\r
+ }\r
+\r
+ ports[portid].overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\r
+ if (ports[portid].overlap.hEvent == NULL) {\r
+ portid = -ENOMEM;\r
+ goto out;\r
+ }\r
+\r
+ hr = WmGetObject(IID_IWMProvider, (LPVOID*) &ports[portid].prov);\r
+ if (FAILED(hr)) {\r
+ CloseHandle(ports[portid].overlap.hEvent);\r
+ portid = GetLastError() & 0x80000000;\r
+ goto out;\r
+ }\r
+\r
+ ports[portid].dev_guid = umad_get_ca_guid(ca_name);\r
+ ports[portid].port_num = (uint8_t) portnum;\r
+\r
+out:\r
+ LeaveCriticalSection(&crit_sec);\r
+ return portid;\r
+}\r
+\r
+int umad_close_port(int portid)\r
+{\r
+ CloseHandle(ports[portid].overlap.hEvent);\r
+ ports[portid].prov->Release();\r
+\r
+ EnterCriticalSection(&crit_sec);\r
+ ports[portid].prov = NULL;\r
+ LeaveCriticalSection(&crit_sec);\r
+\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_set_grh_net(void *umad, void *mad_addr)\r
+{\r
+ struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
+ struct ib_mad_addr *addr = (struct ib_mad_addr *) mad_addr;\r
+\r
+ if (mad_addr) {\r
+ mad->addr.grh_present = 1;\r
+ memcpy(mad->addr.gid, addr->gid, 16);\r
+ mad->addr.flow_label = addr->flow_label;\r
+ mad->addr.hop_limit = addr->hop_limit;\r
+ mad->addr.traffic_class = addr->traffic_class;\r
+ } else\r
+ mad->addr.grh_present = 0;\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_set_grh(void *umad, void *mad_addr)\r
+{\r
+ struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
+ struct ib_mad_addr *addr = (struct ib_mad_addr *) mad_addr;\r
+\r
+ if (mad_addr) {\r
+ mad->addr.grh_present = 1;\r
+ memcpy(mad->addr.gid, addr->gid, 16);\r
+ mad->addr.flow_label = htonl(addr->flow_label);\r
+ mad->addr.hop_limit = addr->hop_limit;\r
+ mad->addr.traffic_class = addr->traffic_class;\r
+ } else\r
+ mad->addr.grh_present = 0;\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_set_pkey(void *umad, int pkey_index)\r
+{\r
+ struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
+\r
+ mad->addr.pkey_index = (uint16_t) pkey_index;\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_get_pkey(void *umad)\r
+{\r
+ struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
+\r
+ return mad->addr.pkey_index;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_set_addr(void *umad, int dlid, int dqp, int sl, int qkey)\r
+{\r
+ struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
+\r
+ mad->addr.qpn = htonl(dqp);\r
+ mad->addr.lid = htons((uint16_t) dlid);\r
+ mad->addr.qkey = htonl(qkey);\r
+ mad->addr.sl = (uint8_t) sl;\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_set_addr_net(void *umad, int dlid, int dqp, int sl, int qkey)\r
+{\r
+ struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
+\r
+ mad->addr.qpn = dqp;\r
+ mad->addr.lid = (uint16_t) dlid;\r
+ mad->addr.qkey = qkey;\r
+ mad->addr.sl = (uint8_t) sl;\r
+\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_status(void *umad)\r
+{\r
+ return ((struct ib_user_mad *) umad)->status;\r
+}\r
+\r
+__declspec(dllexport)\r
+ib_mad_addr_t *umad_get_mad_addr(void *umad)\r
+{\r
+ return &((struct ib_user_mad *) umad)->addr;\r
+}\r
+\r
+__declspec(dllexport)\r
+void *umad_get_mad(void *umad)\r
+{\r
+ return ((struct ib_user_mad *)umad)->data;\r
+}\r
+\r
+__declspec(dllexport)\r
+void *umad_alloc(int num, size_t size)\r
+{\r
+ return new uint8_t[num * size];\r
+}\r
+\r
+__declspec(dllexport)\r
+void umad_free(void *umad)\r
+{\r
+ delete umad;\r
+}\r
+\r
+__declspec(dllexport)\r
+size_t umad_size(void)\r
+{\r
+ return sizeof(struct ib_user_mad);\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_send(int portid, int agentid, void *umad, int length,\r
+ int timeout_ms, int retries)\r
+{\r
+ struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
+ HRESULT hr;\r
+\r
+ mad->agent_id = agentid;\r
+ mad->reserved_id = 0;\r
+\r
+ mad->timeout_ms = (uint32_t) timeout_ms;\r
+ mad->retries = (uint32_t) retries;\r
+ mad->length = (uint32_t) length;\r
+\r
+ hr = ports[portid].prov->Send((WM_MAD *) mad, NULL);\r
+ if (FAILED(hr)) {\r
+ return GetLastError();\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_recv(int portid, void *umad, int *length, int timeout_ms)\r
+{\r
+ WM_MAD *mad = (WM_MAD *) umad;\r
+ um_port_t *port;\r
+ HRESULT hr;\r
+\r
+ port = &ports[portid];\r
+ hr = port->prov->Receive(mad, (size_t) length, &port->overlap);\r
+\r
+ if (hr == E_PENDING) {\r
+ if (port->pending && timeout_ms == 0) {\r
+ do {\r
+ hr = WaitForSingleObject(port->overlap.hEvent, 250);\r
+ } while (hr == WAIT_TIMEOUT && port->pending);\r
+ } else {\r
+ hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms);\r
+ if (hr == WAIT_TIMEOUT) {\r
+ return -EWOULDBLOCK;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (FAILED(hr)) {\r
+ return -EIO;\r
+ }\r
+\r
+ if (mad->Length <= (UINT32) *length) {\r
+ port->pending = FALSE;\r
+ }\r
+\r
+ *length = mad->Length;\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_poll(int portid, int timeout_ms)\r
+{\r
+ WM_MAD mad;\r
+ um_port_t *port;\r
+ HRESULT hr;\r
+\r
+ port = &ports[portid];\r
+ hr = port->prov->Receive(&mad, sizeof mad, &port->overlap);\r
+\r
+ if (hr == E_PENDING) {\r
+ hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms);\r
+ if (hr == WAIT_TIMEOUT) {\r
+ return -ETIMEDOUT;\r
+ }\r
+ }\r
+\r
+ if (FAILED(hr) && hr != STATUS_MORE_ENTRIES) {\r
+ return -EIO;\r
+ }\r
+\r
+ port->pending = TRUE;\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_register_oui(int portid, int mgmt_class, uint8_t rmpp_version,\r
+ uint8_t oui[3], long method_mask[16/sizeof(long)])\r
+{\r
+ WM_REGISTER reg;\r
+ UINT64 id = 0;\r
+\r
+ UNREFERENCED_PARAMETER(rmpp_version);\r
+\r
+ reg.Guid = ports[portid].dev_guid;\r
+ reg.Qpn = (mgmt_class == 0x01 || mgmt_class == 0x81) ? 0 : htonl(1);\r
+ reg.Port = ports[portid].port_num;\r
+ reg.Class = (uint8_t) mgmt_class;\r
+ reg.Version = 1;\r
+ memset(reg.Reserved, 0, sizeof(reg.Reserved));\r
+ memcpy(reg.Oui, oui, sizeof(oui));\r
+ memcpy(reg.Methods, method_mask, sizeof(reg.Methods));\r
+\r
+ ports[portid].prov->Register(®, &id);\r
+\r
+ return (int) id;\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_register(int portid, int mgmt_class, int mgmt_version,\r
+ uint8_t rmpp_version, long method_mask[16/sizeof(long)])\r
+{\r
+ uint8_t oui[3];\r
+\r
+ memset(oui, 0, 3);\r
+ return umad_register_oui(portid, mgmt_class, rmpp_version, oui, method_mask);\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_unregister(int portid, int agentid)\r
+{\r
+ ports[portid].pending = FALSE;\r
+ return ports[portid].prov->Deregister((UINT64) agentid);\r
+}\r
+\r
+HANDLE umad_get_fd(int portid)\r
+{\r
+ return ports[portid].prov->GetFileHandle();\r
+}\r
+\r
+__declspec(dllexport)\r
+int umad_debug(int level)\r
+{\r
+ UNREFERENCED_PARAMETER(level);\r
+ return 0;\r
+}\r
+\r
+__declspec(dllexport)\r
+void umad_addr_dump(ib_mad_addr_t *addr)\r
+{\r
+ UNREFERENCED_PARAMETER(addr);\r
+}\r
+\r
+__declspec(dllexport)\r
+void umad_dump(void *umad)\r
+{\r
+ UNREFERENCED_PARAMETER(umad);\r
+}\r