Version: 1
-Previous: 91a13c798392cba24f8e014df167cd0800e2b2bc
-Head: f23c4746fb3048e5cfc0013b1bfb30e4e578fae9
+Previous: e869fcd6d769f0eebc62d547d0198176b6ea86a1
+Head: f31dfae054abd22d7afd822f68c0f57ee2d344c5
Applied:
rm-build: 6ece22f911fcfc6fceeb779a3cb16702ab4ba386
dapl-cleanup: ad55d4913247fe33cfe9752a538c62bb760413de
- libibverbs-release: 98b6ce2f8f9c0a9e78e3f1e7717dc72c39ae215e
- refresh-temp: f23c4746fb3048e5cfc0013b1bfb30e4e578fae9
+ libibverbs-release: f31dfae054abd22d7afd822f68c0f57ee2d344c5
Unapplied:
debug-wv: 6cf14f62c78d74636413cd01aa624f2825f26b09
dapl-debug: e13c7a46d1fab529c3008c37bac955a1d7738195
Bottom: 5d7a00b20748ebf64b6bc43cd8e99a5c01f6e6d2
-Top: 5d7a00b20748ebf64b6bc43cd8e99a5c01f6e6d2
+Top: b57f60cfc3fc1ea3881329f1abced3d99528a53b
Author: Sean Hefty <sean.hefty@intel.com>
Date: 2010-02-03 16:54:57 -0800
---
-
+diff --git a/trunk/ulp/libibverbs/src/device.cpp b/trunk/ulp/libibverbs/src/device.cpp
+index 1b66d3c..46372bc 100644
+--- a/trunk/ulp/libibverbs/src/device.cpp
++++ b/trunk/ulp/libibverbs/src/device.cpp
+@@ -1,371 +1,372 @@
+-/*\r
+- * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.\r
+- * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.\r
+- *\r
+- * This software is available to you under the OpenIB.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
+-#include <stdio.h>\r
+-#include <infiniband/verbs.h>\r
+-#include <rdma/winverbs.h>\r
+-#include "..\..\..\etc\user\comp_channel.cpp"\r
+-\r
+-CRITICAL_SECTION lock;\r
+-IWVProvider *prov;\r
+-COMP_MANAGER comp_mgr;\r
+-static DWORD ref;\r
+-\r
+-struct verbs_device\r
+-{\r
+- struct ibv_device device;\r
+- uint64_t guid;\r
+- uint8_t phys_port_cnt;\r
+-};\r
+-\r
+-struct verbs_port\r
+-{\r
+- COMP_ENTRY comp_entry;\r
+- DWORD event_flag;\r
+- uint8_t port_num;\r
+-};\r
+-\r
+-struct verbs_context\r
+-{\r
+- struct ibv_context context;\r
+- struct verbs_device device;\r
+- uint8_t closing;\r
+- struct verbs_port *port;\r
+- verbs_port *event_port;\r
+-};\r
+-\r
+-static int ibv_acquire(void)\r
+-{\r
+- HRESULT hr;\r
+-\r
+- EnterCriticalSection(&lock);\r
+- if (ref++ == 0) {\r
+- hr = WvGetObject(IID_IWVProvider, (LPVOID*) &prov);\r
+- if (FAILED(hr)) {\r
+- goto err1;\r
+- }\r
+- hr = CompManagerOpen(&comp_mgr);\r
+- if (FAILED(hr)) {\r
+- goto err2;\r
+- }\r
+- hr = CompManagerMonitor(&comp_mgr, prov->GetFileHandle(), 0);\r
+- if (FAILED(hr)) {\r
+- goto err3;\r
+- }\r
+- }\r
+- LeaveCriticalSection(&lock);\r
+- return 0;\r
+-\r
+-err3:\r
+- CompManagerClose(&comp_mgr);\r
+-err2:\r
+- prov->Release();\r
+-err1:\r
+- ref--;\r
+- LeaveCriticalSection(&lock);\r
+- return hr;\r
+-}\r
+-\r
+-static void ibv_release(void)\r
+-{\r
+- EnterCriticalSection(&lock);\r
+- if (--ref == 0) {\r
+- CompManagerClose(&comp_mgr);\r
+- prov->Release();\r
+- }\r
+- LeaveCriticalSection(&lock);\r
+-}\r
+-\r
+-__declspec(dllexport)\r
+-int ibvw_get_windata(struct ibvw_windata *windata, int version)\r
+-{\r
+- int ret;\r
+-\r
+- if (version != IBVW_WINDATA_VERSION || ibv_acquire()) {\r
+- return -1;\r
+- }\r
+-\r
+- prov->AddRef();\r
+- windata->prov = prov;\r
+- windata->comp_mgr = &comp_mgr;\r
+- return 0;\r
+-}\r
+-\r
+-__declspec(dllexport)\r
+-void ibvw_release_windata(struct ibvw_windata *windata, int version)\r
+-{\r
+- ibv_release();\r
+-}\r
+-\r
+-__declspec(dllexport)\r
+-struct ibv_device **ibv_get_device_list(int *num)\r
+-{\r
+- WV_DEVICE_ATTRIBUTES attr;\r
+- struct verbs_device *dev_array;\r
+- struct ibv_device **pdev_array;\r
+- NET64 *guid;\r
+- SIZE_T size, cnt;\r
+- HRESULT hr;\r
+-\r
+- if (ibv_acquire()) {\r
+- goto err1;\r
+- }\r
+-\r
+- cnt = 0;\r
+- size = sizeof(NET64);\r
+-\r
+- while ((size / sizeof(NET64)) > cnt) {\r
+- if (cnt > 0) {\r
+- delete guid;\r
+- }\r
+-\r
+- cnt = size / sizeof(NET64);\r
+- guid = new NET64[cnt];\r
+- if (guid == NULL) {\r
+- goto err1;\r
+- }\r
+-\r
+- hr = prov->QueryDeviceList(guid, &size);\r
+- if (FAILED(hr)) {\r
+- goto err2;\r
+- }\r
+- }\r
+-\r
+- size /= sizeof(NET64);\r
+- dev_array = new struct verbs_device[size];\r
+- pdev_array = new struct ibv_device*[size + 1];\r
+- if (dev_array == NULL || pdev_array == NULL) {\r
+- goto err2;\r
+- }\r
+-\r
+- for (cnt = 0; cnt < size; cnt++) {\r
+- pdev_array[cnt] = &dev_array[cnt].device;\r
+- hr = prov->QueryDevice(guid[cnt], &attr);\r
+- if (FAILED(hr)) {\r
+- goto err3;\r
+- }\r
+-\r
+- sprintf(dev_array[cnt].device.name, "ibv_device%d", cnt);\r
+- dev_array[cnt].device.node_type = IBV_NODE_UNKNOWN;\r
+- dev_array[cnt].device.transport_type = (ibv_transport_type) attr.DeviceType;\r
+- dev_array[cnt].guid = guid[cnt];\r
+- dev_array[cnt].phys_port_cnt = attr.PhysPortCount;\r
+- }\r
+-\r
+- pdev_array[cnt] = NULL;\r
+- if (num != NULL) {\r
+- *num = (int) size;\r
+- }\r
+- return pdev_array;\r
+-\r
+-err3:\r
+- ibv_free_device_list(pdev_array);\r
+-err2:\r
+- delete guid;\r
+-err1:\r
+- return NULL;\r
+-}\r
+-\r
+-__declspec(dllexport)\r
+-void ibv_free_device_list(struct ibv_device **list)\r
+-{\r
+- ibv_release();\r
+- delete CONTAINING_RECORD(list[0], struct verbs_device, device);\r
+- delete list;\r
+-}\r
+-\r
+-__declspec(dllexport)\r
+-const char *ibv_get_device_name(struct ibv_device *device)\r
+-{\r
+- return device->name;\r
+-}\r
+-\r
+-__declspec(dllexport)\r
+-uint64_t ibv_get_device_guid(struct ibv_device *device)\r
+-{\r
+- return CONTAINING_RECORD(device, struct verbs_device, device)->guid;\r
+-}\r
+-\r
+-__declspec(dllexport)\r
+-struct ibv_context *ibv_open_device(struct ibv_device *device)\r
+-{\r
+- struct verbs_device *vdev;\r
+- struct verbs_context *vcontext;\r
+- HRESULT hr;\r
+- int i;\r
+-\r
+- vdev = CONTAINING_RECORD(device, struct verbs_device, device);\r
+- vcontext = new struct verbs_context;\r
+- if (vcontext == NULL) {\r
+- return NULL;\r
+- }\r
+-\r
+- ibv_acquire();\r
+- memcpy(&vcontext->device, vdev, sizeof(struct verbs_device));\r
+- vcontext->context.device = &vcontext->device.device;\r
+- vcontext->event_port = NULL;\r
+- vcontext->closing = 0;\r
+- CompChannelInit(&comp_mgr, &vcontext->context.channel, INFINITE);\r
+-\r
+- vcontext->port = new struct verbs_port[vdev->phys_port_cnt];\r
+- if (vcontext->port == NULL) {\r
+- goto err1;\r
+- }\r
+-\r
+- hr = prov->OpenDevice(vdev->guid, &vcontext->context.cmd_if);\r
+- if (FAILED(hr)) {\r
+- goto err2;\r
+- }\r
+-\r
+- for (i = 0; i < vdev->phys_port_cnt; i++) {\r
+- vcontext->port[i].port_num = (uint8_t) i + 1;\r
+- vcontext->port[i].event_flag = 0;\r
+- CompEntryInit(&vcontext->context.channel, &vcontext->port[i].comp_entry);\r
+- vcontext->port[i].comp_entry.Busy = 1;\r
+- vcontext->context.cmd_if->Notify(vcontext->port[i].port_num,\r
+- &vcontext->port[i].comp_entry.Overlap,\r
+- &vcontext->port[i].event_flag);\r
+- }\r
+-\r
+- return &vcontext->context;\r
+-\r
+-err2:\r
+- delete vcontext->port;\r
+-err1:\r
+- delete vcontext;\r
+- ibv_release();\r
+- return NULL;\r
+-}\r
+-\r
+-__declspec(dllexport)\r
+-int ibv_close_device(struct ibv_context *context)\r
+-{\r
+- struct verbs_context *vcontext;\r
+- int i;\r
+-\r
+- vcontext = CONTAINING_RECORD(context, struct verbs_context, context);\r
+- vcontext->closing = 1;\r
+- context->cmd_if->CancelOverlappedRequests();\r
+-\r
+- for (i = 0; i < vcontext->device.phys_port_cnt; i++) {\r
+- CompEntryCancel(&vcontext->port[i].comp_entry);\r
+- }\r
+-\r
+- context->cmd_if->Release();\r
+- CompChannelCleanup(&vcontext->context.channel);\r
+- ibv_release();\r
+- delete vcontext->port;\r
+- delete vcontext;\r
+- return 0;\r
+-}\r
+-\r
+-static enum ibv_event_type ibv_get_port_event_state(struct verbs_context *vcontext)\r
+-{\r
+- WV_PORT_ATTRIBUTES attr;\r
+- HRESULT hr;\r
+-\r
+- hr = vcontext->context.cmd_if->QueryPort(vcontext->event_port->port_num, &attr);\r
+- if (FAILED(hr)) {\r
+- return IBV_EVENT_PORT_ERR;\r
+- }\r
+-\r
+- return (attr.State == WvPortActive) ?\r
+- IBV_EVENT_PORT_ACTIVE : IBV_EVENT_PORT_ERR;\r
+-}\r
+-\r
+-static int ibv_report_port_event(struct verbs_context *vcontext,\r
+- struct ibv_async_event *event)\r
+-{\r
+- struct verbs_port *port;\r
+- int ret = 0;\r
+-\r
+- port = vcontext->event_port;\r
+- event->element.port_num = port->port_num;\r
+-\r
+- if (port->event_flag & WV_EVENT_ERROR) {\r
+- event->event_type = IBV_EVENT_DEVICE_FATAL;\r
+- port->event_flag = 0;\r
+- } else if (port->event_flag & WV_EVENT_STATE) {\r
+- event->event_type = ibv_get_port_event_state(vcontext);\r
+- port->event_flag = 0;\r
+- } else if (port->event_flag & WV_EVENT_MANAGEMENT) {\r
+- event->event_type = IBV_EVENT_SM_CHANGE;\r
+- port->event_flag = 0;\r
+- } else if (port->event_flag & WV_EVENT_LINK_ADDRESS) {\r
+- event->event_type = IBV_EVENT_LID_CHANGE;\r
+- port->event_flag &= ~WV_EVENT_LINK_ADDRESS;\r
+- } else if (port->event_flag & WV_EVENT_PARTITION) {\r
+- event->event_type = IBV_EVENT_PKEY_CHANGE;\r
+- port->event_flag &= ~WV_EVENT_PARTITION;\r
+- } else {\r
+- port->event_flag = 0;\r
+- ret = -1;\r
+- }\r
+- \r
+- if (port->event_flag == 0 && !vcontext->closing) {\r
+- port->comp_entry.Busy = 1;\r
+- vcontext->context.cmd_if->Notify(vcontext->event_port->port_num,\r
+- &port->comp_entry.Overlap,\r
+- &port->event_flag);\r
+- vcontext->event_port = NULL;\r
+- }\r
+- return ret;\r
+-}\r
+-\r
+-__declspec(dllexport)\r
+-int ibv_get_async_event(struct ibv_context *context,\r
+- struct ibv_async_event *event)\r
+-{\r
+- struct verbs_context *vcontext;\r
+- COMP_ENTRY *entry;\r
+- int ret;\r
+-\r
+- vcontext = CONTAINING_RECORD(context, struct verbs_context, context);\r
+- if (vcontext->event_port) {\r
+- if (ibv_report_port_event(vcontext, event) == 0) {\r
+- return 0;\r
+- }\r
+- }\r
+-\r
+- ret = CompChannelPoll(&context->channel, &entry);\r
+- if (!ret) {\r
+- vcontext->event_port = CONTAINING_RECORD(entry, struct verbs_port, comp_entry);\r
+- ret = ibv_report_port_event(vcontext, event);\r
+- }\r
+-\r
+- return ret;\r
+-}\r
+-\r
+-__declspec(dllexport)\r
+-void ibv_ack_async_event(struct ibv_async_event *event)\r
+-{\r
+- // Only device/port level events are currently supported\r
+- // nothing to do here at the moment\r
+-}\r
++/*
++ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
++ * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
++ *
++ * This software is available to you under the OpenIB.org BSD license
++ * below:
++ *
++ * Redistribution and use in source and binary forms, with or
++ * without modification, are permitted provided that the following
++ * conditions are met:
++ *
++ * - Redistributions of source code must retain the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials
++ * provided with the distribution.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++ */
++
++#include <stdio.h>
++#include <infiniband/verbs.h>
++#include <rdma/winverbs.h>
++#include "..\..\..\etc\user\comp_channel.cpp"
++
++CRITICAL_SECTION lock;
++IWVProvider *prov;
++COMP_MANAGER comp_mgr;
++static DWORD ref;
++
++struct verbs_device
++{
++ struct ibv_device device;
++ uint64_t guid;
++ uint8_t phys_port_cnt;
++};
++
++struct verbs_port
++{
++ COMP_ENTRY comp_entry;
++ DWORD event_flag;
++ uint8_t port_num;
++};
++
++struct verbs_context
++{
++ struct ibv_context context;
++ struct verbs_device device;
++ uint8_t closing;
++ struct verbs_port *port;
++ verbs_port *event_port;
++};
++
++static int ibv_acquire(void)
++{
++ HRESULT hr;
++
++ EnterCriticalSection(&lock);
++ if (ref++ == 0) {
++ hr = WvGetObject(IID_IWVProvider, (LPVOID*) &prov);
++ if (FAILED(hr)) {
++ goto err1;
++ }
++ hr = CompManagerOpen(&comp_mgr);
++ if (FAILED(hr)) {
++ goto err2;
++ }
++ hr = CompManagerMonitor(&comp_mgr, prov->GetFileHandle(), 0);
++ if (FAILED(hr)) {
++ goto err3;
++ }
++ }
++ LeaveCriticalSection(&lock);
++ return 0;
++
++err3:
++ CompManagerClose(&comp_mgr);
++err2:
++ prov->Release();
++err1:
++ ref--;
++ LeaveCriticalSection(&lock);
++ return hr;
++}
++
++static void ibv_release(void)
++{
++ EnterCriticalSection(&lock);
++ if (--ref == 0) {
++ CompManagerClose(&comp_mgr);
++ prov->Release();
++ }
++ LeaveCriticalSection(&lock);
++}
++
++__declspec(dllexport)
++int ibvw_get_windata(struct ibvw_windata *windata, int version)
++{
++ int ret;
++
++ if (version != IBVW_WINDATA_VERSION || ibv_acquire()) {
++ return -1;
++ }
++
++ prov->AddRef();
++ windata->prov = prov;
++ windata->comp_mgr = &comp_mgr;
++ return 0;
++}
++
++__declspec(dllexport)
++void ibvw_release_windata(struct ibvw_windata *windata, int version)
++{
++ prov->Release();
++ ibv_release();
++}
++
++__declspec(dllexport)
++struct ibv_device **ibv_get_device_list(int *num)
++{
++ WV_DEVICE_ATTRIBUTES attr;
++ struct verbs_device *dev_array;
++ struct ibv_device **pdev_array;
++ NET64 *guid;
++ SIZE_T size, cnt;
++ HRESULT hr;
++
++ if (ibv_acquire()) {
++ goto err1;
++ }
++
++ cnt = 0;
++ size = sizeof(NET64);
++
++ while ((size / sizeof(NET64)) > cnt) {
++ if (cnt > 0) {
++ delete guid;
++ }
++
++ cnt = size / sizeof(NET64);
++ guid = new NET64[cnt];
++ if (guid == NULL) {
++ goto err1;
++ }
++
++ hr = prov->QueryDeviceList(guid, &size);
++ if (FAILED(hr)) {
++ goto err2;
++ }
++ }
++
++ size /= sizeof(NET64);
++ dev_array = new struct verbs_device[size];
++ pdev_array = new struct ibv_device*[size + 1];
++ if (dev_array == NULL || pdev_array == NULL) {
++ goto err2;
++ }
++
++ for (cnt = 0; cnt < size; cnt++) {
++ pdev_array[cnt] = &dev_array[cnt].device;
++ hr = prov->QueryDevice(guid[cnt], &attr);
++ if (FAILED(hr)) {
++ goto err3;
++ }
++
++ sprintf(dev_array[cnt].device.name, "ibv_device%d", cnt);
++ dev_array[cnt].device.node_type = IBV_NODE_UNKNOWN;
++ dev_array[cnt].device.transport_type = (ibv_transport_type) attr.DeviceType;
++ dev_array[cnt].guid = guid[cnt];
++ dev_array[cnt].phys_port_cnt = attr.PhysPortCount;
++ }
++
++ pdev_array[cnt] = NULL;
++ if (num != NULL) {
++ *num = (int) size;
++ }
++ return pdev_array;
++
++err3:
++ ibv_free_device_list(pdev_array);
++err2:
++ delete guid;
++err1:
++ return NULL;
++}
++
++__declspec(dllexport)
++void ibv_free_device_list(struct ibv_device **list)
++{
++ ibv_release();
++ delete CONTAINING_RECORD(list[0], struct verbs_device, device);
++ delete list;
++}
++
++__declspec(dllexport)
++const char *ibv_get_device_name(struct ibv_device *device)
++{
++ return device->name;
++}
++
++__declspec(dllexport)
++uint64_t ibv_get_device_guid(struct ibv_device *device)
++{
++ return CONTAINING_RECORD(device, struct verbs_device, device)->guid;
++}
++
++__declspec(dllexport)
++struct ibv_context *ibv_open_device(struct ibv_device *device)
++{
++ struct verbs_device *vdev;
++ struct verbs_context *vcontext;
++ HRESULT hr;
++ int i;
++
++ vdev = CONTAINING_RECORD(device, struct verbs_device, device);
++ vcontext = new struct verbs_context;
++ if (vcontext == NULL) {
++ return NULL;
++ }
++
++ ibv_acquire();
++ memcpy(&vcontext->device, vdev, sizeof(struct verbs_device));
++ vcontext->context.device = &vcontext->device.device;
++ vcontext->event_port = NULL;
++ vcontext->closing = 0;
++ CompChannelInit(&comp_mgr, &vcontext->context.channel, INFINITE);
++
++ vcontext->port = new struct verbs_port[vdev->phys_port_cnt];
++ if (vcontext->port == NULL) {
++ goto err1;
++ }
++
++ hr = prov->OpenDevice(vdev->guid, &vcontext->context.cmd_if);
++ if (FAILED(hr)) {
++ goto err2;
++ }
++
++ for (i = 0; i < vdev->phys_port_cnt; i++) {
++ vcontext->port[i].port_num = (uint8_t) i + 1;
++ vcontext->port[i].event_flag = 0;
++ CompEntryInit(&vcontext->context.channel, &vcontext->port[i].comp_entry);
++ vcontext->port[i].comp_entry.Busy = 1;
++ vcontext->context.cmd_if->Notify(vcontext->port[i].port_num,
++ &vcontext->port[i].comp_entry.Overlap,
++ &vcontext->port[i].event_flag);
++ }
++
++ return &vcontext->context;
++
++err2:
++ delete vcontext->port;
++err1:
++ delete vcontext;
++ ibv_release();
++ return NULL;
++}
++
++__declspec(dllexport)
++int ibv_close_device(struct ibv_context *context)
++{
++ struct verbs_context *vcontext;
++ int i;
++
++ vcontext = CONTAINING_RECORD(context, struct verbs_context, context);
++ vcontext->closing = 1;
++ context->cmd_if->CancelOverlappedRequests();
++
++ for (i = 0; i < vcontext->device.phys_port_cnt; i++) {
++ CompEntryCancel(&vcontext->port[i].comp_entry);
++ }
++
++ context->cmd_if->Release();
++ CompChannelCleanup(&vcontext->context.channel);
++ ibv_release();
++ delete vcontext->port;
++ delete vcontext;
++ return 0;
++}
++
++static enum ibv_event_type ibv_get_port_event_state(struct verbs_context *vcontext)
++{
++ WV_PORT_ATTRIBUTES attr;
++ HRESULT hr;
++
++ hr = vcontext->context.cmd_if->QueryPort(vcontext->event_port->port_num, &attr);
++ if (FAILED(hr)) {
++ return IBV_EVENT_PORT_ERR;
++ }
++
++ return (attr.State == WvPortActive) ?
++ IBV_EVENT_PORT_ACTIVE : IBV_EVENT_PORT_ERR;
++}
++
++static int ibv_report_port_event(struct verbs_context *vcontext,
++ struct ibv_async_event *event)
++{
++ struct verbs_port *port;
++ int ret = 0;
++
++ port = vcontext->event_port;
++ event->element.port_num = port->port_num;
++
++ if (port->event_flag & WV_EVENT_ERROR) {
++ event->event_type = IBV_EVENT_DEVICE_FATAL;
++ port->event_flag = 0;
++ } else if (port->event_flag & WV_EVENT_STATE) {
++ event->event_type = ibv_get_port_event_state(vcontext);
++ port->event_flag = 0;
++ } else if (port->event_flag & WV_EVENT_MANAGEMENT) {
++ event->event_type = IBV_EVENT_SM_CHANGE;
++ port->event_flag = 0;
++ } else if (port->event_flag & WV_EVENT_LINK_ADDRESS) {
++ event->event_type = IBV_EVENT_LID_CHANGE;
++ port->event_flag &= ~WV_EVENT_LINK_ADDRESS;
++ } else if (port->event_flag & WV_EVENT_PARTITION) {
++ event->event_type = IBV_EVENT_PKEY_CHANGE;
++ port->event_flag &= ~WV_EVENT_PARTITION;
++ } else {
++ port->event_flag = 0;
++ ret = -1;
++ }
++
++ if (port->event_flag == 0 && !vcontext->closing) {
++ port->comp_entry.Busy = 1;
++ vcontext->context.cmd_if->Notify(vcontext->event_port->port_num,
++ &port->comp_entry.Overlap,
++ &port->event_flag);
++ vcontext->event_port = NULL;
++ }
++ return ret;
++}
++
++__declspec(dllexport)
++int ibv_get_async_event(struct ibv_context *context,
++ struct ibv_async_event *event)
++{
++ struct verbs_context *vcontext;
++ COMP_ENTRY *entry;
++ int ret;
++
++ vcontext = CONTAINING_RECORD(context, struct verbs_context, context);
++ if (vcontext->event_port) {
++ if (ibv_report_port_event(vcontext, event) == 0) {
++ return 0;
++ }
++ }
++
++ ret = CompChannelPoll(&context->channel, &entry);
++ if (!ret) {
++ vcontext->event_port = CONTAINING_RECORD(entry, struct verbs_port, comp_entry);
++ ret = ibv_report_port_event(vcontext, event);
++ }
++
++ return ret;
++}
++
++__declspec(dllexport)
++void ibv_ack_async_event(struct ibv_async_event *event)
++{
++ // Only device/port level events are currently supported
++ // nothing to do here at the moment
++}
+++ /dev/null
-Bottom: 5d7a00b20748ebf64b6bc43cd8e99a5c01f6e6d2
-Top: b57f60cfc3fc1ea3881329f1abced3d99528a53b
-Author: Sean Hefty <sean.hefty@intel.com>
-Date: 2010-02-03 16:55:51 -0800
-
-Refresh of libibverbs-release
-
----
-
-diff --git a/trunk/ulp/libibverbs/src/device.cpp b/trunk/ulp/libibverbs/src/device.cpp
-index 1b66d3c..46372bc 100644
---- a/trunk/ulp/libibverbs/src/device.cpp
-+++ b/trunk/ulp/libibverbs/src/device.cpp
-@@ -1,371 +1,372 @@
--/*\r
-- * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.\r
-- * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.\r
-- *\r
-- * This software is available to you under the OpenIB.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
--#include <stdio.h>\r
--#include <infiniband/verbs.h>\r
--#include <rdma/winverbs.h>\r
--#include "..\..\..\etc\user\comp_channel.cpp"\r
--\r
--CRITICAL_SECTION lock;\r
--IWVProvider *prov;\r
--COMP_MANAGER comp_mgr;\r
--static DWORD ref;\r
--\r
--struct verbs_device\r
--{\r
-- struct ibv_device device;\r
-- uint64_t guid;\r
-- uint8_t phys_port_cnt;\r
--};\r
--\r
--struct verbs_port\r
--{\r
-- COMP_ENTRY comp_entry;\r
-- DWORD event_flag;\r
-- uint8_t port_num;\r
--};\r
--\r
--struct verbs_context\r
--{\r
-- struct ibv_context context;\r
-- struct verbs_device device;\r
-- uint8_t closing;\r
-- struct verbs_port *port;\r
-- verbs_port *event_port;\r
--};\r
--\r
--static int ibv_acquire(void)\r
--{\r
-- HRESULT hr;\r
--\r
-- EnterCriticalSection(&lock);\r
-- if (ref++ == 0) {\r
-- hr = WvGetObject(IID_IWVProvider, (LPVOID*) &prov);\r
-- if (FAILED(hr)) {\r
-- goto err1;\r
-- }\r
-- hr = CompManagerOpen(&comp_mgr);\r
-- if (FAILED(hr)) {\r
-- goto err2;\r
-- }\r
-- hr = CompManagerMonitor(&comp_mgr, prov->GetFileHandle(), 0);\r
-- if (FAILED(hr)) {\r
-- goto err3;\r
-- }\r
-- }\r
-- LeaveCriticalSection(&lock);\r
-- return 0;\r
--\r
--err3:\r
-- CompManagerClose(&comp_mgr);\r
--err2:\r
-- prov->Release();\r
--err1:\r
-- ref--;\r
-- LeaveCriticalSection(&lock);\r
-- return hr;\r
--}\r
--\r
--static void ibv_release(void)\r
--{\r
-- EnterCriticalSection(&lock);\r
-- if (--ref == 0) {\r
-- CompManagerClose(&comp_mgr);\r
-- prov->Release();\r
-- }\r
-- LeaveCriticalSection(&lock);\r
--}\r
--\r
--__declspec(dllexport)\r
--int ibvw_get_windata(struct ibvw_windata *windata, int version)\r
--{\r
-- int ret;\r
--\r
-- if (version != IBVW_WINDATA_VERSION || ibv_acquire()) {\r
-- return -1;\r
-- }\r
--\r
-- prov->AddRef();\r
-- windata->prov = prov;\r
-- windata->comp_mgr = &comp_mgr;\r
-- return 0;\r
--}\r
--\r
--__declspec(dllexport)\r
--void ibvw_release_windata(struct ibvw_windata *windata, int version)\r
--{\r
-- ibv_release();\r
--}\r
--\r
--__declspec(dllexport)\r
--struct ibv_device **ibv_get_device_list(int *num)\r
--{\r
-- WV_DEVICE_ATTRIBUTES attr;\r
-- struct verbs_device *dev_array;\r
-- struct ibv_device **pdev_array;\r
-- NET64 *guid;\r
-- SIZE_T size, cnt;\r
-- HRESULT hr;\r
--\r
-- if (ibv_acquire()) {\r
-- goto err1;\r
-- }\r
--\r
-- cnt = 0;\r
-- size = sizeof(NET64);\r
--\r
-- while ((size / sizeof(NET64)) > cnt) {\r
-- if (cnt > 0) {\r
-- delete guid;\r
-- }\r
--\r
-- cnt = size / sizeof(NET64);\r
-- guid = new NET64[cnt];\r
-- if (guid == NULL) {\r
-- goto err1;\r
-- }\r
--\r
-- hr = prov->QueryDeviceList(guid, &size);\r
-- if (FAILED(hr)) {\r
-- goto err2;\r
-- }\r
-- }\r
--\r
-- size /= sizeof(NET64);\r
-- dev_array = new struct verbs_device[size];\r
-- pdev_array = new struct ibv_device*[size + 1];\r
-- if (dev_array == NULL || pdev_array == NULL) {\r
-- goto err2;\r
-- }\r
--\r
-- for (cnt = 0; cnt < size; cnt++) {\r
-- pdev_array[cnt] = &dev_array[cnt].device;\r
-- hr = prov->QueryDevice(guid[cnt], &attr);\r
-- if (FAILED(hr)) {\r
-- goto err3;\r
-- }\r
--\r
-- sprintf(dev_array[cnt].device.name, "ibv_device%d", cnt);\r
-- dev_array[cnt].device.node_type = IBV_NODE_UNKNOWN;\r
-- dev_array[cnt].device.transport_type = (ibv_transport_type) attr.DeviceType;\r
-- dev_array[cnt].guid = guid[cnt];\r
-- dev_array[cnt].phys_port_cnt = attr.PhysPortCount;\r
-- }\r
--\r
-- pdev_array[cnt] = NULL;\r
-- if (num != NULL) {\r
-- *num = (int) size;\r
-- }\r
-- return pdev_array;\r
--\r
--err3:\r
-- ibv_free_device_list(pdev_array);\r
--err2:\r
-- delete guid;\r
--err1:\r
-- return NULL;\r
--}\r
--\r
--__declspec(dllexport)\r
--void ibv_free_device_list(struct ibv_device **list)\r
--{\r
-- ibv_release();\r
-- delete CONTAINING_RECORD(list[0], struct verbs_device, device);\r
-- delete list;\r
--}\r
--\r
--__declspec(dllexport)\r
--const char *ibv_get_device_name(struct ibv_device *device)\r
--{\r
-- return device->name;\r
--}\r
--\r
--__declspec(dllexport)\r
--uint64_t ibv_get_device_guid(struct ibv_device *device)\r
--{\r
-- return CONTAINING_RECORD(device, struct verbs_device, device)->guid;\r
--}\r
--\r
--__declspec(dllexport)\r
--struct ibv_context *ibv_open_device(struct ibv_device *device)\r
--{\r
-- struct verbs_device *vdev;\r
-- struct verbs_context *vcontext;\r
-- HRESULT hr;\r
-- int i;\r
--\r
-- vdev = CONTAINING_RECORD(device, struct verbs_device, device);\r
-- vcontext = new struct verbs_context;\r
-- if (vcontext == NULL) {\r
-- return NULL;\r
-- }\r
--\r
-- ibv_acquire();\r
-- memcpy(&vcontext->device, vdev, sizeof(struct verbs_device));\r
-- vcontext->context.device = &vcontext->device.device;\r
-- vcontext->event_port = NULL;\r
-- vcontext->closing = 0;\r
-- CompChannelInit(&comp_mgr, &vcontext->context.channel, INFINITE);\r
--\r
-- vcontext->port = new struct verbs_port[vdev->phys_port_cnt];\r
-- if (vcontext->port == NULL) {\r
-- goto err1;\r
-- }\r
--\r
-- hr = prov->OpenDevice(vdev->guid, &vcontext->context.cmd_if);\r
-- if (FAILED(hr)) {\r
-- goto err2;\r
-- }\r
--\r
-- for (i = 0; i < vdev->phys_port_cnt; i++) {\r
-- vcontext->port[i].port_num = (uint8_t) i + 1;\r
-- vcontext->port[i].event_flag = 0;\r
-- CompEntryInit(&vcontext->context.channel, &vcontext->port[i].comp_entry);\r
-- vcontext->port[i].comp_entry.Busy = 1;\r
-- vcontext->context.cmd_if->Notify(vcontext->port[i].port_num,\r
-- &vcontext->port[i].comp_entry.Overlap,\r
-- &vcontext->port[i].event_flag);\r
-- }\r
--\r
-- return &vcontext->context;\r
--\r
--err2:\r
-- delete vcontext->port;\r
--err1:\r
-- delete vcontext;\r
-- ibv_release();\r
-- return NULL;\r
--}\r
--\r
--__declspec(dllexport)\r
--int ibv_close_device(struct ibv_context *context)\r
--{\r
-- struct verbs_context *vcontext;\r
-- int i;\r
--\r
-- vcontext = CONTAINING_RECORD(context, struct verbs_context, context);\r
-- vcontext->closing = 1;\r
-- context->cmd_if->CancelOverlappedRequests();\r
--\r
-- for (i = 0; i < vcontext->device.phys_port_cnt; i++) {\r
-- CompEntryCancel(&vcontext->port[i].comp_entry);\r
-- }\r
--\r
-- context->cmd_if->Release();\r
-- CompChannelCleanup(&vcontext->context.channel);\r
-- ibv_release();\r
-- delete vcontext->port;\r
-- delete vcontext;\r
-- return 0;\r
--}\r
--\r
--static enum ibv_event_type ibv_get_port_event_state(struct verbs_context *vcontext)\r
--{\r
-- WV_PORT_ATTRIBUTES attr;\r
-- HRESULT hr;\r
--\r
-- hr = vcontext->context.cmd_if->QueryPort(vcontext->event_port->port_num, &attr);\r
-- if (FAILED(hr)) {\r
-- return IBV_EVENT_PORT_ERR;\r
-- }\r
--\r
-- return (attr.State == WvPortActive) ?\r
-- IBV_EVENT_PORT_ACTIVE : IBV_EVENT_PORT_ERR;\r
--}\r
--\r
--static int ibv_report_port_event(struct verbs_context *vcontext,\r
-- struct ibv_async_event *event)\r
--{\r
-- struct verbs_port *port;\r
-- int ret = 0;\r
--\r
-- port = vcontext->event_port;\r
-- event->element.port_num = port->port_num;\r
--\r
-- if (port->event_flag & WV_EVENT_ERROR) {\r
-- event->event_type = IBV_EVENT_DEVICE_FATAL;\r
-- port->event_flag = 0;\r
-- } else if (port->event_flag & WV_EVENT_STATE) {\r
-- event->event_type = ibv_get_port_event_state(vcontext);\r
-- port->event_flag = 0;\r
-- } else if (port->event_flag & WV_EVENT_MANAGEMENT) {\r
-- event->event_type = IBV_EVENT_SM_CHANGE;\r
-- port->event_flag = 0;\r
-- } else if (port->event_flag & WV_EVENT_LINK_ADDRESS) {\r
-- event->event_type = IBV_EVENT_LID_CHANGE;\r
-- port->event_flag &= ~WV_EVENT_LINK_ADDRESS;\r
-- } else if (port->event_flag & WV_EVENT_PARTITION) {\r
-- event->event_type = IBV_EVENT_PKEY_CHANGE;\r
-- port->event_flag &= ~WV_EVENT_PARTITION;\r
-- } else {\r
-- port->event_flag = 0;\r
-- ret = -1;\r
-- }\r
-- \r
-- if (port->event_flag == 0 && !vcontext->closing) {\r
-- port->comp_entry.Busy = 1;\r
-- vcontext->context.cmd_if->Notify(vcontext->event_port->port_num,\r
-- &port->comp_entry.Overlap,\r
-- &port->event_flag);\r
-- vcontext->event_port = NULL;\r
-- }\r
-- return ret;\r
--}\r
--\r
--__declspec(dllexport)\r
--int ibv_get_async_event(struct ibv_context *context,\r
-- struct ibv_async_event *event)\r
--{\r
-- struct verbs_context *vcontext;\r
-- COMP_ENTRY *entry;\r
-- int ret;\r
--\r
-- vcontext = CONTAINING_RECORD(context, struct verbs_context, context);\r
-- if (vcontext->event_port) {\r
-- if (ibv_report_port_event(vcontext, event) == 0) {\r
-- return 0;\r
-- }\r
-- }\r
--\r
-- ret = CompChannelPoll(&context->channel, &entry);\r
-- if (!ret) {\r
-- vcontext->event_port = CONTAINING_RECORD(entry, struct verbs_port, comp_entry);\r
-- ret = ibv_report_port_event(vcontext, event);\r
-- }\r
--\r
-- return ret;\r
--}\r
--\r
--__declspec(dllexport)\r
--void ibv_ack_async_event(struct ibv_async_event *event)\r
--{\r
-- // Only device/port level events are currently supported\r
-- // nothing to do here at the moment\r
--}\r
-+/*
-+ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
-+ * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
-+ *
-+ * This software is available to you under the OpenIB.org BSD license
-+ * below:
-+ *
-+ * Redistribution and use in source and binary forms, with or
-+ * without modification, are permitted provided that the following
-+ * conditions are met:
-+ *
-+ * - Redistributions of source code must retain the above
-+ * copyright notice, this list of conditions and the following
-+ * disclaimer.
-+ *
-+ * - Redistributions in binary form must reproduce the above
-+ * copyright notice, this list of conditions and the following
-+ * disclaimer in the documentation and/or other materials
-+ * provided with the distribution.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV
-+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+ * SOFTWARE.
-+ */
-+
-+#include <stdio.h>
-+#include <infiniband/verbs.h>
-+#include <rdma/winverbs.h>
-+#include "..\..\..\etc\user\comp_channel.cpp"
-+
-+CRITICAL_SECTION lock;
-+IWVProvider *prov;
-+COMP_MANAGER comp_mgr;
-+static DWORD ref;
-+
-+struct verbs_device
-+{
-+ struct ibv_device device;
-+ uint64_t guid;
-+ uint8_t phys_port_cnt;
-+};
-+
-+struct verbs_port
-+{
-+ COMP_ENTRY comp_entry;
-+ DWORD event_flag;
-+ uint8_t port_num;
-+};
-+
-+struct verbs_context
-+{
-+ struct ibv_context context;
-+ struct verbs_device device;
-+ uint8_t closing;
-+ struct verbs_port *port;
-+ verbs_port *event_port;
-+};
-+
-+static int ibv_acquire(void)
-+{
-+ HRESULT hr;
-+
-+ EnterCriticalSection(&lock);
-+ if (ref++ == 0) {
-+ hr = WvGetObject(IID_IWVProvider, (LPVOID*) &prov);
-+ if (FAILED(hr)) {
-+ goto err1;
-+ }
-+ hr = CompManagerOpen(&comp_mgr);
-+ if (FAILED(hr)) {
-+ goto err2;
-+ }
-+ hr = CompManagerMonitor(&comp_mgr, prov->GetFileHandle(), 0);
-+ if (FAILED(hr)) {
-+ goto err3;
-+ }
-+ }
-+ LeaveCriticalSection(&lock);
-+ return 0;
-+
-+err3:
-+ CompManagerClose(&comp_mgr);
-+err2:
-+ prov->Release();
-+err1:
-+ ref--;
-+ LeaveCriticalSection(&lock);
-+ return hr;
-+}
-+
-+static void ibv_release(void)
-+{
-+ EnterCriticalSection(&lock);
-+ if (--ref == 0) {
-+ CompManagerClose(&comp_mgr);
-+ prov->Release();
-+ }
-+ LeaveCriticalSection(&lock);
-+}
-+
-+__declspec(dllexport)
-+int ibvw_get_windata(struct ibvw_windata *windata, int version)
-+{
-+ int ret;
-+
-+ if (version != IBVW_WINDATA_VERSION || ibv_acquire()) {
-+ return -1;
-+ }
-+
-+ prov->AddRef();
-+ windata->prov = prov;
-+ windata->comp_mgr = &comp_mgr;
-+ return 0;
-+}
-+
-+__declspec(dllexport)
-+void ibvw_release_windata(struct ibvw_windata *windata, int version)
-+{
-+ prov->Release();
-+ ibv_release();
-+}
-+
-+__declspec(dllexport)
-+struct ibv_device **ibv_get_device_list(int *num)
-+{
-+ WV_DEVICE_ATTRIBUTES attr;
-+ struct verbs_device *dev_array;
-+ struct ibv_device **pdev_array;
-+ NET64 *guid;
-+ SIZE_T size, cnt;
-+ HRESULT hr;
-+
-+ if (ibv_acquire()) {
-+ goto err1;
-+ }
-+
-+ cnt = 0;
-+ size = sizeof(NET64);
-+
-+ while ((size / sizeof(NET64)) > cnt) {
-+ if (cnt > 0) {
-+ delete guid;
-+ }
-+
-+ cnt = size / sizeof(NET64);
-+ guid = new NET64[cnt];
-+ if (guid == NULL) {
-+ goto err1;
-+ }
-+
-+ hr = prov->QueryDeviceList(guid, &size);
-+ if (FAILED(hr)) {
-+ goto err2;
-+ }
-+ }
-+
-+ size /= sizeof(NET64);
-+ dev_array = new struct verbs_device[size];
-+ pdev_array = new struct ibv_device*[size + 1];
-+ if (dev_array == NULL || pdev_array == NULL) {
-+ goto err2;
-+ }
-+
-+ for (cnt = 0; cnt < size; cnt++) {
-+ pdev_array[cnt] = &dev_array[cnt].device;
-+ hr = prov->QueryDevice(guid[cnt], &attr);
-+ if (FAILED(hr)) {
-+ goto err3;
-+ }
-+
-+ sprintf(dev_array[cnt].device.name, "ibv_device%d", cnt);
-+ dev_array[cnt].device.node_type = IBV_NODE_UNKNOWN;
-+ dev_array[cnt].device.transport_type = (ibv_transport_type) attr.DeviceType;
-+ dev_array[cnt].guid = guid[cnt];
-+ dev_array[cnt].phys_port_cnt = attr.PhysPortCount;
-+ }
-+
-+ pdev_array[cnt] = NULL;
-+ if (num != NULL) {
-+ *num = (int) size;
-+ }
-+ return pdev_array;
-+
-+err3:
-+ ibv_free_device_list(pdev_array);
-+err2:
-+ delete guid;
-+err1:
-+ return NULL;
-+}
-+
-+__declspec(dllexport)
-+void ibv_free_device_list(struct ibv_device **list)
-+{
-+ ibv_release();
-+ delete CONTAINING_RECORD(list[0], struct verbs_device, device);
-+ delete list;
-+}
-+
-+__declspec(dllexport)
-+const char *ibv_get_device_name(struct ibv_device *device)
-+{
-+ return device->name;
-+}
-+
-+__declspec(dllexport)
-+uint64_t ibv_get_device_guid(struct ibv_device *device)
-+{
-+ return CONTAINING_RECORD(device, struct verbs_device, device)->guid;
-+}
-+
-+__declspec(dllexport)
-+struct ibv_context *ibv_open_device(struct ibv_device *device)
-+{
-+ struct verbs_device *vdev;
-+ struct verbs_context *vcontext;
-+ HRESULT hr;
-+ int i;
-+
-+ vdev = CONTAINING_RECORD(device, struct verbs_device, device);
-+ vcontext = new struct verbs_context;
-+ if (vcontext == NULL) {
-+ return NULL;
-+ }
-+
-+ ibv_acquire();
-+ memcpy(&vcontext->device, vdev, sizeof(struct verbs_device));
-+ vcontext->context.device = &vcontext->device.device;
-+ vcontext->event_port = NULL;
-+ vcontext->closing = 0;
-+ CompChannelInit(&comp_mgr, &vcontext->context.channel, INFINITE);
-+
-+ vcontext->port = new struct verbs_port[vdev->phys_port_cnt];
-+ if (vcontext->port == NULL) {
-+ goto err1;
-+ }
-+
-+ hr = prov->OpenDevice(vdev->guid, &vcontext->context.cmd_if);
-+ if (FAILED(hr)) {
-+ goto err2;
-+ }
-+
-+ for (i = 0; i < vdev->phys_port_cnt; i++) {
-+ vcontext->port[i].port_num = (uint8_t) i + 1;
-+ vcontext->port[i].event_flag = 0;
-+ CompEntryInit(&vcontext->context.channel, &vcontext->port[i].comp_entry);
-+ vcontext->port[i].comp_entry.Busy = 1;
-+ vcontext->context.cmd_if->Notify(vcontext->port[i].port_num,
-+ &vcontext->port[i].comp_entry.Overlap,
-+ &vcontext->port[i].event_flag);
-+ }
-+
-+ return &vcontext->context;
-+
-+err2:
-+ delete vcontext->port;
-+err1:
-+ delete vcontext;
-+ ibv_release();
-+ return NULL;
-+}
-+
-+__declspec(dllexport)
-+int ibv_close_device(struct ibv_context *context)
-+{
-+ struct verbs_context *vcontext;
-+ int i;
-+
-+ vcontext = CONTAINING_RECORD(context, struct verbs_context, context);
-+ vcontext->closing = 1;
-+ context->cmd_if->CancelOverlappedRequests();
-+
-+ for (i = 0; i < vcontext->device.phys_port_cnt; i++) {
-+ CompEntryCancel(&vcontext->port[i].comp_entry);
-+ }
-+
-+ context->cmd_if->Release();
-+ CompChannelCleanup(&vcontext->context.channel);
-+ ibv_release();
-+ delete vcontext->port;
-+ delete vcontext;
-+ return 0;
-+}
-+
-+static enum ibv_event_type ibv_get_port_event_state(struct verbs_context *vcontext)
-+{
-+ WV_PORT_ATTRIBUTES attr;
-+ HRESULT hr;
-+
-+ hr = vcontext->context.cmd_if->QueryPort(vcontext->event_port->port_num, &attr);
-+ if (FAILED(hr)) {
-+ return IBV_EVENT_PORT_ERR;
-+ }
-+
-+ return (attr.State == WvPortActive) ?
-+ IBV_EVENT_PORT_ACTIVE : IBV_EVENT_PORT_ERR;
-+}
-+
-+static int ibv_report_port_event(struct verbs_context *vcontext,
-+ struct ibv_async_event *event)
-+{
-+ struct verbs_port *port;
-+ int ret = 0;
-+
-+ port = vcontext->event_port;
-+ event->element.port_num = port->port_num;
-+
-+ if (port->event_flag & WV_EVENT_ERROR) {
-+ event->event_type = IBV_EVENT_DEVICE_FATAL;
-+ port->event_flag = 0;
-+ } else if (port->event_flag & WV_EVENT_STATE) {
-+ event->event_type = ibv_get_port_event_state(vcontext);
-+ port->event_flag = 0;
-+ } else if (port->event_flag & WV_EVENT_MANAGEMENT) {
-+ event->event_type = IBV_EVENT_SM_CHANGE;
-+ port->event_flag = 0;
-+ } else if (port->event_flag & WV_EVENT_LINK_ADDRESS) {
-+ event->event_type = IBV_EVENT_LID_CHANGE;
-+ port->event_flag &= ~WV_EVENT_LINK_ADDRESS;
-+ } else if (port->event_flag & WV_EVENT_PARTITION) {
-+ event->event_type = IBV_EVENT_PKEY_CHANGE;
-+ port->event_flag &= ~WV_EVENT_PARTITION;
-+ } else {
-+ port->event_flag = 0;
-+ ret = -1;
-+ }
-+
-+ if (port->event_flag == 0 && !vcontext->closing) {
-+ port->comp_entry.Busy = 1;
-+ vcontext->context.cmd_if->Notify(vcontext->event_port->port_num,
-+ &port->comp_entry.Overlap,
-+ &port->event_flag);
-+ vcontext->event_port = NULL;
-+ }
-+ return ret;
-+}
-+
-+__declspec(dllexport)
-+int ibv_get_async_event(struct ibv_context *context,
-+ struct ibv_async_event *event)
-+{
-+ struct verbs_context *vcontext;
-+ COMP_ENTRY *entry;
-+ int ret;
-+
-+ vcontext = CONTAINING_RECORD(context, struct verbs_context, context);
-+ if (vcontext->event_port) {
-+ if (ibv_report_port_event(vcontext, event) == 0) {
-+ return 0;
-+ }
-+ }
-+
-+ ret = CompChannelPoll(&context->channel, &entry);
-+ if (!ret) {
-+ vcontext->event_port = CONTAINING_RECORD(entry, struct verbs_port, comp_entry);
-+ ret = ibv_report_port_event(vcontext, event);
-+ }
-+
-+ return ret;
-+}
-+
-+__declspec(dllexport)
-+void ibv_ack_async_event(struct ibv_async_event *event)
-+{
-+ // Only device/port level events are currently supported
-+ // nothing to do here at the moment
-+}