[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