Initial implementation of CQ:Notify() to support asynchronous notification
of CQ events.

Signed-off-by: Sean Hefty <[EMAIL PROTECTED]>
---
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


_______________________________________________
ofw mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw

Reply via email to