/*\r
* Copyright (c) 2004-2007 Voltaire Inc. All rights reserved.\r
+ * Copyright (c) 2008 Intel Corp., 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
\r
#include <infiniband/umad.h>\r
#include <infiniband/verbs.h>\r
+#include <rdma/wvstatus.h>\r
#include "ibumad.h"\r
\r
#define IB_OPENIB_OUI (0x001405)\r
return -EINVAL;\r
}\r
\r
+static uint8_t umad_find_port(char *ca_name, enum ibv_port_state state)\r
+{\r
+ umad_ca_t ca;\r
+ int i, ret;\r
+\r
+ ret = umad_get_ca(ca_name, &ca);\r
+ if (ret != 0) {\r
+ return 0;\r
+ }\r
+\r
+ for (i = 0; i < ca.numports; i++) {\r
+ if (ca.ports[i]->state == state) {\r
+ i = ca.ports[i]->portnum;\r
+ umad_release_ca(&ca);\r
+ return (uint8_t) i;\r
+ }\r
+ }\r
+\r
+ umad_release_ca(&ca);\r
+ return 0;\r
+}\r
+\r
+static int umad_find_ca_port(enum ibv_port_state state, char *ca_name, uint8_t *port)\r
+{\r
+ char names[8][UMAD_CA_NAME_LEN];\r
+ int cnt, i;\r
+\r
+ cnt = umad_get_cas_names(names, 8);\r
+\r
+ for (i = 0; i < cnt; i++) {\r
+ *port = umad_find_port(names[i], state);\r
+ if (*port != 0) {\r
+ strcpy(ca_name, names[i]);\r
+ return 0;\r
+ }\r
+ }\r
+ return -1;\r
+}\r
+\r
+static int umad_resolve_ca_port(char *ca_name, uint8_t *port)\r
+{\r
+ int ret;\r
+\r
+ if (ca_name[0] != NULL) {\r
+ if (*port != 0) {\r
+ return 0;\r
+ }\r
+\r
+ *port = umad_find_port(ca_name, IBV_PORT_ACTIVE);\r
+ if (*port != 0) {\r
+ return 0;\r
+ }\r
+ *port = umad_find_port(ca_name, IBV_PORT_INIT);\r
+ if (*port != 0) {\r
+ return 0;\r
+ }\r
+ *port = umad_find_port(ca_name, IBV_PORT_DOWN);\r
+ return (*port == 0);\r
+ }\r
+\r
+ ret = umad_find_ca_port(IBV_PORT_ACTIVE, ca_name, port);\r
+ if (ret == 0) {\r
+ return 0;\r
+ }\r
+ ret = umad_find_ca_port(IBV_PORT_INIT, ca_name, port);\r
+ if (ret == 0) {\r
+ return 0;\r
+ }\r
+ ret = umad_find_ca_port(IBV_PORT_DOWN, ca_name, port);\r
+ return ret;\r
+}\r
+\r
+__declspec(dllexport)\r
int umad_open_port(char *ca_name, int portnum)\r
{\r
+ char name[UMAD_CA_NAME_LEN];\r
+ uint8_t port;\r
HRESULT hr;\r
int portid;\r
\r
+ if (ca_name != NULL) {\r
+ strcpy(name, ca_name);\r
+ port = (uint8_t) portnum;\r
+ } else {\r
+ name[0] = NULL;\r
+ port = 0;\r
+ }\r
+\r
+ hr = umad_resolve_ca_port(name, &port);\r
+ if (FAILED(hr)) {\r
+ return hr;\r
+ }\r
+\r
EnterCriticalSection(&crit_sec);\r
for (portid = 0; portid < UMAD_MAX_PORTS; portid++) {\r
if (ports[portid].prov == NULL) {\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
+ ports[portid].dev_guid = umad_get_ca_guid(name);\r
+ ports[portid].port_num = port;\r
\r
out:\r
LeaveCriticalSection(&crit_sec);\r
return portid;\r
}\r
\r
+__declspec(dllexport)\r
int umad_close_port(int portid)\r
{\r
CloseHandle(ports[portid].overlap.hEvent);\r
HRESULT hr;\r
\r
port = &ports[portid];\r
- hr = port->prov->Receive(mad, (size_t) length, &port->overlap);\r
+ hr = port->prov->Receive(mad, sizeof(WM_MAD) + (size_t) *length, &port->overlap);\r
\r
- if (hr == E_PENDING) {\r
+ if (hr == WV_IO_PENDING) {\r
if (port->pending && timeout_ms == 0) {\r
do {\r
hr = WaitForSingleObject(port->overlap.hEvent, 250);\r
}\r
\r
*length = mad->Length;\r
- return 0;\r
+ return (int) mad->Id;\r
}\r
\r
__declspec(dllexport)\r
port = &ports[portid];\r
hr = port->prov->Receive(&mad, sizeof mad, &port->overlap);\r
\r
- if (hr == E_PENDING) {\r
+ if (hr == WV_IO_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
+ if (FAILED(hr) && hr != ERROR_MORE_DATA) {\r
return -EIO;\r
}\r
\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
+ if (method_mask != NULL) {\r
+ memcpy(reg.Methods, method_mask, sizeof(reg.Methods));\r
+ } else {\r
+ memset(reg.Methods, 0, sizeof(reg.Methods));\r
+ }\r
ports[portid].prov->Register(®, &id);\r
\r
return (int) id;\r