[ofw] [RFC] [PATCH] winverbs: add kernel support for cq and srq

Sean Hefty sean.hefty at intel.com
Fri Apr 25 10:16:10 PDT 2008


This adds the kernel support for CQs and SRQs, minus asynchronous event
handling.

And because SVN sucks for patch management, moves some functions between
source files and adds in missing HCA remove handling.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
Index: SOURCES
===================================================================
--- SOURCES	(revision 1071)
+++ SOURCES	(working copy)
@@ -15,7 +15,9 @@
 	wv_driver.c		\
 	wv_provider.c	\
 	wv_device.c		\
+	wv_cq.c			\
 	wv_pd.c			\
+	wv_srq.c		\
 	index_list.c
 
 INCLUDES = ..;..\..\..\inc;..\..\..\inc\kernel;..\..\..\inc\user;
Index: wv_cq.h
===================================================================
--- wv_cq.h	(revision 1035)
+++ wv_cq.h	(working copy)
@@ -32,19 +32,36 @@
 #ifndef _WV_CQ_H_
 #define _WV_CQ_H_
 
+#include <ntddk.h>
 #include <wdm.h>
 #include <iba\ib_types.h>
 #include <iba\ib_ci.h>
+
 #include "wv_device.h"
+#include "wv_provider.h"
 
 typedef struct _WV_COMPLETION_QUEUE
 {
 	WV_DEVICE			*pDevice;
 	ci_interface_t		*pVerbs;
 	ib_cq_handle_t		hVerbsCq;
-	UINT64				Id;
-	LONG				nRef;
+	LIST_ENTRY			Entry;
 
+	KEVENT				Event;
+	LONG				Ref;
+
 }	WV_COMPLETION_QUEUE;
 
+
+void WvCqCreate(WV_PROVIDER *pProvider, WDFREQUEST Request);
+void WvCqDestroy(WV_PROVIDER *pProvider, WDFREQUEST Request);
+void WvCqFree(WV_COMPLETION_QUEUE *pCq);
+
+WV_COMPLETION_QUEUE *WvCqAcquire(WV_PROVIDER *pProvider, UINT64 Id);
+void WvCqRelease(WV_COMPLETION_QUEUE *pCq);
+void WvCqGet(WV_COMPLETION_QUEUE *pCq);
+void WvCqPut(WV_COMPLETION_QUEUE *pCq);
+
+void WvCqResize(WV_PROVIDER *pProvider, WDFREQUEST Request);
+
 #endif //_WV_CQ_H_
Index: wv_device.c
===================================================================
--- wv_device.c	(revision 1071)
+++ wv_device.c	(working copy)
@@ -29,6 +29,7 @@
 
 #include "wv_device.h"
 #include "wv_pd.h"
+#include "wv_cq.h"
 #include "wv_ioctl.h"
 
 void WvDeviceGet(WV_DEVICE *pDevice)
@@ -67,7 +68,7 @@
 	WvDevicePut(pDevice);
 }
 
-WV_DEVICE *WvDeviceAlloc(WV_PROVIDER *pProvider)
+static WV_DEVICE *WvDeviceAlloc(WV_PROVIDER *pProvider)
 {
 	WV_DEVICE *dev;
 
@@ -81,6 +82,7 @@
 	dev->hVerbsDevice = NULL;
 	dev->Ref = 1;
 	InitializeListHead(&dev->PdList);
+	InitializeListHead(&dev->CqList);
 	KeInitializeEvent(&dev->Event, NotificationEvent, FALSE);
 
 	dev->pProvider = pProvider;
@@ -88,7 +90,8 @@
 	return dev;
 }
 
-NTSTATUS WvDeviceInit(WV_DEVICE *pDevice, UINT64 Guid, ci_umv_buf_t *pVerbsData)
+static NTSTATUS WvDeviceInit(WV_DEVICE *pDevice, UINT64 Guid,
+							 ci_umv_buf_t *pVerbsData)
 {
 	WV_RDMA_DEVICE *dev;
 	ib_api_status_t ib_status;
@@ -114,6 +117,92 @@
 	return STATUS_UNSUCCESSFUL;
 }
 
