[ofw] [RFC] [PATCH 6/12] winverbs: implement IWVCompletionQueue
Sean Hefty
sean.hefty at intel.com
Fri Mar 14 23:02:03 PDT 2008
Userspace WinVerb implementation for completion queues. Most
calls are implemented, except for inherited IWVOverlapped routines.
Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
Index: core/winverbs/user/wv_cq.cpp
===================================================================
--- core/winverbs/user/wv_cq.cpp (revision 971)
+++ core/winverbs/user/wv_cq.cpp (working copy)
@@ -27,28 +27,117 @@
* SOFTWARE.
*/
+#include <iba\ib_ci.h>
#include "wv_base.h"
#include "wv_cq.h"
+#include "wv_qp.h"
+CWVCompletionQueue::CWVCompletionQueue(CWVDevice *pDevice)
+{
+ pDevice->AddRef();
+ m_pDevice = pDevice;
+ m_pVerbs = &pDevice->m_Verbs;
+ m_hFile = pDevice->m_hFile;
+
+ m_hVerbsCq = NULL;
+ m_Id = 0;
+
+ m_nRef = 1;
+}
+
STDMETHODIMP CWVCompletionQueue::
+Create(SIZE_T *pEntries)
+{
+ WV_IO_ID *pId;
+ DWORD bytes;
+ ib_api_status_t stat;
+ HRESULT hr;
+ ci_umv_buf_t verbsData;
+ CWVBuffer buf;
+
+ stat = m_pVerbs->pre_create_cq(m_pDevice->m_hVerbsDevice, (UINT32 *) pEntries,
+ &verbsData, &m_hVerbsCq);
+ if (stat != IB_SUCCESS) {
+ return WvConvertIbStatus(stat);
+ }
+
+ bytes = sizeof WV_IO_ID + max(verbsData.input_size, verbsData.output_size);
+ pId = (WV_IO_ID *) buf.Get(bytes);
+ if (pId == NULL) {
+ hr = WV_NO_MEMORY;
+ goto post;
+ }
+
+ pId->Id = m_pDevice->m_Id;
+ pId->VerbInfo = verbsData.command;
+ pId->Data = (UINT32) *pEntries;
+ RtlCopyMemory(pId + 1, verbsData.p_inout_buf, verbsData.input_size);
+
+ if (DeviceIoControl(m_hFile, WV_IOCTL_CQ_CREATE,
+ pId, sizeof WV_IO_ID + verbsData.input_size,
+ pId, sizeof WV_IO_ID + verbsData.output_size,
+ &bytes, NULL)) {
+ hr = WV_SUCCESS;
+ m_Id = pId->Id;
+ *pEntries = pId->Data;
+ } else {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ verbsData.status = pId->VerbInfo;
+ RtlCopyMemory(verbsData.p_inout_buf, pId + 1, verbsData.output_size);
+ buf.Put();
+
+post:
+ m_pVerbs->post_create_cq(m_pDevice->m_hVerbsDevice, (ib_api_status_t) hr,
+ (UINT32) *pEntries, &m_hVerbsCq, &verbsData);
+ return hr;
+}
+
+CWVCompletionQueue::~CWVCompletionQueue()
+{
+ DWORD bytes;
+ HRESULT hr;
+
+ if (m_Id != NULL) {
+ m_pVerbs->pre_destroy_cq(m_hVerbsCq);
+ hr = DeviceIoControl(m_hFile, WV_IOCTL_CQ_DESTROY, &m_Id, sizeof m_Id,
+ NULL, 0, &bytes, NULL) ?
+ WV_SUCCESS : HRESULT_FROM_WIN32(GetLastError());
+ m_pVerbs->post_destroy_cq(m_hVerbsCq, (ib_api_status_t) hr);
+ }
+ m_pDevice->Release();
+}
+
+STDMETHODIMP CWVCompletionQueue::
QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
{
- UNREFERENCED_PARAMETER(riid);
- UNREFERENCED_PARAMETER(ppvObj);
+ if (riid != IID_IUnknown && riid != IID_IWVCompletionQueue) {
+ *ppvObj = NULL;
+ return E_NOINTERFACE;
+ }
- return E_NOTIMPL;
+ *ppvObj = this;
+ AddRef();
+ return WV_SUCCESS;
}
STDMETHODIMP_(ULONG) CWVCompletionQueue::
AddRef(void)
{
- return 0;
+ return InterlockedIncrement(&m_nRef);
}
STDMETHODIMP_(ULONG) CWVCompletionQueue::
Release(void)
{
- return 0;
+ ULONG ref;
+
+ ref = (ULONG) InterlockedDecrement(&m_nRef);
+ if (ref == 0) {
+ delete this;
+ }
+ return ref;
}
STDMETHODIMP CWVCompletionQueue::
@@ -71,42 +160,104 @@
STDMETHODIMP CWVCompletionQueue::
Resize(SIZE_T* pEntries)
{
- UNREFERENCED_PARAMETER(pEntries);
+ WV_IO_ID *pId;
+ DWORD bytes;
+ ib_api_status_t stat;
+ HRESULT hr;
+ ci_umv_buf_t verbsData;
+ CWVBuffer buf;
- return E_NOTIMPL;
+ stat = m_pVerbs->pre_resize_cq(m_hVerbsCq, (UINT32 *) pEntries, &verbsData);
+ if (stat != IB_SUCCESS) {
+ return WvConvertIbStatus(stat);
+ }
+
+ bytes = sizeof WV_IO_ID + max(verbsData.input_size, verbsData.output_size);
+ pId = (WV_IO_ID *) buf.Get(bytes);
+ if (pId == NULL) {
+ hr = WV_NO_MEMORY;
+ goto post;
+ }
+
+ pId->Id = m_Id;
+ pId->VerbInfo = verbsData.command;
+ pId->Data = (UINT32) *pEntries;
+ RtlCopyMemory(pId + 1, verbsData.p_inout_buf, verbsData.input_size);
+
+ if (DeviceIoControl(m_hFile, WV_IOCTL_CQ_RESIZE,
+ pId, sizeof WV_IO_ID + verbsData.input_size,
+ pId, sizeof WV_IO_ID + verbsData.output_size,
+ &bytes, NULL)) {
+ hr = WV_SUCCESS;
+ *pEntries = pId->Data;
+ } else {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ verbsData.status = pId->VerbInfo;
+ RtlCopyMemory(verbsData.p_inout_buf, pId + 1, verbsData.output_size);
+ buf.Put();
+
+post:
+ m_pVerbs->post_resize_cq(m_hVerbsCq, (ib_api_status_t) hr,
+ (UINT32) *pEntries, &verbsData);
+ return hr;
}
STDMETHODIMP CWVCompletionQueue::
Peek(SIZE_T* pCompletedEntries)
{
- UNREFERENCED_PARAMETER(pCompletedEntries);
+ ib_api_status_t stat;
- return E_NOTIMPL;
+ stat = m_pVerbs->peek_cq(m_hVerbsCq, (UINT32 *) pCompletedEntries);
+ if (stat != IB_SUCCESS) {
+ return WvConvertIbStatus(stat);
+ }
+
+ return WV_SUCCESS;
}
STDMETHODIMP CWVCompletionQueue::
Notify(WV_CQ_NOTIFY_TYPE Type, OVERLAPPED* pOverlapped)
{
- UNREFERENCED_PARAMETER(Type);
- UNREFERENCED_PARAMETER(pOverlapped);
+ WV_IO_ID id;
+ DWORD bytes;
+ HRESULT hr;
- return E_NOTIMPL;
+ id.Id = m_Id;
+ id.Data = (UINT32) Type;
+ if (DeviceIoControl(m_hFile, WV_IOCTL_CQ_NOTIFY, &id, sizeof id,
+ NULL, 0, &bytes, pOverlapped)) {
+ hr = WV_SUCCESS;
+ } else {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ return hr;
}
STDMETHODIMP CWVCompletionQueue::
BatchNotify(SIZE_T CompletedEntries, OVERLAPPED* pOverlapped)
{
- UNREFERENCED_PARAMETER(CompletedEntries);
- UNREFERENCED_PARAMETER(pOverlapped);
+ WV_IO_ID id;
+ DWORD bytes;
+ HRESULT hr;
- return E_NOTIMPL;
+ id.Id = m_Id;
+ id.Data = (UINT32) CompletedEntries;
+ if (DeviceIoControl(m_hFile, WV_IOCTL_CQ_BATCH_NOTIFY, &id, sizeof id,
+ NULL, 0, &bytes, pOverlapped)) {
+ hr = WV_SUCCESS;
+ } else {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ return hr;
}
STDMETHODIMP_(SIZE_T) CWVCompletionQueue::
-Poll(WV_COMPLETION* pCompletions[], SIZE_T Entries)
+Poll(WV_COMPLETION Completions[], SIZE_T Entries)
{
- UNREFERENCED_PARAMETER(pCompletions);
- UNREFERENCED_PARAMETER(Entries);
-
- return 0;
+ // WV_COMPLETION aligns with uvp_wc_t by design.
+ return m_pVerbs->poll_cq_array(m_hVerbsCq, Entries, (uvp_wc_t *) Completions);
}
Index: core/winverbs/user/wv_cq.h
===================================================================
--- core/winverbs/user/wv_cq.h (revision 971)
+++ core/winverbs/user/wv_cq.h (working copy)
@@ -33,6 +33,7 @@
#define _WV_CQ_H_
#include "rdma\winverbs.h"
+#include "wv_device.h"
class CWVCompletionQueue : IWVCompletionQueue
{
@@ -52,7 +53,21 @@
STDMETHODIMP Peek(SIZE_T* pCompletedEntries);
STDMETHODIMP Notify(WV_CQ_NOTIFY_TYPE Type, OVERLAPPED* pOverlapped);
STDMETHODIMP BatchNotify(SIZE_T CompletedEntries, OVERLAPPED* pOverlapped);
- STDMETHODIMP_(SIZE_T) Poll(WV_COMPLETION* pCompletions[], SIZE_T Entries);
+ STDMETHODIMP_(SIZE_T) Poll(WV_COMPLETION Completions[], SIZE_T Entries);
+
+ CWVCompletionQueue(CWVDevice *pDevice);
+ ~CWVCompletionQueue();
+ STDMETHODIMP Create(SIZE_T *pEntries);
+
+ CWVDevice *m_pDevice;
+ uvp_interface_t *m_pVerbs;
+ HANDLE m_hFile;
+
+ ib_cq_handle_t m_hVerbsCq;
+ UINT64 m_Id;
+
+protected:
+ volatile LONG m_nRef;
};
#endif //_WV_CQ_H_
\ No newline at end of file
More information about the ofw
mailing list