[ofw] [PATCH][RFC] winverbs/cq: implement CQ:Notify()
Sean Hefty
sean.hefty at intel.com
Wed Apr 30 18:33:19 PDT 2008
Initial implementation of CQ:Notify() to support asynchronous notification
of CQ events.
Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
I'm not sure if the WdfObject*Lock() routines for an IO queue work at dispatch
by default, but that looks easy enough to correct if they don't.
Index: core/winverbs/kernel/wv_cq.c
===================================================================
--- core/winverbs/kernel/wv_cq.c (revision 1090)
+++ core/winverbs/kernel/wv_cq.c (working copy)
@@ -27,6 +27,7 @@
* SOFTWARE.
*/
+#include "wv_driver.h"
#include "wv_cq.h"
#include "wv_ioctl.h"
@@ -68,13 +69,32 @@
static void WvCqEventHandler(ib_event_rec_t *pEvent)
{
- pEvent;
+ WV_COMPLETION_QUEUE *cq = pEvent->context;
+ WDFREQUEST request;
+ NTSTATUS status;
+
+ WdfObjectAcquireLock(cq->Queue);
+ status = WdfIoQueueRetrieveNextRequest(cq->Queue, &request);
+ WdfObjectReleaseLock(cq->Queue);
+
+ if (NT_SUCCESS(status)) {
+ WdfRequestComplete(request, STATUS_UNEXPECTED_IO_ERROR);
+ }
}
static void WvCqHandler(void *Context)
{
- WV_COMPLETION_QUEUE *pCq = Context;
- pCq;
+ WV_COMPLETION_QUEUE *cq = Context;
+ WDFREQUEST request;
+ NTSTATUS status;
+
+ WdfObjectAcquireLock(cq->Queue);
+ status = WdfIoQueueRetrieveNextRequest(cq->Queue, &request);
+ WdfObjectReleaseLock(cq->Queue);
+
+ if (NT_SUCCESS(status)) {
+ WdfRequestComplete(request, STATUS_SUCCESS);
+ }
}
static NTSTATUS WvCqAlloc(WV_DEVICE *pDevice, UINT32 *pSize,
@@ -82,8 +102,10 @@
{
ib_api_status_t ib_status;
WV_COMPLETION_QUEUE *cq;
+ WDF_IO_QUEUE_CONFIG config;
+ NTSTATUS status;
- cq = ExAllocatePoolWithTag(PagedPool, sizeof(WV_COMPLETION_QUEUE), 'qcvw');
+ cq = ExAllocatePoolWithTag(NonPagedPool, sizeof(WV_COMPLETION_QUEUE), 'qcvw');
if (cq == NULL) {
return STATUS_NO_MEMORY;
}
@@ -91,10 +113,18 @@
cq->Ref = 1;
KeInitializeEvent(&cq->Event, NotificationEvent, FALSE);
+ WDF_IO_QUEUE_CONFIG_INIT(&config, WdfIoQueueDispatchManual);
+ status = WdfIoQueueCreate(ControlDevice, &config,
+ WDF_NO_OBJECT_ATTRIBUTES, &cq->Queue);
+ if (!NT_SUCCESS(status)) {
+ goto err;
+ }
+
ib_status = pDevice->pVerbs->create_cq(pDevice->hVerbsDevice, cq,
WvCqEventHandler, WvCqHandler,
pSize, &cq->hVerbsCq, pVerbsData);
if (ib_status != IB_SUCCESS) {
+ status = STATUS_UNSUCCESSFUL;
goto err;
}
@@ -104,7 +134,7 @@
err:
ExFreePool(cq);
- return STATUS_UNSUCCESSFUL;
+ return status;
}
void WvCqCreate(WV_PROVIDER *pProvider, WDFREQUEST Request)
@@ -249,3 +279,38 @@
complete:
WdfRequestCompleteWithInformation(Request, status, len);
}
+
+void WvCqNotify(WV_PROVIDER *pProvider, WDFREQUEST Request)
+{
+ WV_IO_ID *id;
+ WV_COMPLETION_QUEUE *cq;
+ NTSTATUS status;
+ ib_api_status_t ib_status;
+
+ status = WdfRequestRetrieveInputBuffer(Request, sizeof(WV_IO_ID), &id, NULL);
+ if (!NT_SUCCESS(status)) {
+ goto out;
+ }
+
+ cq = WvCqAcquire(pProvider, id->Id);
+ if (cq == NULL) {
+ status = STATUS_NOT_FOUND;
+ goto out;
+ }
+
+ WdfObjectAcquireLock(cq->Queue);
+ ib_status = cq->pVerbs->enable_cq_notify(cq->hVerbsCq,
+ id->Data ==
WV_IO_CQ_NOTIFY_SOLICITED);
+ if (ib_status == IB_SUCCESS) {
+ status = WdfRequestForwardToIoQueue(Request, cq->Queue);
+ } else {
+ status = STATUS_UNSUCCESSFUL;
+ }
+ WdfObjectReleaseLock(cq->Queue);
+ WvCqRelease(cq);
+
+out:
+ if (!NT_SUCCESS(status)) {
+ WdfRequestComplete(Request, status);
+ }
+}
Index: core/winverbs/kernel/wv_cq.h
===================================================================
--- core/winverbs/kernel/wv_cq.h (revision 1075)
+++ core/winverbs/kernel/wv_cq.h (working copy)
@@ -49,6 +49,7 @@
KEVENT Event;
LONG Ref;
+ WDFQUEUE Queue;
} WV_COMPLETION_QUEUE;
@@ -63,5 +64,6 @@
void WvCqPut(WV_COMPLETION_QUEUE *pCq);
void WvCqResize(WV_PROVIDER *pProvider, WDFREQUEST Request);
+void WvCqNotify(WV_PROVIDER *pProvider, WDFREQUEST Request);
#endif //_WV_CQ_H_
Index: core/winverbs/kernel/wv_driver.c
===================================================================
--- core/winverbs/kernel/wv_driver.c (revision 1075)
+++ core/winverbs/kernel/wv_driver.c (working copy)
@@ -49,7 +49,7 @@
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WV_RDMA_DEVICE, WvRdmaDeviceGetContext)
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WV_PROVIDER, WvProviderGetContext)
-static WDFDEVICE ControlDevice;
+WDFDEVICE ControlDevice;
static LIST_ENTRY DevList;
static LIST_ENTRY ProvList;
static KGUARDED_MUTEX Lock;
@@ -233,8 +233,7 @@
WvCqResize(prov, Request);
break;
case WV_IOCTL_CQ_NOTIFY:
- //WvCqNotify(prov, Request);
- WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
+ WvCqNotify(prov, Request);
break;
case WV_IOCTL_CQ_BATCH_NOTIFY:
//WvCqBatchNotify(prov, Request);
Index: core/winverbs/kernel/wv_driver.h
===================================================================
--- core/winverbs/kernel/wv_driver.h (revision 1071)
+++ core/winverbs/kernel/wv_driver.h (working copy)
@@ -34,11 +34,14 @@
#include <ntddk.h>
#include <wdm.h>
+#include <wdf.h>
#include <iba\ib_types.h>
#include <iba\ib_ci.h>
#include <rdma\verbs.h>
+extern WDFDEVICE ControlDevice;
+
typedef struct _WV_RDMA_DEVICE
{
LIST_ENTRY Entry;
Index: core/winverbs/wv_ioctl.h
===================================================================
--- core/winverbs/wv_ioctl.h (revision 1089)
+++ core/winverbs/wv_ioctl.h (working copy)
@@ -493,6 +493,9 @@
} WV_IO_QP_CREATE;
+#define WV_IO_CQ_NOTIFY_SOLICITED 1
+#define WV_IO_CQ_NOTIFY_NEXT 2
+
#define WV_IO_QP_STATE_RESET 0
#define WV_IO_QP_STATE_INIT 1
#define WV_IO_QP_STATE_RTR 2
More information about the ofw
mailing list