From 635622b39878f6d0d894d0a310837a4d2b492418 Mon Sep 17 00:00:00 2001 From: shefty Date: Thu, 11 Dec 2008 21:35:06 +0000 Subject: [PATCH] libibumad: initial working library Signed-off-by: Sean Hefty git-svn-id: svn://openib.tc.cornell.edu/gen1@1781 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- branches/winverbs/ulp/libibumad/src/Sources | 2 +- branches/winverbs/ulp/libibumad/src/umad.cpp | 112 +++++++++++++++++-- 2 files changed, 104 insertions(+), 10 deletions(-) diff --git a/branches/winverbs/ulp/libibumad/src/Sources b/branches/winverbs/ulp/libibumad/src/Sources index 2e74e8e1..1d53cf29 100644 --- a/branches/winverbs/ulp/libibumad/src/Sources +++ b/branches/winverbs/ulp/libibumad/src/Sources @@ -14,7 +14,7 @@ DLLDEF = $(OBJ_PATH)\$O\ibum_exports.def !endif DLLENTRY = DllMain -USE_NTDLL = 1 +USE_MSVCRT=1 SOURCES = \ ibumad.rc \ diff --git a/branches/winverbs/ulp/libibumad/src/umad.cpp b/branches/winverbs/ulp/libibumad/src/umad.cpp index 989b8657..45efdcb4 100644 --- a/branches/winverbs/ulp/libibumad/src/umad.cpp +++ b/branches/winverbs/ulp/libibumad/src/umad.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2007 Voltaire Inc. All rights reserved. + * Copyright (c) 2008 Intel Corp., Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -36,6 +37,7 @@ #include #include +#include #include "ibumad.h" #define IB_OPENIB_OUI (0x001405) @@ -292,11 +294,99 @@ int umad_get_issm_path(char *ca_name, int portnum, char path[], int max) return -EINVAL; } +static uint8_t umad_find_port(char *ca_name, enum ibv_port_state state) +{ + umad_ca_t ca; + int i, ret; + + ret = umad_get_ca(ca_name, &ca); + if (ret != 0) { + return 0; + } + + for (i = 0; i < ca.numports; i++) { + if (ca.ports[i]->state == state) { + i = ca.ports[i]->portnum; + umad_release_ca(&ca); + return (uint8_t) i; + } + } + + umad_release_ca(&ca); + return 0; +} + +static int umad_find_ca_port(enum ibv_port_state state, char *ca_name, uint8_t *port) +{ + char names[8][UMAD_CA_NAME_LEN]; + int cnt, i; + + cnt = umad_get_cas_names(names, 8); + + for (i = 0; i < cnt; i++) { + *port = umad_find_port(names[i], state); + if (*port != 0) { + strcpy(ca_name, names[i]); + return 0; + } + } + return -1; +} + +static int umad_resolve_ca_port(char *ca_name, uint8_t *port) +{ + int ret; + + if (ca_name[0] != NULL) { + if (*port != 0) { + return 0; + } + + *port = umad_find_port(ca_name, IBV_PORT_ACTIVE); + if (*port != 0) { + return 0; + } + *port = umad_find_port(ca_name, IBV_PORT_INIT); + if (*port != 0) { + return 0; + } + *port = umad_find_port(ca_name, IBV_PORT_DOWN); + return (*port == 0); + } + + ret = umad_find_ca_port(IBV_PORT_ACTIVE, ca_name, port); + if (ret == 0) { + return 0; + } + ret = umad_find_ca_port(IBV_PORT_INIT, ca_name, port); + if (ret == 0) { + return 0; + } + ret = umad_find_ca_port(IBV_PORT_DOWN, ca_name, port); + return ret; +} + +__declspec(dllexport) int umad_open_port(char *ca_name, int portnum) { + char name[UMAD_CA_NAME_LEN]; + uint8_t port; HRESULT hr; int portid; + if (ca_name != NULL) { + strcpy(name, ca_name); + port = (uint8_t) portnum; + } else { + name[0] = NULL; + port = 0; + } + + hr = umad_resolve_ca_port(name, &port); + if (FAILED(hr)) { + return hr; + } + EnterCriticalSection(&crit_sec); for (portid = 0; portid < UMAD_MAX_PORTS; portid++) { if (ports[portid].prov == NULL) { @@ -322,14 +412,15 @@ int umad_open_port(char *ca_name, int portnum) goto out; } - ports[portid].dev_guid = umad_get_ca_guid(ca_name); - ports[portid].port_num = (uint8_t) portnum; + ports[portid].dev_guid = umad_get_ca_guid(name); + ports[portid].port_num = port; out: LeaveCriticalSection(&crit_sec); return portid; } +__declspec(dllexport) int umad_close_port(int portid) { CloseHandle(ports[portid].overlap.hEvent); @@ -484,9 +575,9 @@ int umad_recv(int portid, void *umad, int *length, int timeout_ms) HRESULT hr; port = &ports[portid]; - hr = port->prov->Receive(mad, (size_t) length, &port->overlap); + hr = port->prov->Receive(mad, sizeof(WM_MAD) + (size_t) *length, &port->overlap); - if (hr == E_PENDING) { + if (hr == WV_IO_PENDING) { if (port->pending && timeout_ms == 0) { do { hr = WaitForSingleObject(port->overlap.hEvent, 250); @@ -508,7 +599,7 @@ int umad_recv(int portid, void *umad, int *length, int timeout_ms) } *length = mad->Length; - return 0; + return (int) mad->Id; } __declspec(dllexport) @@ -521,14 +612,14 @@ int umad_poll(int portid, int timeout_ms) port = &ports[portid]; hr = port->prov->Receive(&mad, sizeof mad, &port->overlap); - if (hr == E_PENDING) { + if (hr == WV_IO_PENDING) { hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms); if (hr == WAIT_TIMEOUT) { return -ETIMEDOUT; } } - if (FAILED(hr) && hr != STATUS_MORE_ENTRIES) { + if (FAILED(hr) && hr != ERROR_MORE_DATA) { return -EIO; } @@ -552,8 +643,11 @@ int umad_register_oui(int portid, int mgmt_class, uint8_t rmpp_version, reg.Version = 1; memset(reg.Reserved, 0, sizeof(reg.Reserved)); memcpy(reg.Oui, oui, sizeof(oui)); - memcpy(reg.Methods, method_mask, sizeof(reg.Methods)); - + if (method_mask != NULL) { + memcpy(reg.Methods, method_mask, sizeof(reg.Methods)); + } else { + memset(reg.Methods, 0, sizeof(reg.Methods)); + } ports[portid].prov->Register(®, &id); return (int) id; -- 2.46.0