+void WvDeviceOpen(WV_PROVIDER *pProvider, WDFREQUEST Request)
+{
+	WV_IO_ID		*inid, *outid;
+	size_t			inlen, outlen;
+	WV_DEVICE		*dev;
+	NTSTATUS		status;
+	ci_umv_buf_t	verbsData;
+
+	status = WdfRequestRetrieveInputBuffer(Request, sizeof(WV_IO_ID), &inid, &inlen);
+	if (!NT_SUCCESS(status)) {
+		goto err1;
+	}
+	status = WdfRequestRetrieveOutputBuffer(Request, sizeof(WV_IO_ID), &outid, &outlen);
+	if (!NT_SUCCESS(status)) {
+		goto err1;
+	}
+
+	dev = WvDeviceAlloc(pProvider);
+	if (dev == NULL) {
+		status = STATUS_NO_MEMORY;
+		goto err1;
+	}
+
+	KeAcquireGuardedMutex(&pProvider->Lock);
+	WvProviderDisableRemove(pProvider);
+	KeReleaseGuardedMutex(&pProvider->Lock);
+
+	WvInitVerbsData(&verbsData, inid->VerbInfo, inlen - sizeof(WV_IO_ID),
+					outlen - sizeof(WV_IO_ID), inid + 1);
+	status = WvDeviceInit(dev, inid->Id, &verbsData);
+	if (!NT_SUCCESS(status)) {
+		goto err2;
+	}
+
+	KeAcquireGuardedMutex(&pProvider->Lock);
+	outid->Id = IndexListInsertHead(&pProvider->DevIndex, dev);
+	if (outid->Id == 0) {
+		status = STATUS_NO_MEMORY;
+		goto err2;
+	}
+	KeReleaseGuardedMutex(&pProvider->Lock);
+
+	WvProviderEnableRemove(pProvider);
+	outid->VerbInfo = verbsData.status;
+	WdfRequestCompleteWithInformation(Request, status, outlen);
+	return;
+
+err2:
+	WvDeviceFree(dev);
+	WvProviderEnableRemove(pProvider);
+err1:
+	WdfRequestComplete(Request, status);
+}
+
+void WvDeviceClose(WV_PROVIDER *pProvider, WDFREQUEST Request)
+{
+	WV_DEVICE	*dev;
+	UINT64		*id;
+	NTSTATUS	status;
+
+	status = WdfRequestRetrieveInputBuffer(Request, sizeof(UINT64), &id, NULL);
+	if (!NT_SUCCESS(status)) {
+		goto out;
+	}
+
+	KeAcquireGuardedMutex(&pProvider->Lock);
+	WvProviderDisableRemove(pProvider);
+	dev = IndexListAt(&pProvider->DevIndex, (SIZE_T) *id);
+	if (dev == NULL) {
+		status = STATUS_NO_SUCH_DEVICE;
+	} else if (dev->Ref > 1) {
+		status = STATUS_ACCESS_DENIED;
+	} else {
+		IndexListRemove(&pProvider->DevIndex, (SIZE_T) *id);
+		status = STATUS_SUCCESS;
+	}
+	KeReleaseGuardedMutex(&pProvider->Lock);
+
+	if (NT_SUCCESS(status)) {
+		WvDeviceFree(dev);
+	}
+	WvProviderEnableRemove(pProvider);
+out:
+	WdfRequestComplete(Request, status);
+}
+
 void WvDeviceFree(WV_DEVICE *pDevice)
 {
 	if (InterlockedDecrement(&pDevice->Ref) > 0) {
@@ -134,6 +223,7 @@
 {
 	LIST_ENTRY				*entry;
 	WV_PROTECTION_DOMAIN	*pd;
+	WV_COMPLETION_QUEUE		*cq;
 
 	for (entry = pDevice->PdList.Flink; entry != &pDevice->PdList;
 		 entry = entry->Flink) {
@@ -141,6 +231,14 @@
 		WvPdRemoveHandler(pd);
 	}
 
+	for (entry = pDevice->CqList.Flink; entry != &pDevice->CqList;
+		 entry = entry->Flink) {
+		cq = CONTAINING_RECORD(entry, WV_COMPLETION_QUEUE, Entry);
+		pDevice->pVerbs->destroy_cq(cq->hVerbsCq);
+		cq->hVerbsCq = NULL;
+		cq->pVerbs = NULL;
+	}
+
 	pDevice->pVerbs->um_close_ca(pDevice->pDevice->hDevice,
 								 pDevice->hVerbsDevice);
 	WvRdmaDevicePut(pDevice->pDevice);
@@ -498,90 +596,3 @@
 complete:
 	WdfRequestCompleteWithInformation(Request, status, outlen);
 }
-
-void WvPdAllocate(WV_PROVIDER *pProvider, WDFREQUEST Request)
-{
-	WV_IO_ID				*inid, *outid;
-	size_t					inlen, outlen;
-	WV_DEVICE				*dev;
-	WV_PROTECTION_DOMAIN	*pd;
-	NTSTATUS				status;
-	ci_umv_buf_t			verbsData;
-
-	status = WdfRequestRetrieveInputBuffer(Request, sizeof(WV_IO_ID), &inid, &inlen);
-	if (!NT_SUCCESS(status)) {
-		goto err1;
-	}
-	status = WdfRequestRetrieveOutputBuffer(Request, sizeof(WV_IO_ID), &outid, &outlen);
-	if (!NT_SUCCESS(status)) {
-		goto err1;
-	}
-
-	dev = WvDeviceAcquire(pProvider, inid->Id);
-	if (dev == NULL) {
-		status = STATUS_NO_SUCH_DEVICE;
-		goto err1;
-	}
-
-	WvInitVerbsData(&verbsData, inid->VerbInfo, inlen - sizeof(WV_IO_ID),
-					outlen - sizeof(WV_IO_ID), inid + 1);
-	status = WvPdAlloc(dev, &pd, &verbsData);
-	if (!NT_SUCCESS(status)) {
-		goto err2;
-	}
-
-	KeAcquireGuardedMutex(&pProvider->Lock);
-	outid->Id= IndexListInsertHead(&pProvider->PdIndex, pd);
-	if (outid->Id == 0) {
-		status = STATUS_NO_MEMORY;
-		goto err3;
-	}
-	InsertHeadList(&dev->PdList, &pd->Entry);
-	KeReleaseGuardedMutex(&pProvider->Lock);
-
-	WvDeviceRelease(dev);
-	outid->VerbInfo = verbsData.status;
-	WdfRequestCompleteWithInformation(Request, status, outlen);
-	return;
-
-err3:
-	KeReleaseGuardedMutex(&pProvider->Lock);
-	WvPdFree(pd);
-err2:
-	WvDeviceRelease(dev);
-err1:
-	WdfRequestComplete(Request, status);
-}
-
-void WvPdDeallocate(WV_PROVIDER *pProvider, WDFREQUEST Request)
-{
-	WV_PROTECTION_DOMAIN	*pd;
-	UINT64					*id;
-	NTSTATUS				status;
-
-	status = WdfRequestRetrieveInputBuffer(Request, sizeof(UINT64), &id, NULL);
-	if (!NT_SUCCESS(status)) {
-		goto out;
-	}
-
-	KeAcquireGuardedMutex(&pProvider->Lock);
-	WvProviderDisableRemove(pProvider);
-	pd = IndexListAt(&pProvider->PdIndex, (SIZE_T) id);
-	if (pd == NULL) {
-		status = STATUS_NOT_FOUND;
-	} else if (pd->Ref > 1) {
-		status = STATUS_ACCESS_DENIED;
-	} else {
-		IndexListRemove(&pProvider->PdIndex, (SIZE_T) id);
-		RemoveEntryList(&pd->Entry);
-		status = STATUS_SUCCESS;
-	}
-	KeReleaseGuardedMutex(&pProvider->Lock);
-
-	if (NT_SUCCESS(status)) {
-		WvPdFree(pd);
-	}
-	WvProviderEnableRemove(pProvider);
-out:
-	WdfRequestComplete(Request, status);
-}
Index: wv_device.h
===================================================================
--- wv_device.h	(revision 1071)
+++ wv_device.h	(working copy)
@@ -47,8 +47,10 @@
 	ci_interface_t		*pVerbs;
 	LIST_ENTRY			Entry;
 	ib_ca_handle_t		hVerbsDevice;
+
 	LIST_ENTRY			PdList;
-	SIZE_T				Id;
+	LIST_ENTRY			CqList;
+
 	KEVENT				Event;
 	LONG				Ref;
 
@@ -59,8 +61,8 @@
 void WvDeviceGet(WV_DEVICE *pDevice);
 void WvDevicePut(WV_DEVICE *pDevice);
 
-WV_DEVICE *WvDeviceAlloc(WV_PROVIDER *pProvider);
-NTSTATUS WvDeviceInit(WV_DEVICE *pDevice, UINT64 Guid, ci_umv_buf_t *pVerbsData);
+void WvDeviceOpen(WV_PROVIDER *pProvider, WDFREQUEST Request);
+void WvDeviceClose(WV_PROVIDER *pProvider, WDFREQUEST Request);
 void WvDeviceFree(WV_DEVICE *pDevice);
 void WvDeviceRemoveHandler(WV_DEVICE *pDevice);
 
@@ -69,7 +71,4 @@
 void WvDeviceGidQuery(WV_PROVIDER *pProvider, WDFREQUEST Request);
 void WvDevicePkeyQuery(WV_PROVIDER *pProvider, WDFREQUEST Request);
 
-void WvPdAllocate(WV_PROVIDER *pProvider, WDFREQUEST Request);
-void WvPdDeallocate(WV_PROVIDER *pProvider, WDFREQUEST Request);
-
 #endif // __WV_DEVICE_H_
Index: wv_driver.c
===================================================================
--- wv_driver.c	(revision 1071)
+++ wv_driver.c	(working copy)
@@ -39,6 +39,7 @@
 #include "wv_provider.h"
 #include "wv_device.h"
 #include "wv_pd.h"
+#include "wv_srq.h"
 #include "wv_cq.h"
 #include "wv_srq.h"
 #include "wv_qp.h"
@@ -215,17 +216,30 @@
 	case WV_IOCTL_AH_DESTROY:
 		WvAhDestroy(prov, Request);
 		break;
-	//case WV_IOCTL_CQ_CREATE:WvCqCreate;break;
-	//case WV_IOCTL_CQ_DESTROY:WvCqDestroy;break;
-	//case WV_IOCTL_CQ_RESIZE:WvCqResize;break;
+	case WV_IOCTL_CQ_CREATE:
+		WvCqCreate(prov, Request);
+		break;
+	case WV_IOCTL_CQ_DESTROY:
+		WvCqDestroy(prov, Request);
+		break;
+	case WV_IOCTL_CQ_RESIZE:
+		WvCqResize(prov, Request);
+		break;
 	//case WV_IOCTL_CQ_NOTIFY:WvCqNotify;break;
 	//case WV_IOCTL_CQ_BATCH_NOTIFY:WvCqBatchNotify;break;
 	//case WV_IOCTL_CQ_CANCEL:WvCqCancel;break;
-
-	//case WV_IOCTL_SRQ_CREATE:WvSrqCreate;break;
-	//case WV_IOCTL_SRQ_DESTROY:WvSrqDestroy;break;
-	//case WV_IOCTL_SRQ_QUERY:WvSrqQuery;break;
-	//case WV_IOCTL_SRQ_MODIFY:WvSrqModify;break;
+	case WV_IOCTL_SRQ_CREATE:
+		WvSrqCreate(prov, Request);
+		break;
+	case WV_IOCTL_SRQ_DESTROY:
+		WvSrqDestroy(prov, Request);
+		break;
+	case WV_IOCTL_SRQ_QUERY:
+		WvSrqQuery(prov, Request);
+		break;
+	case WV_IOCTL_SRQ_MODIFY:
+		WvSrqModify(prov, Request);
+		break;
 	//case WV_IOCTL_SRQ_NOTIFY:WvSrqNotify;break;
 	//case WV_IOCTL_SRQ_CANCEL:WvSrqCancel;break;
 
Index: wv_pd.c
===================================================================
--- wv_pd.c	(revision 1071)
+++ wv_pd.c	(working copy)
@@ -28,6 +28,7 @@
  */
 
 #include "wv_pd.h"
+#include "wv_srq.h"
 #include "wv_ioctl.h"
 
 void WvPdGet(WV_PROTECTION_DOMAIN *pPd)
@@ -66,19 +67,20 @@
 	WvPdPut(pPd);
 }
 
-NTSTATUS WvPdAlloc(WV_DEVICE *pDevice, WV_PROTECTION_DOMAIN **ppPd,
-				   ci_umv_buf_t *pVerbsData)
+static NTSTATUS WvPdAlloc(WV_DEVICE *pDevice, WV_PROTECTION_DOMAIN **ppPd,
+						  ci_umv_buf_t *pVerbsData)
 {
 	ib_api_status_t			ib_status;
 	WV_PROTECTION_DOMAIN	*pd;
 
-	pd = ExAllocatePoolWithTag(PagedPool, sizeof(WV_PROTECTION_DOMAIN), 'apvw');
+	pd = ExAllocatePoolWithTag(PagedPool, sizeof(WV_PROTECTION_DOMAIN), 'dpvw');
 	if (pd == NULL) {
 		return STATUS_NO_MEMORY;
 	}
 
 	pd->Ref = 1;
 	KeInitializeEvent(&pd->Event, NotificationEvent, FALSE);
+	InitializeListHead(&pd->SrqList);
 	InitializeListHead(&pd->MwList);
 	InitializeListHead(&pd->AhList);
 	cl_qmap_init(&pd->MrMap);
@@ -101,6 +103,93 @@
 	return STATUS_UNSUCCESSFUL;
 }
 
+void WvPdAllocate(WV_PROVIDER *pProvider, WDFREQUEST Request)
+{
+	WV_IO_ID				*inid, *outid;
+	size_t					inlen, outlen;
+	WV_DEVICE				*dev;
+	WV_PROTECTION_DOMAIN	*pd;
+	NTSTATUS				status;
+	ci_umv_buf_t			verbsData;
+
+	status = WdfRequestRetrieveInputBuffer(Request, sizeof(WV_IO_ID), &inid, &inlen);
+	if (!NT_SUCCESS(status)) {
+		goto err1;
+	}
+	status = WdfRequestRetrieveOutputBuffer(Request, sizeof(WV_IO_ID), &outid, &outlen);
+	if (!NT_SUCCESS(status)) {
+		goto err1;
+	}
+
+	dev = WvDeviceAcquire(pProvider, inid->Id);
+	if (dev == NULL) {
+		status = STATUS_NO_SUCH_DEVICE;
+		goto err1;
+	}
+
+	WvInitVerbsData(&verbsData, inid->VerbInfo, inlen - sizeof(WV_IO_ID),
+					outlen - sizeof(WV_IO_ID), inid + 1);
+	status = WvPdAlloc(dev, &pd, &verbsData);
+	if (!NT_SUCCESS(status)) {
+		goto err2;
+	}
+
+	KeAcquireGuardedMutex(&pProvider->Lock);
+	outid->Id = IndexListInsertHead(&pProvider->PdIndex, pd);
+	if (outid->Id == 0) {
+		status = STATUS_NO_MEMORY;
+		goto err3;
+	}
+	InsertHeadList(&dev->PdList, &pd->Entry);
+	KeReleaseGuardedMutex(&pProvider->Lock);
+
+	WvDeviceRelease(dev);
+	outid->VerbInfo = verbsData.status;
+	WdfRequestCompleteWithInformation(Request, status, outlen);
+	return;
+
+err3:
+	KeReleaseGuardedMutex(&pProvider->Lock);
+	WvPdFree(pd);
+err2:
+	WvDeviceRelease(dev);
+err1:
+	WdfRequestComplete(Request, status);
+}
+
+void WvPdDeallocate(WV_PROVIDER *pProvider, WDFREQUEST Request)
+{
+	WV_PROTECTION_DOMAIN	*pd;
+	UINT64					*id;
+	NTSTATUS				status;
+
+	status = WdfRequestRetrieveInputBuffer(Request, sizeof(UINT64), &id, NULL);
+	if (!NT_SUCCESS(status)) {
+		goto out;
+	}
+
+	KeAcquireGuardedMutex(&pProvider->Lock);
+	WvProviderDisableRemove(pProvider);
+	pd = IndexListAt(&pProvider->PdIndex, (SIZE_T) *id);
+	if (pd == NULL) {
+		status = STATUS_NOT_FOUND;
+	} else if (pd->Ref > 1) {
+		status = STATUS_ACCESS_DENIED;
+	} else {
+		IndexListRemove(&pProvider->PdIndex, (SIZE_T) *id);
+		RemoveEntryList(&pd->Entry);
+		status = STATUS_SUCCESS;
+	}
+	KeReleaseGuardedMutex(&pProvider->Lock);
+
+	if (NT_SUCCESS(status)) {
+		WvPdFree(pd);
+	}
+	WvProviderEnableRemove(pProvider);
+out:
+	WdfRequestComplete(Request, status);
+}
+
 void WvPdFree(WV_PROTECTION_DOMAIN *pPd)
 {
 	WV_MEMORY_REGION	*mr;
@@ -131,9 +220,25 @@
 
 void WvPdRemoveHandler(WV_PROTECTION_DOMAIN *pPd)
 {
-	WV_MEMORY_REGION	*mr;
-	cl_map_item_t		*item;
+	WV_SHARED_RECEIVE_QUEUE	*srq;
+	WV_MEMORY_REGION		*mr;
+	WV_ADDRESS_HANDLE		*ah;
+	WV_MEMORY_WINDOW		*mw;
+	cl_map_item_t			*item;
+	LIST_ENTRY				*entry;
 
+	for (entry = pPd->MwList.Flink; entry != &pPd->MwList; entry = entry->Flink) {
+		mw = CONTAINING_RECORD(entry, WV_MEMORY_WINDOW, Entry);
+		pPd->pVerbs->destroy_mw(mw->hVerbsMw);
+		mw->hVerbsMw = NULL;
+	}
+
+	for (entry = pPd->AhList.Flink; entry != &pPd->AhList; entry = entry->Flink) {
+		ah = CONTAINING_RECORD(entry, WV_ADDRESS_HANDLE, Entry);
+		pPd->pVerbs->destroy_av(ah->hVerbsAh);
+		ah->hVerbsAh = NULL;
+	}
+
 	for (item = cl_qmap_head(&pPd->MrMap); item != cl_qmap_end(&pPd->MrMap);
 		 item = cl_qmap_next(item)) {
 		mr = CONTAINING_RECORD(item, WV_MEMORY_REGION, Item);
@@ -141,6 +246,13 @@
 		mr->hVerbsMr = NULL;
 	}
 
+	for (entry = pPd->SrqList.Flink; entry != &pPd->SrqList; entry = entry->Flink) {
+		srq = CONTAINING_RECORD(entry, WV_SHARED_RECEIVE_QUEUE, Entry);
+		pPd->pVerbs->destroy_srq(srq->hVerbsSrq);
+		srq->hVerbsSrq = NULL;
+		srq->pVerbs = NULL;
+	}
+
 	pPd->pVerbs->deallocate_pd(pPd->hVerbsPd);
 	pPd->pVerbs = NULL;
 	pPd->hVerbsPd = NULL;
@@ -331,11 +443,11 @@
 
 	KeAcquireGuardedMutex(&pProvider->Lock);
 	WvProviderDisableRemove(pProvider);
-	mw = IndexListAt(&pProvider->MwIndex, (SIZE_T) id);
+	mw = IndexListAt(&pProvider->MwIndex, (SIZE_T) *id);
 	if (mw == NULL) {
 		status = STATUS_NOT_FOUND;
 	} else {
-		IndexListRemove(&pProvider->MwIndex, (SIZE_T) id);
+		IndexListRemove(&pProvider->MwIndex, (SIZE_T) *id);
 		RemoveEntryList(&mw->Entry);
 		status = STATUS_SUCCESS;
 	}
@@ -457,11 +569,11 @@
 
 	KeAcquireGuardedMutex(&pProvider->Lock);
 	WvProviderDisableRemove(pProvider);
-	ah = IndexListAt(&pProvider->AhIndex, (SIZE_T) id);
+	ah = IndexListAt(&pProvider->AhIndex, (SIZE_T) *id);
 	if (ah == NULL) {
 		status = STATUS_NOT_FOUND;
 	} else {
-		IndexListRemove(&pProvider->AhIndex, (SIZE_T) id);
+		IndexListRemove(&pProvider->AhIndex, (SIZE_T) *id);
 		RemoveEntryList(&ah->Entry);
 		status = STATUS_SUCCESS;
 	}
Index: wv_pd.h
===================================================================
--- wv_pd.h	(revision 1071)
+++ wv_pd.h	(working copy)
@@ -47,6 +47,7 @@
 	ib_pd_handle_t		hVerbsPd;
 	LIST_ENTRY			Entry;
 
+	LIST_ENTRY			SrqList;
 	LIST_ENTRY			MwList;
 	LIST_ENTRY			AhList;
 	KGUARDED_MUTEX		Lock;
@@ -57,13 +58,13 @@
 
 }	WV_PROTECTION_DOMAIN;
 
-struct _WV_PROTECTION_DOMAIN *WvPdAcquire(WV_PROVIDER *pProvider, UINT64 Id);
+WV_PROTECTION_DOMAIN *WvPdAcquire(WV_PROVIDER *pProvider, UINT64 Id);
 void WvPdRelease(WV_PROTECTION_DOMAIN *pPd);
 void WvPdGet(WV_PROTECTION_DOMAIN *pPd);
 void WvPdPut(WV_PROTECTION_DOMAIN *pPd);
 
-NTSTATUS WvPdAlloc(WV_DEVICE *pDevice, WV_PROTECTION_DOMAIN **ppPd,
-				   ci_umv_buf_t *pVerbsData);
+void WvPdAllocate(WV_PROVIDER *pProvider, WDFREQUEST Request);
+void WvPdDeallocate(WV_PROVIDER *pProvider, WDFREQUEST Request);
 void WvPdFree(WV_PROTECTION_DOMAIN *pPd);
 void WvPdRemoveHandler(WV_PROTECTION_DOMAIN *pPd);
 
Index: wv_provider.c
===================================================================
--- wv_provider.c	(revision 1071)
+++ wv_provider.c	(working copy)
@@ -35,6 +35,8 @@
 #include "wv_provider.h"
 #include "wv_device.h"
 #include "wv_pd.h"
+#include "wv_srq.h"
+#include "wv_cq.h"
 
 void WvProviderGet(WV_PROVIDER *pProvider)
 {
@@ -51,7 +53,9 @@
 void WvProviderInit(WV_PROVIDER *pProvider)
 {
 	IndexListInit(&pProvider->DevIndex);
+	IndexListInit(&pProvider->CqIndex);
 	IndexListInit(&pProvider->PdIndex);
+	IndexListInit(&pProvider->SrqIndex);
 	IndexListInit(&pProvider->MwIndex);
 	IndexListInit(&pProvider->AhIndex);
 
@@ -69,7 +73,9 @@
 void WvProviderCleanup(WV_PROVIDER *pProvider)
 {
 	WV_DEVICE				*dev;
+	WV_COMPLETION_QUEUE		*cq;
 	WV_PROTECTION_DOMAIN	*pd;
+	WV_SHARED_RECEIVE_QUEUE	*srq;
 	WV_MEMORY_WINDOW		*mw;
 	WV_ADDRESS_HANDLE		*ah;
 
@@ -81,10 +87,18 @@
 		RemoveEntryList(&mw->Entry);
 		WvMwFree(mw);
 	}
+	while ((srq = IndexListRemoveHead(&pProvider->SrqIndex)) != NULL) {
+		RemoveEntryList(&srq->Entry);
+		WvSrqFree(srq);
+	}
 	while ((pd = IndexListRemoveHead(&pProvider->PdIndex)) != NULL) {
 		RemoveEntryList(&pd->Entry);
 		WvPdFree(pd);
 	}
+	while ((cq = IndexListRemoveHead(&pProvider->CqIndex)) != NULL) {
+		RemoveEntryList(&cq->Entry);
+		WvCqFree(cq);
+	}
 	while ((dev = IndexListRemoveHead(&pProvider->DevIndex)) != NULL) {
 		WvDeviceFree(dev);
 	}
@@ -95,7 +109,9 @@
 
 	IndexListDestroy(&pProvider->AhIndex);
 	IndexListDestroy(&pProvider->MwIndex);
+	IndexListDestroy(&pProvider->SrqIndex);
 	IndexListDestroy(&pProvider->PdIndex);
+	IndexListDestroy(&pProvider->CqIndex);
 	IndexListDestroy(&pProvider->DevIndex);
 }
 
@@ -180,90 +196,3 @@
 	}
 	WvProviderUnlockRemove(pProvider);
 }
-
-void WvDeviceOpen(WV_PROVIDER *pProvider, WDFREQUEST Request)
-{
-	WV_IO_ID		*inid, *outid;
-	size_t			inlen, outlen;
-	WV_DEVICE		*dev;
-	NTSTATUS		status;
-	ci_umv_buf_t	verbsData;
-
-	status = WdfRequestRetrieveInputBuffer(Request, sizeof(WV_IO_ID), &inid, &inlen);
-	if (!NT_SUCCESS(status)) {
-		goto err1;
-	}
-	status = WdfRequestRetrieveOutputBuffer(Request, sizeof(WV_IO_ID), &outid, &outlen);
-	if (!NT_SUCCESS(status)) {
-		goto err1;
-	}
-
-	dev = WvDeviceAlloc(pProvider);
-	if (dev == NULL) {
-		status = STATUS_NO_MEMORY;
-		goto err1;
-	}
-
-	KeAcquireGuardedMutex(&pProvider->Lock);
-	WvProviderDisableRemove(pProvider);
-	KeReleaseGuardedMutex(&pProvider->Lock);
-
-	WvInitVerbsData(&verbsData, inid->VerbInfo, inlen - sizeof(WV_IO_ID),
-					outlen - sizeof(WV_IO_ID), inid + 1);
-	status = WvDeviceInit(dev, inid->Id, &verbsData);
-	if (!NT_SUCCESS(status)) {
-		goto err2;
-	}
-
-	KeAcquireGuardedMutex(&pProvider->Lock);
-	dev->Id = IndexListInsertHead(&pProvider->DevIndex, dev);
-	if (dev->Id == 0) {
-		status = STATUS_NO_MEMORY;
-		goto err2;
-	}
-	KeReleaseGuardedMutex(&pProvider->Lock);
-
-	WvProviderEnableRemove(pProvider);
-	outid->Id = dev->Id;
-	outid->VerbInfo = verbsData.status;
-	WdfRequestCompleteWithInformation(Request, status, outlen);
-	return;
-
-err2:
-	WvDeviceFree(dev);
-	WvProviderEnableRemove(pProvider);
-err1:
-	WdfRequestComplete(Request, status);
-}
-
-void WvDeviceClose(WV_PROVIDER *pProvider, WDFREQUEST Request)
-{
-	WV_DEVICE	*dev;
-	UINT64		*id;
-	NTSTATUS	status;
-
-	status = WdfRequestRetrieveInputBuffer(Request, sizeof(UINT64), &id, NULL);
-	if (!NT_SUCCESS(status)) {
-		goto out;
-	}
-
-	KeAcquireGuardedMutex(&pProvider->Lock);
-	WvProviderDisableRemove(pProvider);
-	dev = IndexListAt(&pProvider->DevIndex, (SIZE_T) id);
-	if (dev == NULL) {
-		status = STATUS_NO_SUCH_DEVICE;
-	} else if (dev->Ref > 1) {
-		status = STATUS_ACCESS_DENIED;
-	} else {
-		IndexListRemove(&pProvider->DevIndex, (SIZE_T) id);
-		status = STATUS_SUCCESS;
-	}
-	KeReleaseGuardedMutex(&pProvider->Lock);
-
-	if (NT_SUCCESS(status)) {
-		WvDeviceFree(dev);
-	}
-	WvProviderEnableRemove(pProvider);
-out:
-	WdfRequestComplete(Request, status);
-}
Index: wv_provider.h
===================================================================
--- wv_provider.h	(revision 1071)
+++ wv_provider.h	(working copy)
@@ -47,7 +47,9 @@
 {
 	LIST_ENTRY		Entry;
 	INDEX_LIST		DevIndex;
+	INDEX_LIST		CqIndex;
 	INDEX_LIST		PdIndex;
+	INDEX_LIST		SrqIndex;
 	INDEX_LIST		MwIndex;
 	INDEX_LIST		AhIndex;
 
@@ -71,7 +73,4 @@
 void WvProviderDisableRemove(WV_PROVIDER *pProvider);
 void WvProviderEnableRemove(WV_PROVIDER *pProvider);
 
-void WvDeviceOpen(WV_PROVIDER *pProvider, WDFREQUEST Request);
-void WvDeviceClose(WV_PROVIDER *pProvider, WDFREQUEST Request);
-
 #endif // _WV_PROVIDER_H_
Index: wv_srq.h
===================================================================
--- wv_srq.h	(revision 1035)
+++ wv_srq.h	(working copy)
@@ -32,19 +32,37 @@
 #ifndef _WV_SRQ_H_
 #define _WV_SRQ_H_
 
+#include <ntddk.h>
 #include <wdm.h>
 #include <iba\ib_types.h>
 #include <iba\ib_ci.h>
+
 #include "wv_pd.h"
+#include "wv_provider.h"
 
 typedef struct _WV_SHARED_RECEIVE_QUEUE
 {
+	WV_PROVIDER				*pProvider;
 	WV_PROTECTION_DOMAIN	*pPd;
 	ci_interface_t			*pVerbs;
 	ib_srq_handle_t			hVerbsSrq;
-	UINT64					Id;
-	LONG					nRef;
+	LIST_ENTRY				Entry;
 
+	KEVENT					Event;
+	LONG					Ref;
+
 }	WV_SHARED_RECEIVE_QUEUE;
 
+void WvSrqCreate(WV_PROVIDER *pProvider, WDFREQUEST Request);
+void WvSrqDestroy(WV_PROVIDER *pProvider, WDFREQUEST Request);
+void WvSrqFree(WV_SHARED_RECEIVE_QUEUE *pSrq);
+
+WV_SHARED_RECEIVE_QUEUE *WvSrqAsrquire(WV_PROVIDER *pProvider, UINT64 Id);
+void WvSrqRelease(WV_SHARED_RECEIVE_QUEUE *pSrq);
+void WvSrqGet(WV_SHARED_RECEIVE_QUEUE *pSrq);
+void WvSrqPut(WV_SHARED_RECEIVE_QUEUE *pSrq);
+
+void WvSrqModify(WV_PROVIDER *pProvider, WDFREQUEST Request);
+void WvSrqQuery(WV_PROVIDER *pProvider, WDFREQUEST Request);
+
 #endif // _WV_SRQ_H_





More information about the ofw mailing list